|
71 | 71 | v-slot="{ active, selected: optionSelected, disabled: optionDisabled }"
|
72 | 72 | :key="index"
|
73 | 73 | as="template"
|
74 |
| - :value="valueAttribute ? option[valueAttribute] : option" |
| 74 | + :value="valueAttribute ? accessor(option, valueAttribute) : option" |
75 | 75 | :disabled="option.disabled"
|
76 | 76 | >
|
77 | 77 | <li :class="[uiMenu.option.base, uiMenu.option.rounded, uiMenu.option.padding, uiMenu.option.size, uiMenu.option.color, active ? uiMenu.option.active : uiMenu.option.inactive, optionSelected && uiMenu.option.selected, optionDisabled && uiMenu.option.disabled]">
|
@@ -140,6 +140,7 @@ import {
|
140 | 140 | import { computedAsync, useDebounceFn } from '@vueuse/core'
|
141 | 141 | import { defu } from 'defu'
|
142 | 142 | import { twMerge, twJoin } from 'tailwind-merge'
|
| 143 | +import { isEqual } from 'ohash' |
143 | 144 | import UIcon from '../elements/Icon.vue'
|
144 | 145 | import UAvatar from '../elements/Avatar.vue'
|
145 | 146 | import { useUI } from '../../composables/useUI'
|
@@ -364,39 +365,53 @@ export default defineComponent({
|
364 | 365 | })
|
365 | 366 |
|
366 | 367 | const selected = computed(() => {
|
367 |
| - if (props.multiple) { |
368 |
| - if (!Array.isArray(props.modelValue) || !props.modelValue.length) { |
369 |
| - return [] |
| 368 | + function compareValues(value1: any, value2: any) { |
| 369 | + if (props.by && typeof value1 === 'object' && typeof value2 === 'object') { |
| 370 | + return isEqual(value1[props.by], value2[props.by]) |
370 | 371 | }
|
| 372 | + return isEqual(value1, value2) |
| 373 | + } |
371 | 374 |
|
| 375 | + function getValue(value: any) { |
372 | 376 | if (props.valueAttribute) {
|
373 |
| - return options.value.filter(option => (props.modelValue as any[]).includes(option[props.valueAttribute])) |
| 377 | + return accessor(value, props.valueAttribute) |
374 | 378 | }
|
375 |
| - return options.value.filter(option => (props.modelValue as any[]).includes(option)) |
| 379 | +
|
| 380 | + return value |
376 | 381 | }
|
377 | 382 |
|
378 |
| - if (props.valueAttribute) { |
379 |
| - return options.value.find(option => option[props.valueAttribute] === props.modelValue) |
| 383 | + if (props.multiple) { |
| 384 | + const modelValue = props.modelValue |
| 385 | + if (!Array.isArray(modelValue) || !modelValue.length) { |
| 386 | + return [] |
| 387 | + } |
| 388 | +
|
| 389 | + return options.value.filter((option) => { |
| 390 | + const optionValue = getValue(option) |
| 391 | + return modelValue.some(value => compareValues(value, optionValue)) |
| 392 | + }) |
380 | 393 | }
|
381 |
| - return options.value.find(option => option === props.modelValue) |
| 394 | +
|
| 395 | + return options.value.find((option) => { |
| 396 | + const optionValue = getValue(option) |
| 397 | + return compareValues(optionValue, toRaw(props.modelValue)) |
| 398 | + }) ?? props.modelValue |
382 | 399 | })
|
383 | 400 |
|
384 | 401 | const label = computed(() => {
|
385 |
| - if (props.multiple) { |
386 |
| - if (Array.isArray(props.modelValue) && props.modelValue.length) { |
387 |
| - return `${selected.value.length} selected` |
388 |
| - } else { |
389 |
| - return null |
390 |
| - } |
391 |
| - } else if (props.modelValue !== undefined && props.modelValue !== null) { |
392 |
| - if (props.valueAttribute) { |
393 |
| - return accessor(selected.value, props.optionAttribute) ?? null |
394 |
| - } else { |
395 |
| - return ['string', 'number'].includes(typeof props.modelValue) ? props.modelValue : accessor(props.modelValue as Record<string, any>, props.optionAttribute) |
396 |
| - } |
| 402 | + if (!selected.value) return null |
| 403 | +
|
| 404 | + if (props.valueAttribute) { |
| 405 | + return accessor(selected.value as Record<string, any>, props.optionAttribute) |
| 406 | + } |
| 407 | +
|
| 408 | + if (Array.isArray(props.modelValue) && props.modelValue.length) { |
| 409 | + return `${props.modelValue.length} selected` |
| 410 | + } else if (['string', 'number'].includes(typeof props.modelValue)) { |
| 411 | + return props.modelValue |
397 | 412 | }
|
398 | 413 |
|
399 |
| - return null |
| 414 | + return accessor(props.modelValue as Record<string, any>, props.optionAttribute) |
400 | 415 | })
|
401 | 416 |
|
402 | 417 | const selectClass = computed(() => {
|
|
0 commit comments