Accessibility for SelectButton
parent
519359e2d4
commit
3df8b0eb1f
|
@ -46,12 +46,6 @@ const SelectButtonProps = [
|
|||
type: "string",
|
||||
default: "null",
|
||||
description: "A property to uniquely identify an option."
|
||||
},
|
||||
{
|
||||
name: "ariaLabelledBy",
|
||||
type: "string",
|
||||
default: "null",
|
||||
description: "Establishes relationships between the component and label(s) where its value should be one or more element IDs."
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -51,10 +51,6 @@ export interface SelectButtonProps {
|
|||
* A property to uniquely identify an option.
|
||||
*/
|
||||
dataKey?: string | undefined;
|
||||
/**
|
||||
* Establishes relationships between the component and label(s) where its value should be one or more element IDs.
|
||||
*/
|
||||
ariaLabelledBy?: string | undefined;
|
||||
}
|
||||
|
||||
export interface SelectButtonSlots {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<template>
|
||||
<div :class="containerClass" role="group">
|
||||
<div v-for="(option, i) of options" :key="getOptionRenderKey(option)" :aria-label="getOptionLabel(option)" role="button" :aria-pressed="isSelected(option)"
|
||||
@click="onOptionSelect($event, option, i)" @keydown.enter.prevent="onOptionSelect($event, option, i)" @keydown.space.prevent="onOptionSelect($event, option)"
|
||||
:tabindex="isOptionDisabled(option) ? null : '0'" @focus="onFocus($event)" @blur="onBlur($event)" :aria-labelledby="ariaLabelledBy" v-ripple
|
||||
:class="getButtonClass(option)">
|
||||
:class="getButtonClass(option)" :tabindex="isOptionDisabled(option) ? null : '0'" v-ripple
|
||||
@click="onOptionSelect($event, option)" @keydown="onKeydown($event, option)" @focus="onFocus($event)" @blur="onBlur($event)">
|
||||
<slot name="option" :option="option" :index="i">
|
||||
<span class="p-button-label">{{getOptionLabel(option)}}</span>
|
||||
</slot>
|
||||
|
@ -26,8 +25,7 @@ export default {
|
|||
optionDisabled: null,
|
||||
multiple: Boolean,
|
||||
disabled: Boolean,
|
||||
dataKey: null,
|
||||
ariaLabelledBy: null
|
||||
dataKey: null
|
||||
},
|
||||
methods: {
|
||||
getOptionLabel(option) {
|
||||
|
@ -58,12 +56,19 @@ export default {
|
|||
newValue = this.modelValue ? [...this.modelValue, optionValue]: [optionValue];
|
||||
}
|
||||
else {
|
||||
newValue = optionValue;
|
||||
newValue = selected ? null : optionValue;
|
||||
}
|
||||
|
||||
this.$emit('update:modelValue', newValue);
|
||||
this.$emit('change', {event: event, value: newValue});
|
||||
},
|
||||
onKeydown(event, option) {
|
||||
//space
|
||||
if (event.which === 32) {
|
||||
this.onOptionSelect(event, option);
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
isSelected(option) {
|
||||
let selected = false;
|
||||
let optionValue = this.getOptionValue(option);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<SelectButton v-model="value2" :options="paymentOptions" optionLabel="name" multiple />
|
||||
|
||||
<h5>Custom Content</h5>
|
||||
<SelectButton v-model="value3" :options="justifyOptions" dataKey="value">
|
||||
<SelectButton v-model="value3" :options="justifyOptions" optionLabel="value" dataKey="value" >
|
||||
<template #option="slotProps">
|
||||
<i :class="slotProps.option.icon"></i>
|
||||
</template>
|
||||
|
@ -45,10 +45,10 @@ export default {
|
|||
{name: 'Option 3', value: 3}
|
||||
],
|
||||
justifyOptions: [
|
||||
{icon: 'pi pi-align-left', value: 'left'},
|
||||
{icon: 'pi pi-align-right', value: 'Right'},
|
||||
{icon: 'pi pi-align-center', value: 'Center'},
|
||||
{icon: 'pi pi-align-justify', value: 'Justify'}]
|
||||
{icon: 'pi pi-align-left', value: 'Left', tabindex: 2},
|
||||
{icon: 'pi pi-align-right', value: 'Right', tabindex: 2},
|
||||
{icon: 'pi pi-align-center', value: 'Center', tabindex: 3},
|
||||
{icon: 'pi pi-align-justify', value: 'Justify', tabindex: 4}]
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -117,12 +117,6 @@ export default {
|
|||
<td>string</td>
|
||||
<td>null</td>
|
||||
<td>A property to uniquely identify an option.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ariaLabelledBy</td>
|
||||
<td>string</td>
|
||||
<td>null</td>
|
||||
<td>Establishes relationships between the component and label(s) where its value should be one or more element IDs.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -178,6 +172,36 @@ export default {
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<h5>Accessibility</h5>
|
||||
<DevelopmentSection>
|
||||
<h6>Screen Reader</h6>
|
||||
<p>The container element that wraps the buttons has a <i>group</i> role whereas each button element uses <i>button</i> role and <i>aria-pressed</i> is updated depending on selection state.
|
||||
Value to describe an option is automatically set using the <i>aria-label</i> property that refers to the label of an option so it is still suggested to define a label even the option display
|
||||
consists of presentational content like icons only.</p>
|
||||
|
||||
<h6>Keyboard Support</h6>
|
||||
<div class="doc-tablewrapper">
|
||||
<table class="doc-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>Function</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><i>tab</i></td>
|
||||
<td>Moves focus to the buttons.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i>space</i></td>
|
||||
<td>Toggles the checked state of a button.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</DevelopmentSection>
|
||||
|
||||
<h5>Dependencies</h5>
|
||||
<p>None.</p>
|
||||
</AppDoc>
|
||||
|
@ -200,7 +224,7 @@ export default {
|
|||
<SelectButton v-model="value2" :options="paymentOptions" optionLabel="name" multiple />
|
||||
|
||||
<h5>Custom Content</h5>
|
||||
<SelectButton v-model="value3" :options="justifyOptions" dataKey="value">
|
||||
<SelectButton v-model="value3" :options="justifyOptions" optionLabel="value" dataKey="value">
|
||||
<template #option="slotProps">
|
||||
<i :class="slotProps.option.icon"></i>
|
||||
</template>
|
||||
|
@ -222,7 +246,7 @@ export default {
|
|||
{name: 'Option 3', value: 3}
|
||||
],
|
||||
justifyOptions: [
|
||||
{icon: 'pi pi-align-left', value: 'left'},
|
||||
{icon: 'pi pi-align-left', value: 'Left'},
|
||||
{icon: 'pi pi-align-right', value: 'Right'},
|
||||
{icon: 'pi pi-align-center', value: 'Center'},
|
||||
{icon: 'pi pi-align-justify', value: 'Justify'}]
|
||||
|
@ -244,7 +268,7 @@ export default {
|
|||
<SelectButton v-model="value2" :options="paymentOptions" optionLabel="name" multiple />
|
||||
|
||||
<h5>Custom Content</h5>
|
||||
<SelectButton v-model="value3" :options="justifyOptions" dataKey="value">
|
||||
<SelectButton v-model="value3" :options="justifyOptions" optionLabel="value" dataKey="value">
|
||||
<template #option="slotProps">
|
||||
<i :class="slotProps.option.icon"></i>
|
||||
</template>
|
||||
|
@ -267,7 +291,7 @@ export default {
|
|||
{name: 'Option 3', value: 3}
|
||||
]);
|
||||
const justifyOptions = ref([
|
||||
{icon: 'pi pi-align-left', value: 'left'},
|
||||
{icon: 'pi pi-align-left', value: 'Left'},
|
||||
{icon: 'pi pi-align-right', value: 'Right'},
|
||||
{icon: 'pi pi-align-center', value: 'Center'},
|
||||
{icon: 'pi pi-align-justify', value: 'Justify'}
|
||||
|
@ -290,7 +314,7 @@ export default {
|
|||
<p-selectbutton v-model="value2" :options="paymentOptions" option-label="name" multiple></p-selectbutton>
|
||||
|
||||
<h5>Custom Content</h5>
|
||||
<p-selectbutton v-model="value3" :options="justifyOptions" data-key="value">
|
||||
<p-selectbutton v-model="value3" :options="justifyOptions" option-label="value" data-key="value">
|
||||
<template #option="slotProps">
|
||||
<i :class="slotProps.option.icon"></i>
|
||||
</template>
|
||||
|
@ -312,7 +336,7 @@ export default {
|
|||
{name: 'Option 3', value: 3}
|
||||
]);
|
||||
const justifyOptions = ref([
|
||||
{icon: 'pi pi-align-left', value: 'left'},
|
||||
{icon: 'pi pi-align-left', value: 'Left'},
|
||||
{icon: 'pi pi-align-right', value: 'Right'},
|
||||
{icon: 'pi pi-align-center', value: 'Center'},
|
||||
{icon: 'pi pi-align-justify', value: 'Justify'}
|
||||
|
|
Loading…
Reference in New Issue