mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-28 02:40:35 +01:00
feat(InputMenu/Select/SelectMenu): introduce valueKey prop
Resolves #108
This commit is contained in:
@@ -80,6 +80,11 @@ export interface InputMenuProps<T> extends Pick<ComboboxRootProps<T>, 'modelValu
|
|||||||
* @defaultValue ['label']
|
* @defaultValue ['label']
|
||||||
*/
|
*/
|
||||||
filter?: boolean | string[]
|
filter?: boolean | string[]
|
||||||
|
/**
|
||||||
|
* When `items` is an array of objects, select the field to use as the value instead of the object itself.
|
||||||
|
* @defaultValue undefined
|
||||||
|
*/
|
||||||
|
valueKey?: keyof T
|
||||||
items?: T[] | T[][]
|
items?: T[] | T[][]
|
||||||
/** Highlight the ring color like a focus state. */
|
/** Highlight the ring color like a focus state. */
|
||||||
highlight?: boolean
|
highlight?: boolean
|
||||||
@@ -313,7 +318,7 @@ function onUpdateOpen(value: boolean) {
|
|||||||
|
|
||||||
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
||||||
|
|
||||||
<ComboboxItem v-else :class="ui.item({ class: props.ui?.item })" :disabled="item.disabled" :value="item">
|
<ComboboxItem v-else :class="ui.item({ class: props.ui?.item })" :disabled="item.disabled" :value="valueKey && typeof item === 'object' ? (item[valueKey as keyof InputMenuItem]) as AcceptableValue : item">
|
||||||
<slot name="item" :item="(item as T)" :index="index">
|
<slot name="item" :item="(item as T)" :index="index">
|
||||||
<slot name="item-leading" :item="(item as T)" :index="index">
|
<slot name="item-leading" :item="(item as T)" :index="index">
|
||||||
<UAvatar v-if="item.avatar" :size="(ui.itemLeadingAvatarSize() as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
<UAvatar v-if="item.avatar" :size="(ui.itemLeadingAvatarSize() as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ export interface SelectProps<T> extends Omit<SelectRootProps, 'dir'>, UseCompone
|
|||||||
* @defaultValue true
|
* @defaultValue true
|
||||||
*/
|
*/
|
||||||
portal?: boolean
|
portal?: boolean
|
||||||
|
/**
|
||||||
|
* When `items` is an array of objects, select the field to use as the value.
|
||||||
|
* @defaultValue 'value'
|
||||||
|
*/
|
||||||
|
valueKey?: string
|
||||||
items?: T[] | T[][]
|
items?: T[] | T[][]
|
||||||
/** Highlight the ring color like a focus state. */
|
/** Highlight the ring color like a focus state. */
|
||||||
highlight?: boolean
|
highlight?: boolean
|
||||||
@@ -92,6 +97,7 @@ import { useAppConfig, useComponentIcons, useFormField, useButtonGroup } from '#
|
|||||||
import { UIcon, UChip, UAvatar } from '#components'
|
import { UIcon, UChip, UAvatar } from '#components'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<SelectProps<T>>(), {
|
const props = withDefaults(defineProps<SelectProps<T>>(), {
|
||||||
|
valueKey: 'value' as any,
|
||||||
portal: true
|
portal: true
|
||||||
})
|
})
|
||||||
const emits = defineEmits<SelectEmits>()
|
const emits = defineEmits<SelectEmits>()
|
||||||
@@ -175,7 +181,7 @@ function onUpdateOpen(value: boolean) {
|
|||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</SelectLabel>
|
</SelectLabel>
|
||||||
<SelectSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
<SelectSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
||||||
<SelectItem v-else :class="ui.item({ class: props.ui?.item })" :disabled="item.disabled" :value="typeof item === 'object' ? item.value : item">
|
<SelectItem v-else :class="ui.item({ class: props.ui?.item })" :disabled="item.disabled" :value="typeof item === 'object' ? (item[valueKey as keyof SelectItem] as string) : item">
|
||||||
<slot name="item" :item="(item as T)" :index="index">
|
<slot name="item" :item="(item as T)" :index="index">
|
||||||
<slot name="item-leading" :item="(item as T)" :index="index">
|
<slot name="item-leading" :item="(item as T)" :index="index">
|
||||||
<UAvatar v-if="item.avatar" :size="(ui.itemLeadingAvatarSize() as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
<UAvatar v-if="item.avatar" :size="(ui.itemLeadingAvatarSize() as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ export interface SelectMenuProps<T> extends Pick<ComboboxRootProps<T>, 'modelVal
|
|||||||
* @defaultValue ['label']
|
* @defaultValue ['label']
|
||||||
*/
|
*/
|
||||||
filter?: boolean | string[]
|
filter?: boolean | string[]
|
||||||
|
/**
|
||||||
|
* When `items` is an array of objects, select the field to use as the value instead of the object itself.
|
||||||
|
* @defaultValue undefined
|
||||||
|
*/
|
||||||
|
valueKey?: keyof T
|
||||||
items?: T[] | T[][]
|
items?: T[] | T[][]
|
||||||
/** Highlight the ring color like a focus state. */
|
/** Highlight the ring color like a focus state. */
|
||||||
highlight?: boolean
|
highlight?: boolean
|
||||||
@@ -246,7 +251,7 @@ function onUpdateOpen(value: boolean) {
|
|||||||
|
|
||||||
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
<ComboboxSeparator v-else-if="item?.type === 'separator'" :class="ui.separator({ class: props.ui?.separator })" />
|
||||||
|
|
||||||
<ComboboxItem v-else :class="ui.item({ class: props.ui?.item })" :disabled="item.disabled" :value="item">
|
<ComboboxItem v-else :class="ui.item({ class: props.ui?.item })" :disabled="item.disabled" :value="valueKey && typeof item === 'object' ? (item[valueKey as keyof SelectMenuItem]) as AcceptableValue : item">
|
||||||
<slot name="item" :item="(item as T)" :index="index">
|
<slot name="item" :item="(item as T)" :index="index">
|
||||||
<slot name="item-leading" :item="(item as T)" :index="index">
|
<slot name="item-leading" :item="(item as T)" :index="index">
|
||||||
<UAvatar v-if="item.avatar" :size="(ui.itemLeadingAvatarSize() as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
<UAvatar v-if="item.avatar" :size="(ui.itemLeadingAvatarSize() as AvatarProps['size'])" v-bind="item.avatar" :class="ui.itemLeadingAvatar({ class: props.ui?.itemLeadingAvatar })" />
|
||||||
|
|||||||
Reference in New Issue
Block a user