Skip to content

Commit

Permalink
Fixed #3304 - Improve Paginator Implementation for Accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
tugcekucukoglu committed Nov 22, 2022
1 parent 83c7bcb commit ee2bf49
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 22 deletions.
9 changes: 9 additions & 0 deletions src/components/config/PrimeVue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ interface PrimeVueLocaleAriaOptions {
moveTop?: string;
moveDown?: string;
moveBottom?: string;
pageLabel?: string;
firstPageLabel?: string;
lastPageLabel?: string;
nextPageLabel?: string;
prevPageLabel?: string;
rowsPerPageLabel?: string;
previousPageLabel?: string;
jumpToPageDropdownLabel?: string;
jumpToPageInputLabel?: string;
}

interface PrimeVueLocaleOptions {
Expand Down
8 changes: 5 additions & 3 deletions src/components/config/PrimeVue.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,15 @@ const defaultOptions = {
moveUp: 'Move Up',
moveDown: 'Move Down',
moveBottom: 'Move Bottom',
pageLabel: 'Page',
pageLabel: '{page}',
firstPageLabel: 'First Page',
lastPageLabel: 'Last Page',
nextPageLabel: 'Next Page',
rowsPerPageDropdownLabel: 'Rows per page',
prevPageLabel: 'Previous Page',
rowsPerPageLabel: 'Rows per page',
previousPageLabel: 'Previous Page',
jumpToPageLabel: 'Jump to Page'
jumpToPageDropdownLabel: 'Jump to Page Dropdown',
jumpToPageInputLabel: 'Jump to Page Input'
}
},
filterMatchModeOptions: {
Expand Down
7 changes: 6 additions & 1 deletion src/components/paginator/JumpToPageInput.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<JTPInput :modelValue="page" @update:modelValue="onChange($event)" class="p-paginator-page-input" :disabled="disabled"></JTPInput>
<JTPInput :modelValue="page" class="p-paginator-page-input" :aria-label="inputArialabel" :disabled="disabled" @update:modelValue="onChange($event)"></JTPInput>
</template>

<script>
Expand All @@ -19,6 +19,11 @@ export default {
this.$emit('page-change', value - 1);
}
},
computed: {
inputArialabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.jumpToPageInputLabel : undefined;
}
},
components: {
JTPInput: InputNumber
}
Expand Down
17 changes: 16 additions & 1 deletion src/components/paginator/PageLinks.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
<template>
<span class="p-paginator-pages">
<button v-for="pageLink of value" :key="pageLink" v-ripple :class="['p-paginator-page p-paginator-element p-link', { 'p-highlight': pageLink - 1 === page }]" type="button" @click="onPageLinkClick($event, pageLink)">{{ pageLink }}</button>
<button
v-for="pageLink of value"
:key="pageLink"
v-ripple
:class="['p-paginator-page p-paginator-element p-link', { 'p-highlight': pageLink - 1 === page }]"
type="button"
:aria-label="ariaPageLabel(pageLink)"
:aria-current="pageLink - 1 === page ? page : undefined"
@click="onPageLinkClick($event, pageLink)"
>
{{ pageLink }}
</button>
</span>
</template>
<script>
Expand All @@ -20,8 +31,12 @@ export default {
originalEvent: event,
value: pageLink
});
},
ariaPageLabel(value) {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.pageLabel.replace(/{page}/g, value) : undefined;
}
},
computed: {},
directives: {
ripple: Ripple
}
Expand Down
19 changes: 6 additions & 13 deletions src/components/paginator/Paginator.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<template>
<div v-if="alwaysShow ? true : pageLinks && pageLinks.length > 1">
<nav v-if="alwaysShow ? true : pageLinks && pageLinks.length > 1">
<div v-for="(value, key) in templateItems" :key="key" ref="paginator" class="p-paginator p-component" :class="getPaginatorClasses(key)">
<div v-if="$slots.start" class="p-paginator-left-content">
<slot name="start" :state="currentState"></slot>
</div>
<template v-for="item in value" :key="item">
<FirstPageLink v-if="item === 'FirstPageLink'" :aria-label="getAriaLabel('firstPageLabel')" @click="changePageToFirst($event)" :disabled="isFirstPage || empty" />
<PrevPageLink v-else-if="item === 'PrevPageLink'" :aria-label="getAriaLabel('previousPageLabel')" @click="changePageToPrev($event)" :disabled="isFirstPage || empty" />
<PrevPageLink v-else-if="item === 'PrevPageLink'" :aria-label="getAriaLabel('prevPageLabel')" @click="changePageToPrev($event)" :disabled="isFirstPage || empty" />
<NextPageLink v-else-if="item === 'NextPageLink'" :aria-label="getAriaLabel('nextPageLabel')" @click="changePageToNext($event)" :disabled="isLastPage || empty" />
<LastPageLink v-else-if="item === 'LastPageLink'" :aria-label="getAriaLabel('lastPageLabel')" @click="changePageToLast($event)" :disabled="isLastPage || empty" />
<PageLinks v-else-if="item === 'PageLinks'" :aria-label="getAriaLabel('pageLabel')" :value="pageLinks" :page="page" @click="changePageLink($event)" />
Expand All @@ -21,22 +21,15 @@
:rows="d_rows"
:totalRecords="totalRecords"
/>
<RowsPerPageDropdown
v-else-if="item === 'RowsPerPageDropdown' && rowsPerPageOptions"
:aria-label="getAriaLabel('rowsPerPageDropdownLabel')"
:rows="d_rows"
:options="rowsPerPageOptions"
@rows-change="onRowChange($event)"
:disabled="empty"
/>
<JumpToPageDropdown v-else-if="item === 'JumpToPageDropdown'" :aria-label="getAriaLabel('jumpToPageLabel')" :page="page" :pageCount="pageCount" @page-change="changePage($event)" :disabled="empty" />
<JumpToPageInput v-else-if="item === 'JumpToPageInput'" :aria-label="getAriaLabel('jumpToPageLabel')" :page="currentPage" @page-change="changePage($event)" :disabled="empty" />
<RowsPerPageDropdown v-else-if="item === 'RowsPerPageDropdown' && rowsPerPageOptions" :aria-label="getAriaLabel('rowsPerPageLabel')" :rows="d_rows" :options="rowsPerPageOptions" @rows-change="onRowChange($event)" :disabled="empty" />
<JumpToPageDropdown v-else-if="item === 'JumpToPageDropdown'" :aria-label="getAriaLabel('jumpToPageDropdownLabel')" :page="page" :pageCount="pageCount" @page-change="changePage($event)" :disabled="empty" />
<JumpToPageInput v-else-if="item === 'JumpToPageInput'" :page="currentPage" @page-change="changePage($event)" :disabled="empty" />
</template>
<div v-if="$slots.end" class="p-paginator-right-content">
<slot name="end" :state="currentState"></slot>
</div>
</div>
</div>
</nav>
</template>

