Skip to content

refactor(spx-gui): replace naive-ui dropdown and tooltip popups#3032

Open
cn0809 wants to merge 6 commits intogoplus:devfrom
cn0809:naive-ui
Open

refactor(spx-gui): replace naive-ui dropdown and tooltip popups#3032
cn0809 wants to merge 6 commits intogoplus:devfrom
cn0809:naive-ui

Conversation

@cn0809
Copy link
Copy Markdown
Collaborator

@cn0809 cn0809 commented Apr 13, 2026

close: #3015

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request replaces the Naive UI-based UIDropdown and UITooltip components with a custom implementation using @floating-ui/dom and a new internal popup management system. It includes updates to UIConfigProvider and UIModal to support this foundation, along with simplified class merging across multiple UI components. Review feedback identifies a logic error in the resolveMaybeRef utility and a functional issue where nested teleported popups may cause parent dropdowns to close prematurely.

Comment thread spx-gui/src/components/ui/UIDropdown.vue
Comment thread spx-gui/src/components/ui/popup/use-floating-popup.ts
Copy link
Copy Markdown
Contributor

@xgopilot xgopilot bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a well-architected replacement of naive-ui popup primitives with a custom @floating-ui/dom implementation. The popup stack management, trigger rendering, and floating-position logic are cleanly separated, and the comprehensive test coverage is a strong positive. A few correctness and performance issues are worth addressing before merge.

Comment thread spx-gui/src/components/ui/popup/trigger.ts Outdated
Comment thread spx-gui/src/components/ui/UIDropdown.vue
Comment thread spx-gui/src/components/ui/popup/use-floating-popup.ts
Comment thread spx-gui/src/components/ui/popup/use-floating-popup.ts
Comment thread spx-gui/src/components/ui/popup/stack.ts
Comment thread spx-gui/src/components/ui/popup/animations.css Outdated
Comment thread spx-gui/src/components/ui/UITooltip.vue
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors spx-gui popup primitives to remove Naive UI NPopover/NTooltip dependencies, introducing an internal popup stack + Floating UI–based positioning to better support nested popups and reduce library-specific workarounds (closes #3015).

Changes:

  • Replaced UIDropdown and UITooltip implementations with internal popups built on @floating-ui/dom, plus a new popup stack/trigger helper layer.
  • Updated shared popup detection (isInPopup) to rely on internal popup root attributes rather than Naive UI popover classes.
  • Standardized cn(...) usage across UI components (allowing undefined class values) and added Vitest coverage for the new popup utilities/components.

Reviewed changes

Copilot reviewed 50 out of 51 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
spx-gui/src/components/ui/utils/index.ts Switches popup detection to internal popup roots; imports popup helpers.
spx-gui/src/components/ui/utils/cn.ts Allows undefined in ClassValue to simplify cn(..., props.class) usage.
spx-gui/src/components/ui/tab/UITabs.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/tab/UITab.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/select/UISelect.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/radio/UITabRadioGroup.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/radio/UITabRadio.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/radio/UIChipRadioGroup.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/popup/use-floating-popup.ts New Floating UI positioning composable (placement/offset/arrow/virtual anchor).
spx-gui/src/components/ui/popup/use-floating-popup.test.ts Unit tests for positioning helpers + composable behavior.
spx-gui/src/components/ui/popup/trigger.ts New trigger rendering/flattening + trigger element resolution helpers.
spx-gui/src/components/ui/popup/stack.ts New popup stack for registration, nesting, and root attribute tagging.
spx-gui/src/components/ui/popup/stack.test.ts Unit tests for popup stack nesting/topmost tracking + root discovery.
spx-gui/src/components/ui/popup/index.ts Popup barrel export + global popup animation CSS import.
spx-gui/src/components/ui/popup/animations.css Adds scale/fade popup transition styles.
spx-gui/src/components/ui/modal/UIModalClose.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/modal/UIModal.vue Provides popup container inside modal root for correct teleport targeting.
spx-gui/src/components/ui/modal/UIFullScreenModalHeader.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/modal/UIDropdownModal.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/menu/UIMenuItem.vue Updates useDropdown import to .vue; uses cn(..., props.class).
spx-gui/src/components/ui/menu/UIMenuGroup.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/menu/UIMenu.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/loading/UILoading.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/loading/UIDetailedLoading.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/index.ts Switches UIDropdown export to .vue.
spx-gui/src/components/ui/icons/UIIcon.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/error/UIError.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/empty/UIEmpty.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/collapse/UICollapseItem.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/collapse/UICollapse.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/block-items/UICornerIcon.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/block-items/UIBlockItemTitle.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UITooltip.vue Replaces Naive UI tooltip with internal Floating UI + popup stack implementation.
spx-gui/src/components/ui/UITooltip.test.ts Component tests for tooltip hover delay and hover-to-content behavior.
spx-gui/src/components/ui/UITag.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIPagination.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIImg.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIDropdownWithTooltip.test.ts Integration tests ensuring tooltip/dropdown interplay and modal container support.
spx-gui/src/components/ui/UIDropdown.vue New internal dropdown implementation with popup stack, outside click/Escape handling.
spx-gui/src/components/ui/UIDropdown.ts Removes old NPopover-based dropdown implementation.
spx-gui/src/components/ui/UIDropdown.test.ts Component tests for hover/click behavior, outside click, and nested dropdown topmost logic.
spx-gui/src/components/ui/UIConfigProvider.vue Removes Naive UI Popover/Tooltip theme overrides; provides popup stack globally.
spx-gui/src/components/ui/UICode.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIChip.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UICard.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIButtonGroupItem.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIButtonGroup.vue Uses cn(..., props.class) with updated ClassValue.
spx-gui/src/components/ui/UIButton.vue Uses classes.value.root(props.class) with updated ClassValue.
spx-gui/src/components/ui/README.md Updates guidance to prefer cn(..., props.class) (no ?? null).
spx-gui/package.json Adds @floating-ui/dom dependency.
spx-gui/package-lock.json Locks @floating-ui/* dependency versions.
Files not reviewed (1)
  • spx-gui/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread spx-gui/src/components/ui/UITooltip.vue
Comment thread spx-gui/src/components/ui/UIDropdown.vue
Comment thread spx-gui/src/components/ui/utils/index.ts Outdated
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.

Replace Naive UI popup primitives (dropdown / tooltip)

2 participants