FieldCode
Поле ввода одноразового кода (OTP): codeLength ячеек на FieldText из @cloud-ru/ds-fields, автопереход фокуса при вводе, вставка кода целиком из буфера, колбек onComplete при заполнении всех ячеек. Опционально — кнопка повторной отправки кода с таймером (resendCode) и хук валидации useFieldCodeValidate.
Когда использовать
- Подтверждение по SMS/email-коду: пользователь вводит фиксированное число цифр.
- Нужен автопереход фокуса между ячейками и вставка кода целиком.
Когда не нужен FieldCode:
- Числовой код как обычная строка без ячеек —
FieldMaskс маскойcode.
Анатомия
Size (default m)
Размер ячеек и подписи наследуется от FieldDecorator:
s— компактный (ячейка 32px).m— средний (ячейка 40px).l— крупный (ячейка 52px).
Слоты и состояния
label— заголовок поля.error/invalidCode— текст ошибки;errorприоритетнее.showEmptyChars— подсветка пустых ячеек (состояние «код не дописан»).spacing— визуальный разрыв после указанных индексов ([2]для форматаXXX XXX).stretchCells— ячейки делят всю ширину контейнера; иначе фиксированная ширина поsize.resendCode— кнопка повторной отправки: заблокирована с таймеромmm:ss, покаsecondsToNextResend > 0.
Imperative ref (FieldCodeRef)
moveFocus(index)— перенести фокус на ячейку.blurFields()— снять фокус со всех ячеек.resetCode()— сбросить значение.
Примеры использования
Базовый
tsx
import { FieldCode } from '@cloud-ru/ds-uikit-product-fields-predefined';
import { useState } from 'react';
export function FieldCodeBasic() {
const [value, setValue] = useState('');
const [completed, setCompleted] = useState('');
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: 12, alignItems: 'center' }}>
<FieldCode codeLength={6} label='Код подтверждения' value={value} onChange={setValue} onComplete={setCompleted} />
<span>{completed ? `Код введён: ${completed}` : 'Введите 6 цифр'}</span>
</div>
);
}Валидация
tsx
import { FieldCode, useFieldCodeValidate } from '@cloud-ru/ds-uikit-product-fields-predefined';
import { useState } from 'react';
const CODE_LENGTH = 6;
export function FieldCodeValidation() {
const [value, setValue] = useState('');
const [touched, setTouched] = useState(false);
const validateCode = useFieldCodeValidate({ codeLength: CODE_LENGTH });
const handleChange = (next: string) => {
setValue(next);
setTouched(true);
};
return (
<FieldCode
codeLength={CODE_LENGTH}
label='Код подтверждения'
value={value}
onChange={handleChange}
error={touched ? validateCode(value) : undefined}
showEmptyChars={touched}
/>
);
}Повторная отправка
tsx
import { FieldCode } from '@cloud-ru/ds-uikit-product-fields-predefined';
import { useEffect, useState } from 'react';
const RESEND_COUNTDOWN_SECONDS = 10;
export function FieldCodeResend() {
const [value, setValue] = useState('');
const [secondsToNextResend, setSecondsToNextResend] = useState(RESEND_COUNTDOWN_SECONDS);
useEffect(() => {
if (secondsToNextResend <= 0) {
return;
}
const timerId = window.setTimeout(() => setSecondsToNextResend(seconds => seconds - 1), 1000);
return () => window.clearTimeout(timerId);
}, [secondsToNextResend]);
const handleResend = () => {
setValue('');
setSecondsToNextResend(RESEND_COUNTDOWN_SECONDS);
};
return (
<FieldCode
codeLength={6}
label='Код подтверждения'
value={value}
onChange={setValue}
resendCode={{ onResend: handleResend, secondsToNextResend }}
/>
);
}Props
Types
Props
FieldCodeProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
cellClassName | string | — | no | CSS-класс ячейки кода |
className | string | — | no | CSS-класс компонента |
codeLength | number | — | yes | Количество цифр в коде (целое ≥ 1) |
data-test-id | string | — | no | |
disabled | boolean | — | no | Поле выключено |
error | string | — | no | Ошибка (приоритетнее `hint`; форсит `validationState=error`) |
invalidCode | string | — | no | Сообщение при неверном коде, если не передан свой `error` |
label | string | — | no | Заголовок |
onChange | ((code: string) => void) | — | no | Колбек изменения значения |
onComplete | ((code: string) => void) | — | no | Колбек ввода всех символов кода |
resendCode | ResendCodeProps | — | no | Компонент отправки нового кода |
showEmptyChars | boolean | — | no | Подсветить пустые символы кода |
size | "l" | "m" | "s" | — | no | Размер |
spacing | number[] | — | no | Позиции, после которых нужно вставить пробел (индексы символов, после которых будет разрыв) |
stretchCells | boolean | — | no | Растягивать ячейки на всю доступную ширину; иначе фиксированная ширина по `size` |
value | string | — | no | Значение кода |
Types
FieldCodeProps
ResendCodeProps
Related props
Size
Адаптивность
Раскладка читается из AdaptiveProvider (@cloud-ru/ds-adaptive); отдельного пропа layoutType нет. На mobile компонент не переносит фокус автоматически (ни при монтировании, ни при resetCode) — чтобы экранная клавиатура не открывалась без действия пользователя. Размер на mobile не меняется — база m.