oscript-ui
oscript-ui

Образец

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

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

  • Настройка меняет вид: название и акцент сайта, подпись письма, карточка проекта.
  • Человеку нужно увидеть результат до сохранения, а не после.
  • Результат выглядит по-разному в светлой и тёмной теме, и это стоит проверить.

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

Рамка и зеркало#

Кит.Образец(Подпись, д…) — узел рода «образец»: фигура с подписью, переключатель «Светлая / Тёмная» и рамка с детьми узла. Слово Зеркало(ИмяПоля) у любого узла внутри — признак data-mirror: скрипт кита пишет в узел текущее значение поля с этим именем при каждом вводе. Текст узла — то, что напечатал сервер, и он же возвращается, когда поле опустело.

Название и акцент — наберите название, выберите цвет

Акцент
Фиолетовый
Шапка сайта

Ромашка

Проекты, участники, сборки

Форма = Кит.Форма("/образец-картинки/шапка", Кит.Поле("title", "Название сайта").Значение("Ромашка").Ид("obrazec-title"), Кит.Поле("accent", "Акцент").Ид("obrazec-accent").Значение("#6750a4") .Образец("#6750a4", "Фиолетовый").Образец("#1a73e8", "Синий") .Образец("#188038", "Зелёный").Образец("#b3261e", "Красный"), Кит.Кнопка("Сохранить").Основная()) .Вид("столбик").БезПерезагрузки(); Образец = Кит.Образец("Шапка сайта", Кит.Область( Кит.Заголовок(3, "Ромашка").Зеркало("title"), Кит.Примечание("Проекты, участники, сборки")).Зеркало("accent", "#6750a4")) .Тема("светлая").Якорь("obrazec-shapki"); HTML = Кит.Область(Кит.Область(Форма).Вид("работа"), Образец).Вид("студия") .Токен("т0кен-сессии").Рендер();

Форма уходит на образец с сервером: там сохранённые название и акцент печатает сервер. Раскладка «поля слева, образец справа» — область вида студия: на узком экране образец уезжает под поля.

Поле цвета — поле вида «цвет» с образцами-кружками, как здесь, или системный выбор цвета — пишет не текст, а пользовательское свойство CSS --mirror-<имя> на узле. Его берёт лист приложения: у этого сайта акцент — полоса слева у шапки (border-left: 6px solid var(--mirror-accent, var(--md-sys-color-primary))). Пустое значение («по умолчанию») свойство снимает, и лист берёт своё. Вторым аргументом Зеркало(ИмяПоля, Цвет) сервер печатает то же свойство с сохранённым цветом — образец верен и без скрипта. Цвет — только #rgb, #rrggbb или #rrggbbaa: он печатается в атрибут style, в CSS-контекст.

Имя поля зеркала — буквы (латиница и кириллица), цифры, «-» и «_», без точки: оно становится признаком data-mirror и частью имени свойства CSS --mirror-<имя>, а точка в имени свойства его ломает. Ключ настройки вида ui.brand зеркалить нельзя — назовите поле формы без точек (brand) и сопоставьте с ключом на сервере. Имя с точкой кит не пропускает: сборка останавливается с этим объяснением.

Акцент в образце#

Зеркало поля с именем accent кит понимает сам: узел образца, на котором стоит --mirror-accent, пересобирает свою палитру акцента из этого цвета. Основная кнопка, плашка вида accent, ссылка и контурная кнопка внутри него берут выбранный цвет так, как возьмут его на сайте; текст на акценте — белый или чёрный по светлоте цвета, контейнер плашки — тот же цвет поверх поверхности рамки. Листа приложения не нужно. Пустое поле («по умолчанию») возвращает узлу акцент рамки.

Акцент перекрашивает кнопку и плашку образца

Акцент
Красный
Акцент на сайте
новоеВсе проекты
Форма = Кит.Форма("/образец-картинки/шапка", Кит.Поле("accent", "Акцент").Ид("obrazec-akcent-pole").ОбразцыТемы().Значение("#e5484d"), Кит.Кнопка("Сохранить").Основная()) .Вид("столбик").БезПерезагрузки(); Образец = Кит.Образец("Акцент на сайте", Кит.Область( Кит.Кнопка("Создать проект").Основная().Иконка("плюс").БезОтправки(), Кит.Плашка("новое").Вид("accent"), Кит.Ссылка("#obrazec-akcenta", "Все проекты")) .Вид("полоса").Зеркало("accent", "#e5484d")) .Якорь("obrazec-akcenta"); HTML = Кит.Область(Кит.Область(Форма).Вид("работа"), Образец).Вид("студия") .Токен("т0кен-сессии").Рендер();

