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

Боковая панель занимает всю высоту и прижата к одной стороне. Как и modal(), это popover: кнопка с соответствующим popovertarget открывает её, а браузер берёт на себя затемнение, клик снаружи и Escape.

На статическом сайте её самая частая работа — меню навигации на телефоне.

Простая панель

fragment(
  button({ popovertarget: 'drawer-basic' }, 'Открыть панель'),
  drawer({ id: 'drawer-basic', title: 'Настройки' },
    stack({ gap: 'md' },
      toggle({ label: 'Поиск Pagefind', checked: true }),
      toggle({ label: 'Оптимизация изображений', checked: true }),
      toggle({ label: 'Серверные острова' }),
    ),
  ),
)

Стороны

fragment(
  stack({ direction: 'row', gap: 'sm' },
    button({ variant: 'outline', color: 'neutral', popovertarget: 'drawer-start' }, 'От начала'),
    button({ variant: 'outline', color: 'neutral', popovertarget: 'drawer-end' }, 'От конца'),
  ),
  drawer({ id: 'drawer-start', side: 'start', title: 'Начало' },
    text({ variant: 'small', tone: 'muted' }, 'Прижата к начальному краю — левому в языке, который читают слева направо.'),
  ),
  drawer({ id: 'drawer-end', title: 'Конец' },
    text({ variant: 'small', tone: 'muted' }, 'Вариант по умолчанию: прижата к конечному краю.'),
  ),
)

Ширина

Любая CSS-длина. Она ограничена 90 % ширины окна, поэтому широкая панель всё равно помещается на телефоне.

fragment(
  stack({ direction: 'row', gap: 'sm' },
    button({ variant: 'outline', color: 'neutral', popovertarget: 'drawer-narrow' }, 'Узкая'),
    button({ variant: 'outline', color: 'neutral', popovertarget: 'drawer-wide' }, 'Широкая'),
  ),
  drawer({ id: 'drawer-narrow', width: '14rem', title: 'Узкая' },
    text({ variant: 'small', tone: 'muted' }, 'width: 14rem'),
  ),
  drawer({ id: 'drawer-wide', width: '34rem', title: 'Широкая' },
    text({ variant: 'small', tone: 'muted' }, 'width: 34rem'),
  ),
)

Как меню навигации

Приём, которого хочет большинство сайтов: кнопка меню в панели, ссылки — в боковой панели.

fragment(
  appBar({ brand: 'sitelo' },
    appBarSpacer(),
    appBarActions(
      iconButton({
        label: 'Открыть навигацию',
        variant: 'ghost',
        color: 'neutral',
        popovertarget: 'drawer-nav',
        icon: icon('menu'),
      }),
    ),
  ),
  drawer({ id: 'drawer-nav', title: 'Навигация' },
    navLink({ href: '#docs', current: true }, 'Документация'),
    navLink({ href: '#ui' }, 'UI'),
    navLink({ href: '#examples' }, 'Примеры'),
    navLink({ href: '#about' }, 'О проекте'),
    divider({ spacing: 'sm' }),
    button({ block: true }, 'Начать'),
  ),
)

Панель фильтров

fragment(
  button({ variant: 'soft', color: 'neutral', popovertarget: 'drawer-filters' }, 'Фильтры'),
  drawer({ id: 'drawer-filters', title: 'Фильтры', width: '22rem' },
    stack({ gap: 'lg' },
      choiceGroup({
        legend: 'Тип',
        name: 'drawer-type',
        value: 'guide',
        options: [
          { value: 'guide', label: 'Руководства' },
          { value: 'example', label: 'Примеры' },
          { value: 'all', label: 'Всё' },
        ],
      }),
      choiceGroup({
        legend: 'Теги',
        name: 'drawer-tags',
        type: 'checkbox',
        value: ['routing'],
        options: ['routing', 'data', 'islands'],
      }),
      stack({ direction: 'row', gap: 'sm' },
        button({ variant: 'ghost', color: 'neutral', popovertarget: 'drawer-filters', popovertargetaction: 'hide' }, 'Отмена'),
        button('Применить'),
      ),
    ),
  ),
)

Пропсы

ПропТипПо умолчаниюОписание
idstring—Обязателен. То, на что указывает popovertarget кнопки-триггера.
titleChild—Заголовок и доступное имя диалога.
side'start' | 'end''end'К какому краю она прижата.
widthstring'20rem'Ширина панели, ограниченная 90vw.
closablebooleantrueПоказывать × в шапке.
closeLabelstring'Close'Доступное имя этой кнопки.