Fixed #5277 - Dropdown: aria-label missing from inner ul element

pull/5638/head
tugcekucukoglu 2024-04-24 09:03:12 +03:00
parent b2a4af2fce
commit c390ba7270
6 changed files with 19 additions and 5 deletions

View File

@ -117,7 +117,7 @@
<slot name="header" :value="modelValue" :suggestions="visibleOptions"></slot> <slot name="header" :value="modelValue" :suggestions="visibleOptions"></slot>
<VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :style="{ height: scrollHeight }" :items="visibleOptions" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')"> <VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :style="{ height: scrollHeight }" :items="visibleOptions" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')">
<template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }"> <template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" v-bind="ptm('list')"> <ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" :aria-label="listAriaLabel" 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('itemGroup')" role="option" v-bind="ptm('itemGroup')"> <li v-if="isOptionGroup(option)" :id="id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('itemGroup')" role="option" v-bind="ptm('itemGroup')">
<slot name="optiongroup" :option="option.optionGroup" :item="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">{{ getOptionGroupLabel(option.optionGroup) }}</slot> <slot name="optiongroup" :option="option.optionGroup" :item="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">{{ getOptionGroupLabel(option.optionGroup) }}</slot>
@ -924,6 +924,9 @@ export default {
selectedMessageText() { selectedMessageText() {
return this.hasSelectedOption ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.modelValue.length : '1') : this.emptySelectionMessageText; return this.hasSelectedOption ? this.selectionMessageText.replaceAll('{0}', this.multiple ? this.modelValue.length : '1') : this.emptySelectionMessageText;
}, },
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
},
focusedOptionId() { focusedOptionId() {
return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null; return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null;
}, },

View File

@ -1,5 +1,5 @@
<template> <template>
<ul :ref="containerRef" :class="cx('list')" v-bind="level === 0 ? ptm('list') : ptm('sublist')"> <ul :ref="containerRef" :class="cx('list')" :aria-label="listAriaLabel" v-bind="level === 0 ? ptm('list') : ptm('sublist')">
<template v-for="(processedOption, index) of options" :key="getOptionLabelToRender(processedOption)"> <template v-for="(processedOption, index) of options" :key="getOptionLabelToRender(processedOption)">
<li <li
:id="getOptionId(processedOption)" :id="getOptionId(processedOption)"
@ -161,6 +161,9 @@ export default {
}, },
containerRef(el) { containerRef(el) {
this.container = el; this.container = el;
},
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
} }
}, },
directives: { directives: {

View File

@ -275,6 +275,7 @@ export interface PrimeVueLocaleAriaOptions {
zoomOut?: string; zoomOut?: string;
rotateRight?: string; rotateRight?: string;
rotateLeft?: string; rotateLeft?: string;
listLabel?: string;
} }
export interface PrimeVueLocaleOptions { export interface PrimeVueLocaleOptions {

View File

@ -119,7 +119,8 @@ export const defaultOptions = {
zoomIn: 'Zoom In', zoomIn: 'Zoom In',
zoomOut: 'Zoom Out', zoomOut: 'Zoom Out',
rotateRight: 'Rotate Right', rotateRight: 'Rotate Right',
rotateLeft: 'Rotate Left' rotateLeft: 'Rotate Left',
listLabel: 'Option List'
} }
}, },
filterMatchModeOptions: { filterMatchModeOptions: {

View File

@ -105,7 +105,7 @@
<div :class="cx('wrapper')" :style="{ 'max-height': virtualScrollerDisabled ? scrollHeight : '' }" v-bind="ptm('wrapper')"> <div :class="cx('wrapper')" :style="{ 'max-height': virtualScrollerDisabled ? scrollHeight : '' }" v-bind="ptm('wrapper')">
<VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :items="visibleOptions" :style="{ height: scrollHeight }" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')"> <VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :items="visibleOptions" :style="{ height: scrollHeight }" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')">
<template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }"> <template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" v-bind="ptm('list')"> <ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" :aria-label="listAriaLabel" 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('itemGroup')" role="option" v-bind="ptm('itemGroup')"> <li v-if="isOptionGroup(option)" :id="id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('itemGroup')" role="option" v-bind="ptm('itemGroup')">
<slot name="optiongroup" :option="option.optionGroup" :index="getOptionIndex(i, getItemOptions)"> <slot name="optiongroup" :option="option.optionGroup" :index="getOptionIndex(i, getItemOptions)">
@ -964,6 +964,9 @@ export default {
selectedMessageText() { selectedMessageText() {
return this.hasSelectedOption ? this.selectionMessageText.replaceAll('{0}', '1') : this.emptySelectionMessageText; return this.hasSelectedOption ? this.selectionMessageText.replaceAll('{0}', '1') : this.emptySelectionMessageText;
}, },
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
},
focusedOptionId() { focusedOptionId() {
return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null; return this.focusedOptionIndex !== -1 ? `${this.id}_${this.focusedOptionIndex}` : null;
}, },

View File

@ -119,7 +119,7 @@
<div :class="cx('wrapper')" :style="{ 'max-height': virtualScrollerDisabled ? scrollHeight : '' }" v-bind="ptm('wrapper')"> <div :class="cx('wrapper')" :style="{ 'max-height': virtualScrollerDisabled ? scrollHeight : '' }" v-bind="ptm('wrapper')">
<VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :items="visibleOptions" :style="{ height: scrollHeight }" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')"> <VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :items="visibleOptions" :style="{ height: scrollHeight }" :tabindex="-1" :disabled="virtualScrollerDisabled" :pt="ptm('virtualScroller')">
<template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }"> <template v-slot:content="{ styleClass, contentRef, items, getItemOptions, contentStyle, itemSize }">
<ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" aria-multiselectable="true" v-bind="ptm('list')"> <ul :ref="(el) => listRef(el, contentRef)" :id="id + '_list'" :class="[cx('list'), styleClass]" :style="contentStyle" role="listbox" aria-multiselectable="true" :aria-label="listAriaLabel" 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('itemGroup')" role="option" v-bind="ptm('itemGroup')"> <li v-if="isOptionGroup(option)" :id="id + '_' + getOptionIndex(i, getItemOptions)" :style="{ height: itemSize ? itemSize + 'px' : undefined }" :class="cx('itemGroup')" role="option" v-bind="ptm('itemGroup')">
<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>
@ -1088,6 +1088,9 @@ export default {
closeAriaLabel() { closeAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.close : undefined; return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.close : undefined;
}, },
listAriaLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.listLabel : undefined;
},
virtualScrollerDisabled() { virtualScrollerDisabled() {
return !this.virtualScrollerOptions; return !this.virtualScrollerOptions;
} }