Merge pull request #2723 from tugcekucukoglu/accessibility-button

Accessibility for Button
pull/2734/head
Tuğçe Küçükoğlu 2022-06-29 16:50:00 +03:00 committed by GitHub
commit 9c0779d528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 250 additions and 34 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<button :class="buttonClass" type="button" v-ripple :disabled="disabled"> <button :class="buttonClass" type="button" :aria-label="defaultAriaLabel" v-ripple :disabled="disabled">
<slot> <slot>
<span v-if="loading && !icon" :class="iconClass"></span> <span v-if="loading && !icon" :class="iconClass"></span>
<span v-if="icon" :class="iconClass"></span> <span v-if="icon" :class="iconClass"></span>
@ -72,6 +72,9 @@ export default {
}, },
disabled() { disabled() {
return this.$attrs.disabled || this.loading; return this.$attrs.disabled || this.loading;
},
defaultAriaLabel() {
return (this.label ? this.label + (this.badge ? ' ' + this.badge : '') : this.$attrs['aria-label']);
} }
}, },
directives: { directives: {

View File

@ -11,6 +11,7 @@ function unbindEvents(el) {
function create(el) { function create(el) {
let ink = document.createElement('span'); let ink = document.createElement('span');
ink.className = 'p-ink'; ink.className = 'p-ink';
ink.setAttribute("role", "presentation");
el.appendChild(ink); el.appendChild(ink);
ink.addEventListener('animationend', onAnimationEnd); ink.addEventListener('animationend', onAnimationEnd);

View File

@ -16,7 +16,7 @@
<Button label="Link" class="p-button-link" /> <Button label="Link" class="p-button-link" />
<h5>Icons</h5> <h5>Icons</h5>
<Button icon="pi pi-check" /> <Button icon="pi pi-check" aria-label="Submit" />
<Button label="Submit" icon="pi pi-check" /> <Button label="Submit" icon="pi pi-check" />
<Button label="Submit" icon="pi pi-check" iconPos="right" /> <Button label="Submit" icon="pi pi-check" iconPos="right" />
@ -77,32 +77,32 @@
<Button label="Danger" class="p-button-outlined p-button-danger" /> <Button label="Danger" class="p-button-outlined p-button-danger" />
<h5>Rounded Icon Buttons</h5> <h5>Rounded Icon Buttons</h5>
<Button icon="pi pi-bookmark" class="p-button-rounded p-button-secondary" /> <Button icon="pi pi-bookmark" class="p-button-rounded p-button-secondary" aria-label="Bookmark" />
<Button icon="pi pi-search" class="p-button-rounded p-button-success" /> <Button icon="pi pi-search" class="p-button-rounded p-button-success" aria-label="Search" />
<Button icon="pi pi-user" class="p-button-rounded p-button-info" /> <Button icon="pi pi-user" class="p-button-rounded p-button-info" aria-label="User" />
<Button icon="pi pi-bell" class="p-button-rounded p-button-warning" /> <Button icon="pi pi-bell" class="p-button-rounded p-button-warning" aria-label="Notification" />
<Button icon="pi pi-heart" class="p-button-rounded p-button-help" /> <Button icon="pi pi-heart" class="p-button-rounded p-button-help" aria-label="Favorite" />
<Button icon="pi pi-times" class="p-button-rounded p-button-danger" /> <Button icon="pi pi-times" class="p-button-rounded p-button-danger" aria-label="Cancel" />
<Button icon="pi pi-check" class="p-button-rounded" /> <Button icon="pi pi-check" class="p-button-rounded" aria-label="Filter" />
<h5>Rounded Text Icon Buttons</h5> <h5>Rounded Text Icon Buttons</h5>
<Button icon="pi pi-check" class="p-button-rounded p-button-text" /> <Button icon="pi pi-check" class="p-button-rounded p-button-text" aria-label="Submit" />
<Button icon="pi pi-bookmark" class="p-button-rounded p-button-secondary p-button-text" /> <Button icon="pi pi-bookmark" class="p-button-rounded p-button-secondary p-button-text" aria-label="Bookmark" />
<Button icon="pi pi-search" class="p-button-rounded p-button-success p-button-text" /> <Button icon="pi pi-search" class="p-button-rounded p-button-success p-button-text" aria-label="Search" />
<Button icon="pi pi-user" class="p-button-rounded p-button-info p-button-text" /> <Button icon="pi pi-user" class="p-button-rounded p-button-info p-button-text" aria-label="User" />
<Button icon="pi pi-bell" class="p-button-rounded p-button-warning p-button-text" /> <Button icon="pi pi-bell" class="p-button-rounded p-button-warning p-button-text" aria-label="Notification" />
<Button icon="pi pi-heart" class="p-button-rounded p-button-help p-button-text" /> <Button icon="pi pi-heart" class="p-button-rounded p-button-help p-button-text" aria-label="Favorite" />
<Button icon="pi pi-times" class="p-button-rounded p-button-danger p-button-text" /> <Button icon="pi pi-times" class="p-button-rounded p-button-danger p-button-text" aria-label="Cancel" />
<Button icon="pi pi-filter" class="p-button-rounded p-button-text p-button-plain" /> <Button icon="pi pi-filter" class="p-button-rounded p-button-text p-button-plain" aria-label="Filter" />
<h5>Rounded and Outlined Icon Buttons</h5> <h5>Rounded and Outlined Icon Buttons</h5>
<Button icon="pi pi-check" class="p-button-rounded p-button-outlined" /> <Button icon="pi pi-check" class="p-button-rounded p-button-outlined" aria-label="Submit" />
<Button icon="pi pi-bookmark" class="p-button-rounded p-button-secondary p-button-outlined" /> <Button icon="pi pi-bookmark" class="p-button-rounded p-button-secondary p-button-outlined" aria-label="Bookmark" />
<Button icon="pi pi-search" class="p-button-rounded p-button-success p-button-outlined" /> <Button icon="pi pi-search" class="p-button-rounded p-button-success p-button-outlined" aria-label="Search" />
<Button icon="pi pi-user" class="p-button-rounded p-button-info p-button-outlined" /> <Button icon="pi pi-user" class="p-button-rounded p-button-info p-button-outlined" aria-label="User" />
<Button icon="pi pi-bell" class="p-button-rounded p-button-warning p-button-outlined" /> <Button icon="pi pi-bell" class="p-button-rounded p-button-warning p-button-outlined" aria-label="Notification" />
<Button icon="pi pi-heart" class="p-button-rounded p-button-help p-button-outlined" /> <Button icon="pi pi-heart" class="p-button-rounded p-button-help p-button-outlined" aria-label="Favorite" />
<Button icon="pi pi-times" class="p-button-rounded p-button-danger p-button-outlined" /> <Button icon="pi pi-times" class="p-button-rounded p-button-danger p-button-outlined" aria-label="Cancel" />
<h5>Badges</h5> <h5>Badges</h5>
<Button type="button" label="Emails" badge="8" /> <Button type="button" label="Emails" badge="8" />
@ -114,15 +114,6 @@
<Button type="button" icon="pi pi-search" :loading="loading[2]" @click="load(2)" /> <Button type="button" icon="pi pi-search" :loading="loading[2]" @click="load(2)" />
<Button type="button" label="Search" :loading="loading[3]" @click="load(3)" /> <Button type="button" label="Search" :loading="loading[3]" @click="load(3)" />
<h5>Templating</h5>
<Button type="button" class="px-3">
<img alt="logo" src="../../assets/images/logo-white.svg" style="width: 1.5rem"/>
</Button>
<Button type="button" class="p-button-outlined p-button-success">
<img alt="logo" src="../../assets/images/logo.svg" style="width: 1.5rem" />
<span class="ml-2 font-bold">PrimeVue</span>
</Button>
<h5>Button Set</h5> <h5>Button Set</h5>
<span class="p-buttonset"> <span class="p-buttonset">
<Button label="Save" icon="pi pi-check" /> <Button label="Save" icon="pi pi-check" />
@ -136,6 +127,42 @@
<Button label="Normal" icon="pi pi-check" class="p-button" /> <Button label="Normal" icon="pi pi-check" class="p-button" />
<Button label="Large" icon="pi pi-check" class="p-button-lg" /> <Button label="Large" icon="pi pi-check" class="p-button-lg" />
</div> </div>
<h5>Template</h5>
<div class="template">
<Button class="google p-0" aria-label="Google">
<i class="pi pi-google px-2"></i>
<span class="px-3">Google</span>
</Button>
<Button class="youtube p-0" aria-label="Youtube">
<i class="pi pi-youtube px-2"></i>
<span class="px-3">Youtube</span>
</Button>
<Button class="vimeo p-0" aria-label="Vimeo">
<i class="pi pi-vimeo px-2"></i>
<span class="px-3">Vimeo</span>
</Button>
<Button class="facebook p-0" aria-label="Facebook">
<i class="pi pi-facebook px-2"></i>
<span class="px-3">Facebook</span>
</Button>
<Button class="twitter p-0" aria-label="Twitter">
<i class="pi pi-twitter px-2"></i>
<span class="px-3">Twitter</span>
</Button>
<Button class="slack p-0" aria-label="Slack">
<i class="pi pi-slack px-2"></i>
<span class="px-3">Slack</span>
</Button>
<Button class="amazon p-0" aria-label="Amazon">
<i class="pi pi-amazon px-2"></i>
<span class="px-3">Amazon</span>
</Button>
<Button class="discord p-0" aria-label="Discord">
<i class="pi pi-discord px-2"></i>
<span class="px-3">Discord</span>
</Button>
</div>
</div> </div>
</div> </div>
@ -186,7 +213,147 @@ export default {
} }
} }
@media screen and (max-width: 640px) { .template .p-button i {
line-height: 2.25rem;
}
.template .p-button.google {
background: linear-gradient(to left, var(--purple-600) 50%, var(--purple-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--purple-700);
}
.template .p-button.google:hover {
background-position: left bottom;
}
.template .p-button.google i {
background-color: var(--purple-700);
}
.template .p-button.google:focus {
box-shadow: 0 0 0 1px var(--purple-400);
}
.template .p-button.youtube {
background: linear-gradient(to left, var(--pink-600) 50%, var(--pink-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--pink-700);
}
.template .p-button.youtube:hover {
background-position: left bottom;
}
.template .p-button.youtube i {
background-color: var(--pink-700);
}
.template .p-button.youtube:focus {
box-shadow: 0 0 0 1px var(--pink-400);
}
.template .p-button.vimeo {
background: linear-gradient(to left, var(--green-200) 50%, var(--green-300) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--green-300);
}
.template .p-button.vimeo:hover {
background-position: left bottom;
}
.template .p-button.vimeo i {
background-color: var(--green-300);
}
.template .p-button.vimeo:focus {
box-shadow: 0 0 0 1px var(--green-400);
}
.template .p-button.facebook {
background: linear-gradient(to left, var(--indigo-600) 50%, var(--indigo-700) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--indigo-700);
}
.template .p-button.facebook:hover {
background-position: left bottom;
}
.template .p-button.facebook i {
background-color: var(--indigo-700);
}
.template .p-button.facebook:focus {
box-shadow: 0 0 0 1px var(--indigo-400);
}
.template .p-button.twitter {
background: linear-gradient(to left, var(--blue-400) 50%, var(--blue-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--blue-500);
}
.template .p-button.twitter:hover {
background-position: left bottom;
}
.template .p-button.twitter i {
background-color: var(--blue-500);
}
.template .p-button.twitter:focus {
box-shadow: 0 0 0 1px var(--blue-200);
}
.template .p-button.slack {
background: linear-gradient(to left, var(--orange-400) 50%, var(--orange-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--orange-500);
}
.template .p-button.slack:hover {
background-position: left bottom;
}
.template .p-button.slack i {
background-color: var(--orange-500);
}
.template .p-button.slack:focus {
box-shadow: 0 0 0 1px var(--orange-200);
}
.template .p-button.amazon {
background: linear-gradient(to left, var(--yellow-400) 50%, var(--yellow-500) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #000;
border-color: var(--yellow-500);
}
.template .p-button.amazon:hover {
background-position: left bottom;
}
.template .p-button.amazon i {
background-color: var(--yellow-500);
}
.template .p-button.amazon:focus {
box-shadow: 0 0 0 1px var(--yellow-200);
}
.template .p-button.discord {
background: linear-gradient(to left, var(--bluegray-700) 50%, var(--bluegray-800) 50%);
background-size: 200% 100%;
background-position: right bottom;
transition: background-position 0.5s ease-out;
color: #fff;
border-color: var(--bluegray-800);
}
.template .p-button.discord:hover {
background-position: left bottom;
}
.template .p-button.discord i {
background-color: var(--bluegray-800);
}
.template .p-button.discord:focus {
box-shadow: 0 0 0 1px var(--bluegray-500);
}
@media screen and (max-width: 960px) {
.p-button { .p-button {
margin-bottom: .5rem; margin-bottom: .5rem;

View File

@ -240,6 +240,51 @@ import Button from 'primevue/button';
</table> </table>
</div> </div>
<h5>Accessibility</h5>
<DevelopmentSection>
<h6>Screen Reader</h6>
<p>Button component renders a native button element that implicitly includes any passed prop. Text to describe the button is defined with the <i>aria-label</i> prop, if not present <i>label</i> prop is used as the value. If the button
is icon only or custom templating is used, it is recommended to use <i>aria-label</i> so that screen readers would be able to read the element properly.</p>
<pre v-code><code>
&lt;Button icon="pi pi-check" aria-label="Submit" /&gt;
&lt;Button icon="pi pi-check" label="Submit" /&gt;
&lt;Button class="youtube p-0" aria-label="Youtube"&gt;
&lt;i class="pi pi-youtube px-2"&gt;&lt;/i&gt;
&lt;span class="px-3"&gt;Youtube&lt;/span&gt;
&lt;/Button&gt;
</code></pre>
<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 button.</td>
</tr>
<tr>
<td><i>enter</i></td>
<td>Activates the button.</td>
</tr>
<tr>
<td><i>space</i></td>
<td>Activates the button.</td>
</tr>
</tbody>
</table>
</div>
</DevelopmentSection>
<h5>Dependencies</h5> <h5>Dependencies</h5>
<p>None.</p> <p>None.</p>
</AppDoc> </AppDoc>