<script>
Expand Down
8 changes: 5 additions & 3 deletions src/views/locale/LocaleDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,15 @@ locale: {
moveUp: 'Move Up',
moveDown: 'Move Down',
moveBottom: 'Move Bottom',
pageLabel: 'Page',
pageLabel: '{page}',
firstPageLabel: 'First Page',
lastPageLabel: 'Last Page',
nextPageLabel: 'Next Page',
rowsPerPageDropdownLabel: 'Rows per page',
prevPageLabel: 'Previous Page',
rowsPerPageLabel: 'Rows per page',
previousPageLabel: 'Previous Page',
jumpToPageLabel: 'Jump to Page'
jumpToPageDropdownLabel: 'Jump to Page Dropdown',
jumpToPageInputLabel: 'Jump to Page Input'
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/views/paginator/PaginatorDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
'640px': 'PrevPageLink CurrentPageReport NextPageLink',
'960px': 'FirstPageLink PrevPageLink CurrentPageReport NextPageLink LastPageLink',
'1300px': 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink',
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink JumpToPageDropdown'
default: 'FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink JumpToPageDropdown JumpToPageInput'
}"
:rows="10"
:totalRecords="totalRecords"
Expand Down
61 changes: 61 additions & 0 deletions src/views/paginator/PaginatorDoc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,67 @@ onPage(event) {
</table>
</div>

<h5>Accessibility</h5>
<h6>Screen Reader</h6>
<p>Paginator is placed inside a <i>nav</i> element to indicate a navigation section. All of the paginator elements can be customized using templating however the default behavious is listed below.</p>

<p>
First, previous, next and last page navigators elements with <i>aria-label</i> attributes referring to the <i>aria.firstPageLabel</i>, <i>aria.prevPageLabel</i>, <i>aria.nextPageLabel</i> and <i>aria.lastPageLabel</i> properties of the
<router-link to="/locale">locale</router-link> API respectively.
</p>

<p>
Page links are also button elements with an <i>aria-label</i> attribute derived from the <i>aria.pageLabel</i> of the <router-link to="/locale">locale</router-link> API. Current page is marked with <i>aria-current</i> set to "page" as
well.
</p>

<p>Current page report uses <i>aria-live="polite"</i> to instruct screen reader about the changes to the pagination state.</p>

<p>
Rows per page dropdown internally uses a dropdown component, refer to the <router-link to="/dropdown">dropdown</router-link> documentation for accessibility details. Additionally, the dropdown uses an <i>aria-label</i> from the
<i>aria.rowsPerPageLabel</i> property of the <router-link to="/locale">locale</router-link> API.
</p>

<p>
Jump to page input is an <i>input</i> element with an <i>aria-label</i> that refers to the <i>aria.jumpToPageInputLabel</i> property and jump to page dropdown internally uses a dropdown component, with an <i>aria-label</i> that refers to
the <i>aria.jumpToPageDropdownLabel</i> property of the <router-link to="/locale">locale</router-link> API.
</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 through the paginator elements.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Executes the paginator element action.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Executes the paginator element action.</td>
</tr>
</tbody>
</table>
</div>

<h6>Rows Per Page Dropdown Keyboard Support</h6>
<p>Refer to the <router-link to="/dropdown">dropdown</router-link> documentation for more details about keyboard support.</p>

<h5>Dependencies</h5>
<p>None.</p>
</AppDoc>
Expand Down

0 comments on commit ee2bf49

Please sign in to comment.