fix: enhance CardContainer and MultiSelect components with improved props handling and filtering logic

This commit is contained in:
Johnpaul
2025-09-13 02:35:00 +01:00
parent 6844b77899
commit 578bb54437
3 changed files with 51 additions and 7 deletions

View File

@@ -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>

View File

@@ -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]"

View File

@@ -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) => ({