Skip to content

Comments

Extract reusable "descendant registry" pattern from ActionBar, with new support for reordering elements#7586

Merged
iansan5653 merged 2 commits intodescendant-registry-patternfrom
copilot/sub-pr-7585
Feb 24, 2026
Merged

Extract reusable "descendant registry" pattern from ActionBar, with new support for reordering elements#7586
iansan5653 merged 2 commits intodescendant-registry-patternfrom
copilot/sub-pr-7585

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

Adds unit tests for createDescendantRegistry and fixes a bug where pure item reordering (no mounts/unmounts/value changes) failed to update the registry order.

Changelog

New

  • Unit tests for createDescendantRegistry covering: descendants inside wrapper components, React fragments, mid-list insertion, unmounting, reordering via key, and deep-tree prepending

Changed

  • createDescendantRegistry Provider now detects when children reference changes without any descendant lifecycle events (the reorder case) and triggers a full rebuild, so the registry always reflects the current render order

Root cause of the reorder bug: When items are reordered using React key props (no remount), no child effects re-run because no hook dependencies change. The commitWorkingRegistry effect was a no-op in the idle state, so the registry stayed stale.

Fix: Track prevChildrenRef in commitWorkingRegistry. When children changes but no descendant fired a register/unregister (i.e., workingRegistryRef is still 'idle'), queue a rebuild — this increments key in context, causing all children to re-run their effects in the new DOM order.

useEffect(function commitWorkingRegistry() {
  const childrenChanged = prevChildrenRef.current !== children
  prevChildrenRef.current = children

  if (workingRegistryRef.current instanceof Map) {
    setRegistry(workingRegistryRef.current)
    workingRegistryRef.current = 'idle'
  } else if (workingRegistryRef.current === 'idle' && childrenChanged) {
    // Reorder detected — rebuild so items re-register in new render order
    workingRegistryRef.current = 'queued'
    setKey(prev => prev + 1)
  }
})

Removed

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Testing & Reviewing

Six new tests in packages/react/src/utils/__tests__/descendant-registry.test.tsx. Each test creates an isolated registry via a createTestRegistry() factory to prevent cross-test context leakage.

Merge checklist


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@changeset-bot
Copy link

changeset-bot bot commented Feb 23, 2026

⚠️ No Changeset found

Latest commit: 628c90e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

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

Click here to learn what changesets are, and how to add one.

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

Co-authored-by: iansan5653 <2294248+iansan5653@users.noreply.github.com>
Copilot AI changed the title [WIP] Extract reusable descendant registry pattern from ActionBar Extract reusable "descendant registry" pattern from ActionBar, with new support for reordering elements Feb 23, 2026
@iansan5653 iansan5653 marked this pull request as ready for review February 24, 2026 13:38
@iansan5653 iansan5653 requested a review from a team as a code owner February 24, 2026 13:38
@iansan5653 iansan5653 merged commit d55720d into descendant-registry-pattern Feb 24, 2026
@iansan5653 iansan5653 deleted the copilot/sub-pr-7585 branch February 24, 2026 13:38
Sign up for free to 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.

2 participants