Drawer
Drawer
Section titled “Drawer”Drawers are side panels that slide in from the screen edges, commonly used for navigation menus.
import { Drawer } from '@truongdq01/ui';
<Drawer open={isOpen} onClose={() => setIsOpen(false)}> <Text>Drawer content</Text></Drawer>;| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Required. Drawer open state |
onClose | () => void | — | Required. Callback when closing |
anchor | "left" | "right" | "top" | "bottom" | "left" | Slide-in direction |
children | ReactNode | — | Drawer content |
Anchors
Section titled “Anchors”Left Drawer (Default)
Section titled “Left Drawer (Default)”<Drawer open={isOpen} onClose={() => setIsOpen(false)}> <Text>Navigation Menu</Text></Drawer>Right Drawer
Section titled “Right Drawer”<Drawer open={isOpen} onClose={() => setIsOpen(false)} anchor="right"> <Text>Settings Panel</Text></Drawer>Top Drawer
Section titled “Top Drawer”<Drawer open={isOpen} onClose={() => setIsOpen(false)} anchor="top"> <Text>Quick Actions</Text></Drawer>Bottom Drawer (Bottom Sheet Alternative)
Section titled “Bottom Drawer (Bottom Sheet Alternative)”<Drawer open={isOpen} onClose={() => setIsOpen(false)} anchor="bottom"> <Text>Additional Options</Text></Drawer>Examples
Section titled “Examples”Navigation Drawer
Section titled “Navigation Drawer”function AppDrawer() { const [open, setOpen] = useState(false);
return ( <> <Button label="Open Menu" onPress={() => setOpen(true)} />
<Drawer open={open} onClose={() => setOpen(false)} anchor="left"> <View style={{ padding: 16 }}> <Typography variant="h6" gutterBottom> Navigation </Typography>
<Button label="Home" variant="ghost" onPress={navigateHome} /> <Button label="Profile" variant="ghost" onPress={navigateProfile} /> <Button label="Settings" variant="ghost" onPress={navigateSettings} />
<Divider />
<Button label="Logout" variant="destructive" onPress={handleLogout} /> </View> </Drawer> </> );}Filter Drawer
Section titled “Filter Drawer”function FilterDrawer() { const [open, setOpen] = useState(false); const [filters, setFilters] = useState({});
return ( <> <Button label="Filters" onPress={() => setOpen(true)} />
<Drawer open={open} onClose={() => setOpen(false)} anchor="right"> <View style={{ padding: 16, width: 300 }}> <Typography variant="h6" gutterBottom> Filters </Typography>
<Checkbox label="In Stock" checked={filters.inStock} onChange={(v) => setFilters({ ...filters, inStock: v })} />
<Slider label="Price Range" value={filters.price} onChange={(v) => setFilters({ ...filters, price: v })} />
<Button label="Apply Filters" onPress={() => { applyFilters(filters); setOpen(false); }} /> </View> </Drawer> </> );}Settings Drawer
Section titled “Settings Drawer”<Drawer open={settingsOpen} onClose={() => setSettingsOpen(false)} anchor="right"> <View style={{ padding: 16, width: 280 }}> <Typography variant="h6" gutterBottom> Settings </Typography>
<Switch label="Dark Mode" value={darkMode} onValueChange={setDarkMode} /> <Switch label="Notifications" value={notifications} onValueChange={setNotifications} />
<Divider style={{ marginVertical: 16 }} />
<Button label="Save" onPress={() => setSettingsOpen(false)} /> </View></Drawer>Controlled Usage
Section titled “Controlled Usage”function ControlledDrawer() { const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false);
return ( <> <Button label="Open Drawer" onPress={handleOpen} /> <Drawer open={open} onClose={handleClose}> <Text>Drawer content</Text> </Drawer> </> );}Drawer with Backdrop Click
Section titled “Drawer with Backdrop Click”The drawer automatically closes when clicking the backdrop overlay:
<Drawer open={isOpen} onClose={() => setIsOpen(false)}> {/* Clicking outside closes the drawer */} <Text>Content</Text></Drawer>Responsive Drawer
Section titled “Responsive Drawer”function ResponsiveDrawer() { const { width } = useWindowDimensions(); const isDesktop = width >= 768; const [open, setOpen] = useState(false);
return ( <> {!isDesktop && <Button label="Menu" onPress={() => setOpen(true)} />}
<Drawer open={isDesktop || open} onClose={() => setOpen(false)} anchor="left" > <NavigationMenu /> </Drawer> </> );}Best Practices
Section titled “Best Practices”- Use left drawer for primary navigation
- Use right drawer for secondary panels (settings, filters)
- Close drawer after navigation action
- Provide clear close mechanism (backdrop click or close button)
❌ Don’t
Section titled “❌ Don’t”- Don’t use for critical content that should always be visible
- Don’t nest drawers
- Don’t make drawers too wide (280-320px is ideal)
- Don’t block drawer closure
Animation Details
Section titled “Animation Details”- Slide Animation: Spring physics for natural feel
- Backdrop Fade: Smooth opacity transition
- Duration: ~200ms
- Easing: Spring configuration from tokens
Accessibility
Section titled “Accessibility”<Drawer open={isOpen} onClose={() => setIsOpen(false)} accessibilityLabel="Navigation menu" accessibilityRole="menu"> <Text>Navigation</Text></Drawer>Related Components
Section titled “Related Components”Modal- Centered overlay dialogsBottomSheet- Mobile-optimized bottom sheetsDialog- Alert and confirmation dialogsMenu- Dropdown menus