Skip to content

Commit

Permalink
ppx: fix 822
Browse files Browse the repository at this point in the history
  • Loading branch information
jchavarri committed Nov 21, 2023
1 parent 5a1127f commit 4d74c0e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 14 deletions.
18 changes: 14 additions & 4 deletions ppx/reason_react_ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,14 @@ let makePropsType ~loc namedTypeList =
};
]

let jsxExprAndChildren ~ident ~loc ~ctxt mapper ~keyProps children =
type component_type = Uppercase | Lowercase

let jsxExprAndChildren ~component_type ~loc ~ctxt mapper ~keyProps children =
let ident =
match component_type with
| Uppercase -> Lident "React"
| Lowercase -> Lident "ReactDOM"
in
let childrenExpr =
Option.map (transformChildrenIfListUpper ~loc ~mapper ~ctxt) children
in
Expand Down Expand Up @@ -477,16 +484,19 @@ let jsxExprAndChildren ~ident ~loc ~ctxt mapper ~keyProps children =
children *)
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsxs") },
None,
Some (Binding.React.array ~loc children) )
Some
(match component_type with
| Uppercase -> children
| Lowercase -> Binding.React.array ~loc children) )
| None, (label, key) :: _ ->
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsxKeyed") },
Some (label, key),
None )
| None, [] ->
(Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsx") }, None, None)

let reactJsxExprAndChildren = jsxExprAndChildren ~ident:(Lident "React")
let reactDomJsxExprAndChildren = jsxExprAndChildren ~ident:(Lident "ReactDOM")
let reactJsxExprAndChildren = jsxExprAndChildren ~component_type:Uppercase
let reactDomJsxExprAndChildren = jsxExprAndChildren ~component_type:Lowercase

(* Builds an AST node for the entire `external` definition of props *)
let makeExternalDecl fnName loc namedArgListWithKeyAndRef namedTypeList =
Expand Down
5 changes: 1 addition & 4 deletions ppx/test/upper.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
let upper_children_single = foo =>
React.jsx(Upper.make, Upper.makeProps(~children=foo, ()));
let upper_children_multiple = (foo, bar) =>
React.jsxs(
Upper.make,
Upper.makeProps(~children=React.array([|foo, bar|]), ()),
);
React.jsxs(Upper.make, Upper.makeProps(~children=[|foo, bar|], ()));
let upper_children =
React.jsx(
Page.make,
Expand Down
37 changes: 31 additions & 6 deletions test/React__test.re
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ module DummyComponentThatMapsChildren = {
[@react.component]
let make = (~children, ()) => {
<div>
{children->React.Children.mapWithIndex((element, index) => {
React.cloneElement(
element,
{"key": {j|$index|j}, "data-index": index},
)
})}
{children
->React.array
->React.Children.mapWithIndex((element, index) => {
React.cloneElement(
element,
{"key": {j|$index|j}, "data-index": index},
)
})}
</div>;
};
};
Expand Down Expand Up @@ -357,4 +359,27 @@ describe("React", () => {
/* We catch the exception here to not populate the error to the toplevel */
()
};

test("Can define components with custom children", () => {
let container = getContainer(container);
let root = ReactDOM.Client.createRoot(container);

module Test = {
type t = {name: string};
[@react.component]
let make = (~children) => {
Array.map(children, c => <div> {React.string(c.name)} </div>)
->React.array;
};
};

act(() => {
ReactDOM.Client.render(
root,
<Test> {Test.name: "foo"} {name: "bar"} </Test>,
)
});

expect(container->DOM.findBySelector("img")->Option.isSome)->toBe(true);
});
});

0 comments on commit 4d74c0e

Please sign in to comment.