mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-07 00:20:07 +00:00
Extract search option as a Vue component (#838)
This commit is contained in:
@@ -43,38 +43,7 @@
|
||||
:optionLabel="'display_name'"
|
||||
>
|
||||
<template v-slot:option="{ option }">
|
||||
<div class="option-container">
|
||||
<div class="option-display-name">
|
||||
<div>
|
||||
<span
|
||||
v-html="highlightQuery(option.display_name, currentQuery)"
|
||||
></span>
|
||||
<span> </span>
|
||||
<Tag v-if="showIdName" severity="secondary">
|
||||
<span v-html="highlightQuery(option.name, currentQuery)"></span>
|
||||
</Tag>
|
||||
</div>
|
||||
<div v-if="showCategory" class="option-category">
|
||||
{{ option.category.replaceAll('/', ' > ') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-badges">
|
||||
<Tag
|
||||
v-if="option.experimental"
|
||||
:value="$t('experimental')"
|
||||
severity="primary"
|
||||
/>
|
||||
<Tag
|
||||
v-if="option.deprecated"
|
||||
:value="$t('deprecated')"
|
||||
severity="danger"
|
||||
/>
|
||||
<NodeSourceChip
|
||||
v-if="option.python_module !== undefined"
|
||||
:python_module="option.python_module"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<NodeSearchItem :nodeDef="option" :currentQuery="currentQuery" />
|
||||
</template>
|
||||
<!-- FilterAndValue -->
|
||||
<template v-slot:chip="{ value }">
|
||||
@@ -92,11 +61,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import AutoCompletePlus from '@/components/primevueOverride/AutoCompletePlus.vue'
|
||||
import Tag from 'primevue/tag'
|
||||
import Dialog from 'primevue/dialog'
|
||||
import Button from 'primevue/button'
|
||||
import NodeSearchFilter from '@/components/searchbox/NodeSearchFilter.vue'
|
||||
import NodeSourceChip from '@/components/node/NodeSourceChip.vue'
|
||||
import NodeSearchItem from '@/components/searchbox/NodeSearchItem.vue'
|
||||
import { type FilterAndValue } from '@/services/nodeSearchService'
|
||||
import NodePreview from '@/components/node/NodePreview.vue'
|
||||
import { ComfyNodeDefImpl, useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
@@ -110,12 +78,6 @@ const { t } = useI18n()
|
||||
const enableNodePreview = computed(() =>
|
||||
settingStore.get('Comfy.NodeSearchBoxImpl.NodePreview')
|
||||
)
|
||||
const showCategory = computed(() =>
|
||||
settingStore.get('Comfy.NodeSearchBoxImpl.ShowCategory')
|
||||
)
|
||||
const showIdName = computed(() =>
|
||||
settingStore.get('Comfy.NodeSearchBoxImpl.ShowIdName')
|
||||
)
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -145,12 +107,6 @@ const search = (query: string) => {
|
||||
]
|
||||
}
|
||||
|
||||
const highlightQuery = (text: string, query: string) => {
|
||||
if (!query) return text
|
||||
const regex = new RegExp(`(${query})`, 'gi')
|
||||
return text.replace(regex, '<span class="highlight">$1</span>')
|
||||
}
|
||||
|
||||
const emit = defineEmits(['addFilter', 'removeFilter', 'addNode'])
|
||||
|
||||
const reFocusInput = () => {
|
||||
@@ -202,29 +158,6 @@ const setHoverSuggestion = (index: number) => {
|
||||
@apply z-10 flex-grow;
|
||||
}
|
||||
|
||||
.option-container {
|
||||
@apply flex justify-between items-center px-2 py-0 cursor-pointer overflow-hidden w-full;
|
||||
}
|
||||
|
||||
.option-display-name {
|
||||
@apply font-semibold flex flex-col;
|
||||
}
|
||||
|
||||
.option-category {
|
||||
@apply font-light text-sm text-gray-400 overflow-hidden text-ellipsis;
|
||||
/* Keeps the text on a single line by default */
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.highlight) {
|
||||
background-color: var(--p-primary-color);
|
||||
color: var(--p-primary-contrast-color);
|
||||
font-weight: bold;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0rem 0.125rem;
|
||||
margin: -0.125rem 0.125rem;
|
||||
}
|
||||
|
||||
._filter-button {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
72
src/components/searchbox/NodeSearchItem.vue
Normal file
72
src/components/searchbox/NodeSearchItem.vue
Normal file
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div
|
||||
class="option-container flex justify-between items-center px-2 py-0 cursor-pointer overflow-hidden w-full"
|
||||
>
|
||||
<div class="option-display-name font-semibold flex flex-col">
|
||||
<div>
|
||||
<span
|
||||
v-html="highlightQuery(nodeDef.display_name, currentQuery)"
|
||||
></span>
|
||||
<span> </span>
|
||||
<Tag v-if="showIdName" severity="secondary">
|
||||
<span v-html="highlightQuery(nodeDef.name, currentQuery)"></span>
|
||||
</Tag>
|
||||
</div>
|
||||
<div
|
||||
v-if="showCategory"
|
||||
class="option-category font-light text-sm text-gray-400 overflow-hidden text-ellipsis whitespace-nowrap"
|
||||
>
|
||||
{{ nodeDef.category.replaceAll('/', ' > ') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="option-badges">
|
||||
<Tag
|
||||
v-if="nodeDef.experimental"
|
||||
:value="$t('experimental')"
|
||||
severity="primary"
|
||||
/>
|
||||
<Tag
|
||||
v-if="nodeDef.deprecated"
|
||||
:value="$t('deprecated')"
|
||||
severity="danger"
|
||||
/>
|
||||
<NodeSourceChip
|
||||
v-if="nodeDef.python_module !== undefined"
|
||||
:python_module="nodeDef.python_module"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Tag from 'primevue/tag'
|
||||
import NodeSourceChip from '@/components/node/NodeSourceChip.vue'
|
||||
import { ComfyNodeDefImpl } from '@/stores/nodeDefStore'
|
||||
import { highlightQuery } from '@/utils/formatUtil'
|
||||
import { computed } from 'vue'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const showCategory = computed(() =>
|
||||
settingStore.get('Comfy.NodeSearchBoxImpl.ShowCategory')
|
||||
)
|
||||
const showIdName = computed(() =>
|
||||
settingStore.get('Comfy.NodeSearchBoxImpl.ShowIdName')
|
||||
)
|
||||
|
||||
defineProps<{
|
||||
nodeDef: ComfyNodeDefImpl
|
||||
currentQuery: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.highlight) {
|
||||
background-color: var(--p-primary-color);
|
||||
color: var(--p-primary-contrast-color);
|
||||
font-weight: bold;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0rem 0.125rem;
|
||||
margin: -0.125rem 0.125rem;
|
||||
}
|
||||
</style>
|
||||
@@ -33,3 +33,9 @@ export function appendJsonExt(path: string) {
|
||||
export function trimJsonExt(path: string) {
|
||||
return path.replace(/\.json$/, '')
|
||||
}
|
||||
|
||||
export function highlightQuery(text: string, query: string) {
|
||||
if (!query) return text
|
||||
const regex = new RegExp(`(${query})`, 'gi')
|
||||
return text.replace(regex, '<span class="highlight">$1</span>')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user