mirror of
https://github.com/flarum/framework.git
synced 2024-11-22 13:35:47 +08:00
[A11Y] Add aria-label to dropdown toggles (#2668)
Implement custom accessible dropdown toggle labels for forum components Making the a11y label more specific to the specific action it performs is critical for good UX with assistive technologies.
This commit is contained in:
parent
0e6a60bd5b
commit
0d139e6133
|
@ -13,6 +13,7 @@ import listItems from '../helpers/listItems';
|
|||
* - `icon` The name of an icon to show in the dropdown toggle button.
|
||||
* - `caretIcon` The name of an icon to show on the right of the button.
|
||||
* - `label` The label of the dropdown toggle button. Defaults to 'Controls'.
|
||||
* - `accessibleToggleLabel` The label used to describe the dropdown toggle button to assistive readers. Defaults to 'Toggle dropdown menu'.
|
||||
* - `onhide`
|
||||
* - `onshow`
|
||||
*
|
||||
|
@ -25,6 +26,7 @@ export default class Dropdown extends Component {
|
|||
attrs.menuClassName = attrs.menuClassName || '';
|
||||
attrs.label = attrs.label || '';
|
||||
attrs.caretIcon = typeof attrs.caretIcon !== 'undefined' ? attrs.caretIcon : 'fas fa-caret-down';
|
||||
attrs.accessibleToggleLabel = attrs.accessibleToggleLabel || app.translator.trans('core.lib.dropdown.toggle_dropdown_accessible_label');
|
||||
}
|
||||
|
||||
oninit(vnode) {
|
||||
|
@ -92,7 +94,13 @@ export default class Dropdown extends Component {
|
|||
*/
|
||||
getButton(children) {
|
||||
return (
|
||||
<button className={'Dropdown-toggle ' + this.attrs.buttonClassName} data-toggle="dropdown" onclick={this.attrs.onclick}>
|
||||
<button
|
||||
className={'Dropdown-toggle ' + this.attrs.buttonClassName}
|
||||
aria-haspopup="menu"
|
||||
aria-label={this.attrs.accessibleToggleLabel}
|
||||
data-toggle="dropdown"
|
||||
onclick={this.attrs.onclick}
|
||||
>
|
||||
{this.getButtonContent(children)}
|
||||
</button>
|
||||
);
|
||||
|
|
|
@ -24,7 +24,12 @@ export default class SplitDropdown extends Dropdown {
|
|||
|
||||
return [
|
||||
Button.component(buttonAttrs, firstChild.children),
|
||||
<button className={'Dropdown-toggle Button Button--icon ' + this.attrs.buttonClassName} data-toggle="dropdown">
|
||||
<button
|
||||
className={'Dropdown-toggle Button Button--icon ' + this.attrs.buttonClassName}
|
||||
aria-haspopup="menu"
|
||||
aria-label={this.attrs.accessibleToggleLabel}
|
||||
data-toggle="dropdown"
|
||||
>
|
||||
{icon(this.attrs.icon, { className: 'Button-icon' })}
|
||||
{icon('fas fa-caret-down', { className: 'Button-caret' })}
|
||||
</button>,
|
||||
|
|
|
@ -87,6 +87,7 @@ export default class DiscussionListItem extends Component {
|
|||
icon: 'fas fa-ellipsis-v',
|
||||
className: 'DiscussionListItem-controls',
|
||||
buttonClassName: 'Button Button--icon Button--flat Slidable-underneath Slidable-underneath--right',
|
||||
accessibleToggleLabel: app.translator.trans('core.forum.discussion_controls.toggle_dropdown_accessible_label'),
|
||||
},
|
||||
controls
|
||||
)
|
||||
|
|
|
@ -189,6 +189,7 @@ export default class DiscussionPage extends Page {
|
|||
icon: 'fas fa-ellipsis-v',
|
||||
className: 'App-primaryControl',
|
||||
buttonClassName: 'Button--primary',
|
||||
accessibleToggleLabel: app.translator.trans('core.forum.discussion_controls.toggle_dropdown_accessible_label'),
|
||||
},
|
||||
DiscussionControls.controls(this.discussion, this).toArray()
|
||||
)
|
||||
|
|
|
@ -57,6 +57,7 @@ export default class HeaderSecondary extends Component {
|
|||
SelectDropdown.component(
|
||||
{
|
||||
buttonClassName: 'Button Button--link',
|
||||
accessibleToggleLabel: app.translator.trans('core.forum.header.locale_dropdown_accessible_label'),
|
||||
},
|
||||
locales
|
||||
),
|
||||
|
|
|
@ -172,6 +172,7 @@ export default class IndexPage extends Page {
|
|||
{
|
||||
buttonClassName: 'Button',
|
||||
className: 'App-titleControl',
|
||||
accessibleToggleLabel: app.translator.trans('core.forum.index.toggle_sidenav_dropdown_accessible_label'),
|
||||
},
|
||||
this.navItems(this).toArray()
|
||||
)
|
||||
|
@ -227,6 +228,7 @@ export default class IndexPage extends Page {
|
|||
{
|
||||
buttonClassName: 'Button',
|
||||
label: sortOptions[app.search.params().sort] || Object.keys(sortMap).map((key) => sortOptions[key])[0],
|
||||
accessibleToggleLabel: app.translator.trans('core.forum.index_sort.toggle_dropdown_accessible_label'),
|
||||
},
|
||||
Object.keys(sortOptions).map((value) => {
|
||||
const label = sortOptions[value];
|
||||
|
|
|
@ -9,6 +9,8 @@ export default class NotificationsDropdown extends Dropdown {
|
|||
attrs.menuClassName = attrs.menuClassName || 'Dropdown-menu--right';
|
||||
attrs.label = attrs.label || app.translator.trans('core.forum.notifications.tooltip');
|
||||
attrs.icon = attrs.icon || 'fas fa-bell';
|
||||
// For best a11y support, both `title` and `aria-label` should be used
|
||||
attrs.accessibleToggleLabel = attrs.accessibleToggleLabel || app.translator.trans('core.forum.notifications.toggle_dropdown_accessible_label');
|
||||
|
||||
super.initAttrs(attrs);
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ export default class Post extends Component {
|
|||
icon="fas fa-ellipsis-h"
|
||||
onshow={() => this.$('.Post-actions').addClass('open')}
|
||||
onhide={() => this.$('.Post-actions').removeClass('open')}
|
||||
accessibleToggleLabel={app.translator.trans('core.forum.post_controls.toggle_dropdown_accessible_label')}
|
||||
>
|
||||
{controls}
|
||||
</Dropdown>
|
||||
|
|
|
@ -17,6 +17,8 @@ export default class SessionDropdown extends Dropdown {
|
|||
attrs.className = 'SessionDropdown';
|
||||
attrs.buttonClassName = 'Button Button--user Button--flat';
|
||||
attrs.menuClassName = 'Dropdown-menu--right';
|
||||
|
||||
attrs.accessibleToggleLabel = app.translator.trans('core.forum.header.session_dropdown_accessible_label');
|
||||
}
|
||||
|
||||
view(vnode) {
|
||||
|
|
|
@ -40,6 +40,7 @@ export default class UserCard extends Component {
|
|||
menuClassName: 'Dropdown-menu--right',
|
||||
buttonClassName: this.attrs.controlsButtonClassName,
|
||||
label: app.translator.trans('core.forum.user_controls.button'),
|
||||
accessibleToggleLabel: app.translator.trans('core.forum.user_controls.toggle_dropdown_accessible_label'),
|
||||
icon: 'fas fa-ellipsis-v',
|
||||
},
|
||||
controls
|
||||
|
|
|
@ -278,6 +278,7 @@ core:
|
|||
rename_button: => core.ref.rename
|
||||
reply_button: => core.ref.reply
|
||||
restore_button: => core.ref.restore
|
||||
toggle_dropdown_accessible_label: Toggle discussion actions dropdown menu
|
||||
|
||||
# These translations are used in the discussion list.
|
||||
discussion_list:
|
||||
|
@ -316,10 +317,12 @@ core:
|
|||
header:
|
||||
admin_button: Administration
|
||||
back_to_index_tooltip: Back to Discussion List
|
||||
locale_dropdown_accessible_label: Change forum locale
|
||||
log_in_link: => core.ref.log_in
|
||||
log_out_button: => core.ref.log_out
|
||||
profile_button: Profile
|
||||
search_placeholder: Search Forum
|
||||
session_dropdown_accessible_label: Toggle session options dropdown menu
|
||||
settings_button: => core.ref.settings
|
||||
sign_up_link: => core.ref.sign_up
|
||||
|
||||
|
@ -332,6 +335,7 @@ core:
|
|||
meta_title_text: => core.ref.all_discussions
|
||||
refresh_tooltip: Refresh
|
||||
start_discussion_button: => core.ref.start_a_discussion
|
||||
toggle_sidenav_dropdown_accessible_label: Toggle navigation dropdown menu
|
||||
|
||||
# These translations are used by the sorting control above the discussion list.
|
||||
index_sort:
|
||||
|
@ -339,6 +343,7 @@ core:
|
|||
newest_button: Newest
|
||||
oldest_button: Oldest
|
||||
relevance_button: Relevance
|
||||
toggle_dropdown_accessible_label: Change discussion list sorting
|
||||
top_button: Top
|
||||
|
||||
# These translations are used in the Log In modal dialog.
|
||||
|
@ -359,6 +364,7 @@ core:
|
|||
mark_all_as_read_tooltip: => core.ref.mark_all_as_read
|
||||
mark_as_read_tooltip: Mark as Read
|
||||
title: => core.ref.notifications
|
||||
toggle_dropdown_accessible_label: View notifications
|
||||
tooltip: => core.ref.notifications
|
||||
|
||||
# These translations are used by tooltips displayed for individual posts.
|
||||
|
@ -375,6 +381,7 @@ core:
|
|||
edit_button: => core.ref.edit
|
||||
hide_confirmation: "Are you sure you want to delete this post?"
|
||||
restore_button: => core.ref.restore
|
||||
toggle_dropdown_accessible_label: Toggle post controls dropdown menu
|
||||
|
||||
# These translations are used in the scrubber to the right of the post stream.
|
||||
post_scrubber:
|
||||
|
@ -448,6 +455,7 @@ core:
|
|||
delete_error_message: "Deletion of user <i>{username} ({email})</i> failed"
|
||||
delete_success_message: "User <i>{username} ({email})</i> was deleted"
|
||||
edit_button: => core.ref.edit
|
||||
toggle_dropdown_accessible_label: Toggle user controls dropdown menu
|
||||
|
||||
# These translations are used in the alert that is shown when a new user has not confirmed their email address.
|
||||
user_email_confirmation:
|
||||
|
@ -462,6 +470,10 @@ core:
|
|||
badge:
|
||||
hidden_tooltip: Hidden
|
||||
|
||||
# These translations are used in the dropdown component.
|
||||
dropdown:
|
||||
toggle_dropdown_accessible_label: Toggle dropdown menu
|
||||
|
||||
# These translations are displayed as error messages.
|
||||
error:
|
||||
dependent_extensions_message: "Cannot disable {extension} until the following dependent extensions are disabled: {extensions}"
|
||||
|
|
Loading…
Reference in New Issue
Block a user