| 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({ ...props }: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
|
| 14 | return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
|
| 15 | }
|
| 16 |
|
| 17 | function SheetClose({ ...props }: React.ComponentProps<typeof SheetPrimitive.Close>) {
|
| 18 | return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
|
| 19 | }
|
| 20 |
|
| 21 | function SheetPortal({ ...props }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
|
| 22 | return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
|
| 23 | }
|
| 24 |
|
| 25 | function SheetOverlay({
|
| 26 | className,
|
| 27 | ...props
|
| 28 | }: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
|
| 29 | return (
|
| 30 | <SheetPrimitive.Overlay
|
| 31 | data-slot="sheet-overlay"
|
| 32 | className={cn(
|
| 33 | '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',
|
| 34 | className,
|
| 35 | )}
|
| 36 | {...props}
|
| 37 | />
|
| 38 | );
|
| 39 | }
|
| 40 |
|
| 41 | function SheetContent({
|
| 42 | className,
|
| 43 | children,
|
| 44 | side = 'right',
|
| 45 | showCloseButton = true,
|
| 46 | ...props
|
| 47 | }: React.ComponentProps<typeof SheetPrimitive.Content> & {
|
| 48 | side?: 'top' | 'right' | 'bottom' | 'left';
|
| 49 | showCloseButton?: boolean;
|
| 50 | }) {
|
| 51 | return (
|
| 52 | <SheetPortal>
|
| 53 | <SheetOverlay />
|
| 54 | <SheetPrimitive.Content
|
| 55 | data-slot="sheet-content"
|
| 56 | className={cn(
|
| 57 | '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',
|
| 58 | side === 'right' &&
|
| 59 | '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',
|
| 60 | side === 'left' &&
|
| 61 | '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',
|
| 62 | side === 'top' &&
|
| 63 | 'inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
|
| 64 | side === 'bottom' &&
|
| 65 | 'inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
|
| 66 | className,
|
| 67 | )}
|
| 68 | {...props}
|
| 69 | >
|
| 70 | {children}
|
| 71 | {showCloseButton && (
|
| 72 | <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">
|
| 73 | <XIcon className="size-4" />
|
| 74 | <span className="sr-only">Close</span>
|
| 75 | </SheetPrimitive.Close>
|
| 76 | )}
|
| 77 | </SheetPrimitive.Content>
|
| 78 | </SheetPortal>
|
| 79 | );
|
| 80 | }
|
| 81 |
|
| 82 | function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
| 83 | return (
|
| 84 | <div
|
| 85 | data-slot="sheet-header"
|
| 86 | className={cn('flex flex-col gap-1.5 p-4', className)}
|
| 87 | {...props}
|
| 88 | />
|
| 89 | );
|
| 90 | }
|
| 91 |
|
| 92 | function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
| 93 | return (
|
| 94 | <div
|
| 95 | data-slot="sheet-footer"
|
| 96 | className={cn('mt-auto flex flex-col gap-2 p-4', className)}
|
| 97 | {...props}
|
| 98 | />
|
| 99 | );
|
| 100 | }
|
| 101 |
|
| 102 | function SheetTitle({ className, ...props }: React.ComponentProps<typeof SheetPrimitive.Title>) {
|
| 103 | return (
|
| 104 | <SheetPrimitive.Title
|
| 105 | data-slot="sheet-title"
|
| 106 | className={cn('font-semibold text-foreground', className)}
|
| 107 | {...props}
|
| 108 | />
|
| 109 | );
|
| 110 | }
|
| 111 |
|
| 112 | function SheetDescription({
|
| 113 | className,
|
| 114 | ...props
|
| 115 | }: React.ComponentProps<typeof SheetPrimitive.Description>) {
|
| 116 | return (
|
| 117 | <SheetPrimitive.Description
|
| 118 | data-slot="sheet-description"
|
| 119 | className={cn('text-sm text-muted-foreground', className)}
|
| 120 | {...props}
|
| 121 | />
|
| 122 | );
|
| 123 | }
|
| 124 |
|
| 125 | export {
|
| 126 | Sheet,
|
| 127 | SheetTrigger,
|
| 128 | SheetClose,
|
| 129 | SheetContent,
|
| 130 | SheetHeader,
|
| 131 | SheetFooter,
|
| 132 | SheetTitle,
|
| 133 | SheetDescription,
|
| 134 | };
|