Select
Адаптивный компонент для выбора одного значения из списка опций. Автоматически переключается между компонентом
NativeSelect
(для мобильных устройств) и CustomSelect
(в остальных случаях).
Связанные компоненты:
Режим работы
Компонент поддерживает работу как в неконтролируемом режиме, так и контролируемом. Это стандартное поведение React-компонентов, прочитать про это можно в документации React ↗.
Для использования неконтролируемого режима достаточно просто не передавать value
или передавать defaultValue
, если
требуется задать значение по умолчанию.
Для контролируемого режима используйте связку свойств value
/onChange
для задания значения и его изменения.
const colors = [
{
value: 'red',
label: 'Красный',
},
{
value: 'green',
label: 'Зелёный',
},
{
value: 'blue',
label: 'Синий',
},
];
// Неконтролируемое состояние
<Select options={colors} defaultValue="red" />;
// Контролируемое состояние
const [color, setColor] = React.useState('red');
<Select options={colors} value={color} onChange={(_, newColor) => setColor(newColor)} />;
Состояния
disabled
Свойство disabled
блокирует взаимодействие с компонентом и добавляет визуальную индикацию недоступности.
Валидация
Свойство status
используется для визуализации валидации компонента - некорректности заполненного поля (значение "error"
)
или успешной валидации (значение "valid"
).
Тестирование (e2e)
Если Select
отрисовывает NativeSelect
, то достаточно передать testId
через data-*
аттрибут для поиска элемента на странице.
Если Select
отрисовывает CustomSelect
, то следуйте рекомендациям из раздела “Тестирование (e2e)” компонента CustomSelect
.
<View activePanel="select">
<Panel id="select">
<PanelHeader>Select</PanelHeader>
<Group>
<FormItem
top="Администратор"
htmlFor="select-id"
bottom="Пример использования Select для выбора администратора из списка"
>
<Select
id="select-id"
placeholder="Не выбран"
options={getRandomUsers(10).map((user) => ({
label: user.name,
value: user.id,
avatar: user.photo_100,
}))}
renderOption={({ option, ...restProps }) => (
<CustomSelectOption
{...restProps}
key={option.value}
before={<Avatar size={24} src={option.avatar} />}
/>
)}
/>
</FormItem>
</Group>
</Panel>
</View>
Доступность (a11y)
Старайтесь сопровождать элемент текстовым описанием, для корректной работы скринридеров. Для этого необходимо вручную передавать некоторые параметры:
- При задании текстового описания с помощью элемента
label
передавайтеid
компонента в свойствоhtmlFor
элементаlabel
. Это позволит фокусироваться на компоненте кликом по заголовку и автоматически добавит имя компоненту для скринридеров. - Если по какой-то причине текстовое описание компонента не получается обернуть в тэг
label
, то можно попробовать связать текстовое описание с компонентом через aria-labelledby ↗. Для этого передайтеid
текстового элемента компоненту в свойство aria-labelledby ↗. - При отсутствии по дизайну у выпадающего списка текстового описания старайтесь всё же его добавлять,
но прятать с помощью элемента
VisuallyHidden
, чтобы оно оставалось доступно для пользователей ассистивных технологий. В крайнем случае используйте aria-label ↗ аттрибут. - При использовании вместе с
FormItem
следуйте рекомендациям раздела “Цифровая доступность” компонентаFormItem
.
Старайтесь сопровождать элемент свойством placeholder
.
Пример рекомендуемого использования компонента Select
с текстовым описанием:
- вместе с
label
<label htmlFor="select-id">Цвет</label>
<Select
id="select-id"
placeholder="Не выбран"
options={[ id: 'red', name: 'Красный' ]}
/>
- вместе с
FormItem
<FormItem top="Цвет" htmlFor="select-id">
<Select id="select-id" placeholder="Не выбран" options={[ id: 'red', name: 'Красный' ]} />
</FormItem>
- вместе с
VisuallyHidden
(используяlabel
иhtmlFor
)
<VisuallyHidden Component="label" htmlFor="select-id">Цвет</VisuallyHidden>
<Select
id="select-id"
placeholder="Не выбран"
options={[ id: 'red', name: 'Красный' ]}
/>
- вместе с aria-labelledby ↗
<span id="select-label-id">Цвет</span>
<Select
aria-labelledby="select-label-id"
placeholder="Не выбран"
options={[ id: 'red', name: 'Красный' ]}
/>
- вместе с
VisuallyHidden
(используя aria-labelledby ↗)
<VisuallyHidden Component="span" id="select-label-id">Цвет</VisuallyHidden>
<Select
aria-labelledby="select-label-id"
placeholder="Не выбран"
options={[ id: 'red', name: 'Красный' ]}
/>
- вместе с aria-label ↗
<Select aria-label="Цвет" placeholder="Не выбран" options={[ id: 'red', name: 'Красный' ]} />
Свойства и методы
Свойство | Описание |
---|---|
after | ReactNode Добавляет иконку справа. Рекомендации:
По умолчанию: - |
afterAlign | FieldIconsAlign Вертикальное выравнивание иконки справа. По умолчанию: - |
align | AlignType По умолчанию: - |
allowClearButton | boolean Если По умолчанию: - |
before | ReactNode Добавляет иконку слева. Рекомендации:
По умолчанию: - |
beforeAlign | FieldIconsAlign Вертикальное выравнивание иконки слева. По умолчанию: - |
ClearButton | ComponentType<CustomSelectClearButtonProps> Кастомная кнопка для очистки значения.
Должна принимать обязательное свойство По умолчанию: - |
clearButtonTestId | string Передает атрибут По умолчанию: - |
defaultValue | SelectValue См. По умолчанию: - |
dropdownAutoWidth | boolean Ширина раскрывающегося списка зависит от контента. По умолчанию: - |
dropdownOffsetDistance | number Отступ от выпадающего списка. По умолчанию: - |
emptyText | string Текст, который будет отображен, если приходит пустой По умолчанию: - |
fetching | boolean Если По умолчанию: - |
filterFn | false | FilterFn<OptionT> Функция для кастомной фильтрации. По умолчанию поиск производится по По умолчанию: - |
forceDropdownPortal | boolean Использовать Portal для рендеринга выпадающего списка. По умолчанию: - |
getRef | Ref<HTMLSelectElement> По умолчанию: - |
getRootRef | Ref<HTMLDivElement> По умолчанию: - |
getSelectInputRef | Ref<HTMLInputElement> Ref на внутрений компонент input. По умолчанию: - |
icon | ReactNode Иконка раскрывающегося списка. По умолчанию: - |
labelTextTestId | string Передает атрибут По умолчанию: - |
mode | "default" | "plain" Режим отображения.
По умолчанию: - |
multiline | boolean Флаг для включения многострочного режима. По умолчанию: - |
nativeSelectTestId | string Передает атрибут По умолчанию: - |
noMaxHeight | boolean Отключает максимальную высоту по умолчанию. По умолчанию: - |
onChange | ((e: ChangeEvent<HTMLSelectElement>, newValue: SelectValue) => void) Обработчик, срабатывающий при изменении выбранного значения. Вторым параметром прокидывается новое значение. По умолчанию: - |
onClose | VoidFunction Обработчик закрытия выпадающего списка. По умолчанию: - |
onInputChange | ((e: ChangeEvent<HTMLInputElement>) => void) Событие изменения текстового поля. По умолчанию: - |
onInputKeyDown | ((e: KeyboardEvent<Element>, isOpen: boolean) => void) Обработчик события По умолчанию: - |
onOpen | VoidFunction Обработчик открытия выпадающего списка. По умолчанию: - |
options | OptionT[] Список опций в списке. По умолчанию: - |
overscrollBehavior | "auto" | "none" | "contain" Поведение overscroll, подробнее можно почитать в документации ↗. По умолчанию: - |
placeholder | string Текст-подсказка при отсутствии выбранного значения. По умолчанию: - |
popupDirection | PopupDirection Направление раскрытия выпадающего списка. По умолчанию: - |
renderDropdown | (({ defaultDropdownContent, }: { defaultDropdownContent: ReactNode; }) => ReactNode) Рендер-проп для кастомного рендера содержимого дропдауна.
В По умолчанию: - |
renderOption | ((props: CustomSelectRenderOption<OptionT>) => ReactNode) Рендер-проп для кастомного рендера опции. В объекте аргумента приходят свойства опции ↗. По умолчанию: - |
searchable | boolean Если По умолчанию: - |
selectType | SelectType Тип отображения компонента. По умолчанию: - |
status | "default" | "error" | "valid" Статус отображения поля в форме. По умолчанию: - |
value | SelectValue Выбранное значение. По умолчанию: - |