Skip to content

shutteringv1.0.0

Overlays

Everything that layers over the page — modals, sheets, tooltips, and a morphing focus view. All trap focus, close on Escape or the backdrop, and animate out before unmounting.

@shuttering/uiimport { Dialog, Drawer, Sheet, Menu, Popover, Tooltip, Spotlight, useConfirm } from '@shuttering/ui'

Dialog

A centered modal built on Base UI — correct roles, focus trapping, and restore-on-close.

PropTypeDefaultDescription
Dialogopen?, onOpenChange?Composes DialogTrigger / DialogContent / DialogHeader / DialogTitle / DialogFooter / DialogClose. Uncontrolled by default.
DialogTrigger · asChildbooleanUse your own element (e.g. a Button) as the trigger.

Drawer

An off-canvas sheet that slides in from a side on a spring.

PropTypeDefaultDescription
open (required)booleanControlled visibility.
onClose (required)() => voidCalled on Escape, backdrop click, or close.
titleReactNodeThe sheet heading.
side'left' | 'right''right'Which edge the sheet enters from.

Sheet

A drag-dismissible sheet. Grab it and throw it toward its edge — past a short distance or a quick flick it dismisses; let go short and it springs back on the house drawer spring. Pulling the other way rubber-bands. Reduced motion drops the drag for a plain fade.

PropTypeDefaultDescription
open (required)booleanControlled visibility.
onClose (required)() => voidCalled on dismiss — a drag past the threshold, Escape, or the backdrop.
side'bottom' | 'right' | 'left''bottom'Which edge it enters from, and the axis you drag to dismiss.
scaleBackgroundbooleanfalseScale a [data-sheet-background] element down behind the sheet (the Vaul depth effect). No-op if absent; skipped under reduced motion.
titlestringThe sheet heading.

Tooltip

Scales in from its trigger on hover and focus. Wrap a tree in one TooltipProvider.

Spotlight

A focus view that morphs out of its trigger — the trigger and the panel share a layoutId, so the card grows into the panel (a shared-layout FLIP).

PropTypeDefaultDescription
open (required)booleanControlled visibility.
onClose (required)() => voidClose handler.
layoutIdstringShared with a motion element to morph the panel out of it.
title / subtitleReactNodeThe panel heading.

Confirm

An imperative confirm that resolves a promise — no ad-hoc modal state per call site.

const ok = await confirm({…}) resolves true or false. Wrap the app in ConfirmProvider once; call useConfirm() anywhere below it.

Popover

A non-modal surface anchored to a trigger — a menu, a small form, a bit of detail. Positioned with align, side, and an offset; dismisses on outside click and Escape.

PropTypeDefaultDescription
PopoverContent · align'start' | 'center' | 'end''center'Alignment along the trigger edge.
PopoverContent · side'top' | 'right' | 'bottom' | 'left'Preferred side; flips to stay in view.
PopoverContent · sideOffsetnumber4Gap from the trigger, in px.

Menu

An actions menu anchored to a trigger — it scales in from the corner nearest the trigger, with roving keyboard focus, typeahead, grouped items, and checkbox/radio/submenu variants. Dismisses on outside click and Escape.

PropTypeDefaultDescription
Menuopen?, onOpenChange?Composes MenuTrigger / MenuContent / MenuItem / MenuSeparator / MenuGroup / MenuCheckboxItem / MenuRadioGroup / MenuSubmenu. Uncontrolled by default.
MenuTrigger · asChildbooleanUse your own element (e.g. a Button) as the trigger.
MenuContent · align'start' | 'center' | 'end''start'Alignment along the trigger edge; side flips to stay in view.
MenuItem · onClick() => voidRuns on select; the menu closes unless closeOnClick is false.

Designed & built by stxkxs — React 19, Tailwind v4, and its own @shuttering/* packages.

Agent surfaces are always-on. Proprietary.

© stxkxs