Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/components/primevueOverride/SelectPlus.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
import Select from 'primevue/select'

export default {
name: 'SelectPlus',
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
name: 'SelectPlus',
name: 'SelectPlus',
emits: ['hide'],

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I was a little concerned that this change would also result in overriding the emits defined by the extended Select component, but, as far as I can tell, defining it here doesn't change the emitsOptions on the component instance.

Suggestion should be fine to make.

extends: Select,
emits: ['hide'],
methods: {
onOverlayLeave() {
this.unbindOutsideClickListener()
this.unbindScrollListener()
this.unbindResizeListener()

this.$emit('hide')
this.overlay = null
}
}
}
Comment on lines +4 to +18
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, check if the file exists and examine its full content
echo "=== Checking SelectPlus.vue file ==="
cat -n src/components/primevueOverride/SelectPlus.vue

# Check PrimeVue Select implementation for onOverlayLeave
echo -e "\n=== Checking PrimeVue Select onOverlayLeave ==="
find node_modules/primevue -name "Select.vue" -o -name "Select.js" 2>/dev/null | head -1 | xargs grep -A 20 "onOverlayLeave" 2>/dev/null || echo "Not found in Select files"

# Search more broadly in primevue for this method
echo -e "\n=== Searching PrimeVue for onOverlayLeave ==="
grep -r "onOverlayLeave" node_modules/primevue --include="*.vue" --include="*.js" 2>/dev/null | head -5

# Check if there's a BaseSelect or mixin
echo -e "\n=== Looking for Select core implementation ==="
ls -la node_modules/primevue/select/ 2>/dev/null || echo "No select directory"

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 771


🏁 Script executed:

#!/bin/bash
# Check PrimeVue version and structure
echo "=== PrimeVue package info ==="
grep '"primevue"' package.json || grep '"primevue"' package-lock.json | head -2

# Look at what methods Select actually has
echo -e "\n=== Checking Select component methods ==="
node -e "const Select = require('primevue/select').default; console.log(Object.getOwnPropertyNames(Select.prototype).sort())"

# Find Select implementation file
echo -e "\n=== Finding Select implementation ==="
find node_modules/primevue -type f -name "*.js" -o -name "*.vue" | grep -i select | head -10

# Check actual Select file
echo -e "\n=== Examining Select implementation ==="
cat node_modules/primevue/select/select.esm.js 2>/dev/null | head -100 || cat node_modules/primevue/dist/select/select.esm.js 2>/dev/null | head -100

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 1167


🏁 Script executed:

#!/bin/bash
# Search for unbindOutsideClickListener usage to understand where it comes from
echo "=== Searching for unbind methods in codebase ==="
rg "unbindOutsideClickListener|unbindScrollListener|unbindResizeListener" src/ --type vue --type ts --type js

# Check if SelectPlus is used elsewhere
echo -e "\n=== Finding SelectPlus usage ==="
rg "SelectPlus|from.*SelectPlus" src/ --type vue --type ts

# Look for other PrimeVue overrides
echo -e "\n=== Finding other PrimeVue overrides ==="
find src/components/primevueOverride -type f -name "*.vue" 2>/dev/null

# Check git history/comments about SelectPlus
echo -e "\n=== Checking for context in related files ==="
grep -r "autofocus" src/components/primevueOverride/ --include="*.vue" --include="*.ts" --include="*.js" -B 2 -A 2 2>/dev/null || echo "No autofocus refs found"

# Search for any parent method calls in the overrides
echo -e "\n=== Looking for super calls in overrides ==="
rg "super\." src/components/primevueOverride/ --type vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 512


🏁 Script executed:

#!/bin/bash
# Search without type restrictions
echo "=== Searching for onOverlayLeave ==="
rg "onOverlayLeave" src/

# Search for SelectPlus imports/usage
echo -e "\n=== SelectPlus usage ==="
rg "SelectPlus" src/

# Check PrimeVue docs - look at node_modules structure differently
echo -e "\n=== PrimeVue files ==="
find node_modules -path "*primevue*" -name "*.d.ts" 2>/dev/null | grep -i select | head -5

# Try to find TypeScript definitions for Select
echo -e "\n=== PrimeVue Select types ==="
find . -name "*.d.ts" -exec grep -l "class Select\|interface Select" {} \; 2>/dev/null | head -3 | xargs cat 2>/dev/null | head -80

# Check package.json for primevue version and structure
echo -e "\n=== Full primevue config ==="
rg '"primevue"' . --type json -A 5 -B 2

# Look for pnpm-lock or package-lock for primevue version
echo -e "\n=== Primevue in lock file ==="
grep -A 2 '"primevue":' pnpm-lock.yaml 2>/dev/null | head -10

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 2516


🏁 Script executed:

#!/bin/bash
# Check WidgetSelectDefault to understand SelectPlus usage context
echo "=== WidgetSelectDefault context ==="
cat -n src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue | head -80

# Look for recent git history on SelectPlus
echo -e "\n=== Git log for SelectPlus ==="
git log --oneline src/components/primevueOverride/SelectPlus.vue 2>/dev/null | head -5

