import {Select} from '@gravity-ui/uikit';
Компонент Select — это контрол, который предоставляет список опций для выбора.
§Options
Опции для выбора.
§Определение опций
Опции можно определять в виде массива объектов или в качестве дочерних элементов компонента. Первый способ подходит для случаев, когда опции требуют сложной подготовки и, возможно, запоминания. Второй способ удобен, когда опций немного и их настройка не требует сложных вычислений.
§Одноуровневый список
Array of objects
Child nodes
<Select
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>
<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>§Группированный список
Array of objects
Child nodes
<Select
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>
<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>§Хранение данных в опциях
С помощью свойства option.data можно определить и сохранить уникальные данные в каждой опции. Это может быть полезно при необходимости обогащения данных с использованием обратного вызова onUpdate или, например, при отрисовке опций с помощью renderOption.
§Выбор нескольких опций
Чтобы включить множественный выбор, используйте свойство multiple. Значение по умолчанию — false.
<Select multiple={true}>
<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>§Счетчик
С помощью свойства hasCounter в компонент можно добавить счетчик выбранных опций.
<Select multiple={true} hasCounter={true}>
<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>§Фильтрация опций
Для активации секции фильтрации в списке опций используйте свойство filterable. Значение по умолчанию — false.
<Select filterable={true}>
<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. Размер по умолчанию — 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>§Ширина контрола
По умолчанию ширина контрола растягивается, чтобы соответствовать ширине содержимого выбранных опций. Вы можете самостоятельно регулировать ширину с помощью свойства width:
'max' — растягивает ширину контрола на всю ширину родительского элемента.
number — применяет ширину в пикселях.
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>§Ширина списка опций.
Ширину списка опций можно изменять с помощью свойства popupWidth. Возможные значения:
'fit' — применяет ширину контрола.
number — применяет ширину в пикселях.
Особенности поведения по умолчанию:
-
Ширина списка опций соответствует ширине самой широкой опции, но не превышает
90vw. Это не применимо, если используется виртуализация. -
Узкие опции растягиваются до ширины контрола.
§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>§Виртуализированный список
Для оптимального отображения большого количества опций в компоненте Selectпредусмотрен встроенный инструмент виртуализации списка. Виртуализация включается, когда количество опций превышает пороговое значение (по умолчанию 50). Пороговое значение можно изменить с помощью свойства virtualizationThreshold.
При включении виртуализации к элементу списка опций применяются определенные ограничения:
-
Ширина списка опций больше не изменяется в зависимости от длины самой длинной опции.
-
Минимальная ширина списка опций равна ширине контрола или
100px, если ширина контрола меньше100px.
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>§Расширенное использование
Существует множество способов настроить Select более тонко.
§Рендеринг пользовательского контрола
Для создания пользовательского контрола используйте свойство renderControl.
Обратите внимание, что для правильной работы контрола необходимо передать все аргументы в узел (как при использовании стандартной конфигурации).
<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>§Отображение секции пользовательской фильтрации
Для отображения секции пользовательской фильтрации используйте свойство renderFilter и установите filterable в значение true.
Обратите внимание, что для правильной работы фильтра необходимо передать все аргументы в узел (как при использовании стандартной конфигурации).
<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>§Отображение пользовательских опций
Для отображения пользовательских опций используйте свойство renderOption:
<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>§Отображение выбранных пользовательских опций
Для отображения выбранных пользовательских опций используйте свойство renderSelectedOption:
<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>§Отображение опций с разной высотой
Опции имеют фиксированную высоту, в соответсвии с заданным свойством size. Если нужно отобразить опции с разной высотой, используйте свойство option.data, которое будет содержать информацию о требуемой высоте опции, а также getOptionHeight для установки этого значения.
<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>§Отображение пользовательского счетчика опций
Для отображения пользовательского счетчика опций используйте свойство renderCounter. Счетчик отображается только при включенном множественном выборе (multiple={true}) и hasCounter={true}.
<Select
multiple={true}
hasCounter={true}
renderCounter={(_, {count, disabled}) => {
if (count === 0) {
return null;
}
if (count >= 2) {
return (
<div
style={{
padding: '0 8px',
color: disabled ? '#999' : '#027bf3',
fontWeight: 'bold',
}}
>
+{count}
</div>
);
}
return count;
}}
>
<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>§Отображение списка опций
Свойство renderPopup позволяет управлять содержимым списка опций: изменять порядок стандартных элементов (фильтр, список), скрывать их или добавлять собственные элементы между ними, до или после них.
<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 (ошибка)
Это состояние Select указывает на некорректный ввод данных пользователем. Для изменения внешнего представления Select примените свойство validationState, задав ему значение "invalid". Опционально можно задать текст сообщения об ошибке через свойство errorMessage. По умолчанию текст сообщения выводится вне компонента.
Место вывода сообщения можно изменить с помощью свойства errorPlacement.
<Select placeholder="Placeholder" errorMessage="Error message" validationState="invalid" />
<Select placeholder="Placeholder" errorPlacement="inside" errorMessage="Error message" validationState="invalid" />§Свойства
| Имя | Описание | Тип | Значение по умолчанию |
|---|---|---|---|
| className | Имя класса контрола. | string | |
| defaultValue | Значения по умолчанию для выбранных опций в случае использования неуправляемого состояния. | string[] | |
| disabled | Указывает на то, что пользователь не может взаимодействовать с контролом. | boolean | false |
| filterable | Указывает на то, что список опций содержит секцию фильтрации. | boolean | false |
| filterOption | Используется для сравнения опции со значением фильтра. | function | |
| filterPlaceholder | Текст-заглушка по умолчанию для поля ввода фильтра. | string | |
| getOptionHeight | Используется для задания высоты опций. | function | |
| getOptionGroupHeight | Используется для задания высоты заголовка группы опций. | function | |
| hasClear | Позволяет отображать иконку для очистки выбранных опций. | boolean | false |
| id | HTML-атрибут id. | string | |
| label | Лейбл контрола. | string | |
| loading | Добавляет элемент загрузки в конец списка опций. Работает как постоянный индикатор загрузки, пока список опций пуст. | boolean | |
| multiple | Включает множественный выбор опций. | boolean | false |
| name | Имя контрола. | string | |
| onBlur | Обработчик, который вызывается, когда элемент теряет фокус. | function | |
| filter | Контролируемое значение фильтра. | string | '' |
| onFilterChange | Срабатывает при каждом изменении фильтра. | function | |
| onFocus | Обработчик, который вызывается, когда элемент получает фокус. | function | |
| onLoadMore | Срабатывает, когда индикатор загрузки становится видимым. | function | |
| onOpenChange | Срабатывает при каждом изменении видимости списка опций. | function | |
| onUpdate | Срабатывает, когда пользователь подтверждает изменение значения Select. | function | |
| options | Конфигурация опций. | (SelectOption | SelectOptionGroup)[] | |
| pin | Вид границ контрола. | string | 'round-round' |
| placeholder | Текст-заглушка. | string | |
| popupClassName | Имя класса (className) для списка опций. | string | |
| popupPlacement | Размещение списка опций относительно контрола. | PopupPlacement Array<PopupPlacement> | ['bottom-start', 'bottom-end', 'top-start', 'top-end'] |
| popupWidth | Ширина списка опций. | number | 'fit' | 'outfit' | 'outfit' |
| qa | Атрибут идентификатора для тестирования (data-qa). | string | |
| renderControl | Используется для рендеринга пользовательского контрола. | function | |
| renderCounter | Используется для рендеринга пользовательского счетчика. Работает только с hasCounter. | function | |
| renderEmptyOptions | Используется для рендеринга узла для пустого списка опций. | function | |
| renderFilter | Используется для рендеринга секции пользовательской фильтрации. | function | |
| renderOption | Используется для рендеринга пользовательских опций. | function | |
| renderOptionGroup | Используется для рендеринга заголовков групп опций. | function | |
| renderSelectedOption | Используется для рендеринга выбранных опций. | function | |
| renderPopup | Используется для рендеринга содержимого списка опций. | function | |
| size | Размер контрола и опций. | string | 'm' |
| value | Значения для выбранных опций, которые передаются в обработчик onUpdate. | string[] | |
| view | Вид контрола. | string | 'normal' |
| virtualizationThreshold | Порог количества опций, после которого включается виртуализация. | number | 50 |
| width | Ширина контрола | string | number | undefined |
| errorMessage | Текст ошибки. | string | |
| errorPlacement | Положение отображения ошибки. | outside inside | outside |
| validationState | Состояние валидации. | "invalid" | |
| hasCounter | Показывает количество выбранных опций. Счетчик появляется только тогда, когда включен множественный выбор. | boolean |
§API CSS
| Имя | Описание |
|---|---|
--g-select-focus-outline-color | Цвет обводки при фокусе на элементе (по умолчанию отсутствует). |