ADR-UI-020. Кнопки
Кнопки встречаются по всей системе. Фиксируем базовый компонент кнопки (типы, состояния, геометрия) и единое правило их размещения в футерах (порядок и стороны), чтобы пользователь выработал мышечную память, а разработчик/ИИ не решали заново на каждом экране.
1. Контекст и постановка задачи
Кнопки нужны везде: футеры форм, шапки страниц, карточки, действия в строках. Зафиксировать надо две вещи:
- компонент — единые типы, состояния и геометрия кнопки;
- размещение — порядок и стороны кнопок в футерах (правило кросс-срезовое: не принадлежит ни формам, ни паттерну страницы, поэтому живёт отдельным ADR, на который ссылаются).
2. Драйверы решения
- Предсказуемость — главное действие всегда в одном месте.
- Единообразие — одинаковые кнопки во всех контекстах.
- Один факт в одном месте — остальные ADR/страницы ссылаются сюда.
- Готовность к codegen — генераторы получают однозначное правило.
3. Рассмотренные варианты (размещение)
- A. Целевая слева, «Отмена» следом —
[Сохранить] [Отмена]. - B. «Отмена» слева, целевая справа —
[Отмена] [Сохранить]. - C. Не фиксировать — на усмотрение страницы (ведёт к разнобою).
4. Решение
1. Базовый компонент Button
Base-компонент набора ui/. Геометрия едина для всех типов, различаются только цвета.
- Типы (variant):
primary,secondary,tertiary,ghost,danger,inverse. - Состояния:
default,hover,active,disabled,focus(кольцо4px). - Геометрия: высота
40px,border-radius: 9999px(pill — полностью скруглённая капсула), текст — Body/M · medium; опциональная иконка слева (20px, gap6px), вариант icon-only —40×40. - Цвета
bg/text/borderпо каждому типу и состоянию — через control-токены (--icd-*, ADR-UI-004); иконка красится в цвет текста.
2. Размещение в футерах (выбран вариант A + уточнение по деструктивным)
Главный принцип — целевая (главная) кнопка слева, вторичные и «Отмена» — следом, в левом кластере. Деструктивная кнопка ставится справа и оторванно только если она вторичная.
- Случай A — главное действие неразрушающее + есть отдельное деструктивное (форма
редактирования). Футер во всю ширину (space-between):
[Главная] [вторичные…] [Отмена]слева …[Опасная]справа-оторвана. - Случай B — деструктивное действие само целевое (диалог подтверждения удаления):
[Удалить] [Отмена]слева (кластер не растягиваем).
3. Типы по роли действия
- Главное действие экрана/футера →
primary. На один футер — ровно одна primary. - Отмена / нейтральное вторичное →
secondaryилиtertiary; «Отмена» никогда не primary. - Деструктивное →
danger(не primary): вторичное — справа-оторвано (A), целевое — слева (B). - Третичное малозначимое →
ghost.
4. Выравнивание
- Футер формы — во всю ширину: левый кластер прижат влево, деструктивная — к правому краю. Горизонтальный интервал между кнопками — токеном (ADR-UI-004).
- Футер идёт сразу под полями формы (ADR-UI-009), не приклеен к низу.
- В шапке страницы кнопки действий — справа от заголовка (разметку контейнера задаёт ADR-UI-005).
Правила подтверждений в модалках/поповерах — отложены вместе с модалками.
5. Положительные следствия
- Пользователь всегда знает, где главное действие.
- Единый компонент и одно правило размещения — прототип, код и генераторы совпадают.
- Споры «где кнопка / какой тип» закрыты ссылкой на один ADR.
6. Отрицательные следствия и компромиссы
- Полный набор из 6 типов × 5 состояний — это набор control-токенов, который надо один раз завести и поддерживать (наполняем по мере использования типов).
- Раскладка футера «во всю ширину со space-between» — не дефолт браузера; инкапсулируется в компоненте футера формы (появится с формами).
7. Проверка
- Целевая (главная) кнопка — всегда слева; на форме редактирования «Сохранить» слева, «Удалить» (вторичная деструктивная) — справа-оторвана (случай A).
- В диалоге подтверждения удаления
[Удалить](danger) — слева,[Отмена]следом (случай B). - На каждом футере — не больше одной primary-кнопки.
- Кнопка использует типы
primary/secondary/tertiary/ghost/danger/inverseи токены control.
8. Открытые вопросы / отложено
- Кнопки подтверждений в модалках/поповерах — вместе с модалками (отложено). В коде есть
экспериментальный
ui/confirm-popover(подтверждение удаления рядом с кнопкой) — проверяем удобство, паттерн не ратифицирован, возможна замена; правила порядка кнопок при этом соблюдены (случай B). - Адаптив — стек кнопок футера на узких экранах (< 1280) уточним при вёрстке форм.
- Единый словарь подписей («Создать»/«Сохранить»/«Отмена» без синонимов) — по мере появления действий.