diff --git a/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx b/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx index d9118990211..031bb5b932d 100644 --- a/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx +++ b/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx @@ -148,14 +148,14 @@ export const VAutocomplete = genericComponent vTextFieldRef.value?.color) const label = computed(() => menu.value ? props.closeText : props.openText) - const { items, transformIn, transformOut } = useItems(props) + const { items, transformIn, transformOut, emptyValues } = useItems(props) const { textColorClasses, textColorStyles } = useTextColor(color) const search = useProxiedModel(props, 'search', '') const model = useProxiedModel( props, 'modelValue', [], - v => transformIn(v === null ? [null] : wrapInArray(v)), + v => transformIn(v === null ? [null] : wrapInArray(v, emptyValues.value)), v => { const transformed = transformOut(v) return props.multiple ? transformed : (transformed[0] ?? null) @@ -385,7 +385,7 @@ export const VAutocomplete = genericComponent title === search.value)) search.value = '' + search.value = '' selectionIndex.value = -1 } }) diff --git a/packages/vuetify/src/components/VCombobox/VCombobox.tsx b/packages/vuetify/src/components/VCombobox/VCombobox.tsx index 262ab674406..0a28123cef4 100644 --- a/packages/vuetify/src/components/VCombobox/VCombobox.tsx +++ b/packages/vuetify/src/components/VCombobox/VCombobox.tsx @@ -159,7 +159,7 @@ export const VCombobox = genericComponent transformIn(wrapInArray(v)), + v => transformIn(wrapInArray(v, [''])), v => { const transformed = transformOut(v) return props.multiple ? transformed : (transformed[0] ?? null) diff --git a/packages/vuetify/src/components/VSelect/VSelect.tsx b/packages/vuetify/src/components/VSelect/VSelect.tsx index 36483e21859..a0b3eedee6b 100644 --- a/packages/vuetify/src/components/VSelect/VSelect.tsx +++ b/packages/vuetify/src/components/VSelect/VSelect.tsx @@ -151,12 +151,12 @@ export const VSelect = genericComponent transformIn(v === null ? [null] : wrapInArray(v)), + v => transformIn(v === null ? [null] : wrapInArray(v, emptyValues.value)), v => { const transformed = transformOut(v) return props.multiple ? transformed : (transformed[0] ?? null) diff --git a/packages/vuetify/src/composables/list-items.ts b/packages/vuetify/src/composables/list-items.ts index 56340662290..7c1484c5c2a 100644 --- a/packages/vuetify/src/composables/list-items.ts +++ b/packages/vuetify/src/composables/list-items.ts @@ -95,7 +95,8 @@ export function transformItems (props: Omit, items: ItemProp export function useItems (props: ItemProps) { const items = computed(() => transformItems(props, props.items)) - const hasNullItem = computed(() => items.value.some(item => item.value === null)) + const allValues = computed(() => items.value.map(item => item.value)) + const hasNullItem = computed(() => allValues.value.includes(null)) function transformIn (value: any[]): ListItem[] { if (!hasNullItem.value) { @@ -120,5 +121,7 @@ export function useItems (props: ItemProps) { : value.map(({ value }) => value) } - return { items, transformIn, transformOut } + const emptyValues = computed(() => ['', null, undefined].filter(v => !allValues.value.includes(v))) + + return { items, transformIn, transformOut, emptyValues } } diff --git a/packages/vuetify/src/util/helpers.ts b/packages/vuetify/src/util/helpers.ts index bd8eddea62e..720c31f4384 100644 --- a/packages/vuetify/src/util/helpers.ts +++ b/packages/vuetify/src/util/helpers.ts @@ -389,11 +389,12 @@ export function arrayDiff (a: any[], b: any[]): any[] { type IfAny = 0 extends (1 & T) ? Y : N; export function wrapInArray ( - v: T | null | undefined + v: T | null | undefined, + emptyValues: any[] = [] ): T extends readonly any[] ? IfAny : NonNullable[] { - return v == null + return v == null || emptyValues.includes(v) ? [] : Array.isArray(v) ? v as any : [v]