bukatchuk ui

Элементы

Боковая панель

Панель кабинета: группы ссылок, активный пункт, вложенные группы, сворачивание до значков с запоминанием; на узком экране выезжает поверх страницы. Каркас .sidebar-layout.

sidebar с версии 0.1.0 со скриптом

Примеры

Кабинет сервиса видеоконференций
<div class="sidebar-layout">
  <aside class="sidebar" id="sb-ex-1" data-ui-sidebar="meet-cabinet" aria-label="Кабинет">
    <div class="sidebar__head">
      <span class="sidebar__title">Кабинет</span>
      <button class="sidebar__collapse" type="button" data-ui-sidebar-collapse aria-expanded="true" aria-label="Свернуть панель">«</button>
      <button class="sidebar__close" type="button" data-ui-sidebar-close aria-label="Закрыть панель">×</button>
    </div>
    <nav class="sidebar__nav" aria-label="Разделы кабинета">
      <div class="sidebar__group" role="group" aria-labelledby="sb-ex-1-g1">
        <p class="sidebar__label" id="sb-ex-1-g1">Работа</p>
        <ul class="sidebar__list">
          <li><a class="sidebar__link is-active" href="/meetings/" aria-current="page"><span class="sidebar__icon" aria-hidden="true">▣</span><span class="sidebar__text">Встречи</span><span class="sidebar__badge">3</span></a></li>
          <li><a class="sidebar__link" href="/rooms/"><span class="sidebar__icon" aria-hidden="true">□</span><span class="sidebar__text">Комнаты</span></a></li>
          <li>
            <button class="sidebar__link sidebar__toggle" type="button" aria-expanded="true" aria-controls="sb-ex-1-rec"><span class="sidebar__icon" aria-hidden="true">●</span><span class="sidebar__text">Записи</span><span class="sidebar__caret" aria-hidden="true">↓</span></button>
            <ul class="sidebar__list sidebar__list--nested" id="sb-ex-1-rec">
              <li><a class="sidebar__link" href="/recordings/new/"><span class="sidebar__text">Новые</span></a></li>
              <li><a class="sidebar__link" href="/recordings/archive/"><span class="sidebar__text">Архив</span></a></li>
            </ul>
          </li>
        </ul>
      </div>
      <div class="sidebar__group" role="group" aria-labelledby="sb-ex-1-g2">
        <p class="sidebar__label" id="sb-ex-1-g2">Настройки</p>
        <ul class="sidebar__list">
          <li><a class="sidebar__link" href="/team/"><span class="sidebar__icon" aria-hidden="true">☰</span><span class="sidebar__text">Команда</span></a></li>
          <li><a class="sidebar__link" href="/billing/"><span class="sidebar__icon" aria-hidden="true">₽</span><span class="sidebar__text">Оплата</span></a></li>
        </ul>
      </div>
    </nav>
  </aside>
  <div class="sidebar__backdrop" data-ui-sidebar-close></div>
  <div class="sidebar-layout__main">
    <button class="sidebar-layout__open" type="button" data-ui-sidebar-open="#sb-ex-1" aria-expanded="false" aria-controls="sb-ex-1"><span aria-hidden="true">☰</span> Разделы</button>
    <h2>Ближайшие встречи</h2>
    <p class="muted">Содержимое страницы кабинета.</p>
  </div>
