Дерево разделов
Дерево разделов — навигация внутри объекта или приложения: список ссылок на разделы, при необходимости с вложенными. Колонкой оно стоит слева в доме настроек, рядом — в шапке страницы. Текущий раздел подсвечен индикатором Material, и подсвечивает его сервер.
Когда использовать#
- У объекта или приложения больше пяти-шести разделов, и вкладками их уже не уместить.
- Разделы группируются: «Доступ» и под ним «Метки», «Ключи».
- Навигация должна стоять на каждой странице одинаково — в боковой колонке или в шапке.
Не берите дерево для двух-трёх видов одного объекта — им место во вкладках. Для выбора значений в иерархии есть дерево галок: там пункты отмечают, а здесь по ним переходят.
Колонкой#
Вертикаль — вид по умолчанию: пункты идут колонкой, каждый ростом 48 пикселей, вложенные сдвинуты вправо. Так выглядит колонка разделов в доме настроек и оглавление слева на этом сайте.
Вертикаль — дом настроек
Дети = Новый Массив();
Дети.Добавить(Новый Структура("Подпись, Адрес", "Метки", "/настройки/метки"));
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен, Иконка",
"Общие", "/настройки", Истина, "шестерёнка"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Дети",
"Доступ", "/настройки/доступ", Дети));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Заголовок, Разделы",
"Настройки проекта", Разделы));В дереве холста имя дерева задаёт слово Заголовок, а разделы приходят прежним списком структур: слов для пунктов у дерева нет (см. Язык узлов).
Узлом холста — словами
Дети = Новый Массив();
Дети.Добавить(Новый Структура("Подпись, Адрес", "Метки", "/настройки/метки"));
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен, Иконка",
"Общие", "/настройки", Истина, "шестерёнка"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Дети",
"Доступ", "/настройки/доступ", Дети));
HTML = Кит.ДеревоРазделов(Новый Структура("Разделы", Разделы))
.Заголовок("Настройки проекта").Рендер();Пункт — пилюля ящика навигации Material. Текущий раздел залит цветом secondary-container; на наведении пункт проявляется слоем состояния.
Рубрики и опасный раздел#
Десять и больше разделов плоским списком не читаются. Поле раздела Рубрика группирует их: подпись рубрики печатается над первым разделом с этим именем — заголовком секции ящика навигации Material: title-small обычным регистром, приглушённо и с воздухом сверху. Разделы не переставляются: порядок остаётся тот, что пришёл, поэтому разделы одной рубрики кладите подряд.
Поле Опасный помечает раздел необратимого. Он печатается цветом ошибки, значок тоже, и стоит последним и без рубрики, где бы ни пришёл в списке. Открытый опасный раздел залит цветом error-container и несёт aria-current, как любой текущий.
Три рубрики и опасный раздел
Разделы = Новый Массив();
Разделы.Добавить(Настройки.Раздел("Удаление проекта", "/настройки/удаление", "корзина",
Ложь, "", Истина));
Разделы.Добавить(Настройки.Раздел("Общие", "/настройки", "шестерёнка", Истина));
Разделы.Добавить(Настройки.Раздел("Участники", "/настройки/участники", "аккаунт",
Ложь, "Доступ"));
Разделы.Добавить(Настройки.Раздел("Ключи", "/настройки/ключи", "ключ", Ложь, "Доступ"));
Разделы.Добавить(Настройки.Раздел("Почта", "/настройки/почта", "конверт",
Ложь, "Оповещения"));
Разделы.Добавить(Настройки.Раздел("Метки", "/настройки/метки", "тег", Ложь, "Оповещения"));
Разделы.Добавить(Настройки.Раздел("История", "/настройки/история", "история",
Ложь, "Журнал"));
HTML = Кит.ДеревоРазделов(Новый Структура("Разделы", Разделы))
.Заголовок("Настройки проекта").Рендер();В доме настроек рубрики и опасный раздел задаются словами: Рубрика(Подпись) у дома и Опасный() у раздела. В ряду шапки рубрики не печатаются — подпись между ходами читалась бы ещё одним ходом, по которому нельзя перейти. В группе разделов единого меню на телефоне — печатаются, в том же порядке.
Рядом#
Ориентация = «горизонталь» ставит пункты в ряд. Так каркас страницы печатает дороги приложения в шапке — тем же компонентом, с классом tree--top, который раздвигает пункты пошире.
Горизонталь — шапка
Дети = Новый Массив();
Дети.Добавить(Новый Структура("Подпись, Адрес", "Метки", "/настройки/метки"));
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен, Иконка",
"Общие", "/настройки", Истина, "шестерёнка"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Дети",
"Доступ", "/настройки/доступ", Дети));
HTML = Набор.ДеревоРазделов().Отрисовать(
Новый Структура("Заголовок, Разделы, Ориентация",
"Основная навигация", Разделы, "горизонталь"));В ряду вложенный список встаёт под своим пунктом и разрывает строку. Держите горизонталь в один уровень — как в гайдлайнах ниже.
Ряд дорог шапки
Дороги = Новый Массив();
Дороги.Добавить(Новый Структура("Подпись, Адрес, Иконка, Активен",
"Проекты", "/проекты", "куб", Истина));
Дороги.Добавить(Новый Структура("Подпись, Адрес, Иконка", "Команды", "/команды", "стопка"));
Дороги.Добавить(Новый Структура("Подпись, Адрес, Иконка", "Настройки", "/настройки", "шестерёнка"));
HTML = Набор.ДеревоРазделов().Отрисовать(
Новый Структура("Заголовок, Разделы, Ориентация, Класс",
"Дороги приложения", Дороги, "горизонталь", "tree--top"));Вложенность#
Дети раздела — массив той же формы, что и разделы. Компонент печатает всё, что пришло: свернуть ветку в браузере нельзя. Хотите показать подразделы только у текущего раздела — кладите Дети только ему, это решает сервер.
Ветка открыта у текущего раздела
Ключи = Новый Массив();
Ключи.Добавить(Новый Структура("Подпись, Адрес, Активен",
"Ключи доступа", "/настройки/доступ/ключи", Истина));
Ключи.Добавить(Новый Структура("Подпись, Адрес", "Участники", "/настройки/доступ/участники"));
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка",
"Общие", "/настройки", "шестерёнка"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка, Дети",
"Доступ", "/настройки/доступ", "замок", Ключи));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка",
"Уведомления", "/настройки/уведомления", "конверт"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Заголовок, Разделы",
"Настройки проекта", Разделы));Глубина ограничена четырьмя уровнями: модель приходит извне, и раздел может оказаться в собственных детях. Всё, что глубже, не печатается.
Раздел без адреса или с опасной схемой адреса остаётся в списке подписью, но перестаёт быть ссылкой. Пустой список разделов не печатает ничего.
Гайдлайны#
Код
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен", "Проекты", "/проекты", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Команды", "/команды"));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Настройки", "/настройки"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Разделы, Ориентация", Разделы, "горизонталь"));Код
Дети = Новый Массив();
Дети.Добавить(Новый Структура("Подпись, Адрес", "Метки", "/команды/метки"));
Дети.Добавить(Новый Структура("Подпись, Адрес", "Квоты", "/команды/квоты"));
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен", "Проекты", "/проекты", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Дети", "Команды", "/команды", Дети));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Настройки", "/настройки"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Разделы, Ориентация", Разделы, "горизонталь"));Код
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Общие", "/настройки"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен", "Доступ", "/настройки/доступ", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Уведомления", "/настройки/уведомления"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Разделы", Разделы));Код
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен", "Общие", "/настройки", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен", "Доступ", "/настройки/доступ", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Уведомления", "/настройки/уведомления"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Разделы", Разделы));Код
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка, Активен", "Общие", "/н", "шестерёнка", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка", "Доступ", "/н/доступ", "замок"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка", "Уведомления", "/н/уведомления", "конверт"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Разделы", Разделы));Код
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Иконка, Активен", "Общие", "/н", "шестерёнка", Истина));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Доступ", "/н/доступ"));
Разделы.Добавить(Новый Структура("Подпись, Адрес", "Уведомления", "/н/уведомления"));
HTML = Набор.ДеревоРазделов().Отрисовать(Новый Структура("Разделы", Разделы));Доступность#
- Дерево печатается
<nav>сaria-label: по умолчанию «Разделы», своё имя — полеЗаголовок. На странице с несколькими навигациями имена обязаны различаться, иначе скринридер покажет два одинаковых «Разделы». - Текущий раздел-ссылка несёт
aria-current="page"; цвет индикатора — только второй носитель этого смысла. - Вложенность выражена вложенными списками
<ul>, поэтому скринридер называет уровень и число пунктов в нём. - Иконка пункта декоративна, имя пункта — его подпись. Пункт без подписи не называется ничем: подпись обязательна.
- Рубрика — элемент списка с текстом, не ссылка: скринридер читает её на своём месте, перед разделами её группы.
- Опасный раздел отличается не только цветом: он всегда последний, и подпись называет необратимое словами («Удаление проекта»).
Узлом холста#
На холсте дерево — узел рода «разделы»: его кладут в боковую колонку раскладки.
Дерево узлом
Дети = Новый Массив();
Дети.Добавить(Новый Структура("Подпись, Адрес", "Метки", "/настройки/метки"));
Разделы = Новый Массив();
Разделы.Добавить(Новый Структура("Подпись, Адрес, Активен, Иконка",
"Общие", "/настройки", Истина, "шестерёнка"));
Разделы.Добавить(Новый Структура("Подпись, Адрес, Дети",
"Доступ", "/настройки/доступ", Дети));
HTML = Кит.ДеревоРазделов(Новый Структура("Разделы", Разделы))
.Заголовок("Настройки проекта").Рендер();Модель#
Структура ниже — прежний вид модели. В дереве холста из её полей словом пишется только Заголовок; Разделы, Ориентация и Класс по-прежнему передают структурой.
ДеревоРазделов.Отрисовать()src/Классы/компоненты/ДеревоРазделов.os
Отрисовывает дерево разделов.
Параметры:
Модель - Структура - Заголовок (aria-label, "Разделы"), Разделы (массив структур
Подпись, Адрес, Активен, Иконка, Рубрика (подпись над первым разделом с этим
именем рубрики; в горизонтали не печатается), Опасный (раздел цветом ошибки,
всегда последним и без рубрики), Дети — вложенные разделы той же формы),
Класс, Ориентация ("вертикаль" | "горизонталь").
Возвращаемое значение:
Строка - фрагмент <nav class="tree"> либо "" для пустого списка разделов.Кит.ДеревоРазделов()src/Классы/холст/Кит.os
Дерево разделов — навигация по дому настроек. Слова: Заголовок. Параметры: Модель - Структура - модель компонента «Дерево разделов». Возвращаемое значение: ЭлементЭкрана
ДеревоРазделов.ПредельнаяГлубина()src/Классы/компоненты/ДеревоРазделов.os
Предельная глубина вложенности разделов — страховка от бесконечной рекурсии: модель приходит извне, и раздел может оказаться в собственных «Детях». Возвращаемое значение: Число
ДеревоРазделов.ПунктыПоПорядку()src/Классы/компоненты/ДеревоРазделов.os
Разделы в порядке печати и подписи рубрик над ними. Рубрика печатается над ПЕРВЫМ
разделом со своим именем: разделы не переставляются, поэтому порядок, который выбрал
дом, сохраняется. Опасные разделы уходят в конец и рубрики не получают: необратимое
не должно стоять между «Метками» и «Тегами», и под чужой рубрикой ему тоже не место.
Параметры:
Разделы - Массив из Структура - разделы одного уровня, см. Отрисовать.
Возвращаемое значение:
Массив из Структура - Раздел (структура раздела как пришла), Рубрика (подпись, которую
печатать над ним; "" — не печатать).