init
This commit is contained in:
commit
e068e34254
10 changed files with 282 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
_build/
|
||||||
42
.ocamlformat
Normal file
42
.ocamlformat
Normal file
|
|
@ -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
|
||||||
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# slippery_slidy
|
||||||
|
|
||||||
|
js_of_ocmal + brr library to make slider
|
||||||
26
dune-project
Normal file
26
dune-project
Normal file
|
|
@ -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
|
||||||
5
examples/dune
Normal file
5
examples/dune
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
(executable
|
||||||
|
(name slider)
|
||||||
|
(modules slider)
|
||||||
|
(libraries js_of_ocaml brr slippery_slidy)
|
||||||
|
(modes js))
|
||||||
32
examples/slider.ml
Normal file
32
examples/slider.ml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
(* This add a slidder to into <main>
|
||||||
|
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 );
|
||||||
|
()
|
||||||
4
lib/dune
Normal file
4
lib/dune
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
(library
|
||||||
|
(name slippery_slidy)
|
||||||
|
(public_name slippery_slidy)
|
||||||
|
(libraries js_of_ocaml brr))
|
||||||
100
lib/slippery_slidy.ml
Normal file
100
lib/slippery_slidy.ml
Normal file
|
|
@ -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 <textarea> and <input> elements that accept
|
||||||
|
text input (type=text, type=tel, etc.), the interface is InputEvent;
|
||||||
|
for others, the interface is Event."
|
||||||
|
|
||||||
|
passing the El.t to the handler to avoid using Obj.magic to get "evt.target"
|
||||||
|
and directly doing "el.value" in the handler does not work for some reason
|
||||||
|
(we get a value="") *)
|
||||||
|
let handler evt =
|
||||||
|
(* here evt is a "Event" not a "EventInput"
|
||||||
|
no need to take Ev.as_type *)
|
||||||
|
let evt : Jv.t = Obj.magic evt in
|
||||||
|
let target : Jv.t = Jv.get evt "target" in
|
||||||
|
let value : Jv.t = Jv.get target "value" in
|
||||||
|
let x = float_of_string (Jv.to_string value) in
|
||||||
|
f x
|
||||||
|
in
|
||||||
|
let target = El.as_target slider.slider_el in
|
||||||
|
let input_ev = Ev.Type.create (Jstr.v "input") in
|
||||||
|
let _ : Ev.listener = Ev.listen input_ev handler target in
|
||||||
|
()
|
||||||
36
lib/slippery_slidy.mli
Normal file
36
lib/slippery_slidy.mli
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
val step_to_string : step_kind -> string
|
||||||
|
|
||||||
|
val mk_datalist : Jstr.t list -> string -> datalist
|
||||||
|
|
||||||
|
(** make a div of class "slippery-slidy-container" containing a slider of class
|
||||||
|
"slippery-slidy-slider" wi id [id]
|
||||||
|
|
||||||
|
don't forget to add your slider and datalist to your document *)
|
||||||
|
val mk_slider :
|
||||||
|
min:float
|
||||||
|
-> max:float
|
||||||
|
-> step:step_kind
|
||||||
|
-> value:float
|
||||||
|
-> id:string
|
||||||
|
-> label:string
|
||||||
|
-> datalist_id:string option
|
||||||
|
-> slider
|
||||||
|
|
||||||
|
val add_slider_input_listener : slider -> (float -> unit) -> unit
|
||||||
33
slippery_slidy.opam
Normal file
33
slippery_slidy.opam
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
# This file is generated by dune, edit dune-project instead
|
||||||
|
opam-version: "2.0"
|
||||||
|
synopsis: "A short synopsis"
|
||||||
|
description: "A longer description"
|
||||||
|
maintainer: ["Maintainer Name"]
|
||||||
|
authors: ["Author Name"]
|
||||||
|
license: "LICENSE"
|
||||||
|
tags: ["topics" "to describe" "your" "project"]
|
||||||
|
homepage: "https://github.com/username/reponame"
|
||||||
|
doc: "https://url/to/documentation"
|
||||||
|
bug-reports: "https://github.com/username/reponame/issues"
|
||||||
|
depends: [
|
||||||
|
"ocaml"
|
||||||
|
"dune" {>= "3.14"}
|
||||||
|
"js_of_ocaml"
|
||||||
|
"brr"
|
||||||
|
"odoc" {with-doc}
|
||||||
|
]
|
||||||
|
build: [
|
||||||
|
["dune" "subst"] {dev}
|
||||||
|
[
|
||||||
|
"dune"
|
||||||
|
"build"
|
||||||
|
"-p"
|
||||||
|
name
|
||||||
|
"-j"
|
||||||
|
jobs
|
||||||
|
"@install"
|
||||||
|
"@runtest" {with-test}
|
||||||
|
"@doc" {with-doc}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
dev-repo: "git+https://github.com/username/reponame.git"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue