Modal
Centered overlay dialog on Ark UI's Dialog machine — focus trap, scroll lock, RTL and animated enter/exit, with a flat props API and composable parts.
The Modal is a centered overlay built on Ark UI's Dialog state machine. Ark owns focus-trapping, body scroll-lock, RTL, the Esc / click-outside behaviour and the data-state attribute that drives the enter/exit animations; the kit adds a flat props API plus styled, composable parts.
import { Modal } from '@42/ui-react/modal';
<Modal open={open} onOpenChange={setOpen} title="Welcome">
<Text>Anything you like in the body.</Text>
</Modal>To spawn modals imperatively — without useState at every call site — use the overlays manager.
Basic usage
open / onOpenChange make the modal a controlled component. onOpenChange is flattened to (open: boolean) => void.
Code
const [open, setOpen] = useState(false);<Button onClick={() => setOpen(true)}>Open modal</Button><Modal open={open} onOpenChange={setOpen} title="Welcome aboard"><Text>Focus is trapped and the page is scroll-locked while open.</Text></Modal>Sizes
size maps to the kit's width tokens (xs–xl), plus full for a near-fullscreen sheet.
Code
<Modal size="sm" … /><Modal size="md" … /> // default<Modal size="lg" … /><Modal size="xl" … />Centered
By default the modal anchors near the top of the viewport (so tall content grows downward). Set centered to vertically center it.
Code
<Modal centered title="Centered" … />Description & close button
title and description render the header; withCloseButton (default true) adds a dogfooded ActionIcon close button.
Code
<Modaltitle="Delete file"description="This action cannot be undone."withCloseButton={false}/>Composable parts
The high-level <Modal> covers the common case. For full control over structure, compose the parts directly — they carry the same styling and Ark wiring:
<Modal.Root open={open} onOpenChange={({ open }) => setOpen(open)}>
<Modal.Trigger asChild>
<Button>Open</Button>
</Modal.Trigger>
<Modal.Backdrop />
<Modal.Positioner centered>
<Modal.Content size="md">
<Modal.Header>
<Modal.Title>Custom layout</Modal.Title>
<Modal.CloseTrigger />
</Modal.Header>
<Modal.Body>…</Modal.Body>
<Modal.Footer>
<Button variant="default">Cancel</Button>
<Button>Save</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Positioner>
</Modal.Root>API
Prop
Type
All other props (modal, trapFocus, preventScroll, id, lazyMount, …) forward to Ark's Dialog.Root.
Accessibility
- Ark traps focus inside the content while open and restores it to the trigger on close.
- The body is scroll-locked (
preventScroll) and content below is hidden from assistive tech (modal). titlewiresaria-labelledbyanddescriptionwiresaria-describedbyautomatically. When you omit atitle, pass anaria-label.- Animations collapse to a 1ms opacity tween under
prefers-reduced-motion.
Tooltip
A hover/focus hint on Ark UI's Tooltip — ARIA-wired (role="tooltip" + aria-describedby), portaled and animated. Drops into running text or wraps any element.
Drawer
Edge-anchored panel on Ark UI's Drawer machine — swipe-to-dismiss, snap points and a drag grabber, with an RTL-aware placement prop.