mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-28 10:12:11 +00:00
V2 Node Search (+ hidden Node Library changes) (#8987)
## Summary Redesigned node search with categories ## Changes - **What**: Adds a v2 search component, leaving the existing implementation untouched - It also brings onboard the incomplete node library & preview changes, disabled and behind a hidden setting - **Breaking**: Changes the 'default' value of the node search setting to v2, adding v1 (legacy) as an option ## Screenshots (if applicable) https://github.com/user-attachments/assets/2ab797df-58f0-48e8-8b20-2a1809e3735f ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8987-V2-Node-Search-hidden-Node-Library-changes-30c6d73d36508160902bcb92553f147c) by [Unito](https://www.unito.io) --------- Co-authored-by: Yourz <crazilou@vip.qq.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Christian Byrne <cbyrne@comfy.org>
This commit is contained in:
@@ -6,10 +6,13 @@
|
||||
:dismissable-mask="dismissable"
|
||||
:pt="{
|
||||
root: {
|
||||
class: 'invisible-dialog-root',
|
||||
role: 'search'
|
||||
class: useSearchBoxV2
|
||||
? 'w-4/5 min-w-[32rem] max-w-[56rem] border-0 bg-transparent mt-[10vh] max-md:w-[95%] max-md:min-w-0 overflow-visible'
|
||||
: 'invisible-dialog-root'
|
||||
},
|
||||
mask: {
|
||||
class: useSearchBoxV2 ? 'items-start' : 'node-search-box-dialog-mask'
|
||||
},
|
||||
mask: { class: 'node-search-box-dialog-mask' },
|
||||
transition: {
|
||||
enterFromClass: 'opacity-0 scale-75',
|
||||
// 100ms is the duration of the transition in the dialog component
|
||||
@@ -21,7 +24,24 @@
|
||||
@hide="clearFilters"
|
||||
>
|
||||
<template #container>
|
||||
<div v-if="useSearchBoxV2" role="search" class="relative">
|
||||
<NodeSearchContent
|
||||
:filters="nodeFilters"
|
||||
@add-filter="addFilter"
|
||||
@remove-filter="removeFilter"
|
||||
@add-node="addNode"
|
||||
@hover-node="hoveredNodeDef = $event"
|
||||
/>
|
||||
<NodePreviewCard
|
||||
v-if="hoveredNodeDef && enableNodePreview"
|
||||
:key="hoveredNodeDef.name"
|
||||
:node-def="hoveredNodeDef"
|
||||
show-category-path
|
||||
class="absolute top-0 left-full ml-3"
|
||||
/>
|
||||
</div>
|
||||
<NodeSearchBox
|
||||
v-else
|
||||
:filters="nodeFilters"
|
||||
@add-filter="addFilter"
|
||||
@remove-filter="removeFilter"
|
||||
@@ -33,7 +53,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import { useEventListener, useWindowSize } from '@vueuse/core'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import Dialog from 'primevue/dialog'
|
||||
import { computed, ref, toRaw, watch, watchEffect } from 'vue'
|
||||
@@ -52,6 +72,9 @@ import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
import { LinkReleaseTriggerAction } from '@/types/searchBoxTypes'
|
||||
import type { FuseFilterWithValue } from '@/utils/fuseUtil'
|
||||
|
||||
import NodePreviewCard from '@/components/node/NodePreviewCard.vue'
|
||||
|
||||
import NodeSearchContent from './v2/NodeSearchContent.vue'
|
||||
import NodeSearchBox from './NodeSearchBox.vue'
|
||||
|
||||
let triggerEvent: CanvasPointerEvent | null = null
|
||||
@@ -62,8 +85,19 @@ const settingStore = useSettingStore()
|
||||
const searchBoxStore = useSearchBoxStore()
|
||||
const litegraphService = useLitegraphService()
|
||||
|
||||
const { visible, newSearchBoxEnabled } = storeToRefs(searchBoxStore)
|
||||
const { visible, newSearchBoxEnabled, useSearchBoxV2 } =
|
||||
storeToRefs(searchBoxStore)
|
||||
const dismissable = ref(true)
|
||||
const hoveredNodeDef = ref<ComfyNodeDefImpl | null>(null)
|
||||
const { width: windowWidth } = useWindowSize()
|
||||
// Minimum viewport width for the preview panel to fit beside the dialog
|
||||
const MIN_WIDTH_FOR_PREVIEW = 1320
|
||||
const enableNodePreview = computed(
|
||||
() =>
|
||||
useSearchBoxV2.value &&
|
||||
settingStore.get('Comfy.NodeSearchBoxImpl.NodePreview') &&
|
||||
windowWidth.value >= MIN_WIDTH_FOR_PREVIEW
|
||||
)
|
||||
function getNewNodeLocation(): Point {
|
||||
return triggerEvent
|
||||
? [triggerEvent.canvasX, triggerEvent.canvasY]
|
||||
@@ -74,9 +108,7 @@ function addFilter(filter: FuseFilterWithValue<ComfyNodeDefImpl, string>) {
|
||||
const isDuplicate = nodeFilters.value.some(
|
||||
(f) => f.filterDef.id === filter.filterDef.id && f.value === filter.value
|
||||
)
|
||||
if (!isDuplicate) {
|
||||
nodeFilters.value.push(filter)
|
||||
}
|
||||
if (!isDuplicate) nodeFilters.value.push(filter)
|
||||
}
|
||||
function removeFilter(filter: FuseFilterWithValue<ComfyNodeDefImpl, string>) {
|
||||
nodeFilters.value = nodeFilters.value.filter(
|
||||
@@ -85,16 +117,20 @@ function removeFilter(filter: FuseFilterWithValue<ComfyNodeDefImpl, string>) {
|
||||
}
|
||||
function clearFilters() {
|
||||
nodeFilters.value = []
|
||||
hoveredNodeDef.value = null
|
||||
}
|
||||
function closeDialog() {
|
||||
visible.value = false
|
||||
}
|
||||
const canvasStore = useCanvasStore()
|
||||
|
||||
function addNode(nodeDef: ComfyNodeDefImpl) {
|
||||
const node = litegraphService.addNodeOnGraph(nodeDef, {
|
||||
pos: getNewNodeLocation()
|
||||
})
|
||||
function addNode(nodeDef: ComfyNodeDefImpl, dragEvent?: MouseEvent) {
|
||||
const node = litegraphService.addNodeOnGraph(
|
||||
nodeDef,
|
||||
{ pos: getNewNodeLocation() },
|
||||
{ ghost: useSearchBoxV2.value, dragEvent }
|
||||
)
|
||||
if (!node) return
|
||||
|
||||
if (disconnectOnReset && triggerEvent) {
|
||||
canvasStore.getCanvas().linkConnector.connectToNode(node, triggerEvent)
|
||||
|
||||
Reference in New Issue
Block a user