let search s xs = if s == "" then [| |] else let results = Js.Array.filter (Js.String.includes s) xs in if Js.Array.length results == 1 && results.(0) == s then [| |] else results let render_completion on_select entries = H.div [| HA.class_ "g-Autocomplete__Completion" |] (entries |> Js.Array.map (fun c -> H.button [| HA.class_ "g-Autocomplete__Entry" ; HA.type_ "button" ; HE.on_click (fun _ -> on_select c) |] [| H.text c |])) let create id label values on_input attrs = let completion = H.div [| |] [| |] in let update_completion target value = let entries = search value values in Element.mount_on completion (render_completion (fun selected -> let () = Element.set_value target selected in let () = Element.remove_children completion in on_input selected) entries) in H.div [| HA.class_ "g-Autocomplete" |] [| H.div [| HA.class_ "g-Form__Label" |] [| H.label [| HA.for_ id |] [| H.text label |] |] ; H.input (Js.Array.concat [| HA.id id ; HA.class_ "g-Autocomplete__Input" ; HA.autocomplete "off" ; HE.on_click (fun e -> let target = Event.target e in let value = Element.value target in update_completion target value) ; HE.on_input (fun e -> let target = Event.target e in let value = Element.value target in let () = update_completion target value in on_input value) |] attrs) [| |] ; completion |]