Dialog

An animated dialog component powered by Framer Motion, offering smooth transitions and interactive visual effects for modal windows

Installation

npm install vaul
drawer.tsx
`use client`
import React, {
createContext,
useContext,
useState,
useEffect,
ReactNode,
} from 'react'
import { Drawer as VaulHeader } from 'vaul'
interface DrawerContextProps {
open: boolean
setOpen: (open: boolean) => void
}
const DrawerContext = createContext<DrawerContextProps | undefined>(undefined)
const useSidebarDrawer = () => {
const context = useContext(DrawerContext)
if (!context) {
throw new Error('useDrawer must be used within a DrawerProvider')
}
return context
}
interface DrawerSidebarProps {
children: ReactNode
open?: boolean
setOpen?: (open: boolean) => void
drawerBtn?:any | null
}
export function HeaderDrawer({
children,
open: controlledOpen,
setOpen: controlledSetOpen,
drawerBtn
}: DrawerSidebarProps) {
const [internalOpen, setInternalOpen] = useState(false)
const open = controlledOpen !== undefined ? controlledOpen : internalOpen
const setOpen =
controlledSetOpen !== undefined ? controlledSetOpen : setInternalOpen
const [isDesktop, setIsDesktop] = useState(false)
useEffect(() => {
const mediaQuery = window.matchMedia('(min-width: 768px)')
const handleMediaChange = (event: MediaQueryListEvent) => {
setIsDesktop(event.matches)
}
setIsDesktop(mediaQuery.matches)
mediaQuery.addEventListener('change', handleMediaChange)
return () => {
mediaQuery.removeEventListener('change', handleMediaChange)
}
}, [])
console.log(drawerBtn);
return (
<DrawerContext.Provider value={{ open, setOpen }}>
<>
<VaulHeader.Root
open={open}
direction="top"
onOpenChange={setOpen}
dismissible={isDesktop ? false : true}
>
{drawerBtn &&
<VaulHeader.Trigger asChild>
{drawerBtn()}
</VaulHeader.Trigger>
}
<VaulHeader.Portal>
<VaulHeader.Overlay className="fixed inset-0 dark:bg-black/40 bg-white/50 backdrop-blur-sm z-50 " />
<VaulHeader.Content className="dark:bg-gray-900 bg-white border-b z-50 w-full h-fit py-3 fixed top-0 left-0">
{children}
</VaulHeader.Content>
</VaulHeader.Portal>
</VaulHeader.Root>
</>
</DrawerContext.Provider>
)
}
export function DrawerContent({ children }: { children: ReactNode }) {
return <>{children}</>
}

you can use state or default button to control the dialog

const [sidebarOpen, setSidebarOpen] = useState(false)
return (
<>
<HeaderDrawer
open={headerOpen}
setOpen={setHeaderOpen}
drawerBtn={()=> { return <button><MenuIcon/></button>
}}>
<DrawerContent>
</DrawerContent>
</HeaderDrawer>
)

Props

PropTypeDescription
openbooleanThe content to be displayed within the AuroraBackground component.
setOpenbooleanthis is an function to close and open the drawer
drawerBtnfunctionthis is an function for default button, when you don't to use state then you can use drawerBtn