From 9b198dfce7bfe33851e5098931a9d5752b562742 Mon Sep 17 00:00:00 2001 From: Austin Mroz Date: Tue, 13 Jan 2026 15:52:16 -0800 Subject: [PATCH] nits and test fixes --- .../fixtures/components/ComfyNodeSearchBox.ts | 4 +- src/components/searchbox/NodeSearchBox.vue | 44 +++++++++++-------- .../searchbox/NodeSearchBoxPopover.vue | 1 - 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/browser_tests/fixtures/components/ComfyNodeSearchBox.ts b/browser_tests/fixtures/components/ComfyNodeSearchBox.ts index 59a33e254b..92d2e09482 100644 --- a/browser_tests/fixtures/components/ComfyNodeSearchBox.ts +++ b/browser_tests/fixtures/components/ComfyNodeSearchBox.ts @@ -44,7 +44,7 @@ export class ComfyNodeSearchBox { '.comfy-vue-node-search-container input[type="text"]' ) this.dropdown = page.locator( - '.comfy-vue-node-search-container .p-autocomplete-list' + '.comfy-vue-node-search-container .comfy-autocomplete-list' ) this.filterSelectionPanel = new ComfyNodeSearchFilterSelectionPanel(page) } @@ -61,7 +61,7 @@ export class ComfyNodeSearchBox { await this.input.fill(nodeName) await this.dropdown.waitFor({ state: 'visible' }) await this.dropdown - .locator('li') + .locator('.option-container') .nth(options?.suggestionIndex || 0) .click() } diff --git a/src/components/searchbox/NodeSearchBox.vue b/src/components/searchbox/NodeSearchBox.vue index e758f1ad9c..04da0a077f 100644 --- a/src/components/searchbox/NodeSearchBox.vue +++ b/src/components/searchbox/NodeSearchBox.vue @@ -61,24 +61,32 @@ ref="inputRef" v-model="currentQuery" class="text-base h-5 bg-transparent border-0 focus:outline-0 flex-1" + type="text" autofocus :placeholder="t('g.searchNodes') + '...'" @keydown.enter.prevent="onAddNode(hoveredSuggestion)" + @keydown.down.prevent="updateIndexBy(1)" + @keydown.up.prevent="updateIndexBy(-1)" />
-
+
import { refDebounced, useVirtualList } from '@vueuse/core' -import { debounce } from 'es-toolkit/compat' import Dialog from 'primevue/dialog' -import { computed, nextTick, ref, useTemplateRef } from 'vue' +import { computed, nextTick, ref, useTemplateRef, watchEffect } from 'vue' import { useI18n } from 'vue-i18n' import NodePreview from '@/components/node/NodePreview.vue' @@ -107,6 +114,7 @@ import { useTelemetry } from '@/platform/telemetry' import type { ComfyNodeDefImpl } from '@/stores/nodeDefStore' import { useNodeDefStore, useNodeFrequencyStore } from '@/stores/nodeDefStore' import type { FuseFilterWithValue } from '@/utils/fuseUtil' +import { cn } from '@/utils/tailwindUtil' import SearchFilterChip from '../common/SearchFilterChip.vue' @@ -124,7 +132,6 @@ const { filters, searchLimit = 64 } = defineProps<{ }>() const nodeSearchFilterVisible = ref(false) -const hoveredSuggestion = ref() const currentQuery = ref('') const debouncedQuery = refDebounced(currentQuery, 100, { maxWait: 400 }) const inputRef = useTemplateRef('inputRef') @@ -132,20 +139,17 @@ const inputRef = useTemplateRef('inputRef') const nodeDefStore = useNodeDefStore() const nodeFrequencyStore = useNodeFrequencyStore() -// Debounced search tracking (500ms as per implementation plan) -const debouncedTrackSearch = debounce((query: string) => { +watchEffect(() => { + const query = debouncedQuery.value if (query.trim()) { telemetry?.trackNodeSearch({ query }) } -}, 500) +}) const suggestions = computed(() => { const query = debouncedQuery.value const queryIsEmpty = query === '' && filters.length === 0 - // Track search queries with debounce - debouncedTrackSearch(query) - return queryIsEmpty ? nodeFrequencyStore.topNodeDefs : [ @@ -188,12 +192,14 @@ const onRemoveFilter = async ( emit('removeFilter', filterAndValue) inputRef.value?.focus() } -const setHoverSuggestion = (index: number) => { - if (index === -1) { - hoveredSuggestion.value = undefined - return - } - const value = suggestions.value[index] - hoveredSuggestion.value = value +const hoveredIndex = ref() +const hoveredSuggestion = computed(() => + hoveredIndex.value ? suggestions.value[hoveredIndex.value] : undefined +) +function updateIndexBy(delta: number) { + hoveredIndex.value = Math.max( + 0, + Math.min(suggestions.value.length, (hoveredIndex.value ?? 0) + delta) + ) } diff --git a/src/components/searchbox/NodeSearchBoxPopover.vue b/src/components/searchbox/NodeSearchBoxPopover.vue index 967d739a7d..47a1bdf7b2 100644 --- a/src/components/searchbox/NodeSearchBoxPopover.vue +++ b/src/components/searchbox/NodeSearchBoxPopover.vue @@ -12,7 +12,6 @@ mask: { class: 'node-search-box-dialog-mask' }, transition: { enterFromClass: 'opacity-0', - // 100ms is the duration of the transition in the dialog component enterActiveClass: 'transition-all duration-20 ease-out', leaveActiveClass: 'transition-all duration-20 ease-in', leaveToClass: 'opacity-0 scale-75'