Skip to content

Commit

Permalink
Merge branch 'main' of github.com:ml-in-barcelona/server-reason-react
Browse files Browse the repository at this point in the history
* 'main' of github.com:ml-in-barcelona/server-reason-react:
  Make React.Children.* APIs work as expected (#130)
  • Loading branch information
davesnx committed Apr 24, 2024
2 parents ab1411d + 124c0f7 commit 2cf3242
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 21 deletions.
48 changes: 39 additions & 9 deletions packages/react/src/React.ml
Original file line number Diff line number Diff line change
Expand Up @@ -601,15 +601,45 @@ let useLayoutEffect5 _ _ = ()
let useLayoutEffect6 _ _ = ()

module Children = struct
let map fn elements = Array.map fn elements
let mapWithIndex fn elements = Array.mapi fn elements
let forEach fn elements = Array.iter fn elements
let forEachWithIndex fn elements = Array.iteri fn elements
let count elements = Array.length elements

let only elements =
if Array.length elements >= 1 then Array.get elements 0
else raise (Invalid_argument "Expected at least one child")
let map element fn =
match element with
| List children -> Array.map fn children |> Array.to_list |> list
| _ -> fn element

let mapWithIndex element fn =
match element with
| List children ->
Array.mapi (fun index element -> fn element index) children
|> Array.to_list |> list
| _ -> fn element 0

let forEach element fn =
match element with
| List children -> Array.iter fn children
| _ ->
let _ = fn element in
()

let forEachWithIndex element fn =
match element with
| List children ->
Array.iteri (fun index element -> fn element index) children
| _ ->
let _ = fn element 0 in
()

let count element =
match element with
| List children -> Array.length children
| Empty -> 0
| _ -> 1

let only element =
match element with
| List children ->
if Array.length children >= 1 then Array.get children 0
else raise (Invalid_argument "Expected at least one child")
| _ -> element

let toArray element = [| element |]
end
Expand Down
15 changes: 6 additions & 9 deletions packages/react/src/React.mli
Original file line number Diff line number Diff line change
Expand Up @@ -708,15 +708,12 @@ val useLayoutEffect6 :
val setDisplayName : 'component -> string -> unit

module Children : sig
val map : (element -> element) -> element array -> element array

val mapWithIndex :
(int -> element -> element) -> element array -> element array

val forEach : (element -> unit) -> element array -> unit
val forEachWithIndex : (int -> element -> unit) -> element array -> unit
val count : element array -> int
val only : element array -> element
val map : element -> (element -> element) -> element
val mapWithIndex : element -> (element -> int -> element) -> element
val forEach : element -> (element -> unit) -> unit
val forEachWithIndex : element -> (element -> int -> unit) -> unit
val count : element -> int
val only : element -> element
val toArray : element -> element array
end

Expand Down
38 changes: 35 additions & 3 deletions packages/react/test/test_react.ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
let test title fn = Alcotest.test_case title `Quick fn

let assert_string left right =
Alcotest.check Alcotest.string "should be equal" right left

Expand All @@ -24,11 +26,41 @@ let use_effect_doesnt_fire () =
in
assert_string (ReactDOM.renderToStaticMarkup app) "<div>foo</div>"

let case title fn = Alcotest.test_case title `Quick fn
module Gap = struct
let make ~children =
React.Children.map children (fun element ->
if element = React.null then React.null
else
React.createElement "div"
[ React.JSX.String ("class", "divider") ]
[ element ])
end

let children_map_one_element () =
let app =
React.Upper_case_component
(fun () -> Gap.make ~children:(React.string "foo"))
in
assert_string
(ReactDOM.renderToStaticMarkup app)
"<div class=\"divider\">foo</div>"

let children_map_list_element () =
let app =
React.Upper_case_component
(fun () ->
Gap.make
~children:(React.list [ React.string "foo"; React.string "lola" ]))
in
assert_string
(ReactDOM.renderToStaticMarkup app)
"<div class=\"divider\">foo</div><div class=\"divider\">lola</div>"

let tests =
( "React",
[
case "useState" use_state_doesnt_fire;
case "useEffect" use_effect_doesnt_fire;
test "useState" use_state_doesnt_fire;
test "useEffect" use_effect_doesnt_fire;
test "Children.map" children_map_one_element;
test "Children.map" children_map_list_element;
] )

0 comments on commit 2cf3242

Please sign in to comment.