oscript-ui
oscript-ui

Кнопка

Кнопка запускает действие: сохранить, отправить, удалить, открыть окно. Если адрес задан, она печатается ссылкой и ведёт на другую страницу, оставаясь внешне кнопкой.

Когда использовать#

  • Человек должен сделать что-то: отправить форму, подтвердить, создать запись.
  • Нужно главное действие экрана, которое должно бросаться в глаза.
  • Ссылка оформлена кнопкой, потому что это шаг сценария («Создать проект»), а не переход по тексту.

Не берите кнопку для перехода внутри текста — там нужна обычная ссылка. Для выбора одного из нескольких видов экрана подойдут вкладки. Для действий над строкой таблицы, которых больше двух, подойдёт меню.

В дереве холста кнопка собирается словами: подпись позицией, вариант, размер и остальное — цепочкой (см. Язык узлов).

Узлом холста — словами

HTML = Кит.Кнопка("Сохранить").Основная().Иконка("сохранить").Рендер();

Варианты#

Вариант задаёт вес кнопки. Выбирайте его по тому, насколько действие важно на этом экране, а не по вкусу.

Основная — главное действие экрана

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, Иконка", "Сохранить", "основная", "сохранить"));

Основная кнопка в Material залита цветом primary и на наведении приподнимается. На экране она одна: если залито всё, не выделено ничего.

Вторичная — второе по важности действие

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, Иконка", "Предпросмотр", "вторичная", "поиск"));

Вторичная кнопка — кнопка с обводкой. Она стоит рядом с основной («Отмена» рядом с «Сохранить») или одна там, где действие нужно, но не главное.

Опасная — действие, которое нельзя отменить

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, Иконка", "Удалить проект", "опасная", "корзина"));

Опасная кнопка залита цветом ошибки. Ставьте её только на необратимые действия, и лучше внутри опасной зоны с подтверждением.

Ссылка — самое лёгкое действие

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, Иконка", "Подробнее", "ссылка", "вправо"));

Кнопка-текст без заливки и рамки. Ей место в плотных местах (строка таблицы, подвал карточки) и рядом с другими кнопками как третье действие.

Размеры#

Обычная кнопка — 36 пикселей высотой, кнопка-значок — круг 36. Малая (28) нужна в строке таблицы и в шапке, большая (56) — на пустом экране с одним действием.

Малая

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Размер", "Отозвать", "малый"));

Большая

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Размер, Иконка", "Создать первый проект", "большой", "плюс"));

Во всю ширину — в узкой колонке и на телефоне

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, ВоВсюШирину", "Войти", Истина));

Ссылка-кнопка#

Задан Адрес — кнопка печатается тегом <a>: переход работает без формы, открывается в новой вкладке колесом мыши и индексируется. Вид при этом тот же.

Ссылка-кнопка

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Адрес, Иконка", "Открыть список", "/документы", "вправо"));

Состояния#

Заблокированная кнопка остаётся на месте и не отвечает. Занятая показывает круговой индикатор: сервер уже работает, второй раз нажимать не нужно.

Заблокирована

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Заблокирована", "Нельзя", Истина));

Занята

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Занята", "Сохраняется", Истина));

Заблокированная ссылка-кнопка — без адреса и с aria-disabled

Недоступно
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Адрес, Заблокирована", "Недоступно", "/документы", Истина));

Только иконка#

Кнопка-значок — круг 40 пикселей. Подпись у неё всё равно обязательна: она уходит в aria-label и всплывающую подсказку, иначе скринридер прочтёт «кнопка» и ничего больше.

Переключатель темы

HTML = Набор.Кнопка().Отрисовать( Новый Структура("Подпись, Вариант, Размер, Иконка, ТолькоИконка", "Переключить тему", "ссылка", "малый", "луна", Истина));

Со счётчиком — сколько ждёт человека

HTML = Набор.Кнопка().Отрисовать( Новый Структура("Подпись, Вариант, Иконка, ТолькоИконка, Счётчик, ПодписьСчётчика", "Уведомления", "вторичная", "конверт", Истина, 3, "3 новых"));

Кнопка и форма#

