Действуй как product designer. Confirm-диалог — это последняя защита от ошибки, но злоупотребление превращает его в click-through. Юзер перестаёт читать и нажимает «OK» рефлекторно. Цель: confirm там, где он реально нужен, undo там, где confirm раздражает.
Действие: {{action}} Blast radius: {{blast_radius}} Reversibility: {{reversibility}}
Закон destructive confirm: матрица решений
| Reversibility | Blast radius | Паттерн |
|---|---|---|
| Instant undo доступно | 1 объект | Сделать сразу + toast «Undid» (никакого confirm) |
| Soft-delete (восстановимо ≤ 30 дней) | 1 объект | Сделать + toast с Undo (8 sec) |
| Soft-delete | N объектов | Inline confirm (без modal) или toast с countdown |
| Irreversible | 1 объект | Modal confirm (одна кнопка confirm) |
| Irreversible | N объектов | Modal с type-to-confirm |
| Irreversible + cascade other users | Anything | Modal с type-to-confirm + cooldown + email-notification после |
Иерархия защиты (от слабой к сильной)
Level 0: Undo
- Действие выполняется мгновенно. Toast «X deleted. [Undo]» на 8-10 сек.
- Подходит для reversible single-object actions.
Level 1: Inline confirm
- Кнопка превращается в «Sure? Yes / Cancel» прямо на месте.
- Не блокирует UI. Юзер может игнорировать (передумал) — confirm исчезает.
- Подходит для soft-destructive (archive, hide, remove from list).
[Delete] → click → [Sure? Yes / No] → yes → action
Level 2: Modal confirm
- Открывается modal с описанием последствий + 2 кнопками.
- Confirm — destructive style (red). Cancel — primary, focused by default.
- Esc / click-outside dismisses.
┌─────────────────────────────┐
│ Delete project "Alpha"? │
│ │
│ This will delete: │
│ • 24 tasks │
│ • 8 files │
│ • Activity history │
│ │
│ This can be restored from │
│ trash within 30 days. │
│ │
│ [Cancel] [Delete] │
└─────────────────────────────┘
Level 3: Modal с type-to-confirm
- Юзер должен напечатать имя объекта (или слово «DELETE»).
- Submit button disabled пока не напечатано точно.
- Для большого blast radius или irreversible.
┌──────────────────────────────────────┐
│ Delete workspace "Acme Corp"? │
│ │
│ This will permanently delete: │
│ • 8 projects │
│ • 142 tasks │
│ • 12 team members will lose access │
│ • All data, irrecoverable │
│ │
│ Type "Acme Corp" to confirm: │
│ [______________________] │
│ │
│ [Cancel] [Delete forever] │
└──────────────────────────────────────┘
Level 4: Cooldown + email
- Подтверждение запускает delayed action (24h).
- Email с возможностью отменить в течение этого времени.
- Для account deletion, data export deletion, contract termination.
Принципы copy внутри confirm
- Title — конкретный. «Delete project Alpha?» лучше «Are you sure?».
- Описание последствий списком. Что именно уничтожается. Цифры (24 tasks, 8 files).
- Что НЕ восстановимо. Явно: «This is permanent» или «Can be restored from trash within 30 days».
- Кто ещё затронут. «12 team members will lose access» — если касается других.
- Кнопка confirm — глагол. «Delete», «Cancel subscription», «Leave team». Не «OK», не «Yes».
- Destructive style на confirm кнопке. Cancel — primary. Юзер выбирает destructive осознанно.
Default focus
- Focus на Cancel (или Esc-equivalent), не на Confirm.
- Юзер случайно нажмёт Enter → отменит, не подтвердит.
- Type-to-confirm: focus на input.
Cancel-recovery
- Cancel должен быть мгновенным и без подтверждения.
- Esc, click-outside, X — все ведут к Cancel.
- Никакого «You sure you want to cancel?» — это абсурд.
Multi-step destructive (для большого blast)
Иногда лучше split на 2 шага:
- Шаг 1: Disable / Pause. Объект становится недоступен, но не удалён.
- Шаг 2 (через N дней): Permanent delete. Email напоминание: «You disabled X N days ago. Click to delete permanently or restore.»
Это даёт «cooldown period» без раздражения юзера.
Edge cases
- Bulk delete (50 items): type-to-confirm с числом «Type 50 to confirm». Юзер видит scale.
- Cascade delete (delete parent → удаляет children): показать tree в confirm: «This will delete Project + 24 tasks + 8 docs.»
- Dependency check: «This file is used by 3 other documents. Continue?»
- Permission denied: не показывай confirm если юзер не имеет прав — кнопка должна быть disabled с tooltip «Only admin can delete».
- Network failure после confirm: toast «Delete failed. [Retry]». Объект остаётся.
Mobile
- Modal — bottom-sheet (full-screen на small).
- Кнопки крупные, разнесены (Cancel сверху или слева, Delete снизу или справа).
- Type-to-confirm — клавиатура должна быть type='text' (не email/number).
- Никаких swipe-to-delete без confirm для destructive (легко свайпнуть случайно).
A11y
- Modal —
role="dialog",aria-modal="true",aria-labelledby= title id. - Focus trap внутри modal.
- Esc closes (восстанавливает focus на trigger).
- Type-to-confirm input —
aria-describedbyс instruction text. - Кнопка delete —
aria-label="Delete project Alpha permanently"(явно).
Формат вывода
Уровень защиты
Какой level (0-4) для данного action + почему (по матрице).
Spec confirm UI
- Title (точный текст)
- Body (структура: список последствий, что необратимо, кто затронут)
- Кнопки (Cancel left/Confirm right, style)
- Default focus
- Dismiss (Esc, click-outside, X)
Type-to-confirm (если применимо)
- Что вводить
- Validation (case-sensitive?)
- Hint в placeholder
Cooldown / email (если Level 4)
- Время ожидания
- Email-text
- Cancel-link
Recovery / undo
- Если есть soft-delete: где restore
- Если есть undo-window: длительность
- Если permanent: explicit warning
Edge cases
3-5 пунктов: bulk / cascade / permission / network failure.
Mobile-spec
Что меняется на 375px.
A11y чеклист
Роли, focus, keyboard.
Anti-patterns (НЕ делать)
- ❌ «Are you sure?» на reversible action. Используй undo.
- ❌ «Yes / No» кнопки. «Delete / Cancel» лучше — глагол.
- ❌ Confirm с фокусом на destructive кнопке по умолчанию. Случайный Enter уничтожит.
- ❌ Modal без описания последствий. «Delete X?» — что именно произойдёт?
- ❌ Type-to-confirm на тривиальном действии. Юзер взбесится.
- ❌ Cooldown без email. Юзер забыл, период прошёл — данные пропали.
- ❌ Confirm для bulk без указания числа. «Delete selected?» — сколько именно?
- ❌ Destructive action как icon-only без label на mobile. Случайный тап.
- ❌ Modal, который нельзя закрыть Esc. Юзер чувствует себя в ловушке.
Полный UX-аудит сайта
Эвристическая оценка по Нильсену + проверка ключевых сценариев. На выходе — приоритизированный список проблем.
Конверсионный аудит формы регистрации
Карта трения по форме регистрации + 10 фиксов с ожидаемым импактом. Не «сделать красиво», а «убрать конкретное препятствие».
Mobile-friendly аудит (375px)
Аудит мобильной версии на iPhone SE: тач-таргеты, скролл, попапы, tap-vs-hover, input zoom.