mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-19 06:20:10 +00:00
Vue component multi-select widget (#2987)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
:key="widget.id"
|
||||
:widget="widget"
|
||||
:widget-state="domWidgetStore.widgetStates.get(widget.id)"
|
||||
@update:widget-value="widget.value = $event"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -16,7 +17,7 @@ import { computed, watch } from 'vue'
|
||||
|
||||
import DomWidget from '@/components/graph/widgets/DomWidget.vue'
|
||||
import { useChainCallback } from '@/composables/functional/useChainCallback'
|
||||
import { DOMWidget } from '@/scripts/domWidget'
|
||||
import { BaseDOMWidget } from '@/scripts/domWidget'
|
||||
import { useDomWidgetStore } from '@/stores/domWidgetStore'
|
||||
import { useCanvasStore } from '@/stores/graphStore'
|
||||
|
||||
@@ -24,7 +25,7 @@ const domWidgetStore = useDomWidgetStore()
|
||||
const widgets = computed(() =>
|
||||
Array.from(
|
||||
domWidgetStore.widgetInstances.values() as Iterable<
|
||||
DOMWidget<HTMLElement, object | string>
|
||||
BaseDOMWidget<string | object>
|
||||
>
|
||||
)
|
||||
)
|
||||
|
||||
@@ -5,7 +5,15 @@
|
||||
ref="widgetElement"
|
||||
:style="style"
|
||||
v-show="widgetState.visible"
|
||||
/>
|
||||
>
|
||||
<component
|
||||
v-if="isComponentWidget(widget)"
|
||||
:is="widget.component"
|
||||
:modelValue="widget.value"
|
||||
@update:modelValue="emit('update:widgetValue', $event)"
|
||||
:widget="widget"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -15,16 +23,24 @@ import { CSSProperties, computed, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import { useAbsolutePosition } from '@/composables/element/useAbsolutePosition'
|
||||
import { useDomClipping } from '@/composables/element/useDomClipping'
|
||||
import type { DOMWidget } from '@/scripts/domWidget'
|
||||
import {
|
||||
type BaseDOMWidget,
|
||||
isComponentWidget,
|
||||
isDOMWidget
|
||||
} from '@/scripts/domWidget'
|
||||
import { DomWidgetState } from '@/stores/domWidgetStore'
|
||||
import { useCanvasStore } from '@/stores/graphStore'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
|
||||
const { widget, widgetState } = defineProps<{
|
||||
widget: DOMWidget<HTMLElement, any>
|
||||
widget: BaseDOMWidget<string | object>
|
||||
widgetState: DomWidgetState
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:widgetValue', value: string | object): void
|
||||
}>()
|
||||
|
||||
const widgetElement = ref<HTMLElement>()
|
||||
|
||||
const { style: positionStyle, updatePositionWithTransform } =
|
||||
@@ -92,27 +108,31 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
if (widget.element.blur) {
|
||||
useEventListener(document, 'mousedown', (event) => {
|
||||
if (!widget.element.contains(event.target as HTMLElement)) {
|
||||
widget.element.blur()
|
||||
}
|
||||
})
|
||||
}
|
||||
if (isDOMWidget(widget)) {
|
||||
if (widget.element.blur) {
|
||||
useEventListener(document, 'mousedown', (event) => {
|
||||
if (!widget.element.contains(event.target as HTMLElement)) {
|
||||
widget.element.blur()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
for (const evt of widget.options.selectOn ?? ['focus', 'click']) {
|
||||
useEventListener(widget.element, evt, () => {
|
||||
const lgCanvas = canvasStore.canvas
|
||||
lgCanvas?.selectNode(widget.node)
|
||||
lgCanvas?.bringToFront(widget.node)
|
||||
})
|
||||
for (const evt of widget.options.selectOn ?? ['focus', 'click']) {
|
||||
useEventListener(widget.element, evt, () => {
|
||||
const lgCanvas = canvasStore.canvas
|
||||
lgCanvas?.selectNode(widget.node)
|
||||
lgCanvas?.bringToFront(widget.node)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const inputSpec = widget.node.constructor.nodeData
|
||||
const tooltip = inputSpec?.inputs?.[widget.name]?.tooltip
|
||||
|
||||
onMounted(() => {
|
||||
widgetElement.value.appendChild(widget.element)
|
||||
if (isDOMWidget(widget)) {
|
||||
widgetElement.value.appendChild(widget.element)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
30
src/components/graph/widgets/MultiSelectWidget.vue
Normal file
30
src/components/graph/widgets/MultiSelectWidget.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div>
|
||||
<MultiSelect
|
||||
v-model="selectedItems"
|
||||
:options="options"
|
||||
filter
|
||||
:placeholder="placeholder"
|
||||
:maxSelectedLabels="3"
|
||||
:display="display"
|
||||
class="w-full"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import MultiSelect from 'primevue/multiselect'
|
||||
|
||||
import type { ComboInputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
|
||||
import type { ComponentWidget } from '@/scripts/domWidget'
|
||||
|
||||
const selectedItems = defineModel<string[]>({ required: true })
|
||||
const { widget } = defineProps<{
|
||||
widget: ComponentWidget<string[]>
|
||||
}>()
|
||||
|
||||
const inputSpec = widget.inputSpec as ComboInputSpec
|
||||
const options = inputSpec.options ?? []
|
||||
const placeholder = inputSpec.multi_select?.placeholder ?? 'Select items'
|
||||
const display = inputSpec.multi_select?.chip ? 'chip' : 'comma'
|
||||
</script>
|
||||
Reference in New Issue
Block a user