@manhphi1309/drawer
v0.2.23
Published
A customizable and accessible drawer component built on top of `vaul` for the shadcn-custom monorepo.
Readme
@manhphi1309/drawer
A customizable and accessible drawer component built on top of vaul for the shadcn-custom monorepo.
Subcomponents
This package exports the following subcomponents:
DrawerDrawerPortalDrawerOverlayDrawerTriggerDrawerCloseDrawerContentDrawerHeaderDrawerFooterDrawerTitleDrawerDescriptionuseDrawerPanel(Hook)
Dependencies
vaul(Underlying drawer primitive)@manhphi1309/utils(For styling and merging class names)
Installation
npm install @manhphi1309/drawerUsage Example
import { Button } from "@manhphi1309/button"
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@manhphi1309/drawer"
export default function App() {
return (
<Drawer>
<DrawerTrigger asChild>
<Button variant="outline">Open Drawer</Button>
</DrawerTrigger>
<DrawerContent>
<div className="mx-auto w-full max-w-sm">
<DrawerHeader>
<DrawerTitle>Action Required</DrawerTitle>
<DrawerDescription>
Please confirm your action below.
</DrawerDescription>
</DrawerHeader>
<div className="p-4">
<p>Are you sure you want to proceed?</p>
</div>
<DrawerFooter>
<Button>Confirm</Button>
<DrawerClose asChild>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</div>
</DrawerContent>
</Drawer>
)
}Multi-Step Wizard Example
The drawer has built-in support for a multi-step sliding wizard with lazy loading. You can control it manually from the parent, or let it manage its own state internally using the useDrawerPanel hook.
import { Button } from "@manhphi1309/button"
import {
Drawer,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
useDrawerPanel,
} from "@manhphi1309/drawer"
function PanelOne() {
const { nextPanel } = useDrawerPanel()
return (
<div className="p-4 flex flex-col gap-4 h-full">
<DrawerHeader className="px-0">
<DrawerTitle>Step 1</DrawerTitle>
</DrawerHeader>
<div className="mt-auto">
<Button onClick={nextPanel}>Next Step</Button>
</div>
</div>
)
}
function PanelTwo() {
const { prevPanel } = useDrawerPanel()
return (
<div className="p-4 flex flex-col gap-4 h-full">
<DrawerHeader className="px-0">
<DrawerTitle>Step 2</DrawerTitle>
</DrawerHeader>
<div className="mt-auto">
<Button variant="outline" onClick={prevPanel}>
Go Back
</Button>
</div>
</div>
)
}
export default function WizardApp() {
return (
<Drawer>
<DrawerTrigger asChild>
<Button>Open Wizard</Button>
</DrawerTrigger>
<DrawerContent panels={[<PanelOne key="1" />, <PanelTwo key="2" />]} />
</Drawer>
)
}Props
The Drawer component natively wraps and accepts all props provided by the vaul library.
Drawer
| Prop | Type | Description |
| :------------- | :--------------------------------------- | :----------------------------------------------------------------------------- |
| direction | "top" \| "bottom" \| "left" \| "right" | Direction the drawer slides in from. |
| open | boolean | Controlled open state. |
| onOpenChange | (open: boolean) => void | Callback when the open state changes. |
| snapPoints | number[] \| string[] | Array of numbers from 0 to 1 or string values representing heights to snap to. |
DrawerContent
| Prop | Type | Description |
| :------------------- | :------------------------ | :--------------------------------------------------------------------------- |
| showHandle | boolean | Default true. Whether to display the drag handle at the top of the drawer. |
| panels | React.ReactNode[] | An array of panel components to render in the sliding track. |
| activePanelIndex | number | (Controlled mode) The index of the currently active panel. |
| onPanelIndexChange | (index: number) => void | (Controlled mode) Callback fired when a navigation hook triggers a slide. |
For a complete and advanced list of properties (like fadeFromIndex, activeSnapPoint, etc.), please refer to the official Vaul documentation.
