diff --git a/Makefile b/Makefile index 3512619a7..6ffd83c0e 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,7 @@ format-check: ## Checks if format is correct .PHONY: install install: ## Update the package dependencies when new deps are added to dune-project - @opam install . --deps-only --with-test + @opam install . --deps-only --with-test --with-dev-setup @npm install .PHONY: init diff --git a/docs/components.md b/docs/components.md index 2a667aa13..814c046a8 100644 --- a/docs/components.md +++ b/docs/components.md @@ -65,7 +65,7 @@ The component above could be called like this: ``` -## Rendering text, int, floats, arrays and null +## Rendering text, int, floats, arrays, lists, and null In order for the compiler to understand that rendering a string of text or a number is intentional, you need to explicitely write it: @@ -75,6 +75,7 @@ In order for the compiler to understand that rendering a string of text or a num {React.int(3)} {React.float(1.23)} {React.array([|
, |])} + {React.list([
, ])} {React.null}
``` diff --git a/dune-project b/dune-project index fbeb92d80..886d208cb 100644 --- a/dune-project +++ b/dune-project @@ -43,11 +43,11 @@ (ocaml-lsp-server :with-dev-setup) (opam-check-npm-deps (and - (= 1.0.0) + (= 3.0.1) :with-dev-setup)) (ocamlformat (and - (= 0.24.0) + (= 0.27.0) :with-dev-setup)))) (package @@ -64,5 +64,5 @@ (merlin :with-test) (ocamlformat (and - (= 0.24.0) + (= 0.27.0) :with-dev-setup)))) diff --git a/reason-react-ppx.opam b/reason-react-ppx.opam index e9f168131..8bbc1290c 100644 --- a/reason-react-ppx.opam +++ b/reason-react-ppx.opam @@ -19,7 +19,7 @@ depends: [ "reason" {>= "3.12.0"} "ppxlib" {>= "0.33.0"} "merlin" {with-test} - "ocamlformat" {= "0.24.0" & with-dev-setup} + "ocamlformat" {= "0.27.0" & with-dev-setup} "odoc" {with-doc} ] build: [ diff --git a/reason-react.opam b/reason-react.opam index e2329051c..1a8cc20d6 100644 --- a/reason-react.opam +++ b/reason-react.opam @@ -23,8 +23,8 @@ depends: [ "reason-react-ppx" {= version} "reason" {>= "3.12.0"} "ocaml-lsp-server" {with-dev-setup} - "opam-check-npm-deps" {= "1.0.0" & with-dev-setup} - "ocamlformat" {= "0.24.0" & with-dev-setup} + "opam-check-npm-deps" {= "3.0.1" & with-dev-setup} + "ocamlformat" {= "0.27.0" & with-dev-setup} "odoc" {with-doc} ] build: [ diff --git a/src/React.re b/src/React.re index 17a7f61b1..9c55d8f31 100644 --- a/src/React.re +++ b/src/React.re @@ -309,6 +309,7 @@ external float: float => element = "%identity"; external int: int => element = "%identity"; external string: string => element = "%identity"; external array: array(element) => element = "%identity"; +let list: list(element) => element = xs => xs |> Array.of_list |> array; /* this function exists to prepare for making `component` abstract */ external component: componentLike('props, element) => component('props) = diff --git a/src/React.rei b/src/React.rei index c7664b2ba..27bb710ad 100644 --- a/src/React.rei +++ b/src/React.rei @@ -7,6 +7,7 @@ external float: float => element = "%identity"; external int: int => element = "%identity"; external string: string => element = "%identity"; external array: array(element) => element = "%identity"; +let list: list(element) => element; /* this function exists to prepare for making `component` abstract */ external component: componentLike('props, element) => component('props) = @@ -565,7 +566,8 @@ module Uncurried: { }; [@mel.module "react"] -external startTransition: ([@mel.uncurry] (unit => unit)) => unit = "startTransition"; +external startTransition: ([@mel.uncurry] (unit => unit)) => unit = + "startTransition"; [@mel.module "react"] external useTransition: unit => (bool, callback(callback(unit, unit), unit)) = diff --git a/test/React__test.re b/test/React__test.re index 4bb4d9158..b9584cd9d 100644 --- a/test/React__test.re +++ b/test/React__test.re @@ -169,6 +169,39 @@ describe("React", () => { ->toBe(true); }); + test("can render list of elements", () => { + let container = getContainer(container); + let list = + [1, 2, 3] + ->List.map(item => { +
item->React.int
+ }); + let root = ReactDOM.Client.createRoot(container); + + act(() => {ReactDOM.Client.render(root,
list->React.list
)}); + + expect( + container + ->DOM.findBySelectorAndPartialTextContent("div", "1") + ->Option.isSome, + ) + ->toBe(true); + + expect( + container + ->DOM.findBySelectorAndPartialTextContent("div", "2") + ->Option.isSome, + ) + ->toBe(true); + + expect( + container + ->DOM.findBySelectorAndPartialTextContent("div", "3") + ->Option.isSome, + ) + ->toBe(true); + }); + test("can clone an element", () => { let container = getContainer(container); let root = ReactDOM.Client.createRoot(container);