Настройки
Всякая настройка сначала отвечает на один вопрос — применяется она сразу или по сохранению. Всё остальное на экране следует из ответа.
Что решает
Экран настроек выглядит формой, а ведёт себя пультом, и смешение этих двух — та самая причина, по которой настройки так часто сбивают с толку.
Всё остальное решает один вопрос: изменение применяется сразу или по сохранению? Мгновенным настройкам не нужны ни кнопки, ни состояние «несохранено»; отложенным нужно и то и другое, и нужно об этом сказать. Экран, смешавший их без видимой границы, приучает не доверять ни тем ни другим.
Анатомия
Контрол выбирают по форме выбора, а не по тому, сколько он занимает места. Условие для каждого записано в библиотеке:
- Настройка включается сразу —
GrSwitch. Это переключатель именно потому, что «применить» тут нет: щелчок и есть действие. - Вариантов до семи и все видны —
GrRadioGroup. Один выбор из набора, который читается взглядом. - Переключение вида одного и того же —
GrSegmented. Настройка не объекта, а того, как вы на него смотрите. - Значений несколько из короткого набора —
GrCheckboxGroup. Одно поле, много значений, общее состояние. - Поле формы со списком значений —
GrSelect. Когда набор слишком длинный, чтобы показывать его раскрытым. - Точное число не важно —
GrSlider. Значение, которое чувствуют, а не вводят; если число точное, ему место в поле. - Форма длинная —
GrFormSection. Секции делают страницу настроек просматриваемой; без них это список, который читают сверху. - Действие необратимо —
GrConfirmDialog. Удаление рабочего пространства не стоит среди чекбоксов.
Пример
Так и не так
Так — Мгновенные настройки применяются мгновенно
Переключатель меняет то, о чём он, в момент щелчка, и экран показывает результат. Никакого «сохранить» для переключателей: кнопка просила бы подтвердить уже сделанное.
Так не надо — Кнопка сохранения над страницей переключателей
Если кнопка есть, то переключатели не были переключателями — это форма, нарисованная контролами в форме переключателей. Человек щёлкнул три, ушёл — и потерял все три, не узнав об этом.
Так — Состояние произносится, а не только окрашено
«Уведомления: включены» лучше цветной дорожки. GrSwitch — нативная
<button role="switch">: состояние объявляется, а Space и Enter переключают —
именно это попробует тот, кто работает с клавиатуры.
Так не надо — Переключатель для того, что не бинарно
У «темы» три значения — светлая, тёмная, системная, — а у переключателя два.
Получается переключатель плюс спрятанное третье состояние, и спрятанное
оказывается умолчанием. Три варианта — это GrRadioGroup или GrSegmented.
Так — Опасное — отдельно
Удаление аккаунта, отзыв всех токенов, передача владения: ниже настроек,
визуально отдельно, и GrConfirmDialog называет последствие словами. Расстояние
здесь — часть решения.
Так не надо — Опасное действие в общем ряду
Красная кнопка среди обычных — один промах мимо необратимого. Цвет предупреждает только тех, кто его видит, а экран, посещённый пятьдесят раз, не читает никто.
Доступность
Переключатель — переключатель, радиогруппа — радиогруппа. Роли разные, и
клавиатура разная: Space или Enter переключают switch; в радиогруппе ходят
стрелки, и выбор едет вместе с фокусом. Нарисовать одно другим — значит объявить
не то, что происходит.
GrSegmented ходит по обеим осям. Влево-вправо и вверх-вниз, при любой
ориентации, — этого требует APG от radiogroup, и человек, попробовавший другую
пару стрелок, не должен упереться в пустоту.
Группировка должна быть настоящей. GrFormSection даёт группу с заголовком, и
скринридер может сказать, к какому разделу относится контрол. Визуальная
группировка — группировка только для тех, кто её видит.
Самое трудное в экране настроек не на этой странице: это решить, какие настройки вообще должны существовать. Каждая опция — вопрос, на который продукт отказался ответить за пользователя.
Компоненты паттерна
Список строится из frontmatter, а не из ссылок в тексте: переименование слага здесь не теряется.
GrSwitchФормыGrRadioGroupФормыGrSegmentedФормыGrCheckboxGroupФормыGrSelectФормыGrSliderФормыGrFormSectionФормыGrConfirmDialogСлои
Клавиатура
Контракты приходят из библиотеки. Паттерн их не пересказывает — он на них ссылается.
GrSwitchКонтракт компонентаGrRadioGroupКонтракт компонентаGrSegmentedКонтракт компонентаGrCheckboxGroupКонтракт компонентаGrSelectКонтракт компонентаGrSliderКонтракт компонентаGrConfirmDialogКонтракт компонента