OTP input
OTP input принимает короткий одноразовый код: код подтверждения из SMS или письма, код двухфакторной проверки, PIN. На каждый символ — своя ячейка, а под ними одно настоящее поле.
<tk-field label="Enter the 6-digit code we sent you" helper="Sent to +1 ••• ••• 4321"> <tk-otp-input name="code"></tk-otp-input> </tk-field>
Анатомия
| Часть | Что это |
|---|---|
tk-otp-input |
сам элемент; одна остановка Tab |
part field |
ряд ячеек |
part box |
одна ячейка, 48×48px |
part input |
одно настоящее <input>, невидимое, поверх ряда |
Подпись, подсказку и сообщение об ошибке рисует
Длина, тип и маска
<tk-field label="Enter your 4-digit PIN"> <tk-otp-input name="pin" length="4" mask></tk-otp-input> </tk-field>
<tk-field label="Enter a backup code"> <tk-otp-input name="backup" length="8" type="alphanumeric"></tk-otp-input> </tk-field>
lengthзадаёт число ячеек: по умолчанию 6, для PIN — 4.type:numeric(по умолчанию) принимает 0–9 и открывает цифровую клавиатуру;alphanumericпринимает буквы и цифры и сохраняет регистр.maskпоказывает заполненные ячейки точками. Только для кода, который человек знает, например PIN: маска может помешать телефону подставить код из SMS.
Ввод и вставка
- Введённый символ заполняет ячейку, и курсор переходит к следующей. Символ на заполненной ячейке заменяет её.
- Backspace стирает ячейку и возвращается назад. Стрелки, Home и End переходят между ячейками. Tab всегда выводит из поля.
- Вставка заполняет все ячейки с любой позиции, а пробелы и дефисы отбрасывает:
«98 76-54» становится
987654. - Код из SMS, который подставляет телефон, заполняет все ячейки сразу.
- В активной ячейке мигает курсор; при ограничении анимации он не мигает.
Состояния
<tk-otp-input aria-label="Verification code" value="482913" readonly></tk-otp-input> <tk-otp-input aria-label="Verification code" disabled></tk-otp-input>
<tk-field label="Enter the 6-digit code we sent you" error="That code is incorrect. Check it and try again."> <tk-otp-input name="code" value="123456"></tk-otp-input> </tk-field>
При наведении ячейки не меняются. Активная ячейка окрашивается в цвет фокуса и получает более толстую рамку — это и есть индикатор фокуса.
- Ошибка: задайте
errorу Field. Все ячейки, включая активную, станут красными, а под рядом появится сообщение. OTP input код не проверяет: когда и что сказать, решаете вы. readonly: на поле можно перейти и скопировать код, но не изменить.disabled: на поле нельзя перейти и нельзя ввести код, а в форму оно не попадает.- Обязательное поле: задайте
requiredу Field. Форма отправится, только когда код введён целиком. - Зелёного состояния для верного кода нет. Переводите человека на следующий экран.
Завершение
Когда заполнена последняя ячейка, поле отправляет событие tk-complete с кодом в
detail.value. Само оно форму не отправляет и фокус не переводит.
- Отправлять форму по
tk-completeможно, но человеку со скринридером или клавиатурой может понадобиться проверить код. Кнопка проверки надёжнее. - Если код неверный, задайте
errorу Field и оставьте фокус в поле.
Когда использовать
- OTP input — для одноразового кода фиксированной длины: кода подтверждения, кода двухфакторной проверки, PIN.
- Для другого текста, в том числе длинного номера заявки, берите
Input . Пароль вводят вtk-input type="password". - Подойдёт и одно обычное поле. Input с
inputmode="numeric"иautocomplete="one-time-code"проще и так же доступен. OTP input берите, когда ячейки помогают увидеть длину кода. - Всё вокруг собирайте сами: ссылку «Отправить ещё раз» с таймером, кнопку проверки, текст «код отправлен на…» и экран успеха.
Текст
- Подпись: назовите код и его длину: «Введите 6-значный код, который мы отправили».
- Подсказка: куда отправлен код или сколько он действует. Без ссылок.
- Ошибка: скажите, что случилось и что делать: «Код неверный. Проверьте его и попробуйте снова» или, если ничего не введено, «Введите 6-значный код». Без «пожалуйста» и «извините».
Подробнее в
Можно / нельзя
| ✅ Можно | ❌ Нельзя |
|---|---|
| Называть в подписи код и его длину | Оставлять поле без имени |
| Разрешать вставить код целиком | Запрещать вставку или требовать по символу на ячейку |
Оставлять автозаполнение one-time-code |
Собирать код из отдельных полей |
Ставить mask для PIN |
Маскировать код из SMS |
| Показывать неверный код через ошибку Field | Красить ячейки в зелёный при успехе |
| Брать одно поле Input, если так проще | Навязывать ячейки там, где они не помогают |
Связанные
Field : подпись, подсказка и ошибка вокруг кода.Input : любой другой текст и вариант кода в одном поле.
API
Атрибуты
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
length |
number | 6 |
число ячеек |
type |
numeric | alphanumeric |
numeric |
допустимые символы и экранная клавиатура |
mask |
boolean | false |
показывает заполненные ячейки точками |
value |
string | '' |
код; отправляется под именем name |
name |
string | — | имя поля в форме |
autocomplete |
string | one-time-code |
позволяет телефону подставить код из SMS; off отключает |
inputmode |
string | numeric или text |
экранная клавиатура; следует за type |
required |
boolean | false |
браузер не отправит форму, пока код не введён целиком |
readonly |
boolean | false |
можно перейти и скопировать, нельзя изменить |
disabled |
boolean | false |
не в фокусе, не редактируется, не попадает в форму |
События
| Событие | Detail | Когда |
|---|---|---|
input |
— | при любом изменении кода: ввод, вставка, автозаполнение, удаление |
change |
— | при уходе из поля после изменения |
tk-complete |
{ value } |
когда заполнена последняя ячейка |
Сброс формы возвращает первоначальное значение и не вызывает change.
Методы
focus(): переводит фокус в поле.
CSS
::part(field): ряд ячеек.::part(box): каждая ячейка.::part(input): настоящее<input>.
Токены
| Роль | Покой | Активная ячейка | Ошибка | Отключено | Только чтение |
|---|---|---|---|---|---|
| рамка ячейки | border/subtle |
border/accent/focus |
border/error |
border/disabled |
border/subtle |
| фон ячейки | surface/default |
surface/default |
surface/default |
surface/disabled |
surface/subtle |
| символ | text/default |
text/default |
text/default |
text/disabled |
text/default |
Курсор — border/accent/focus, при ошибке красный. Символы — font-size-lg, средней
насыщенности. Углы ячеек — radius-8, между ячейками space-8. Значения по темам:
Доступность
Встроено:
- Одно настоящее
<input>: одна остановка Tab, одно поле для скринридера, нативные курсор, вставка и автозаполнение. - По умолчанию
autocomplete="one-time-code", поэтому коды из SMS подставляются сами. - Клавиатура следует за
type: для цифровых кодов — цифровая. - Ввод никогда не уводит фокус из поля, а Tab всегда выводит из него.
- Field вокруг поля называет его, связывает с ним подсказку и ошибку и при ошибке отмечает поле как неверное.
- Enter отправляет форму, в которой стоит поле.
На вашей стороне:
- Дайте каждому OTP input имя: подпись в Field или
aria-label. - Не отправляйте форму сразу после ввода последнего символа, не дав проверить код.
- Ставьте
maskтолько для кодов, которые человек знает.
| Клавиша | Действие |
|---|---|
Tab |
переводит фокус в поле и выводит из него |
← / →, Home / End |
переход между ячейками |
Backspace |
стирает ячейку и возвращается назад |
Enter |
отправляет форму |
Пределы контраста
У рамки ячейки в покое те же пределы, что у Input: см.