Skip to content

Autocomplete

A select whose popover filters its list by a search field, HeroUI's on Kobalte's combo box.

Solidtype_heroui.Autocomplete is a select whose popover holds a search field that filters its list, on Kobalte’s Combobox, with the classes HeroUI’s own autocompleteVariants gives. Its search is the Search_field inside its Autocomplete.Filter, and its list the List_box beside it, as in HeroUI; Label, Description and Field_error inside it name, describe and qualify it.

HeroUI’s example draws the states chosen as tags, with a TagGroup, which is not ported yet; here they are listed as the value draws them.

States to Visit
Select states
autocomplete_usage.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<Autocomplete
class_="w-[256px]" placeholder="Select states" selection_mode=`multiple>
<Label>"States to Visit"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value /> <Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search options" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)
selection_mode=`multiple>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
<Autocomplete>
<Label>...</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Description>...</Description>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input />
</Search_field.Group>
</Search_field>
<List_box>
<List_box.Item id="...">...</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>

Single Select Variants

Primary variant
Select one
Secondary variant
Select one

Multiple Select Variants

Primary variant
Select options
Secondary variant
Select options
autocomplete_variants.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let items =
[|
("option1", "Option 1");
("option2", "Option 2");
("option3", "Option 3");
("option4", "Option 4");
|]
let variant ~label ~variant ~mode =
let selected, set_selected = S.create_signal [||] in
<Autocomplete
class_="w-[256px]"
placeholder=(fun () ->
match mode with
| `single -> "Select one"
| `multiple -> "Select options")
selection_mode=(fun () -> mode)
value=(fun () -> S.get selected)
variant=(fun () -> variant)
on_change=(S.set set_selected)>
<Label>(fun () -> Jsx.string label)</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search options" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)
selection_mode=(fun () -> (mode :> List_box.selection_mode))>
<Solidtype.For each=(fun () -> items)>
(fun (id, name) _ ->
<List_box.Item id=(fun () -> id) text_value=(fun () -> name)>
(fun () -> Jsx.string name) <List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
let make () =
<div class_="flex flex-col gap-8">
<div class_="flex flex-col gap-4">
<h3 class_="text-lg font-semibold">"Single Select Variants"</h3>
<div class_="flex flex-col gap-4">
(fun () ->
Jsx.element
(variant ~label:"Primary variant" ~variant:`primary ~mode:`single))
(fun () ->
Jsx.element
(variant ~label:"Secondary variant" ~variant:`secondary
~mode:`single))
</div>
</div>
<div class_="flex flex-col gap-4">
<h3 class_="text-lg font-semibold">"Multiple Select Variants"</h3>
<div class_="flex flex-col gap-4">
(fun () ->
Jsx.element
(variant ~label:"Primary variant" ~variant:`primary ~mode:`multiple))
(fun () ->
Jsx.element
(variant ~label:"Secondary variant" ~variant:`secondary
~mode:`multiple))
</div>
</div>
</div>
State
Select one
autocomplete_full_width.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<div class_="w-[400px] space-y-4">
<Autocomplete full_width=true placeholder="Select one" variant=`secondary>
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
</div>
State
Select one
Select your state of residence
autocomplete_with_description.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
module Description = Solidtype_heroui.Description
let make () =
<Autocomplete class_="w-[256px]" placeholder="Select one">
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Description>"Select your state of residence"</Description>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>

HeroUI’s required autocomplete is checked by the browser as its form is submitted. A Form here checks nothing itself, as with a text field: the example says the autocomplete is invalid once a submit finds it empty.

State
Select one
autocomplete_required.mlx
module S = Solidtype.Solid
module Autocomplete = Solidtype_heroui.Autocomplete
module Button = Solidtype_heroui.Button
module Empty_state = Solidtype_heroui.Empty_state
module Field_error = Solidtype_heroui.Field_error
module Form = Solidtype_heroui.Form
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
external prevent_default : Dom.event -> unit = "preventDefault" [@@mel.send]
external alert : string -> unit = "alert" [@@mel.scope "window"]
let make () =
let state, set_state = S.create_signal [||] in
(* A required autocomplete shows its error once a submit has been tried, as
the browser's validation React Aria reads does. *)
let tried, set_tried = S.create_signal false in
let missing () = S.get tried && Array.length (S.get state) = 0 in
<Form
class_="flex w-[256px] flex-col gap-4"
on_submit=(fun e ->
prevent_default e;
S.set set_tried true;
if Array.length (S.get state) > 0 then
alert "Form submitted successfully!")>
<Autocomplete
is_required=true
is_invalid=(fun () -> missing ())
class_="w-full"
name="state"
placeholder="Select one"
on_change=(S.set set_state)>
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
<Field_error>"Please select an item in the list."</Field_error>
</Autocomplete>
<Button type_=`submit>"Submit"</Button>
</Form>
State
autocomplete_disabled.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<Autocomplete
is_disabled=true
class_="w-[256px]"
default_value=(fun () -> [| "california" |])
placeholder="Select one">
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
Animal
Select an animal
autocomplete_with_disabled_options.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<Autocomplete
class_="w-[256px]"
disabled_keys=(fun () -> [| "cat"; "kangaroo" |])
placeholder="Select an animal">
<Label>"Animal"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search animals" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search animals..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="dog" text_value="Dog">
"Dog" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="cat" text_value="Cat">
"Cat" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="bird" text_value="Bird">
"Bird" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="kangaroo" text_value="Kangaroo">
"Kangaroo" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="elephant" text_value="Elephant">
"Elephant" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="tiger" text_value="Tiger">
"Tiger" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
State
Select one
autocomplete_allows_empty_collection.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<Autocomplete
allows_empty_collection=true class_="w-[256px]" placeholder="Select one">
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)
/>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
Country
Select a country
autocomplete_with_sections.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
module Header = Solidtype_heroui.Header
module Separator = Solidtype_heroui.Separator
let make () =
<Autocomplete class_="w-[256px]" placeholder="Select a country">
<Label>"Country"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search countries" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search countries..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Section>
<Header>"North America"</Header>
<List_box.Item id="usa" text_value="United States">
"United States" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="canada" text_value="Canada">
"Canada" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="mexico" text_value="Mexico">
"Mexico" <List_box.Item_indicator />
</List_box.Item>
</List_box.Section>
<Separator />
<List_box.Section>
<Header>"Europe"</Header>
<List_box.Item id="uk" text_value="United Kingdom">
"United Kingdom" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="france" text_value="France">
"France" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="germany" text_value="Germany">
"Germany" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="spain" text_value="Spain">
"Spain" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="italy" text_value="Italy">
"Italy" <List_box.Item_indicator />
</List_box.Item>
</List_box.Section>
<Separator />
<List_box.Section>
<Header>"Asia"</Header>
<List_box.Item id="japan" text_value="Japan">
"Japan" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="china" text_value="China">
"China" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="india" text_value="India">
"India" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="south-korea" text_value="South Korea">
"South Korea" <List_box.Item_indicator />
</List_box.Item>
</List_box.Section>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
States
Select states
autocomplete_multiple_select.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<Autocomplete
class_="w-[256px]" placeholder="Select states" selection_mode=`multiple>
<Label>"States"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search options" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)
selection_mode=`multiple>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>