</div>
Панель без вложенных групп
<div class="sidebar-layout">
  <aside class="sidebar" id="sb-ex-2" data-ui-sidebar="blog-admin" aria-label="Администрирование блога">
    <div class="sidebar__head">
      <span class="sidebar__title">Блог</span>
      <button class="sidebar__collapse" type="button" data-ui-sidebar-collapse aria-expanded="true" aria-label="Свернуть панель">«</button>
      <button class="sidebar__close" type="button" data-ui-sidebar-close aria-label="Закрыть панель">×</button>
    </div>
    <nav class="sidebar__nav" aria-label="Разделы">
      <ul class="sidebar__list">
        <li><a class="sidebar__link" href="/admin/posts/"><span class="sidebar__icon" aria-hidden="true">≡</span><span class="sidebar__text">Записи</span></a></li>
        <li><a class="sidebar__link is-active" href="/admin/drafts/" aria-current="page"><span class="sidebar__icon" aria-hidden="true">✎</span><span class="sidebar__text">Черновики</span><span class="sidebar__badge">2</span></a></li>
        <li><a class="sidebar__link" href="/admin/comments/"><span class="sidebar__icon" aria-hidden="true">✉</span><span class="sidebar__text">Комментарии</span></a></li>
      </ul>
    </nav>
  </aside>
  <div class="sidebar__backdrop" data-ui-sidebar-close></div>
  <div class="sidebar-layout__main">
    <button class="sidebar-layout__open" type="button" data-ui-sidebar-open="#sb-ex-2" aria-expanded="false" aria-controls="sb-ex-2"><span aria-hidden="true">☰</span> Разделы</button>
    <h2>Черновики</h2>
  </div>
</div>

Установка

bukatchuk-ui add sidebar

Вместе с компонентом установятся: tokens, fonts, base, core.

Файлы

ФайлНазначение
sidebar.cssстили
sidebar.jsскрипт
example.htmlобразец разметки, в проект не копируется
sidebar.jekyll.htmlвставка для Jekyll
sidebar.jinja.htmlвставка для Jinja

Переменные

ПеременнаяЧто задаёт
--sidebar-wширина панели
--sidebar-w-minширина свёрнутой панели
--sidebar-main-padполя основной области

Клавиши

КлавишаДействие
Tabпереход по пунктам; на узком экране фокус удерживается внутри открытой панели
Enter, Пробелперейти по ссылке, раскрыть или свернуть группу, свернуть или развернуть панель
Escзакрыть выехавшую панель, фокус возвращается на кнопку «Разделы»

Вставка для Jekyll

{%- comment -%}
  Боковая панель кабинета (без содержимого: каркас .sidebar-layout и основную область откройте в шаблоне сами,
  см. example.html). Параметры: groups — список групп из _data (label, items); пункт: text, href, icon, badge.
  key — ключ запоминания свёрнутого состояния, title — название панели, id — id панели (по умолчанию sidebar).
  Вложенные группы на Jekyll пишутся вручную по образцу из example.html.
{%- endcomment -%}
{%- assign sid = include.id | default: 'sidebar' -%}
<aside class="sidebar" id="{{ sid }}" data-ui-sidebar="{{ include.key | default: 'cabinet' }}" aria-label="{{ include.title | default: 'Кабинет' }}">
  <div class="sidebar__head">
    <span class="sidebar__title">{{ include.title | default: 'Кабинет' }}</span>
    <button class="sidebar__collapse" type="button" data-ui-sidebar-collapse aria-expanded="true" aria-label="Свернуть панель">«</button>
    <button class="sidebar__close" type="button" data-ui-sidebar-close aria-label="Закрыть панель">×</button>
  </div>
  <nav class="sidebar__nav" aria-label="Разделы">
    {%- for g in include.groups %}
    <div class="sidebar__group"{% if g.label %} role="group" aria-labelledby="{{ sid }}-g{{ forloop.index }}"{% endif %}>
      {%- if g.label %}
      <p class="sidebar__label" id="{{ sid }}-g{{ forloop.index }}">{{ g.label }}</p>
      {%- endif %}
      <ul class="sidebar__list">
        {%- for it in g.items %}
        {%- assign current = false -%}
        {%- if page.url == it.href %}{% assign current = true %}{% endif %}
        <li><a class="sidebar__link{% if current %} is-active{% endif %}" href="{{ it.href | relative_url }}"{% if current %} aria-current="page"{% endif %}>
          <span class="sidebar__icon" aria-hidden="true">{{ it.icon | default: '•' }}</span><span class="sidebar__text">{{ it.text }}</span>{% if it.badge %}<span class="sidebar__badge">{{ it.badge }}</span>{% endif %}
        </a></li>
        {%- endfor %}
      </ul>
    </div>
    {%- endfor %}
  </nav>
