Skip to content

Commit

Permalink
Merge pull request #3834 from jenemde/master
Browse files Browse the repository at this point in the history
A11y enhancements
  • Loading branch information
nolimits4web authored Sep 25, 2020
2 parents fcd5262 + 493ff5c commit a13e307
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 9 deletions.
13 changes: 9 additions & 4 deletions playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
</head>

<body>
<div class="swiper-container">
<section class="swiper-container">
<div class="swiper-scrollbar"></div>
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<button class="swiper-button-prev"></button>
<button class="swiper-button-next"></button>
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
Expand All @@ -26,7 +26,7 @@
<div class="swiper-slide">Slide 10</div>
</div>
<div class="swiper-pagination"></div>
</div>
</section>
<style>
body,
html {
Expand Down Expand Up @@ -75,6 +75,11 @@
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
a11y: {
containerMessage: 'Example content',
containerRoleDescriptionMessage: 'carousel',
itemRoleDescriptionMessage: 'slide',
},
});
</script>
</body>
Expand Down
72 changes: 67 additions & 5 deletions src/components/a11y/a11y.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import $ from '../../utils/dom';
import { bindModuleMethods } from '../../utils/utils';

const A11y = {
getRandomNumber(size = 16) {
const randomChar = () => Math.round(16 * Math.random()).toString(16);
return 'x'.repeat(size).replace(/x/g, randomChar);
},
makeElFocusable($el) {
$el.attr('tabIndex', '0');
return $el;
Expand All @@ -14,10 +18,26 @@ const A11y = {
$el.attr('role', role);
return $el;
},
addElRoleDescription($el, description) {
$el.attr('aria-role-description', description);
return $el;
},
addElControls($el, controls) {
$el.attr('aria-controls', controls);
return $el;
},
addElLabel($el, label) {
$el.attr('aria-label', label);
return $el;
},
addElId($el, id) {
$el.attr('id', id);
return $el;
},
addElLive($el, live) {
$el.attr('aria-live', live);
return $el;
},
disableEl($el) {
$el.attr('aria-disabled', true);
return $el;
Expand Down Expand Up @@ -111,11 +131,43 @@ const A11y = {
},
init() {
const swiper = this;
const params = swiper.params.a11y;

swiper.$el.append(swiper.a11y.liveRegion);

// Container
const $containerEl = swiper.$el;
if (params.containerRoleDescriptionMessage) {
swiper.a11y.addElRoleDescription($containerEl, params.containerRoleDescriptionMessage);
}
if (params.containerMessage) {
swiper.a11y.addElLabel($containerEl, params.containerMessage);
}

// Wrapper
const $wrapperEl = swiper.$wrapperEl;
const wrapperId = $wrapperEl.attr('id') || `swiper-wrapper-${swiper.a11y.getRandomNumber(16)}`;
let live;
swiper.a11y.addElId($wrapperEl, wrapperId);

if (swiper.params.autoplay && swiper.params.autoplay.enabled) {
live = 'off';
} else {
live = 'polite';
}
swiper.a11y.addElLive($wrapperEl, live);

// Slide
if (params.itemRoleDescriptionMessage) {
swiper.a11y.addElRoleDescription($(swiper.slides), params.itemRoleDescriptionMessage);
}
swiper.a11y.addElRole($(swiper.slides), 'group');
swiper.slides.each((slideEl) => {
const $slideEl = $(slideEl);
swiper.a11y.addElLabel($slideEl, `${$slideEl.index() + 1} / ${swiper.slides.length}`);
});

// Navigation
const params = swiper.params.a11y;
let $nextEl;
let $prevEl;
if (swiper.navigation && swiper.navigation.$nextEl) {
Expand All @@ -124,17 +176,24 @@ const A11y = {
if (swiper.navigation && swiper.navigation.$prevEl) {
$prevEl = swiper.navigation.$prevEl;
}

if ($nextEl) {
swiper.a11y.makeElFocusable($nextEl);
swiper.a11y.addElRole($nextEl, 'button');
if ($nextEl[0].tagName !== 'BUTTON') {
swiper.a11y.addElRole($nextEl, 'button');
$nextEl.on('keydown', swiper.a11y.onEnterKey);
}
swiper.a11y.addElLabel($nextEl, params.nextSlideMessage);
$nextEl.on('keydown', swiper.a11y.onEnterKey);
swiper.a11y.addElControls($nextEl, wrapperId);
}
if ($prevEl) {
swiper.a11y.makeElFocusable($prevEl);
swiper.a11y.addElRole($prevEl, 'button');
if ($prevEl[0].tagName !== 'BUTTON') {
swiper.a11y.addElRole($prevEl, 'button');
$prevEl.on('keydown', swiper.a11y.onEnterKey);
}
swiper.a11y.addElLabel($prevEl, params.prevSlideMessage);
$prevEl.on('keydown', swiper.a11y.onEnterKey);
swiper.a11y.addElControls($prevEl, wrapperId);
}

// Pagination
Expand Down Expand Up @@ -197,6 +256,9 @@ export default {
firstSlideMessage: 'This is the first slide',
lastSlideMessage: 'This is the last slide',
paginationBulletMessage: 'Go to slide {{index}}',
containerMessage: null,
containerRoleDescriptionMessage: null,
itemRoleDescriptionMessage: null,
},
},
create() {
Expand Down
21 changes: 21 additions & 0 deletions src/types/components/a11y.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,25 @@ export interface A11yOptions {
* @default 'swiper-notification'
*/
notificationClass?: string;

/**
* Message for screen readers for outer swiper container
*
* @default null
*/
containerMessage?: string;

/**
* Message for screen readers describing the role of outer swiper container
*
* @default null
*/
containerRoleDescriptionMessage?: string;

/**
* Message for screen readers describing the role of slide element
*
* @default null
*/
itemRoleDescriptionMessage?: string;
}

0 comments on commit a13e307

Please sign in to comment.