FieldCombo
Текстовое поле со слотами вокруг строки ввода: текстовые префикс и постфикс, иконки слева и справа, кнопки-сегменты по краям. Всё остальное — размеры, валидация, кнопки очистки и копирования — совпадает с FieldText; слоты и есть единственное отличие.
Когда использовать
- К значению нужна единица измерения или символ валюты — префикс либо постфикс.
- Полю нужен ведущий маркер контекста — иконка слева.
- Рядом с вводом нужно действие или выбор — кнопка-сегмент со своим выпадающим списком.
- Слотов нет:
- берите
FieldText— у него та же раскладка без лишней поверхности API.
- берите
Анатомия
Оси size, validationState и background работают так же, как у FieldText.
Outline (default true)
Разделитель между основным полем и слотами elementBefore / elementAfter. outline = false убирает
вертикальную линию — слот и поле визуально сливаются.
Слоты
prefix/postfix— текст по краям строки ввода, попадает в копируемое значение.iconBefore/iconAfter— иконка внутри строки ввода, без своей зоны нажатия.elementBefore/elementAfter— кнопка-сегмент со своей рамкой фокуса и опциональнымdroplist.
Установка
pnpm add @cloud-ru/ds-fields
import { FieldCombo } from '@cloud-ru/ds-fields'
Примеры использования
Префикс и постфикс
$
USD
tsx
import { FieldCombo } from '@cloud-ru/ds-fields';
import { useState } from 'react';
export function Affixes() {
const [value, setValue] = useState('100');
return <FieldCombo label='Сумма' prefix='$' postfix='USD' value={value} onChange={setValue} />;
}Иконка слева
tsx
import { FieldCombo } from '@cloud-ru/ds-fields';
import { SearchSVG } from '@cloud-ru/ds-icons/interface/system';
import { useState } from 'react';
export function IconBefore() {
const [value, setValue] = useState('');
return (
<FieldCombo label='Поиск' placeholder='Найти статью' iconBefore={<SearchSVG />} value={value} onChange={setValue} />
);
}Иконка справа
tsx
import { FieldCombo } from '@cloud-ru/ds-fields';
import { QuestionSVG } from '@cloud-ru/ds-icons/interface/system';
import { useState } from 'react';
export function IconAfter() {
const [value, setValue] = useState('user@example.com');
return (
<FieldCombo
label='Email'
placeholder='user@example.com'
iconAfter={<QuestionSVG />}
value={value}
onChange={setValue}
/>
);
}Иконка + префикс/постфикс
₽
/мес
tsx
import { FieldCombo } from '@cloud-ru/ds-fields';
import { BankCardSVG } from '@cloud-ru/ds-icons/interface/web';
import { useState } from 'react';
export function IconAndAffix() {
const [value, setValue] = useState('1234');
return (
<FieldCombo
label='Сумма пополнения'
iconBefore={<BankCardSVG />}
prefix='₽'
postfix='/мес'
value={value}
onChange={setValue}
/>
);
}Кнопка-слот слева
tsx
import { FieldCombo } from '@cloud-ru/ds-fields';
import { CalendarSVG } from '@cloud-ru/ds-icons/interface/system';
import { useState } from 'react';
function formatToday(): string {
return new Date().toLocaleDateString('ru-RU');
}
export function ElementBefore() {
const [value, setValue] = useState('');
return (
<FieldCombo
label='Дата'
placeholder='12.04.2026'
elementBefore={{
action: <CalendarSVG />,
onClick: () => setValue(formatToday()),
}}
value={value}
onChange={setValue}
/>
);
}Кнопка-слот справа
USD
tsx
import { FieldCombo } from '@cloud-ru/ds-fields';
import { useState } from 'react';
const CURRENCIES = [
{ id: 'USD', content: { label: 'USD — доллар' } },
{ id: 'EUR', content: { label: 'EUR — евро' } },
{ id: 'RUB', content: { label: 'RUB — рубль' } },
];
export function ElementAfter() {
const [value, setValue] = useState('100');
const [currency, setCurrency] = useState<string | number | undefined>('USD');
return (
<FieldCombo
label='Валюта'
placeholder='Сумма'
postfix={currency}
elementAfter={{
action: currency,
droplist: {
items: CURRENCIES,
closeDroplistOnItemClick: true,
selection: {
mode: 'single',
value: currency,
onChange: setCurrency,
},
},
}}
value={value}
onChange={setValue}
/>
);
}Props
Types
Props
FieldComboProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
allowMoreThanMaxLength | boolean | false | no | Разрешить ввод свыше `maxLength` символов (счётчик продолжит расти). |
autoComplete | string | boolean | false | no | Включен ли автокомплит для поля |
autoFocus | boolean | false | no | Включен ли авто-фокус для поля |
background | boolean | true | no | Фон поля (acrylic) |
caption | string | — | no | Вторичная подпись справа |
className | string | — | no | CSS-класс CSS-класс корня `FieldDecorator` |
data-test-id | string | — | no | |
defaultValue | string | | no | Начальное значение (uncontrolled-режим) |
disabled | boolean | false | no | Поле выключено Является ли поле деактивированным |
elementAfter | FieldElementSlot | — | no | Слот справа (кнопка / селект с опциональным выпадающим списком) |
elementBefore | FieldElementSlot | — | no | Слот слева (кнопка / селект с опциональным выпадающим списком) |
error | string | — | no | Ошибка (приоритетнее `hint`; форсит `validationState=error`) |
fieldClassName | string | — | no | CSS-класс оболочки поля ввода |
hint | string | — | no | Подсказка |
iconAfter | ReactNode | — | no | Иконка справа от строки ввода |
iconBefore | ReactNode | — | no | Иконка слева от строки ввода |
id | string | — | no | Значение html-атрибута id |
innerRef | Ref<HTMLDivElement> | — | no | Ref на корневой DOM-элемент |
innerTestIds | { shell?: string; input?: string; } | undefined | — | no | Идентификаторы внутренних слотов — оболочки и строки ввода. Нужны компонентам, которые рендерят `FieldCombo` под собственным именем (`FieldText`): их e2e адресует свои слоты, а не слоты `FieldCombo`. |
inputMode | "decimal" | "email" | "none" | "numeric" | "search" | "tel" | "text" | "url" | — | no | Режим работы экранной клавиатуры |
label | string | | no | Заголовок |
labelFor | string | — | no | HTML-атрибут `for` для `<label>` |
labelTooltip | QuestionTooltipProps | — | no | Подсказка (question-tooltip) у заголовка |
layoutPresets | Partial<Record<LayoutType, Partial<{ autoFocus: boolean; }>>> | — | no | Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`. |
length | FieldLength | — | no | Счётчик длины `current/max` |
max | number | — | no | Максимальное значение поля |
maxLength | number | — | no | Максимальная длина вводимого значения |
min | number | — | no | Минимальное значение поля |
name | string | — | no | Значение html-атрибута name |
onBlur | FocusEventHandler<HTMLInputElement> | — | no | Колбек обработки потери фокуса |
onChange | ((value: string) => void) | — | no | Колбек смены значения |
onClearButtonClick | (() => void) | — | no | Колбек клика по кнопке очистки |
onClick | MouseEventHandler<HTMLInputElement> | — | no | Колбек обработки клика |
onCopyButtonClick | (() => void) | — | no | Колбек после копирования значения в буфер |
onFocus | FocusEventHandler<HTMLInputElement> | — | no | Колбек обработки получения фокуса |
onKeyDown | KeyboardEventHandler<HTMLInputElement> | — | no | Колбек обработки начала нажатия клавиши клавиатуры |
onMouseDown | MouseEventHandler<HTMLInputElement> | — | no | Колбек обработки нажатия кнопки мыши |
onPaste | ClipboardEventHandler<HTMLInputElement> | — | no | Колбек обработки вставки значения |
outline | boolean | true | no | Разделитель между основным полем и слотами `elementBefore` / `elementAfter` |
pattern | string | — | no | Регулярное выражение валидного инпута |
placeholder | string | — | no | Значение плейсхолдера |
postfix | ReactNode | — | no | Постфикс (текст или нода) |
prefix | ReactNode | — | no | Префикс (текст или нода) |
prefixIcon | ReactNode | — | no | Ведущая иконка. @deprecated Используйте `iconBefore` — он приоритетнее, если заданы оба. |
readonly | boolean | false | no | Только для чтения Является ли поле доступным только для чтения |
required | boolean | — | no | Показать знак обязательности `*` |
showClearButton | boolean | true | no | Показывать кнопку очистки значения (как в Search) |
showCopyButton | boolean | true | no | Показывать кнопку копирования значения (только при `readonly = true` и непустом `value`) |
showHintIcon | boolean | — | no | Отображение статус-иконки у подсказки (по умолчанию `true`) |
size | "l" | "m" | "s" | m | no | Размер |
spellCheck | boolean | true | no | Значение атрибута spellcheck (проверка орфографии) |
step | string | number | — | no | Максимальное значение поля |
tabIndex | number | 0 | no | Значение атрибута tab-index |
type | "email" | "number" | "password" | "tel" | "text" | "url" | — | no | Тип инпута |
validationState | "default" | "error" | "success" | "warning" | default | no | Состояние валидации |
value | string | — | no | Значение поля (controlled-режим) |