Drawer
Drawer is a panel component displayed as an overlay at the edges of the screen.
Usage#
import { Drawer } from '@primereact/ui/drawer';<Drawer>
<Drawer.Trigger />
<Drawer.Backdrop />
<Drawer.Portal>
<Drawer.Header>
<Drawer.Title />
<Drawer.Close />
</Drawer.Header>
<Drawer.Content />
<Drawer.Footer />
</Drawer.Portal>
</Drawer>Examples#
Position#
The position of the drawer can be customized with the position property. The available values are left, right, top and bottom.
'use client';
import { ArrowDown } from '@primeicons/react/arrow-down';
import { ArrowLeft } from '@primeicons/react/arrow-left';
import { ArrowRight } from '@primeicons/react/arrow-right';
import { ArrowUp } from '@primeicons/react/arrow-up';
import { Times } from '@primeicons/react/times';
import { DrawerRootChangeEvent } from '@primereact/types/shared/drawer';
import { Button } from '@primereact/ui/button';
import { Drawer } from '@primereact/ui/drawer';
import * as React from 'react';
export default function PositionDemo() {
const [visibleLeft, setVisibleLeft] = React.useState<boolean>(false);
const [visibleRight, setVisibleRight] = React.useState<boolean>(false);
const [visibleTop, setVisibleTop] = React.useState<boolean>(false);
const [visibleBottom, setVisibleBottom] = React.useState<boolean>(false);
return (
<div>
<div className="flex gap-2 justify-center">
<Button iconOnly onClick={() => setVisibleLeft(true)}>
<ArrowRight />
</Button>
<Button iconOnly onClick={() => setVisibleRight(true)}>
<ArrowLeft />
</Button>
<Button iconOnly onClick={() => setVisibleTop(true)}>
<ArrowDown />
</Button>
<Button iconOnly onClick={() => setVisibleBottom(true)}>
<ArrowUp />
</Button>
</div>
<Drawer.Root open={visibleLeft} onOpenChange={(e: DrawerRootChangeEvent) => setVisibleLeft(e.value as boolean)}>
<Drawer.Backdrop />
<Drawer.Portal className="w-full md:w-80">
<Drawer.Header>
<Drawer.Title>Left Drawer</Drawer.Title>
<Drawer.Close>
<Times />
</Drawer.Close>
</Drawer.Header>
<Drawer.Content>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
<Drawer.Root position="right" open={visibleRight} onOpenChange={(e: DrawerRootChangeEvent) => setVisibleRight(e.value as boolean)}>
<Drawer.Backdrop />
<Drawer.Portal className="w-full md:w-80">
<Drawer.Header>
<Drawer.Title>Right Drawer</Drawer.Title>
<Drawer.Close>
<Times />
</Drawer.Close>
</Drawer.Header>
<Drawer.Content>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
<Drawer.Root
position="top"
open={visibleTop}
onOpenChange={(e: DrawerRootChangeEvent) => setVisibleTop(e.value as boolean)}
style={{ height: 'auto' }}
>
<Drawer.Backdrop />
<Drawer.Portal>
<Drawer.Header>
<Drawer.Title>Top Drawer</Drawer.Title>
<Drawer.Close>
<Times />
</Drawer.Close>
</Drawer.Header>
<Drawer.Content>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
<Drawer.Root
position="bottom"
open={visibleBottom}
onOpenChange={(e: DrawerRootChangeEvent) => setVisibleBottom(e.value as boolean)}
style={{ height: 'auto' }}
>
<Drawer.Backdrop />
<Drawer.Portal>
<Drawer.Header>
<Drawer.Title>Bottom Drawer</Drawer.Title>
<Drawer.Close>
<Times />
</Drawer.Close>
</Drawer.Header>
<Drawer.Content>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
</div>
);
}
Full Screen#
The full screen mode is enabled when position property is set as full.
import { Times } from '@primeicons/react/times';
import { WindowMaximize } from '@primeicons/react/window-maximize';
import { Drawer } from '@primereact/ui/drawer';
export default function FullScreenDemo() {
return (
<div className="flex justify-center">
<Drawer.Root position="full">
<Drawer.Trigger iconOnly>
<WindowMaximize />
</Drawer.Trigger>
<Drawer.Backdrop />
<Drawer.Portal>
<Drawer.Header>
<Drawer.Title>Drawer</Drawer.Title>
<Drawer.Close>
<Times />
</Drawer.Close>
</Drawer.Header>
<Drawer.Content>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
</div>
);
}
Responsive#
The responsive mode can be enabled by adding className or style to the Drawer.Portal component.
import { Check } from '@primeicons/react/check';
import { Times } from '@primeicons/react/times';
import { Button } from '@primereact/ui/button';
import { Checkbox } from '@primereact/ui/checkbox';
import { Drawer } from '@primereact/ui/drawer';
import { InputText } from '@primereact/ui/inputtext';
import { Label } from '@primereact/ui/label';
import { Password } from '@primereact/ui/password';
export default function ResponsiveDemo() {
return (
<div className="flex justify-center">
<Drawer.Root>
<Drawer.Trigger>Log in</Drawer.Trigger>
<Drawer.Backdrop />
<Drawer.Portal className="w-full sm:w-96 md:w-md lg:w-120">
<Drawer.Header>
<Drawer.Title>Responsive Drawer</Drawer.Title>
<Drawer.Close>
<Times />
</Drawer.Close>
</Drawer.Header>
<Drawer.Content>
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Label htmlFor="email" className="font-medium text-sm">
Email
</Label>
<InputText id="email" placeholder="Enter your email" className="w-full" />
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="password" className="font-medium text-sm">
Password
</Label>
<Password inputId="password" placeholder="Enter your password" className="w-full" toggleMask />
</div>
<div className="flex items-center gap-2">
<Checkbox.Root inputId="remember" value="remember">
<Checkbox.Box>
<Checkbox.Indicator className="data-unchecked:hidden!" as={Check} />
</Checkbox.Box>
</Checkbox.Root>
<Label htmlFor="remember" className="text-sm">
Remember me
</Label>
</div>
<Button className="w-full">Sign In</Button>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
</div>
);
}
Accessibility#
Screen Reader#
Drawer component uses complementary role by default, since any attribute is passed to the root element aria role can be changed depending on your use case and additional attributes like aria-labelledby can be added. In addition aria-modal is added since focus is kept within the drawer when opened.
Trigger element also has aria-expanded and aria-controls to be handled explicitly.
Overlay Keyboard Support#
| Key | Function |
|---|---|
tab | Moves focus to the next the focusable element within the drawer. |
shift + tab | Moves focus to the previous the focusable element within the drawer. |
escape | Closes the drawer. |
Close Button Keyboard Support#
| Key | Function |
|---|---|
enter | Closes the drawer. |
space | Closes the drawer. |