Skip to content
Snippets Groups Projects
Commit bbbca9ff authored by Konrad Mohrfeldt's avatar Konrad Mohrfeldt :koala:
Browse files

feat: restore ComboBox’s support for non-array modelValue

parent cc1a4ee5
No related branches found
No related tags found
No related merge requests found
......@@ -50,7 +50,7 @@
@keydown.delete="maybeRemoveChoice"
/>
<slot name="selected" :items="modelValue" :deselect="selectChoice" :is-open="isOpen" />
<slot name="selected" :deselect="selectChoice" :is-open="isOpen" />
<kbd
v-if="keyboardShortcut && keyboardShortcutLabel !== undefined && !isTouch"
......@@ -123,7 +123,7 @@
</div>
</template>
<script lang="ts" setup generic="ItemType extends { id: number | string }">
<script lang="ts" setup generic="T">
import { computed, nextTick, Ref, ref, useSlots, watch, watchEffect } from 'vue'
import { onClickOutside, useFocusWithin, useMediaQuery, whenever } from '@vueuse/core'
import { clamp, useId } from '@/util'
......@@ -137,16 +137,12 @@ defineSlots<{
default(
props: Record<string, unknown> & {
id: string
choice: ItemType
choice: T
index: number
activeIndex: number
},
): unknown
selected(props: {
items: ItemType[]
deselect: (choice: ItemType) => void
isOpen: boolean
}): unknown
selected(props: { deselect: (choice: T) => void; isOpen: boolean }): unknown
filter?(props: { resultsId: string }): any
noData?(props: Record<string, never>): any
pre?(props: Record<string, never>): any
......@@ -154,34 +150,45 @@ defineSlots<{
const props = withDefaults(
defineProps<{
modelValue: ItemType[]
choices: ItemType[]
modelValue: T | T[]
choices: T[]
keyboardShortcut?: Ref<boolean> | undefined
keyboardShortcutLabel?: string
label?: string
noDataLabel?: string
getKey?: (obj: ItemType) => string | number
getKey?: (obj: T) => string | number
closeOnSelect?: boolean
inputClass?: unknown
inputContainerClass?: unknown
drawerClass?: unknown
multiple?: boolean
}>(),
{
keyboardShortcut: undefined,
keyboardShortcutLabel: '',
label: '',
noDataLabel: '',
getKey: (obj: ItemType) => obj.id,
getKey: (obj: T) => {
if (
typeof obj === 'object' &&
obj !== null &&
'id' in obj &&
(typeof obj.id === 'string' || typeof obj.id === 'number')
) {
return obj.id
} else if (typeof obj === 'string' || typeof obj === 'number') {
return obj
} else {
throw new TypeError('You need to define a custom getKey function for your ComboBox object')
}
},
closeOnSelect: true,
inputClass: undefined,
inputContainerClass: undefined,
drawerClass: undefined,
multiple: false,
},
)
const emit = defineEmits<{
(e: 'update:modelValue', value: ItemType[]): void
(e: 'update:modelValue', value: T | T[]): void
(e: 'search', value: string): void
(e: 'open'): void
(e: 'close'): void
......@@ -237,9 +244,9 @@ function ensureOpen(event: Event) {
}
}
function selectChoice(choice: ItemType) {
if (!props.multiple) {
emit('update:modelValue', [choice])
function selectChoice(choice: T) {
if (!Array.isArray(props.modelValue)) {
emit('update:modelValue', choice)
} else {
const objIdentity = props.getKey(choice)
const dataCopy = Array.from(props.modelValue)
......@@ -266,7 +273,7 @@ function selectChoice(choice: ItemType) {
}
function maybeRemoveChoice() {
if (query.value === '' && props.modelValue.length > 0) {
if (query.value === '' && Array.isArray(props.modelValue)) {
const newValue = Array.from(props.modelValue)
newValue.splice(newValue.length - 1, 1)
emit('update:modelValue', newValue)
......
......@@ -52,7 +52,6 @@
v-model="contributors"
:choices="relevantHosts"
:close-on-select="false"
multiple
input-container-class="tw-flex tw-flex-wrap tw-gap-2 tw-w-full form-control tw-h-auto tw-min-h-[46px]"
input-class="tw-border-none tw-min-w-[150px] focus:tw-outline-none"
@search="hostSearch = $event"
......@@ -63,9 +62,9 @@
</li>
</template>
<template #selected="{ items, deselect }">
<template #selected="{ deselect }">
<Tag
v-for="(host, index) in items"
v-for="(host, index) in contributors"
:key="index"
:label="host.name"
removable
......
<template>
<ComboBox
v-if="!areShowsLoading"
v-model="showModel"
v-model="selectedShow"
:label="t('showSelector.selectShow')"
:no-data-label="hasShows ? t('showSelector.noDataMatch') : t('showSelector.noData')"
:keyboard-shortcut="!isMac ? keys.alt_k : undefined"
......@@ -108,10 +108,6 @@ const sortedShows = computed(() => {
{ asc: (show) => sanitizeHTML(show.name).toLowerCase() },
])
})
const showModel = computed({
get: () => [selectedShow.value],
set: (value: Show[]) => (selectedShow.value = value[0]),
})
const filteredShows = computed(() => {
return sortedShows.value
.filter((show) => (filterActive.value !== null ? show.isActive === filterActive.value : true))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment