The NativeSelect
component is a simple wrapper for the <select>
element with
TextField
styles. Just like native <select>
elements, this wrapper does
not support:
readOnly
(it can almost manually be done by disabiling each option
yourself, but it'll make it impossible to close on mobile devices if it there
are so many options that it covers the entire viewport)That being said, the demo below will show you some patterns you can use to fake
placeholder text using the floating label and an empty <option>
element as
well as a read-only view by disabling all <option>
s.
The Select
component is a custom widget that allows you to have additional
styling controls for a native <select>
element while still being accessible.
This component inherits all the TextField
styles just like the NativeSelect
,
but also allows each option
to be rendered like a ListItem
from the @react-md/list
and @react-md/menu packages.
Note: Even though the
Select
component supports theinline
prop, it does not behave the same was as theNativeSelect
or a native<select>
component since it will not automatically update it's width to be the longest renderable option. The size will update whenever the value of the select changes.
This component is fully controlled, so you will need to provide the current
value
, an onChange
handler, and a list of options
. An option can be:
ListItem
(see the next example for more
details here)The onChange
handler will not be a native change event since there are no
<input>
or <select>
elements being rendered. Instead, the onChange
handler
will be provided the next value string as the first argument and the option as
the second: onChange(nextValue: string, option: object | string | number)
.
Just like a native <select>
component, the list of options can be shown by
clicking, pressing the space key, or using the up and down arrow keys. Once the
list of options are shown, the user can:
Check out the next example for some better examples of the typeahead feature
The default behavior for the Select
component is to just render any number
or string
options as the children
within the ListItem
. Since it is
sometimes helpful to be able to add additional information, styling, or icons
with the options, an option can also be an object of props to pass to the
ListItem
instead.
When the option
is an object, the default behavior will be to:
option.label || option.children
as the displayable childrenoption.value
as the value for this optionoption.label
and option.value
keys from the object before
passing it as props to the ListItem
The label will be displayed in the option itself as well as in the select button when the option's value matches the select's value. This simplest way to add customization is to transform your list of options to follow this pattern.
However, this might not match all use-cases and customizations required, so the select also has the following props to help with rendering and accessibility:
labelKey
- A key on the object that should be considered the labelvalueKey
- A key on the object that should be considered the valuegetOptionLabel
- A function that is called for each option to extract a
labelgetOptionValue
- A function that is called for each option to extract a
valuegetDisplayLabel
- A function that is called for the selected option that
should return a renderable ode to display within the Select
's button.You probably won't need all this additional functionality other than the
labelKey
andvalueKey
props, but it might be useful for virtualization libraries or other stuff like that.
The examples below will show some use-cases for these props to add some more style to your select fields:
labelKey
and valueKey
props converting a list of states that
have the format of interface State { name: string; abbreviation: string; }
without needing to transform the list yourselfchildren
within each option and still being search
accessibleSelect
's
button