Meowland docs
Workbench

Component reference

Drawer

A modal panel that slides in from the start edge over a scrim, for navigation on narrow screens.

Preview

Narrow-screen navigation

The title and close button share a fixed region; the body scrolls independently. After choosing a destination, pressing Escape, or closing via the scrim, focus returns to the trigger button.

packages/meowtail/stories/drawer.stories.tsxline 25tsx
render() {
  const open = signal(false);
  return (
    <Stack align="start">
      <Button
        variant="outline"
        onClick={() => {
          open.value = true;
        }}
      >
        <Icon name="menu" />
        Open navigation drawer
      </Button>
      <Drawer
        label="Main navigation"
        open={open}
        onOpenChange={(next) => {
          open.value = next;
        }}
        header={
          <DialogHeader
            title="Meowland"
            actions={
              <IconButton
                label="Close navigation"
                onClick={() => {
                  open.value = false;
                }}
              >
                <Icon name="x" />
              </IconButton>
            }
          />
        }
      >
        <Stack gap="compact">
          <NavItem
            label="Chat"
            icon={<Icon name="message-square" />}
            active
            onClick={() => {
              open.value = false;
            }}
          />
          <NavItem
            label="Memory and knowledge"
            icon={<Icon name="file-text" />}
            onClick={() => {
              open.value = false;
            }}
          />
          <NavItem
            label="Services"
            icon={<Icon name="network" />}
            onClick={() => {
              open.value = false;
            }}
          />
          <NavItem
            label="Messaging"
            icon={<Icon name="message-square" />}
            onClick={() => {
              open.value = false;
            }}
          />
          <NavItem
            label="Reminders"
            icon={<Icon name="list-checks" />}
            badge={
              <Tag kind="count" tone="warning">
                1
              </Tag>
            }
            onClick={() => {
              open.value = false;
            }}
          />
          {Array.from({ length: 8 }, (_, i) => (
            <NavItem
              label={`Authorized sample extension ${i + 1}`}
              icon={<Icon name="file-text" />}
              onClick={() => {
                open.value = false;
              }}
            />
          ))}
          <span>
            <StatusDot state="success" /> Runtime connected
          </span>
          <NavItem
            label="Settings"
            icon={<Icon name="settings" />}
            onClick={() => {
              open.value = false;
            }}
          />
        </Stack>
      </Drawer>
    </Stack>
  );
}

Installation

bun add meowtail

Usage

usage.tsts
import { Drawer } from "meowtail";

API reference

The native dialog supplies focus containment and Escape; the scrim dismisses.

Props

PropTypeDefault
labelRequiredAccessible name of the drawer.
string–
openRequired
MaybeSignal<boolean>–
onOpenChangeRequiredCalled when the reader dismisses the drawer (scrim, Escape); the owner updates open.
(open: boolean) => void–
header
Child–

Also takes className, children and the attributes and events of its root element.

DOM parts

rootpanel

Registry

The component is registered as drawer in the meowtail component registry.