Combobox
A field that suggests as you type, and keeps one of its suggestions.
forSlots(ComboboxSlots)(Recipes.Combobox({}))
Usage
The function that drew the preview, over the theme module Create a theme writes. The preview passes it the style picked above instead of its default.
export const ComboboxStyle = forSlots(ComboboxSlots)(Recipes.Combobox({}))
export const cities = ['Kyiv', 'Lagos', 'Lima', 'Oslo', 'Osaka', 'Quito', 'Seoul', 'Zurich']
export const CityBox: ReturnType<typeof ComboboxView.create<string>> = ComboboxView.create<string>()
/** What is typed and highlighted is the component's; the city is the Model's. */
export interface ComboboxState {
readonly combobox: UiCombobox.Model
readonly city: Option.Option<string>
}
export const combobox = <Message>(
style: NamedStyle<typeof ComboboxSlots>,
state: ComboboxState,
toMessage: (message: UiCombobox.Message) => Message,
h: HtmlBuilder<Message>,
): Html => {
const typed = state.combobox.inputValue.toLowerCase()
return h.submodel({
slotId: state.combobox.id,
model: state.combobox,
view: CityBox.view,
viewInputs: {
anchor: { placement: 'bottom-start', gap: 4, padding: 8, portal: false },
items: cities.filter(city => city.toLowerCase().includes(typed)),
restingInputValue: Option.getOrElse(state.city, () => ''),
maybeSelectedValue: state.city,
itemToConfig: (city: string) => ({ content: h.span([], [city]) }),
itemToValue: (city: string) => city,
itemToDisplayText: (city: string) => city,
inputPlaceholder: 'Find a city',
buttonContent: h.span([], ['▾']),
toView: Combobox.toView([style.mixin, ...Combobox.fluid], { h }),
},
toParentMessage: toMessage,
})
}