ข้ามไปเนื้อหา
WhereUI

ค้นหาในเอกสาร

ค้นหาชื่อ component หรือหน้าเอกสาร

Sheet

จาก shadcn

แผงที่เลื่อนออกมาจากขอบจอเพื่อแสดงรายละเอียดหรือฟอร์มสั้น ๆ โดยไม่ต้องออกจากหน้าปัจจุบัน เลือกด้านที่โผล่ได้ 4 ด้าน

ติดตั้ง

Terminal
pnpm dlx shadcn@latest add @whereui/sheet

ต้องผูก registry และติดตั้ง @whereui/theme นำหน้าเสมอเมื่อติดตั้งครั้งแรก

การใช้งาน

import {  Sheet,  SheetContent,  SheetDescription,  SheetHeader,  SheetTitle,  SheetTrigger,} from "@/components/ui/sheet"import { Button } from "@/components/ui/button"<Sheet>  <SheetTrigger render={<Button variant="outline" />}>เปิดแผง</SheetTrigger>  <SheetContent>    <SheetHeader>      <SheetTitle>รายละเอียด</SheetTitle>      <SheetDescription>ข้อมูลผู้อนุมัติในสายงานของคุณ</SheetDescription>    </SheetHeader>  </SheetContent></Sheet>

ตัวอย่างเพิ่มเติม

แผงจากทุกด้าน

ข้อควรรู้

  • Base UI ไม่มี asChild — ใช้ prop render ส่ง component ที่ต้องการให้ trigger แสดงผลเป็น เช่น render={<Button />}
  • ปิดได้ด้วยปุ่มปิดมุมบน กด Esc หรือคลิกพื้นหลัง และโฟกัสถูกดักไว้ในแผงเพื่อการเข้าถึง
  • บนมือถือควรพิจารณาใช้ Drawer แทน เพราะเข้าถึงด้านล่างจอง่ายกว่า

ซอร์สโค้ด

components/ui/sheet.tsx
"use client"import * as React from "react"import { Dialog as SheetPrimitive } from "@base-ui/react/dialog"import { cn } from "cn"import { Button } from "@/components/ui/button"import { XIcon } from "lucide-react"function Sheet({ ...props }: SheetPrimitive.Root.Props) {  return <SheetPrimitive.Root data-slot="sheet" {...props} />}function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {  return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />}function SheetClose({ ...props }: SheetPrimitive.Close.Props) {  return <SheetPrimitive.Close data-slot="sheet-close" {...props} />}function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {  return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />}function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {  return (    <SheetPrimitive.Backdrop      data-slot="sheet-overlay"      className={cn(        "fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",        className      )}      {...props}    />  )}function SheetContent({  className,  children,  side = "right",  showCloseButton = true,  ...props}: SheetPrimitive.Popup.Props & {  side?: "top" | "right" | "bottom" | "left"  showCloseButton?: boolean}) {  return (    <SheetPortal>      <SheetOverlay />      <SheetPrimitive.Popup        data-slot="sheet-content"        data-side={side}        className={cn(          "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",          className        )}        {...props}      >        {children}        {showCloseButton && (          <SheetPrimitive.Close            data-slot="sheet-close"            render={              <Button                variant="ghost"                className="absolute top-3 right-3"                size="icon-sm"              />            }          >            <XIcon            />            <span className="sr-only">Close</span>          </SheetPrimitive.Close>        )}      </SheetPrimitive.Popup>    </SheetPortal>  )}function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {  return (    <div      data-slot="sheet-header"      className={cn("flex flex-col gap-0.5 p-4", className)}      {...props}    />  )}function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {  return (    <div      data-slot="sheet-footer"      className={cn("mt-auto flex flex-col gap-2 p-4", className)}      {...props}    />  )}function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {  return (    <SheetPrimitive.Title      data-slot="sheet-title"      className={cn(        "font-heading text-base font-medium text-foreground",        className      )}      {...props}    />  )}function SheetDescription({  className,  ...props}: SheetPrimitive.Description.Props) {  return (    <SheetPrimitive.Description      data-slot="sheet-description"      className={cn("text-sm text-muted-foreground", className)}      {...props}    />  )}export {  Sheet,  SheetTrigger,  SheetClose,  SheetContent,  SheetHeader,  SheetFooter,  SheetTitle,  SheetDescription,}