Skip to content

feat(Combobox): add unmountOnHide prop - #2842

Open
onmax wants to merge 2 commits into
unovue:v2from
onmax:feat/combobox-unmount-on-hide
Open

feat(Combobox): add unmountOnHide prop#2842
onmax wants to merge 2 commits into
unovue:v2from
onmax:feat/combobox-unmount-on-hide

Conversation

@onmax

@onmax onmax commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

Follows the Dialog precedent in #2662.

❓ Type of change

  • 📖 Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Adds unmountOnHide to ComboboxRoot, defaulting to true. When false, content stays mounted but hidden while closed, preserving expensive option subtrees and internal state across open cycles.

Closed persistent content is excluded from focus, dismissal, body-scroll-lock, and surrounding-content ARIA behavior. ComboboxContent.forceMount keeps its existing low-level semantics. Tests cover persistence, unchanged defaults, event safety, body-lock changes, multiple instances, and cleanup.

📸 Screenshots (if appropriate)

Not applicable.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

Summary by CodeRabbit

  • New Features

    • Added the unmountOnHide option to Combobox, defaulting to true.
    • Combobox content can remain mounted and visually hidden when closed by setting unmountOnHide to false.
    • Autocomplete retains its default unmounting behavior.
  • Bug Fixes

    • Improved focus restoration, scrolling, dismissal, portal cleanup, and Escape-key handling for persistent Combobox content.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Combobox adds the unmountOnHide option. Closed content remains mounted and hidden when the option is false. Presence-aware handling updates focus, dismissal, scroll locking, and portal behavior. Autocomplete keeps the default unmounting behavior.

Changes

Combobox unmount-on-hide

Layer / File(s) Summary
Option and context wiring
packages/core/src/Combobox/ComboboxRoot.vue, packages/core/src/Autocomplete/AutocompleteRoot.vue, packages/core/src/Combobox/story/*, docs/content/meta/ComboboxRoot.md
Adds the optional unmountOnHide prop with a default of true, provides it through the root context, enables it for Autocomplete, and documents the option.
Presence-aware content lifecycle
packages/core/src/Combobox/ComboboxContent.vue, packages/core/src/Combobox/ComboboxContentImpl.vue
Uses presence state to control mounting, visibility, body scroll locking, focus restoration, dismissal, and popper props.
Persistent content validation
packages/core/src/Combobox/Combobox.test.ts
Tests persistent DOM and internal state, focus restoration, hidden interaction handling, scroll locking, portal cleanup, multiple instances, and default unmounting.

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

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant ComboboxRoot
  participant ComboboxContent
  participant Presence
  participant ComboboxContentImpl
  participant FocusScope
  participant DismissableLayer
  ComboboxRoot->>ComboboxContent: Provide unmountOnHide
  ComboboxContent->>Presence: Derive forceMount
  Presence->>ComboboxContentImpl: Pass present and visibility
  ComboboxContentImpl->>FocusScope: Pass present state
  ComboboxContentImpl->>DismissableLayer: Pass present state
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding the unmountOnHide prop to Combobox.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@pkg-pr-new

pkg-pr-new Bot commented Aug 4, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/reka-ui@2842

commit: ac92b4f

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 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.

Inline comments:
In `@packages/core/src/Combobox/ComboboxContentImpl.vue`:
- Around line 101-109: Update the `watch` callback for `props.present` to detect
any active descendant within `currentElement`, rather than relying only on
`isInputWithinContent.value`. When content hides and the active element is
inside the content—including slotted `option-state` inputs—restore focus to
`rootContext.triggerElement` after `nextTick`, while preserving the existing
guards for unrelated active elements.
- Around line 57-58: Update the scroll-lock watcher beside useBodyScrollLock to
react to both props.present and props.bodyLock, ensuring scrollLocked is
recomputed and released when bodyLock becomes false while content remains
present. Add a regression test covering a bodyLock change from true to false
while the combobox is open.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3018224d-d636-4948-a32c-4716ce88fea1

📥 Commits

Reviewing files that changed from the base of the PR and between a24ea69 and 12f141b.

📒 Files selected for processing (8)
  • docs/content/meta/ComboboxRoot.md
  • packages/core/src/Autocomplete/AutocompleteRoot.vue
  • packages/core/src/Combobox/Combobox.test.ts
  • packages/core/src/Combobox/ComboboxContent.vue
  • packages/core/src/Combobox/ComboboxContentImpl.vue
  • packages/core/src/Combobox/ComboboxRoot.vue
  • packages/core/src/Combobox/story/_ComboboxManualFilter.vue
  • packages/core/src/Combobox/story/_ComboboxObject.vue

Comment thread packages/core/src/Combobox/ComboboxContentImpl.vue Outdated
Comment thread packages/core/src/Combobox/ComboboxContentImpl.vue
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.

1 participant