Skip to content

Commit

Permalink
refactor(filter): only accept objects
Browse files Browse the repository at this point in the history
  • Loading branch information
KaelWD committed Feb 18, 2022
1 parent 31e708c commit 6143358
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 39 deletions.
13 changes: 6 additions & 7 deletions packages/vuetify/src/components/VAutocomplete/VAutocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,15 @@ export const VAutocomplete = genericComponent<new <T>() => {
})
}

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 = []
Expand Down Expand Up @@ -211,6 +207,9 @@ export const VAutocomplete = genericComponent<new <T>() => {
v-model:active={ model.value }
activeStrategy={ props.multiple ? 'multiple' : 'single' }
>
{ !filteredItems.value.length && !props.hideNoData && (
<VListItem title={ t(props.noDataText) } />
)}
{ filteredItems.value.map(({ item, matches }) => (
<VListItem
value={ item.value }
Expand Down Expand Up @@ -262,7 +261,7 @@ export const VAutocomplete = genericComponent<new <T>() => {
})

return useForwardRef({
//
filteredItems,
}, vTextFieldRef)
},
})
Expand Down
34 changes: 14 additions & 20 deletions packages/vuetify/src/composables/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, FilterFunction>
Expand Down Expand Up @@ -38,8 +39,8 @@ export const makeFilterProps = propsFactory({
},
}, 'filter')

export function filterItems (
items: (Record<string, any> | string)[],
export function filterItems<T = Record<string, any>> (
items: T[],
query: string,
options?: {
customKeyFilter?: FilterKeyFunctions
Expand All @@ -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<string, FilterMatch> }[] = []
// 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
Expand All @@ -60,14 +60,14 @@ export function filterItems (
loop:
for (const item of items) {
const customMatches: Record<string, FilterMatch> = {}
let defaultMatches: Record<string, FilterMatch> | FilterMatch[] = {}
const defaultMatches: Record<string, FilterMatch> = {}
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
Expand Down Expand Up @@ -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 } })
Expand All @@ -114,10 +108,10 @@ export function filterItems (
return array
}

export function useFilter (
export function useFilter<T> (
props: FilterProps,
items: Ref<any[]> | any[],
query?: Ref<string | undefined> | undefined,
items: MaybeRef<T[]>,
query?: Ref<string | undefined>,
) {
const strQuery = computed(() => (
typeof query?.value !== 'string' &&
Expand All @@ -126,7 +120,7 @@ export function useFilter (

const filteredItems = computed(() => {
return filterItems(
wrapInRef(items).value,
unref(items),
strQuery.value,
{
customKeyFilter: props.customKeyFilter,
Expand Down
10 changes: 5 additions & 5 deletions packages/vuetify/src/composables/locale.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -126,9 +126,9 @@ export function createDefaultLocaleAdapter (options?: LocaleOptions): LocaleAdap
fallback: MaybeRef<string>
messages: MaybeRef<LocaleMessages>
}) => {
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,
Expand Down
8 changes: 1 addition & 7 deletions packages/vuetify/src/util/helpers.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -479,12 +479,6 @@ export function toKebabCase (str = '') {

export type MaybeRef<T> = T | Ref<T>

export type ExtractMaybeRef<P> = P extends MaybeRef<infer T> ? T : P;

export function wrapInRef <T> (x: T) {
return (isRef(x) ? x : ref(x)) as Ref<ExtractMaybeRef<T>>
}

export function findChildren (vnode?: VNodeChild): ComponentInternalInstance[] {
if (!vnode || typeof vnode !== 'object') {
return []
Expand Down

0 comments on commit 6143358

Please sign in to comment.