21 lines
7.8 KiB
JSON
21 lines
7.8 KiB
JSON
{
|
|
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
"name": "radix-sheet",
|
|
"type": "registry:ui",
|
|
"title": "Radix Sheet",
|
|
"description": "Extends the Dialog component to display content that complements the main content of the screen.",
|
|
"dependencies": [
|
|
"motion",
|
|
"class-variance-authority",
|
|
"lucide-react",
|
|
"radix-ui"
|
|
],
|
|
"files": [
|
|
{
|
|
"path": "registry/radix/sheet/index.tsx",
|
|
"content": "'use client';\n\nimport * as React from 'react';\nimport { Dialog as SheetPrimitive } from 'radix-ui';\nimport {\n AnimatePresence,\n motion,\n type HTMLMotionProps,\n type Transition,\n} from 'motion/react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\n\nimport { cn } from '@/lib/utils';\n\ntype SheetContextType = {\n isOpen: boolean;\n};\n\nconst SheetContext = React.createContext<SheetContextType | undefined>(\n undefined,\n);\n\nconst useSheet = (): SheetContextType => {\n const context = React.useContext(SheetContext);\n if (!context) {\n throw new Error('useSheet must be used within a Sheet');\n }\n return context;\n};\n\ntype SheetProps = React.ComponentProps<typeof SheetPrimitive.Root>;\n\nfunction Sheet({ children, ...props }: SheetProps) {\n const [isOpen, setIsOpen] = React.useState(\n props?.open ?? props?.defaultOpen ?? false,\n );\n\n React.useEffect(() => {\n if (props?.open !== undefined) setIsOpen(props.open);\n }, [props?.open]);\n\n const handleOpenChange = React.useCallback(\n (open: boolean) => {\n setIsOpen(open);\n props.onOpenChange?.(open);\n },\n [props],\n );\n\n return (\n <SheetContext.Provider value={{ isOpen }}>\n <SheetPrimitive.Root\n data-slot=\"sheet\"\n {...props}\n onOpenChange={handleOpenChange}\n >\n {children}\n </SheetPrimitive.Root>\n </SheetContext.Provider>\n );\n}\n\ntype SheetTriggerProps = React.ComponentProps<typeof SheetPrimitive.Trigger>;\n\nfunction SheetTrigger(props: SheetTriggerProps) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\ntype SheetCloseProps = React.ComponentProps<typeof SheetPrimitive.Close>;\n\nfunction SheetClose(props: SheetCloseProps) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\ntype SheetPortalProps = React.ComponentProps<typeof SheetPrimitive.Portal>;\n\nfunction SheetPortal(props: SheetPortalProps) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\n}\n\ntype SheetOverlayProps = React.ComponentProps<typeof SheetPrimitive.Overlay>;\n\nfunction SheetOverlay({ className, ...props }: SheetOverlayProps) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-50 bg-black/80', className)}\n {...props}\n />\n );\n}\n\nconst sheetVariants = cva('fixed z-50 gap-4 bg-background p-6 shadow-lg', {\n variants: {\n side: {\n top: 'inset-x-0 top-0 border-b',\n bottom: 'inset-x-0 bottom-0 border-t',\n left: 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',\n right: 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',\n },\n },\n defaultVariants: {\n side: 'right',\n },\n});\n\ntype SheetContentProps = React.ComponentProps<typeof SheetPrimitive.Content> &\n VariantProps<typeof sheetVariants> &\n HTMLMotionProps<'div'> & {\n transition?: Transition;\n overlay?: boolean;\n };\n\nfunction SheetContent({\n side = 'right',\n className,\n transition = { type: 'spring', stiffness: 150, damping: 25 },\n overlay = true,\n children,\n ...props\n}: SheetContentProps) {\n const { isOpen } = useSheet();\n\n return (\n <AnimatePresence>\n {isOpen && (\n <SheetPortal forceMount data-slot=\"sheet-portal\">\n {overlay && (\n <SheetOverlay asChild forceMount>\n <motion.div\n key=\"sheet-overlay\"\n data-slot=\"sheet-overlay\"\n initial={{ opacity: 0, filter: 'blur(4px)' }}\n animate={{ opacity: 1, filter: 'blur(0px)' }}\n exit={{ opacity: 0, filter: 'blur(4px)' }}\n transition={{ duration: 0.2, ease: 'easeInOut' }}\n />\n </SheetOverlay>\n )}\n <SheetPrimitive.Content asChild forceMount {...props}>\n <motion.div\n key=\"sheet-content\"\n data-slot=\"sheet-content\"\n initial={\n side === 'right'\n ? { x: '100%', opacity: 0 }\n : side === 'left'\n ? { x: '-100%', opacity: 0 }\n : side === 'top'\n ? { y: '-100%', opacity: 0 }\n : { y: '100%', opacity: 0 }\n }\n animate={{ x: 0, y: 0, opacity: 1 }}\n exit={\n side === 'right'\n ? { x: '100%', opacity: 0 }\n : side === 'left'\n ? { x: '-100%', opacity: 0 }\n : side === 'top'\n ? { y: '-100%', opacity: 0 }\n : { y: '100%', opacity: 0 }\n }\n transition={transition}\n className={cn(sheetVariants({ side }), className)}\n {...props}\n >\n {children}\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\"\n >\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </motion.div>\n </SheetPrimitive.Content>\n </SheetPortal>\n )}\n </AnimatePresence>\n );\n}\n\ntype SheetHeaderProps = React.ComponentProps<'div'>;\n\nfunction SheetHeader({ className, ...props }: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\n 'flex flex-col space-y-2 text-center sm:text-left',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SheetFooterProps = React.ComponentProps<'div'>;\n\nfunction SheetFooter({ className, ...props }: SheetFooterProps) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n className,\n )}\n {...props}\n />\n );\n}\n\ntype SheetTitleProps = React.ComponentProps<typeof SheetPrimitive.Title>;\n\nfunction SheetTitle({ className, ...props }: SheetTitleProps) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('text-lg font-semibold text-foreground', className)}\n {...props}\n />\n );\n}\n\ntype SheetDescriptionProps = React.ComponentProps<\n typeof SheetPrimitive.Description\n>;\n\nfunction SheetDescription({ className, ...props }: SheetDescriptionProps) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n );\n}\n\nexport {\n useSheet,\n Sheet,\n SheetPortal,\n SheetOverlay,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n type SheetProps,\n type SheetPortalProps,\n type SheetOverlayProps,\n type SheetTriggerProps,\n type SheetCloseProps,\n type SheetContentProps,\n type SheetHeaderProps,\n type SheetFooterProps,\n type SheetTitleProps,\n type SheetDescriptionProps,\n};\n",
|
|
"type": "registry:ui",
|
|
"target": "components/animate-ui/radix/sheet.tsx"
|
|
}
|
|
]
|
|
} |