Skip to content

Commit

Permalink
Basic accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Maronato committed Mar 20, 2020
1 parent 1f37e6e commit aeb7b10
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 49 deletions.
92 changes: 47 additions & 45 deletions README.md

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion src/components/VtCloseButton.vue
@@ -1,5 +1,10 @@
<template>
<component :is="buttonComponent" :class="classes" v-on="$listeners">
<component
:aria-label="ariaLabel"
:is="buttonComponent"
:class="classes"
v-on="$listeners"
>
</component>
</template>
Expand Down
3 changes: 2 additions & 1 deletion src/components/VtToast.vue
Expand Up @@ -9,7 +9,7 @@
@focus="focusPlay"
>
<Icon v-if="icon" :custom-icon="icon" :type="type" />
<div :class="bodyClasses">
<div :role="accessibility.toastRole || 'alert'" :class="bodyClasses">
<template v-if="typeof content === 'string'">{{ content }}</template>
<component
:is="getVueComponentFromObj(content)"
Expand All @@ -25,6 +25,7 @@
:component="closeButton"
:class-names="closeButtonClassName"
:show-on-hover="showCloseButtonOnHover"
:aria-label="accessibility.closeButtonLabel"
@click.stop="closeToast"
/>
<ProgressBar
Expand Down
15 changes: 13 additions & 2 deletions src/ts/propValidators.ts
Expand Up @@ -41,7 +41,11 @@ const CLOSE_BUTTON = {
default: "button"
},
classNames: COMMON.classNames,
showOnHover: Boolean
showOnHover: Boolean,
ariaLabel: {
type: String,
default: "close"
}
};