Перекрашивается только узел с зеркалом и то, что внутри него, и только в образце: страница вокруг остаётся в своём акценте. Зеркало на самой рамке (Кит.Образец(…).Зеркало("accent", …)) перекрашивает рамку целиком. Поле с другим именем перекрашивает только то, что возьмёт его свойство в листе приложения.

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

Зеркало признаком#

Текстом вид не поменять: выбор сегмента «Устаревший» должен перекрасить плашку, а не вписать в неё слово deprecated. Слово ЗеркалоПризнаком(ИмяПоля, Значение) пишет значение поля — выбранного сегмента, радиокнопки, варианта списка, набранного текста — в признак data-mirror-<имя> узла, и вид по нему задаёт лист приложения: [data-mirror-стиль="deprecated"] .tag { … }. Вторым аргументом сервер печатает текущее значение тем же признаком — без скрипта образец показывает сохранённый вид; скрипт кита переписывает признак при каждом выборе. Текст узла и свойство --mirror-* слово не трогает.

Зеркало признаком годится и для компонента — плашки, значка, кнопки: разметку компонента кит не переписывает, а только кладёт признак на его первый тег. У одного узла может быть несколько зеркал признаком, по одному на поле: узел несёт их список признаком data-mirrors, по нему скрипт его и находит. Имя поля — по тем же правилам, что у Зеркало; в признаке оно печатается строчными.

Плашка меняет вид по сегменту, а значок — по списку

Так будет выглядеть плашка
v2.4
Форма = Кит.Форма("/проекты/альфа/тег", Кит.Сегменты("стиль", Кит.Сегмент("plain", "Обычный"), Кит.Сегмент("stable", "Стабильный"), Кит.Сегмент("deprecated", "Устаревший")).Подпись("Стиль плашки").Выбрано("stable"), Кит.Поле("значок", "Значок").Вариант("тег", "Тег").Вариант("ключ", "Ключ") .Вариант("пакет", "Пакет").Значение("ключ"), Кит.Кнопка("Сохранить").Основная()) .Вид("столбик").БезПерезагрузки(); Плашка = Кит.Плашка( Кит.Надпись(Кит.Иконка("тег")).Признак("glyph", "тег"), Кит.Надпись(Кит.Иконка("ключ")).Признак("glyph", "ключ"), Кит.Надпись(Кит.Иконка("пакет")).Признак("glyph", "пакет"), "v2.4") .ЗеркалоПризнаком("стиль", "stable").ЗеркалоПризнаком("значок", "ключ"); Образец = Кит.Образец("Так будет выглядеть плашка", Плашка).Якорь("obrazec-plashki"); HTML = Кит.Область(Кит.Область(Форма).Вид("работа"), Образец).Вид("студия") .Токен("т0кен-сессии").Рендер();

Лист этого сайта — то, что напишет приложение: вид плашки по признаку стиля и один глиф из трёх по признаку значка. Кит здесь ничего не знает ни о стилях, ни о глифах.

Тема рамки#

Тема рамки — атрибут data-theme на ней: словом Тема("светлая" | "тёмная") сервер печатает её сразу, переключатель меняет её скриптом, повторное нажатие возвращает рамку к теме страницы. Обе палитры уже лежат в голове страницы, но привязаны к <html>, поэтому для рамки скрипт собирает палитру из того же блока токенов и подключает листом без разметки. Сменился акцент страницы — палитра рамки пересобирается.

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

Что печатает сервер

<figure id="obrazec-razmetka" class="preview"><figcaption class="preview__label">Карточка проекта</figcaption><div class="preview__themes" role="group" aria-label="Тема образца"><button type="button" class="preview__theme" data-preview-theme="light" aria-pressed="false">Светлая</button><button type="button" class="preview__theme" data-preview-theme="dark" aria-pressed="true">Тёмная</button></div><div class="preview__frame" data-theme="dark"><h3 data-mirror="name">Альфа</h3><p class="muted">Сборка каждую ночь</p></div></figure>
HTML = Кит.Образец("Карточка проекта", Кит.Заголовок(3, "Альфа").Зеркало("name"), Кит.Примечание("Сборка каждую ночь")) .Тема("тёмная").Якорь("obrazec-razmetka").Рендер();

