Sidebar 使用手册
v1.9.5 · @snowui-design-system/components
许可阅读:首次阅读组件文档、源码或 npm 使用流程,先读完整 LICENSE;同任务同版本去重。公开 API 配置与内部实现修改分别按许可处理;全部组件使用统一运行包,源码权益以许可为准。
组件介绍
组织应用的品牌入口、分组导航与底部操作,支持折叠和独立滚动,适合多页面应用。
使用选择
用于应用左侧分组导航,组合 SidebarSection 与 SidebarItem。页面负责路由和内容;公开 logo / footer 角色可替换内置内容,普通右侧信息列不使用 Sidebar。
sections 提供导航数据;children 与 sections 同时渲染,并非替换关系。
直属 as="logo" 替换标识,as="footer" 进入固定底部;宽度和折叠状态可绑定,默认启用持久化。
导航及滚动区默认名称、内置折叠按钮(含text浮层展开按钮)随LocaleProvider更新;显式ariaLabel优先于Provider消息。
快速开始
以下示例展示推荐的基本组合。更多场景与组合限制见后文。
API
未重新声明的继承能力请查所属基础组件文档;本表只列本组件源码具名公开属性。
使用边界与详细说明
API 参考
默认 Logo 的 host 为 as="logo",内部以 SnowUILogo as="logo-icon" variant="icon" 与 SnowUILogo as="logo-wordmark" variant="text" 明确区分图形和字标。直接子节点 as="logo" 会被安置到 Header 并完整替换默认 Logo;自定义 Logo 同样必须用它的直接子节点 as="logo-icon" 标记折叠后保留的图形,其余直接子节点视为展开态文字或字标并在折叠时隐藏。直接子节点 as="footer" 会被安置到底部覆盖 Footer。它们不抑制 sections 生成的 Body 内容,其余显式子节点会与 sections 依次渲染在 Body。第三方内容不支持 as 时,用对应角色的 Frame 包裹。Sidebar 根输出 data-collapsed,并提供 Sidebar Context。
布局与行为
展开默认宽度
220px,有图标模式折叠宽度60px,text 模式折叠宽度0px,高度100%。resizable={true}时,右侧边框全高均可在默认160px~480px范围内拖拽调整展开宽度,并通过width/bind:width与onWidthChange对外同步;边缘显示 Indicator 默认宽度调整指示器。设为false时不渲染整边调宽命中层。折叠与展开以 Sidebar 根宽度为主时间轴:展开宽度 → 折叠宽度(icon 为 60px,text 为 0px)使用
SIDE_PANEL_DISAPPEAR_MOTION的临界阻尼 spring timing,折叠宽度 → 上次展开宽度使用SIDE_PANEL_APPEAR_MOTION的同系 timing;该 timing 复用 Frame 默认 move spring。拖拽期间临时关闭宽度 transition,使边缘与指针同步;enableDefaultMotion={false}与系统 reduced motion 均关闭该过渡。右侧整边调宽命中层仅在
resizable={true}且展开态存在,沿 Sidebar 右侧边框全高铺开,渲染 Indicator 默认短条。命中层与 Sidebar 的可见 overlay scrollbar Thumb 重叠时遵守 Indicator 的 Resize 优先规则,滚动条未被覆盖的区域继续响应。折叠不会覆盖已调整的展开宽度,再次展开时恢复该宽度。根容器默认 padding 为左右
12px(var(--padding-3))、上下16px(var(--padding-4));这是 Sidebar 组件默认值,不由使用方重复补 class 或 style。Header 与 Footer 均为非滚动区;Footer 全宽贴底,
ScrollArea独立滚动并延伸至底部,在 Footer 区域内按设计渐隐。Sidebar 根的 Header / Body 默认 gap 为var(--gap-3)(12px),即 Logo 区域与下方导航区域之间的默认间距;它与 Body 内相邻导航内容的 4px gap 是两个独立层级。Body 纵向 overlay scrollbar 根据根横向 padding 自动外移,轨道右边缘始终距 Sidebar 右边框
4px;默认 12px 横向 padding 时其right偏移为-8px。Logo 所在 Header 区域使用
4px上下 padding;滚动视口延伸到 Logo 区域背后,并以 Header 实测高度、顶部 padding 和 Header/Body gap 组成的固定区高度实现反向渐隐:从下往上进入区域 20% 时保留 20% 可见度,到 40% 时完全消失。Logo 本身不参与遮罩,列表顶部保留对应空间。Body 导航内容默认使用
var(--gap-1)(4px)间距,直接组合的 SidebarItem 与 SidebarSection 内部列表保持一致。SidebarItemData.depth={1}与显式SidebarItem depth={1}使用同一二级导航视觉:组件在 leading 槽绘制等长双臂、1px Black/40% 密集点线、4px 圆角的 L 形层级连接线,并以该连接线替换普通 Icon。竖线中心与一级 Item Icon 中心同列,横线中心与二级文字中心同轴。Sidebar 内所有横向 Separator 使用同一默认样式,不区分 SidebarSection 自动生成或调用方显式组合:上下与左右 padding 均为
8px(var(--padding-2))、line-height: 0、分割线本体保持 Separator 默认0.5px与 Black/10%。节点自身使用 content-box 背景裁切表达 padding,不要求外部 wrapper 或 class;横向与纵向 padding 分别通过--snowui-sidebar-separator-padding-x-override、--snowui-sidebar-separator-padding-y-override覆盖。每个 SidebarSection 的分类内容末尾内置该 Separator,调用方无需为分类手动补分割线。状态记忆默认开启,未传
persistenceKey时使用snowui:sidebar:default保存 active item 与各 Section 的折叠状态。刷新后自动恢复标题展开 / 折叠状态与最后 active item;恢复时若当前 active item 位于已折叠 Section,Sidebar 强制展开该 Section,并将修正后的展开状态重新保存。外部传入的activeItemId优先于旧存储记录;可见的无分类 active item 不得继承旧分类 ID 并误展开该分类。同一 origin 存在多个 Sidebar 时,宿主必须提供稳定且唯一的persistenceKey;不需要状态记忆时显式设置persistence={false}。恢复 active item 后,仅当 Body 确实存在纵向溢出时才定位:以“active item 中心 = Body 实际可视区域中心”为目标,首尾位置按可滚动边界夹紧。恢复后立即定位一次,并在默认 Section 布局动效结束后再次校正,避免折叠布局变化造成偏移。
active 视觉状态由 Sidebar 管理;宿主仍通过
activeItemId/onActiveItemChange持有实际导航与内容切换。恢复合法的持久化 active item 时,Sidebar 会调用onActiveItemChange通知宿主。默认与自定义
as="logo"host 均使用4px左右 padding,使 Logo 图形与 SidebarItem 图标垂直对齐。Header 在展开 / 折叠状态使用同一套起始对齐结构,Logo Icon 保持固定 leading slot;Test 示例以固定宽度左对齐宿主承载 Sidebar,避免居中宿主在根宽度变化时带动整个 Logo 位移。Logo host 强制保持单行,wordmark 通过 host 裁切与透明度收起,不会在窄宽度下换行并撑高 Logo,也不在动效起点直接切换整体 Header 对齐。
折叠按钮是内置默认样式
<Button iconOnly size="sm">,与 Logo 位于同一 Header 水平线上,并始终位于 Logo host 分配区域的右边。透明命中 host 使用--size-6并由 Header flex 安置;展开态增加var(--padding-1)(4px)右侧 margin,使按钮相对原位置左移 4px,折叠态不增加该间距。ResourceSize16 图标在 host 内居中;展开态图标不得越过 Header 与导航项共用的内容右边界,在 16px 名义根字号下与该边界保持8px间距。不得再用额外 transform 或非 Token 偏移改变此位置。Logo host 填充按钮之前的剩余 Header 宽度,只设置稳定的 36px 最小 leading slot;按钮会跟随 Sidebar 宽度以 Frame 默认 move spring 从 Logo 区域右侧平移到折叠位置,不发生瞬移。按钮外层保留同尺寸透明命中 host,因此鼠标进入 Sidebar,或直接进入按钮应出现的位置(包括折叠态超出根视觉边界的部分)时都能显示按钮。默认navigationVariant="icon"时按上述 hover / focus-within 规则显形;navigationVariant="text"的折叠态隐藏 Logo、Body 和 Footer,根宽度、padding 与 gap 收到零;展开按钮脱离根布局,挂载到 body 并在支持时进入浏览器 top layer,保持可见、可点击。按钮命中盒距当前可视区域左边 var(--padding-3)(名义 12px),上边 var(--padding-4)(名义 16px);采用 fixed 定位保证页面滚动不改变边距。旧浏览器回退为 body 浮层。按钮保留原有图形与尺寸;Header 与顶层按钮交接时从当前可见位置连续移动,复用侧栏展开/收起的 spring timing,快速反向操作从当前动画位置接续;reduced motion 或 enableDefaultMotion={false} 时直接定位;键盘操作后焦点在内置按钮与浮层按钮间恢复,隐藏侧栏 inert 且 aria-hidden。折叠开始时,Sidebar 宽度、Item 文字与 Section 标题同时开始变化:宽度收窄,Item 文字和标题消费 Frame color bridge 渐隐;Item leading Icon 保持原横向位置。标题透明度归零后,标题高度、padding 与 Section gap 才消费 Frame size bridge 收起,Item 随后上移。展开时按同一组 bridge 平滑恢复。
折叠按钮不内置 Tooltip,通过随状态更新的
aria-label保留“展开 / 折叠侧边栏”可访问名称。其余内置 Tooltip(折叠态 Item label、Item action、Section action)统一位于对应元素右侧(position="right")。Section 标题默认可折叠但不显示 Tooltip。默认不设置背景色。
Footer 只内置底部覆盖区域,不内置业务文案;区域默认使用 Figma Auto Layout 的 Align top left:内容整体位于容器左上方,内部横向排列并在同一水平线上垂直居中,内容 gap 为
8px;显式singleLine的Footer内容组合保留至少4 CSS px横向间距,较大现有覆盖保持;普通Footer间距不改。区域全宽贴底,内边距上12px、下16px、左右20px。区域无圆角,不绘制背景色,也不使用背景模糊,避免覆盖宿主边框及拖宽时的模糊重绘。直接子节点as="footer"提供业务内容。折叠 / 展开期间 Footer 固定使用展开态内容宽度与底部位置,不跟随根宽度收缩或位移,只使用与 Sidebar 宽度时间轴一致的 opacity 渐隐 / 渐显;折叠态通过inert、aria-hidden与pointer-events: none退出交互。存在 Footer 时,Sidebar 通过共享
resizeManager跟踪 Footer 实际高度;滚动内容延伸至 Sidebar 底部,使用 alpha 遮罩还原 Footer 覆盖渐变:Footer 顶部内容保留 100%,向下 20% 高度时保留 20%,到 40% 时完全不可见。Footer 自身内容不参与遮罩,深浅主题均不需要叠加背景色。导航尾部保留 Footer 高度 + 12px 安全区,保证滚到底时最后一项完整位于 Footer 上方。高度由声明式样式维护,拖宽时不中断;Logo 区域使用同一曲线的垂直镜像。
连续 Hover
continuousHover 默认 true。导航容器拥有唯一背景层,在所有可用 SidebarItem(包括 Section 内项目)之间连续移动。active 项的持久背景不被替换, hover 到 active 项时两个背景叠加形成更深颜色。Section 标题属于明确阻断区域: pointer 位于标题时共享层隐藏,不把标题当作相邻 Item 间隙。设为 false 恢复逐项 hover。
Sidebar 样式覆盖
先阅读 完整 LICENSE;同任务、同版本、同范围去重。
优先用组件公开 Props 匹配合适样式,尽可能保留原有视觉。确需改写时按 样式选择与改写顺序 使用自己的 class(含项目已有 Tailwind)或实例 style。以下名称来自源码实际消费的公开 override;先核对目标作用域,不修改私有 DOM。采用 SnowUI Token 时选择正确类别,外部应用不被要求安装一方 utilities。
Sidebar 类型与状态
必填属性:无具名必填属性。
可双向绑定:bind:collapsed、bind:width。
继承声明:Omit<FrameProps, "children" | "width">。继承能力以基类公开文档为准;Omit 中的字段已排除,不能按基类原样使用。
以下为公开属性实际引用的类型声明,来自源码;Svelte Snippet 表示内容片段,ComponentProps 表示对应组件的 Props。
SidebarSectionData
来源:components/src/blocks/Sidebar.svelte
SidebarActionData
来源:components/src/blocks/sidebar-context.svelte.ts
SidebarItemData
来源:components/src/blocks/sidebar-context.svelte.ts
ComponentPartsOf
来源:components/src/logic/component-parts.svelte.ts
ConfigurableComponentPartProps
来源:components/src/logic/component-parts.svelte.ts
ComponentPartControlledKey
来源:components/src/logic/component-parts.svelte.ts