Кнопка отправки умеет отправить свою форму не туда, куда смотрит форма (АдресОтправки), и открыть ответ в новой вкладке (ВНовойВкладке). Так «Предпросмотр» живёт в той же форме, что и «Сохранить», и не теряет введённое.

Отправляет форму на другой адрес своего приложения

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, АдресОтправки", "Предпросмотр", "вторичная", "/статьи/предпросмотр"));

Ответ — в новой вкладке, форма остаётся как была

HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, АдресОтправки, ВНовойВкладке", "Предпросмотр", "вторичная", "/статьи/предпросмотр", Истина));

АдресОтправки принимает только адрес своего приложения: путь, запрос или якорь. Схема и чужой хост — исключение разработчику, потому что вместе с формой уехал бы и токен CSRF.

Кнопка без отправки#

Кнопка внутри формы по умолчанию её отправляет (type="submit"): так работает Enter в поле и так сервер получает форму без скрипта. Кнопке, которая форму слать не должна, — кнопке образца, который показывает, как будет выглядеть сохранённое, кнопке «Показать ещё» своего скрипта, — нужно слово БезОтправки(): она печатается type="button" и форму не трогает. Прежнее имя того же слова — Обычная(). Кнопку-ссылку (Адрес) слово не меняет: ссылка формы не отправляет и так.

В форме значений — кнопка образца не отправляет форму

Как увидят посетители
HTML = Кит.Форма("/настройки/оформление", Кит.Поле("brand", "Название").Значение("Ромашка"), Кит.Образец("Как увидят посетители", Кит.Ряд("действия", Кит.Кнопка("Создать проект").Основная().Иконка("плюс").БезОтправки())), Кит.Кнопка("Сохранить").Основная()).Токен("т0кен-сессии").Рендер();

Не делайте кнопку образца ссылкой на сам образец (Адрес("#образец")): щелчок по ней прокручивает страницу и меняет адрес, а скринридер объявляет ссылку, а не кнопку.

Гайдлайны#

ДелайтеОдно главное действие на экране — основной кнопкой, остальные легче
Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "Отмена", "вторичная"))
	+ Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Иконка", "Сохранить", "сохранить"));
Не делайтеНесколько основных кнопок рядом: глаз не находит главное
Код
HTML = Набор.Кнопка().Отрисовать("Отмена")
	+ Набор.Кнопка().Отрисовать("Сохранить")
	+ Набор.Кнопка().Отрисовать("Опубликовать");
ДелайтеПодпись — глагол, который говорит, что случится
Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант, Иконка",
	"Удалить проект", "опасная", "корзина"));
Не делайтеПодпись, которая не называет действие
Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Вариант", "ОК", "опасная"));
ДелайтеИконка рядом с подписью повторяет смысл
Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Иконка", "Скачать", "скачать"));
Не делайтеИконка спорит с подписью
Код
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Иконка", "Скачать", "корзина"));

Доступность#

  • Подпись обязательна всегда. У кнопки-значка она уходит в aria-label, и кит не соберёт кнопку без неё.
  • Заблокированная ссылка печатается без href и с aria-disabled: атрибут disabled на ссылке браузер не слушает.
  • Занятая кнопка несёт aria-busy="true".
  • Кнопка БезОтправки — настоящая кнопка (type="button"): скринридер называет её кнопкой, Enter и пробел нажимают её, а Enter в поле формы её не нажимает.
  • Фокус с клавиатуры виден всегда: обводка цветом secondary вокруг пилюли.
  • На касании (pointer: coarse) область нажатия кнопки-значка — 48 × 48 пикселей, как требует Material, хотя видна она кругом 36 (малая — 32): область расширяет невидимый псевдоэлемент. Так же расширены крестик плашки списка, кружок акцента, значок «?» подсказки, а ссылка, которая одна в ячейке таблицы, занимает всю высоту ряда и не ниже 48.

Узлом холста#

На холсте кнопка — такой же узел, как остальные: её кладут в форму, ряд или ячейку таблицы.

Кнопка узлом дерева

HTML = Кит.Кнопка("Сохранить").Основная().Рендер();

Модель#

Поля модели — из комментария в исходнике компонента, поэтому справка не отстаёт от кода. Структура с этими полями — прежний вид модели: в дереве холста те же поля пишут слова Кит.Кнопка.

