ComboBox#
Усложненный вариант базового компонента Select. Имеет в себе функциональность фильтрации, множественного выбора, очистки поля. Одиночный выбор рекомендуется использовать, когда нужна фильтрация по полю. В остальных случаях рекомендуется использовать Select.
import { ComboBox } from '@v-uik/combo-box'
№ |
Свойство |
Описание |
Значение по умолчанию |
|---|---|---|---|
1 |
canClear |
Очистка поля (boolean) |
- |
2 |
disableVisibleSelectedValue |
Отключить отображение выбранных опций внутри поля (boolean) |
- |
3 |
delimiter |
Разделитель для опций в режиме multiple, без тегов (string) |
- |
4 |
disabled |
Заблокировать поле (boolean) |
- |
5 |
dropdownProps |
Свойства компонента Dropdown (Partial |
- |
6 |
error |
Индикатор ошибки (boolean) |
- |
7 |
errorIconTooltipProps |
Свойства компонента Tooltip для иконки ошибки |
- |
8 |
filterOption |
Функция для переопределения логики поиска |
- |
9 |
getOptionLabel |
Функция переопределения заголовка опции |
- |
10 |
getOptionPrefix |
Функция переопределения префикса выводимого в элементе опции |
- |
11 |
getOptionSuffix |
Функция переопределения суффикса выводимого в элементе опции |
- |
12 |
getOptionValue |
Функция переопределения значения опции |
- |
13 |
groupBy |
Группировка опций по признаку |
- |
14 |
helperText |
Подпись под полем выбора (ReactNode) |
- |
15 |
helperTextProps |
Свойства компонента InputHelperText (InputHelperTextProps) |
- |
16 |
inputValue |
Значение текстового поля (string) |
- |
17 |
isOptionDisabled |
Функция переопределения логики блокировки опции |
- |
18 |
isSearchable |
Разрешен ли поиск (boolean) |
- |
19 |
label |
Подпись над полем выбора (ReactNode) |
- |
20 |
labelProps |
Свойства компонента InputLabel (InputLabelProps) |
- |
21 |
limitByWidth |
Данный флаг устанавливает максимальную ширину выпадающего списка равной ширине самого поля (boolean) |
- |
22 |
listProps |
Свойства компонента List |
- |
23 |
noOptionsText |
Текст, если ничего не найдено (string) |
- |
24 |
onInputChange |
Обработчик изменения текстового поля |
- |
25 |
openOnFocus |
Если true, всплывающее окно откроется при фокусе на поле (boolean) |
- |
26 |
options |
Список опций ( |
- |
27 |
placeholder |
Заполнитель поля — подсказка внутри поля (string) |
- |
28 |
rows |
Количество отображаемых строк за один раз внутри выпадающего списка (number) |
- |
29 |
showErrorIcon |
Показать дополнительную иконку ошибки (boolean) |
- |
30 |
size |
Размер поля: "sm", "md", "lg" |
"md" |
31 |
ref |
|
- |
32 |
value |
Текущее значение |
- |
33 |
onChange |
Обработчик события выбора опции |
- |
34 |
multiple |
Включить мультивыбор (boolean) |
- |
35 |
disableCloseOnSelect |
Отключить закрытие при выборе опции. Неактуален для одиночного выбора (boolean) |
- |
36 |
withTags |
Выбранные опции отображаются в виде тегов. Неактуален для одиночного выбора (boolean) |
- |
37 |
limitTags |
Настраивает количество отображаемых тегов, если включена опция withTags для отображение тегов в поле ввода. Если опций будет больше указанного лимита, они будут скрыты и появится тег с указанием скрытых опций, формата +n (number) |
- |
38 |
selectOnFocus |
Выделять слово в текстовом поле при фокусе. Неактуален для множественного выбора (boolean) |
- |
39 |
classes |
CSS классы компонента: |
- |
Единичный выбор#
За открытие выпадающего списка при фокусе на элементе отвечает свойство openOnFocus.
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: '1', label: 'Lorem 1', suffix: 'suffix' },
{ value: '2', label: 'Options 2' },
{ value: '3', label: 'Optional 3' },
{ value: '4', label: 'First 11' },
{ value: '5', label: 'Last 5' },
{ value: '6', label: 'Lucan 6' },
{ value: '7', label: 'Fierro 7' },
{ value: '8', label: 'Long option number is so long option 11' },
{ value: '9', label: 'Option 9' },
{ value: '10', label: 'Option 10' },
{ value: '11', label: 'Lorem ispum 11' },
{ value: '12', label: 'Ferrari 12' },
]
export const SingleSelect = (): JSX.Element => {
const [value, setValue] = React.useState<string>('')
return (
<div style={{ width: 250 }}>
<ComboBox
canClear
isSearchable
openOnFocus
helperText="Helper Text"
label="Label"
options={options}
placeholder="Введите сюда текст"
value={value}
onChange={setValue}
/>
</div>
)
}
Множественный выбор#
Для множественного выбора используется параметр multiple. За открытие выпадающего списка при фокусе на элементе отвечает свойство openOnFocus.
Чтобы выпадающий список не закрывался при выборе нескольких значений, используйте свойство disableCloseOnSelect.
В этом случае список закрывается по клику за пределами вы списка.
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
export const options = [
{ value: '1', label: 'Опция 1' },
{ value: '2', label: 'Опция 2' },
{ value: '3', label: 'Опция 3' },
{ value: '4', label: 'Опция 4' },
{ value: '5', label: 'Опция 5' },
{ value: '6', label: 'Длинная опция 6' },
{ value: '7', label: 'Опция 7' },
{ value: '8', label: 'Опция 8' },
{ value: '9', label: 'Опция 9' },
{ value: '10', label: 'Опция 10' },
{ value: '11', label: 'Опция 11' },
{ value: '12', label: 'Длинная опция 12', disabled: true },
{ value: '13', label: 'Опция 13' },
{ value: '14', label: 'Опция 14' },
{ value: '15', label: 'Опция 15' },
{ value: '16', label: 'Опция 16' },
{ value: '17', label: 'Опция 17' },
{ value: '18', label: 'Опция 18' },
{ value: '19', label: 'Опция 19' },
{ value: '20', label: 'Опция 20' },
{ value: '21', label: 'Опция 21' },
{ value: '22', label: 'Длинная опция 22' },
{ value: '23', label: 'Опция 23' },
{ value: '24', label: 'Опция 24' },
{ value: '25', label: 'Опция 25', disabled: true },
{ value: '26', label: 'Невероятно длинная опция имеющая номер 26' },
{ value: '27', label: 'Опция 27' },
{ value: '28', label: 'Опция 28' },
{ value: '29', label: 'Опция 29' },
]
export const MultipleSelect = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>(['1', '22'])
return (
<div style={{ width: 400 }}>
<ComboBox
canClear
disableCloseOnSelect
multiple
openOnFocus
isSearchable
label="Label"
options={options}
value={value}
onChange={setValue}
/>
</div>
)
}
Множественный выбор с поиском#
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: '', label: 'Выберите значение' },
{ value: '1', label: 'Lorem 1' },
{ value: '2', label: 'Options 2' },
{ value: '3', label: 'Optional 3' },
{ value: '4', label: 'First 11' },
{ value: '5', label: 'Last 5' },
{ value: '6', label: 'Lucan 6' },
{ value: '7', label: 'Fierro 7' },
{ value: '8', label: 'Long option number is so long option 11' },
{ value: '9', label: 'Option 9' },
{ value: '10', label: 'Option 10' },
{ value: '11', label: 'Lorem ispum 11' },
{ value: '12', label: 'Ferrari 12' },
]
export const Searchable = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>([])
const mappedOptions = options.sort((a, b) => a.label.localeCompare(b.label)) // asc sort
return (
<ComboBox
multiple
canClear
isSearchable
groupBy={(option) =>
(option as typeof mappedOptions[number]).label.charAt(0)
}
helperText="Helper Text"
label="Label"
options={mappedOptions}
placeholder="Выберите значение"
value={value}
onChange={setValue}
/>
)
}
Ошибка валидации#
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: '1', label: 'Опция 1' },
{ value: '2', label: 'Опция 2' },
{ value: '3', label: 'Опция 3' },
{ value: '4', label: 'Опция 4' },
{ value: '5', label: 'Опция 5' },
{ value: '6', label: 'Длинная опция 6' },
{ value: '7', label: 'Опция 7' },
{ value: '8', label: 'Опция 8' },
{ value: '9', label: 'Опция 9' },
{ value: '10', label: 'Опция 10' },
{ value: '11', label: 'Опция 11' },
{ value: '12', label: 'Длинная опция 1212121212121212121212121212121212' },
]
export const Error = (): JSX.Element => {
const [value, setValue] = React.useState<string>('')
return (
<div style={{ width: 400 }}>
<ComboBox
error
canClear
label="Label"
value={value}
options={options}
helperText="Error Text"
errorIconTooltipProps={{
dropdownProps: {
placement: 'top',
content: 'Поле не может быть пустым',
},
}}
onChange={setValue}
/>
</div>
)
}
Отображение опций за пределами компонента ComboBox#
Если выбранные значения нужно отобразить за пределами поля выбора, можно воспользоваться параметром disableVisibleData.
В этом случае данные не отобразятся внутри поля. После чего можно отобразить value в любом удобном формате, например, в тегах.
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
import { Tag } from '@v-uik/tag'
const options = [
{ value: '1', label: 'Опция 1' },
{ value: '2', label: 'Опция 2' },
{ value: '3', label: 'Опция 3' },
{ value: '4', label: 'Опция 4' },
{ value: '5', label: 'Опция 5' },
{ value: '6', label: 'Длинная опция 6' },
{ value: '7', label: 'Опция 7' },
{ value: '8', label: 'Опция 8' },
{ value: '9', label: 'Опция 9' },
{ value: '10', label: 'Опция 10' },
{ value: '11', label: 'Опция 11' },
{ value: '12', label: 'Длинная опция 12', disabled: true },
]
export const OutsideTags = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>(['1', '6', '10'])
return (
<div style={{ width: 400 }}>
{value?.map((value) => (
<Tag key={value} selected style={{ margin: '0 4px 4px 0' }} kind="lite">
{options.find((item) => item.value === value)?.label}
</Tag>
))}
<ComboBox
multiple
disableVisibleSelectedValue
disableCloseOnSelect
label="Label"
rows={6}
value={value}
options={options}
onChange={setValue}
/>
</div>
)
}
Разделитель между опциями#
Разделители опций можно настроить через объект listProps параметром stripe.
import React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: '1', label: 'Опция 1' },
{ value: '2', label: 'Опция 2' },
{ value: '3', label: 'Опция 3' },
{ value: '4', label: 'Опция 4' },
{ value: '5', label: 'Опция 5' },
{ value: '6', label: 'Длинная опция 6' },
{ value: '7', label: 'Опция 7' },
{ value: '8', label: 'Опция 8' },
{ value: '9', label: 'Опция 9' },
{ value: '10', label: 'Опция 10' },
{ value: '11', label: 'Опция 11' },
{ value: '12', label: 'Длинная опция 12', disabled: true },
{ value: '13', label: 'Опция 13' },
{ value: '14', label: 'Опция 14' },
{ value: '15', label: 'Опция 15' },
{ value: '16', label: 'Опция 16' },
{ value: '17', label: 'Опция 17' },
{ value: '18', label: 'Опция 18' },
{ value: '19', label: 'Опция 19' },
{ value: '20', label: 'Опция 20' },
{ value: '21', label: 'Опция 21' },
{ value: '22', label: 'Длинная опция 22' },
{ value: '23', label: 'Опция 23' },
{ value: '24', label: 'Опция 24' },
{ value: '25', label: 'Опция 25', disabled: true },
{ value: '26', label: 'Невероятно длинная опция имеющая номер 26' },
{ value: '27', label: 'Опция 27' },
{ value: '28', label: 'Опция 28' },
{ value: '29', label: 'Опция 29' },
]
export const DividerOptions = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>([])
return (
<ComboBox
multiple
canClear
withTags
isSearchable
listProps={{ stripe: true }}
label="Label"
value={value}
options={options}
onChange={setValue}
/>
)
}
Замена содержимого опций#
Внутри опций выпадающего списка можно размещать кастомное содержимое. За это поведение отвечают свойства
prefix и suffix массива с опциями.
import React from 'react'
import { ComboBox } from '@v-uik/combo-box'
import { Icon } from './assets/Icon'
const options = [
{ value: '1', label: 'Опция 1', prefix: <Icon /> },
{ value: '2', label: 'Опция 2', prefix: <Icon /> },
{ value: '3', label: 'Опция 3', prefix: <Icon /> },
{ value: '4', label: 'Опция 4', prefix: <Icon /> },
]
export const OptionsWithIcon = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>([])
return (
<div style={{ width: 320 }}>
<ComboBox
canClear
limitByWidth
multiple
openOnFocus
withTags
label="Label"
value={value}
options={options}
onChange={setValue}
/>
</div>
)
}
Опции с заголовком и описанием
Обычно для отображения значения используется свойство label, которое можно считать заголовком опции.
Если требуется добавить описание, используйте свойство description. В этом случаев
label получит жирное начертание, а description отобразится под label.
import React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{
value: '1',
label: 'Option 1',
description: 'Консультация по учетной записи в СУДИР/Домене',
multilineDisplay: true,
},
{
value: '2',
label: 'Option 2',
description:
'Создание/изменение шаблонов заявок на доступ к ФИР (в рамках УниФИР)',
},
{
value: '3',
label: 'Option 3',
description: 'Назначение согласующего по доступам',
},
{
value: '4',
label: 'Option 4',
description:
'Предоставление доступа к МГ/Местной/Мобильной связи/Международной связи',
multilineDisplay: true,
},
]
export const OptionsWithTitle = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>(['1'])
return (
<div style={{ width: 286 }}>
<ComboBox
limitByWidth
multiple
canClear
withTags
openOnFocus
label="Label"
value={value}
options={options}
onChange={setValue}
/>
</div>
)
}
Компактное отображение тегов#
Для компактных интерфейсов существует решение по отображению n-тегов,
или, в случае 0, просто отображается счетчик. За это отвечает параметр limitTags.
Если указать отрицательное значение, будет считаться как 0.
import React from 'react'
import { ComboBox } from '@v-uik/combo-box'
import { InputNumber } from '@v-uik/input-number'
const options = [
{ value: '1', label: 'Опция 1' },
{ value: '2', label: 'Опция 2' },
{ value: '3', label: 'Опция 3' },
{ value: '4', label: 'Опция 4' },
{ value: '5', label: 'Опция 5' },
{ value: '6', label: 'Длинная опция 6' },
{ value: '7', label: 'Опция 7' },
{ value: '8', label: 'Опция 8' },
{ value: '9', label: 'Опция 9' },
{ value: '10', label: 'Опция 10' },
{ value: '11', label: 'Опция 11' },
{ value: '12', label: 'Длинная опция 12', disabled: true },
{ value: '13', label: 'Опция 13' },
{ value: '14', label: 'Опция 14' },
{ value: '15', label: 'Опция 15' },
{ value: '16', label: 'Опция 16' },
{ value: '17', label: 'Опция 17' },
{ value: '18', label: 'Опция 18' },
{ value: '19', label: 'Опция 19' },
{ value: '20', label: 'Опция 20' },
{ value: '21', label: 'Опция 21' },
{ value: '22', label: 'Длинная опция 22' },
{ value: '23', label: 'Опция 23' },
{ value: '24', label: 'Опция 24' },
{ value: '25', label: 'Опция 25', disabled: true },
{ value: '26', label: 'Невероятно длинная опция имеющая номер 26' },
{ value: '27', label: 'Опция 27' },
{ value: '28', label: 'Опция 28' },
{ value: '29', label: 'Опция 29' },
]
export const CompactTags = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>(['1', '6', '26', '29'])
const [limitTags, setLimitTags] = React.useState<number | null>(3)
return (
<div style={{ width: 300 }}>
<InputNumber
precision={0}
value={limitTags}
label="Ограничить количество тегов"
onChange={setLimitTags}
/>
<ComboBox
multiple
withTags
openOnFocus
disableCloseOnSelect
limitTags={limitTags as number}
label="Label"
value={value}
options={options}
onChange={setValue}
/>
</div>
)
}
Группировка#
Группирует элементы с помощью опции groupBy.
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: '1', label: 'Lorem 1' },
{ value: '2', label: 'Options 2' },
{ value: '3', label: 'Optional 3' },
{ value: '4', label: 'First 11' },
{ value: '5', label: 'Last 5' },
{ value: '6', label: 'Lucan 6' },
{ value: '7', label: 'Fierro 7' },
{ value: '8', label: 'Long option number is so long option 11' },
{ value: '9', label: 'Option 9' },
{ value: '10', label: 'Option 10' },
{ value: '11', label: 'Lorem ispum 11' },
{ value: '12', label: 'Ferrari 12' },
]
export const Grouping = (): JSX.Element => {
const [value, setValue] = React.useState<string>('')
const mappedOptions = options.sort((a, b) => a.label.localeCompare(b.label)) // asc sort
return (
<div style={{ width: 250 }}>
<ComboBox
canClear
isSearchable
openOnFocus
groupBy={(option) =>
(option as typeof mappedOptions[number]).label.charAt(0)
}
helperText="Helper Text"
label="Label"
options={mappedOptions}
placeholder="Введите сюда текст"
value={value}
onChange={setValue}
/>
</div>
)
}
Конфигурация поиска#
Из пакета @v-uik/combo-box поставляется функция-конфигуратор createFilter с помощью которой можно легко конфигурировать поиск.
Также поиск можно настроить самостоятельно.
import * as React from 'react'
import { ComboBox, createFilter } from '@v-uik/combo-box'
import { CheckboxGroup } from '@v-uik/checkbox-group'
import { LabelControl } from '@v-uik/label-control'
import { Checkbox } from '@v-uik/checkbox'
const options = [
{ value: 'ocean', label: 'Ocean' },
{ value: 'blue', label: 'Blue' },
{ value: 'purple', label: 'Purple' },
{ value: 'red', label: 'Red' },
{ value: 'orange', label: 'Orange' },
{ value: 'yellow', label: 'Yellow' },
{ value: 'green', label: 'Green' },
{ value: 'forest', label: 'Forest' },
{ value: 'slate', label: 'Slate' },
{ value: 'silver', label: 'Silver' },
]
export const AdvancedSearch = (): JSX.Element => {
const [checkboxValue, setCheckboxValue] = React.useState<string[]>([])
const handleChange = (value: string[] | undefined) => {
setCheckboxValue(value ?? [])
}
const filterConfig = {
ignoreCase: checkboxValue.includes('ignoreCase'),
trim: checkboxValue.includes('trim'),
matchFrom: checkboxValue.includes('matchFrom')
? ('start' as const)
: ('any' as const),
}
const [value, setValue] = React.useState<string>('')
return (
<div style={{ width: 350 }}>
<ComboBox
isSearchable
filterOption={createFilter(filterConfig)}
label="Label"
options={options}
placeholder="Введите сюда текст"
value={value}
onChange={setValue}
/>
<CheckboxGroup
label="Конфигурация поиска"
value={checkboxValue}
direction="vertical"
onChange={(_, value) => handleChange(value)}
>
<LabelControl
label="Игнорирование пробелов"
name="debt"
control={<Checkbox />}
/>
<LabelControl
name="ignoreCase"
control={<Checkbox />}
label="Игнорирование регистра"
/>
<LabelControl
name="matchFrom"
control={<Checkbox />}
label="Откуда начинать поиск"
/>
</CheckboxGroup>
</div>
)
}
Замена заголовка опции и значения опции#
При помощи параметра getOptionLabel можно конфигурировать отображаемое значение из объекта, а при помощи getOptionValue заменять исходное значение value.
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
import { Text } from '@v-uik/typography'
const options = [
{ value: 'vanilla', label: 'Vanilla', rating: 'safe' },
{ value: 'chocolate', label: 'Chocolate', rating: 'good' },
{ value: 'strawberry', label: 'Strawberry', rating: 'wild' },
{ value: 'salted-caramel', label: 'Salted Caramel', rating: 'crazy' },
]
export const ReplaceLabel = (): JSX.Element => {
const [value, setValue] = React.useState<string>('')
return (
<div style={{ width: 350 }}>
<ComboBox
canClear
isSearchable
openOnFocus
helperText="Helper Text"
label="Label"
options={options}
getOptionLabel={(option) => `${option.label}: ${option.rating}`}
getOptionValue={(option) => option.rating}
placeholder="Введите сюда текст"
value={value}
onChange={setValue}
/>
<Text>Выбранное значение: {JSON.stringify(value)}</Text>
</div>
)
}
Условие блокировки опции#
При помощи параметра isOptionDisabled можно настраивать блокировку опций.
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: 'vanilla', label: 'Vanilla', rating: 2 },
{ value: 'chocolate', label: 'Chocolate', rating: 4 },
{ value: 'strawberry', label: 'Strawberry', rating: 1 },
{ value: 'salted-caramel', label: 'Salted Caramel', rating: 6 },
{ value: 'double-chocolate', label: 'Double Chocolate', rating: 5 },
{ value: 'late', label: 'Late', rating: 12 },
{ value: 'raf', label: 'Raf', rating: 7 },
]
export const TermDisabled = (): JSX.Element => {
const [value, setValue] = React.useState<string>('')
return (
<div style={{ width: 350 }}>
<ComboBox
canClear
isSearchable
openOnFocus
helperText="Helper Text"
label="Label"
options={options}
getOptionLabel={(option) => `${option.label}: ${option.rating}`}
isOptionDisabled={(option) => option.rating < 5}
placeholder="Введите сюда текст"
value={value}
onChange={setValue}
/>
</div>
)
}
Замена разделителя в строчном отображении#
import * as React from 'react'
import { ComboBox } from '@v-uik/combo-box'
const options = [
{ value: 'vanilla', label: 'Vanilla' },
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'salted-caramel', label: 'Salted Caramel' },
]
export const ReplaceDelimiter = (): JSX.Element => {
const [value, setValue] = React.useState<string[]>([''])
return (
<div style={{ width: 350 }}>
<ComboBox
multiple
helperText="Helper Text"
label="Label"
options={options}
placeholder="Введите сюда текст"
delimiter=" - "
value={value}
onChange={setValue}
/>
</div>
)
}