Drawer
Overlays & menusBrick 0.1.12

Drawer

Drawer is a modal task surface that enters from a logical or physical edge.

Live example

Built from the published package

Interactive
Choose with confidence

Know when Drawer is the right part

Use it when

Use it for focused navigation, details, or editing that benefits from retaining page context.

Choose another path when

Use Dialog for a centered modal task and nonmodal layout for persistent page content. Drawer does not own application navigation or responsive shell policy.

Installation and imports

tsx
import * as Drawer from "@flowstack-ui/brick/drawer";
import "@flowstack-ui/brick/styles.css";

The module-namespace form above is safe in React Server Components and keeps the containing page server-rendered. Inside an already client-owned module, the legacy import { Drawer } runtime object remains supported.

The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:

tsx
import "@flowstack-ui/brick/styles/core.css"; // once at the application root
import "@flowstack-ui/brick/styles/drawer.css";

Add the modular stylesheet for every other Brick component the route renders. Do not combine modular styles with styles.css or tokens.css.

Quick start

tsx
<Drawer.Root>
  <Drawer.Trigger>Open</Drawer.Trigger>
  <Drawer.Portal>
    <Drawer.Overlay />
    <Drawer.Content>
      <Drawer.Header><Drawer.Title>Settings</Drawer.Title></Drawer.Header>
      <Drawer.Body>Settings content</Drawer.Body>
      <Drawer.Footer><Drawer.Close>Done</Drawer.Close></Drawer.Footer>
    </Drawer.Content>
  </Drawer.Portal>
</Drawer.Root>

Visual recipes and states

Placement selects the entering edge; start/end are logical. Size selects fixed inline dimensions for side drawers and content-responsive block-size caps for top/bottom drawers. xl may grow to the available viewport but still shrinks around shorter content; full always uses the viewport. A top/bottom Drawer grows with its authored content until the selected cap, then Body becomes the scroll owner. Atom owns state, focus trap/return, dismissal, presence, portal, and placement state.

Examples

tsx
<Drawer.Content placement="start" size="lg">
  <Drawer.Title>Navigation</Drawer.Title>
  <Drawer.Body></Drawer.Body>
</Drawer.Content>
Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

Public exports are the Drawer namespace; named DrawerRoot, DrawerTrigger, DrawerPortal, DrawerOverlay, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerBody, DrawerFooter, DrawerClose, and DrawerBranch parts; their corresponding prop types; and DrawerPlacement, DrawerSize, plus DrawerFooterJustify.

The component subpath additionally exports Root, Trigger, Portal, Overlay, Content, Header, Title, Description, Body, Footer, Close, and Branch as short aliases for the recommended RSC-safe module-namespace composition.

ts
DrawerRootProps
DrawerTriggerProps
DrawerPortalProps
DrawerOverlayProps
DrawerContentProps
DrawerHeaderProps
DrawerTitleProps
DrawerDescriptionProps
DrawerBodyProps
DrawerFooterProps
DrawerCloseProps
DrawerBranchProps
Content propValuesDefault
placementstart, end, top, bottomend
sizesm, md, lg, xl, fullmd
Footer propValuesDefault
justifystart, center, end, betweenend

Root and the composable behavior parts inherit Atom modal/drawer props. Title is intentionally a native heading with an as level prop rather than an asChild layout host; Description is a native paragraph. Header, Body, and Footer accept native div attributes and data-slot. Footer justify controls simple logical action distribution; use layout components inside Footer for more complex grouping, and use Button fullWidth when an action itself should fill the row. Footer reflects the selected value through data-justify.

Shared responsibility

Accessibility

Atom owns modal semantics, focus containment/return, Escape and outside dismissal. Supply a concise Title and, when useful, Description. When a visible heading would be inappropriate, give Content an explicit aria-label or aria-labelledby; do not pass a multi-element brand lockup through Title. Keep an accessible Close action and use Branch only for externally portalled content that belongs to the same modal interaction.

Responsive behavior

Drawer constrains its dimensions to the viewport and uses safe-area tokens. The application chooses breakpoints and whether a Drawer becomes another pattern. Logical placement supports RTL.

Stable visual contract

Styling and tokens

Customization

Use placement/size and Atom modal props first, then public tokens and compound parts. Apply className/style to the owning part for scoped exceptions.

Tokens and CSS hooks

Stable classes and overridable data-slot values cover Trigger, Overlay, Content, Header, Title, Description, Body, Footer, Close, and Branch. Content reflects data-size; Atom reflects placement. Public tokens are --brick-drawer-inline-size-sm, --brick-drawer-inline-size-md, --brick-drawer-inline-size-lg, --brick-drawer-inline-size-xl, --brick-drawer-block-size-sm, --brick-drawer-block-size-md, --brick-drawer-block-size-lg, --brick-drawer-block-size-xl, --brick-drawer-background, --brick-drawer-radius, --brick-drawer-shadow, --brick-drawer-space, --brick-drawer-safe-top, --brick-drawer-safe-right, --brick-drawer-safe-bottom, and --brick-drawer-safe-left.

--brick-drawer-background and --brick-drawer-radius may be set on a theme ancestor to change every Drawer in that scope, or on one Content instance for a local exception. When unset, they fall back to --brick-color-surface-overlay and --brick-radius-overlay, respectively.

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.