侧边栏
侧边栏由你自己写:遍历文档树,用 Sidebar 组件渲染每一项。结构、顺序和每一项的样子都在你的代码里。
完整的例子
---
import { Sidebar } from '@minidocs/astro/components';
import { navState } from '@minidocs/astro/runtime';
import { tree } from '../lib/docs';
const { id } = Astro.props;
const nav = navState(tree, id);
---
<Sidebar.Root id="sidebar" label="文档">
<Sidebar.List>
{tree.map(function item(node) {
return (
<Sidebar.Item>
{node.children.length > 0 ? (
<Sidebar.Group {...nav.of(node)}>
<Fragment slot="label">{node.label}</Fragment>
<Sidebar.List>{node.children.map(item)}</Sidebar.List>
</Sidebar.Group>
) : (
<Sidebar.Link {...nav.of(node)}>{node.label}</Sidebar.Link>
)}
</Sidebar.Item>
);
})}
</Sidebar.List>
</Sidebar.Root>
tree.map 的回调起了名字 item,遇到有子节点的分组时,用 node.children.map(item) 渲染下一层,所以树有多少层都能渲染出来。多语言站点把 tree 换成 tree[locale]。
nav.of(node)
navState(tree, id) 记下当前页面在树里的位置,nav.of(node) 返回渲染一个节点要用的值:
| 字段 | 含义 |
|---|---|
href |
页面或外部链接的地址,分组没有 |
current |
这个节点是不是当前页面 |
open |
当前页面是不是这个节点本身或在它下面 |
这些字段和组件的参数同名,所以可以直接展开。也可以改写其中的值,比如让某个分组始终展开:
<Sidebar.Group {...nav.of(node)} open>
每个组件的参数见组件与样式。
分组的几种样子
小标题
第一层的分组常常只是一个小标题,下面直接列出页面,不能折叠。用 Sidebar.Label 加 Sidebar.List。下面的写法在第一层用小标题,更深的层级用可折叠的分组:
{tree.map(function item(node) {
return (
<Sidebar.Item>
{node.children.length === 0 ? (
<Sidebar.Link {...nav.of(node)}>{node.label}</Sidebar.Link>
) : tree.includes(node) ? (
<>
<Sidebar.Label>{node.label}</Sidebar.Label>
<Sidebar.List>{node.children.map(item)}</Sidebar.List>
</>
) : (
<Sidebar.Group {...nav.of(node)}>
<Fragment slot="label">{node.label}</Fragment>
<Sidebar.List>{node.children.map(item)}</Sidebar.List>
</Sidebar.Group>
)}
</Sidebar.Item>
);
})}
可折叠的分组
Sidebar.Group 渲染成可以折叠的分组,点击标题展开或收起,上面的完整例子用的就是它。分组的标题写在 label slot 里。
手风琴
给同一层的分组传相同的 name,展开一个时其他的会自动收起。有自己页面的分组不参与:
<Sidebar.Group {...nav.of(node)} name="sections">
有自己页面的分组
用 page(id, children) 定义的分组本身也是一个页面,nav.of(node) 会给它 href。它的标题在不同页面上表现不同:
| 当前页面 | 点击标题 |
|---|---|
| 其他页面 | 跳转到分组的页面,并展开 |
| 分组下面的页面 | 跳转到分组的页面 |
| 分组自己的页面 | 收起或展开 |
跨页面保持状态
从一个页面跳到另一个页面时,侧边栏会保持原来的样子:展开的分组和滚动位置都不变。当前页面所在的分组总是展开的,这样你总能在侧边栏里看到自己在哪。
窄屏下的菜单
Sidebar.Trigger 是打开和关闭侧边栏的按钮,target 是侧边栏的 id:
<Sidebar.Trigger target="sidebar" aria-label="菜单">☰</Sidebar.Trigger>
<Sidebar.Root id="sidebar" label="文档">...</Sidebar.Root>
侧边栏放在 Layout.Sidebar 里时,默认样式在窄屏下把它变成从左侧滑出的抽屉,按 Esc 或点击外面会关闭,见页面布局。