Skip to content

Drawer

A slide-in panel anchored to an edge of the viewport.

Project details

Review project activity, ownership, and open follow-ups.

<>
<Button label="Open drawer" onClick={() => setIsOpen(true)} />
<Drawer {...args} isOpen={isOpen} onOpenChange={setIsOpen}>
<DrawerContent onClose={() => setIsOpen(false)} />
</Drawer>
</>

Right drawer

Review project activity, ownership, and open follow-ups.

<>
<div style={{display: 'flex', flexWrap: 'wrap', gap: 8}}>
{placements.map(option => (
<Button
key={option.placement}
label={option.label}
onClick={() => setPlacement(option.placement)}
/>
))}
</div>
<Drawer
isOpen={placement != null}
label={`${placements.find(option => option.placement === placement)?.label ?? 'Right'} drawer`}
onOpenChange={nextOpen => {
if (!nextOpen) {
setPlacement(null);
}
}}
placement={activePlacement}>
<DrawerContent
onClose={() => setPlacement(null)}
title={`${placements.find(option => option.placement === activePlacement)?.label ?? 'Right'} drawer`}
/>
</Drawer>
</>

480px drawer

Review project activity, ownership, and open follow-ups.

<>
<div style={{display: 'flex', flexWrap: 'wrap', gap: 8}}>
<Button
label="Open 480px drawer"
onClick={() => setVariant('numeric')}
/>
<Button
label="Open 60vw drawer"
onClick={() => setVariant('string')}
/>
</div>
<Drawer
isOpen={variant != null}
label="Custom size drawer"
onOpenChange={nextOpen => {
if (!nextOpen) {
setVariant(null);
}
}}
placement="end"
size={variant === 'string' ? '60vw' : 480}>
<DrawerContent
onClose={() => setVariant(null)}
title={variant === 'string' ? '60vw drawer' : '480px drawer'}
/>
</Drawer>
</>

Edit profile

Backdrop and Escape dismissal are disabled, so unsaved edits can only be discarded through an explicit action.

<>
<Button label="Edit profile" onClick={() => setIsOpen(true)} />
<Drawer {...args} isOpen={isOpen} onOpenChange={setIsOpen}>
<Layout
content={
<LayoutContent>
<div
style={{display: 'flex', flexDirection: 'column', gap: 16}}>
<Text as="p" color="secondary">
Backdrop and Escape dismissal are disabled, so unsaved edits
can only be discarded through an explicit action.
</Text>
<TextInput
label="Display name"
onChange={() => {}}
value="Ada Lovelace"
/>
</div>
</LayoutContent>
}
footer={
<LayoutFooter
primaryButton={
<Button
label="Save"
onClick={() => setIsOpen(false)}
variant="primary"
/>
}
secondaryButton={
<Button label="Discard" onClick={() => setIsOpen(false)} />
}
/>
}
header={<LayoutHeader title="Edit profile" />}
/>
</Drawer>
</>
<>
<Button
label="Show report"
onClick={() =>
drawer.show(
<Layout
content={
<LayoutContent>
<Text as="p" color="secondary">
The report is ready for review.
</Text>
</LayoutContent>
}
footer={
<LayoutFooter
primaryButton={
<Button
label="Close"
onClick={drawer.hide}
variant="primary"
/>
}
/>
}
header={<LayoutHeader title="Generated report" />}
/>,
)
}
/>
{drawer.element}
</>

Auto focus

<>
<Button label="Open drawer" onClick={() => setIsOpen(true)} />
<Drawer
isOpen={isOpen}
label="Auto focus drawer"
onOpenChange={setIsOpen}
size={400}>
<Layout
content={
<LayoutContent>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 12,
}}>
<button
data-autofocus="true"
style={{alignSelf: 'flex-start'}}
type="button">
Focused action
</button>
<TextInput
label="Notes"
onChange={() => {}}
placeholder="Add notes"
value=""
/>
</div>
</LayoutContent>
}
footer={
<LayoutFooter
primaryButton={
<Button
label="Close"
onClick={() => setIsOpen(false)}
variant="primary"
/>
}
/>
}
header={<LayoutHeader title="Auto focus" />}
/>
</Drawer>
</>

Edit workspace

Manage workspace metadata and defaults.

Setting group 1: Configure access, notifications, and workflow defaults for this workspace.

Setting group 2: Configure access, notifications, and workflow defaults for this workspace.

Setting group 3: Configure access, notifications, and workflow defaults for this workspace.

Setting group 4: Configure access, notifications, and workflow defaults for this workspace.

Setting group 5: Configure access, notifications, and workflow defaults for this workspace.

Setting group 6: Configure access, notifications, and workflow defaults for this workspace.

Setting group 7: Configure access, notifications, and workflow defaults for this workspace.

Setting group 8: Configure access, notifications, and workflow defaults for this workspace.

Setting group 9: Configure access, notifications, and workflow defaults for this workspace.

Setting group 10: Configure access, notifications, and workflow defaults for this workspace.

<>
<Button label="Edit workspace" onClick={() => setIsOpen(true)} />
<Drawer {...args} isOpen={isOpen} onOpenChange={setIsOpen}>
<Layout
content={
<LayoutContent label="Workspace settings">
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: 16,
}}>
<TextInput
label="Workspace name"
onChange={() => {}}
value="Research Operations"
/>
<TextInput
label="Owner"
onChange={() => {}}
value="Ada Lovelace"
/>
{Array.from({length: 10}, (_, index) => (
<Text as="p" color="secondary" key={index}>
Setting group {index + 1}: Configure access,
notifications, and workflow defaults for this workspace.
</Text>
))}
</div>
</LayoutContent>
}
footer={
<LayoutFooter
primaryButton={
<Button
label="Save"
onClick={() => setIsOpen(false)}
variant="primary"
/>
}
secondaryButton={
<Button label="Cancel" onClick={() => setIsOpen(false)} />
}
/>
}
header={
<LayoutHeader
subtitle="Manage workspace metadata and defaults."
title="Edit workspace"
/>
}
/>
</Drawer>
</>

A slide-in panel anchored to an edge of the viewport.

PropTypeDefaultDescription
children*ReactNodeDrawer body content.
classNamestringAdditional CSS class names applied to the drawer.
data-testidstringTest ID applied to the drawer.
dismissBehaviorDrawerDismissBehavior{isEscapeDismissEnabled: true, isBackdropDismissEnabled: true}Controls whether Escape and backdrop clicks request dismissal. Pass a boolean to enable or disable both behaviors together.
isOpen*booleanWhether the drawer is open.
label*stringAccessible label for the drawer.
onOpenChange*(isOpen: boolean) => voidCalled when the drawer requests an open-state change.
placement"end" | "start" | "top" | "bottom"'end'Edge of the viewport the drawer slides in from.
refRef<HTMLDialogElement>Ref forwarded to the drawer element.
sizenumber | stringWidth (start/end) or height (top/bottom) of the drawer.
styleCSSPropertiesInline styles applied to the drawer.