Кит.Кнопка()src/Классы/холст/Кит.os

Кнопка формы или ссылка-кнопка. Слова: Основная, Вторичная, Опасная, Ссылкой, Малая,
Большая, Обычная, БезОтправки (кнопка в форме, которая её не отправляет: type="button";
Обычная — то же), Иконка, ТолькоИконка, Адрес, Имя(Имя, Значение), БезВалидации,
АдресОтправки, ВНовойВкладке, ВФорме(Якорь), Заблокирована, Занята, Подсказка,
ВоВсюШирину, Текущая, Команда(Команда, Цель), Открывает(Ид), Счётчик(Число, Подпись),
ЗнакРаскрытия, Картинка.

Параметры:
 Модель - Строка, Структура - подпись кнопки; Структура — прежний вид модели
          компонента «Кнопка».

Возвращаемое значение:
 ЭлементЭкрана

Кнопка.Отрисовать()src/Классы/компоненты/Кнопка.os

Отрисовывает кнопку либо ссылку-кнопку (если задан Адрес).

Параметры:
 Модель - Структура, Строка - подпись либо структура: Подпись (обязательна),
          Вариант ("основная" | "вторичная" | "опасная" | "ссылка"), Размер
          ("обычный" | "малый" | "большой"), Адрес, Тип ("отправка" | "обычная"),
          Имя и Значение (name/value кнопки формы), Иконка, Картинка (адрес изображения
          вместо иконки набора; небезопасный или пустой адрес изображения не даёт),
          Заблокирована, Занята (disabled + aria-busy), Подсказка, ВоВсюШирину,
          ТолькоИконка (подпись уходит в aria-label вместо видимого текста),
          БезВалидации (formnovalidate: кнопка отправляет форму, не спрашивая
          обязательные поля), АдресОтправки (formaction: кнопка отправки шлёт свою
          форму на этот адрес вместо адреса формы; адрес своего приложения,
          относительный; пустой атрибута не даёт; у кнопки, которая форму не
          отправляет, не печатается), ВНовойВкладке (formtarget="_blank": ответ на
          отправку открывается в новой вкладке, а страница с заполненной формой
          остаётся как была; у кнопки, которая форму не отправляет, не печатается),
          Форма (атрибут form: кнопка отправки стоит вне своей формы и отправляет
          форму с этим якорем — так действия формы собираются в одном ряду с кнопками
          соседних форм; у кнопки, которая форму не отправляет, не печатается),
          Текущая (ссылка-кнопка помечается aria-current как выбранная в своей
          группе), Команда ("показать-окно" | "закрыть":
          кнопка управляет элементом движком браузера, без скрипта) и Цель
          (идентификатор управляемого элемента; обязательна при Команде),
          Окно (идентификатор окна этой страницы у ссылки-кнопки с Адресом: ссылка
          несёт признак data-opens, и скрипт кита открывает это окно вместо перехода;
          без скрипта — переход по Адресу на страницу, где сервер печатает окно
          открытым; у кнопки без Адреса не печатается), Закрывает (дев-сборка 8:
          идентификатор окна у ссылки-кнопки с Адресом: ссылка несёт признак data-closes,
          и скрипт кита закрывает это окно вместо перехода; без скрипта — переход по
          Адресу на страницу без окна; у кнопки без Адреса не печатается),
          Открывает (идентификатор всплывающей панели: кнопка становится её
          открывашкой — атрибут popovertarget, и открытие, закрытие и состояние
          «открыто» тоже берёт на себя движок), Счётчик (число на кнопке: ноль,
          пусто и отсутствие бейджа не печатают вовсе), ПодписьСчётчика (чем это
          число называется в речи; обязательна, когда бейдж печатается: у кнопки
          с видимым текстом она прячется внутрь кнопки, у кнопки-значка входит
          в её aria-label) и
          ЗнакРаскрытия (кнопка показывает шеврон — видимый признак того,
          что она открывает панель).

Возвращаемое значение:
 Строка - HTML-фрагмент. Кидается исключением, если Подпись пуста или у кнопки
          отправки АдресОтправки — не относительный адрес своего приложения.