Skip to content

Commit

Permalink
typed keys 2
Browse files Browse the repository at this point in the history
  • Loading branch information
jchavarri committed Nov 3, 2023
1 parent 9e5a888 commit cb8ba82
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 16 deletions.
12 changes: 9 additions & 3 deletions ppx/reason_react_ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ module Binding = struct
{ txt = Longident.Ldot (Lident "React", "array"); loc })
[ (nolabel, children) ]

let unsafeArray ~loc children =
Builder.pexp_apply ~loc
(Builder.pexp_ident ~loc
{ txt = Longident.Ldot (Lident "React", "unsafeArray"); loc })
[ (nolabel, children) ]

let componentLike ~loc props return =
Ptyp_constr
( { loc; txt = Ldot (Lident "React", "componentLike") },
Expand Down Expand Up @@ -448,7 +454,7 @@ let jsxExprAndChildren ~ident ~loc ~ctxt mapper ~keyProps children =
when list = [] ->
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsxKeyed") },
Some (label, key),
Some (Binding.React.array ~loc children) )
Some (Binding.React.unsafeArray ~loc children) )
| Some (ListLiteral { pexp_desc = Pexp_array list }), [] when list = [] ->
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsx") },
None,
Expand All @@ -458,13 +464,13 @@ let jsxExprAndChildren ~ident ~loc ~ctxt mapper ~keyProps children =
children *)
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsxsKeyed") },
Some (label, key),
Some (Binding.React.array ~loc children) )
Some (Binding.React.unsafeArray ~loc children) )
| Some (ListLiteral children), [] ->
(* this is a hack to support react components that introspect into their
children *)
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsxs") },
None,
Some (Binding.React.array ~loc children) )
Some (Binding.React.unsafeArray ~loc children) )
| None, (label, key) :: _ ->
( Builder.pexp_ident ~loc { loc; txt = Ldot (ident, "jsxKeyed") },
Some (label, key),
Expand Down
6 changes: 4 additions & 2 deletions src/React.re
Original file line number Diff line number Diff line change
Expand Up @@ -301,14 +301,16 @@ module Event = {
};

type element;
type elementKeyed;
type componentLike('props, 'return) = 'props => 'return;
type component('props) = componentLike('props, element);

external null: element = "null";
external float: float => element = "%identity";
external int: int => element = "%identity";
external string: string => element = "%identity";
external array: array(element) => element = "%identity";
external array: array(elementKeyed) => element = "%identity";
external unsafeArray: array(element) => element = "%identity";

/* this function exists to prepare for making `component` abstract */
external component: componentLike('props, element) => component('props) =
Expand All @@ -328,7 +330,7 @@ external createElementVariadic:

[@mel.module "react/jsx-runtime"]
external jsxKeyed:
(component('props), 'props, ~key: string=?, unit) => element =
(component('props), 'props, ~key: string=?, unit) => elementKeyed =
"jsx";

[@mel.module "react/jsx-runtime"]
Expand Down
6 changes: 4 additions & 2 deletions src/React.rei
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
type element;
type elementKeyed;
type componentLike('props, 'return) = 'props => 'return;
type component('props) = componentLike('props, element);

external null: element = "null";
external float: float => element = "%identity";
external int: int => element = "%identity";
external string: string => element = "%identity";
external array: array(element) => element = "%identity";
external array: array(elementKeyed) => element = "%identity";
external unsafeArray: array(element) => element = "%identity";

/* this function exists to prepare for making `component` abstract */
external component: componentLike('props, element) => component('props) =
Expand All @@ -26,7 +28,7 @@ external createElementVariadic:

[@mel.module "react/jsx-runtime"]
external jsxKeyed:
(component('props), 'props, ~key: string=?, unit) => element =
(component('props), 'props, ~key: string=?, unit) => elementKeyed =
"jsx";

[@mel.module "react/jsx-runtime"]
Expand Down
2 changes: 1 addition & 1 deletion src/ReactDOM.re
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ external createDOMElementVariadic:
"createElement";

[@mel.module "react/jsx-runtime"]
external jsxKeyed: (string, domProps, ~key: string=?, unit) => React.element =
external jsxKeyed: (string, domProps, ~key: string=?, unit) => React.elementKeyed =
"jsx";

[@mel.module "react/jsx-runtime"]
Expand Down
2 changes: 1 addition & 1 deletion src/ReactDOM.rei
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,7 @@ external createDOMElementVariadic:
"createElement";

[@mel.module "react/jsx-runtime"]
external jsxKeyed: (string, domProps, ~key: string=?, unit) => React.element =
external jsxKeyed: (string, domProps, ~key: string=?, unit) => React.elementKeyed =
"jsx";

[@mel.module "react/jsx-runtime"]
Expand Down
2 changes: 1 addition & 1 deletion test/Hooks__test.re
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ module DummyStatefulComponent = {
let make = (~initialValue=0, ()) => {
let (value, setValue) = React.useState(() => initialValue);

<button key="asdf" onClick={_ => setValue(value => value + 1)}>
<button onClick={_ => setValue(value => value + 1)}>
value->React.int
</button>;
};
Expand Down
18 changes: 12 additions & 6 deletions test/React__test.re
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,12 @@ describe("React", () => {
act(() => {
ReactDOM.Client.render(
root,
<React.Fragment key=?title>
<div> "Child"->React.string </div>
</React.Fragment>,
[|
<React.Fragment key=?title>
<div> "Child"->React.string </div>
</React.Fragment>,
|]
->React.array,
)
});

Expand All @@ -309,9 +312,12 @@ describe("React", () => {
};

let render = author =>
<div key={author.Author.name}>
<div> <img src={author.imageUrl} /> </div>
</div>;
[|
<div key={author.Author.name}>
<div> <img src={author.imageUrl} /> </div>
</div>,
|]
->React.array;

act(() => {
ReactDOM.Client.render(
Expand Down

0 comments on commit cb8ba82

Please sign in to comment.