Overlays

Drawer

A bottom-sheet dialog that slides up from the bottom of the screen, great for mobile-first interactions.

Preview
01 Installation

Install

Pull Drawer from the barrel for everyday use, or the granular path when you want a tighter bundle.

tsxBarrel1 line
import { Drawer } from "@brika/clay";
tsxGranular1 line
import { Drawer } from "@brika/clay/components/drawer";
02 Usage

A minimal example

Drop this into a page. Native HTML attributes pass through to the underlying primitive.

tsxDrawer.tsx35 lines
import { Button } from '@brika/clay/components/button';
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from '@brika/clay/components/drawer';
/** Bottom-sheet overlay, drag the handle or tap outside to close. */
export default function DrawerDefaultDemo() {
  return (
    <Drawer>
      <DrawerTrigger asChild>
        <Button variant="outline">Open drawer</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Publish changes</DrawerTitle>
          <DrawerDescription>
            Review and confirm before pushing to production.
          </DrawerDescription>
        </DrawerHeader>
        <DrawerFooter>
          <Button>Publish</Button>
          <DrawerClose asChild>
            <Button variant="outline">Cancel</Button>
          </DrawerClose>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  );
}
03 Examples

Drawer, every way

Form

Drawer used for mobile-first data entry, keeps the form reachable at the bottom of the screen.

Scrollable

Drawer with a scrollable list body and a fixed footer, suited for notification feeds or item pickers.

04 Accessibility

Accessibility

  • Focus is trapped inside the drawer while open.
  • Escape dismisses the drawer; the drag handle is decorative and keyboard users dismiss with Escape.
  • DrawerTitle is required for an accessible name.
  • Ensure scrollable content inside the drawer is reachable by keyboard, not only by touch-drag.
05 Tokens 14 theme-overridable

Theme tokens

Every CSS variable Drawer reads, with its default and the dotted path you'd write in a ThemeConfig JSON to override it. Set any of these in your theme to retune Drawer without touching component code.

Drawer tokens

14 tokens
ColorFill, border, and text colors.4
  • --drawer-surface-containercolorvar(--popover)
    components.drawer.surfaceContainer

    Background of the drawer panel.

  • --drawer-overlay-colorcoloroklch(0 0 0 / 0.5)
    components.drawer.overlayColor

    Color of the modal scrim shown behind an open drawer. Defaults to black at 50% opacity.

  • --drawer-handle-colorcolorvar(--muted)
    components.drawer.handleColor

    Fill of the small horizontal handle pill drawn at the top of the drawer panel.

  • --drawer-description-colorcolorvar(--muted-foreground)
    components.drawer.descriptionColor

    Foreground color of the drawer description text.

GeometrySizes, lengths, and corner radii.4
  • --drawer-radiusradiusvar(--radius-container)
    components.drawer.radius

    Drawer sheet top-corner radius.

  • --drawer-padding-xsizecalc(var(--spacing) * 6)
    components.drawer.paddingX

    Inline padding inside the drawer.

  • --drawer-padding-ysizecalc(var(--spacing) * 4)
    components.drawer.paddingY

    Block padding inside the drawer.

  • --drawer-gapsizecalc(var(--spacing) * 2)
    components.drawer.gap

    Gap between adjacent children inside the drawer.

BorderBorder width and style.2
  • --drawer-border-widthborder-width1px
    components.drawer.borderWidth

    Border width on the drawer. Set non-zero for outline-style variants.

  • --drawer-border-styleborder-stylesolid
    components.drawer.borderStyle

    Border style on the drawer (`solid`, `dashed`, `double`, `none`).

ElevationDrop shadow and depth.2
  • --drawer-shadowshadowvar(--shadow-overlay)
    components.drawer.shadow

    Drawer elevation.

  • --drawer-backdrop-blurblur0px
    components.drawer.backdropBlur

    Backdrop blur behind translucent drawer.

MotionAnimation duration and easing.2
  • --drawer-durationdurationvar(--motion-standard-duration)
    components.drawer.duration

    Transition duration for drawer state changes.

  • --drawer-easingeasingvar(--motion-standard-easing)
    components.drawer.easing

    Transition easing for drawer state changes.

Override in a theme

Authoring a theme is plain JSON. Drop overrides under components.drawer, the names are camelCase versions of the variable suffix.

jsonmy-theme.json12 lines
{
  "id": "my-theme",
  "name": "My Theme",
  "description": "...",
  "accentSwatches": ["#000"],

  "components": {
    "drawer": {
      "paddingX": "calc(var(--spacing) * 6)"
    }
  }
}

Then apply with applyTheme(myTheme) (see the theming guide), scope it to a subtree with themeToCssVars(myTheme, mode), or consume any token directly in your own JSX with the matching Tailwind utility (e.g. bg-drawer-…) — see the chips on each token row.

06 API reference

API reference

Props specific to Drawer. Native HTML attributes pass through to the underlying primitive, see the component source on GitHub for the full type signature.

<DrawerContent />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<DrawerDescription />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<DrawerFooter />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<DrawerHeader />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<DrawerOverlay />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<DrawerTitle />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.