diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c47f0161b..d8550e2809 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 +- 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 diff --git a/res_syntax/cli/reactjs_jsx_v4.ml b/res_syntax/cli/reactjs_jsx_v4.ml index 7023bd74cf..3fa3cd3a30 100644 --- a/res_syntax/cli/reactjs_jsx_v4.ml +++ b/res_syntax/cli/reactjs_jsx_v4.ml @@ -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 diff --git a/res_syntax/tests/ppx/react/expected/forwardRef.res.txt b/res_syntax/tests/ppx/react/expected/forwardRef.res.txt index 45703e4727..c071e3c83b 100644 --- a/res_syntax/tests/ppx/react/expected/forwardRef.res.txt +++ b/res_syntax/tests/ppx/react/expected/forwardRef.res.txt @@ -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, + ) => + 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 = { @@ -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" + } +} diff --git a/res_syntax/tests/ppx/react/forwardRef.res b/res_syntax/tests/ppx/react/forwardRef.res index 6eea1a29cb..b814e14476 100644 --- a/res_syntax/tests/ppx/react/forwardRef.res +++ b/res_syntax/tests/ppx/react/forwardRef.res @@ -52,6 +52,31 @@ module V4C = { } } +module V4CUncurried = { + module FancyInput = { + @react.component + let make = React.forwardRef((. ~className=?, ~children, ref: Js.Nullable.t) => +
+ Belt.Option.map(React.Ref.domRef)} + /> + children +
+ ) + } + + @react.component + let make = () => { + let input = React.useRef(Js.Nullable.null) + +
+ {React.string("Click to focus")} +
+ } +} + @@jsxConfig({version: 4, mode: "automatic"}) module V4A = { @@ -78,3 +103,28 @@ module V4A = { } } + +module V4AUncurried = { + module FancyInput = { + @react.component + let make = React.forwardRef((. ~className=?, ~children, ref) => +
+ Belt.Option.map(ReactDOM.Ref.domRef)} + /> + children +
+ ) + } + + @react.component + let make = () => { + let input = React.useRef(Js.Nullable.null) + +
+ {React.string("Click to focus")} +
+ } +}