Sidebar
基础导航基于 Bootstrap 5 的侧边栏组件,用于构建应用侧边导航:通过 SidebarHeader/SidebarBody/SidebarFooter 组织区域,SidebarGroup 分组导航项,导航项支持图标、徽标、激活与禁用状态;支持收起为图标模式、视口低于断点时自动切换为带遮罩的响应式抽屉(点击遮罩或 Esc 关闭)、明暗主题与左右停靠,并可通过 SidebarProvider/useSidebar 将状态提升实现受控组合
Component Demo
Basic usage and examples of the Sidebar component
基础示例
Sidebar 组合 Header/Body/Footer 三个区域,导航内容通过 SidebarGroup 分组,链接与按钮导航项支持 `icon`、`badge` 与 `active` 状态
无图标导航项
`icon` 为可选属性:未传图标的导航项不预留图标位、文字紧贴左侧;示例第一组为纯文字导航, 第二组为带图标导航
无图标收起展开
未传入 `icon` 时,收起为图标模式后自动以内容首字作为图标(如「仪」「订」「消」), 展开时首字淡出、完整文字淡入;点击触发器可观察收起与展开的过渡
收起为图标模式
点击 SidebarTrigger 在展开与图标模式之间切换,收起后仅保留图标,分组标题与文字标签自动隐藏
深色主题与右侧停靠
`variant="dark"` 在根元素上设置 `data-bs-theme="dark"`,所有 Bootstrap 变量自动适配; `placement="end"` 将侧边栏停靠到右侧
响应式抽屉
视口宽度低于 `breakpoint` 时切换为固定定位抽屉:带遮罩与滑动动画,支持点击遮罩、Esc 键关闭;将浏览器窗口缩窄到 992px 以下即可观察抽屉效果
Provider 与受控模式
SidebarProvider 将状态提升到侧边栏之外,SidebarTrigger 可以放在任意位置控制侧边栏;通过 `collapsed`/`onCollapsedChange` 实现受控收起,移动端抽屉对应 `open`/`onOpenChange`
交互与状态
`active` 切换高亮导航项,`badge` 展示未读数量,`disabled` 禁用不可用的导航项
自定义插槽
Header/Body/Footer 插槽接受任意内容,可自由组合搜索框、进度条、版本信息等
API Documentation
Complete API reference for the Sidebar component
Props
Sidebar
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'aside' | 渲染的根元素类型 |
breakpoint | SidebarBreakpoint | null | 'md' | 响应式断点:视口宽度低于该断点时切换为抽屉模式(固定定位 + 遮罩 + 滑动动画);传入 `null` 始终内联展示 |
collapsed | boolean | - | 受控的收起(图标模式)状态;提供后点击触发器不会自动更新,仅触发 onCollapsedChange 回调 |
collapsedWidth | number | string | 60 | 收起态宽度,数字按像素处理,也可传入任意 CSS 长度 |
collapseOnSelect | boolean | true | 移动端抽屉模式下点击任意导航项后自动关闭抽屉 |
defaultCollapsed | boolean | false | 非受控模式下的初始收起状态 |
defaultOpen | boolean | false | 非受控模式下的初始移动端抽屉打开状态 |
onCollapsedChange | (collapsed: boolean) => void | - | 收起状态变化回调,参数为新的收起状态 |
onItemSelect | () => void | - | 点击任意导航项(SidebarItem/SidebarLink/SidebarButton)后的回调 |
onOpenChange | (open: boolean) => void | - | 移动端抽屉打开状态变化回调,参数为新的打开状态 |
open | boolean | - | 受控的移动端抽屉打开状态;提供后仅触发 onOpenChange 回调 |
placement | SidebarPlacement | 'start' | 侧边栏停靠位置,`start` 左侧、`end` 右侧 |
variant | SidebarVariant | 'light' | 明暗主题,`dark` 会同时在根元素上设置 `data-bs-theme="dark"` |
width | number | string | 256 | 展开态宽度,数字按像素处理,也可传入任意 CSS 长度 |
SidebarProvider
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | ReactNode | - | 需要被上下文中的 Sidebar、SidebarTrigger、SidebarBackdrop 等消费的子内容 |
...stateProps | SidebarStateProps | - | 与 Sidebar 相同的受控/非受控状态属性(breakpoint、collapsed、open 等),由 Provider 统一持有并共享给其子树中的所有 Sidebar 部件 |
SidebarTrigger
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'button' | 渲染的根元素类型 |
children | ReactNode | - | 触发器上的文字标签,侧边栏收起为图标模式时自动隐藏 |
onClick | (event: MouseEvent) => void | - | 点击回调;移动端切换抽屉开合,桌面端切换收起状态。未传入 aria-label 时根据当前状态自动生成无障碍标签 |
SidebarHeader
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'header' | 渲染的根元素类型 |
children | ReactNode | - | 顶部区域内容,如品牌标识、SidebarTrigger、搜索框 |
SidebarBody
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'div' | 渲染的根元素类型 |
children | ReactNode | - | 中间可滚动区域内容,通常放置 SidebarGroup 导航分组 |
SidebarFooter
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'footer' | 渲染的根元素类型 |
children | ReactNode | - | 底部区域内容,如用户信息、版本号 |
SidebarGroup
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'div' | 导航分组容器渲染的根元素类型 |
children | ReactNode | - | 分组内容,通常由 SidebarGroupLabel 与 SidebarGroupContent 组成 |
SidebarGroupLabel
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'div' | 分组标题渲染的根元素类型 |
children | ReactNode | - | 分组标题文本,侧边栏收起为图标模式时自动隐藏 |
SidebarGroupContent
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
as | ElementType | 'div' | 分组内容容器渲染的根元素类型 |
children | ReactNode | - | 分组内的导航项列表(SidebarItem/SidebarLink/SidebarButton) |
SidebarItem
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
active | boolean | false | 是否处于激活状态,激活项渲染高亮背景并设置 aria-current="page" |
badge | ReactNode | - | 导航项右侧的徽标内容,如 `<span className="badge text-bg-primary">12</span>` |
children | ReactNode | - | 导航项文字内容,通常为字符串或带样式文本 |
disabled | boolean | false | 是否禁用,禁用项不可点击并降低透明度 |
href | string | - | 链接地址;传入时渲染 `<a>` 元素,否则渲染 `<button>` 元素 |
icon | ReactNode | - | 导航项左侧图标(可选);未传入时不预留图标位、文字紧贴左侧,收起为图标模式时以内容首字作为图标 |
onClick | (event: MouseEvent) => void | - | 点击回调;移动端配合 collapseOnSelect 在导航后自动关闭抽屉 |
SidebarLink
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
href | string | - | 链接地址(必填) |
...itemProps | SidebarItemBaseProps | - | 与 SidebarItem 相同的导航项配置(active、badge、disabled、icon 等) |
SidebarButton
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
type | ButtonHTMLAttributes['type'] | 'button' | 按钮原生 type 属性 |
...itemProps | SidebarItemBaseProps | - | 与 SidebarItem 相同的导航项配置(active、badge、disabled、icon 等) |
SidebarDivider
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 分隔线原生属性与自定义类名,用于分隔导航分组 |
SidebarBackdrop
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 移动端抽屉遮罩;Sidebar 在移动端自动通过 Portal 渲染,也可在自定义布局中单独使用 |
useSidebar
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
返回值 | SidebarContextValue | - | 上下文对象:提供 collapsed、isMobile、mobileOpen 等状态与 setMobileOpen、toggleCollapsed 等操作 |
Common Props
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
children | ReactNode | - | 子内容(导航项文字等) |
className | string | - | 自定义类名 |
...rest | HTMLAttributes | - | 透传原生元素属性(如 `style`、`aria-label` 等) |
Type Definitions
SidebarBreakpoint
响应式断点类型
type SidebarBreakpoint = 'lg' | 'md' | 'sm' | 'xl' | 'xxl';SidebarPlacement
侧边栏停靠位置类型
type SidebarPlacement = 'end' | 'start';SidebarVariant
明暗主题类型
type SidebarVariant = 'dark' | 'light';SidebarStateProps
Sidebar 与 SidebarProvider 共享的状态属性接口
interface SidebarStateProps {
breakpoint?: null | SidebarBreakpoint;
collapsed?: boolean;
collapseOnSelect?: boolean;
defaultCollapsed?: boolean;
defaultOpen?: boolean;
onCollapsedChange?: (collapsed: boolean) => void;
onItemSelect?: () => void;
onOpenChange?: (open: boolean) => void;
open?: boolean;
placement?: SidebarPlacement;
variant?: SidebarVariant;
}SidebarContextValue
useSidebar 返回的上下文值接口
interface SidebarContextValue {
breakpoint: null | SidebarBreakpoint;
collapsed: boolean;
collapseOnSelect: boolean;
isMobile: boolean;
mobileOpen: boolean;
onItemSelect?: () => void;
placement: SidebarPlacement;
setMobileOpen: (open: boolean) => void;
toggleCollapsed: () => void;
variant: SidebarVariant;
}SidebarProviderProps
SidebarProvider 属性接口
interface SidebarProviderProps extends SidebarStateProps {
children?: ReactNode;
}SidebarProps
Sidebar 属性接口
interface SidebarProps extends Omit<HTMLAttributes<HTMLElement>, 'title'>, SidebarStateProps {
as?: ElementType;
collapsedWidth?: number | string;
width?: number | string;
}SidebarRegionProps
Header/Body/Footer 区域属性接口
interface SidebarRegionProps extends HTMLAttributes<HTMLElement> {
as?: ElementType;
children?: ReactNode;
className?: string;
}SidebarGroupProps
SidebarGroup 属性类型
type SidebarGroupProps = SidebarRegionProps;SidebarGroupLabelProps
SidebarGroupLabel 属性类型
type SidebarGroupLabelProps = SidebarRegionProps;SidebarGroupContentProps
SidebarGroupContent 属性类型
type SidebarGroupContentProps = SidebarRegionProps;SidebarItemBaseProps
导航项共享配置接口
interface SidebarItemBaseProps {
active?: boolean;
badge?: ReactNode;
disabled?: boolean;
icon?: ReactNode;
}SidebarItemProps
SidebarItem 属性接口
interface SidebarItemProps extends HTMLAttributes<HTMLElement>, SidebarItemBaseProps {
href?: string;
}SidebarLinkProps
SidebarLink 属性接口
interface SidebarLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement>, SidebarItemBaseProps {
href: string;
}SidebarButtonProps
SidebarButton 属性类型
type SidebarButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & SidebarItemBaseProps;SidebarTriggerProps
SidebarTrigger 属性接口
interface SidebarTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
as?: ElementType;
}SidebarBackdropProps
SidebarBackdrop 属性类型
type SidebarBackdropProps = HTMLAttributes<HTMLDivElement>;SidebarDividerProps
SidebarDivider 属性类型
type SidebarDividerProps = HTMLAttributes<HTMLHRElement>;