- 手风琴
- 提示
- 警告对话框
- 宽高比
- 头像
- 徽章
- 面包屑导航
- 按钮
- 按钮组
- 日历 Calendar
- 卡片
- Carousel
- 图表 Chart
- 复选框
- 折叠面板
- 组合框
- 命令
- 上下文菜单
- 数据表格 Data Table
- 日期选择器 Date Picker
- 对话框 Dialog
- 抽屉
- 下拉菜单
- Empty
- 字段
- 悬停卡片
- 输入
- 输入组
- 输入 OTP
- 项目
- Kbd
- 标签
- 菜单栏
- 原生选择框
- 导航菜单 Navigation Menu
- 分页
- 弹出框
- 进度 Progress
- 单选框组
- 可调整大小
- 滚动区域 Scroll Area
- 选择框
- 分隔符 Separator
- 侧边栏 Sheet
- 侧边栏 Sidebar
- 骨架屏
- 滑块
- Sonner
- 加载指示器 Spinner
- 开关
- 表格
- 标签页 Tabs
- 文本域
- 吐司
- 切换按钮 Toggle
- 切换组
- 提示 Tooltip
- 排版


一个可折叠为图标的侧边栏。
侧边栏是最复杂的组件之一。它们是任何应用的核心,通常包含许多动态部分。
我不喜欢构建侧边栏。所以我构建了 30 多个。各种配置。然后我将核心组件提取到 sidebar.tsx 中。
现在我们有了一个坚实的基础。可组合。可主题。可定制。
安装
运行以下命令安装 sidebar.tsx
pnpm dlx shadcn@latest add sidebar
将以下颜色添加到你的 CSS 文件
上述命令应帮你安装颜色。如果没有,请复制下面内容粘贴到你的 CSS 文件中。
我们稍后会在主题部分详细介绍颜色。
@layer base {
:root {
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.439 0 0);
}
}结构
一个 Sidebar 组件由以下部分组成:
SidebarProvider- 处理可折叠状态。Sidebar- 侧边栏容器。SidebarHeader和SidebarFooter- 分别固定在侧边栏的顶部和底部。SidebarContent- 可滚动内容区域。SidebarGroup- 侧边栏内容内的分组区域。SidebarTrigger- 侧边栏的触发按钮。
用法
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<AppSidebar />
<main>
<SidebarTrigger />
{children}
</main>
</SidebarProvider>
)
}import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarHeader,
} from "@/components/ui/sidebar"
export function AppSidebar() {
return (
<Sidebar>
<SidebarHeader />
<SidebarContent>
<SidebarGroup />
<SidebarGroup />
</SidebarContent>
<SidebarFooter />
</Sidebar>
)
}你的第一个侧边栏
让我们从最基础的侧边栏开始。一个可折叠的带菜单的侧边栏。
在应用根部添加 SidebarProvider 和 SidebarTrigger。
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<AppSidebar />
<main>
<SidebarTrigger />
{children}
</main>
</SidebarProvider>
)
}在 components/app-sidebar.tsx 新建一个侧边栏组件。
import { Sidebar, SidebarContent } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
<Sidebar>
<SidebarContent />
</Sidebar>
)
}现在,我们给侧边栏添加一个 SidebarMenu。
我们将在 SidebarGroup 中使用 SidebarMenu。
import { Calendar, Home, Inbox, Search, Settings } from "lucide-react"
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar"
// 菜单项。
const items = [
{
title: "Home",
url: "#",
icon: Home,
},
{
title: "Inbox",
url: "#",
icon: Inbox,
},
{
title: "Calendar",
url: "#",
icon: Calendar,
},
{
title: "Search",
url: "#",
icon: Search,
},
{
title: "Settings",
url: "#",
icon: Settings,
},
]
export function AppSidebar() {
return (
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>应用</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<a href={item.url}>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
)
}你已创建了你的第一个侧边栏。
你应该看到类似这样的效果:


