Drawer

Side-panel dialog with configurable size and dismissal.

Overview

  • Use a drawer for supporting tasks that benefit from visible page context.

When to use

  • Use Drawer for inspectors, review sidebars, or longer-form side workflows.
  • Use it when the surrounding page context needs to stay visible.

When not to use

  • Do not use Drawer when the decision must fully interrupt the page; use Dialog.
  • Do not use Drawer for tiny advisory surfaces; use Popover or Tooltip.

Structural parts

open control

trigger

Control that opens the drawer.

edge sheet

surface

Side-anchored overlay surface.

optional footer actions

footer

Optional actions area inside the drawer.

Public interface

Props
NameTypeDefaultDescription
openbooleanfalseControlled open state.
side'left' | 'right''right'Chooses the drawer edge.
size'sm' | 'md' | 'lg''md'Chooses the drawer width recipe.
titlestring—Drawer title.
descriptionstring—Optional supporting explanation.
closeOnEscapebooleantrueAllows Escape to close the drawer.
closeOnOutsidePressbooleantrueAllows outside press dismissal.
onOpenChange(detail: { open: boolean }) => void—Runs when the drawer opens or closes.
themeThemeContract—Sets the theme used to resolve component styles.
Events
NamePayloadDescription
openchange{ open: boolean }Fires when an overlay-style component opens or closes through user interaction.
Slots
NameDescription
triggerOptional trigger content.
defaultDrawer body content.
footerOptional footer actions.

Variants, sizes, and states

Variants

  • right: Default right-side drawer
  • left: Left-side drawer for alternate context flows

Sizes

  • sm: Narrow drawer
  • md: Default drawer
  • lg: Wider drawer

States

  • closed: Drawer is hidden
  • open: Drawer is visible and focus-contained

Accessibility

Semantics

  • Uses overlay semantics that reflect whether the surface is modal, contextual, or advisory.
  • Uses dialog semantics in a side panel.

Keyboard

  • Supports Escape dismissal when allowed.
  • Returns focus to the trigger after closing.

Screen readers

  • Announces the overlay surface with its title, description, or tooltip content as available.

Checklist

  • Verify that the control has an accessible name.
  • Verify that keyboard focus is visible in every state and size.
  • Identify disabled, selected, and error states with text or symbols as well as color.

Tokens and CSS variables

root

--dk-motion-duration
200ms

backdrop

--dk-drawer-backdrop-bg
rgba(15, 23, 42, 0.45)

surface

--dk-drawer-surface-bg
#f2f5fb
--dk-drawer-surface-fg
#16181c
--dk-drawer-surface-border
#95989d
--dk-drawer-surface-radius
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-drawer-surface-shadow
0 10px 15px rgba(0, 0, 0, 0.06), 0 4px 6px rgba(0, 0, 0, 0.04)
--dk-drawer-surface-width
420px
--dk-drawer-surface-padding
clamp(1.778rem, 1.6296rem + 0.658vw, 2.222rem)

title

--dk-drawer-title-size
clamp(1.778rem, 1.6296rem + 0.658vw, 2.222rem)
--dk-drawer-title-weight
650

description

--dk-drawer-description-size
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

footer

--dk-drawer-footer-gap
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

Examples

Starter

Side inspector

A side panel for a supporting task.

<Drawer title="Inspector" description="Secondary support flow."><svelte:fragment slot="trigger">Open drawer</svelte:fragment>Keep supporting work visible without leaving the page.</Drawer>

Common patterns

Left-side sheet

Left-side drawers can support alternate app shells or editing flows.

<Drawer side="left" title="Filters"><svelte:fragment slot="trigger">Open filters</svelte:fragment>Filter controls here.</Drawer>

Edge cases

Externally controlled drawer

Control open state when app workflow owns the sheet lifecycle.

<Drawer open={isInspectorOpen} onOpenChange={(detail) => isInspectorOpen = detail.open} title="Inspector">Contextual details</Drawer>

Mathematical fixtures

Calculated fixtures; browser evidence is not collected. Layout estimates use declared text behavior and maximum token values.

default-right (side=left|size=sm)

pass

side=left|size=sm

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, layout
  • Evaluated: contrast, layout
  • Contrast: 98.5 Lc
  • Layout: surface · single-line 0 px single-line estimate; 0 px minimum width
    360 px: pass 420 px: pass 520 px: pass

default-right (side=right|size=sm)

pass

side=right|size=sm

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, layout
  • Evaluated: contrast, layout
  • Contrast: 98.5 Lc
  • Layout: surface · single-line 0 px single-line estimate; 0 px minimum width
    360 px: pass 420 px: pass 520 px: pass

default-right (side=left|size=md)

pass

side=left|size=md

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, layout
  • Evaluated: contrast, layout
  • Contrast: 98.5 Lc
  • Layout: surface · single-line 0 px single-line estimate; 0 px minimum width
    360 px: pass 420 px: pass 520 px: pass

default-right (side=right|size=md)

pass

side=right|size=md

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, layout
  • Evaluated: contrast, layout
  • Contrast: 98.5 Lc
  • Layout: surface · single-line 0 px single-line estimate; 0 px minimum width
    360 px: pass 420 px: pass 520 px: pass

large-left

pass

side=left|size=lg

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, layout
  • Evaluated: contrast, layout
  • Contrast: 98.5 Lc
  • Layout: surface · single-line 0 px single-line estimate; 0 px minimum width
    360 px: pass 420 px: pass 520 px: pass

default-right (side=right|size=lg)

pass

side=right|size=lg

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, layout
  • Evaluated: contrast, layout
  • Contrast: 98.5 Lc
  • Layout: surface · single-line 0 px single-line estimate; 0 px minimum width
    360 px: pass 420 px: pass 520 px: pass