A custom combobox, with support for keyboard navigation This Preset can be used for basic comboboxes, without complex selection models or option/value relationships.
Stores whether the menu is open or not, and which option is currently focussed.
It does not store which option is selected.
Is updated and returned in the #update function.
Context is passed around internally, and is just used to track if the menu has been recently opened
init : Model option
Initialise a closed menu, you can use this in your own init function
Internal.Msg option
Passed in to #update
menuOpened : Msg option
A #Msg that is sent when the menu is opened
menuClosed : Msg option
A #Msg that is sent when the menu is closed
update : Msg option -> { model : Model option, config : Context -> Config option selection, options : List option, selected : selection } -> ( selection, Model option, Platform.Cmd.Cmd (Msg option) )
Call this in your own update function, it returns the latest selection,
the dropdown model, and Cmd
s to pass on. You will need to save the selection and menu in your model.
Created in #config
This is passed into #update and #view and is used to control how the menu reacts to user input
{ id : String
, optionToLabel : option -> String
, optionToId : option -> String
, optionToSelection : option -> selection
, selectionToOption : selection -> List option -> Maybe option
, selectionToLabel : selection -> String
, selectionCleared : Menus.Select.Change selection
, matchesInput : String -> option -> Basics.Bool
, containsInput : String -> option -> Basics.Bool
, visibleOptions : VisibleOptionConfig option selection -> String -> selection -> Maybe ( Menus.Active.Active option
, List option ) -> Maybe ( Menus.Active.Active option
, List option )
}
Passed in to #config
- id
: Must be unique, and is displayed in the HTML, used for accessibility
- optionToLabel
: Allows users to use keyboard input to search for options
- optionToId
: Uniquely identify each option
- optionToSelection
: Turn any option into your selection, for instance you might want the selection to be Maybe option
,
so you would have optionToSelection = Just
- selectionToOption
: Given the current selection and a list of options, find the option that corresponds to the selection.
- selectionToLabel
: What to set as the menu input's value
- selectionCleared
: When the user presses backspace, while the menu is closed or the input is empty, what should happen to the selection?
Returning NotChanged
will make the combobox non-clearable.
- matchesInput
: Given a string and an option, does the option exactly match the string?
- containsInput
: Given a string and an option, does the option "contain" the string?
- visibleOptions
: The Preset does some work under the scenes to already filter down visible options using data passed in from this config object,
but there are a couple of "plugins", #autoSelect and #creatable you can use here to change how the combobox functions.
config : OptionConfig option selection -> Context -> Config option selection
Create a #Config type. You don't need to explicitly pass in the Context
yourself,
the #update and #view functions expect Context -> Config option selection
.
{ optionToLabel : option -> String
, optionToId : option -> String
, optionToSelection : option -> selection
, selectionToOption : selection -> List option -> Maybe option
, selectionToLabel : selection -> String
, matchesInput : String -> option -> Basics.Bool
, containsInput : String -> option -> Basics.Bool
}
This is passed down to the #autoSelect and #creatable plugins from the main config
autoSelect : VisibleOptionConfig option selection -> String -> selection -> Maybe ( Menus.Active.Active option, List option ) -> Maybe ( Menus.Active.Active option, List option )
This plugin will automatically select the closest match to the input. If you are combining this with other plugins, use it last or any changes within the latter plugins won't be autoselected.
Preset.Combobox.config
{ ...
, visibleOptions =
Preset.Combobox.autoSelect
}
{ newOption : String -> option }
Passed into #creatable Define how to create a new option, given a string
creatable : CreatableConfig option -> VisibleOptionConfig option selection -> String -> selection -> Maybe ( Menus.Active.Active option, List option ) -> Maybe ( Menus.Active.Active option, List option )
This plugin allows people to create new options when they enter input that doesn't exactly match any of the options.
Preset.Combobox.config
{ ...
, visibleOptions =
Preset.Combobox.creatable
{ newOption = \label -> NewOption label }
}
view : { model : Model option, config : Context -> Config option selection, options : List option, selected : selection } -> (Token option selection -> List option -> Html (Msg option)) -> Html (Msg option)
This needs to wrap your menu. It does not render any HTML, but provides a #Token that you pass into view functions, and also the currently visible options.
isOpen : Token option selection -> Basics.Bool
Check whether the menu is open or closed
focussedOption : Token option selection -> Maybe option
Returns the currently focussed option
options : Token option selection -> List (Html.Attribute (Msg option)) -> List (Html (Msg option)) -> Html (Msg option)
A wrapper for the list of options in the menu. This should be a direct parent of your list of option nodes.
option : Token option selection -> { value : option, isSelected : Basics.Bool } -> List (Html.Attribute (Msg option)) -> List (Html Basics.Never) -> Html (Msg option)
A focus and selectable option
input : Token option selection -> { placeholder : String } -> List (Html.Attribute (Msg option)) -> Html (Msg option)
The input used to open and close the menu
optionsDiv : Token option selection -> List (Html.Attribute (Msg option)) -> List (Html (Msg option)) -> Html (Msg option)
A wrapper for the list of options in the menu. This should be a direct parent of your list of option nodes.
Created automatically when you call #view, pass it in to view functions
token : { model : Model option, config : Context -> Config option selection, options : List option, selected : selection } -> Token option selection
Create a token manually for use in view and helper functions