Гайдлайны#

Карточка проекта

Альфа

Сборка каждую ночь

ДелайтеОбразец показывает то, что меняют поля рядом
Код
Образец = Кит.Образец("Карточка проекта",
	Кит.Заголовок(3, "Альфа").Зеркало("name"),
	Кит.Примечание("Сборка каждую ночь").Зеркало("about"));
HTML = Образец.Якорь("delat-obrazec").Рендер();
Образец

Пример заголовка

Пример текста

Не делайтеОбразец без связи с полями: картинка, которая не отвечает на ввод
Код
Образец = Кит.Образец("Образец",
	Кит.Заголовок(3, "Пример заголовка"),
	Кит.Примечание("Пример текста"));
HTML = Образец.Якорь("ne-delat-obrazec").Рендер();

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

  • Образец — фигура (<figure>): подпись первой (<figcaption>), ею фигура и названа.
  • Переключатель — группа «Тема образца» из двух кнопок-тумблеров с aria-pressed: скринридер говорит, какая тема нажата.
  • Зеркало пишет текст, а не разметку: набранное в поле не исполняется.
  • Текст на акценте в образце — белый или чёрный, что контрастнее к выбранному цвету: кнопка образца читается при любом акценте палитры.
  • Смена текста в зеркале не объявляется скринридеру: человек и так слышит, что набирает. Если образец важен для решения, пусть сервер повторит его словами после сохранения — тостом.

Модель#

Кит.Образец()src/Классы/холст/Кит.os

Образец — рамка предпросмотра: подпись, переключатель темы (светлая, тёмная) и рамка,
в которую кладут любое дерево. Что показывать, решает приложение; меняться по мере ввода
образцу помогает слово Зеркало(ИмяПоля) у узлов внутри него. Без скрипта рамка показана
в теме страницы, переключатель спрятан. Слова: Тема(«светлая» | «тёмная»), Якорь,
Зеркало.

Параметры:
 Подпись - Строка - что показано: подпись фигуры для глаза и скринридера.
 Р1…Р8   - ЭлементЭкрана, Строка - (необязательные) содержимое рамки; строка — текст.

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

ЭлементЭкрана.Зеркало()src/Классы/холст/ЭлементЭкрана.os

Зеркало значения: узел показывает текущее значение поля с этим именем, и скрипт кита
переписывает его при каждом вводе — образец меняется без сервера. Узел печатает признак
data-mirror; текст узла — то, что напечатал сервер, и он же возвращается, когда поле
опустело. Для поля цвета (системный выбор цвета или образцы-кружки) скрипт пишет не текст,
а пользовательское свойство CSS --mirror-<имя> на узле: его берёт лист приложения
(background: var(--mirror-accent, …)). Цвет вторым аргументом печатает то же свойство
сервером — сохранённое значение видно и без скрипта. Зеркало поля accent внутри образца
кит понимает сам (0.13, дев-сборка 6): узел пересобирает из --mirror-accent свою палитру
акцента, и основная кнопка, плашка accent и ссылка внутри берут выбранный цвет. Имя поля —
без точки: ключ настройки «ui.brand» зеркалят полем формы «brand».

Параметры:
 ИмяПоля - Строка - имя поля формы (name): буквы, цифры, «-» и «_».
 Цвет    - Строка - (необязательный) текущий цвет #rgb, #rrggbb или #rrggbbaa.

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

ЭлементЭкрана.Тема()src/Классы/холст/ЭлементЭкрана.os

Тема рамки образца при печати. Без слова рамка показана в теме страницы; переключатель
на рамке меняет тему скриптом.

Параметры:
 Значение - Строка - «светлая» | «тёмная».

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

Образец.Отрисовать()src/Классы/холст/Образец.os

Печатает рамку образца.

Параметры:
 Модель - Структура - Подпись (обязательна: что показано — она и подпись фигуры для
          скринридера), Тема («light» | «dark» | "" — тема рамки при печати; пусто —
          тема страницы), Атрибуты (ДОВЕРЕННЫЙ фрагмент атрибутов фигуры: id, класс,
          data-признаки — его печатает холст), Тело (ДОВЕРЕННЫЙ HTML содержимого рамки),
          Палитры (дев-сборка 9: ДОВЕРЕННЫЙ CSS палитр пресета темы для рамки — его
          собирает холст из ТокеныТемы; печатается <style> в конце фигуры).

Возвращаемое значение:
 Строка - HTML <figure>.