mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-06 08:00:05 +00:00
fix: enhance CardContainer and MultiSelect components with improved props handling and filtering logic
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="containerClasses">
|
||||
<div :class="containerClasses" :style="containerStyle">
|
||||
<slot name="top"></slot>
|
||||
<slot name="bottom"></slot>
|
||||
</div>
|
||||
@@ -8,8 +8,14 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const { ratio = 'square' } = defineProps<{
|
||||
ratio?: 'square' | 'portrait' | 'tallPortrait'
|
||||
const {
|
||||
ratio = 'square',
|
||||
maxWidth,
|
||||
minWidth
|
||||
} = defineProps<{
|
||||
maxWidth?: number
|
||||
minWidth?: number
|
||||
ratio?: 'square' | 'portrait' | 'tallPortrait' | 'none'
|
||||
}>()
|
||||
|
||||
const containerClasses = computed(() => {
|
||||
@@ -25,4 +31,13 @@ const containerClasses = computed(() => {
|
||||
|
||||
return `${baseClasses} ${ratioClasses[ratio]}`
|
||||
})
|
||||
|
||||
const containerStyle = computed(() =>
|
||||
maxWidth || minWidth
|
||||
? {
|
||||
maxWidth: `${maxWidth}px`,
|
||||
minWidth: `${minWidth}px`
|
||||
}
|
||||
: {}
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
v-for="template in displayTemplates"
|
||||
:key="template.name"
|
||||
ref="cardRefs"
|
||||
:ratio="undefined"
|
||||
ratio="none"
|
||||
:max-width="300"
|
||||
:min-width="200"
|
||||
class="cursor-pointer transition-all duration-300 hover:scale-[1.02]"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
-->
|
||||
<MultiSelect
|
||||
v-model="selectedItems"
|
||||
v-bind="$attrs"
|
||||
v-bind="{ ...$attrs, options: filteredOptions }"
|
||||
option-label="name"
|
||||
unstyled
|
||||
:max-selected-labels="0"
|
||||
@@ -100,11 +100,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Fuse from 'fuse.js'
|
||||
import Button from 'primevue/button'
|
||||
import MultiSelect, {
|
||||
MultiSelectPassThroughMethodOptions
|
||||
} from 'primevue/multiselect'
|
||||
import { computed } from 'vue'
|
||||
import { computed, useAttrs } from 'vue'
|
||||
|
||||
import SearchBox from '@/components/input/SearchBox.vue'
|
||||
import { usePopoverSizing } from '@/composables/usePopoverSizing'
|
||||
@@ -152,13 +153,41 @@ const {
|
||||
const selectedItems = defineModel<Option[]>({
|
||||
required: true
|
||||
})
|
||||
const searchQuery = defineModel<string>('searchQuery')
|
||||
const searchQuery = defineModel<string>('searchQuery', { default: '' })
|
||||
const selectedCount = computed(() => selectedItems.value.length)
|
||||
|
||||
const popoverStyle = usePopoverSizing({
|
||||
minWidth: popoverMinWidth,
|
||||
maxWidth: popoverMaxWidth
|
||||
})
|
||||
const attrs = useAttrs()
|
||||
const originalOptions = computed(() => (attrs.options as Option[]) || [])
|
||||
|
||||
const fuse = computed(
|
||||
() =>
|
||||
new Fuse(originalOptions.value, {
|
||||
keys: ['name', 'value'],
|
||||
threshold: 0.3,
|
||||
includeScore: false
|
||||
})
|
||||
)
|
||||
|
||||
// Filter options based on search, but always include selected items
|
||||
const filteredOptions = computed(() => {
|
||||
if (!searchQuery.value || searchQuery.value.trim() === '') {
|
||||
return originalOptions.value
|
||||
}
|
||||
|
||||
const searchResults = fuse.value
|
||||
.search(searchQuery.value)
|
||||
.map((result) => result.item)
|
||||
|
||||
const selectedButNotInResults = selectedItems.value.filter(
|
||||
(item) => !searchResults.some((result) => result.value === item.value)
|
||||
)
|
||||
|
||||
return [...selectedButNotInResults, ...searchResults]
|
||||
})
|
||||
|
||||
const pt = computed(() => ({
|
||||
root: ({ props }: MultiSelectPassThroughMethodOptions) => ({
|
||||
|
||||
Reference in New Issue
Block a user