aboutsummaryrefslogtreecommitdiff
path: root/lib/elements/input.ml
blob: 5def7d4deaffefa0afbeeb9fcaf822a6019a7705 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
open Brr
open Brr_note
open Note

(** Create a slider element, and a signal with the value. 

 [at] is the attribute list given to the element *)
let slider : at:Brr.At.t list -> Brr.El.t * float S.t =
 fun ~at ->
  let slider = El.input ~at () in

  let init_value = Jstr.to_float (El.prop El.Prop.value slider) in

  let event =
    Evr.on_el
      Ev.input
      (fun _ ->
        let raw_value = El.prop El.Prop.value slider in
        Jstr.to_float raw_value )
      slider
    |> S.hold init_value
  in
  (slider, event)


type file =
  { file : File.t
  ; content : Jstr.t
  }

(** Read the content from the file *)
let file_loader : file Note.E.send -> File.t -> unit =
 fun event file ->
  let blob = File.as_blob file in
  Fut.await
    (Blob.text blob)
    (Result.iter (fun content -> event { file; content }))


(** Create an imput which load a file.

    [file_loader (Jstr.v ".json"] will create an input which only accept json
    files, and an event which gives access to the file.

*)
let file_loader : Jstr.t -> Brr.El.t * file Note.event =
 fun selector ->
  let add_file_event, add_file_sender = Note.E.create () in

  let i =
    El.input
      ()
      ~at:[ At.type' (Jstr.v "file"); (At.v (Jstr.v "accept")) selector ]
  in

  (* The event return a list of files.

     We are only interested by a single on, and keep only the first from the
     list. *)
  let on_change files = file_loader add_file_sender (List.hd files) in

  Ev.listen Ev.change (fun _e -> on_change (El.Input.files i)) (El.as_target i);

  (i, add_file_event)