diff --git a/src/runtime/components/InputMenu.vue b/src/runtime/components/InputMenu.vue index 3633bc2f..17289458 100644 --- a/src/runtime/components/InputMenu.vue +++ b/src/runtime/components/InputMenu.vue @@ -86,6 +86,11 @@ export interface InputMenuProps extends Pick, 'modelValu * @defaultValue undefined */ valueKey?: keyof T + /** + * When `items` is an array of objects, select the field to use as the label. + * @defaultValue 'label' + */ + labelKey?: keyof T items?: T[] | T[][] /** Highlight the ring color like a focus state. */ highlight?: boolean @@ -124,10 +129,10 @@ import { useAppConfig } from '#imports' import { useButtonGroup } from '../composables/useButtonGroup' import { useComponentIcons } from '../composables/useComponentIcons' import { useFormField } from '../composables/useFormField' +import { get, escapeRegExp } from '../utils' import UIcon from './Icon.vue' import UAvatar from './Avatar.vue' import UChip from './Chip.vue' -import { get, escapeRegExp } from '../utils' defineOptions({ inheritAttrs: false }) @@ -135,7 +140,8 @@ const props = withDefaults(defineProps>(), { type: 'text', autofocusDelay: 0, portal: true, - filter: () => ['label'] + filter: () => ['label'], + labelKey: 'label' as keyof T }) const emits = defineEmits>() const slots = defineSlots>() @@ -164,9 +170,9 @@ const ui = computed(() => inputMenu({ })) function displayValue(value: AcceptableValue): string { - const item = items.value.find(item => props.valueKey ? isEqual(item[props.valueKey], value) : isEqual(item, value)) + const item = items.value.find(item => props.valueKey ? isEqual(get(item as Record, props.valueKey as string), value) : isEqual(item, value)) - return item && (typeof item === 'object' ? item.label : item) + return item && (typeof item === 'object' ? get(item, props.labelKey as string) : item) } function filterFunction(items: ArrayOrWrapped, searchTerm: string): ArrayOrWrapped { @@ -174,7 +180,7 @@ function filterFunction(items: ArrayOrWrapped, searchTerm: stri return items } - const fields = Array.isArray(props.filter) ? props.filter : ['label'] + const fields = Array.isArray(props.filter) ? props.filter : [props.labelKey] const escapedSearchTerm = escapeRegExp(searchTerm) return items.filter((item) => { @@ -183,7 +189,7 @@ function filterFunction(items: ArrayOrWrapped, searchTerm: stri } return fields.some((field) => { - const child = get(item, field) + const child = get(item, field as string) return child !== null && child !== undefined && String(child).search(new RegExp(escapedSearchTerm, 'i')) !== -1 }) @@ -325,7 +331,7 @@ defineExpose({