# Get commit message for SelectPlus
echo -e "\n=== SelectPlus commit details ==="
git log -1 --format="%B" -- src/components/primevueOverride/SelectPlus.vue 2>/dev/null || echo "No git history"

# Check if there are any comments about why this override exists
echo -e "\n=== Comments near SelectPlus in codebase ==="
grep -B 5 -A 2 "SelectPlus" src/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue 2>/dev/null | head -20

# Look for AutoCompletePlus to see if it has similar pattern
echo -e "\n=== AutoCompletePlus structure ==="
cat src/components/primevueOverride/AutoCompletePlus.vue

Repository: Comfy-Org/ComfyUI_frontend

Length of output: 4714


Consider calling the parent's onOverlayLeave method explicitly or document why it's being completely replaced.

The override doesn't invoke the parent implementation, unlike the pattern used in AutoCompletePlus.vue which explicitly calls parent lifecycle hooks (e.g., AutoComplete.mounted.call(this)). While the unbind methods are correctly called, adding a parent method call or explanatory comment would maintain consistency with existing override patterns and guard against future regressions.

🤖 Prompt for AI Agents
In @src/components/primevueOverride/SelectPlus.vue around lines 4 - 18, The
override of onOverlayLeave in SelectPlus replaces the parent Select behavior
without calling the parent's onOverlayLeave; either call
Select.methods.onOverlayLeave.call(this) (or Select.onOverlayLeave.call(this))
at the start or end of SelectPlus.methods.onOverlayLeave to preserve parent
logic, or add a brief comment in SelectPlus explaining why the parent method
must be fully replaced (referencing the pattern used in AutoCompletePlus where
AutoComplete.mounted.call(this) is invoked) so future maintainers understand the
intentional deviation.

</script>
Comment on lines 1 to 19
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 30, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider long-term migration away from PrimeVue components.

While this override appropriately uses the Options API for PrimeVue compatibility, note that the codebase is moving toward VueUse, shadcn/vue, or Reka UI instead of PrimeVue components. This is acceptable as a short-term fix for existing usage, but consider planning a migration path.

Based on learnings, the repository is transitioning away from PrimeVue components.

Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai Where else in the codebase do we use the Options API for Vue components?

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all .vue files and check for Options API usage
# Options API typically has "export default {" followed by options like methods, data, computed, etc.

echo "=== Vue files using Options API (excluding <script setup>) ==="
echo ""

# Find all .vue files
fd -e vue -x sh -c '
  file="$1"
  # Check if file does NOT have <script setup> (which indicates Composition API)
  if ! grep -q "<script setup" "$file"; then
    # Check if it has export default with Options API patterns
    if grep -q "export default" "$file"; then
      # Check for common Options API properties
      if grep -E "(methods:|data\(|computed:|watch:|extends:|mixins:)" "$file" > /dev/null; then
        echo "$file"
        # Show a snippet of the export default section
        grep -A 5 "export default" "$file" | head -10
        echo "---"
      fi
    fi
  fi
' _ {}

Length of output: 440


@DrJKL The Options API is used in only 2 places in the codebase, both in the src/components/primevueOverride/ directory:

  1. src/components/primevueOverride/AutoCompletePlus.vue - extends PrimeVue's AutoComplete component
  2. src/components/primevueOverride/SelectPlus.vue - extends PrimeVue's Select component (the current file)

Both files use the Options API specifically because they extend PrimeVue components, which is consistent with the repository's guideline that states: "Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)."

The rest of the codebase uses the Composition API (typically <script setup>), so this is a very limited and intentional use of the Options API for PrimeVue compatibility purposes only.


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Avoid new usage of PrimeVue components; use VueUse, shadcn/vue, or Reka UI instead

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-21T06:04:12.562Z
Learning: Applies to **/*.vue : Leverage VueUse functions for performance-enhancing styles in Vue components

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles

Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai Open an issue tracking the removal of SelectPlus and replacing it with our own component. Assign @AustinMroz

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create a GitHub issue tracking the removal of SelectPlus

gh issue create \
  --repo Comfy-Org/ComfyUI_frontend \
  --title "Replace SelectPlus with custom component (migrate away from PrimeVue)" \
  --body "## Context

SelectPlus was introduced in PR #7804 as a temporary fix to override PrimeVue's Select component behavior. As part of the ongoing migration away from PrimeVue components toward VueUse, shadcn/vue, or Reka UI, this component should be replaced with a custom implementation.

## Current Implementation

- Location: \`src/components/primevueOverride/SelectPlus.vue\`
- Extends PrimeVue's Select component
- Overrides \`onOverlayLeave\` method to fix autofocus error on close

## Task

Replace SelectPlus with a custom select component that doesn't depend on PrimeVue.

## References

- PR where SelectPlus was introduced: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7804
- Discussion: https://github.com/Comfy-Org/ComfyUI_frontend/pull/7804#discussion_r2652376749
- Requested by: @DrJKL" \
  --assignee AustinMroz

Length of output: 57


@DrJKL I've created issue #8034 to track the removal of SelectPlus and its replacement with a custom component. The issue has been assigned to @AustinMroz as requested.


🧠 Learnings used
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Dropdown component with Select

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue OverlayPanel component with Popover

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-01-10T00:24:17.695Z
Learning: Applies to src/**/*.vue : Avoid new usage of PrimeVue components

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InputSwitch component with ToggleSwitch

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Sidebar component with Drawer

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Chips component with AutoComplete with multiple enabled

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Calendar component with DatePicker

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue Steps component with Stepper without panels

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue InlineMessage component with Message

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Replace PrimeVue TabMenu component with Tabs without panels

Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Use the Vue 3 Composition API instead of the Options API when writing Vue components (exception: when overriding or extending PrimeVue components for compatibility)

