| 1 | "use client"
|
| 2 |
|
| 3 | import * as React from "react"
|
| 4 | import { XIcon } from "lucide-react"
|
| 5 | import { Dialog as SheetPrimitive } from "radix-ui"
|
| 6 |
|
| 7 | import { cn } from "@/lib/utils"
|
| 8 |
|
| 9 | function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
|
| 10 | return <SheetPrimitive.Root data-slot="sheet" {...props} />
|
| 11 | }
|
| 12 |
|
| 13 | function SheetTrigger({
|
| 14 | ...props
|
| 15 | }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
| 16 | return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
|
| 17 | }
|
| 18 |
|
| 19 | function SheetClose({
|
| 20 | ...props
|
| 21 | }: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
| 22 | return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
|
| 23 | }
|
| 24 |
|
| 25 | function SheetPortal({
|
| 26 | ...props
|
| 27 | }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
|
| 28 | return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
|
| 29 | }
|
| 30 |
|
| 31 | function SheetOverlay({
|
| 32 | className,
|
| 33 | ...props
|
| 34 | }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
|
| 35 | return (
|
| 36 | <SheetPrimitive.Overlay
|
| 37 | data-slot="sheet-overlay"
|
| 38 | className={cn(
|
| 39 | "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
| 40 | className
|
| 41 | )}
|
| 42 | {...props}
|
| 43 | />
|
| 44 | )
|
| 45 | }
|
| 46 |
|
| 47 | function SheetContent({
|
| 48 | className,
|
| 49 | children,
|
| 50 | side = "right",
|
| 51 | showCloseButton = true,
|
| 52 | ...props
|
| 53 | }: React.ComponentProps<typeof SheetPrimitive.Content> & {
|
| 54 | side?: "top" | "right" | "bottom" | "left"
|
| 55 | showCloseButton?: boolean
|
| 56 | }) {
|
| 57 | return (
|
| 58 | <SheetPortal>
|
| 59 | <SheetOverlay />
|
| 60 | <SheetPrimitive.Content
|
| 61 | data-slot="sheet-content"
|
| 62 | className={cn(
|
| 63 | "fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500",
|
| 64 | side === "right" &&
|
| 65 | "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
|
| 66 | side === "left" &&
|
| 67 | "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
| 68 | side === "top" &&
|
| 69 | "inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
|
| 70 | side === "bottom" &&
|
| 71 | "inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
|
| 72 | className
|
| 73 | )}
|
| 74 | {...props}
|
| 75 | >
|
| 76 | {children}
|
| 77 | {showCloseButton && (
|
| 78 | <SheetPrimitive.Close className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary">
|
| 79 | <XIcon className="size-4" />
|
| 80 | <span className="sr-only">Close</span>
|
| 81 | </SheetPrimitive.Close>
|
| 82 | )}
|
| 83 | </SheetPrimitive.Content>
|
| 84 | </SheetPortal>
|
| 85 | )
|
| 86 | }
|
| 87 |
|
| 88 | function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
|
| 89 | return (
|
| 90 | <div
|
| 91 | data-slot="sheet-header"
|
| 92 | className={cn("flex flex-col gap-1.5 p-4", className)}
|
| 93 | {...props}
|
| 94 | />
|
| 95 | )
|
| 96 | }
|
| 97 |
|
| 98 | function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
| 99 | return (
|
| 100 | <div
|
| 101 | data-slot="sheet-footer"
|
| 102 | className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
| 103 | {...props}
|
| 104 | />
|
| 105 | )
|
| 106 | }
|
| 107 |
|
| 108 | function SheetTitle({
|
| 109 | className,
|
| 110 | ...props
|
| 111 | }: React.ComponentProps<typeof SheetPrimitive.Title>) {
|
| 112 | return (
|
| 113 | <SheetPrimitive.Title
|
| 114 | data-slot="sheet-title"
|
| 115 | className={cn("font-semibold text-foreground", className)}
|
| 116 | {...props}
|
| 117 | />
|
| 118 | )
|
| 119 | }
|
| 120 |
|
| 121 | function SheetDescription({
|
| 122 | className,
|
| 123 | ...props
|
| 124 | }: React.ComponentProps<typeof SheetPrimitive.Description>) {
|
| 125 | return (
|
| 126 | <SheetPrimitive.Description
|
| 127 | data-slot="sheet-description"
|
| 128 | className={cn("text-sm text-muted-foreground", className)}
|
| 129 | {...props}
|
| 130 | />
|
| 131 | )
|
| 132 | }
|
| 133 |
|
| 134 | export {
|
| 135 | Sheet,
|
| 136 | SheetTrigger,
|
| 137 | SheetClose,
|
| 138 | SheetContent,
|
| 139 | SheetHeader,
|
| 140 | SheetFooter,
|
| 141 | SheetTitle,
|
| 142 | SheetDescription,
|
| 143 | }
|