import {Select} from '@gravity-ui/uikit';
Select
is a control that provides a list of options that a user can select.
§Options
Options to select.
§Defining options
You can define options as an array of objects or as the children of a component. The first approach is useful for cases where options require complex preparation and, possibly, memorization. The second one is convenient when there are few options, and their configuration does not require complex calculations.
§Flat list
Array of objects
Child nodes
<Select
placeholder="value"
options={[
{value: 'val_1', content: 'Value 1'},
{value: 'val_2', content: 'Value 2'},
{value: 'val_3', content: 'Value 3'},
{value: 'val_4', content: 'Value 4'},
]}
/>
<Select placeholder="value">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Grouped list
Array of objects
Child nodes
<Select
placeholder="value"
options={[
{
label: 'Group 1',
options: [
{value: 'val_1', content: 'Value 1'},
{value: 'val_2', content: 'Value 2'},
],
},
{
label: 'Group 2',
options: [
{value: 'val_3', content: 'Value 3'},
{value: 'val_4', content: 'Value 4'},
],
},
]}
/>
<Select placeholder="value">
<Select.OptionGroup label="Group 1">
<Select.Option value="val_1" content="Value 1" />
<Select.Option value="val_2" content="Value 2" />
</Select.OptionGroup>
<Select.OptionGroup label="Group 2">
<Select.Option value="val_3" content="Value 3" />
<Select.Option value="val_4" content="Value 4" />
</Select.OptionGroup>
</Select>
§Storing data in options
You can define and store unique data in each option by using the option.data
property. This can be useful when you need to enrich the data when using the onUpdate
callback or, for example, when drawing your options with renderOption
.
§Selecting multiple options
To enable multiple selection, use the multiple
property. Its default value is false
.
<Select multiple={true} placeholder="values">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Counter
You can add a counter of the selected items to the component using the hasCounter
property.
<Select multiple={true} hasCounter={true} placeholder="values">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Filtering options
To enable filter section, use the filterable
property. Its default value is false
.
<Select filterable={true} placeholder="Filterable">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Size
To manage the default control and option size, use the size
property. Its default size is m
.
<Select size="s" placeholder="S Size">
<Select.Option value="val_1">Value 1</Select.Option>
</Select>
<Select size="m" placeholder="M Size">
<Select.Option value="val_1">Value 1</Select.Option>
</Select>
<Select size="l" placeholder="L Size">
<Select.Option value="val_1">Value 1</Select.Option>
</Select>
<Select size="xl" placeholder="XL Size">
<Select.Option value="val_1">Value 1</Select.Option>
</Select>
§Control width
By default, the control width stretches to match the width of the content of the selected options. You can manage it by using the width
property:
'max'
: Stretches to the full width of the parent.
number
: Applies width in pixels.
Default
Max
In pixels
<Select>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select width="max">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select width={150}>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Popup width
You can manage the popup width with the popupWidth
property. The available values are:
'fit'
: Apply control width.
number
: Apply width in pixels.
Points to note about the default behavior:
-
The popup width is equal to the width of the widest option, but not wider than
90vw
. This does not apply in case you use virtualization. -
Narrow options are stretched to fit the width of the control.
§Non-virtualized list
A regular list when all the elements are in the dom tree at once.
Default
Fit
In pixels
<Select>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select>
<Select.Option value="val_1">Loooooooooooooooooooong Value 1</Select.Option>
<Select.Option value="val_2">Loooooooooooooooooooong Value 2</Select.Option>
<Select.Option value="val_3">Loooooooooooooooooooong Value 3</Select.Option>
<Select.Option value="val_4">Loooooooooooooooooooong Value 4</Select.Option>
</Select>
<Select popupWidth="fit">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select popupWidth="fit">
<Select.Option value="val_1">Loooooooooooooooooooong Value 1</Select.Option>
<Select.Option value="val_2">Loooooooooooooooooooong Value 2</Select.Option>
<Select.Option value="val_3">Loooooooooooooooooooong Value 3</Select.Option>
<Select.Option value="val_4">Loooooooooooooooooooong Value 4</Select.Option>
</Select>
<Select popupWidth={80}>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select popupWidth={80}>
<Select.Option value="val_1">Loooooooooooooooooooong Value 1</Select.Option>
<Select.Option value="val_2">Loooooooooooooooooooong Value 2</Select.Option>
<Select.Option value="val_3">Loooooooooooooooooooong Value 3</Select.Option>
<Select.Option value="val_4">Loooooooooooooooooooong Value 4</Select.Option>
</Select>
§Virtualized list
For optimal display of a large number of options, Select
has a built-in list virtualization tool. Virtualization is enabled after overcoming the threshold of the number of options (50
by default). You can manage this value using the virtualizationThreshold
property.
When using virtualization, some restrictions apply to the popup element:
-
The popup width no longer gets adjusted to the length of the longest option.
-
The minimum width of the popup is equal to the width of the control, or
100px
if the control is shorter.
Default
In pixels
<Select>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select>
<Select.Option value="val_1">Loooooooooooooooooooong Value 1</Select.Option>
<Select.Option value="val_2">Loooooooooooooooooooong Value 2</Select.Option>
<Select.Option value="val_3">Loooooooooooooooooooong Value 3</Select.Option>
<Select.Option value="val_4">Loooooooooooooooooooong Value 4</Select.Option>
</Select>
<Select popupWidth="fit">
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select popupWidth="fit">
<Select.Option value="val_1">Loooooooooooooooooooong Value 1</Select.Option>
<Select.Option value="val_2">Loooooooooooooooooooong Value 2</Select.Option>
<Select.Option value="val_3">Loooooooooooooooooooong Value 3</Select.Option>
<Select.Option value="val_4">Loooooooooooooooooooong Value 4</Select.Option>
</Select>
<Select popupWidth={80}>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select popupWidth={80}>
<Select.Option value="val_1">Loooooooooooooooooooong Value 1</Select.Option>
<Select.Option value="val_2">Loooooooooooooooooooong Value 2</Select.Option>
<Select.Option value="val_3">Loooooooooooooooooooong Value 3</Select.Option>
<Select.Option value="val_4">Loooooooooooooooooooong Value 4</Select.Option>
</Select>
§Advanced usage
There are many ways to customize your Select
.
§Rendering custom control
To render a custom control, use the renderControl
property.
Note: You should forward all arguments to your node in order to enable consistent behavior, just as when using the default control.
<Select
renderControl={({onClick, onKeyDown, ref}) => {
return <button ref={ref} onClick={onClick} extraProps={{onKeyDown}}>Custom control</button>
}}
>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Rendering custom filter section
To render a custom filter section, use the renderFilter
property and set the filterable
property to true
.
Note: You need to forward all arguments to your node in order to enable a properly working filter, just as when using the default configuration.
<Select
placeholder="Custom filter"
filterable={true}
renderFilter={({onChange, onKeyDown, ref, value}) => {
return (
<div style={{display: 'flex', flexDirection: 'column'}}>
<input
ref={ref}
value={value}
size="1"
onKeyDown={onKeyDown}
onChange={(e) => onChange(e.target.value)}
/>
<button>Do smth</button>
</div>
);
}}
>
<Select.Option value="val_1">Value 1</Select.Option>
</Select>
§Rendering custom options
To render custom options, use the renderOption
property:
<Select
renderOption={(option) => {
return (
<div style={{color: option.data.color}}>
{option.children}
</div>
);
}}
>
<Select.Option value="val_1" data={{color: '#8FE1A1'}}>Value 1</Select.Option>
<Select.Option value="val_2" data={{color: '#38C0A8'}}>Value 2</Select.Option>
<Select.Option value="val_3" data={{color: '#3A7AC3'}}>Value 3</Select.Option>
<Select.Option value="val_4" data={{color: '#534581'}}>Value 4</Select.Option>
</Select>
§Rendering custom selected options
To render custom selected options, use the renderSelectedOption
property:
<Select
renderSelectedOption={(option) => {
return (
<div style={{color: option.data.color}}>
{option.children}
</div>
);
}}
>
<Select.Option value="val_1" data={{color: '#8FE1A1'}}>Value 1</Select.Option>
<Select.Option value="val_2" data={{color: '#38C0A8'}}>Value 2</Select.Option>
<Select.Option value="val_3" data={{color: '#3A7AC3'}}>Value 3</Select.Option>
<Select.Option value="val_4" data={{color: '#534581'}}>Value 4</Select.Option>
</Select>
§Rendering options with different heights
Options have a fixed height according to the size
property. If you need to render options with different heights, you can use the option.data
property. It will store information about what height you need to set for the options, as well as the getOptionHeight
property to set this value.
<Select
getOptionHeight={(option) => option.data.height}
>
<Select.Option value="val_1" data={{height: 20}}>Value 1</Select.Option>
<Select.Option value="val_2" data={{height: 40}}>Value 2</Select.Option>
<Select.Option value="val_3" data={{height: 60}}>Value 3</Select.Option>
<Select.Option value="val_4" data={{height: 80}}>Value 4</Select.Option>
</Select>
§Rendering custom popup
To render custom popup, use the renderPopup
property.
<Select
filterable
placeholder="Custom popup"
renderPopup={({renderList, renderFilter}) => {
return (
<React.Fragment>
{renderFilter()}
<div style={{width: "100%", height: "20px", backgroundColor: "tomato"}} />
{renderList()}
</React.Fragment>
);
}}
>
<Select.Option value="val_1" data={{color: '#8FE1A1'}}>Value 1</Select.Option>
<Select.Option value="val_2" data={{color: '#38C0A8'}}>Value 2</Select.Option>
<Select.Option value="val_3" data={{color: '#3A7AC3'}}>Value 3</Select.Option>
<Select.Option value="val_4" data={{color: '#534581'}}>Value 4</Select.Option>
</Select>
§Error
This Select
state is for incorrect user input. To change the Select
appearance, use the validationState
property with the "invalid"
value. Optionally, you can provide an error message through the errorMessage
property. By default, the message text is rendered outside the component.
You can change this with the errorPlacement
property.
<Select
placeholder="Placeholder"
errorMessage="Error message"
validationState="invalid"
>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
<Select
placeholder="Placeholder"
errorPlacement="inside"
errorMessage="Error message"
validationState="invalid"
>
<Select.Option value="val_1">Value 1</Select.Option>
<Select.Option value="val_2">Value 2</Select.Option>
<Select.Option value="val_3">Value 3</Select.Option>
<Select.Option value="val_4">Value 4</Select.Option>
</Select>
§Properties
Name | Description | Type | Default |
---|---|---|---|
className | Control className | string | |
defaultValue | Default values that represent selected options in case of using an uncontrolled state | string[] | |
disabled | Shows that the user cannot work with the control | boolean | false |
filterable | Shows that select popup has a filter section | boolean | false |
filterOption | Used to compare option with filter | function | |
filterPlaceholder | Default filter input placeholder text | string | |
getOptionHeight | Used to set height of customized user options | function | |
getOptionGroupHeight | Used to set height of customized user option group | function | |
hasClear | Enables displaying icon for clearing selected options | boolean | false |
id | id HTML attribute | string | |
label | Control label | string | |
loading | Adds the loading item to the end of the option list. Works like a persistent loading indicator while the options list is empty. | boolean | |
multiple | Shows whether multiple options can be selected in the list | boolean | false |
name | Name of the control | string | |
onBlur | Handler that is called when the element loses focus. | function | |
filter | Controlled filter value | string | '' |
onFilterChange | Fires every time after changing the filter | function | |
onFocus | Handler that is called when the element gets focus | function | |
onLoadMore | Fires when the loading indicator gets visible | function | |
onOpenChange | Fires every time after changing popup visibility | function | |
onUpdate | Fires when an alteration to the Select value is committed by the user | function | |
options | Options to select | (SelectOption | SelectOptionGroup)[] | |
pin | Control border view | string | 'round-round' |
placeholder | Placeholder text | string | |
popupClassName | Popup with the option list className | string | |
popupPlacement | Popup placement | PopupPlacement Array<PopupPlacement> | ['bottom-start', 'bottom-end', 'top-start', 'top-end'] |
popupWidth | Popup width | number | 'fit' | 'outfit' | 'outfit' |
qa | Test id attribute (data-qa ) | string | |
renderControl | Used to render user control | function | |
renderEmptyOptions | Used to render a node for an empty option list | function | |
renderFilter | Used to render user filter section | function | |
renderOption | Used to render user options | function | |
renderOptionGroup | Used to render user option groups | function | |
renderSelectedOption | Used to render user selected options | function | |
renderPopup | Used to render user popup content | function | |
size | Control / options size | string | 'm' |
value | Values that represent selected options | string[] | |
view | Control view | string | 'normal' |
virtualizationThreshold | Option count threshold after which virtualization is enabled | number | 50 |
width | Control width | string | number | undefined |
errorMessage | Error text | string | |
errorPlacement | Error position | outside inside | outside |
validationState | Validation state | "invalid" | |
hasCounter | Shows the selected option count. The counter appears only when the multiple selection is enabled. | boolean |
§CSS API
Name | Description |
---|---|
--g-select-focus-outline-color | Outline color if focused (missing by default) |