Learnt from: christian-byrne
Repo: Comfy-Org/ComfyUI_frontend PR: 6300
File: src/platform/updates/components/WhatsNewPopup.vue:5-13
Timestamp: 2025-12-09T03:50:03.127Z
Learning: In the Comfy-Org/ComfyUI_frontend repository, when avoiding PrimeVue components, prefer using the repo's common button components from src/components/button/ (IconButton.vue, TextButton.vue, IconTextButton.vue) rather than plain HTML buttons. These components wrap PrimeVue with custom design system styling.

Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { createTestingPinia } from '@pinia/testing'
import { mount } from '@vue/test-utils'
import PrimeVue from 'primevue/config'
import Select from 'primevue/select'
import type { SelectProps } from 'primevue/select'
import { beforeEach, describe, expect, it, vi } from 'vitest'

import SelectPlus from '@/components/primevueOverride/SelectPlus.vue'
import type { ComboInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'

import WidgetSelect from '@/renderer/extensions/vueNodes/widgets/components/WidgetSelect.vue'
import WidgetSelectDefault from '@/renderer/extensions/vueNodes/widgets/components/WidgetSelectDefault.vue'
import WidgetSelectDropdown from '@/renderer/extensions/vueNodes/widgets/components/WidgetSelectDropdown.vue'
Expand Down Expand Up @@ -76,7 +75,7 @@ describe('WidgetSelect Value Binding', () => {
},
global: {
plugins: [PrimeVue, createTestingPinia()],
components: { Select }
components: { SelectPlus }
}
})
}
Expand All @@ -85,7 +84,7 @@ describe('WidgetSelect Value Binding', () => {
wrapper: ReturnType<typeof mount>,
value: string
) => {
const select = wrapper.findComponent({ name: 'Select' })
const select = wrapper.findComponent({ name: 'SelectPlus' })
await select.setValue(value)
return wrapper.emitted('update:modelValue')
}
Expand Down Expand Up @@ -150,7 +149,7 @@ describe('WidgetSelect Value Binding', () => {
const widget = createMockWidget('', { values: [] })
const wrapper = mountComponent(widget, '')

const select = wrapper.findComponent({ name: 'Select' })
const select = wrapper.findComponent({ name: 'SelectPlus' })
expect(select.props('options')).toEqual([])
})

Expand All @@ -160,7 +159,7 @@ describe('WidgetSelect Value Binding', () => {
})
const wrapper = mountComponent(widget, 'only_option')

const select = wrapper.findComponent({ name: 'Select' })
const select = wrapper.findComponent({ name: 'SelectPlus' })
const options = select.props('options')
expect(options).toHaveLength(1)
expect(options[0]).toEqual('only_option')
Expand Down Expand Up @@ -228,7 +227,7 @@ describe('WidgetSelect Value Binding', () => {
},
global: {
plugins: [PrimeVue, createTestingPinia()],
components: { Select }
components: { SelectPlus }
}
})

Expand All @@ -247,7 +246,7 @@ describe('WidgetSelect Value Binding', () => {
},
global: {
plugins: [PrimeVue, createTestingPinia()],
components: { Select }
components: { SelectPlus }
}
})

Expand All @@ -271,7 +270,7 @@ describe('WidgetSelect Value Binding', () => {
},
global: {
plugins: [PrimeVue, createTestingPinia()],
components: { Select }
components: { SelectPlus }
}
})

Expand All @@ -290,7 +289,7 @@ describe('WidgetSelect Value Binding', () => {
},
global: {
plugins: [PrimeVue, createTestingPinia()],
components: { Select }
components: { SelectPlus }
}
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<WidgetLayoutField :widget>
<Select
<SelectPlus
v-model="modelValue"
:invalid
:filter="selectOptions.length > 4"
:auto-filter-focus="selectOptions.length > 4"
auto-filter-focus
:options="selectOptions"
v-bind="combinedProps"
:class="cn(WidgetInputBaseClass, 'w-full text-xs')"
Expand All @@ -25,9 +25,9 @@
</template>

<script setup lang="ts">
import Select from 'primevue/select'
import { computed } from 'vue'

import SelectPlus from '@/components/primevueOverride/SelectPlus.vue'
import { useTransformCompatOverlayProps } from '@/composables/useTransformCompatOverlayProps'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import { cn } from '@/utils/tailwindUtil'
Expand Down
Loading