import * as React from 'react' import { motion } from 'framer-motion' import * as DialogPrimitive from '@radix-ui/react-dialog' import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '@/lib/utils' import { MOTION_FADE, MOTION_DURATION, MOTION_EASE } from '@/lib/motion' import { CloseLine } from './icons-inline' import { getThemeFromDocument } from './theme-from-document' const Drawer = DialogPrimitive.Root const DrawerTrigger = DialogPrimitive.Trigger const DrawerClose = DialogPrimitive.Close const DrawerPortal = DialogPrimitive.Portal const DrawerOverlay = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DrawerOverlay.displayName = DialogPrimitive.Overlay.displayName const drawerVariants = cva( 'fixed z-50 gap-4 bg-bg-base text-text shadow-lg border-border p-6 outline-none flex flex-col', { variants: { side: { top: 'inset-x-0 top-0 border-b', bottom: 'inset-x-0 bottom-0 border-t', left: 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm', right: 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm', }, }, defaultVariants: { side: 'right' }, }, ) const sideOffsetMap = { top: { initial: { y: '-100%' }, animate: { y: 0 }, exit: { y: '-100%' } }, bottom: { initial: { y: '100%' }, animate: { y: 0 }, exit: { y: '100%' } }, left: { initial: { x: '-100%' }, animate: { x: 0 }, exit: { x: '-100%' } }, right: { initial: { x: '100%' }, animate: { x: 0 }, exit: { x: '100%' } }, } as const export interface DrawerContentProps extends React.ComponentPropsWithoutRef, VariantProps { side?: 'top' | 'right' | 'bottom' | 'left' showCloseButton?: boolean /** When provided (e.g. from ThemeStyleProvider), used for portal wrapper */ dataStyle?: string dataTheme?: string } const DrawerContent = React.forwardRef< React.ElementRef, DrawerContentProps >( ( { side = 'right', className, children, showCloseButton = true, dataStyle, dataTheme, ...props }, ref, ) => { const fromDoc = getThemeFromDocument() const dataProps = dataStyle !== undefined ? { 'data-style': dataStyle, 'data-theme': dataTheme ?? fromDoc['data-theme'] ?? '' } : fromDoc const motionProps = sideOffsetMap[side] return (
{children} {showCloseButton && ( Close )}
) }, ) DrawerContent.displayName = DialogPrimitive.Content.displayName const DrawerHeader = React.forwardRef>( ({ className, ...props }, ref) => (
), ) DrawerHeader.displayName = 'DrawerHeader' const DrawerFooter = React.forwardRef>( ({ className, ...props }, ref) => (
), ) DrawerFooter.displayName = 'DrawerFooter' const DrawerTitle = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DrawerTitle.displayName = DialogPrimitive.Title.displayName const DrawerDescription = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )) DrawerDescription.displayName = DialogPrimitive.Description.displayName export type DrawerHeaderProps = React.HTMLAttributes export type DrawerFooterProps = React.HTMLAttributes export { Drawer, DrawerTrigger, DrawerClose, DrawerPortal, DrawerOverlay, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, drawerVariants, }