Dialog
Dialog presents a focused modal task or information surface above the current page. Atom owns modal state, focus, dismissal, portals, background isolation, scroll containment, and presence; Brick supplies the finished visual anatomy.
Built from the published package
Know when Dialog is the right part
Use it when
Use Dialog for short forms, settings, details, previews, and multi-control tasks that temporarily block interaction with the page.
Choose another path when
Use a future AlertDialog for urgent destructive confirmation, Drawer for side-attached modal content, and Popover or Menu when the page must remain interactive.
Dialog is modal-only. It does not own application workflow, submission, data loading, routing, or generated action copy.
Installation and imports
The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:
Add the modular stylesheet for every other Brick component the route renders.
Do not combine modular styles with styles.css or tokens.css.
The namespace is also available from @flowstack-ui/brick. Advanced consumers
may import the canonical direct parts from the Dialog subpath.
Quick start
Overlay and Content must remain siblings. Nesting Content inside Overlay places the dialog inside an accessibility-hidden subtree and is rejected by Atom.
Visual recipes and states
Content supports sm, md, and lg; md is the default. Atom's public
data-state, data-positioned, and disabled outputs drive open, closed,
positioned, and unavailable styling. Dialog intentionally has no tone, variant,
placement, fullscreen, or arbitrary-width prop.
Examples
Portals, scopes, and Branch
A default body portal uses document-level tokens. To retain a scoped theme, portal into an element inside that scope or render inline:
Register third-party content that must portal outside Content:
Prefer placing the third-party portal inside Content when its API supports a container. Branch preserves the third party's keyboard model while keeping it inside the active modal boundary.
API
Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.
Public exports are the Dialog namespace; named DialogRoot,
DialogTrigger, DialogPortal, DialogOverlay, DialogContent,
DialogHeader, DialogTitle, DialogDescription, DialogBody,
DialogFooter, DialogClose, and DialogBranch parts; and their
corresponding prop types plus DialogSize.
Root
Forwards Atom's open, defaultOpen, onOpenChange, closeOnEscape,
closeOnBackdropClick, disabled, and keepMounted contract. Root renders no
DOM element and has no ref.
Content
| Prop | Values | Default |
|---|---|---|
size | sm, md, lg | md |
Size changes
the preferred maximum inline measure only. Content also forwards native ARIA,
role, initialFocus, and finalFocus supported by Atom.
Portal and Overlay
Portal forwards container and disabled. A container must be a same-document
HTMLElement. Overlay forwards its independent disabled dismissal control.
Trigger, Close, and Branch
These parts forward Atom's asChild and render composition. The composed
element must accept the merged props and ref and retain valid semantics.
Title
Title defaults to h2; as accepts h1 through h6. A visible Title supplies
the generated accessible name. Consumers that intentionally omit it must add
an explicit native aria-label or aria-labelledby to Content.
Accessibility
Title supplies the accessible name and Description supplies the optional
accessible description. If Title is intentionally omitted, Content requires an
explicit native aria-label or aria-labelledby. Consumers keep action labels
clear and preserve a logical source and focus order.
Keyboard and focus
| Input | Result |
|---|---|
| Enter or Space on Trigger | Opens through native/composed control behavior |
| Tab | Advances within the active modal and owned branches |
| Shift+Tab | Moves backward within the active modal |
| Escape | Closes only the top Dialog when enabled |
Focus enters according to Atom's interaction-aware policy and restores to an
explicit finalFocus, the prior connected target, or the mounted Trigger.
Touch opening avoids focusing the first input automatically unless native
autoFocus or explicit initialFocus requests it.
Responsive behavior
Content is centered and bounded by safe-area-aware viewport gaps and dynamic viewport height. Body uses contained scrolling so Header and Footer remain reachable with long content. All sizes shrink to available width. Footer wraps without reversing action or focus order, and logical properties support RTL.
Styling and tokens
Customization
Prefer the documented size prop and semantic tokens first, then the five
component tokens above. Use part-level classes, slots, className, and style
only for localized needs that cannot be expressed through those supported
contracts.
Tokens and CSS hooks
Stable classes and default slots are:
| Part | Class | Slot |
|---|---|---|
| Trigger | .brick-dialog-trigger | dialog-trigger |
| Overlay | .brick-dialog-overlay | dialog-overlay |
| Content | .brick-dialog-content | dialog-content |
| Header | .brick-dialog-header | dialog-header |
| Title | .brick-dialog-title | dialog-title |
| Description | .brick-dialog-description | dialog-description |
| Body | .brick-dialog-body | dialog-body |
| Footer | .brick-dialog-footer | dialog-footer |
| Close | .brick-dialog-close | dialog-close |
| Branch | .brick-dialog-branch | modal-branch |
Content exposes these component tokens:
--brick-dialog-max-inline-size--brick-dialog-max-block-size--brick-dialog-space--brick-dialog-radius--brick-dialog-shadow
Atom owns data-state and data-positioned; Content adds data-size. Brick
honors reduced motion and forced colors. Consumers own accessibility and layout
verification after arbitrary class, style, or token overrides.
Advanced reference
Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.