侧边导航 · SideNav
侧边导航用于导航场景。下面的官方示例展示原生用法与状态,属性名保持上游 API。
安装与前置条件
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。
示例与使用方式
- 侧边导航 · 综合展示 1:首先体验这个示例,再查看代码理解组件的组合方式。
- 侧边导航 · 综合展示 2:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 综合展示 3:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 综合展示 4:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 综合展示 5:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 基础用法 6:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 交互示例 7:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 基础用法 8:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 基础用法 9:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 交互示例 10:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 基础用法 11:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 侧边导航 · 交互示例 12:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
API 与上游详细参考
优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。
Side Nav
A sidebar navigation component for organizing application pages with sections, nested items, and icons. Use SideNav as the primary navigation when an app has 5 or more destinations or requires hierarchical grouping.
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| header | ReactNode | Header area (typically SideNavHeading). Sticky. | |
| topContent | ReactNode | Content below the header, e.g., a create button. | |
| children | ReactNode | Navigation sections and items. Scrollable. | |
| footer | ReactNode | Footer area above the icon bar. | |
| footerIcons | ReactNode | Footer icon bar. The row cascades a 'sm' size to the interactive children it contains, so its icons and the built-in collapse button come out one height; pass an explicit size on a child to opt out. | |
| collapsible | boolean | { defaultIsCollapsed?: boolean; isCollapsed?: boolean; onCollapsedChange?: (isCollapsed: boolean) => void; hasButton?: boolean; buttonLabel?: string } | false | Enables collapse behavior. true for uncontrolled with default toggle button, or an object for controlled mode and advanced config (defaultIsCollapsed, isCollapsed + onCollapsedChange, hasButton, buttonLabel). A controlled config can also be passed to a SideNavCollapseButton rendered outside this SideNav, so both share one state. |
| resizable | boolean | { defaultWidth?: number; minWidth?: number; maxWidth?: number; autoSaveId?: string; onWidthChange?: (width: number) => void; defaultIsCollapsed?: boolean; isCollapsed?: boolean; onCollapseChange?: (isCollapsed: boolean) => void } | false | Enables a resize handle at the inline-end edge. true for defaults (260px initial, 180-480px range), or a ResizableConfig object (defaultWidth, minWidth, maxWidth, autoSaveId for localStorage persistence of width and collapse state, onWidthChange). It can also own collapse state (defaultIsCollapsed, isCollapsed + onCollapseChange); when both props carry collapse state, resizable wins and a dev warning names the conflicting keys. The handle is hidden while collapsed. |
| handleRef | Ref<SideNavImperativeCollapseHandle> | Deprecated. Imperative collapse handle for SideNavCollapseButton instances rendered outside this SideNav; hand both the same controlled collapsible config instead. Separate from ref, which continues to expose the root HTMLElement. | |
| xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |
使用建议
- Use sections to group related navigation items and help users scan for their destination.
- Pair outline and filled icon variants so the selected state is visually distinct.
- Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.
- SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they name icon-only items unless a meaningful aria-label supplies more context.
- While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.
- 避免:Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.
- 避免:Use for filtering content; use tabs or filter buttons instead.
主题 API
{
"targets": [
{
"className": "astryx-side-nav",
"visualProps": [
"mode"
]
},
{
"className": "astryx-side-nav-heading"
},
{
"className": "astryx-side-nav-item",
"visualProps": [
"size"
],
"states": [
"selected",
"disabled"
]
},
{
"className": "astryx-side-nav-section"
}
]
}
SideNavHeading
SideNavItem
SideNavSection
SideNavCollapseButton
组件结构
- Product icon and name: Branding area at the top of the nav.
- Navigation items: Sections and groups of navigable links.
- Collapse/expand toggle: Toggle to collapse or expand the side nav.
Side Nav Collapse Button
侧边栏折叠切换按钮。放置在 SideNav 内部(自动读取上下文)或外部(向两者传入同一个受控 collapsible 配置)。默认渲染为仅图标的 ghost 按钮。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| collapsible | {isCollapsed: boolean, onCollapsedChange: (isCollapsed: boolean) => void} | 与 SideNav 相同的受控 collapsible 配置。仅在按钮渲染在侧边栏外部、无法读取折叠上下文时需要。 | |
| handleRef | RefObject<SideNavImperativeCollapseHandle | null> | 已废弃。来自 SideNav 的命令式折叠句柄;请改用 collapsible。 | |
| label | string | 自定义按钮标签。提供时渲染为带箭头的文本按钮。省略时渲染为仅图标按钮。 | |
| size | 'sm' | 'md' | 'lg' | 按钮尺寸。默认使用容器级联的尺寸(SideNav 页脚内为 'sm'),无容器时为 'md'。当按钮位于已设定尺寸的容器之外且需要与相邻元素保持一致时显式设置。 | |
| children | ReactNode | 自定义按钮内容。覆盖默认的箭头图标和标签。 |
Side Nav Heading
产品/套件/账户头部,具有智能交互边界逻辑,支持链接和菜单弹出框。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| heading * | string | 产品/应用名称。 | |
| icon | ReactNode | 产品/应用图标。 | |
| headingHref | string | 标题的链接。 | |
| superheading | string | 标题上方的文本。 | |
| superheadingHref | string | 上方标题的链接。 | |
| subheading | string | 标题下方的文本。 | |
| subheadingHref | string | 下方标题的链接。 | |
| menu | ReactNode | 在弹出框内渲染的菜单内容。 | |
| headerEndContent | ReactNode | 在标题行尾部渲染的内容,位于文本和箭头之间。适用于徽章、状态指示器或紧凑操作按钮。折叠时隐藏。 |
Side Nav Item
导航项,支持图标、选中状态、可选尾部内容,以及通过 children 实现嵌套。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label * | string | 项目标签。 | |
| as | LinkComponentType | 自定义链接组件。 | |
| icon | IconType | 轮廓(未选中)变体中显示的图标。 | |
| selectedIcon | IconType | 选中时显示的图标(填充变体)。 | |
| isSelected | boolean | false | 将此项标记为当前页面。 |
| isDisabled | boolean | false | 禁用状态。 |
| href | string | 导航 URL。 | |
| onClick | (e: MouseEvent) => void | 点击处理函数。 | |
| endContent | ReactNode | 仅用于被动右侧内容(徽章、计数)。交互控件请使用 actions。 | |
| actions | ReactNode | 行级次要控件(图标按钮、菜单),作为主元素的同级节点渲染在行尾——位于展开/折叠切换按钮之后、任何嵌套子项之前(DOM 与焦点顺序一致)。每个控件自行负责其无障碍名称与行为。控件通过 SizeContext 继承行内控件尺寸,因此未指定尺寸的图标按钮会与内置的展开/折叠切换按钮保持同一尺寸;显式指定的 size 优先。侧边栏折叠为图标栏时隐藏。被动内容(徽章、计数)请使用 endContent;交互内容请使用 actions。 | |
| children | ReactNode | 用于嵌套的子项。 | |
| collapsible | boolean | { defaultIsCollapsed?: boolean, isCollapsed?: boolean, onCollapsedChange?: (isCollapsed: boolean) => void } | false | 启用带子项的折叠行为。传 true 为非受控模式(默认展开),或传对象用于受控模式。 |
| size | 'sm' | 'md' | 'lg' | 'md' | 导航项的尺寸变体。 |
Side Nav Section
分组,支持可选的标题、副标题和尾部内容。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| title * | string | 分组标题。 | |
| subtitle | string | 分组副标题。 | |
| children | ReactNode | 分组项目。 | |
| endContent | ReactNode | 分组头部的右侧内容。 | |
| isHeaderHidden | boolean | false | 视觉上隐藏分组头部,同时保持屏幕阅读器可访问。 |
| xstyle | StyleXStyles | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |