Skip to main content

Overview

Drawer (also known as Navigation Drawer) provides access to destinations in your app or website. It slides in from the side of the screen and can be temporary (overlaying content) or permanent (alongside content).

Installation

npm install @naturacosmeticos/natds-web

Import

import { 
  Drawer,
  DrawerHeader,
  DrawerBody,
  DrawerFooter 
} from '@naturacosmeticos/natds-web';

Props

Drawer

Inherits all props from Material-UI’s Drawer component.
anchor
'left' | 'right' | 'top' | 'bottom'
Side from which the drawer will appear. Defaults to 'left'.
open
boolean
required
If true, the drawer is open.
onClose
function
Callback fired when the component requests to be closed.
variant
'permanent' | 'persistent' | 'temporary'
The variant to use. Defaults to 'temporary'.
  • temporary: Overlays content and includes a backdrop
  • persistent: Pushes content and stays open
  • permanent: Always visible, typically on larger screens
children
ReactNode
The content of the drawer, typically DrawerHeader, DrawerBody, and DrawerFooter.
classes
object
Override or extend the styles applied to the component.

DrawerHeader

primary
ReactNode
Primary text to display, typically a user name or title.
secondary
ReactNode
Secondary text to display, typically additional information.
avatarSrc
string
Source URL for the avatar image.
avatarChildren
ReactNode
Content for the avatar, such as initials or an icon.
avatarComponent
React.ElementType
The component used for the avatar node. Defaults to Avatar.
component
React.ElementType
The component used for the root node. Defaults to "div".
children
ReactNode
Custom content for the header.

DrawerBody

children
ReactNode
The content of the drawer body.
component
React.ElementType
The component used for the root node. Defaults to "div".
scrollComponent
React.ElementType
The component used for the scroll node. Defaults to "div".

DrawerFooter

children
ReactNode
The content of the drawer footer.
component
React.ElementType
The component used for the root node. Defaults to "div".

Usage

Basic Drawer

import { 
  Drawer,
  DrawerHeader,
  DrawerBody,
  DrawerFooter,
  Button
} from '@naturacosmeticos/natds-web';
import { useState } from 'react';

function BasicDrawer() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Open Drawer</Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        anchor="left"
      >
        <div style={{ width: 256 }}>
          <DrawerHeader
            primary="User Name"
            secondary="[email protected]"
          />
          <DrawerBody>
            <p>Drawer content goes here</p>
          </DrawerBody>
          <DrawerFooter>
            <Button onClick={() => setOpen(false)}>Close</Button>
          </DrawerFooter>
        </div>
      </Drawer>
    </>
  );
}

Complete Drawer Composition

import { 
  Drawer,
  DrawerHeader,
  DrawerBody,
  DrawerFooter,
  DrawerMenu,
  DrawerMenuItem,
  Button,
  IconButton,
  Icon
} from '@naturacosmeticos/natds-web';
import { useState } from 'react';

function CompleteDrawer() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <IconButton onClick={() => setOpen(true)}>
        <Icon name="outlined-navigation-menu" />
      </IconButton>
      
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        anchor="left"
        variant="temporary"
      >
        <div style={{
          display: 'flex',
          flexFlow: 'column nowrap',
          height: '100%',
          width: 256
        }}>
          <DrawerHeader
            avatarSrc="/path/to/avatar.jpg"
            primary="John Doe"
            secondary="[email protected]"
          />
          
          <DrawerBody>
            <DrawerMenu>
              <DrawerMenuItem
                icon={<Icon name="outlined-navigation-home" />}
                onClick={() => console.log('Home clicked')}
              >
                Home
              </DrawerMenuItem>
              <DrawerMenuItem
                icon={<Icon name="outlined-social-person" />}
                onClick={() => console.log('Profile clicked')}
              >
                Profile
              </DrawerMenuItem>
              <DrawerMenuItem
                icon={<Icon name="outlined-action-settings" />}
                onClick={() => console.log('Settings clicked')}
              >
                Settings
              </DrawerMenuItem>
            </DrawerMenu>
          </DrawerBody>
          
          <DrawerFooter>
            <Button 
              variant="text" 
              fullWidth
              onClick={() => console.log('Logout')}
            >
              Logout
            </Button>
          </DrawerFooter>
        </div>
      </Drawer>
    </>
  );
}

