Паттерны
Строка поиска
Когда использовать:
- полю нужно действие отправки или поиска в конце
Заметки о композиции:
- сначала инпут, затем действие
- размер действия должен совпадать с размером поля
Компромиссы:
- компактно и практично
- горизонтальная плотность выше, чем у простого поля
import type { CSSProperties, FormEvent } from 'react';
import { Button, Icon, IconButton, Text, TextField, TextFieldInput } from '@vega-ui/react';
import { SearchIcon, XIcon } from '@vega-ui/icons';
import { useRef, useState } from 'react';
import './examples.css';
export default function SearchWithClearAndSubmit() {
const inputRef = useRef<HTMLInputElement>(null);
const [query, setQuery] = useState('');
const [searched, setSearched] = useState('');
const onSubmit = (event: FormEvent<HTMLFormElement>) => {Суффикс со счётчиком или статусом
Когда использовать:
- текущему значению нужна лёгкая обратная связь прямо в строке
Заметки о композиции:
- текст суффикса должен быть коротким
- не сужайте инпут слишком сильно
Компромиссы:
- мгновенная обратная связь
- может уменьшить полезную ширину ввода
import { Label, Text, TextField, TextFieldInput } from '@vega-ui/react';
import { useId, useState } from 'react';
const MAX_LENGTH = 60;
export default function CharacterCounterSuffix() {
const id = useId();
const counterId = `${id}-counter`;
const [title, setTitle] = useState('Q3 roadmap review');
const remaining = MAX_LENGTH - title.length;
return (Префикс и суффикс
Когда использовать:
- фиксированный текст — часть значения: протокол, домен или единица измерения
Заметки о композиции:
- держите аффиксы вне значения и скрывайте их от скринридера, если лейбл или подсказка уже это говорят
- инпут должен сжиматься (
minWidth: 0), а аффиксы — сохранять ширину
Компромиссы:
- эффективно для плотных элементов управления
- перегрузить легче, чем простое поле
import { HelperText, Label, Text, TextField, TextFieldInput } from '@vega-ui/react';
import { useId, useState } from 'react';
const affixStyle = {
flexShrink: 0,
whiteSpace: 'nowrap',
color: 'var(--label-secondary)',
} as const;
export default function SubdomainPrefixSuffix() {
const id = useId();
const hintId = `${id}-hint`;Сравнение
Быстрое правило выбора
Используйте TextField для однострочного ввода текста, особенно когда полю нужна композиция с префиксом или суффиксом. Используйте TextArea для многострочного ввода, а специализированные поля — когда нужна маска или продвинутое поведение.
TextField и TextArea
Используйте TextField, когда:
- значение однострочное
Используйте TextArea, когда:
- содержимое намеренно многострочное
TextField и PasswordField
Используйте TextField, когда:
- вводится обычный текст
Используйте PasswordField, когда:
- полю нужно маскирование пароля и переключатель видимости
TextField и NumberField
Используйте TextField, когда:
- значение — произвольный текст, даже если в нём есть цифры
Используйте NumberField, когда:
- важны шаг, границы или числовые ограничения
TextField и PhoneField
Используйте TextField, когда:
- значение — обычный текст и не требует поведения телефона с учётом страны
Используйте PhoneField, когда:
- выбор страны, форматирование и разбор номера в каноническую форму входят в контракт одного поля
Выбирайте этот компонент, когда
- элемент управления однострочный
- полезна необязательная композиция с префиксом или суффиксом
- достаточно семантики нативного инпута
- поле должно оставаться универсальным, а не специализированным
Не выбирайте этот компонент, когда
- поле многострочное
- взаимодействию нужно поведение пароля, числа или сегментированного кода
Решение проблем
Поле рендерится, но значение не попадает в отправку формы
Симптом
Обёртка видна, но в отправленной форме нет ожидаемого значения.
Вероятная причина
name или другие пропсы формы заданы на TextField, а не на TextFieldInput.
Как проверить
- изучите отрендеренную разметку
- убедитесь, что у нативного инпута есть ожидаемые атрибуты формы
Исправление
Задайте атрибуты формы на TextFieldInput.
Стиль ошибки не отображается
Симптом
Инпут невалиден, но контур поля по-прежнему нейтральный.
Вероятная причина
Обёртка не получила error.
Как проверить
- изучите пропсы
TextField - убедитесь, что на обёртке есть
data-error='true'
Исправление
Задайте error на TextField и при необходимости сохраните семантику невалидности на инпуте.
Содержимое префикса или суффикса мешает пользоваться полем
Симптом
Область ввода кажется тесной, или переходы фокуса становятся неудобными.
Вероятная причина
Вокруг инпута добавлено слишком много элементов управления.
Как проверить
- временно уберите лишние дочерние элементы
- сравните взаимодействие с простым полем
Исправление
Сократите композицию до одного понятного инпута и только самых необходимых соседних действий.