overlays
Dialog
A standard modal dialog — scrim, focus trap and Escape — with no shared-element continuity to its trigger.
- overlays
- dialog
- modal
- confirmation
Plain modal semantics; Morph remains the shared-element continuity route.
Live preview
Quick usage
import { Dialog } from "@pinky-ui/systems";
<Dialog open={open} onOpenChange={setOpen} title="Delete project?" description="This cannot be undone." footer={<button onClick={confirm}>Delete</button>} />Presets
Default
Restrained production behaviour.
Default behaviour
Quiet
Reduced intensity for dense product screens.
disabled={true}
Install
Add @pinky-ui/systems as a dependency, or use the CLI to copy this component's source directly into your project — no dependency to manage, fully editable.
npm install @pinky-ui/systemspnpm add @pinky-ui/systemsyarn add @pinky-ui/systemsnpx pinky-ui add dialogPrefer to run the whole repository locally instead?
git clone https://github.com/florash/Pinky-UI.git
cd Pinky-UI
npm install
npm run devProps
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | — | Controlled open state. |
| className | string | — | Styles the outer interaction surface. |
Accessibility
- Keyboard and touch paths match the pointer interaction.
- Stable labels and values remain available without motion.
Performance
- The panel mounts only while open; no scroll-lock or listener persists when closed.
Reduced motion
Motion resolves immediately while semantics, focus and state remain unchanged.
When to use
- Confirmations, settings and content opened from more than one place
When not to use
- A dialog that should read as the same object as its trigger — use Morph
Skill
Purpose
A standard modal dialog — scrim, focus trap, Escape, focus restoration — with no shared-element continuity to whatever opened it. Use it for confirmations, settings and anything that can be opened from more than one place.
Interaction anatomy
- Opens as a plain fade-and-scale surface, not a shared-layout expansion.
- Escape closes it; clicking the scrim closes it; a visible close button closes it.
- Focus moves into the panel on open and returns to whatever triggered it on close.
- Tab is trapped inside the panel while open.
Good for
- Confirmations, especially destructive ones
- Settings panels and forms opened from more than one entry point
- Any modal content where "this is the same object as the trigger" isn't true
Avoid for
- A surface that should read as the same object as what opened it — that's [[morph]]
- Content large enough to need its own scroll region and a persistent trigger relationship — consider a sheet instead on mobile
Usage
<Dialog
open={open}
onOpenChange={setOpen}
title="Delete project?"
description="This cannot be undone."
footer={<button onClick={confirmDelete}>Delete</button>}
/>Accessibility
role="dialog",aria-modal="true"and an accessible label are set automatically fromtitle.- Focus moves to the first focusable element on open and Tab cannot escape the panel.
- Closing — by Escape, scrim click or the close button — always returns focus to whatever had it before the dialog opened.
Performance
The panel and its scrim mount only while open is true; no scroll-lock, listener or trapped-tab handler persists once it's closed.
Composes with
Nothing needs to nest inside a Dialog beyond ordinary form and button content — it doesn't compose with other primitives so much as host them. Don't nest a Dialog inside a Morph panel or vice versa; pick one modal system for a given flow.