components / drawer

Drawer

Edge-anchored dialog surface for contextual tasks, side sheets, and longer-form secondary workflows.

Overview

What it is

This section explains the intent of the component before the implementation details.

  • Drawer is the side-anchored companion to Dialog for workflows that benefit from more surrounding context.
  • It keeps the user in the page while still giving a focused surface for secondary tasks.

Aliases

side sheet

Decision guide

How to choose it

Use these notes to decide quickly whether this is the right DK component for the job.

Decision guide

  • Choose Drawer when the interaction should feel deliberate, documented, and reusable across product surfaces.
  • If the scenario is more specialized than the current Drawer contract, prefer a simpler component or build a dedicated workflow on top of the lower-level DK primitives.

Do

  • Keep the Drawer label, value, or status language direct enough to scan quickly.
  • Use the documented size and state recipes instead of inventing one-off variants in product code.

Do not

  • Do not hide the main purpose of Drawer behind decorative copy or overloaded surface treatments.
  • Do not stretch Drawer into a workflow it was not designed to handle just because the visuals are close.

Usage

When to use

Prefer these situations when choosing this component.

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

Usage

When not to use

These patterns are better served by a different component or a simpler surface.

  • 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.

Anti-patterns

  • Using Drawer as a generic layout container instead of a purpose-built interaction or content surface.
  • Forking the documented recipe in product code instead of extending the shared DK contract.

Migration notes

  • Migrate legacy drawer usage by mapping existing variants and states onto the documented DK props before porting any custom styling.
  • Treat the docs examples as the reference contract for accessibility and event behavior during adoption.

Anatomy

Structural parts

The anatomy explains which pieces matter to the recipe and accessibility model.

open affordance

trigger

Control that opens the drawer.

edge sheet

surface

Side-anchored overlay surface.

optional footer actions

footer

Optional actions area inside the drawer.

API

Public interface

The docs contract distinguishes props, DOM events, and slots so integration behavior is explicit.

Props

NameTypeDefaultDescription
openbooleanfalseControlled open state.
side'left' | 'right''right'Chooses the drawer edge.
size'sm' | 'md' | 'lg''md'Chooses the drawer width recipe.
titlestringDrawer title.
descriptionstringOptional supporting explanation.
closeOnEscapebooleantrueAllows Escape to close the drawer.
closeOnOutsidePressbooleantrueAllows outside press dismissal.
onOpenChange(detail: { open: boolean }) => voidCallback fired when the drawer opens or closes.
themeThemeContractOverrides the compiled DK theme used to resolve tokens and recipes for this component.

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.

Recipes

Variants, sizes, and states

These notes summarize the intended recipe surface rather than exposing raw implementation detail first.

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

Accessibility contract

This is the behavior the component promises to assistive tech and keyboard users today.

Semantics

  • Uses overlay semantics that reflect whether the surface is modal, contextual, or advisory.
  • Uses dialog-like semantics with an edge-anchored surface.

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 the visible label or title still produces a clear accessible name.
  • Verify focus remains obvious in every supported state and size.
  • Verify disabled, selected, and error states do not rely on color alone.

Implementation

Tokens and slot vars

This section shows the representative compiled slot variables that the runtime consumes for the selected design system.

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)

Implementation notes

  • Drawer is ideal when context matters. If the user needs complete interruption, Dialog is usually the better fit.

Implementation checklist

  • Use the public component API first and only drop to lower-level primitives when the component contract genuinely does not fit.
  • Keep theme overrides token-driven so proofs and recipes stay meaningful.
  • Verify the shipped examples and proof fixtures still represent the real product scenario you are implementing.

Examples

Copy-paste examples

Each example is intentionally practical, grouped by starter, common pattern, and edge-case coverage.

Examples
3
Depth
expanded

Starter

1 example

starter

Starter: side inspector

A right-side secondary workflow surface.

Copy snippet

<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

1 example

common

Common: left-side sheet

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

Copy snippet

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

Edge cases

1 example

edge

Edge: externally controlled drawer

Control open state when app workflow owns the sheet lifecycle.

Copy snippet

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

Verification

Curated proof fixtures

Proofs stay visible in the docs so the system shows what it can guarantee, not just what it can render.

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

pass

side=left|size=sm

  • Contrast: 98.5 Lc
  • Layout: 0 / 360, 420, 520

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

pass

side=right|size=sm

  • Contrast: 98.5 Lc
  • Layout: 0 / 360, 420, 520

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

pass

side=left|size=md

  • Contrast: 98.5 Lc
  • Layout: 0 / 360, 420, 520

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

pass

side=right|size=md

  • Contrast: 98.5 Lc
  • Layout: 0 / 360, 420, 520

large-left

pass

side=left|size=lg

  • Contrast: 98.5 Lc
  • Layout: 0 / 360, 420, 520

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

pass

side=right|size=lg

  • Contrast: 98.5 Lc
  • Layout: 0 / 360, 420, 520