Forms
Формы — место, где интерфейс просит. Лейбл сверху, outline 40 px, валидация on-blur для формата, on-submit для логики. Одна колонка по умолчанию. Текст подсказки лучше извинения.
Анатомия поля
Лейбл сверху. Это стандарт web-форм: меньше eye-tracking, лучше для мобильных, проще выровнять. Подсказка — под инпутом, заранее. Ошибка — на её месте, с иконкой и конкретным объяснением.
Required vs optional
Помечаем опциональные, а не обязательные (подход Adam Silver). В большинстве форм большинство полей — обязательные, логичнее помечать исключения. Меньше визуального шума.
Text input
Outlined-стиль: 1 px бордер, белый фон, radius 8. Один размер по умолчанию — 40 px. Дополнительный .sm 32 px для плотных форм Analyst.
Размеры
Состояния
С иконкой / addon
Textarea
Тот же стиль, что и input. min-height 88 px, resize vertical. Padding 10 × 12.
Select
Используем нативный <select> для простого выбора (страна, валюта, язык). Кастомный dropdown — только там, где нужны иконки, поиск или богатые опции. Native всегда доступнее и на mobile открывает родную карусель.
Native vs custom — когда что
| Если… | Используй |
|---|---|
| Простой список (<15 опций, текст) | Native select |
| Поиск нужен или 50+ опций | Custom (combobox) |
| Иконки / описание у опции | Custom dropdown |
| Multi-select | Custom + chips |
Checkbox / Radio
Стандартные — квадрат для checkbox, круг для radio. 18 × 18, бордер 1.5 px. Заполняются foreground при active.
Карточный выбор
Когда выбор — это решение, а не галка. Pricing, онбординг, выбор тарифа. Те же radio-семантика, но вся карточка кликается.
Switch
Только для настроек, которые применяются мгновенно — автосохранение, тема, уведомления. Не используем как «чекбокс на стероидах» в формах.
Switch vs Checkbox
| Switch | Применяется сразу. «Включить тёмную тему» — и тема меняется. Без Submit-кнопки. |
| Checkbox | Часть формы. Применится после Submit. «Я согласен с условиями». |
File upload
Drag-and-drop зона + клик для выбора. Под ней — список загруженных файлов с возможностью удалить.
Валидация
Mix-стратегия. Не дёргаем юзера, пока он печатает.
| Когда | Что проверяем |
|---|---|
| On blur (юзер ушёл из поля) | Формат — email, телефон, дата, URL. Дать обратную связь немедленно. |
| On submit | Обязательность, бизнес-правила, кросс-полевые правила («password = confirm»). |
| On input (live) | Только помощь — счётчик символов, индикатор силы пароля. Не ошибки. |
| Снять ошибку | Как только юзер исправил, до blur. Иначе он видит ошибку, исправляя её. |
Сообщение ошибки — шаблон
«Похоже, домен неполный. Попробуйте ivan@aist.tech.»
«Пароль должен содержать минимум 8 символов. Сейчас 5.»
«Invalid input. Try again.»
«Вы ввели неправильный пароль.»
Раскладка форм
Одна колонка по умолчанию. Это самый эффективный формат — eye-tracking прямой, completion rate выше. Две колонки — только для связанных пар: «Имя / Фамилия», «Город / Индекс», «Дата С / по».
Сетка с label слева — для settings
На широких settings-страницах хорошо работает «split» — слева заголовок секции и описание, справа — поля. Лейблы полей по-прежнему сверху над инпутом, но вся секция получает контекст.
Организация
Имя организации видят все участники. Slug — часть URL и API-ключей.
Регион данных
Где физически хранятся ваши данные. Сменить можно только при пустом workspace.
Длинные формы
Когда полей много — разбиваем. Три паттерна, выбирай по контексту.
| Паттерн | Когда |
|---|---|
| Одна страница (single-page) | Settings. Юзер хочет видеть всё и скроллить. Sticky-сабменю слева — бонус. |
| Step-by-step (wizard) | Онбординг, регистрация, оплата. Юзер не знает структуру — ведём его. |
| Tabs / accordion | Профиль организации, конфигурация продукта. Логически независимые группы. |
Wizard — stepper сверху
Voice / Copy
| Не так | Так |
|---|---|
| First Name | Имя |
| Required field | (ничего — по умолчанию обязательно) |
| Submit | Сохранить · Создать · Отправить · Подтвердить |
| Please enter a valid email | Похоже, домен неполный. |
| Are you sure? | Удалить «Voice Operator»? Это нельзя отменить. |
Принципы
- Лейбл всегда сверху. Никакого «слева на 200 px» — это паттерн 90-х.
- Помечаем optional, не required. Меньше шума, ясный сигнал «это можно пропустить».
- Одна колонка по умолчанию. Две — только для пар.
- Validate on blur, submit on click. Не ругаемся пока юзер печатает.
- Native select когда можно. Custom — когда нужны иконки, поиск или multi-select.
- Switch = мгновенно. Если есть Submit — это checkbox.
- Кнопка — глагол результата. «Сохранить», «Создать запрос», «Отправить счёт». Не «OK», не «Submit».
Tokens reference
| Element | Property | Value |
|---|---|---|
| Input | height (sm / md / lg) | 32 / 40 / 48 px |
| Input | radius / border | 8 / 1 px #E0E0E0 |
| Input | focus ring | 3 px rgba(17,17,17,0.08) |
| Input invalid | focus ring | 3 px rgba(220,38,38,0.12) |
| Label | font / size / weight | Commissioner 13/500 |
| Help | font / size | Commissioner 12, muted |
| Error | font / size | Commissioner 13, destructive |
| Checkbox / Radio | size | 18 × 18 px, border 1.5 |
| Switch | track / thumb | 36 × 20 / 16 × 16 |
| File-drop | border / padding | 1.5 dashed / 24 px |
| Field gap | label↔input / field↔field | 6 / 20 px |
К хабу: Design System →