Skip to content
ghostui

Preview

Campaigns

Fieldwork · 2 campaigns

Autumn layers
12 assets · Ready for review
Everyday carry
6 assets · Draft

Design guidance

Use a drawer to create an object, apply filters, open workspace navigation, inspect details, or review a collection while keeping the current page in view. Placement, size, and modality are separate choices. Use a title that names the task, or an accessible Popup label for a button-only action sheet. Add a description only when it helps the user complete that task. For a non-modal drawer, omit the Backdrop so the page stays interactive.

The viewport keeps an 8px gap from each screen edge, with safe-area and virtual-keyboard insets applied where they take more space. Bottom and top sheets are capped at 460px. Side drawers are 400px wide. Both fit the available space on small screens. Override --drawer-width on the Popup when a product needs a different width. Header padding is 16px on each side. Core has no top padding, so the content starts 16px after the header. Footer actions stack vertically and fill the content width. The footer uses the shared subtle surface (050 in light mode) by default. Set --drawer-footer-background on a Popup or Footer to change it, or use the Footer’s native style.background.

For a footer that blends into the body, use a normal style override:

Installation

Install Drawer. The examples also compose Button, ButtonGroup, Field, Input, InputGroup, Item, Combobox, DatePicker, Textarea, Select, AlertDialog, and Composer. Install those owners when you copy an example; campaign data and state stay in the caller.

Install

Basic usage

The trigger and title give the dialog an accessible name. Grip is optional. Without it, Popup has no grip padding. A direct-child Grip adds 4px at its edge. Side drawers reserve the 16px grip lane plus this 4px along the full edge, so Header, Core, and Footer share the same inset. Grip stays at the top, aligned with the Header row. The other three Popup edges keep their normal padding. Keep Grip outside Content so mouse users can drag it while selecting text. Touch users can swipe the sheet; scrollable content keeps normal scrolling.

Structures

Drawer.Root owns open state and modal behavior. Drawer.Trigger opens it. Drawer.Portal places the overlay outside the page layout. Drawer.Viewport owns placement and the screen-edge gap; it contains Drawer.Backdrop for modal use and Drawer.Popup. Add optional Drawer.Grip and one Drawer.Content as Popup siblings. Grip floats over the current row and adds only 4px along its full edge; normal 16px content padding becomes 20px on that edge. For a bottom sheet this is the top edge; for a top sheet it is the bottom. Side drawers inset all three regions together along the opening edge, with the grip at the top. Each region keeps its normal 16px content padding. Compose Drawer.Header for the title, optional description, and close control; Drawer.Core owns padded, scrollable task content; and Drawer.Footer holds stacked full-width actions, with the primary action first. Side drawers pin the footer while the Core scrolls. Top and bottom drawers hug their content until the available height requires Core scrolling. Drawer.Close can wrap a canonical Button or IconButton.

Nested Drawer.Root instances belong inside the parent Content; the examples place the child Trigger in the parent Footer as its primary CTA. Base UI keeps the parent mounted and restores focus when the child closes. Its native nested depth and frontmost-height values drive the stacked presentation. Drawer.VirtualKeyboardProvider manages keyboard-aware focus and scroll for form drawers. Drawer.SwipeArea can open a drawer by touch; always keep a visible trigger as an alternative. Drawer.IndentBackground and Drawer.Indent are an opt-in page treatment. They do not constrain a portal. For a contained panel, pass the positioned scene element to Drawer.Portal container={scene} and add ui-drawer-viewport--contained to its Viewport. The inset example keeps its backdrop and drawer inside that scene; its non-modal state leaves the rest of this page available.

Examples

Placement, modality, Grip, snap points, and content are independent choices. Each example combines these properties for a task; campaign data and state belong to the caller.

Placement

The swipe direction matches the edge where each drawer opens. The right, left, top, and bottom previews use independent content and state. Navigation uses canonical Button controls. Base UI owns Drawer gesture and snap state; each caller owns collection changes such as adding and removing images.

Right · Task filters

Filter campaign tasks by search, status, assignee, due date, and priority. Apply updates the results. Cancel keeps the applied filters. Reset edits the draft back to its defaults.

Campaign tasks

Fieldwork · Spring campaign

6 of 6 tasks shown

  • Review hero copyNora Nguyen · In progress · High priority
  • Approve shot listYou · To do · High priority
  • Upload product cutoutsAlex Rivera · To do · Normal priority
  • Schedule launch emailsNora Nguyen · To do · Normal priority
  • Publish campaign briefYou · Done · Normal priority
  • Export email cropsAlex Rivera · To do · High priority

Open workspace sections and recent campaigns. Canonical Button controls use fixed icon lanes, mark the current destination, close the drawer, and update the visible page section.

Campaigns

  • Trailpack spring launch
  • Autumn layers
  • Everyday carry

Top · Saved prompts

Select one of three saved instructions and insert it into the visible multiline draft. Cancel and Close keep the previous inserted text.

Spring campaign

12 assets · Draft

Write a launch email for the Trailpack.

Use the approved campaign brief. Include the 14L capacity and recycled nylon shell.

Bottom · Controlled source

Open the full launch brief, then show its contents in the page. This is a controlled bottom drawer with local result state.

Optional grip

Use Grip only when users need a visible drag target. It stays outside Content so mouse selection remains available.

Fieldwork / Spring campaign

Create launch copy and choose campaign images from the approved brief.

Snap points

Keep this non-modal image collection open while browsing. Its count, order, and contents update together. The Core grows between the header and pinned footer, which stays at the visible bottom. Base UI owns Drawer gesture and snap state; the caller owns adding and removing images. Use in campaign carries the current selection into the page. Images are local example assets.

Nested drawers

Each placement opens four levels: Preferences → Security settings → Session settings → Trusted device. The full-width footer action opens the next level. Back closes one level and restores the previous panel. Top and bottom keep an 8px parent strip.

Indented page

The contained portal shows source file facts and one Done action. Its short content leaves the page indent visible around the sheet.

Fieldwork / Spring campaign

Review the approved source before you draft campaign copy.

Modality and related behavior

Non-modal assistant

The page stays interactive while the assistant shows a launch-email draft and accepts a local revision request.

Keyboard-aware draft

The virtual keyboard provider keeps the focused field and action in reach.

Swipe to open

The edge gesture has a visible button alternative.

Fieldwork / Spring campaign

Use the Trailpack brief while you draft launch copy and review campaign backgrounds.

Unsaved changes

Saving keeps the text in the saved result. Discard clears it. Keep editing retains the input.

Action sheet

Use a vertical ButtonGroup with outline Buttons. Nest groups to separate related actions, conversation management, and Cancel. This sheet has no grip, header, or footer; aria-label names the dialog. Copy failure closes the sheet and shows an error on the page.

Detached triggers

Detached triggers open the same panel from separate caller locations.

Responsive placement

Keep the drawer on the right on wide screens and place it at the bottom on narrow screens.

API reference

Drawer re-exports the installed Base UI parts and keeps its modal, focus, swipe, nested, and snap behavior. Header, Core, and Footer are forwarded native HTML regions with their matching HTML attributes and refs. All three are optional; a button-only action sheet can place ButtonGroup directly inside Content. Grip forwards native div attributes and its ref, is hidden from assistive technology by default, and provides no separate gesture engine. Place it outside Content so mouse drags reach Base UI Viewport. Content preserves mouse text selection; touch swipes and scroll arbitration remain Base UI behavior. See the Base UI Drawer API for inherited props and state.