From 614335814256a342646e579bb171b3d2e044e136 Mon Sep 17 00:00:00 2001 From: Kael Date: Fri, 18 Feb 2022 19:03:23 +1100 Subject: [PATCH] refactor(filter): only accept objects --- .../VAutocomplete/VAutocomplete.tsx | 13 ++++--- packages/vuetify/src/composables/filter.ts | 34 ++++++++----------- packages/vuetify/src/composables/locale.ts | 10 +++--- packages/vuetify/src/util/helpers.ts | 8 +---- 4 files changed, 26 insertions(+), 39 deletions(-) diff --git a/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx b/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx index 18b8bf22e9c..0880aa08196 100644 --- a/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx +++ b/packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx @@ -112,19 +112,15 @@ export const VAutocomplete = genericComponent() => { }) } - if (!array.length && !props.hideNoData) { - array.push({ title: t(props.noDataText) }) - } - return array }) const selections = computed(() => { - return wrapInArray(model.value).map(value => { + return model.value.map(value => { return items.value.find(item => item.value === value) }) }) const searchValue = computed(() => isPristine.value ? undefined : search.value) - const { filteredItems } = useFilter(props, items.value, searchValue) + const { filteredItems } = useFilter(props, items, searchValue) function onClear (e: MouseEvent) { model.value = [] @@ -211,6 +207,9 @@ export const VAutocomplete = genericComponent() => { v-model:active={ model.value } activeStrategy={ props.multiple ? 'multiple' : 'single' } > + { !filteredItems.value.length && !props.hideNoData && ( + + )} { filteredItems.value.map(({ item, matches }) => ( () => { }) return useForwardRef({ - // + filteredItems, }, vTextFieldRef) }, }) diff --git a/packages/vuetify/src/composables/filter.ts b/packages/vuetify/src/composables/filter.ts index 1235ef6cd06..f53fa23b3ea 100644 --- a/packages/vuetify/src/composables/filter.ts +++ b/packages/vuetify/src/composables/filter.ts @@ -2,11 +2,12 @@ /* eslint-disable no-labels */ // Utilities -import { getPropertyFromItem, propsFactory, wrapInArray, wrapInRef } from '@/util' -import { computed } from 'vue' +import { getPropertyFromItem, propsFactory, wrapInArray } from '@/util' +import { computed, unref } from 'vue' // Types import type { PropType, Ref } from 'vue' +import type { MaybeRef } from '@/util' export type FilterFunction = (value: string, query: string, item?: any) => FilterMatch export type FilterKeyFunctions = Record @@ -38,8 +39,8 @@ export const makeFilterProps = propsFactory({ }, }, 'filter') -export function filterItems ( - items: (Record | string)[], +export function filterItems> ( + items: T[], query: string, options?: { customKeyFilter?: FilterKeyFunctions @@ -48,9 +49,8 @@ export function filterItems ( filterMode?: FilterMode }, ) { - const array: (typeof items) = [] - // always ensure we fallback - // to a functioning filter + const array: { item: T, matches: Record }[] = [] + // always ensure we fall back to a functioning filter const filter = options?.default ?? defaultFilter const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length @@ -60,14 +60,14 @@ export function filterItems ( loop: for (const item of items) { const customMatches: Record = {} - let defaultMatches: Record | FilterMatch[] = {} + const defaultMatches: Record = {} let match: FilterMatch = -1 - if (typeof item === 'object') { + if (query && typeof item === 'object') { const filterKeys = keys || Object.keys(item) for (const key of filterKeys) { - const value = getPropertyFromItem(item, key, item) + const value = getPropertyFromItem(item as any, key, item) const keyFilter = options?.customKeyFilter?.[key] match = keyFilter @@ -100,12 +100,6 @@ export function filterItems ( !defaultMatchesLength ) ) continue - } else if (typeof item === 'string') { - match = filter(item, query, item) - - if (match === -1 || match === false) continue - - defaultMatches = wrapInArray(match) } array.push({ item, matches: { ...defaultMatches, ...customMatches } }) @@ -114,10 +108,10 @@ export function filterItems ( return array } -export function useFilter ( +export function useFilter ( props: FilterProps, - items: Ref | any[], - query?: Ref | undefined, + items: MaybeRef, + query?: Ref, ) { const strQuery = computed(() => ( typeof query?.value !== 'string' && @@ -126,7 +120,7 @@ export function useFilter ( const filteredItems = computed(() => { return filterItems( - wrapInRef(items).value, + unref(items), strQuery.value, { customKeyFilter: props.customKeyFilter, diff --git a/packages/vuetify/src/composables/locale.ts b/packages/vuetify/src/composables/locale.ts index d4841f66524..27c1d52f5fc 100644 --- a/packages/vuetify/src/composables/locale.ts +++ b/packages/vuetify/src/composables/locale.ts @@ -1,5 +1,5 @@ -import { computed, inject, provide } from 'vue' -import { consoleError, consoleWarn, getObjectValueByPath, wrapInRef } from '@/util' +import { computed, inject, provide, ref } from 'vue' +import { consoleError, consoleWarn, getObjectValueByPath } from '@/util' import en from '@/locale/en' @@ -126,9 +126,9 @@ export function createDefaultLocaleAdapter (options?: LocaleOptions): LocaleAdap fallback: MaybeRef messages: MaybeRef }) => { - const current = wrapInRef(options.current) - const fallback = wrapInRef(options.fallback) - const messages = wrapInRef(options.messages) + const current = ref(options.current) + const fallback = ref(options.fallback) + const messages = ref(options.messages) return { current, diff --git a/packages/vuetify/src/util/helpers.ts b/packages/vuetify/src/util/helpers.ts index fee3e86b35d..9d6b02bd0bd 100644 --- a/packages/vuetify/src/util/helpers.ts +++ b/packages/vuetify/src/util/helpers.ts @@ -1,5 +1,5 @@ // Utilities -import { camelize, Fragment, isRef, ref } from 'vue' +import { camelize, Fragment } from 'vue' // Types import type { ComponentInternalInstance, ComponentPublicInstance, InjectionKey, Ref, Slots, VNode, VNodeChild } from 'vue' @@ -479,12 +479,6 @@ export function toKebabCase (str = '') { export type MaybeRef = T | Ref -export type ExtractMaybeRef

= P extends MaybeRef ? T : P; - -export function wrapInRef (x: T) { - return (isRef(x) ? x : ref(x)) as Ref> -} - export function findChildren (vnode?: VNodeChild): ComponentInternalInstance[] { if (!vnode || typeof vnode !== 'object') { return []