Warren UI

Sheet

Right-side slide-over panel with overlay, focus trap and Esc handling.

Source
"use client"

import { useState } from "react"
import { Button } from "@/registry/warren/button/button"
import { Sheet } from "@/registry/warren/sheet/sheet"

export default function SheetDemo() {
  const [open, setOpen] = useState(false)
  return (
    <div className="flex flex-wrap items-center justify-center gap-4 py-12">
      <Button onClick={() => setOpen(true)}>
        MAP SETTINGS
      </Button>
      <Sheet
        open={open}
        onOpenChange={setOpen}
        title="MAP SETTINGS"
        description="FULLSCREEN · VIEW LAYERS"
        footer={
          <span className="font-mono text-[9px] uppercase tracking-wide text-muted-foreground">
            FIT · WHOLE MAP
          </span>
        }
      >
        <p className="font-mono text-[10px] uppercase leading-relaxed tracking-wide text-muted-foreground">
          THE PANEL DOCKS TO THE RIGHT EDGE — THE SURFACE BEHIND STAYS LIVE WHILE LAYERS TOGGLE.
        </p>
      </Sheet>
    </div>
  )
}

Installation

npx shadcn@latest add https://warren.eduard3v.com/r/sheet.json

Usage

import { Sheet } from "@/components/ui/sheet"
<Sheet
  open={open}
  onOpenChange={setOpen}
  title="MAP SETTINGS"
  description="FULLSCREEN · VIEW LAYERS"
  footer={<span>FIT · WHOLE MAP</span>}
>
  <p>LAYER SWITCHES</p>
</Sheet>

Sheet is controlled — the caller owns open and passes onOpenChange (called with false on Escape, an overlay pointerdown, or the close button). It renders a flat dim overlay plus a right-edge slide-over panel (150ms ease-out, disabled under prefers-reduced-motion). While open the body scroll locks and focus moves to the panel, where Tab and Shift+Tab cycle within the sheet's focusable controls; on close focus returns to the previously focused element. Because it docks to the viewport edge instead of covering center stage, the map (or any anchor surface) stays visible behind it — prefer it over Dialog when toggling layers needs live visual feedback.

Structure

Header (p-4 pb-0, title + close button) · description line · scrollable body · optional footer strip under a 1px hairline. The panel is role="dialog" with aria-modal="true", aria-labelledby wired from the title, and aria-describedby when a description is present. Flat and radius-0 — a single left hairline separates panel from page.

API Reference

Prop

Type

On this page