fix(cmdk): Keep CMDKAction nodes mounted across modal open/close cycles#112650
Merged
JonasBa merged 2 commits intojb/cmdk/jsx-pocfrom Apr 10, 2026
Merged
fix(cmdk): Keep CMDKAction nodes mounted across modal open/close cycles#112650JonasBa merged 2 commits intojb/cmdk/jsx-pocfrom
JonasBa merged 2 commits intojb/cmdk/jsx-pocfrom
Conversation
Selecting a group action and then closing and reopening the command palette caused the palette to show an empty state. The nav stack stored a useId() key that was tied to the CMDKAction component instance. When the modal closed, those instances unmounted and unregistered their keys from the collection store. On reopen, new instances generated new keys, leaving the stored key pointing to nothing. Fix by moving the slot outlets from CommandPalette (mounted only when the modal is open) into CommandPaletteProvider (always mounted). The outlets are rendered in a display:none container in task → page → global DOM order so that presortBySlotRef's compareDocumentPosition ordering is preserved. GlobalCommandPaletteActions is moved to the navigation component where it has org context and is always mounted, portaling into the provider's persistent global outlet. As a side effect, page-slot actions registered from page components are also stable across modal cycles for the same reason. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CommandPaletteProvider previously rendered a hidden div with three slot outlet elements. Because the global test wrapper includes CommandPaletteProvider, that hidden div showed up in every test's container, breaking tests that assert toBeEmptyDOMElement(). Move the outlets into UserAndOrganizationNavigation in navigation/index.tsx so they only exist when the full nav is mounted. CommandPaletteProvider becomes a pure context provider with no DOM output. Slot consumers and presortBySlotRef already degrade gracefully when outlets are absent, so tests unrelated to CMDK are unaffected. Slot-specific tests in commandPalette.spec.tsx and modal.spec.tsx now render a local SlotOutlets component explicitly, making their dependency on outlets visible rather than relying on a hidden side-effect in the provider. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Move CommandPalette Slot outside of the conditionally rendered CommandPalette which makes the action registration stable and enables the user to toggle the modal on/off without losing state