@@ -86,6 +86,11 @@ export interface InputMenuProps<T> extends Pick<ComboboxRootProps<T>, 'modelValu
8686 * @defaultValue undefined
8787 */
8888 valueKey? : keyof T
89+ /**
90+ * When `items` is an array of objects, select the field to use as the label.
91+ * @defaultValue 'label'
92+ */
93+ labelKey? : keyof T
8994 items? : T [] | T [][]
9095 /** Highlight the ring color like a focus state. */
9196 highlight? : boolean
@@ -124,18 +129,19 @@ import { useAppConfig } from '#imports'
124129import { useButtonGroup } from ' ../composables/useButtonGroup'
125130import { useComponentIcons } from ' ../composables/useComponentIcons'
126131import { useFormField } from ' ../composables/useFormField'
132+ import { get , escapeRegExp } from ' ../utils'
127133import UIcon from ' ./Icon.vue'
128134import UAvatar from ' ./Avatar.vue'
129135import UChip from ' ./Chip.vue'
130- import { get , escapeRegExp } from ' ../utils'
131136
132137defineOptions ({ inheritAttrs: false })
133138
134139const props = withDefaults (defineProps <InputMenuProps <T >>(), {
135140 type: ' text' ,
136141 autofocusDelay: 0 ,
137142 portal: true ,
138- filter : () => [' label' ]
143+ filter : () => [' label' ],
144+ labelKey: ' label' as keyof T
139145})
140146const emits = defineEmits <InputMenuEmits <T >>()
141147const slots = defineSlots <InputMenuSlots <T >>()
@@ -164,17 +170,17 @@ const ui = computed(() => inputMenu({
164170}))
165171
166172function displayValue(value : AcceptableValue ): string {
167- const item = items .value .find (item => props .valueKey ? isEqual (item [ props .valueKey ] , value ) : isEqual (item , value ))
173+ const item = items .value .find (item => props .valueKey ? isEqual (get ( item as Record < string , any >, props .valueKey as string ) , value ) : isEqual (item , value ))
168174
169- return item && (typeof item === ' object' ? item . label : item )
175+ return item && (typeof item === ' object' ? get ( item , props . labelKey as string ) : item )
170176}
171177
172178function filterFunction(items : ArrayOrWrapped <AcceptableValue >, searchTerm : string ): ArrayOrWrapped <AcceptableValue > {
173179 if (props .filter === false ) {
174180 return items
175181 }
176182
177- const fields = Array .isArray (props .filter ) ? props .filter : [' label ' ]
183+ const fields = Array .isArray (props .filter ) ? props .filter : [props . labelKey ]
178184 const escapedSearchTerm = escapeRegExp (searchTerm )
179185
180186 return items .filter ((item ) => {
@@ -183,7 +189,7 @@ function filterFunction(items: ArrayOrWrapped<AcceptableValue>, searchTerm: stri
183189 }
184190
185191 return fields .some ((field ) => {
186- const child = get (item , field )
192+ const child = get (item , field as string )
187193
188194 return child !== null && child !== undefined && String (child ).search (new RegExp (escapedSearchTerm , ' i' )) !== - 1
189195 })
@@ -325,7 +331,7 @@ defineExpose({
325331 <ComboboxGroup v-for =" (group, groupIndex) in groups" :key =" `group-${groupIndex}`" :class =" ui.group({ class: props.ui?.group })" >
326332 <template v-for =" (item , index ) in group " :key =" ` group-${groupIndex }-${index } ` " >
327333 <ComboboxLabel v-if =" item?.type === 'label'" :class =" ui.label({ class: props.ui?.label })" >
328- {{ item.label }}
334+ {{ get( item, props.labelKey as string) }}
329335 </ComboboxLabel >
330336
331337 <ComboboxSeparator v-else-if =" item?.type === 'separator'" :class =" ui.separator({ class: props.ui?.separator })" />
@@ -334,7 +340,7 @@ defineExpose({
334340 v-else
335341 :class =" ui.item({ class: props.ui?.item })"
336342 :disabled =" item.disabled"
337- :value =" valueKey && typeof item === 'object' ? (item[ valueKey as keyof InputMenuItem]) as AcceptableValue : item"
343+ :value =" valueKey && typeof item === 'object' ? get (item, props. valueKey as string) : item"
338344 @select =" item.select"
339345 >
340346 <slot name =" item" :item =" (item as T)" :index =" index" >
@@ -353,7 +359,7 @@ defineExpose({
353359
354360 <span :class =" ui.itemLabel({ class: props.ui?.itemLabel })" >
355361 <slot name =" item-label" :item =" (item as T)" :index =" index" >
356- {{ typeof item === 'object' ? item.label : item }}
362+ {{ typeof item === 'object' ? get( item, props.labelKey as string) : item }}
357363 </slot >
358364 </span >
359365
0 commit comments