Skip to content

fix(Dialog): improve responsive presentation behavior - #5352

Open
rubyycheung wants to merge 2 commits into
mainfrom
fix/dialog-responsive-interaction
Open

fix(Dialog): improve responsive presentation behavior#5352
rubyycheung wants to merge 2 commits into
mainfrom
fix/dialog-responsive-interaction

Conversation

@rubyycheung

@rubyycheung rubyycheung commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • clamp standard Dialog width to the container and dynamic viewport with spacing-token gutters, preserving consumer width as the preferred surface width
  • switch Dialog's default max height from 75vh to 75dvh, add safe-area-aware padding for fullscreen Dialog content, and make fullscreen open with fade-only motion instead of the centered Dialog translate/scale
  • add honest wide/narrow Dialog Storybook layout references plus explicit mobile presentation alternatives: keep Dialog, fullscreen Dialog, or BottomSheet
  • add an opt-in DialogAdaptivePresentation block recipe showing an AdaptiveDialog wrapper: Dialog remains the default everywhere, and callers may explicitly opt into BottomSheet only for touch-oriented <=lg contexts

Responsive and Interaction Readiness outcomes

Responsive layout

Check Result Evidence
Wide viewport layout Pass Existing Dialog stories plus Core/Dialog -- Readiness / wide viewport; requested 400px/default width remains the preferred surface width.
Narrow viewport layout Pass Core/Dialog -- Readiness / narrow viewport; standard Dialog now emits max-width: min(100%, calc(100dvw - var(--spacing-4) - var(--spacing-4))).
Content fit / wrapping / overflow Pass Dialog body remains in the existing flex/scroll wrapper; tests assert the emitted width clamp and max-height variables; narrow story uses wrapping footer buttons.

Touch, pointer, and hover

Check Result Evidence
Narrow viewport + coarse pointer + no hover Pass Core Dialog has no pointer/hover media branch; geometry remains width-driven. Storybook references are visual viewport/layout references only, not pointer emulation.
Wide viewport + coarse pointer + no hover Pass Core Dialog does not force narrow/mobile geometry from coarse pointer state.
Hover independence Pass Required actions are visible buttons; no required action or information depends on hover.
Gestures and alternatives N/A for Core Dialog Core Dialog adds no custom gesture behavior. Gesture adaptation exists only in the explicit BottomSheet recipe, where callers knowingly opt into BottomSheet dismissal semantics.

Accessibility and interaction contracts

Check Result Evidence
WCAG 2.2 AA target size Pass Dialog actions use Button sizing; default md Button is 32px, above SC 2.5.8's 24x24 CSS px minimum. No 44/48 guidance is introduced.
Semantics Pass Native <dialog>, aria-modal, DialogHeader labeling, and alertdialog only for purpose="required" remain unchanged and covered by existing tests.
Keyboard/focus/dismissal Pass Existing Dialog/DialogHeader tests cover Escape behavior, purpose mapping, accessible name precedence, title focus, and focus restoration paths; AlertDialog tests pass against the shared Dialog changes.
Reduced motion Pass Standard Dialog keeps the existing directional translate/scale entrance and reduced-motion disable. Fullscreen Dialog now uses a separate opacity-only entrance, also disabled under prefers-reduced-motion: reduce.

Mobile viewport constraints

Check Result Evidence
Dynamic viewport sizing Pass Default maxHeight is now 75dvh; standard Dialog width clamp uses 100dvw.
Safe-area insets Pass Fullscreen Dialog inner padding uses max(existing token padding, env(safe-area-inset-* , 0px)), preserving the spacing-token floor while honoring larger safe-area insets.
Software keyboard Partial / improved dvh improves dynamic viewport sizing where supported, and the adaptive recipe uses BottomSheet height="tall" for keyboard-heavy forms. This does not prove keyboard occlusion handling for every Dialog/browser/content combination.
Scroll behavior Pass Existing flex wrapper and scroll support remain in place; tests keep the wrapper path attached.

Presentation choice

Dialog remains the default component and default presentation. This PR does not add automatic BottomSheet behavior to Core Dialog and does not introduce a universal adaptive component.

