Skip to main content
PolyUI/docs

浮层组件

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"抽屉从哪一侧滑入。
showCloseButtonbooleantrue是否显示右上角关闭按钮。
classNamestring自定义样式类名。

Sheet (Root)

属性类型默认值说明
openboolean受控开关状态。
onOpenChange(open: boolean) => void状态变化回调。
defaultOpenbooleanfalse非受控初始状态。