抽屉

抽屉是贴在某一侧、占满高度的面板。和 modal() 一样,它是一个 popover:带有对应 popovertarget 的按钮打开它,遮罩、点击外部关闭和 Esc 都由浏览器负责。

在静态站点上,它最常见的活儿是手机上的导航菜单。

基础抽屉

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'),
  ),
)

作为导航菜单

多数站点想要的那种做法:栏里放一个菜单按钮,链接放进抽屉。

sitelo
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'该按钮的无障碍名称。