Overview
The Drawer block is a panel that slides in over the page — from the side on desktop, from the bottom on mobile by default. It comes in two variants: Card (you compose its header, body, and footer) and Page (it embeds another page with inputs you pass in). A drawer starts closed and is opened by the Control drawer action or its showDrawer method.
Note: New Card drawers arrive pre-assembled with a title header and a footer holding Cancel and Confirm buttons. Customize slot content by dropping blocks into each slot.
For a centered dialog that blocks the whole page instead of sliding in from an edge, see Modal.
Drawer Variants
| Variant | What it shows | Use case |
| Card | Three slots: Header, Body, Footer — each holds one block (Stack by default) | Edit forms, detail views, custom composed layouts |
| Page | Embeds an existing app page with Page Inputs you bind | Reusing detail pages as overlays, drill-down navigation between drawers |
Content Properties
| Property | Type | Default | Appears When | Description |
| variant | "card" | "page" | card | Always | Whether to show composed Card slots or an embedded Page |
| pageId | page reference | — | variant = page | The app page to embed. Only static-path pages are selectable |
| inputs | object (bindable) | — | variant = page | Values passed to the embedded page's inputs (e.g., selected row ID) |
| slots | header, body, footer | Title header + Cancel/Confirm footer | variant = card | The three layout areas of a Card drawer |
| containerId | block reference | page root | Always | Which part of the page the drawer overlays. Default: whole page |
| hideOnClickOutside | boolean | true | Always | Close the drawer when user clicks outside it |
| dragDownToClose | boolean | true (mobile) | Mobile + position = Bottom | Let users swipe down to dismiss the drawer |
| interactions | event list | — | Always | On Open / On Close event handlers |
| permissions | permission rule | — | Always | Restrict who can see or use the drawer |
Appearance Properties
| Property | Type | Default | Description |
| position | "left" | "right" | "bottom" | right (desktop), bottom (mobile) | Which edge the drawer slides in from. Bottom offered on mobile/tablet only |
| defaultWidth | px or % | 38.2% | Width of Start/End positioned drawers |
| defaultHeight | px or % | 61.8% (mobile) | Height of Bottom positioned drawers |
| type | "fixed" | "floating" | fixed | Floating insets the drawer from screen edges with rounded corners |
| backdrop.showBackdrop | boolean | false | Dims the page behind the drawer |
| backdrop.backdropStyles | color + blur (0–20) | backdrop color, blur 8 | Backdrop tint and blur intensity. High blur can hurt performance on low-end devices |
| visibility | condition | — | Show/hide the block itself |
Events
| Event | Trigger | Payload |
| On Open | The drawer opens (content appears) | — |
| On Close | The drawer closes (content removed) | — |
Methods
| Method | Parameters | What it does |
showDrawer | — | Opens the drawer |
hideDrawer | — | Closes the drawer |
Call these via a Control block method action or the Control drawer action. They can also be called directly from a script at the block's own name.
Behaviors & Gotchas
Warning: A closed drawer doesn't exist: While closed, the drawer and all blocks inside it are removed from the page entirely. Blocks inside have no state, bindings resolve to nothing, and data sources don't run. Each open starts fresh — forms inside a drawer won't remember prior input.
Warning: Hide-on-click-outside locks the backdrop toggle: With Hide on Click Outside on, Show Backdrop is locked. The drawer places a transparent backdrop to catch outside clicks — meaning the first click outside closes the drawer but does NOT reach elements under it.
Note: Only static-path pages can be embedded: The Page variant only shows pages with static paths. Pass record IDs through Page Inputs rather than URL segments.
Note: One drawer at a time: Opening a second drawer closes the first. Drawers only stack when the opener is itself a page embedded inside a drawer (drill-down pattern).
Note: Start/End positions flip in RTL: In right-to-left locales, End slides from the left, Start from the right.
Note: Mobile default is a bottom sheet: The mobile variant defaults to Position = Bottom, 61.8% height, Drag Down to Close enabled.
Examples & Patterns
Drawer vs. Modal
Both are overlays with Card and Page variants. Reach for a Drawer when the panel should sit at the edge of the page and may leave the rest of the page usable. Reach for a Modal when the user must deal with the dialog before doing anything else.
| Feature | Drawer | Modal |
| Position | Edge of page (left, right, bottom) | Centered over page |
| Backdrop | Optional, configurable | Always blocks interaction behind it |
| Default size | 38.2% wide (desktop), 61.8% tall (mobile) | 400×400 px |
| Full-screen mode | Not applicable | Set width+height to 100% |
| Page variant | Yes (embeds another page) | Yes (embeds another page) |
| Exposed state | None | state.open |
| Mobile default | Bottom sheet at 61.8% height | Same centered dialog |
| Multiple open | One at a time (second closes first) | Standard: one centered |
| Dismiss methods | hideDrawer(), click-outside, drag-down (mobile) | hideModal(), Escape, click-outside, close button |
Related Blocks
| Block | Relationship |
| Modal | Centered blocking dialog — use when the page behind must not be interactive |
| Bottom Sheet | Purpose-built swipeable bottom panel for mobile |
| Mobile Contextual Dialog | Small anchored popover for in-context menus |
| Stack | The default container inside each slot (header/body/footer) |
| Form / Table | Typical drawer contents and triggers |
Frequently Asked Questions
Why does my form inside a Drawer reset every time it's opened?
This is by design. A closed Drawer is completely removed from the page — all blocks inside it are unmounted. When you reopen it, everything starts fresh. If you need to persist data between opens, store it in a page variable instead of relying on the Drawer's internal state.
Can a page have multiple Drawers open at the same time?
No. A page shows one Drawer at a time. Triggering a second Drawer closes the first. Drawers only stack when the opener itself is a page embedded inside a Drawer (the drill-down pattern), which creates a back-navigation history.
What is the difference between Hide on Click Outside and Show Backdrop?
Hide on Click Outside places a transparent backdrop to catch outside clicks, which also disables the Show Backdrop toggle (they conflict). Show Backdrop (without Hide on Click Outside) dims the page visually but does not close the Drawer on backdrop clicks. Use Hide on Click Outside for a light dismissal experience, and Show Backdrop for a non-dismissable focused panel.
Can I embed a page with a dynamic URL parameter in a Drawer?
No. Only pages with static paths can be embedded. Pages with dynamic URL segments (like /records/:id) are not available in the page picker. Pass the dynamic value (like a record ID) through Page Inputs instead.
Why does my Drawer open from the bottom on mobile?
That is the mobile default. The mobile variant sets Position = Bottom with 61.8% height and Drag Down to Close enabled, which produces a bottom-sheet presentation. Change Position in the Appearance panel if you want a side drawer instead.