Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
v0.4 - Alpha 0.4 UNRELEASED
v0.5 - Alpha 0.5 UNRELEASED
======

- brr-lwd: Fix handling of multiple reactive attributes (by @panglesd, #53)
- brr-lwd: Add support for reactive styles and properties (by @panglesd, #60)

v0.4 - Alpha 0.4
======

- Add Lwd.update (by @OlivierNicole and @Julow) and Lwd.may_update functions
- Lwd.set: change binding before invalidation, otherwise the old value could be re-observed (reported by @voodoos)
- brr-lwd: support declarative events and set of css classes
- Nottui: fix treatment of some terminal events that were delayed because of improper buffer flushing, reported by @darrenldl
- Introduce Nottui_unix: move platform-specific code of Nottui to a separate library (by @Dinosaure and @Reynir, #44, #51)

v0.3 - Alpha 0.3
======
Expand Down
9 changes: 9 additions & 0 deletions examples/reactive-props-brr/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ROOT=$(realpath $(PWD)/../..)
NAME=$(subst $(ROOT)/,,$(realpath $(PWD)))

all:
dune build index.html main.js
@echo "open $(ROOT)/_build/default/$(NAME)/index.html"

clean:
dune clean
21 changes: 21 additions & 0 deletions examples/reactive-props-brr/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(executables
(names main)
(libraries js_of_ocaml brr lwd brr-lwd)
(modes byte))

(rule
(targets main.js)
(action
(run
%{bin:js_of_ocaml}
--noruntime
%{lib:js_of_ocaml-compiler:runtime.js}
--source-map
%{dep:main.bc}
-o
%{targets}
--pretty)))

(alias
(name default)
(deps main.js index.html))
10 changes: 10 additions & 0 deletions examples/reactive-props-brr/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<title>Reactive props</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="main.js"></script>
</head>
<body>
</body>
</html>
76 changes: 76 additions & 0 deletions examples/reactive-props-brr/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
open Brr
open Brr_lwd
open Lwd_infix

(* A string input, whose value is synced with the given var *)
let string var =
let h =
fun ev ->
let el = ev |> Brr.Ev.target |> Brr.Ev.target_to_jv in
let new_value = Jv.get el "value" |> Jv.to_string in
Brr.Console.(log [ new_value ]);
Lwd.set var new_value
in
let ev = [ `P (Brr_lwd.Elwd.handler Brr.Ev.input h) ] in
let at =
let value =
let$ v = Lwd.get var in
Brr.At.value (Jstr.of_string v)
in
[ `R value; `P (Brr.At.type' (Jstr.v "text")) ]
in
Brr_lwd.Elwd.input ~at ~ev ()

(* A checkbox, whose checked prop is synced the reactive [check s] *)
let checkbox s check description =
let checked =
let$ s = s in
Elwd.P (El.Prop.checked, check s)
in
let checkbox_el =
Elwd.input
~at:[ `P (At.type' (Jstr.v "checkbox")) ]
~st:[ `P (Jstr.v "pointer-events", Jstr.v "none") ]
~pr:[ `R checked ] ()
in
Elwd.div [ `R checkbox_el; `P (El.txt' description) ]

(* A string input, and checks whether it's long enough, contains uppercase,
contains numbers *)
let ui =
let s = Lwd.var "" in
let string_input = string s in
let s = Lwd.get s in
let checkbox_length =
let check s = String.length s >= 5 in
checkbox s check "Has length at least 5"
in
let checkbox_uppercase =
let check s = String.exists (function 'A' .. 'Z' -> true | _ -> false) s in
checkbox s check "Has uppercase"
in
let checkbox_numbers =
let check s = String.exists (function '0' .. '9' -> true | _ -> false) s in
checkbox s check "Has numbers"
in
Elwd.div [ `R string_input ; `R checkbox_length ; `R checkbox_numbers ; `R checkbox_uppercase ]

(* Injection of reactive element to the DOM *)
let () =
let ui = Lwd.observe ui in
let on_invalidate _ =
Console.(log [ str "on invalidate" ]);
let _ : int =
G.request_animation_frame @@ fun _ ->
let _ui = Lwd.quick_sample ui in
()
in
()
in
let on_load _ =
Console.(log [ str "onload" ]);
El.append_children (Document.body G.document) [ Lwd.quick_sample ui ];
Lwd.set_on_invalidate ui on_invalidate
in
ignore (Ev.listen Ev.dom_content_loaded on_load (Window.as_target G.window));
()
9 changes: 9 additions & 0 deletions examples/reactive-styles-brr/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ROOT=$(realpath $(PWD)/../..)
NAME=$(subst $(ROOT)/,,$(realpath $(PWD)))

all:
dune build index.html main.js
@echo "open $(ROOT)/_build/default/$(NAME)/index.html"

clean:
dune clean
21 changes: 21 additions & 0 deletions examples/reactive-styles-brr/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(executables
(names main)
(libraries js_of_ocaml brr lwd brr-lwd)
(modes byte))

(rule
(targets main.js)
(action
(run
%{bin:js_of_ocaml}
--noruntime
%{lib:js_of_ocaml-compiler:runtime.js}
--source-map
%{dep:main.bc}
-o
%{targets}
--pretty)))

(alias
(name default)
(deps main.js index.html))
10 changes: 10 additions & 0 deletions examples/reactive-styles-brr/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<title>Reactive styles</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="main.js"></script>
</head>
<body>
</body>
</html>
84 changes: 84 additions & 0 deletions examples/reactive-styles-brr/main.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
open Brr
open Brr_lwd
open Lwd_infix

(* A float input, whose value is synced with the given var *)
let float var =
let h =
fun ev ->
let el = ev |> Brr.Ev.target |> Brr.Ev.target_to_jv in
let new_value = Jv.get el "value" |> Jv.to_string |> float_of_string in
Brr.Console.(log [ new_value ]);
Lwd.set var new_value
in
let ev = [ `P (Brr_lwd.Elwd.handler Brr.Ev.input h) ] in
let at =
let v =
let$ v = Lwd.get var in
Brr.At.value (Jstr.of_float v)
in
[ `R v; `P (Brr.At.type' (Jstr.v "number")) ]
in
Brr_lwd.Elwd.input ~at ~ev ()

(* Two float input (x and y), and a square whose absolute position is given by x
and y *)
let ui =
let top = Lwd.var 1.0 in
let set_top = float top in
let left = Lwd.var 1.0 in
let set_left = float left in
let block =
let top =
let$ top = Lwd.get top in
let top = Jstr.append (Jstr.of_float top) (Jstr.v "px") in
(El.Style.top, top)
in
let left =
let$ left = Lwd.get left in
let left = Jstr.append (Jstr.of_float left) (Jstr.v "px") in
(El.Style.left, left)
in
let st =
[
`R top;
`R left;
`P (El.Style.width, Jstr.v "50px");
`P (El.Style.height, Jstr.v "50px");
`P (El.Style.position, Jstr.v "absolute");
`P (El.Style.background_color, Jstr.v "red");
]
in
Elwd.div ~st []
in
let playground =
Elwd.div
~st:
[
`P (El.Style.width, Jstr.v "1000px");
`P (El.Style.height, Jstr.v "1000px");
`P (El.Style.position, Jstr.v "relative");
]
[ `R block ]
in
Elwd.div [ `R set_top; `R set_left; `R playground ]

(* Injection of reactive element to the DOM *)
let () =
let ui = Lwd.observe ui in
let on_invalidate _ =
Console.(log [ str "on invalidate" ]);
let _ : int =
G.request_animation_frame @@ fun _ ->
let _ui = Lwd.quick_sample ui in
()
in
()
in
let on_load _ =
Console.(log [ str "onload" ]);
El.append_children (Document.body G.document) [ Lwd.quick_sample ui ];
Lwd.set_on_invalidate ui on_invalidate
in
ignore (Ev.listen Ev.dom_content_loaded on_load (Window.as_target G.window));
()
Loading