From e068e342544f8b02841ec891cf293051748f980b Mon Sep 17 00:00:00 2001 From: Swrup Date: Thu, 11 Apr 2024 15:46:46 +0200 Subject: [PATCH] init --- .gitignore | 1 + .ocamlformat | 42 +++++++++++++++++ README.md | 3 ++ dune-project | 26 +++++++++++ examples/dune | 5 +++ examples/slider.ml | 32 +++++++++++++ lib/dune | 4 ++ lib/slippery_slidy.ml | 100 +++++++++++++++++++++++++++++++++++++++++ lib/slippery_slidy.mli | 36 +++++++++++++++ slippery_slidy.opam | 33 ++++++++++++++ 10 files changed, 282 insertions(+) create mode 100644 .gitignore create mode 100644 .ocamlformat create mode 100644 README.md create mode 100644 dune-project create mode 100644 examples/dune create mode 100644 examples/slider.ml create mode 100644 lib/dune create mode 100644 lib/slippery_slidy.ml create mode 100644 lib/slippery_slidy.mli create mode 100644 slippery_slidy.opam diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69fa449 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/.ocamlformat b/.ocamlformat new file mode 100644 index 0000000..74ae9c5 --- /dev/null +++ b/.ocamlformat @@ -0,0 +1,42 @@ +version=0.26.1 +assignment-operator=end-line +break-cases=fit +break-fun-decl=wrap +break-fun-sig=wrap +break-infix=wrap +break-infix-before-func=false +break-separators=before +break-sequences=true +cases-exp-indent=2 +cases-matching-exp-indent=normal +doc-comments=before +doc-comments-padding=2 +doc-comments-tag-only=default +dock-collection-brackets=false +exp-grouping=preserve +field-space=loose +if-then-else=compact +indicate-multiline-delimiters=space +indicate-nested-or-patterns=unsafe-no +infix-precedence=indent +leading-nested-match-parens=false +let-and=sparse +let-binding-spacing=compact +let-module=compact +margin=80 +max-indent=68 +module-item-spacing=sparse +ocp-indent-compat=false +parens-ite=false +parens-tuple=always +parse-docstrings=true +sequence-blank-line=preserve-one +sequence-style=terminator +single-case=compact +space-around-arrays=true +space-around-lists=true +space-around-records=true +space-around-variants=true +type-decl=sparse +wrap-comments=false +wrap-fun-args=true diff --git a/README.md b/README.md new file mode 100644 index 0000000..31bfe05 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# slippery_slidy + +js_of_ocmal + brr library to make slider diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..88902de --- /dev/null +++ b/dune-project @@ -0,0 +1,26 @@ +(lang dune 3.14) + +(name slippery_slidy) + +(generate_opam_files true) + +(source + (github username/reponame)) + +(authors "Author Name") + +(maintainers "Maintainer Name") + +(license LICENSE) + +(documentation https://url/to/documentation) + +(package + (name slippery_slidy) + (synopsis "A short synopsis") + (description "A longer description") + (depends ocaml dune js_of_ocaml brr) + (tags + (topics "to describe" your project))) + +; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project diff --git a/examples/dune b/examples/dune new file mode 100644 index 0000000..ffe3346 --- /dev/null +++ b/examples/dune @@ -0,0 +1,5 @@ +(executable + (name slider) + (modules slider) + (libraries js_of_ocaml brr slippery_slidy) + (modes js)) diff --git a/examples/slider.ml b/examples/slider.ml new file mode 100644 index 0000000..831f8c2 --- /dev/null +++ b/examples/slider.ml @@ -0,0 +1,32 @@ +(* This add a slidder to into
+ moving the slider print its value to the console *) +open Brr + +let append_el_to_main el = + let main = + match El.find_first_by_selector (Jstr.v "main") with + | Some main -> main + | None -> failwith "append_el_to_main: main element not found" + in + El.append_children main [ el ]; + () + +let () = + let datalist = + Slippery_slidy.mk_datalist + (List.map Jstr.of_float [ 2.; 3.; 5.; 8.; 13. ]) + "my-slider-datalist" + in + let slider = + Slippery_slidy.mk_slider ~min:0. ~max:100. ~step:Any ~value:50. + ~id:"my-slider" ~label:"Important slider, slide carefully" + ~datalist_id:(Some datalist.datalist_id) + in + append_el_to_main slider.slider_el; + (* don't forget to add datalist to document too! *) + append_el_to_main datalist.datalist_el; + + (* add listener on slider change *) + Slippery_slidy.add_slider_input_listener slider (fun x -> + Printf.printf "slider value: %f !!@." x ); + () diff --git a/lib/dune b/lib/dune new file mode 100644 index 0000000..2660ae3 --- /dev/null +++ b/lib/dune @@ -0,0 +1,4 @@ +(library + (name slippery_slidy) + (public_name slippery_slidy) + (libraries js_of_ocaml brr)) diff --git a/lib/slippery_slidy.ml b/lib/slippery_slidy.ml new file mode 100644 index 0000000..39c72d3 --- /dev/null +++ b/lib/slippery_slidy.ml @@ -0,0 +1,100 @@ +open Brr + +type datalist = + { datalist_id : string + ; datalist_el : El.t + } + +type slider = + { slider_id : string + ; slider_el : El.t + } + +(* Any is for continuous slider *) +type step_kind = + | Any + | Step_value of float + +let step_to_string step = + match step with Any -> "any" | Step_value f -> Float.to_string f + +let mk_datalist : Jstr.t list -> string -> datalist = + fun l id -> + let option_el_l = + List.map (fun s -> El.option ~d:G.document ~at:[ At.value s ] []) l + in + let datalist = + El.datalist ~d:G.document ~at:[ At.id (Jstr.v id) ] option_el_l + in + { datalist_id = id; datalist_el = datalist } + +(* make a div of class slippery-slidy-container containing a + slider of class slippery-slidy-slider *) +let mk_slider : + min:float + -> max:float + -> step:step_kind + -> value:float + -> id:string + -> label:string + -> datalist_id:string option + -> slider = + fun ~min ~max ~step ~value ~id ~label ~datalist_id -> + (* some checks *) + let b = min <= max && value <= max && value >= min in + if not b then + raise (Invalid_argument "mk_slider: parameters did not pass validation") + else + let datalist = + match datalist_id with + | None -> [] + | Some datalist_id -> [ At.v (Jstr.v "list") (Jstr.v datalist_id) ] + in + let input_el = + El.input ~d:G.document + ~at: + ( datalist + @ [ At.type' (Jstr.v "range") + ; At.float (Jstr.v "min") min + ; At.float (Jstr.v "max") max + ; At.v (Jstr.v "step") (Jstr.v (step_to_string step)) + ; At.value (Jstr.of_float value) + ; At.id (Jstr.v id) + ; At.class' (Jstr.v "slippery-slidy-slider") + ] ) + () + in + let label = + El.label ~d:G.document + ~at:[ At.for' (Jstr.v id) ] + [ El.txt' ~d:G.document label ] + in + let slider_container_el = + El.div ~d:G.document + ~at:[ At.class' (Jstr.v "slippery-slidy-container") ] + [ label; input_el ] + in + { slider_id = id; slider_el = slider_container_el } + +let add_slider_input_listener slider f = + (* we do not use Ev.input because it makes a Ev.Input.t but: + "For