Select
The Select component allows you to choose one or multiple options from a
collapsed dropdown with options.
Import
import { Select } from '@dynatrace/strato-components-preview/forms';
Use cases
Use multiple selection
The Select supports multiple selection. You can enable that by adding the
multiple prop. If enabled, the "Select all" option gets added automatically.
Group options together
You can use the Select.Groups to group more options in the same group.
Control the state
The Select can also be controlled, meaning that you can handle the selection
state. To do so, you need to use the onChange prop to provide a handler that
is called when the internal state changes. That state can be modified and is
applied as soon as it's passed to the value prop.
Show a custom placeholder
You can use the Select.Trigger component to show a placeholder for the trigger
button by adding the placeholder prop. If no option is selected, the
placeholder value is shown by default. Notice that the clearable prop is
used here to enable empty selection.
Show a custom display value
You can use the Select.DisplayValue component to customize what is rendered on
the trigger. By default, the placeholder is shown when no option is selected.
You can also render content inside a Select.Prefix component to show an icon
in front of the trigger display value for example. When you select a value, the
content inside the Select.DisplayValue slot is then rendered inside the
trigger.
Customize the trigger
You can use the Select.CustomTrigger component to render custom content inside
the trigger slot, so you can control the styling or its rendered text.
As the Select component renders a hidden input inside the trigger for forms
integration, if you're using an interactive element (e.g. a <button>) as
trigger, you would run into accessibility issues due to nesting interactive
items. Therefore, you would need to polymorph it to a non-interactive element
(e.g. a <div>) and take care of the focus styling yourself. To do so, you can
use the useFocusRing utility and pass it the focusWithin option, which
returns the necessary focus styles if an embedded element gains the focus. See
the useFocusRing documentation for
more details.
Disable options
In the Select, you can disable each option separately by adding the disabled
prop on the Select.Option component. Otherwise, if you need to disable the
whole Select component, you can add the disabled prop directly.
Make the selection clearable
In a single select, the clearable prop adds a button to the overlay when an
option is selected to allow users to deselect the option. By default,
clearable is set to false for the single select and true if multiple
selection is enabled. For the multi-select, an option is added to select or
deselect all options.
Filter options
You can search through options by adding the Select.Filter component. This
renders a search input, where you can type the filtering term and filter the
options on the client-side. If no options are found after filtering, you can
also customize the shown message by adding content to the Select.EmptyState
component, which is only valid within the Select.Content element. Otherwise,
the default message is shown: "No items found.".
Control the filtering of the options
You can also control the filtering of the options by adding the value and the
onFilterChange props on the Select.Filter component.
Complex objects as values
There are some known limitations when using complex objects as option values.
For the Select to be able to keep the user's selection between renders, you
can opt for one of the following approaches:
- Use the controlled variant of the Select.
- Use cached values inside of your component function (for example, by using
useMemooruseState).
- Declare variables outside of your component function.
The value returned by a form when the user selects an option depends on the properties of the selected option.
- If you provide a textValue, that will be the returned value.
- If you don't provide a textValue, and thevaluecan be converted to a string, the stringifiedvaluewill be returned.
- If you don't provide a textValueor a stringifiablevalue, the option label will be submitted.
- If no textValueis given, and neither thevaluenor the option label can be stringified, a fallback value will be submitted.
Filter complex options
If you're using a custom component as Select.Option, the text value of this
option can't be determined automatically. To enable the filtering of these
options and to show which option is selected, you need to provide a textValue
with a string representation of the Select.Option.
Add icons to options
The Select.SelectOption component allows adding icons in front of the option
node with the Select.Prefix or after it with the Select.Suffix. The same can
be done to add prefix and suffix icons inside the Select.DisplayValue slot, as
shown above.
Show the loading state
You can show the loading state of the Select.Option components by adding the
loading prop to the Select.Content component.
Set the width of the trigger
You can set the width of the trigger by adding the width prop on the
Select.Trigger component and either giving it a fixed value or setting it to
full, which would adjust it to the width of its container. By default, it's
set to content, so it adjusts to the width of the trigger content.
Set the width of the content
You can set the width of the content by adding the width prop on the
Select.Content component and giving it a fixed value. By default, it has a
min-width of 96px and adjusts to the size of the trigger. If the text of the
options is overflowing, the text is truncated at the end by default. However,
you can also add the TextEllipsis component directly inside the
Select.Option and wrap the text inside it to set the truncation to the start
or middle, if necessary. See
the TextEllipsis documentation for
more details.
Pass large amounts of data
The Select can handle large amounts of options. If the content is too large to
fit, the select options are virtualized.
Show selected options first
In the Select, you can use the showSelectedOptionsFirst prop to configure
whether the options should be reordered to show the selected options at the top.
If this is set to true the options will be reordered when the overlay is
closed and opened again. For elected options inside an Select.Group, this will
position its group at the top, as well as order the option to the top within the
group.
Validate
This example shows how you can validate the Select using the react-hook-form
package, which handles error messages. For connecting the form with the Select
and validating, you need to register the field with custom error messages and
use the useForm hook from react-hook-form. Also, by using the controlState
prop, you can override the error messages and connect the Select's error state
and message to that of the form. This shows a hint in case of an error and
applies proper styling to the component. You can also add custom validation
logic when registering the Select by passing in a validate function to the
register options.
React to open state changes
In the Select you can react to changes to the open state using the
onOpenChange prop. This prop expects a callback method which receives the new
open state as a single boolean argument.