Select

Maintainer:
korvin89
GitHub
size
pin
placeholder
label
multiple
filterable
disabled
hasClear
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 в компонент можно добавить счетчик выбранных вариантов.

0
<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>

Отображение выбранных пользовательских вариантов

Для отображения выбранных пользовательских вариантов используйте свойство renderOption:

<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>

Отображение пользовательских всплывающих окон

Для отображения пользовательских всплывающих окон используйте свойство 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.

Error message
<Select placeholder="Placeholder" errorMessage="Error message" validationState="invalid" />
<Select placeholder="Placeholder" errorPlacement="inside" errorMessage="Error message" validationState="invalid" />

Свойства

ИмяОписаниеТипЗначение по умолчанию
classNameИмя класса контрола.string
defaultValueЗначения по умолчанию для выбранных вариантов в случае использования неуправляемого состояния.string[]
disabledУказывает на то, что пользователь не может взаимодействовать с контролом.booleanfalse
filterableУказывает на то, что всплывающее окно выбора содержит секцию фильтрации.booleanfalse
filterOptionИспользуется для сравнения варианта со значением фильтра.function
filterPlaceholderТекст-заглушка по умолчанию для поля ввода фильтра.string
getOptionHeightИспользуется для задания высоты пользовательских вариантов.function
getOptionGroupHeightИспользуется для задания высоты группы пользовательских вариантов.function
hasClearПозволяет отображать иконку для очистки выбранных вариантов.booleanfalse
idHTML-атрибут id.string
labelЛейбл контрола.string
loadingДобавляет элемент загрузки в конец списка вариантов. Работает как постоянный индикатор загрузки, пока список вариантов пуст.boolean
multipleУказывает на наличие возможности выбора несколько вариантов в списке.booleanfalse
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
renderEmptyOptionsИспользуется для рендеринга узла для пустого списка вариантов.function
renderFilterИспользуется для рендеринга секции пользовательской фильтрации.function
renderOptionИспользуется для рендеринга пользовательских вариантов.function
renderOptionGroupИспользуется для рендеринга групп пользовательских вариантов.function
renderSelectedOptionИспользуется для рендеринга выбранных пользователем вариантов.function
renderPopupИспользуется для рендеринга содержимого пользовательского всплывающего окна.function
sizeРазмер контрола / вариантов.string'm'
valueЗначения для выбранных вариантов.string[]
viewВид контрола.string'normal'
virtualizationThresholdПорог количества вариантов, после которого включается виртуализация.number50
widthШирина контролаstring | numberundefined
errorMessageТекст ошибки.string
errorPlacementПоложение отображения ошибки.outside insideoutside
validationStateСостояние валидации."invalid"
hasCounterПоказывает количество выбранных вариантов. Счетчик появляется только тогда, когда включен множественный выбор.boolean

API CSS

ИмяОписание
--g-select-focus-outline-colorЦвет обводки при фокусе на элементе (по умолчанию отсутствует).