The new recipe demonstrates component substitution only when a caller explicitly opts in:

  • touchPresentation="dialog" keeps Dialog even in touch-oriented <=lg contexts.
  • touchPresentation="fullscreen" chooses fullscreen Dialog for touch-oriented <=lg contexts.
  • touchPresentation="bottom-sheet" chooses BottomSheet only when (max-width: 1024px) and (pointer: coarse) and (hover: none) matches.
  • Narrow fine-pointer environments remain Dialog unless the deterministic presentation override says otherwise.
  • presentation="dialog" | "fullscreen" | "bottom-sheet" provides a deterministic override for tests and unusual environments.
  • isOpen, onOpenChange, purpose, and accessible label/title contracts are aligned across presentations.
  • BottomSheet's purpose mapping controls swipe and scrim dismissal (form blocks swipe/scrim, info allows them, required blocks implicit dismissal), so callers choose the adaptive presentation knowingly.
  • The recipe is for touch-oriented form/detail contexts; AlertDialog/destructive confirmations should stay on Dialog by default.

Local Storybook review

Storybook is running locally on port 6007. Useful story IDs:

  • core-dialog--readiness-wide-viewport
  • core-dialog--readiness-narrow-viewport
  • core-dialog--mobile-presentation-keep-dialog
  • core-dialog--mobile-presentation-fullscreen-dialog
  • core-dialog--mobile-presentation-bottom-sheet

Validation

All of these passed locally:

  • pnpm exec prettier --check packages/core/src/Dialog/Dialog.tsx packages/core/src/Dialog/Dialog.test.tsx apps/storybook/stories/Dialog.stories.tsx packages/cli/assets/templates/blocks/components/Dialog/DialogAdaptivePresentation.tsx packages/cli/assets/templates/blocks/components/Dialog/DialogAdaptivePresentation.doc.mjs .changeset/dialog-responsive-interaction.md
  • pnpm exec vitest run packages/core/src/Dialog/Dialog.test.tsx packages/core/src/Dialog/DialogHeader.test.tsx packages/core/src/AlertDialog/AlertDialog.test.tsx
  • pnpm exec vitest run packages/cli/clients/cli/commands/dialog-adaptive-template.test.mjs
  • pnpm -F @astryxdesign/cli astryx template DialogAdaptivePresentation plus checks for touchPresentation="bottom-sheet", TOUCH_ORIENTED_LG_QUERY, and presentation prop
  • pnpm -F @astryxdesign/cli astryx component Dialog --dense
  • pnpm -F @astryxdesign/core typecheck
  • pnpm -F @astryxdesign/core typecheck:docs
  • pnpm -F @astryxdesign/storybook typecheck
  • pnpm -F @astryxdesign/cli typecheck:template-docs
  • pnpm exec eslint packages/core/src/Dialog/Dialog.tsx packages/core/src/Dialog/Dialog.test.tsx apps/storybook/stories/Dialog.stories.tsx packages/cli/assets/templates/blocks/components/Dialog/DialogAdaptivePresentation.tsx packages/cli/clients/cli/commands/dialog-adaptive-template.test.mjs
  • pnpm check:changesets
  • pnpm check:repo
  • pnpm lab:readiness:check
  • git diff --check

Relationship

Independent of AlertDialog #5343 and the Responsive and Interaction Readiness rubric #5351. Neither unmerged PR is a dependency.

@vercel

vercel Bot commented Aug 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview Aug 23, 2026 5:45am

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Aug 23, 2026
@github-actions github-actions Bot added the needs:code-review High-risk change (new package/component/API) — needs human code review before merge label Aug 23, 2026
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

Modified Components

Dialog (@astryxdesign/core) · View in Storybook
Metric Before After Delta
Bundle Size (ESM) N/A N/A N/A
Lines of Code N/A 668 -
Complexity N/A Very High (80) -

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.8KB 1.2KB

Accessibility Audit

Status: No accessibility violations detected.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

github-actions Bot added a commit that referenced this pull request Aug 23, 2026
@rubyycheung
rubyycheung marked this pull request as ready for review August 23, 2026 05:49
github-actions Bot added a commit that referenced this pull request Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot. needs:code-review High-risk change (new package/component/API) — needs human code review before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant