Overlays and modals

Sheet
v0.2.3
Documentation Under Review

A slide-out panel built on Radix UI Dialog with CVA side variants, modal and complementary modes, and full keyboard accessibility.

Prefer AI-assisted development?

This documentation is available via the Catalyst MCP Server. Learn how to connect →

Catalyst Sheet extends Radix UI Dialog with built-in slide animations, four edge positions, and accessibility defaults — giving you a production-ready slide-out panel for settings, help content, and workflows without any extra configuration.

Preview

Installation

npm install @pmi/catalyst-sheet

The Sheet component requires the tailwindcss-animate plugin for slide animations. Add the Sheet preset to your tailwind.config.ts:

import tailwindSheetPreset from '@pmi/catalyst-sheet/tailwind.config';

export default {
  presets: [tailwindSheetPreset],
};
import {
  SheetRoot,
  SheetTrigger,
  SheetContent,
  SheetHeader,
  SheetFooter,
  SheetTitle,
  SheetDescription,
  SheetClose,
} from '@pmi/catalyst-sheet';

API Reference

Sheet is a compound component built on Radix UI Dialog. The sections below summarize the Catalyst-specific props for each part.

SheetRoot

Manages open/close state and modal behaviour. Accepts all Radix Dialog Root props — open, onOpenChange, defaultOpen, modal — directly.

SheetContent

The slide-in panel. Renders a SheetOverlay internally.

Prop

Type

SheetOverlay

The backdrop rendered behind the open sheet. Controlled automatically by SheetContent — use customOverlayClass on SheetContent to style it without rendering SheetOverlay directly. Accepts unstyled to strip default styles, plus all standard Radix Overlay props.

SheetHeader

Header wrapper with standard padding and flex column layout. Accepts unstyled to strip default styles, plus all standard div props.

SheetFooter

Footer wrapper with action button layout. Accepts unstyled to strip default styles, plus all standard div props.

SheetTitle

Required accessible title connected to aria-labelledby. Accepts unstyled to strip default styles, plus all Radix Dialog Title props.

SheetDescription

Optional description connected to aria-describedby. Accepts unstyled to strip default styles, plus all Radix Dialog Description props.

SheetTrigger / SheetClose

Pass-throughs to Radix Dialog Trigger and Close. Both accept asChild to merge props onto a custom element.

Accessibility

Sheet is designed to meet WCAG 2.2 AA standards.

Keyboard Interactions

KeyAction
TabMoves focus to the next interactive element inside the sheet
Shift + TabMoves focus to the previous interactive element inside the sheet
EscapeCloses the sheet and returns focus to the trigger
Enter / SpaceActivates a focused button or trigger

ARIA

  • Radix UI renders role="dialog", aria-modal="true" (in modal mode), aria-labelledby, and aria-describedby automatically.
  • SheetTitle is required — it provides the accessible name for the dialog (WCAG 2.2 SC 4.1.2).
  • SheetDescription is recommended — it gives additional context via aria-describedby.
  • Always add <span className="sr-only">Close</span> to icon-only close buttons (WCAG 2.2 SC 1.1.1).
  • In modal mode, focus is trapped inside the sheet and returns to the trigger on close (WCAG 2.2 SC 2.4.3).
  • In complementary mode (modal={false}), focus is not trapped — ensure the sheet can still be closed via keyboard.
  • When using custom colours, verify foreground-to-background contrast meets the WCAG 2.2 AA minimum of 4.5:1 for text (SC 1.4.3).

See the Radix Dialog accessibility docs for inherited baseline behavior.

Choosing the Right Component

Use Sheet when supplementary content needs to stay accessible alongside the main workflow. Reach for a different primitive when:

If you need…Use instead
A blocking confirmation or short-form dialogDialog
A bottom-anchored mobile action panelDrawer
A small contextual popup anchored to a triggerPopover

On this page