@ai-created/ui
All components

Overlays

Modal family

A composable Headless UI modal shell for richer application layouts with header, body, and footer regions.

ModalOverlayModalPanelModalHeaderModalBodyModalFooterModalSize
View source

Component workbench

Configure the production component, inspect it at responsive widths, copy synchronized JSX, and share the exact state from one workspace.

Anatomy

Named regions define what belongs to the component, what remains optional, and where semantic responsibility lives.

1

Overlay

Required

Mounted dialog root, scroll container, backdrop, and focus scope.

2

Panel

Required

Bounded flex-column Surface.

3

Header

Required

Optional eyebrow, title, description, custom content, and close action.

4

Body

Required

Primary content region with optional internal scrolling.

5

Footer

Optional

Optional bordered action region.

Construction and authoring

The Figma-equivalent asset model, auto-layout, resizing, properties, slots, content bounds, localization, and governance contract.

Asset kind

component

Design library name

Components/Overlays/Modal

Maturity

stable

Last reviewed

2026-08-29

Canvas applicability

Publish a composable overlay component with panel, header, body, and footer slots.

Auto layout

Direction
vertical
Gap
0px between regions
Padding
16px viewport inset; region padding owned by subcomponents; close target pinned 6px from the header top and logical end
Alignment
Stretch
Wrap
Region content wraps

Resizing

Width
fill
Height
content-controlled
Minimum width
280px
Maximum width
sm 384px; md 512px; lg 672px; xl 896px
Minimum height
Content controlled
Maximum height
Viewport minus 32px
Overflow
auto

Exposed design properties

PropertyTypeDefaultCode mappingOptions or notes
OpenbooleanfalseConditional rendering of ModalOverlayNo additional constraint
SizevariantlgModalPanel.sizesm, md, lg, xl
Backdrop closesbooleantrueModalOverlay.closeOnBackdropNo additional constraint
Scrollable bodybooleantrueModalBody.scrollNo additional constraint
HeadingRequiredtextSettingsModalHeader.headingNo additional constraint
DescriptiontextNoneModalHeader.descriptionNo additional constraint
BodyRequiredslotNoneModalBody childrenNo additional constraint
FooterslotNoneModalFooter childrenNo additional constraint

Nested assets and slots

ModalOverlay

subcomponent / required

Backdrop, semantics, dismissal, and focus boundary.

ModalOverlay

ModalPanel

subcomponent / required

Sized modal surface.

ModalPanel

ModalHeader

subcomponent / required

Heading, optional description, and close control.

ModalHeader

ModalBody

subcomponent / required

Primary scroll region.

ModalBody

ModalFooter

subcomponent

Action region.

ModalFooter

Content limits

Heading

One line preferred, maximum two lines

Overflow: Wrap; never truncate.

The modal task should remain clear.

Footer actions

One primary and up to two secondary actions

Overflow: Move tertiary actions into body content.

A contained decision needs a clear hierarchy.

Body

One focused workflow

Overflow: Use a full page for broad or deeply nested tasks.

Modal interruption cost rises with complexity.

Localization and RTL

Translatable: Heading, Description, Body, Action labels

  • Header close action and footer alignment use logical sides.
  • Content follows locale direction.
  • Test long action labels.
  • Test body overflow and 200% zoom.
  • Test nested directional form controls.

Responsive behavior

Panel is viewport-constrained and body may scroll.

No internal breakpoint

  • Maintain 16px viewport inset.
  • On product-defined small screens, a full-height presentation may be composed outside this primitive.

Authoring limits

  • Figma nesting demonstrates structure but not portal, focus, inert background, or scroll-lock behavior.
  • Consumers own whether the ModalOverlay is mounted; this family has no open prop itself.

Accountable owner

Design systems overlay primitive owner

Canonical source: src/components/Modal.tsx

  • Subcomponent contracts and dismissal changes require overlay accessibility review.
  • A breaking property, token, or behavior change requires design and engineering approval, a migration note, and a major release.
  • The design asset, implementation, documentation, accessibility contract, and regression coverage must ship in the same change.
Read the system construction standard

Visual specification

These measurements and semantic tokens define the supported visual contract. Local overrides should preserve the same hierarchy and interaction cues.

Panel max width

384 / 512 / 672 / 896px

sm / md / lg / xl; shared with Dialog.

Panel max height

viewport − 48px mobile / viewport − 64px md+

Overlay padding

16px mobile / 24px md+

Top offset mobile

64px

Header padding

