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

ड्रॉअर

मोबाइल मेनू, फ़िल्टर और त्वरित फ़ॉर्म के लिए किसी भी किनारे से स्लाइड-इन होने वाली एक इशारा-संचालित शीट — नव-ब्रूटलिस्ट शैली की सीमाओं और छायाओं के साथ।

"use client"

import * as React from "react"

ड्रॉअर स्क्रीन के किनारे से सरकता पैनल है, जिसे खींचकर बंद किया जा सकता है। Emil Kowalski के Vaul पर बना है और नियोब्रूटलिस्ट रेसिपी के अनुसार स्टाइल किया गया है: मोटे बॉर्डर, कठोर छायाएँ और बोल्ड टाइपोग्राफ़ी।

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

  • मोबाइल एक्शन शीट — शेयर मेनू, सॉर्ट विकल्प, त्वरित पुष्टि। टच पर drag-to-dismiss छोटे क्लोज़ बटन ढूँढने से बेहतर है।
  • फ़िल्टर और सेटिंग्स पैनल — ई-कॉमर्स फ़िल्टर या प्रेफ़रेंस जिन्हें पॉपओवर से ज़्यादा जगह चाहिए पर पूरा पेज नहीं।
  • रिस्पॉन्सिव डायलॉग — डेस्कटॉप पर Dialog और मोबाइल पर ड्रॉअर (नीचे उदाहरण देखें)।

परिचय

Drawer को emilkowalski द्वारा बनाए गए Vaul के आधार पर बनाया गया है.

इंस्टॉलेशन

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

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

pnpm add vaul
npm install vaul
yarn add vaul
bun add vaul

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

components/ui/drawer.tsx
"use client"

import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"

import { cn } from "@/lib/utils"

function Drawer({
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) {
  return <DrawerPrimitive.Root data-slot="drawer" {...props} />
}

function DrawerTrigger({
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
  return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
}

function DrawerPortal({
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
  return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
}

function DrawerClose({
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Close>) {
  return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
}

function DrawerOverlay({
  className,
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
  return (
    <DrawerPrimitive.Overlay
      data-slot="drawer-overlay"
      className={cn(
        "fixed inset-0 z-50 bg-foreground/20 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 DrawerContent({
  className,
  children,
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Content>) {
  return (
    <DrawerPortal data-slot="drawer-portal">
      <DrawerOverlay />
      <DrawerPrimitive.Content
        data-slot="drawer-content"
        className={cn(
          "group/drawer-content fixed z-50 flex h-auto flex-col bg-popover text-sm text-popover-foreground shadow-md data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t-2 data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r-2 data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l-2 data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b-2 data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm",
          className
        )}
        {...props}
      >
        <div className="mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
        {children}
      </DrawerPrimitive.Content>
    </DrawerPortal>
  )
}

function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="drawer-header"
      className={cn(
        "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left",
        className
      )}
      {...props}
    />
  )
}

function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="drawer-footer"
      className={cn("mt-auto flex flex-col gap-2 p-4", className)}
      {...props}
    />
  )
}

function DrawerTitle({
  className,
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Title>) {
  return (
    <DrawerPrimitive.Title
      data-slot="drawer-title"
      className={cn(
        "font-head text-base font-medium text-foreground",
        className
      )}
      {...props}
    />
  )
}

function DrawerDescription({
  className,
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Description>) {
  return (
    <DrawerPrimitive.Description
      data-slot="drawer-description"
      className={cn("text-sm text-muted-foreground", className)}
      {...props}
    />
  )
}

export {
  Drawer,
  DrawerPortal,
  DrawerOverlay,
  DrawerTrigger,
  DrawerClose,
  DrawerContent,
  DrawerHeader,
  DrawerFooter,
  DrawerTitle,
  DrawerDescription,
}

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

उपयोग

import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
<Drawer>
  <DrawerTrigger>Open</DrawerTrigger>
  <DrawerContent>
    <DrawerHeader>
      <DrawerTitle>Are you absolutely sure?</DrawerTitle>
      <DrawerDescription>This action cannot be undone.</DrawerDescription>
    </DrawerHeader>
    <DrawerFooter>
      <Button>Submit</Button>
      <DrawerClose>
        <Button variant="outline">Cancel</Button>
      </DrawerClose>
    </DrawerFooter>
  </DrawerContent>
</Drawer>

कंपोज़िशन

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

Drawer
├── DrawerTrigger
└── DrawerContent
    ├── DrawerHeader
    │   ├── DrawerTitle
    │   └── DrawerDescription
    └── DrawerFooter

उदाहरण

स्क्रॉल करने योग्य कंटेंट

कंटेंट स्क्रॉल होने के दौरान एक्शन को दिखाई देते रखें.

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

साइड

drawer की साइड सेट करने के लिए direction प्रॉप का उपयोग करें. उपलब्ध विकल्प top, right, bottom, और left हैं.

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

रिस्पॉन्सिव डायलॉग

आप एक रिस्पॉन्सिव डायलॉग बनाने के लिए Dialog और Drawer कंपोनेंट को जोड़ सकते हैं. यह डेस्कटॉप पर Dialog कंपोनेंट और मोबाइल पर Drawer रेंडर करता है.

"use client"

import * as React from "react"

RTL

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

"use client"

import * as React from "react"

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

ड्रॉअर WAI-ARIA Dialog (Modal) पैटर्न का पालन करता है: Vaul Radix Dialog प्रिमिटिव पर बना है, इसलिए पैनल role="dialog" और aria-modal के साथ रेंडर होता है, खुले रहने पर फ़ोकस ट्रैप करता है, और DrawerTitle / DrawerDescription से लेबल/वर्णित होता है। खींचकर बंद करना सिर्फ़ पॉइंटर के लिए है — कीबोर्ड उपयोगकर्ता Escape या DrawerClose बटन से बंद करते हैं, इसलिए हमेशा एक शामिल करें।

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

कुंजीक्रिया
Space / Enterफ़ोकस किए गए ट्रिगर से ड्रॉअर खोलें
Tab / Shift + Tabड्रॉअर कंटेंट के बीच फ़ोकस घुमाएँ (फ़ोकस ट्रैप)
Escapeड्रॉअर बंद करें और फ़ोकस ट्रिगर पर लौटाएँ

API रेफ़रेंस

पूरे API रेफ़रेंस के लिए Vaul डॉक्युमेंटेशन देखें.