Select

Maintainer:
korvin89
GitHub
size
pin
placeholder
label
multiple
filterable
disabled
hasClear
hasCounter
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>

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

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

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
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Порог количества опций, после которого включается виртуализация.number50
widthШирина контролаstring | numberundefined
errorMessageТекст ошибки.string
errorPlacementПоложение отображения ошибки.outside insideoutside
validationStateСостояние валидации."invalid"
hasCounterПоказывает количество выбранных опций. Счетчик появляется только тогда, когда включен множественный выбор.boolean

API CSS

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