20px horizontal mobile / 24px md; 12px vertical

Body/footer padding

20px horizontal mobile / 24px md; 16px vertical

Close target

44 × 44px

Close glyph

24 × 24px

Close glyph inset

16px from top and logical end

Shared with Dialog; the target does not determine header height.

Rules

  • Compose regions only inside ModalPanel.
  • Use the shared overlay header and close-control pattern.
  • Hover strengthens the icon without drawing a border; keyboard focus retains the standard outline.
  • Keep a single scrollable body between fixed header and footer.
  • Use alertdialog role only for consequential confirmations.

Responsive behavior

  • Aligns near the top on small screens and centers from sm upward.
  • Body scrolls within a viewport-bounded panel.

Token dependencies

--color-overlay

Backdrop.

--color-surface / --color-border

Panel and dividers through Surface.

--color-text / --color-text2

Heading and description.

--radius-md

Panel radius.

States and behavior

A component is not complete until its passive, interactive, disabled, and exceptional states remain understandable in both themes.

closed

Trigger
ModalOverlay is not rendered.
Visual response
No modal UI.
Behavior
Page owns focus and scrolling.

open

Trigger
ModalOverlay is mounted.
Visual response
Blurred overlay and panel are visible.
Behavior
Headless UI traps focus, locks background interaction, and handles Escape.

nested

Trigger
A modal is opened from another focus scope.
Visual response
Higher-level modal remains visually subordinate.
Behavior
Use sparingly and verify focus restoration at each level.
Accessibility
Every dialog must retain a unique name.

focus-visible

Trigger
Keyboard focus reaches a control.
Visual response
The focused child component supplies its standard ring.
Behavior
Tab remains within the active dialog.

Accessibility contract

Semantics, accessible naming, keyboard behavior, focus and announcements are implementation requirements, not optional documentation.

Semantics
Headless UI Dialog; Header uses DialogTitle and Description, and alertdialog is supported.
Accessible name
ModalHeader heading supplies the name; description supplies supporting text.
  • Always include ModalHeader with a meaningful heading or provide an equivalent Headless UI title.
  • Supply an onClose control unless the operation intentionally prevents dismissal.
  • Keep footer action order and labels explicit.

Keyboard behavior

Escape
Requests onClose when supplied.
Tab / Shift+Tab
Cycles through focusable modal content.
Enter / Space
Activates the focused control.

Implementation

Use the public package API and preserve the controlled-state, native-attribute, and ref contracts described below.

tsx
import { ModalOverlay, ModalPanel, ModalHeader, ModalBody, ModalFooter } from '@ai-created/ui';

Client Component required

  • Render ModalOverlay conditionally; it is always open while mounted.
  • onClose is optional because ConfirmDialog can suppress dismissal while loading.
  • closeOnBackdrop affects pointer backdrop dismissal only.
  • ModalBody scroll defaults to true.
tsx
<ModalOverlay onClose={onClose}><ModalPanel><ModalHeader heading="Settings" onClose={onClose} /><ModalBody>...</ModalBody><ModalFooter>...</ModalFooter></ModalPanel></ModalOverlay>

Public API

These props and helpers are compatibility contracts. Changes require migration guidance and release notes.

PropTypeDefaultContract
ModalOverlay.onClose() => voidundefinedDismiss callback.
ModalOverlay.closeOnBackdropbooleantrueWhether backdrop clicks dismiss.
ModalPanel.sizeModalSizelgsm, md, lg, or xl.
ModalHeader.headingReactNoderequiredHeading content.
ModalHeader.onClose() => voidundefinedOptional close action.
ModalBody.scrollbooleantrueAllows the body region to scroll.
childrenReactNoderequiredContent for each region.

Usage guidance

These rules keep the component recognizable across products without preventing deliberate composition.

Do

  • Use for rich but bounded application tasks.
  • Keep the primary action in the footer and close action in the header.

Do not

  • Do not mount without a panel and title.
  • Do not place essential page navigation inside a modal.

Testing contract

The component should be verified as rendered UI, an interaction model, an accessibility surface, and a theme-aware visual artifact.

Unit

  • Maps the shared Dialog panel sizes and every region option.
  • Optional onClose behavior is deterministic.

Interaction

  • Escape, backdrop setting, 44px close button, focus trap, body scrolling, and restoration work.

Accessibility

  • Dialog naming, description, role, focus order, and inert background are valid.

Visual

  • Capture sizes, mobile top alignment, desktop centering, overflow, header/footer variants, and themes.

Related specifications