Skip to content

Commit

Permalink
ppx: fix 822
Browse files Browse the repository at this point in the history
  • Loading branch information
jchavarri authored and anmonteiro committed Nov 24, 2024
1 parent c07e413 commit 69250c5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 15 deletions.
18 changes: 14 additions & 4 deletions ppx/reason_react_ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,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 @@ -492,16 +499,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
45 changes: 38 additions & 7 deletions test/React__test.re
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@ module DummyComponentThatMapsChildren = {
[@react.component]
let make = (~children, ()) => {
<div>
{children->React.Children.mapWithIndex((element, index) => {
React.cloneElement(
element,
{"key": string_of_int(index), "data-index": index},
)
})}
{children
->React.array
->React.Children.mapWithIndex((element, index) => {
React.cloneElement(
element,
{
"key": string_of_int(index),
"data-index": index,
},
)
})}
</div>;
};
};
Expand Down Expand Up @@ -318,7 +323,10 @@ describe("React", () => {
act(() => {
ReactDOM.Client.render(
root,
render({name: "Joe", imageUrl: "https://foo.png"}),
render({
name: "Joe",
imageUrl: "https://foo.png",
}),
)
});

Expand Down Expand Up @@ -409,4 +417,27 @@ describe("React", () => {

expect(Memo.renders^)->toBe(2);
});

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 69250c5

Please sign in to comment.