let search s xs = Js.Array.filter (Js.String.includes s) xs let render_completion render_entry on_select entries = H.div [| HA.class_ "g-Autocomplete__Completion" |] (entries |> Js.Array.map (fun c -> Button.raw [| HA.class_ "g-Autocomplete__Entry" ; HA.type_ "button" ; HE.on_click (fun e -> let () = Event.stop_propagation e in let () = Event.prevent_default e in on_select c) |] (render_entry c))) let create attrs id values render_entry on_input = let completion = H.div [| |] [| |] in let update_completion target value = let entries = search value values in Element.mount_on completion (render_completion render_entry (fun selected -> let () = Element.set_value target selected in let () = Element.remove_children completion in on_input selected) entries) in let hide_completion () = Element.mount_on completion (H.text "") in let input = H.input (HA.concat attrs [| HA.id id ; HA.class_ "g-Autocomplete__Input" ; HA.autocomplete "off" ; HE.on_focus (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) |]) [| |] in let () = Element.add_event_listener input "blur" (fun e -> if Js.isNullable (Event.related_target e) then hide_completion ()) in H.div [| HA.class_ "g-Autocomplete" |] [| input ; completion ; Button.raw [| HA.class_ "g-Autocomplete__Clear fa fa-close" ; HA.type_ "button" ; HE.on_click (fun _ -> let () = on_input "" in let () = Element.set_value input "" in Element.focus input) |] [| |] |]