ChipChoice.Custom
Чип-фильтр, в выпадающем меню которого рендерится произвольный контент через проп content. Подходит для сценариев, которые не покрываются готовыми вариантами Single / Multiple / Date / Time.
Когда использовать
- Когда контент выпадающего меню — нестандартный: вложенная форма, слайдер диапазона, кастомный список с группировкой.
- Когда нужно полностью контролировать разметку и логику выбора значения.
Когда не нужен ChipChoice.Custom:
- Для одиночного или множественного выбора из списка — используйте
Single/Multiple. - Для дат и времени —
Date/DateRange/Time.
Анатомия
Size (default s)
s— для плотных строк фильтров.m— стандартный размер.l— для крупных форм.
Content
Проп content получает объект CustomContentRenderProps и возвращает контент выпадающего меню:
value— текущее значение компонента.onChange(value)— применить новое значение.closeDroplist()— закрыть меню и вернуть фокус на чип.
Отображение выбранного значения в самом чипе задаёт valueRender(value).
Состояния
disabled— отключает взаимодействие.loading— показывает спиннер вместо иконки.
Установка
pnpm add @cloud-ru/ds-chips
import { ChipChoice } from '@cloud-ru/ds-chips'
ChipChoice использует портал для выпадающего меню — оберните дерево в PortalContextProvider из @cloud-ru/ds-portal-context.
Примеры использования
Произвольное меню
tsx
import { Button } from '@cloud-ru/ds-button';
import { ChipChoice } from '@cloud-ru/ds-chips';
import { useState } from 'react';
const PRIORITIES = [
{ value: 'low', label: 'Низкий' },
{ value: 'medium', label: 'Средний' },
{ value: 'high', label: 'Высокий' },
];
export function ChoiceCustomBasic() {
const [value, setValue] = useState<string | undefined>(undefined);
return (
<ChipChoice.Custom
label='Приоритет'
value={value}
onChange={setValue}
valueRender={current => PRIORITIES.find(item => item.value === current)?.label ?? null}
content={({ closeDroplist, onChange }) => (
<div style={{ display: 'flex', flexDirection: 'column', gap: 4, padding: 8 }}>
{PRIORITIES.map(item => (
<Button
key={item.value}
view='function'
appearance='neutral'
label={item.label}
onClick={() => {
onChange?.(item.value);
closeDroplist();
}}
/>
))}
</div>
)}
/>
);
}Props
Types
Props
ChipChoiceCustomProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
className | string | — | no | CSS-класс |
content | ((props: CustomContentRenderProps<any>) => ReactNode) | — | no | Контент выпадающего меню |
data-test-id | string | — | no | |
disabled | boolean | — | no | Отключён |
dropDownClassName | string | — | no | |
icon | ReactNode | — | no | Иконка |
label | string | — | no | Текст чипа |
loading | boolean | — | no | Состояние загрузки |
onChange | ((value: any) => void) | — | no | Колбек смены значения |
onClearButtonClick | MouseEventHandler<HTMLButtonElement> | — | no | Колбек для клика по кнопке очистки |
onClick | MouseEventHandler<HTMLButtonElement | HTMLDivElement> | — | no | Колбек обработки клика |
onOpenChange | ((isOpen: boolean) => void) | — | no | Колбек отображения компонента |
open | boolean | — | no | Управляет состоянием показан/не показан |
placement | "bottom" | "bottom-end" | "bottom-start" | "left" | "left-end" | "left-start" | "right" | "right-end" | "right-start" | "top" | "top-end" | "top-start" | bottom-start | no | Расположение выпадающего меню |
size | "l" | "m" | "s" | m | no | Размер |
tabIndex | number | — | no | Индекс в порядке фокусировки |
truncateVariant | "end" | "middle" | 'middle' | no | Вариант обрезания строки Вариант обрезания значения |
value | any | — | no | Фактическое значение |
valueRender | ((value: any) => ReactNode) | — | no | Отображаемое значение |
widthStrategy | "auto" | "eq" | "gte" | gte | no | Стратегия управления шириной контейнера поповера |
Storybook
Figma
Смотри также
- ChipChoice.Single — одиночный выбор из списка.
- Chips — обзор пакета.