</aside>
<div class="sidebar__backdrop" data-ui-sidebar-close></div>

Макрос для Jinja

{#- Боковая панель кабинета с каркасом. groups — список групп: label (подпись, можно пустую) и items;
    пункт: text, href, icon, badge, children (вложенные пункты: text, href). active — href текущей страницы.
    key — ключ, под которым запоминается свёрнутое состояние. Содержимое страницы передаётся через caller(). -#}
{% macro sidebar(groups, active=None, key='cabinet', title='Кабинет', id='sidebar') -%}
<div class="sidebar-layout">
  <aside class="sidebar" id="{{ id }}" data-ui-sidebar="{{ key }}" aria-label="{{ title }}">
    <div class="sidebar__head">
      <span class="sidebar__title">{{ title }}</span>
      <button class="sidebar__collapse" type="button" data-ui-sidebar-collapse aria-expanded="true" aria-label="Свернуть панель">«</button>
      <button class="sidebar__close" type="button" data-ui-sidebar-close aria-label="Закрыть панель">×</button>
    </div>
    <nav class="sidebar__nav" aria-label="Разделы">
      {%- for g in groups %}
      <div class="sidebar__group"{% if g.label %} role="group" aria-labelledby="{{ id }}-g{{ loop.index }}"{% endif %}>
        {%- if g.label %}
        <p class="sidebar__label" id="{{ id }}-g{{ loop.index }}">{{ g.label }}</p>
        {%- endif %}
        <ul class="sidebar__list">
          {%- for it in g['items'] %}
          <li>
            {%- if it.children %}
            {%- set open = (active == it.href) or (it.children | selectattr('href', 'equalto', active) | list | length > 0) %}
            <button class="sidebar__link sidebar__toggle" type="button" aria-expanded="{{ 'true' if open else 'false' }}" aria-controls="{{ id }}-n{{ loop.index }}">
              <span class="sidebar__icon" aria-hidden="true">{{ it.icon or '•' }}</span><span class="sidebar__text">{{ it.text }}</span><span class="sidebar__caret" aria-hidden="true">↓</span>
            </button>
            <ul class="sidebar__list sidebar__list--nested" id="{{ id }}-n{{ loop.index }}">
              {%- for c in it.children %}
              <li><a class="sidebar__link{% if c.href == active %} is-active{% endif %}" href="{{ c.href }}"{% if c.href == active %} aria-current="page"{% endif %}><span class="sidebar__text">{{ c.text }}</span></a></li>
              {%- endfor %}
            </ul>
            {%- else %}
            <a class="sidebar__link{% if it.href == active %} is-active{% endif %}" href="{{ it.href }}"{% if it.href == active %} aria-current="page"{% endif %}>
              <span class="sidebar__icon" aria-hidden="true">{{ it.icon or '•' }}</span><span class="sidebar__text">{{ it.text }}</span>{% if it.badge %}<span class="sidebar__badge">{{ it.badge }}</span>{% endif %}
            </a>
            {%- endif %}
          </li>
          {%- endfor %}
        </ul>
      </div>
      {%- endfor %}
    </nav>
  </aside>
  <div class="sidebar__backdrop" data-ui-sidebar-close></div>
  <div class="sidebar-layout__main">
    <button class="sidebar-layout__open" type="button" data-ui-sidebar-open="#{{ id }}" aria-expanded="false" aria-controls="{{ id }}"><span aria-hidden="true">☰</span> Разделы</button>
    {{ caller() if caller else '' }}
  </div>
</div>
{%- endmacro %}