浮层组件
Sheet 侧边抽屉
从屏幕边缘滑入的抽屉面板,支持上、下、左、右四个方向,适用于导航菜单、表单、详情面板等场景。
安装
bash
pnpm dlx shadcn@latest add sheet -c packages/react基础用法
tsx
import {
Sheet, SheetTrigger, SheetContent,
SheetHeader, SheetTitle, SheetDescription,
SheetFooter, SheetClose,
} from "@polyui/react/sheet"
import { Button } from "@polyui/react/button"
export function SheetExample() {
return (
<Sheet>
<SheetTrigger asChild>
<Button variant="outline">打开抽屉</Button>
</SheetTrigger>
<SheetContent side="right">
<SheetHeader>
<SheetTitle>编辑资料</SheetTitle>
<SheetDescription>
在此修改你的个人信息,完成后点击保存。
</SheetDescription>
</SheetHeader>
<div className="py-4">
{/* 表单内容 */}
</div>
<SheetFooter>
<SheetClose asChild>
<Button>保存</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
)
}侧边
Side
tsx
import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose } from "@polyui/react/sheet"
import { Button } from "@polyui/react/button"
export function SheetSide() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Side</p>
<div className="flex flex-wrap gap-2">
{(["left", "right", "top", "bottom"] as const).map((side) => (
<Sheet key={side}>
<SheetTrigger render={<Button variant="outline" />}>{side}</SheetTrigger>
<SheetContent side={side}>
<SheetHeader>
<SheetTitle>Sheet — {side}</SheetTitle>
<SheetDescription>Slides in from the {side} edge of the screen.</SheetDescription>
</SheetHeader>
<div className="py-4 text-sm text-muted-foreground">Place your content here.</div>
<SheetFooter>
<SheetClose render={<Button variant="outline" />}>Close</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
))}
</div>
</div>
)
}带表单
With Form
tsx
import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose } from "@polyui/react/sheet"
import { Button } from "@polyui/react/button"
import { Input } from "@polyui/react/input"
import { Label } from "@polyui/react/label"
export function SheetWithForm() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">With Form</p>
<Sheet>
<SheetTrigger render={<Button variant="outline">Edit Profile</Button>} />
<SheetContent side="right">
<SheetHeader>
<SheetTitle>Edit Profile</SheetTitle>
<SheetDescription>Update your profile information. Click save when done.</SheetDescription>
</SheetHeader>
<div className="flex flex-col gap-4 py-4">
<div className="flex flex-col gap-1.5">
<Label htmlFor="sheet-name">Name</Label>
<Input id="sheet-name" placeholder="Sarah Chen" />
</div>
<div className="flex flex-col gap-1.5">
<Label htmlFor="sheet-email">Email</Label>
<Input id="sheet-email" type="email" placeholder="sarah@example.com" />
</div>
<div className="flex flex-col gap-1.5">
<Label htmlFor="sheet-username">Username</Label>
<Input id="sheet-username" placeholder="@sarah" />
</div>
</div>
<SheetFooter>
<SheetClose render={<Button variant="outline" />}>Cancel</SheetClose>
<Button>Save changes</Button>
</SheetFooter>
</SheetContent>
</Sheet>
</div>
)
}无关闭按钮
No Close Button
tsx
import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose } from "@polyui/react/sheet"
import { Button } from "@polyui/react/button"
export function SheetNoCloseButton() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">No Close Button</p>
<Sheet>
<SheetTrigger render={<Button variant="outline">Open (no × button)</Button>} />
<SheetContent side="right" showCloseButton={false}>
<SheetHeader>
<SheetTitle>Custom close</SheetTitle>
<SheetDescription>The built-in close button is hidden. Use the footer button to close.</SheetDescription>
</SheetHeader>
<div className="py-4 text-sm text-muted-foreground">This sheet has no top-right × button.</div>
<SheetFooter>
<SheetClose render={<Button className="w-full" />}>Done</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
</div>
)
}导航菜单
Navigation Menu
tsx
import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetClose } from "@polyui/react/sheet"
import { Button } from "@polyui/react/button"
export function SheetNavigationMenu() {
return (
<div className="flex flex-col gap-3">
<p className="text-xs font-mono text-muted-foreground uppercase tracking-widest">Navigation Menu</p>
<Sheet>
<SheetTrigger render={<Button variant="outline">Open Menu</Button>} />
<SheetContent side="left">
<SheetHeader>
<SheetTitle>Navigation</SheetTitle>
</SheetHeader>
<nav className="flex flex-col gap-1 py-4">
{["Dashboard", "Projects", "Team", "Reports", "Settings"].map((item) => (
<SheetClose
key={item}
render={
<button className="flex items-center rounded-md px-3 py-2 text-sm font-medium text-foreground hover:bg-accent hover:text-accent-foreground transition-colors text-left" />
}
>
{item}
</SheetClose>
))}
</nav>
</SheetContent>
</Sheet>
</div>
)
}Props
SheetContent
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
side | "top" | "right" | "bottom" | "left" | "right" | 抽屉从哪一侧滑入。 |
showCloseButton | boolean | true | 是否显示右上角关闭按钮。 |
className | string | — | 自定义样式类名。 |
Sheet (Root)
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
open | boolean | — | 受控开关状态。 |
onOpenChange | (open: boolean) => void | — | 状态变化回调。 |
defaultOpen | boolean | false | 非受控初始状态。 |