const PROGRESS_BAR = {
Expand Down Expand Up @@ -88,7 +92,14 @@ const CORE_TOAST = {
icon: ICON.customIcon,
closeButton: CLOSE_BUTTON.component,
closeButtonClassName: CLOSE_BUTTON.classNames,
showCloseButtonOnHover: CLOSE_BUTTON.showOnHover
showCloseButtonOnHover: CLOSE_BUTTON.showOnHover,
accessibility: {
type: Object as PropType<PluginOptions["accessibility"]>,
default: () => ({
toastRole: "alert",
closeButtonLabel: "close"
})
}
};

const TOAST = {
Expand Down
17 changes: 17 additions & 0 deletions src/types/index.ts
Expand Up @@ -80,6 +80,23 @@ export interface CommonOptions {
* Custom classes applied to the close button of the toast.
*/
closeButtonClassName?: string | string[];
/**
* Accessibility options
*/
accessibility?: {
/**
* Toast accessibility role
*
* Accessibility option "role" for screen readers. Defaults to "alert".
*/
toastRole?: string;
/**
* Close button label
*
* Accessibility option of the closeButton's "label" for screen readers. Defaults to "close".
*/
closeButtonLabel?: string;
};
}

export interface PluginOptions extends CommonOptions {
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/components/VtCloseButton.spec.ts
Expand Up @@ -97,4 +97,18 @@ describe("VtCloseButton", () => {
wrapper.trigger("click");
expect(onClick).toHaveBeenCalled();
});
it("renders default aria label", () => {
const wrapper = mount(VtCloseButton);
expect(wrapper.find("button[aria-label='close']").exists()).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
it("renders custom aria label", () => {
const wrapper = mount(VtCloseButton, {
propsData: {
ariaLabel: "text"
}
});
expect(wrapper.find("button[aria-label='text']").exists()).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
});
14 changes: 14 additions & 0 deletions tests/unit/components/VtToast.spec.ts
Expand Up @@ -91,6 +91,20 @@ describe("VtToast", () => {
expect(wrapper.contains(VtProgressBar)).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
it("renders default aria role and button aria label", () => {
const wrapper = mountToast();
expect(wrapper.find("[role='alert']").exists()).toBe(true);
expect(wrapper.find("button[aria-label='close']").exists()).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
it("renders custom aria role and button aria label", () => {
const wrapper = mountToast({
accessibility: { toastRole: "status", closeButtonLabel: "text" }
});
expect(wrapper.find("[role='status']").exists()).toBe(true);
expect(wrapper.find("button[aria-label='text']").exists()).toBe(true);
expect(wrapper.element).toMatchSnapshot();
});
});
describe("classes", () => {
it("returns default classes", () => {
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/components/__snapshots__/VtCloseButton.spec.ts.snap
Expand Up @@ -2,6 +2,7 @@

exports[`VtCloseButton adds 'show-on-hover' class 1`] = `
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand All @@ -12,6 +13,7 @@ exports[`VtCloseButton adds 'show-on-hover' class 1`] = `

exports[`VtCloseButton adds 'show-on-hover' class 2`] = `
<button
aria-label="close"
class="Vue-Toastification__close-button show-on-hover"
>
Expand All @@ -22,6 +24,7 @@ exports[`VtCloseButton adds 'show-on-hover' class 2`] = `

exports[`VtCloseButton adds custom class array 1`] = `
<button
aria-label="close"
class="Vue-Toastification__close-button my-class my-class2"
>
Expand All @@ -32,6 +35,7 @@ exports[`VtCloseButton adds custom class array 1`] = `

exports[`VtCloseButton adds custom class string 1`] = `
<button
aria-label="close"
class="Vue-Toastification__close-button my-class"
>
Expand All @@ -42,6 +46,29 @@ exports[`VtCloseButton adds custom class string 1`] = `

exports[`VtCloseButton matches default snapshot 1`] = `
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
</button>
`;

exports[`VtCloseButton renders custom aria label 1`] = `
<button
aria-label="text"
class="Vue-Toastification__close-button"
>
</button>
`;

exports[`VtCloseButton renders default aria label 1`] = `
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand All @@ -52,6 +79,7 @@ exports[`VtCloseButton matches default snapshot 1`] = `

exports[`VtCloseButton string custom component 1`] = `
<div
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand All @@ -62,6 +90,7 @@ exports[`VtCloseButton string custom component 1`] = `

exports[`VtCloseButton vue custom component 1`] = `
<div
aria-label="close"
class="Vue-Toastification__close-button"
>
Example component
Expand Down
97 changes: 97 additions & 0 deletions tests/unit/components/__snapshots__/VtToast.spec.ts.snap
Expand Up @@ -22,11 +22,13 @@ exports[`VtToast snapshots renders 1`] = `
<div
class="Vue-Toastification__toast-body"
role="alert"
>
content
</div>
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand Down Expand Up @@ -63,6 +65,7 @@ exports[`VtToast ui closeButton = false removes it 1`] = `
<div
class="Vue-Toastification__toast-body"
role="alert"
>
content
</div>
Expand Down Expand Up @@ -98,11 +101,13 @@ exports[`VtToast ui has all default sub components 1`] = `
<div
class="Vue-Toastification__toast-body"
role="alert"
>
content
</div>
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand All @@ -125,11 +130,56 @@ exports[`VtToast ui icon = false removes it 1`] = `
<div
class="Vue-Toastification__toast-body"
role="alert"
>
content
</div>
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
</button>
<div
class="Vue-Toastification__progress-bar"
style="animation-duration: 5000ms; animation-play-state: running; opacity: 1;"
/>
</div>
`;

exports[`VtToast ui renders custom aria role and button aria label 1`] = `
<div
class="Vue-Toastification__toast Vue-Toastification__toast--default top-right"
>
<svg
aria-hidden="true"
class="svg-inline--fa fa-info-circle fa-w-16 Vue-Toastification__icon"
data-icon="info-circle"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"
fill="currentColor"
/>
</svg>
<div
class="Vue-Toastification__toast-body"
role="status"
>
content
</div>
<button
aria-label="text"
class="Vue-Toastification__close-button"
>
Expand Down Expand Up @@ -166,6 +216,7 @@ exports[`VtToast ui renders custom component 1`] = `
<div
class="Vue-Toastification__toast-component-body"
role="alert"
>
<div
toast-id="1"
Expand All @@ -175,6 +226,50 @@ exports[`VtToast ui renders custom component 1`] = `
</div>
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
</button>
<div
class="Vue-Toastification__progress-bar"
style="animation-duration: 5000ms; animation-play-state: running; opacity: 1;"
/>
</div>
`;

exports[`VtToast ui renders default aria role and button aria label 1`] = `
<div
class="Vue-Toastification__toast Vue-Toastification__toast--default top-right"
>
<svg
aria-hidden="true"
class="svg-inline--fa fa-info-circle fa-w-16 Vue-Toastification__icon"
data-icon="info-circle"
data-prefix="fas"
focusable="false"
role="img"
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"
fill="currentColor"
/>
</svg>
<div
class="Vue-Toastification__toast-body"
role="alert"
>
content
</div>
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand Down Expand Up @@ -211,11 +306,13 @@ exports[`VtToast ui timeout = false removes progress bar 1`] = `
<div
class="Vue-Toastification__toast-body"
role="alert"
>
content
</div>
<button
aria-label="close"
class="Vue-Toastification__close-button"
>
Expand Down

0 comments on commit aeb7b10

Please sign in to comment.