सामग्री पर जाएँ

शीट

स्क्रीन के किनारे से स्लाइड-इन होने वाला एक पैनल, जो नेविगेशन ड्रॉअर, फ़िल्टर और संपादन फ़ॉर्म के लिए है — जिसमें नियोब्रूटलिस्ट शैली का बॉर्डर-और-छाया प्रभाव है।

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

शीट एक ऐसा डायलॉग है जो स्क्रीन के बीच में नहीं, बल्कि किसी किनारे से लगा होता है — ओवरले, फ़ोकस ट्रैप और डिसमिस का बर्ताव वही, बस जगह अलग। यह Base UI Dialog प्रिमिटिव पर बना है और नियोब्रूटलिस्ट रेसिपी के अनुसार स्टाइल किया गया है: मोटे बॉर्डर, कठोर छायाएँ और बोल्ड टाइपोग्राफ़ी।

इसे इन स्थितियों में चुनें:

  • मोबाइल नेविगेशन — हैमबर्गर ड्रॉअर, जो किनारे से स्लाइड होकर आता है।
  • कार्ट और डिटेल पैनल — शॉपिंग कार्ट, ऑर्डर सारांश या पंक्ति का विवरण, वह भी पेज छोड़े बिना।
  • एडिट फ़ॉर्म — साइड पैनल में रिकॉर्ड अपडेट करें, और टेबल सामने दिखती रहे।

इंस्टॉलेशन

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/sheet.json
npx shadcn@latest add https://neobrutalism.com/r/base/sheet.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/sheet.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/sheet.json

निम्नलिखित डिपेंडेंसी इंस्टॉल करें:

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

निम्नलिखित कोड को अपने प्रोजेक्ट में कॉपी और पेस्ट करें.

components/ui/sheet.tsx
"use client"

import * as React from "react"
import { XIcon } from "lucide-react"
import { Dialog as SheetPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"

function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
  return <SheetPrimitive.Root data-slot="sheet" {...props} />
}

function SheetTrigger({
  ...props
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
  return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
}

function SheetClose({
  ...props
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
  return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
}

function SheetPortal({
  ...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
  return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
}

function SheetOverlay({
  className,
  ...props
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
  return (
    <SheetPrimitive.Overlay
      data-slot="sheet-overlay"
      className={cn(
        "fixed inset-0 z-50 bg-foreground/20 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
        className
      )}
      {...props}
    />
  )
}

function SheetContent({
  className,
  children,
  side = "right",
  showCloseButton = true,
  ...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
  side?: "top" | "right" | "bottom" | "left"
  showCloseButton?: boolean
}) {
  return (
    <SheetPortal>
      <SheetOverlay />
      <SheetPrimitive.Content
        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-md transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t-2 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-2 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-2 data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b-2 data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
          className
        )}
        {...props}
      >
        {children}
        {showCloseButton && (
          <SheetPrimitive.Close data-slot="sheet-close" asChild>
            <Button
              variant="ghost"
              className="absolute top-3 right-3"
              size="icon-sm"
            >
              <XIcon />
              <span className="sr-only">Close</span>
            </Button>
          </SheetPrimitive.Close>
        )}
      </SheetPrimitive.Content>
    </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
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
  return (
    <SheetPrimitive.Title
      data-slot="sheet-title"
      className={cn(
        "font-head text-base font-medium text-foreground",
        className
      )}
      {...props}
    />
  )
}

function SheetDescription({
  className,
  ...props
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
  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,
}

अपने प्रोजेक्ट सेटअप के अनुसार इंपोर्ट पाथ अपडेट करें.

उपयोग

import {
  Sheet,
  SheetClose,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet"
<Sheet>
  <SheetTrigger>Open</SheetTrigger>
  <SheetContent>
    <SheetHeader>
      <SheetTitle>Are you absolutely sure?</SheetTitle>
      <SheetDescription>This action cannot be undone.</SheetDescription>
    </SheetHeader>
  </SheetContent>
</Sheet>

कंपोज़िशन

Sheet बनाने के लिए निम्नलिखित कंपोज़िशन का उपयोग करें:

Sheet
├── SheetTrigger
└── SheetContent
    ├── SheetHeader
    │   ├── SheetTitle
    │   └── SheetDescription
    └── SheetFooter

उदाहरण

साइड

sheet स्क्रीन के जिस किनारे से दिखाई दे, उसे सेट करने के लिए SheetContent पर side prop का उपयोग करें. मान top, right, bottom या left हैं.

import { Button } from "@/components/ui/button"
import {
  Sheet,

बिना क्लोज़ बटन के

क्लोज़ बटन छिपाने के लिए SheetContent पर showCloseButton={false} का उपयोग करें.

import { Button } from "@/components/ui/button"
import {
  Sheet,

RTL

Neobrutalism में RTL समर्थन सक्षम करने के लिए, RTL कॉन्फ़िगरेशन गाइड देखें.

"use client"

import {

एक्सेसिबिलिटी

शीट WAI-ARIA Dialog (Modal) पैटर्न का पालन करती है: पैनल aria-modal के साथ role="dialog" रेंडर करता है, खुलने पर फ़ोकस उसके भीतर चला जाता है और वहीं रुका रहता है, और SheetTitle / SheetDescription, aria-labelledby / aria-describedby से जुड़े रहते हैं — SheetTitle हमेशा रेंडर करें, ज़रूरत पड़े तो दृश्य रूप से छिपाकर।

कीबोर्ड इंटरैक्शन:

कुंजीक्रिया
Space / Enterट्रिगर पर फ़ोकस होने पर शीट खोलें
Tab / Shift + Tabशीट के भीतर फ़ोकस-योग्य एलिमेंट्स के बीच फ़ोकस बदलें (फ़ोकस ट्रैप)
Escशीट बंद करें और फ़ोकस ट्रिगर पर लौटाएँ

API रेफ़रेंस

Base UI Dialog दस्तावेज़ देखें.