Behavior
Positioning and direction
The drawer can open from any edge. Set the Open Direction prop to control the entry point. Each direction uses its own CSS transforms and border-radius rules.
Bottom (default)
Slides up, rounded top corners, max-height capped
Top
Slides down, rounded bottom corners, accounts for admin bar
Left
Slides in from the left, full-height with rounded corners
Right
Slides in from the right, full-height with rounded corners
Drag-to-close
On open drawers, a pointer drag in the closing direction moves the drawer and dims the overlay proportionally. Releasing past the close threshold (25% of the drawer dimension) closes it — otherwise it snaps back.
Velocity detection — fast swipes close immediately regardless of distance
Over-drag dampening — dragging past the open position applies logarithmic resistance
Scroll awareness — dragging is suppressed for 100ms after scrolling inside the drawer body, preventing scroll-to-close conflicts
Handle-only mode — restrict drag to the
.c-drawer__handleelement with thehandleOnlyoptionNo-drag mode — disable swipe-to-close entirely with the Disable Drag to Close prop
cursor: grabbingis applied globally during drag via.c-drawer--dragging
Snap points
Vertical drawers (top or bottom) can rest at multiple heights instead of just open or closed. Add data-snap-point to any element inside the drawer body and the drawer will snap to that element's edge as the user drags.
Use "top" to snap to the element's top edge, "bottom" to snap to its bottom edge. The drawer opens to the smallest snap point first, and dragging below it closes the drawer. Snap points are ignored for left/right drawers.
Snap navigation buttons
Add data-snap-to to any button inside the drawer to step between snap points on click — useful for discoverability and for visitors who won't drag.
"next"expands to the next-larger snap point."previous"collapses to the next-smaller one.At the extremes the button does nothing —
"next"no-ops at full height,"previous"no-ops at the smallest snap point. It never closes the drawer.Use a real
<button>element. The component does not synthesize keyboard or focus behavior, so a<div>would not be operable by keyboard or screen-reader users.The button's availability is reflected with
aria-disabledat the extremes. Style the inactive state with[data-snap-to][aria-disabled="true"]if so you desire.On non-snap drawers (no
data-snap-pointelements, or left/right direction) the button is ignored — it's inert markup.
Nested drawers
You can open a drawer from inside another drawer. When this happens, the parent scales back slightly while the child opens on top, then restores when the child closes.
A few things to keep in mind:
Passive drawers cannot be nested — they don't participate in the stack.
The child drawer gets its own close gesture and close button. Closing it returns the parent to full size.
You can nest multiple levels deep, but one or two is the practical limit for usability.
Passive mode
Passive mode renders the drawer as a non-modal notification bar. It has no overlay, cannot trap focus, and does not lock body scroll.
Overlay is hidden (CSS managed), body scroll is not locked
Click outside does not close — only drag or a close button dismisses it
Trigger elements do not receive
aria-expandedupdatespointer-events: noneon the wrapper lets users interact with content beneathIdeal for bottom-sheet notifications that don't demand immediate attention
Enable with the Passive Mode prop or the passive constructor option.
Auto-open and persistence
Drawers can open automatically on page load with configurable delay and storage-backed frequency control.
every-visit
Always show (no persistence)
until-dismissed
Show until the user closes it, then never again
once
Show one time only (recorded on open)
after-delay
Re-show after a configurable duration since last dismissal
Duration strings accept 30s, 2h, 7d, or bare numbers (treated as hours). All persistence uses localStorage with keys namespaced under etch-drawer-.
Configure with the Auto Open, Auto Open Delay, Auto Open Reshow, and Auto Open Reshow Delay props.
Etch builder integration
Inside the Etch visual builder iframe, the Drawer disables all gesture handling and event binding. The builder controls open/close via the Show In Builder prop, which toggles visibility on the wrapper element through a MutationObserver.
No drag, no pointer events, no keyboard bindings
CSS rules handle visibility from the prop value
The open/close class toggle still synchronizes
data-statefor preview rendering
Last updated