你的第一个侧边栏。
组件
sidebar.tsx 中的组件旨在支持组合,即你通过组合提供的组件来构建侧边栏。它们也能很好地与其他 shadcn/ui 组件配合使用,比如 DropdownMenu、Collapsible 或 Dialog 等。
如果你需要修改 sidebar.tsx 中的代码,欢迎这么做。代码是你的。将 sidebar.tsx 作为起点,构建自己的侧边栏。
接下来的部分,我们将详细介绍各个组件及如何使用它们。
SidebarProvider
SidebarProvider 组件用于为 Sidebar 组件提供上下文。你的应用应始终被 SidebarProvider 包裹。
属性
| 名称 | 类型 | 说明 |
|---|---|---|
defaultOpen | boolean | 侧边栏的默认打开状态。 |
open | boolean | 侧边栏打开状态(受控)。 |
onOpenChange | (open: boolean) => void | 设置侧边栏打开状态的回调(受控)。 |
宽度
如果你的应用中只有一个侧边栏,可以使用 sidebar.tsx 中的 SIDEBAR_WIDTH 和 SIDEBAR_WIDTH_MOBILE 变量来设置侧边栏宽度。
const SIDEBAR_WIDTH = "16rem"
const SIDEBAR_WIDTH_MOBILE = "18rem"如果有多个侧边栏,你可以使用 style 属性设置宽度。
通过 style 属性中的 --sidebar-width 和 --sidebar-width-mobile CSS 变量来设置宽度。
<SidebarProvider
style={{
"--sidebar-width": "20rem",
"--sidebar-width-mobile": "20rem",
}}
>
<Sidebar />
</SidebarProvider>这样既会控制侧边栏宽度,也会调整布局间距。
键盘快捷键
SIDEBAR_KEYBOARD_SHORTCUT 变量用于设置打开关闭侧边栏的快捷键。
在 Mac 上使用 cmd+b,在 Windows 上使用 ctrl+b。
你可以通过修改 SIDEBAR_KEYBOARD_SHORTCUT 变量自定义快捷键。
const SIDEBAR_KEYBOARD_SHORTCUT = "b"状态持久化
SidebarProvider 支持在页面刷新和服务端渲染间保持侧边栏状态。它使用 cookie 来存储当前状态。每当状态改变时,会设置一个名为 sidebar_state 的默认 cookie 保存开/关状态,后续页面加载时读取此 cookie 恢复状态。
在 Next.js 中持久化状态,可像下面这样配置 app/layout.tsx 中的 SidebarProvider:
import { cookies } from "next/headers"
import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"
import { AppSidebar } from "@/components/app-sidebar"
export async function Layout({ children }: { children: React.ReactNode }) {
const cookieStore = await cookies()
const defaultOpen = cookieStore.get("sidebar_state")?.value === "true"
return (
<SidebarProvider defaultOpen={defaultOpen}>
<AppSidebar />
<main>
<SidebarTrigger />
{children}
</main>
</SidebarProvider>
)
}你也可以通过修改 sidebar.tsx 中的 SIDEBAR_COOKIE_NAME 变量自定义 cookie 名称。
const SIDEBAR_COOKIE_NAME = "sidebar_state"Sidebar
主侧边栏组件,用于渲染可折叠的侧边栏。
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return <Sidebar />
}属性
| 属性 | 类型 | 说明 |
|---|---|---|
side | 'left' 或 'right' | 侧边栏出现的侧边。 |
variant | 'sidebar'、'floating' 或 'inset' | 侧边栏的样式变体。 |
collapsible | 'offcanvas'、'icon' 或 'none' | 侧边栏的可折叠状态。 |
side
用 side 属性来切换侧边栏所在侧。
可用选项为 left 和 right。
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return <Sidebar side="left | right" />
}variant
用 variant 属性来切换侧边栏样式变体。
可用选项为 sidebar、floating 和 inset。
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return <Sidebar variant="sidebar | floating | inset" />
}注意: 如果使用 inset 变体,记得用 SidebarInset 组件包裹主内容。
<SidebarProvider>
<Sidebar variant="inset" />
<SidebarInset>
<main>{children}</main>
</SidebarInset>
</SidebarProvider>collapsible
用 collapsible 属性让侧边栏可折叠。
可用选项为 offcanvas、icon 和 none。
import { Sidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
return <Sidebar collapsible="offcanvas | icon | none" />
}| 属性 | 说明 |
|---|---|
offcanvas | 可折叠的侧边栏,从左或右滑动进出。 |
icon | 折叠为图标的侧边栏。 |
none | 不可折叠的侧边栏。 |
useSidebar
useSidebar 钩子用于控制侧边栏状态。
import { useSidebar } from "@/components/ui/sidebar"
export function AppSidebar() {
const {
state,
open,
setOpen,
openMobile,
setOpenMobile,
isMobile,
toggleSidebar,
} = useSidebar()
}| 属性 | 类型 | 说明 |
|---|---|---|
state | 'expanded' 或 'collapsed' | 当前侧边栏状态。 |
open | boolean | 侧边栏是否打开。 |
setOpen | (open: boolean) => void | 设置侧边栏打开状态。 |
openMobile | boolean | 移动端侧边栏是否打开。 |
setOpenMobile | (open: boolean) => void | 设置移动端侧边栏打开状态。 |
isMobile | boolean | 是否处于移动端状态。 |
toggleSidebar | () => void | 切换侧边栏开关。支持桌面和移动端。 |
SidebarHeader
SidebarHeader 组件用于为侧边栏添加一个粘性头部。
下面示例展示在 SidebarHeader 中添加一个 <DropdownMenu>。


