Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat(headless): dialog stacking state and alertdialog role by maxyinger · Pull Request #9427 · clerk/javascript · GitHub
Skip to content

feat(headless): dialog stacking state and alertdialog role - #9427

Merged
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state
Aug 14, 2026
Merged

feat(headless): dialog stacking state and alertdialog role#9427
maxyinger merged 3 commits into
mainfrom
max/dialog-stacking-state

Conversation

@maxyinger

@maxyingermaxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • updates ARIA role to accept 'dialog' or 'alertdialog' and defaults to 'dialog'
  • Adds data-stackeddata-stack-base
    • needed for panel → prompt → alert stack
    • allows for styling deviations for nested modals beyond data-nested
    • data-nested still exists with existing behavior

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

@changeset-bot

changeset-botBot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a0b22cc

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
clerk-js-sandboxReadyReadyPreviewAug 14, 2026 8:37pm
swingsetReadyReadyPreviewAug 14, 2026 8:37pm

Request Review

@coderabbitai

coderabbitaiBot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ee24454-c9d6-4afd-b403-7ff527ec792f

📥 Commits

Reviewing files that changed from the base of the PR and between 3e567d0 and 677b258.

📒 Files selected for processing (1)
  • .changeset/dialog-stacking-state.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/dialog-stacking-state.md

📝 Walkthrough

Walkthrough

The Dialog primitive supports dialog and alertdialog roles. It tracks open and mounted nested dialogs. Dialog popups and backdrops expose stacking and exit-state data attributes. Documentation and tests cover nested stacks, closing dialogs, exit transitions, three-level stacks, and dialogs inside popovers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score:⚪ Minimal · up to 677b2

This PR updates headless dialog semantics and stacking state; no actionable merge-blocking risk remains beyond normal checks and review.

Suggested reviewers:austincalvelage

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Title check✅ PassedThe title clearly summarizes the two main changes: dialog stacking state and support for the alertdialog role.
Description check✅ PassedThe description directly explains the new ARIA role support, stacking attributes, tests, build status, and feature classification.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-newBot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@9427

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@9427

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@9427

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@9427

@clerk/electron

npm i https://pkg.pr.new/@clerk/electron@9427

@clerk/electron-passkeys

npm i https://pkg.pr.new/@clerk/electron-passkeys@9427

@clerk/eslint-plugin

npm i https://pkg.pr.new/@clerk/eslint-plugin@9427

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@9427

@clerk/expo-google-signin

npm i https://pkg.pr.new/@clerk/expo-google-signin@9427

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@9427

@clerk/express

npm i https://pkg.pr.new/@clerk/express@9427

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@9427

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@9427

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@9427

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@9427

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@9427

@clerk/react

npm i https://pkg.pr.new/@clerk/react@9427

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@9427

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@9427

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@9427

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@9427

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@9427

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@9427

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@9427

commit: a0b22cc

@coderabbitaicoderabbitaiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/headless/src/primitives/drawer/drawer-context.ts (1)

33-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten the rationale comment.

The Omit change is correct, but the multi-line rationale is longer than needed. Keep the explanation to one terse line that states why drawer context excludes dialog stacking state.

As per coding guidelines, “Keep code comments minimal. Add comments only when critical to explain why a non-obvious change was made; never restate code behavior, and keep warranted comments to one terse line rather than a verbose multi-line block.”

Suggested change
-//-//-// The stacking pair goes with them. A drawer already counts its own nesting as-// `nestedOpenCount` / `onNested`, which is a different question from the dialog's: `isStacked`-// asks whether a DIALOG sits above, and a drawer's stacked-child styling has nothing to read it-// from. Inheriting them would oblige every drawer root to publish two values no drawer part uses.+// Drawer nesting uses `nestedOpenCount`; dialog stacking state does not belong in this context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/headless/src/primitives/drawer/drawer-context.ts` around lines 33 -
38, Shorten the comment immediately above DrawerContextValue to one terse line
explaining that drawer context excludes dialog-only stacking state. Keep the
existing Omit<DialogContextValue, 'isStacked' | 'stackedChildCount' | 'store'>
declaration unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/headless/src/primitives/drawer/drawer-context.ts`:
- Around line 33-38: Shorten the comment immediately above DrawerContextValue to
one terse line explaining that drawer context excludes dialog-only stacking
state. Keep the existing Omit<DialogContextValue, 'isStacked' |
'stackedChildCount' | 'store'> declaration unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d2e396e-5086-4c87-9364-d1a7a3719544

📥 Commits

Reviewing files that changed from the base of the PR and between b39c5a1 and fb78cab.

📒 Files selected for processing (1)
  • packages/headless/src/primitives/drawer/drawer-context.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • clerk/clerk_go(manual)
  • clerk/dashboard(manual)
  • clerk/accounts(manual)
  • clerk/backoffice(manual)
  • clerk/clerk(manual)
  • clerk/clerk-docs(manual)
  • clerk/cloudflare-workers(manual)
  • clerk/clerk-ios(auto-detected)
  • clerk/cli(auto-detected)
  • clerk/clerk-android(auto-detected)

maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from fb78cab to 3e567d0CompareAugust 13, 2026 19:58
Comment threadpackages/headless/src/primitives/dialog/dialog-backdrop.tsx
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 3e567d0 to 677b258CompareAugust 13, 2026 22:24
maxyinger added a commit that referenced this pull request Aug 13, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from 677b258 to a33c2bbCompareAugust 13, 2026 23:08
maxyinger added a commit that referenced this pull request Aug 14, 2026
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyingerforce-pushed the max/dialog-stacking-state branch from a33c2bb to fa30752CompareAugust 14, 2026 15:01
maxyingerand others added 3 commits August 14, 2026 14:34
Adds the two signals the Mosaic stacking styles need, and the role an
AlertDialog preset needs.
`data-stacked` / `data-stack-base` describe dialog-on-dialog specifically,
in both directions of the relationship. `data-nested` could not: it reports
any floating ancestor, so a dialog opened from a menu item reads as nested
while sitting on the bare page. Under the incoming rule that a stacked
dialog paints no backdrop, styling off `data-nested` would leave that
dialog with no scrim at all.
The child registers with its parent while OPEN rather than while mounted,
so a dialog beneath comes forward with its child's exit transition rather
than after it. The count is of direct children only, which is enough for
the single recede step that exists.
`DrawerContextValue` inherits from `DialogContextValue`, so adding `isStacked`
and `stackedChildCount` there made every drawer root fail to satisfy its own
context — `tsc --noEmit` was red for the whole package, and for swingset, which
typechecks headless from source.
They belong in the same `Omit` as `store`. A drawer already tracks its nesting
as `nestedOpenCount`, and `isStacked` asks a question about DIALOGS that a
drawer has nothing to answer with.
Publish "still covering" rather than the raw `open` flag from
`DialogNestingContext`, so a stacked child keeps `data-stacked` for the
length of the parent's exit instead of painting a second scrim over the
parent's fading one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger merged commit c2bd42c into mainAug 14, 2026
67 of 83 checks passed
@maxyinger
maxyinger deleted the max/dialog-stacking-state branch August 14, 2026 23:28
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@maxyinger@alexcarpenter@austincalvelage