refactor: #7090 for Listbox

pull/7064/merge
Mert Sincan 2025-01-14 11:11:35 +00:00
parent 0bfe3ce507
commit b05dac3b13
1 changed files with 7 additions and 13 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<div :id="id" :class="cx('root')" @focusout="onFocusout" v-bind="ptmi('root')"> <div :id="$id" :class="cx('root')" @focusout="onFocusout" v-bind="ptmi('root')">
<span <span
ref="firstHiddenFocusableElement" ref="firstHiddenFocusableElement"
role="presentation" role="presentation"
@ -25,7 +25,7 @@
autocomplete="off" autocomplete="off"
:disabled="disabled" :disabled="disabled"
:unstyled="unstyled" :unstyled="unstyled"
:aria-owns="id + '_list'" :aria-owns="$id + '_list'"
:aria-activedescendant="focusedOptionId" :aria-activedescendant="focusedOptionId"
:tabindex="!disabled && !focused ? tabindex : -1" :tabindex="!disabled && !focused ? tabindex : -1"
@input="onFilterChange" @input="onFilterChange"
@ -49,7 +49,7 @@
<template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }"> <template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }">
<ul <ul
:ref="(el) => listRef(el, contentRef)" :ref="(el) => listRef(el, contentRef)"
:id="id + '_list'" :id="$id + '_list'"
:class="[cx('list'), styleClass]" :class="[cx('list'), styleClass]"
:style="contentStyle" :style="contentStyle"
:tabindex="-1" :tabindex="-1"
@ -65,12 +65,12 @@
v-bind="ptm('list')" v-bind="ptm('list')"
> >
<template v-for="(option, i) of items" :key="getOptionRenderKey(option, getOptionIndex(i, getItemOptions))"> <template v-for="(option, i) of items" :key="getOptionRenderKey(option, getOptionIndex(i, getItemOptions))">
<li v-if="isOptionGroup(option)" :id="id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('optionGroup')" role="option" v-bind="ptm('optionGroup')"> <li v-if="isOptionGroup(option)" :id="$id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('optionGroup')" role="option" v-bind="ptm('optionGroup')">
<slot name="optiongroup" :option="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">{{ getOptionGroupLabel(option.optionGroup) }}</slot> <slot name="optiongroup" :option="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">{{ getOptionGroupLabel(option.optionGroup) }}</slot>
</li> </li>
<li <li
v-else v-else
:id="id + '_' + getOptionIndex(i, getItemOptions)" :id="$id + '_' + getOptionIndex(i, getItemOptions)"
v-ripple v-ripple
:style="{ height: itemSize ? itemSize + 'px' : undefined }" :style="{ height: itemSize ? itemSize + 'px' : undefined }"
:class="cx('option', { option, index: i, getItemOptions })" :class="cx('option', { option, index: i, getItemOptions })"
@ -135,7 +135,6 @@
import { findSingle, focus, getFirstFocusableElement, isElement } from '@primeuix/utils/dom'; import { findSingle, focus, getFirstFocusableElement, isElement } from '@primeuix/utils/dom';
import { equals, findLastIndex, isNotEmpty, isPrintableCharacter, resolveFieldData } from '@primeuix/utils/object'; import { equals, findLastIndex, isNotEmpty, isPrintableCharacter, resolveFieldData } from '@primeuix/utils/object';
import { FilterService } from '@primevue/core/api'; import { FilterService } from '@primevue/core/api';
import { UniqueComponentId } from '@primevue/core/utils';
import BlankIcon from '@primevue/icons/blank'; import BlankIcon from '@primevue/icons/blank';
import CheckIcon from '@primevue/icons/check'; import CheckIcon from '@primevue/icons/check';
import SearchIcon from '@primevue/icons/search'; import SearchIcon from '@primevue/icons/search';
@ -159,22 +158,17 @@ export default {
searchValue: '', searchValue: '',
data() { data() {
return { return {
id: this.$attrs.id,
filterValue: null, filterValue: null,
focused: false, focused: false,
focusedOptionIndex: -1 focusedOptionIndex: -1
}; };
}, },
watch: { watch: {
'$attrs.id': function (newValue) {
this.id = newValue || UniqueComponentId();
},
options() { options() {
this.autoUpdateModel(); this.autoUpdateModel();
} }
}, },
mounted() { mounted() {
this.id = this.id || UniqueComponentId();
this.autoUpdateModel(); this.autoUpdateModel();
}, },
methods: { methods: {
@ -683,7 +677,7 @@ export default {
}, },
scrollInView(index = -1) { scrollInView(index = -1) {
this.$nextTick(() => { this.$nextTick(() => {
const id = index !== -1 ? `${this.id}_${index}` : this.focusedOptionId; const id = index !== -1 ? `${this.$id}_${index}` : this.focusedOptionId;
const element = findSingle(this.list, `li[id="${id}"]`); const element = findSingle(this.list, `li[id="${id}"]`);
if (element) { if (element) {
@ -764,7 +758,7 @@ export default {
return this.$filled ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.d_value.length : '1') : this.emptySelectionMessageText; return this.$filled ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.d_value.length : '1') : this.emptySelectionMessageText;
}, },
focusedOptionId() { focusedOptionId() {
return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null; return this.focusedOptionIndex !== -1 ? `${this.$id}_${this.focusedOptionIndex}` : null;
}, },
ariaSetSize() { ariaSetSize() {
return this.visibleOptions.filter((option) => !this.isOptionGroup(option)).length; return this.visibleOptions.filter((option) => !this.isOptionGroup(option)).length;