Temporary Drawer (Default)

Overlays content with a backdrop. Closes when backdrop is clicked.
import { Drawer, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';

function TemporaryDrawer() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Open Menu</Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        variant="temporary"
        anchor="left"
      >
        <div style={{ width: 256, padding: 16 }}>
          <h2>Navigation</h2>
          <p>Menu items here</p>
        </div>
      </Drawer>
    </>
  );
}

Persistent Drawer

Stays open until explicitly closed. Pushes page content.
import { Drawer, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';

function PersistentDrawer() {
  const [open, setOpen] = useState(false);

  return (
    <div style={{ display: 'flex' }}>
      <Drawer
        open={open}
        variant="persistent"
        anchor="left"
      >
        <div style={{ width: 256, padding: 16 }}>
          <h2>Navigation</h2>
          <Button onClick={() => setOpen(false)}>Close</Button>
        </div>
      </Drawer>
      
      <main style={{ flexGrow: 1, padding: 16 }}>
        <Button onClick={() => setOpen(!open)}>
          {open ? 'Close' : 'Open'} Drawer
        </Button>
        <p>Page content</p>
      </main>
    </div>
  );
}

Permanent Drawer

Always visible, typically for desktop layouts.
import { Drawer } from '@naturacosmeticos/natds-web';

function PermanentDrawer() {
  return (
    <div style={{ display: 'flex' }}>
      <Drawer
        open={true}
        variant="permanent"
        anchor="left"
      >
        <div style={{ width: 256, padding: 16 }}>
          <h2>Navigation</h2>
          <nav>
            {/* Navigation items */}
          </nav>
        </div>
      </Drawer>
      
      <main style={{ flexGrow: 1, padding: 16 }}>
        <h1>Main Content</h1>
      </main>
    </div>
  );
}

Right-Side Drawer

import { Drawer, Button } from '@naturacosmeticos/natds-web';
import { useState } from 'react';

function RightDrawer() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>Open Settings</Button>
      <Drawer
        open={open}
        onClose={() => setOpen(false)}
        anchor="right"
      >
        <div style={{ width: 300, padding: 16 }}>
          <h2>Settings</h2>
          {/* Settings content */}
        </div>
      </Drawer>
    </>
  );
}

With Avatar Header

import { 
  Drawer,
  DrawerHeader,
  DrawerBody 
} from '@naturacosmeticos/natds-web';

function DrawerWithAvatar({ open, onClose }) {
  return (
    <Drawer open={open} onClose={onClose} anchor="left">
      <div style={{ width: 256 }}>
        <DrawerHeader
          avatarChildren="JD"
          primary="John Doe"
          secondary="Premium Member"
        />
        <DrawerBody>
          {/* Navigation content */}
        </DrawerBody>
      </div>
    </Drawer>
  );
}

Composition Pattern

The Drawer component is designed to work with its subcomponents:
<Drawer>
  <DrawerHeader />  {/* User info, branding */}
  <DrawerBody />    {/* Main navigation, content */}
  <DrawerFooter />  {/* Actions, settings */}
</Drawer>

Best Practices

  • Use temporary variant for mobile navigation
  • Use permanent variant for desktop side navigation
  • Set appropriate width (typically 256px for navigation drawers)
  • Include a close button or method for temporary drawers
  • Group related navigation items together
  • Consider responsive behavior across screen sizes

Accessibility

  • Drawer automatically manages focus when opened
  • Press ESC to close temporary drawers
  • Include proper ARIA labels for navigation items
  • Ensure keyboard navigation works for all interactive elements
  • Test with screen readers
  • Maintain focus trap within open drawer

Responsive Design

import { Drawer, useMediaQuery, useTheme } from '@naturacosmeticos/natds-web';

function ResponsiveDrawer({ open, onClose, children }) {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

  return (
    <Drawer
      open={open}
      onClose={onClose}
      variant={isMobile ? 'temporary' : 'permanent'}
      anchor="left"
    >
      {children}
    </Drawer>
  );
}

Material-UI Reference

This component is based on Material-UI’s Drawer. For advanced usage, see the Material-UI Drawer documentation.

Build docs developers (and LLMs) love