带下拉菜单的侧边栏头部。
<Sidebar>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton>
Select Workspace
<ChevronDown className="ml-auto" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[--radix-popper-anchor-width]">
<DropdownMenuItem>
<span>Acme Inc</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Acme Corp.</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
</Sidebar>SidebarFooter
使用 SidebarFooter 组件添加固定底部区域。
下面示例在 SidebarFooter 添加一个 <DropdownMenu>。


带下拉菜单的侧边栏底部。
export function AppSidebar() {
return (
<SidebarProvider>
<Sidebar>
<SidebarHeader />
<SidebarContent />
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton>
<User2 /> Username
<ChevronUp className="ml-auto" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
className="w-[--radix-popper-anchor-width]"
>
<DropdownMenuItem>
<span>Account</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Billing</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Sign out</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>
</SidebarProvider>
)
}SidebarContent
SidebarContent 包裹侧边栏内容,是添加 SidebarGroup 的地方。它是可滚动的。
import { Sidebar, SidebarContent } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
<Sidebar>
<SidebarContent>
<SidebarGroup />
<SidebarGroup />
</SidebarContent>
</Sidebar>
)
}SidebarGroup
使用 SidebarGroup 创建侧边栏的分区。
SidebarGroup 包含 SidebarGroupLabel、SidebarGroupContent 和可选的 SidebarGroupAction。


一个侧边栏分组。
import { Sidebar, SidebarContent, SidebarGroup } from "@/components/ui/sidebar"
export function AppSidebar() {
return (
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>应用</SidebarGroupLabel>
<SidebarGroupAction>
<Plus /> <span className="sr-only">添加项目</span>
</SidebarGroupAction>
<SidebarGroupContent></SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
)
}可折叠的 SidebarGroup
若想让 SidebarGroup 可折叠,用 Collapsible 包裹它。


一个可折叠的侧边栏分组。
export function AppSidebar() {
return (
<Collapsible defaultOpen className="group/collapsible">
<SidebarGroup>
<SidebarGroupLabel asChild>
<CollapsibleTrigger>
帮助
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
</CollapsibleTrigger>
</SidebarGroupLabel>
<CollapsibleContent>
<SidebarGroupContent />
</CollapsibleContent>
</SidebarGroup>
</Collapsible>
)
}提示: 我们将 CollapsibleTrigger 包裹在 SidebarGroupLabel 中,以便渲染为按钮。
SidebarGroupAction
使用 SidebarGroupAction 为 SidebarGroup 添加操作按钮。


带操作按钮的侧边栏分组。
export function AppSidebar() {
return (
<SidebarGroup>
<SidebarGroupLabel asChild>项目</SidebarGroupLabel>
<SidebarGroupAction title="添加项目">
<Plus /> <span className="sr-only">添加项目</span>
</SidebarGroupAction>
<SidebarGroupContent />
</SidebarGroup>
)
}SidebarMenu
SidebarMenu 用于在 SidebarGroup 内创建菜单。
SidebarMenu 由 SidebarMenuItem、SidebarMenuButton、<SidebarMenuAction /> 和 <SidebarMenuSub /> 组成。
下面示例是一个渲染项目列表的侧边栏菜单。


