UI: Upgrade title validation to cleanup-based re-validation#77165
Conversation
|
Size Change: 0 B Total Size: 7.75 MB ℹ️ View Unchanged
|
|
Flaky tests detected in 501dc02. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/24553032732
|
e17da14 to
d07925b
Compare
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
d07925b to
afe743b
Compare
Extract a shared `useScheduleValidation` hook and refactor Dialog, Popover, and Tabs validation contexts to use it. Title registration now returns a cleanup function so that conditionally rendered titles are caught at runtime (dev only). - New `useScheduleValidation` hook in `packages/ui/src/utils/` - Dialog/Popover: `registerTitle` returns cleanup, mount effect schedules initial validation, errors thrown via `setTimeout` - Tabs: replace inline scheduling logic with the shared hook - Tests: switch from `TestErrorBoundary` to `collectUncaughtErrors`, add conditional-rendering test cases Made-with: Cursor
Enhancement entry for the cleanup-based re-validation improvement and internal entry for the shared useScheduleValidation hook. Made-with: Cursor
Reset `unmountedRef` to `false` at the start of the effect body so that StrictMode's mount → cleanup → re-mount cycle doesn't leave the flag permanently stuck at `true`. Made-with: Cursor
afe743b to
501dc02
Compare
What?
Follow-up to #76438.
Upgrade dev-only title validation in Dialog and Popover from mount-only to cleanup-based re-validation, so conditionally rendered titles are caught. Extract a shared
useScheduleValidationhook and refactor Tabs to use it too.Why?
The current validation only runs on mount (
useEffect([], [])). If a title is conditionally rendered (added/removed after mount), the check never re-fires, silently allowing an inaccessible dialog or popover.How?
useScheduleValidationhook that handles deferredsetTimeout(..., 0)scheduling and timer cleanup.registerTitlenow returns a cleanup function. Both register and unregister triggerscheduleValidation.useLayoutEffecttouseEffectwith cleanup.Implementation details
useScheduleValidationhook (packages/ui/src/utils/)validatecallback (ref-stored to avoid stale closures)scheduleValidationfunctionsetTimeout(..., 0)to let all registrations/unregistrations settleError mechanism change
Validation errors are now thrown inside
setTimeout(uncaught window errors) rather than during React's commit phase (error boundary). This is consistent with Tabs' existing behavior. Tests switch fromTestErrorBoundarytocollectUncaughtErrors.Files changed
utils/use-schedule-validation.tstabs/context.tsxdialog/context.tsxdialog/title.tsxuseEffectwith cleanupdialog/test/index.test.tsxcollectUncaughtErrors+ new testspopover/context.tsxpopover/title.tsxuseEffectwith cleanuppopover/test/index.test.tsxcollectUncaughtErrors+ new testsTesting Instructions
npm run test:unit packages/ui/src/dialog/test/index.test.tsxnpm run test:unit packages/ui/src/popover/test/index.test.tsxnpm run test:unit packages/ui/src/tabs/test/index.test.tsxUse of AI Tools
Cursor + Claude Opus 4.6