The dropdown
input allows users to select a value from a list of options. Unlike native select elements, the dropdown input allows you to customize both its appearance and behavior.
The options
prop can accept three different formats of values:
value
and label
keys (see example above)['A', 'B', 'C']
{ a: 'A', b: 'B', c: 'C' }
If you assign options as an empty array, the input will be rendered in a disabled state.
The dropdown input will render in single-select mode by default.
Dropdown inputs with the prop multiple
set will render in multi-select mode.
Notice in the example above that because the multiple
prop is set, the value
prop must be an array.
Instead of passing a static list to the options
prop, options can be assigned dynamically.
In this example, the function, loadHorrorMovies
, makes a request to the API for TMDB to load a list of horror movies. Assigning the function to the options
prop will load the options when the end-user opens the listbox.
By default the dropdown will only load options asynchronously once (upon the listbox being expanded). Setting the prop always-load-on-open
will cause the dropdown to load options every time the listbox is expanded.
The prop load-on-created
will cause the dropdown to load options as soon as it is created.
A function assigned the options prop will be passed two arguments: page
and hasNextPage
. The page argument indicates the current page number, and hasNextPage is a callback function that indicates whether there are more pages to load.
If you would rather allow the user to load more options without having to click the Load more option at the bottom of the options list, you can set the load-on-scroll
prop to true, and our function, loadCurrentlyPopularMovies
will be called again:
FormKit's dropdown input also provides an optionLoader
prop that allows you to rehydrate values that are not in the options list. In this example the dropdown is provided an initial value (two movie IDs). The optionLoader
function is called for each value that is not in the options list.
Notice in the example above that the optionLoader function is passed two arguments: the value
of the selected option (in this case, the movie ID) and the cachedOption
. The cachedOption prop is used for preventing unnecessary lookups. If the cachedOption is not null
it means that the selected option has already been loaded, and you can return the cachedOption directly.
Unlike native select elements, the dropdown input can be customized via. markup.
The dropdown input allows you to customize the look and feel of each option by using the option slot. In this example, we are using the option slot to display each option's asset; logo and name:
The dropdown input allows you to customize the look and feel of the selected option(s).
When using the dropdown input as a multi-select
, you can customize the look and feel of the selected options by setting the selection-appearance
prop to either truncate
(the default) or tags
.
If you only want to customize the display of the selected option, use the selection slot (as opposed to the option slot mentioned above):
The selection slot does not exist on the multi-select dropdown with selection appearance truncate
.
The following props allow you to customize the behavior of the dropdown input.
The dropdown input, by default, will be rendered in a disabled state if no options are passed. Optionally, you may pass the empty-message
prop a message to display when no options are available:
If you would like to allow users to remove the selected value, set the selection-removable
prop to true. This will render a close icon next to the selected value:
The selection-removable prop cannot be used for multi-selects.
By default, when the selection-removable
prop is set to true
, the dropdown will not open after the selected value is removed. You can change this behavior by setting the open-on-remove
prop to true
:
By default, when the multiple
prop is set, the dropdown will not close after an option is selected. You can change this behavior by setting the close-on-select
prop to true
:
If you would like expand the listbox as soon as the dropdown input is focused, you can use the open-on-focus
prop:
When using the dropdown with static options, FormKit's dropdown also comes with a feature called overscroll
. Setting the behavior
prop to overscroll will render the listbox directly over the input to maximize the available size for the list:
If you would like to limit the number of options that can be selected, you can use the max
prop:
If you would like the listitems in the listbox to be grouped, pass the options
prop an array of objects and include the property group
:
Prop | Type | Default | Description |
---|---|---|---|
options | any | [] | The list of options the user can select from. |
load-on-scroll | boolean | false | When set to `true`, the dropdown will try loading more options based on the end-user`s scroll position |
option-loader | function | null | Used for hydrating initial value, or performing an additional request to load more information of a selected option. |
empty-message | string | undefined | Renders a message when there are no options to display. |
selection-appearance | string | truncate | For multi-select dropdowns, this prop allows you to customize the look and feel of the selected options. Possible values are `truncate` (the default) or `tags`. |
selection-removable | boolean | false | For single-select dropdowns, this prop allows you to remove the selected value. |
open-on-remove | boolean | false | When the `selection-removable` prop is set to `true`, the dropdown will not open after the selected value is removed. You can change this behavior by setting the `open-on-remove` prop to `true`. |
close-on-select | boolean | false | When the `multiple` prop is set, the dropdown will not close after an option is selected. You can change this behavior by setting the `close-on-select` prop to `true`. |
open-on-focus | boolean | false | If you would like expand the listbox as soon as the dropdown input is focused, you can use the `open-on-focus` prop. |
options-appearance | string | undefined | For multi-select dropdowns, this prop allows you to customize the look and feel of the selected options. Possible values are `default` (the default) or `checkbox`. |
multiple | boolean | false | When set to `true`, the dropdown will allow the user to select multiple options. |
behavior | string | undefined | Renders the listbox directly over the input to maximize the available size for the list. |
always-load-on-open | boolean | false | Determines whether the dropdown should always load its options when opened or whether it should reference the options that were previously found when opening. |
load-on-created | boolean | false | When set to `true`, the dropdown will load the options when the node is created. |
max | number | string | undefined | If you would like to limit the number of options that can be selected, you can use the `max` prop (applies only to multi-select). |
deselect | boolean | true | When set to `false`, the end-user cannot deselect a selected option form the listbox. |
popover | boolean | false | Renders the input's listbox using the browser Popover API. |
Show Universal props | |||
config | Object | {} | Configuration options to provide to the input’s node and any descendent node of this input. |
delay | Number | 20 | Number of milliseconds to debounce an input’s value before the commit hook is dispatched. |
dirtyBehavior | string | touched | Determines how the "dirty" flag of this input is set. Can be set to touched or compare — touched (the default) is more performant, but will not detect when the form is once again matching its initial state. |
errors | Array | [] | Array of strings to show as error messages on this field. |
help | String | '' | Text for help text associated with the input. |
id | String | input_{n} | The unique id of the input. Providing an id also allows the input’s node to be globally accessed. |
ignore | Boolean | false | Prevents an input from being included in any parent (group, list, form etc). Useful when using inputs for UI instead of actual values. |
index | Number | undefined | Allows an input to be inserted at the given index if the parent is a list. If the input’s value is undefined, it inherits the value from that index position. If it has a value it inserts it into the lists’s values at the given index. |
label | String | '' | Text for the label element associated with the input. |
name | String | input_{n} | The name of the input as identified in the data object. This should be unique within a group of fields. |
parent | FormKitNode | contextual | By default the parent is a wrapping group, list or form — but this props allows explicit assignment of the parent node. |
prefix-icon | String | '' | Specifies an icon to put in the prefixIcon section. |
preserve | boolean | false | Preserves the value of the input on a parent group, list, or form when the input unmounts. |
preserve-errors | boolean | false | By default errors set on inputs using setErrors are automatically cleared on input, setting this prop to true maintains the error until it is explicitly cleared. |
sections-schema | Object | {} | An object of section keys and schema partial values, where each schema partial is applied to the respective section. |
suffix-icon | String | '' | Specifies an icon to put in the suffixIcon section. |
type | String | text | The type of input to render from the library. |
validation | String, Array | [] | The validation rules to be applied to the input. |
validation-visibility | String | blur | Determines when to show an input's failing validation rules. Valid values are blur , dirty , and live . |
validation-label | String | {label prop} | Determines what label to use in validation error messages, by default it uses the label prop if available, otherwise it uses the name prop. |
validation-rules | Object | {} | Additional custom validation rules to make available to the validation prop. |
value | Any | undefined | Seeds the initial value of an input and/or its children. Not reactive. Can seed entire groups (forms) and lists.. |
You can target a specific section of an input using that section's "key", allowing you to modify that section's classes, HTML (via :sections-schema
, or content (via slots)). Read more about sections here.
Section-key | Description |
---|---|
selector | The selector section is a button element that opens the dropdown options list. |
selection | Contains the selected option. |
listitem | A list item element that contains the option section. |
option | A div that contains the option content. |
listbox | The listbox section is a ul element that contains the options list. |
dropdownWrapper | Wraps the listbox section. A div that handles scrolling the listbox. |
optionLoading | A span element that is conditionally rendered within the selected option when loading is occurring. |
loaderIcon | An element for outputting an icon in the selector element when loading is occurring. |
selectIcon | An element for outputting an icon in the selector element when the dropdown is closed. |
selectedIcon | An element for outputting an icon next to the selected option when inside the listbox. |
loadMore | A list item element that is conditionally rendered at the bottom of the options list when there are more pages to load. |
loadMoreInner | A span element that acts as a wrapper for the loaderIcon within the loadMore section. |
emptyMessage | A list item element that is conditionally rendered when there are no options to display. |
emptyMessageInner | A span element that acts as a wrapper for the emptyMessage section. |
tagsWrapper | A div element that wraps the tags section. |
tags | A div element that contains the tags. |
tagWrapper | A div element that wraps the tag. |
tag | A div element that contains the tag label and removeSelection section. |
tagLabel | A span element that contains the tag label. |
removeSelection | A span element that contains the removeSelection icon. |
selectorSelectionsWrapper | A div element that wraps the selectorSelections section. |
selectorSelections | A div element that contains the selectorSelectionsItem sections. |
selectorSelectionsItem | A div element that contains the selectorSelectionsItem content. |
truncationCount | A div element that contains the truncationCount content. |
Show Universal section keys | |
outer | The outermost wrapping element. |
wrapper | A wrapper around the label and input. |
label | The label of the input. |
prefix | Has no output by default, but allows content directly before an input element. |
prefixIcon | An element for outputting an icon before the prefix section. |
inner | A wrapper around the actual input element. |
suffix | Has no output by default, but allows content directly after an input element. |
suffixIcon | An element for outputting an icon after the suffix section. |
input | The input element itself. |
help | The element containing help text. |
messages | A wrapper around all the messages. |
message | The element (or many elements) containing a message — most often validation and error messages. |
All FormKit inputs are designed with the following accessibility considerations in mind. Help us continually improve accessibility for all by filing accessibility issues here:
Section Key | Attribute | Default | Description |
---|---|---|---|
selector | tabindex | 0 | Prioritizes keyboard focus order by setting it to 0 |
aria-haspopup | listbox | Signals the presence of a pop-up listbox triggered by interaction. | |
aria-expanded | Indicates whether the dropdown element is currently expanded or collapsed. | ||
aria-controls | Links this element to the ID of the listbox element. | ||
aria-describedBy | Associate this element with descriptive text from another element. | ||
placeholder | aria-hidden | true | Makes this element not exposed to the accessibility API when no placeholder exists. |
removeSelection | tabindex | -1 | Prioritizes keyboard focus order by setting it to -1 |
aria-controls | Links this element to the ID of the input element. | ||
selections | aria-live | polite | Annouces to screen readers that this element was dynamically updated without interrupting the current task. |
aria-hidden | true | Makes this element not exposed to the accessibility API. | |
selectionsItem | aria-hidden | true | Makes this element not exposed to the accessibility API when last visible index and index are greater than last visible index. |
tagWrapper | tabindex | 0 | Prioritizes keyboard focus order by setting it to 0 |
tag | tabindex | 0 | Prioritizes keyboard focus order by setting it to 0 |
tagsWrapper | aria-live | polite | Annouces to screen readers that this element was dynamically updated without interrupting the current task. |
Show Universal section key | |||
label | label | for | Associates the label to an input element. Users can click on the label to focus the input or to toggle between states. |
input | input | disabled | Disables an HTML element, preventing user interaction and signaling a non-interactive state. |
aria-describedby | Associates an element with a description, aiding screen readers. | ||
aria-required | Adds this attribute when validation is required. | ||
icon | icon | for | Whenever icon is defined as a label it links it to an input element. |
Keyboard Event | Description |
---|---|
Tab | Moves the focus to the next focusable input on the page. |
Shift + Tab | Moves the focus to the previous focusable input on the page. |