带项目列表的侧边栏菜单。
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>项目</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{projects.map((project) => (
<SidebarMenuItem key={project.name}>
<SidebarMenuButton asChild>
<a href={project.url}>
<project.icon />
<span>{project.name}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>SidebarMenuButton
SidebarMenuButton 用于在 SidebarMenuItem 中渲染菜单按钮。
链接或锚点
默认渲染为按钮,但可用 asChild 属性渲染其他组件,如 Link 或 a 标签。
<SidebarMenuButton asChild>
<a href="#">首页</a>
</SidebarMenuButton>图标与标签
可在按钮中渲染图标和被截断的标签。标签应包裹在 <span> 中。
<SidebarMenuButton asChild>
<a href="#">
<Home />
<span>首页</span>
</a>
</SidebarMenuButton>isActive
使用 isActive 属性标记菜单项为激活状态。
<SidebarMenuButton asChild isActive>
<a href="#">首页</a>
</SidebarMenuButton>SidebarMenuAction
SidebarMenuAction 用于在 SidebarMenuItem 中渲染菜单操作按钮。
此按钮独立于 SidebarMenuButton,即你可以有一个 <SidebarMenuButton /> 做链接点击,另一个 <SidebarMenuAction /> 作为按钮。
<SidebarMenuItem>
<SidebarMenuButton asChild>
<a href="#">
<Home />
<span>首页</span>
</a>
</SidebarMenuButton>
<SidebarMenuAction>
<Plus /> <span className="sr-only">添加项目</span>
</SidebarMenuAction>
</SidebarMenuItem>DropdownMenu 示例
SidebarMenuAction 里嵌套 DropdownMenu 示例。


带下拉菜单的侧边栏菜单操作。
<SidebarMenuItem>
<SidebarMenuButton asChild>
<a href="#">
<Home />
<span>首页</span>
</a>
</SidebarMenuButton>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuAction>
<MoreHorizontal />
</SidebarMenuAction>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" align="start">
<DropdownMenuItem>
<span>编辑项目</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>删除项目</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>SidebarMenuSub
SidebarMenuSub 用于渲染子菜单。
用 <SidebarMenuSubItem /> 和 <SidebarMenuSubButton /> 渲染子菜单项。


带子菜单的侧边栏菜单。
<SidebarMenuItem>
<SidebarMenuButton />
<SidebarMenuSub>
<SidebarMenuSubItem>
<SidebarMenuSubButton />
</SidebarMenuSubItem>
<SidebarMenuSubItem>
<SidebarMenuSubButton />
</SidebarMenuSubItem>
</SidebarMenuSub>
</SidebarMenuItem>可折叠的 SidebarMenu
要让 SidebarMenu 可折叠,使用 Collapsible 包裹它和 SidebarMenuSub。


一个可折叠的侧边栏菜单。
<SidebarMenu>
<Collapsible defaultOpen className="group/collapsible">
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton />
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub>
<SidebarMenuSubItem />
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
</SidebarMenu>SidebarMenuBadge
SidebarMenuBadge 用于在 SidebarMenuItem 中渲染徽章。


带徽章的侧边栏菜单。
<SidebarMenuItem>
<SidebarMenuButton />
<SidebarMenuBadge>24</SidebarMenuBadge>
</SidebarMenuItem>SidebarMenuSkeleton
SidebarMenuSkeleton 用于渲染菜单的骨架屏。可以用作 React 服务端组件、SWR 或 react-query 加载时的占位。
function NavProjectsSkeleton() {
return (
<SidebarMenu>
{Array.from({ length: 5 }).map((_, index) => (
<SidebarMenuItem key={index}>
<SidebarMenuSkeleton />
</SidebarMenuItem>
))}
</SidebarMenu>
)
}SidebarSeparator
SidebarSeparator 用于在侧边栏内渲染分割线。
<Sidebar>
<SidebarHeader />
<SidebarSeparator />
<SidebarContent>
<SidebarGroup />
<SidebarSeparator />
<SidebarGroup />
</SidebarContent>
</Sidebar>SidebarTrigger
SidebarTrigger 用于渲染切换侧边栏的按钮。
必须在 SidebarProvider 内使用。
<SidebarProvider>
<Sidebar />
<main>
<SidebarTrigger />
</main>
</SidebarProvider>自定义触发器
使用 useSidebar 钩子创建自定义触发器。
import { useSidebar } from "@/components/ui/sidebar"
export function CustomTrigger() {
const { toggleSidebar } = useSidebar()
return <button onClick={toggleSidebar}>切换侧边栏</button>
}SidebarRail
SidebarRail 用于在侧边栏内渲染一个轨道,可用于切换侧边栏。
<Sidebar>
<SidebarHeader />
<SidebarContent>
<SidebarGroup />
</SidebarContent>
<SidebarFooter />
<SidebarRail />
</Sidebar>数据获取
React 服务端组件
下面是一个使用 React 服务端组件渲染项目列表的 SidebarMenu 例子。


使用 React 服务端组件的侧边栏菜单。
function NavProjectsSkeleton() {
return (
<SidebarMenu>
{Array.from({ length: 5 }).map((_, index) => (
<SidebarMenuItem key={index}>
<SidebarMenuSkeleton showIcon />
</SidebarMenuItem>
))}
</SidebarMenu>
)
}async function NavProjects() {
const projects = await fetchProjects()
return (
<SidebarMenu>
{projects.map((project) => (
<SidebarMenuItem key={project.name}>
<SidebarMenuButton asChild>
<a href={project.url}>
<project.icon />
<span>{project.name}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
)
}function AppSidebar() {
return (
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>项目</SidebarGroupLabel>
<SidebarGroupContent>
<React.Suspense fallback={<NavProjectsSkeleton />}>
<NavProjects />
</React.Suspense>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
)
}SWR 与 React Query
也可以用同样的方式配合 SWR 或 react-query。
function NavProjects() {
const { data, isLoading } = useSWR("/api/projects", fetcher)
if (isLoading) {
return (
<SidebarMenu>
{Array.from({ length: 5 }).map((_, index) => (
<SidebarMenuItem key={index}>
<SidebarMenuSkeleton showIcon />
</SidebarMenuItem>
))}
</SidebarMenu>
)
}
if (!data) {
return ...
}
return (
<SidebarMenu>
{data.map((project) => (
<SidebarMenuItem key={project.name}>
<SidebarMenuButton asChild>
<a href={project.url}>
<project.icon />
<span>{project.name}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
)
}function NavProjects() {
const { data, isLoading } = useQuery()
if (isLoading) {
return (
<SidebarMenu>
{Array.from({ length: 5 }).map((_, index) => (
<SidebarMenuItem key={index}>
<SidebarMenuSkeleton showIcon />
</SidebarMenuItem>
))}
</SidebarMenu>
)
}
if (!data) {
return ...
}
return (
<SidebarMenu>
{data.map((project) => (
<SidebarMenuItem key={project.name}>
<SidebarMenuButton asChild>
<a href={project.url}>
<project.icon />
<span>{project.name}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
)
}受控侧边栏
使用 open 和 onOpenChange 属性来控制侧边栏。


一个受控的侧边栏。
export function AppSidebar() {
const [open, setOpen] = React.useState(false)
return (
<SidebarProvider open={open} onOpenChange={setOpen}>
<Sidebar />
</SidebarProvider>
)
}主题
我们使用以下 CSS 变量为侧边栏设定主题。
@layer base {
:root {
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 0 0% 98%;
--sidebar-primary-foreground: 240 5.9% 10%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
}我们故意对侧边栏和应用其他部分使用不同的变量,这样可以让侧边栏拥有与主应用不同的样式。例如,给侧边栏一个比主应用更暗的色调。
样式
以下是根据不同状态样式化侧边栏的小技巧。
- 根据侧边栏折叠状态样式化元素。 以下示例会在侧边栏为
icon模式时隐藏SidebarGroup。
<Sidebar collapsible="icon">
<SidebarContent>
<SidebarGroup className="group-data-[collapsible=icon]:hidden" />
</SidebarContent>
</Sidebar>- 根据菜单按钮激活状态样式化菜单操作。 以下会在菜单按钮处于激活状态时强制显示菜单操作。
<SidebarMenuItem>
<SidebarMenuButton />
<SidebarMenuAction className="peer-data-[active=true]/menu-button:opacity-100" />
</SidebarMenuItem>更多关于使用状态进行样式化的提示见此Twitter 线程。
更新日志
2024-10-30 Cookie 处理 in setOpen
- #5593 - 改进
<SidebarProvider>中 setOpen 回调逻辑。
更新 <SidebarProvider> 中的 setOpen 回调:
const setOpen = React.useCallback(
(value: boolean | ((value: boolean) => boolean)) => {
const openState = typeof value === "function" ? value(open) : value
if (setOpenProp) {
setOpenProp(openState)
} else {
_setOpen(openState)
}
// 设置 cookie 保存侧边栏状态。
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
},
[setOpenProp, open]
)2024-10-21 修复 text-sidebar-foreground
- #5491 - 将
text-sidebar-foreground从<SidebarProvider>移动到<Sidebar>。
2024-10-20 修正 useSidebar 钩子中的拼写错误。
修正拼写错误。
- throw new Error("useSidebar must be used within a Sidebar.")
+ throw new Error("useSidebar must be used within a SidebarProvider.")目录
安装结构用法你的第一个侧边栏组件SidebarProvider属性宽度键盘快捷键状态持久化Sidebar属性sidevariantcollapsibleuseSidebarSidebarHeaderSidebarFooterSidebarContentSidebarGroup可折叠的 SidebarGroupSidebarGroupActionSidebarMenuSidebarMenuButton链接或锚点图标与标签isActiveSidebarMenuActionDropdownMenu 示例SidebarMenuSub可折叠的 SidebarMenuSidebarMenuBadgeSidebarMenuSkeletonSidebarSeparatorSidebarTrigger自定义触发器SidebarRail数据获取React 服务端组件SWR 与 React Query受控侧边栏主题样式更新日志2024-10-30 Cookie 处理 in setOpen2024-10-21 修复text-sidebar-foreground2024-10-20 修正 useSidebar 钩子中的拼写错误。