Skip to content

Fix uncurried forwardRef component #5808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ These are only breaking changes for unformatted code.

- Syntax: process uncurried types explicitly in the parser/printer https://github.com/rescript-lang/rescript-compiler/pull/5784
- Syntax: process uncurried function declarations explicitly in the parser/printer https://github.com/rescript-lang/rescript-compiler/pull/5794
- PPX V4: allow uncurried `make` function and treat it like a currie one https://github.com/rescript-lang/rescript-compiler/pull/5802
- PPX V4: allow uncurried `make` function and treat it like a curried one https://github.com/rescript-lang/rescript-compiler/pull/5802
Copy link
Member Author

@mununki mununki Nov 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed typo currie -> curried

- PPX V4: allow uncurried `make` function with nolabel arguments e.g. `forwardRef` component https://github.com/rescript-lang/rescript-compiler/pull/5808

# 10.1.0-rc.5

Expand Down
17 changes: 13 additions & 4 deletions res_syntax/cli/reactjs_jsx_v4.ml
Original file line number Diff line number Diff line change
Expand Up @@ -817,12 +817,21 @@ let transformStructureItem ~config mapper item =
React_jsx_common.raiseErrorMultipleReactComponent ~loc:pstr_loc
else (
config.hasReactComponent <- true;
let binding =
match binding.pvb_expr.pexp_desc with
let rec removeArityRecord expr =
match expr.pexp_desc with
| Pexp_record
([({txt = Ldot (Ldot (Lident "Js", "Fn"), _)}, e)], None) ->
{binding with pvb_expr = e}
| _ -> binding
e
| Pexp_apply (forwardRef, [(label, e)]) ->
{
expr with
pexp_desc =
Pexp_apply (forwardRef, [(label, removeArityRecord e)]);
}
| _ -> expr
in
let binding =
{binding with pvb_expr = removeArityRecord binding.pvb_expr}
in
let coreTypeOfAttr =
React_jsx_common.coreTypeOfAttrs binding.pvb_attributes
Expand Down
113 changes: 113 additions & 0 deletions res_syntax/tests/ppx/react/expected/forwardRef.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,63 @@ module V4C = {
}
}

module V4CUncurried = {
module FancyInput = {
type props<'className, 'children, 'ref> = {
className?: 'className,
children: 'children,
ref?: 'ref,
}

@react.component
let make = (
{?className, children, _}: props<'className, 'children, ReactRef.currentDomRef>,
ref: Js.Nullable.t<ReactRef.currentDomRef>,
) =>
ReactDOM.createDOMElementVariadic(
"div",
[
ReactDOM.createDOMElementVariadic(
"input",
~props={
type_: "text",
?className,
ref: ?Js.Nullable.toOption(ref)->Belt.Option.map(React.Ref.domRef),
},
[],
),
children,
],
)
let make = React.forwardRef({
let \"ForwardRef$V4CUncurried$FancyInput" = (props: props<_>, ref) => make(props, ref)

\"ForwardRef$V4CUncurried$FancyInput"
})
}
type props = {}

@react.component
let make = (_: props) => {
let input = React.useRef(Js.Nullable.null)

ReactDOM.createDOMElementVariadic(
"div",
[
React.createElement(
FancyInput.make,
{ref: input, children: {React.string("Click to focus")}},
),
],
)
}
let make = {
let \"ForwardRef$V4CUncurried" = props => make(props)

\"ForwardRef$V4CUncurried"
}
}

@@jsxConfig({version: 4, mode: "automatic"})

module V4A = {
Expand Down Expand Up @@ -181,3 +238,59 @@ module V4A = {
\"ForwardRef$V4A"
}
}

module V4AUncurried = {
module FancyInput = {
type props<'className, 'children, 'ref> = {
className?: 'className,
children: 'children,
ref?: 'ref,
}

@react.component
let make = (
{?className, children, _}: props<'className, 'children, ReactDOM.Ref.currentDomRef>,
ref,
) =>
ReactDOM.jsxs(
"div",
{
children: React.array([
ReactDOM.jsx(
"input",
{
type_: "text",
?className,
ref: ?Js.Nullable.toOption(ref)->Belt.Option.map(ReactDOM.Ref.domRef),
},
),
children,
]),
},
)
let make = React.forwardRef({
let \"ForwardRef$V4AUncurried$FancyInput" = (props: props<_>, ref) => make(props, ref)

\"ForwardRef$V4AUncurried$FancyInput"
})
}
type props = {}

@react.component
let make = (_: props) => {
let input = React.useRef(Js.Nullable.null)
ReactDOM.jsx(
"div",
{
children: ?ReactDOM.someElement(
React.jsx(FancyInput.make, {ref: input, children: {React.string("Click to focus")}}),
),
},
)
}
let make = {
let \"ForwardRef$V4AUncurried" = props => make(props)

\"ForwardRef$V4AUncurried"
}
}
50 changes: 50 additions & 0 deletions res_syntax/tests/ppx/react/forwardRef.res
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,31 @@ module V4C = {
}
}

module V4CUncurried = {
module FancyInput = {
@react.component
let make = React.forwardRef((. ~className=?, ~children, ref: Js.Nullable.t<ReactRef.currentDomRef>) =>
<div>
<input
type_="text"
?className
ref=?{Js.Nullable.toOption(ref)->Belt.Option.map(React.Ref.domRef)}
/>
children
</div>
)
}

@react.component
let make = () => {
let input = React.useRef(Js.Nullable.null)

<div>
<FancyInput ref=input> {React.string("Click to focus")} </FancyInput>
</div>
}
}

@@jsxConfig({version: 4, mode: "automatic"})

module V4A = {
Expand All @@ -78,3 +103,28 @@ module V4A = {
</div>
}
}

module V4AUncurried = {
module FancyInput = {
@react.component
let make = React.forwardRef((. ~className=?, ~children, ref) =>
<div>
<input
type_="text"
?className
ref=?{Js.Nullable.toOption(ref)->Belt.Option.map(ReactDOM.Ref.domRef)}
/>
children
</div>
)
}

@react.component
let make = () => {
let input = React.useRef(Js.Nullable.null)

<div>
<FancyInput ref=input> {React.string("Click to focus")} </FancyInput>
</div>
}
}