let-def / lwd Goto Github PK
View Code? Open in Web Editor NEWLightweight document
License: MIT License
Lightweight document
License: MIT License
Hi,
First off, thanks a lot for your work on Lwd! I started porting a JS app to it yesterday and I'm really impressed by the elegance of the API!
I've encountered an issue with the rendering of SVG elements.
While inspecting the generated HTML, the code looks good, but the SVG is not displayed.
I've pushed a small repro here: https://github.com/tmattio/lwd-svg-repro/blob/main/lib/app.ml.
Let me know if there's anything I can do to help debug that ๐
With Notty it is possible to check for mouse events and modifier keys together. For example shift scrolling. This doesn't appear to be possible in nottui.
Here are some things I think would be convenient for a lot of UIs. I can contribute some of them if needed :).
I also think that Nottui_widget
should just be a module in nottui
, there's not much point having one without the other imho.
join_x_list
( reexpose Nottui.Ui.hcat
?)pack_x_list
(on lists of ui Lwd.t
, more convenient than manually using the monoid)<ul> <li>โฆ</li><li>โฆ
)\ | / -
animation, or something)Hi, I was trying out the Brr backend and had a couple of questions.
let ui =
let count = Lwd.var 0 in
let on_click () = Lwd.set count (Lwd.peek count + 1) in
let button =
Lwd.map
~f:(fun i ->
let btn = El.button [El.txt' (string_of_int i)] in
Ev.listen Ev.click (fun _e -> on_click ()) (El.as_target btn);
btn)
(Lwd.get count)
in
Elwd.div [`R button]
The rest of the file is the same as in the Brr example. If I replace the last line with button
, the button no longer updates.
Anyway, I really like Lwd so far, awesome work!
Trying to run either the button or tree example gives a type error when trying to build. I'm not sure if it's something with dune or the package (possible version conflicts with dune?) but the hello world example ran, but none of the UI components seemed to work and caused type errors.
button sample code error ->
dune build
File "tui.ml", line 10, characters 13-20:
10 | Ui_loop.run (Lwd.map button (Lwd.get vcount));;
^^^^^^^
Error (warning 6 [labels-omitted]): label f was omitted in the
application of this function.
File "tui.ml", line 10, characters 21-27:
10 | Ui_loop.run (Lwd.map button (Lwd.get vcount));;
^^^^^^
Error: This expression has type int -> ui
but an expression was expected of type 'a Lwd.t
code
open Nottui;;
module W = Nottui_widgets;;
let vcount = Lwd.var 0;;
let button count =
W.button (Printf.sprintf "Clicked %d times!" count)
(fun () -> Lwd.set vcount (count + 1));;
Ui_loop.run (Lwd.map button (Lwd.get vcount));;
dune
(executable
(name tui)
(libraries base nottui))
dune-project
(lang dune 2.9)
(name tui)
Contrary to Notty.I.zcat the order of composition for Ui.zcat appears to be reversed.
Nottui.Ui_loop.run
could provide an easy way to combine the default behavior ("quit on escape") with custom behavior (like a quit button).
For that I think it could take an optional bool Lwd.var
instead of a bool Lwd.t
, and add the escape behavior on top of that?
Currently, it's not possible to do a Notty_unix.Term.cursor
(just after a Term.image
) via nottui
. It will be nice to have the ability to fill a value with which position we want for the cursor. Like Nottui.move_cursor
.
It's common to have a Lwd.map
node that performs side effects and always return the same value. This constant document must be integrated in bigger documents to receive updates but might cause unecessary computations.
let constant_document =
let$ some_document in
do_side_effect some_document;
()
let main =
let$ () = constant_document in
costly_operation
In this example, do_side_effect
might interact with the DOM and costly_operation
might wrap many of such constant documents into a sequence used as the children elements in the DOM, which will be fully evaluated every time.
Could these unnecessary computations be avoided by adding a "short circuit" node in the document ?
For example:
let constant_document =
Lwd.reuse_map some_document ~cmp:(=) ~f:do_side_effect
How does one create a scroll area that will stop scrolling down when there's no more widgets to display? Perhaps the answer is to use vscroll_area? But I don't understand this function
When trying to fix a scrolling-related bug, I found that sensors don't work:
type sensor_state = {x : int; y : int; w : int; h : int; count : int}
let sensor_text () =
let state_var = Lwd.var {x = 0; y = 0; w = 0; h = 0; count = 0} in
let widget state =
Nottui_widgets.printf ~attr:Notty.A.(bg white ++ fg black) "(%d, %d, %d, %d) updated %d times" state.x state.y state.w state.h state.count
|> Nottui.Ui.permanent_sensor (fun ~x ~y ~w ~h () ->
Lwd.set state_var {x; y; w; h; count = succ state.count}
)
in
Lwd.map ~f:widget (Lwd.get state_var)
let () =
let midpane = Nottui_widgets.v_pane (sensor_text ()) (sensor_text ()) in
let rightpane = Nottui_widgets.h_pane midpane (sensor_text ()) in
let root = Nottui_widgets.hbox [sensor_text (); rightpane] in
Nottui.Ui_loop.run root
No matter what I resize (splits or terminal) I get something vaguely like this:
(0, 0, 0, 0) updated 0 times(0, 0, 0, 0) updated 0 t (0, 0, 0, 0) updated 0 times
(0, 0, 0, 0) updated 0 t
Using LWD installed from source at commit 3bfeca4d37560f8778610c51d60d2d1aedfa519d
Hi @let-def :))
Thanks for lwd! I've been using the brr-lwd backend on a few projects and have really enjoyed using it. I was wondering if it might be released soon? Anything I can do to help with that?
I used it in this toplevel for Irmin and also this little application for looking at Northern Irish forest data.
make the widgets into a submodule of Ui
? seems a bit useless to have Ui
without a collection of standard widgets imho ๐
Nottui
(easily aliasable/openable). I'll refer to it as UI
from now on.Lwd
as UI.Incremental
and Lwd_seq
as UI.Seq
UI.Syntax
with let$
and other bind/map from Lwd
, along with UI helpers like <|>
or <->
for h/v concatenation of UI elementsUI.t = UI.Pure.t Lwd.t
would make a lot of sense (where UI.Pure.t
can be the base type for non-reactive elements). Most functions will work on lwd-wrapped things.UI
, for example UI.s
for a string widget, UI.space
, UI.sprintf
, hcat
(list), hjoin
(binary horizontal concat), <|>
(alias for hcat)UI.Scrollable
for the whole thing, along with a UI.scrollable : โฆ
function for the common case)pretty
as UI.Pretty
(can be just a module alias for lightweightness)flex
needs more testing (but would be useful to keep)scrollable
currently doesn't take as much space as it can, so only the used part is actually scrollablealso see #5 for a bigger wishlist ๐ด ๐ ๐
The reducer seems to reuse old values, perhaps using physical equality on the elements of the sequence ?
It could be useful to pass a custom equality function and to define some guarantees about which values are reused.
I don't know which guarantees would be useful but I think it should be possible to avoid the lwd_to_remove
marking step in tyxml-lwd's DOM update.
This trick cannot be used in a library where it's not possible to store new state on elements.
Reusing old values in a smart way should be able to avoid false-positives when listing dropped elements.
An element that moves would be removed then added again but this could be optimised an other way.
I noticed that in the code below, if I swap Lwd_seq.bind
with Lwd_seq.lift
, the whole sequence become dropped on every updates.
This might be because physical equality is lost when it wraps every elements of the sequence into a freshly allocated Lwd_seq.element
. In the bind
case, the sequence nodes are allocated once and shared (allocated outside of the document).
let$ childs = Lwd_seq.bind childs Fun.id in
let dropped, r = R.update_and_get_dropped !reducer childs in
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.