Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(a11y): fix a11y warning in alert, and other a11y fixes #3237

Merged
merged 3 commits into from
Dec 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions js/src/common/components/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Button from './Button';
import listItems from '../helpers/listItems';
import extract from '../utils/extract';
import type Mithril from 'mithril';
import classList from '../utils/classList';
import app from '../app';

export interface AlertAttrs extends ComponentAttrs {
/** The type of alert this is. Will be used to give the alert a class name of `Alert--{type}`. */
Expand All @@ -24,7 +26,7 @@ export default class Alert<T extends AlertAttrs = AlertAttrs> extends Component<
const attrs = Object.assign({}, this.attrs);

const type = extract(attrs, 'type');
attrs.className = 'Alert Alert--' + type + ' ' + (attrs.className || '');
attrs.className = classList('Alert', `Alert--${type}`, attrs.className);

const content = extract(attrs, 'content') || vnode.children;
const controls = (extract(attrs, 'controls') || []) as Mithril.Vnode[];
Expand All @@ -37,13 +39,20 @@ export default class Alert<T extends AlertAttrs = AlertAttrs> extends Component<
const dismissControl: Mithril.Vnode[] = [];

if (dismissible || dismissible === undefined) {
dismissControl.push(<Button icon="fas fa-times" className="Button Button--link Button--icon Alert-dismiss" onclick={ondismiss} />);
dismissControl.push(
<Button
aria-label={app.translator.trans('core.lib.alert.dismiss_a11y_label')}
icon="fas fa-times"
class="Button Button--link Button--icon Alert-dismiss"
onclick={ondismiss}
/>
);
}

return (
<div {...attrs}>
<span className="Alert-body">{content}</span>
<ul className="Alert-controls">{listItems(controls.concat(dismissControl))}</ul>
<span class="Alert-body">{content}</span>
<ul class="Alert-controls">{listItems(controls.concat(dismissControl))}</ul>
</div>
);
}
Expand Down
21 changes: 12 additions & 9 deletions js/src/common/components/AlertManager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Component from '../Component';
import Alert from './Alert';

/**
* The `AlertManager` component provides an area in which `Alert` components can
Expand All @@ -14,14 +13,18 @@ export default class AlertManager extends Component {

view() {
return (
<div className="AlertManager">
{Object.entries(this.state.getActiveAlerts()).map(([key, alert]) => (
<div className="AlertManager-alert">
<alert.componentClass {...alert.attrs} ondismiss={this.state.dismiss.bind(this.state, key)}>
{alert.children}
</alert.componentClass>
</div>
))}
<div class="AlertManager">
{Object.entries(this.state.getActiveAlerts()).map(([key, alert]) => {
const urgent = alert.attrs.type === 'error';

return (
<div class="AlertManager-alert" role="alert" aria-live={urgent ? 'assertive' : 'polite'}>
<alert.componentClass {...alert.attrs} ondismiss={this.state.dismiss.bind(this.state, key)}>
{alert.children}
</alert.componentClass>
</div>
);
})}
</div>
);
}
Expand Down
4 changes: 4 additions & 0 deletions locale/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ core:
lib:
debug_button: Debug

# These translations are used in the Alert component.
alert:
dismiss_a11y_label: Dismiss alert

# These translations are displayed as tooltips for discussion badges.
badge:
hidden_tooltip: Hidden
Expand Down