Skip to content

refactor(ui): adopt the dialog close confirmation - #9441

Open
maxyinger wants to merge 2 commits into
max/dialog-close-confirmationfrom
max/adopt-close-confirmation
Open

refactor(ui): adopt the dialog close confirmation#9441
maxyinger wants to merge 2 commits into
max/dialog-close-confirmationfrom
max/adopt-close-confirmation

Conversation

@maxyinger

@maxyinger maxyinger commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Description

  • org-profile edit form guards its close — pending edits raise "Discard changes?"
    • predicate is the machine's own dataChanged, exported as hasUnsavedEdits
    • its Cancel is now a Dialog.Close — was a bare send({ type: 'CANCEL' }) that bypassed onOpenChange
  • Destructive gets no confirmation — a delete in flight can't be called back
    • closedBy='none' while deleting, closerequest otherwise
    • Cancel disabled for the same window

Preview

Swingset links tbd

  • /organization/organization-profile-profile-section — real machine, fake 800ms update
  • /organization/organization-profile-delete-section — same for the delete
Discard changes Delete in flight
https://github.com/user-attachments/assets/44668267-78db-43a2-b5d3-c74cbb53c836 https://github.com/user-attachments/assets/f77723b8-6d60-40a2-aca5-a425e51f1750

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:

@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview Aug 13, 2026 11:11pm
swingset Ready Ready Preview Aug 13, 2026 11:11pm

Request Review

@changeset-bot

changeset-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 40d7533

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

@github-actions github-actions Bot added the ui label Aug 13, 2026
@maxyinger
maxyinger force-pushed the max/adopt-close-confirmation branch from 3a0462c to 0be4aff Compare August 13, 2026 17:35
maxyinger added a commit that referenced this pull request Aug 13, 2026
Disable `Destructive`'s Cancel while the delete is in flight, so the block
enforces the no-dismissal invariant its `closedBy` comment states instead
of relying on each consumer's machine to drop the event. Correct a comment
that named a corner X this dialog does not render.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger force-pushed the max/adopt-close-confirmation branch from 0be4aff to 677fdd2 Compare August 13, 2026 19:59
@pkg-pr-new

pkg-pr-new Bot commented Aug 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/electron

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

@clerk/electron-passkeys

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

@clerk/eslint-plugin

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

@clerk/expo

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

@clerk/expo-google-signin

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/hono

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

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

@clerk/upgrade

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

@clerk/vue

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

commit: 40d7533

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

API Changes Report

Generated by Break Check on 2026-08-13T23:15:23.982Z

Summary

Metric Count
Packages analyzed 19
Packages with changes 0
🔴 Breaking changes 0
🟡 Non-breaking changes 0
🟢 Additions 0

No API Changes Detected

All packages have stable APIs with no detected changes.


Report generated by Break Check

Last ran on 40d7533.

maxyinger added a commit that referenced this pull request Aug 13, 2026
Disable `Destructive`'s Cancel while the delete is in flight, so the block
enforces the no-dismissal invariant its `closedBy` comment states instead
of relying on each consumer's machine to drop the event. Correct a comment
that named a corner X this dialog does not render.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@maxyinger
maxyinger force-pushed the max/adopt-close-confirmation branch from 677fdd2 to 86ed2d0 Compare August 13, 2026 22:24
maxyinger and others added 2 commits August 13, 2026 17:08
Two dialogs that could throw work away, treated differently, because they are
different problems wearing the same description.

The org-profile edit form now guards its close: edits raise "Discard changes?"
instead of vanishing. The predicate is the machine's own `dataChanged`, exported
as `hasUnsavedEdits` rather than restated in the view, so the guard and the
SUBMIT guard cannot come to disagree about what an edit is. Typing a value and
undoing it therefore closes without a question, since nothing changed.

Its Cancel button was the live instance of the bypass the new hook's docs warn
about: wired to a bare `send({ type: 'CANCEL' })`, it went around
`onOpenChange` — so it was the one way out that discarded edits without asking,
including after this change. It is now a `Dialog.Close`, which funnels.

`Destructive` gets no confirmation, and that is the point. Its remaining bug is
closing mid-delete, and a confirmation is the wrong shape for it: the request
cannot be called back, so there is no answer that changes anything. It is simply
not dismissible while the delete is in flight (`closedBy='none'`), and
`closerequest` the rest of the time, as before. Asking "discard your typed text?"
on the way out of a confirmation dialog would be a confirmation to escape a
confirmation.

Neither dialog asks while its request is in flight: `CANCEL` is not a transition
the `saving` state accepts either, so a question there would be one whose answer
changes nothing.
Disable `Destructive`'s Cancel while the delete is in flight, so the block
enforces the no-dismissal invariant its `closedBy` comment states instead
of relying on each consumer's machine to drop the event. Correct a comment
that named a corner X this dialog does not render.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant