Overlays
All overlays are built on Radix primitives, so focus trap, Esc,
scroll lock, ARIA roles, and keyboard navigation are correct by construction. We supply the
styling with adaptive tokens — pass surface="dark" to theme any overlay for the dark shell.
No backdrop blur (brand rule).
import { Modal } from '@repo/ui/overlay';
const [open, setOpen] = useState(false);<Modal open={open} onOpenChange={setOpen} title="Submit order?" description="…" footer={<><Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button> <Button onClick={submit}>Submit</Button></>}> Body content</Modal>title is required (wired to the accessible name). Props: open, onOpenChange, title,
description?, size? (sm|md|lg|xl), surface?, trigger?, footer?.
Drawer
Section titled “Drawer”Same API as Modal plus side (right|left) and width. A full-height slide-over.
Tooltip
Section titled “Tooltip”<Tooltip label="Archive"><button aria-label="Archive">…</button></Tooltip>Always ink (reads the same on any surface). The child must accept a ref (Radix asChild).
Popover
Section titled “Popover”<Popover trigger={<Button>Info</Button>} side="bottom" align="center">…</Popover>Floating panel with collision handling; surface-aware.
DropdownMenu
Section titled “DropdownMenu”<DropdownMenu trigger={<Button>Actions ▾</Button>}> <DropdownMenu.Label>Order</DropdownMenu.Label> <DropdownMenu.Item onSelect={archive}>Archive</DropdownMenu.Item> <DropdownMenu.Separator /> <DropdownMenu.Item danger onSelect={remove}>Delete</DropdownMenu.Item></DropdownMenu>CommandPalette
Section titled “CommandPalette”import { CommandPalette } from '@repo/ui/overlay';
<CommandPalette open={open} onOpenChange={setOpen} commands={[ { id: 'inbox', label: 'Go to inbox', hint: 'g i', onSelect: goInbox }, { id: 'archive', label: 'Archive order', keywords: ['remove'], onSelect: archive },]} />A Cmd+K palette on Radix Dialog + fuzzysort (filters across label, hint, group,
keywords). Implements the combobox/listbox pattern: arrow keys move the active option
(aria-activedescendant), Enter selects, Esc closes. Wire your own ⌘K shortcut to toggle open.
Replaces the app’s three ad-hoc Cmd+K variants.
Do / don’t
Section titled “Do / don’t”- Do give icon-only triggers an
aria-label(and aTooltipfor sighted users). - Do keep modal copy short; one primary action in the footer.
- Don’t nest a Drawer inside a Modal, or add backdrop blur.
- Don’t hand-roll focus traps — that’s why these exist.
Accessibility
Section titled “Accessibility”- Focus trap + restore,
Esc, scroll lock,role/aria-modal/aria-haspopup, arrow-key menu nav — all from Radix. Modal/Drawer verified withjest-axe;color-schemematches the overlay’s surface so native controls inside render correctly.