The ids chosen are value, an array, as a select’s are.

State (controlled)

Selected: California

autocomplete_controlled.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let states =
[|
("california", "California");
("texas", "Texas");
("florida", "Florida");
("new-york", "New York");
("illinois", "Illinois");
("pennsylvania", "Pennsylvania");
|]
let make () =
let state, set_state = S.create_signal [| "california" |] in
let name () =
match S.get state with
| [| key |] -> (
match Array.find_opt (fun (id, _) -> String.equal id key) states with
| Some (_, name) -> name
| None -> "None")
| _ -> "None"
in
<div class_="space-y-4">
<Autocomplete
class_="w-[256px]"
placeholder="Select a state"
value=(fun () -> S.get state)
on_change=(S.set set_state)>
<Label>"State (controlled)"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<Solidtype.For each=(fun () -> states)>
(fun (id, name) _ ->
<List_box.Item id=(fun () -> id) text_value=(fun () -> name)>
(fun () -> Jsx.string name) <List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
<p class_="text-sm text-muted">
(fun () -> Jsx.string ("Selected: " ^ name ()))
</p>
</div>
States (controlled multiple)

Selected: California, Texas

autocomplete_controlled_multiple.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let states =
[|
("california", "California");
("texas", "Texas");
("florida", "Florida");
("new-york", "New York");
("illinois", "Illinois");
("pennsylvania", "Pennsylvania");
|]
let make () =
let selected, set_selected = S.create_signal [| "california"; "texas" |] in
let names () =
S.get selected |> Array.to_list
|> List.filter_map (fun key ->
Option.map snd
(Array.find_opt (fun (id, _) -> String.equal id key) states))
in
<div class_="space-y-4">
<Autocomplete
class_="w-[256px]"
placeholder="Select states"
selection_mode=`multiple
value=(fun () -> S.get selected)
on_change=(S.set set_selected)>
<Label>"States (controlled multiple)"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)
selection_mode=`multiple>
<Solidtype.For each=(fun () -> states)>
(fun (id, name) _ ->
<List_box.Item id=(fun () -> id) text_value=(fun () -> name)>
(fun () -> Jsx.string name) <List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
<p class_="text-sm text-muted">
(fun () ->
Jsx.string
("Selected: "
^
match names () with
| [] -> "None"
| names -> String.concat ", " names))
</p>
</div>
State
Select one

Autocomplete is closed

autocomplete_controlled_open_state.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Button = Solidtype_heroui.Button
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let states =
[|
("florida", "Florida");
("delaware", "Delaware");
("california", "California");
("texas", "Texas");
("new-york", "New York");
("washington", "Washington");
|]
let make () =
let is_open, set_open = S.create_signal false in
<div class_="space-y-4">
<Autocomplete
class_="w-[256px]"
is_open=(fun () -> S.get is_open)
placeholder="Select one"
on_open_change=(S.set set_open)>
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<Solidtype.For each=(fun () -> states)>
(fun (id, name) _ ->
<List_box.Item id=(fun () -> id) text_value=(fun () -> name)>
(fun () -> Jsx.string name) <List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
<Button on_click=(fun _ -> S.set set_open (not (S.get is_open)))>
(fun () ->
Jsx.string
((if S.get is_open then "Close" else "Open") ^ " Autocomplete"))
</Button>
<p class_="text-sm text-muted">
(fun () ->
Jsx.string
("Autocomplete is " ^ if S.get is_open then "open" else "closed"))
</p>
</div>

HeroUI’s example searches a server for each text typed; here the same names are searched after the same wait. The filter’s input_value and on_input_change hold the search’s text.

Search a Star Wars characters
Search...
autocomplete_asynchronous_filtering.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
(* The first two pages of https://swapi.py4e.com/api/people/, which HeroUI's
example searches, here searched after the same wait. *)
let characters =
[|
"Luke Skywalker";
"C-3PO";
"R2-D2";
"Darth Vader";
"Leia Organa";
"Owen Lars";
"Beru Whitesun lars";
"R5-D4";
"Biggs Darklighter";
"Obi-Wan Kenobi";
"Anakin Skywalker";
"Wilhuff Tarkin";
"Chewbacca";
"Han Solo";
"Greedo";
"Jabba Desilijic Tiure";
"Wedge Antilles";
"Jek Tono Porkins";
"Yoda";
"Palpatine";
|]
(* How long the fetch it stands in for takes. *)
let load_ms = 400
(* Whether [part] is in [name], whatever their case, as the search finds it. *)
let holds ~part name =
let name = String.lowercase_ascii name
and part = String.lowercase_ascii part in
let n = String.length part in
let rec from i =
i + n <= String.length name
&& (String.equal (String.sub name i n) part || from (i + 1))
in
from 0
let make () =
let filter_text, set_filter_text = S.create_signal "" in
let found, set_found = S.create_signal characters in
let search text =
S.set set_filter_text text;
let timer =
Js.Global.setTimeout
~f:(fun () ->
S.set set_found
(Array.of_list
(List.filter
(fun name -> holds ~part:text name)
(Array.to_list characters))))
load_ms
in
S.on_cleanup (fun () -> Js.Global.clearTimeout timer)
in
<Autocomplete
allows_empty_collection=true class_="w-[256px]" placeholder="Search...">
<Label>"Search a Star Wars characters"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter
input_value=(fun () -> S.get filter_text) on_input_change=search>
<Search_field
aria_label="Search characters" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search characters..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
class_="max-h-[420px] overflow-y-auto"
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<Solidtype.For each=(fun () -> S.get found)>
(fun name _ ->
<List_box.Item id=(fun () -> name) text_value=(fun () -> name)>
(fun () -> Jsx.string name) <List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
State
Select one
autocomplete_custom_indicator.mlx
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
let make () =
<Autocomplete class_="w-[256px]" placeholder="Select one">
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator class_="size-3">
<Gravity.Chevrons_expand_vertical />
</Autocomplete.Indicator>
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>

Autocomplete.Value’s children are a function of the ids chosen, drawn while one is; the autocomplete draws its placeholder while none is.

Currency
autocomplete_custom_value.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Description = Solidtype_heroui.Description
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
type currency = { code : string; id : string; name : string; symbol : string }
let currencies =
[|
{ code = "USD"; id = "usd"; name = "US Dollar"; symbol = "$" };
{ code = "EUR"; id = "eur"; name = "Euro"; symbol = {js|€|js} };
{ code = "GBP"; id = "gbp"; name = "British Pound"; symbol = {js|£|js} };
{ code = "JPY"; id = "jpy"; name = "Japanese Yen"; symbol = {js|¥|js} };
{ code = "CHF"; id = "chf"; name = "Swiss Franc"; symbol = {js|₣|js} };
|]
let make () =
<Autocomplete
class_="w-[256px]"
default_value=(fun () -> [| "usd" |])
placeholder="Select a currency">
<Label>"Currency"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value>
(fun keys ->
<span class_="contents">
(fun () ->
match S.get keys with
| [| key |] -> (
match
Array.find_opt (fun c -> String.equal c.id key) currencies
with
| Some c ->
Jsx.element
<span class_="flex min-w-0 items-center gap-1.5">
<span class_="font-medium">
(fun () -> Jsx.string c.symbol)
</span>
<span>(fun () -> Jsx.string c.code)</span>
<span class_="truncate text-muted">
(fun () -> Jsx.string c.name)
</span>
</span>
| None -> Jsx.element Jsx.nothing)
| _ -> Jsx.element Jsx.nothing)
</span>)
</Autocomplete.Value>
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search currencies" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search currencies..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<Solidtype.For each=(fun () -> currencies)>
(fun c _ ->
<List_box.Item
id=(fun () -> c.id) text_value=(fun () -> c.code ^ " " ^ c.name)>
<div class_="flex flex-col">
<Label>(fun () -> Jsx.string c.code)</Label>
<Description>(fun () -> Jsx.string c.name)</Description>
</div>
<List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
State
Select one
autocomplete_in_surface.mlx
module S = Solidtype.Solid
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
module Surface = Solidtype_heroui.Surface
let make () =
let selected, set_selected = S.create_signal [||] in
<Surface class_="w-[320px] rounded-3xl p-6">
<Autocomplete
class_="w-full"
placeholder="Select one"
value=(fun () -> S.get selected)
variant=`secondary
on_change=(S.set set_selected)>
<Label>"State"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search states" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search states..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<List_box.Item id="florida" text_value="Florida">
"Florida" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="delaware" text_value="Delaware">
"Delaware" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="california" text_value="California">
"California" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="texas" text_value="Texas">
"Texas" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="new-york" text_value="New York">
"New York" <List_box.Item_indicator />
</List_box.Item>
<List_box.Item id="washington" text_value="Washington">
"Washington" <List_box.Item_indicator />
</List_box.Item>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
</Surface>

HeroUI’s Virtualization example draws a long list by React Aria’s Virtualizer, which a List_box has no counterpart of yet: it draws every option.

User
Select a user
autocomplete_user_selection.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Avatar = Solidtype_heroui.Avatar
module Description = Solidtype_heroui.Description
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Autocomplete = Solidtype_heroui.Autocomplete
module Empty_state = Solidtype_heroui.Empty_state
module Search_field = Solidtype_heroui.Search_field
type user = {
avatar_url : string;
email : string;
fallback : string;
id : string;
name : string;
}
let users =
[|
{
avatar_url =
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/blue.jpg";
email = "bob@heroui.com";
fallback = "B";
id = "1";
name = "Bob";
};
{
avatar_url =
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/green.jpg";
email = "fred@heroui.com";
fallback = "F";
id = "2";
name = "Fred";
};
{
avatar_url =
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/purple.jpg";
email = "martha@heroui.com";
fallback = "M";
id = "3";
name = "Martha";
};
{
avatar_url =
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/red.jpg";
email = "john@heroui.com";
fallback = "J";
id = "4";
name = "John";
};
{
avatar_url =
"https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/orange.jpg";
email = "jane@heroui.com";
fallback = "J";
id = "5";
name = "Jane";
};
|]
let make () =
<Autocomplete class_="w-[256px]" placeholder="Select a user">
<Label>"User"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value>
(fun keys ->
<span class_="contents">
(fun () ->
match S.get keys with
| [| key |] -> (
match
Array.find_opt
(fun (user : user) -> String.equal user.id key)
users
with
| Some user ->
Jsx.element
<div class_="flex items-center gap-2">
<Avatar class_="size-4" size=`sm>
<Avatar.Image src=(fun () -> user.avatar_url) />
<Avatar.Fallback>
(fun () -> Jsx.string user.fallback)
</Avatar.Fallback>
</Avatar>
<span>(fun () -> Jsx.string user.name)</span>
</div>
| None -> Jsx.element Jsx.nothing)
| keys ->
Jsx.string
(string_of_int (Array.length keys) ^ " users selected"))
</span>)
</Autocomplete.Value>
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter>
<Search_field
aria_label="Search users" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search users..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>"No results found"</Empty_state>)>
<Solidtype.For each=(fun () -> users)>
(fun (user : user) _ ->
<List_box.Item
id=(fun () -> user.id) text_value=(fun () -> user.name)>
<Avatar size=`sm>
<Avatar.Image src=(fun () -> user.avatar_url) />
<Avatar.Fallback>
(fun () -> Jsx.string user.fallback)
</Avatar.Fallback>
</Avatar>
<div class_="flex flex-col">
<Label>(fun () -> Jsx.string user.name)</Label>
<Description>(fun () -> Jsx.string user.email)</Description>
</div>
<List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>
City
Search for a city
autocomplete_location_search.mlx
module S = Solidtype.Solid
module Jsx = Solidtype.Jsx
module Autocomplete = Solidtype_heroui.Autocomplete
module Description = Solidtype_heroui.Description
module Empty_state = Solidtype_heroui.Empty_state
module Label = Solidtype_heroui.Label
module List_box = Solidtype_heroui.List_box
module Search_field = Solidtype_heroui.Search_field
type city = { name : string; country : string }
let cities =
[|
{ country = "USA"; name = "New York" };
{ country = "USA"; name = "Los Angeles" };
{ country = "USA"; name = "Chicago" };
{ country = "UK"; name = "London" };
{ country = "France"; name = "Paris" };
{ country = "Japan"; name = "Tokyo" };
{ country = "Australia"; name = "Sydney" };
{ country = "Canada"; name = "Toronto" };
{ country = "Germany"; name = "Berlin" };
{ country = "Spain"; name = "Madrid" };
|]
(* How long the search it stands in for takes. *)
let search_ms = 300
(* Whether [part] is in [text], whatever their case. *)
let holds ~part text =
let text = String.lowercase_ascii text
and part = String.lowercase_ascii part in
let n = String.length part in
let rec from i =
i + n <= String.length text
&& (String.equal (String.sub text i n) part || from (i + 1))
in
from 0
let make () =
let selected, set_selected = S.create_signal [||] in
let loading, set_loading = S.create_signal false in
(* HeroUI's example stands in for a search that takes a while. *)
let filter text typed =
String.equal typed ""
||
(S.set set_loading true;
let (_ : Js.Global.timeoutId) =
Js.Global.setTimeout ~f:(fun () -> S.set set_loading false) search_ms
in
holds ~part:typed text)
in
<Autocomplete
class_="w-[256px]"
placeholder="Search for a city"
value=(fun () -> S.get selected)
on_change=(S.set set_selected)>
<Label>"City"</Label>
<Autocomplete.Trigger>
<Autocomplete.Value />
<Autocomplete.Clear_button />
<Autocomplete.Indicator />
</Autocomplete.Trigger>
<Autocomplete.Popover>
<Autocomplete.Filter filter>
<Search_field
aria_label="Search cities" name="search" variant=`secondary>
<Search_field.Group>
<Search_field.Search_icon />
<Search_field.Input placeholder="Search cities..." />
<Search_field.Clear_button />
</Search_field.Group>
</Search_field>
<List_box
render_empty_state=(fun _ ->
<Empty_state>
(fun () ->
Jsx.string
(if S.get loading then "Searching..."
else "No cities found"))
</Empty_state>)>
<Solidtype.For each=(fun () -> cities)>
(fun city _ ->
<List_box.Item
id=(fun () -> city.name) text_value=(fun () -> city.name)>
<div class_="flex flex-col">
<Label>(fun () -> Jsx.string city.name)</Label>
<Description>(fun () -> Jsx.string city.country)</Description>
</div>
<List_box.Item_indicator />
</List_box.Item>)
</Solidtype.For>
</List_box>
</Autocomplete.Filter>
</Autocomplete.Popover>
</Autocomplete>

User Selection Multiple, Tag Group Selection, Email Recipients

Section titled “User Selection Multiple, Tag Group Selection, Email Recipients”

These draw the options chosen as tags, with HeroUI’s TagGroup, which is not ported yet.

HeroUI’s Tailwind example draws the people chosen as tags, with a TagGroup, which is not ported yet; class_ is added after HeroUI’s classes on every part, as the examples above show.

HeroUI’s classes are global, so a stylesheet restyles every one, as with HeroUI in React:

@layer components {
.autocomplete__trigger {
@apply rounded-lg border border-border bg-surface;
}
.autocomplete__popover {
@apply rounded-xl;
}
}
  • .autocomplete, .autocomplete--primary, .autocomplete--secondary, .autocomplete--full-width
  • .autocomplete__trigger, .autocomplete__value, .autocomplete__clear-button, .autocomplete__indicator, .autocomplete__popover
  • Open: [data-open="true"] on the autocomplete and its indicator
  • Focus: [data-focused="true"] on the autocomplete while its button has the focus; [data-focus-within="true"] on its trigger
  • Hover: [data-hovered="true"] on the trigger
  • Placeholder: [data-placeholder="true"] on the value
  • Empty: [data-empty="true"] on the clear button
  • Invalid, Disabled, Required: [data-invalid="true"], [data-disabled="true"], [data-required="true"] on the autocomplete
  • Entering and Exiting: [data-entering="true"], [data-exiting="true"] on the popover

Kobalte’s combo box filters its options by the search’s text, whatever its case or accents, or by the filter given, and keeps the focus in the search while the arrows move through the list, as React Aria’s autocomplete does. Its list is the List_box beside the search, whose options join the autocomplete while it is closed too, so its value shows the option chosen; the search moves into the popover each time it opens, and starts empty.

A press on the trigger, or an arrow on its button, opens the list and gives the search the focus; typing gives the first option the search keeps the focus. Enter or a press chooses: in a choice of one the list closes and the focus goes back to the button, where React Aria’s is lost to the page. While the list is open the page outside is hidden from a reader and no pointer reaches it, as React Aria’s modal popover does.

The search’s input is Kobalte’s combo box input, which tells a reader it expands and which option it holds, where React Aria’s is a search box that controls the list.

Each prop beside the name HeroUI’s React component gives it.

React solidtype Type Default Description
placeholder placeholder string "Select an item" Shown while nothing is chosen
selectionMode selection_mode `single | `multiple `single One or many, read as it is made
value value string array The ids chosen, controlled
defaultValue default_value string array The ids chosen at first
onChange on_change string array -> unit Told the ids chosen as they change
onClear on_clear unit -> unit Told as it is cleared
disabledKeys disabled_keys string array The disabled options’ ids
isOpen is_open bool Whether its list is open, controlled
defaultOpen default_open bool false Whether it starts open
onOpenChange on_open_change bool -> unit Told as it opens or closes
allowsEmptyCollection allows_empty_collection bool false Whether it opens with no option at all
isDisabled is_disabled bool false Whether it is disabled
isRequired is_required bool false Whether a choice is required
isInvalid is_invalid bool false Whether it is invalid
name name string Its name in a form
fullWidth full_width bool false Whether it fills its container
variant variant `primary | `secondary `primary Its look
className class_ string Added after HeroUI’s classes
children children elements Its label, trigger, description and popover
React solidtype Type Description
filter filter string -> string -> bool Keeps an option given its text and the search’s; contains by default
inputValue input_value string The search’s text, controlled
onInputChange on_input_change string -> unit Told the search’s text as it changes
children children elements Its Search_field and List_box

Autocomplete.Trigger, Autocomplete.Popover, Autocomplete.Indicator, Autocomplete.Clear_button

Section titled “Autocomplete.Trigger, Autocomplete.Popover, Autocomplete.Indicator, Autocomplete.Clear_button”
React solidtype Type Description
placement placement `top | `bottom | `left | `right The popover’s side, bottom by default
className class_ string Added after HeroUI’s classes
children children elements What it holds; the indicator’s own icon
onClick on_click Dom.mouseEvent -> unit The clear button’s, told after it clears
React solidtype Type Description
className class_ string Added after HeroUI’s classes
children children string array accessor -> element What it draws while something is chosen, given the ids chosen

Original HeroUI documentation: Autocomplete.

The same HeroUI Autocomplete twice, under the same props: in solidtype on the left, in React on the right. Below them, every attribute of each button: a marked row is one they disagree on, and a dimmed row is a framework’s own, which no style reads.

solidtype — OCaml, on Solid and Kobalte
State
Select one
React — TypeScript, on React Aria
attributesolidtypeReact