feat(a11y) buttons can now have toggled-aware a11y labels

We can now set toggledAccessibilityLabel and toggleTooltip attributes on
an AbstractButton, allowing us to change its label depending on toggled
state.

This is important so that all users, whether they use a screen reader or
not, understand clearly the actual action that the button will do when
they'll press it.
This commit is contained in:
Emmanuel Pelletier 2022-10-20 11:49:19 +02:00 committed by Calin-Teodor
parent 8982f17ce1
commit d9692cc4fa
1 changed files with 45 additions and 2 deletions

View File

@ -108,10 +108,21 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
* A succinct description of what the button does. Used by accessibility * A succinct description of what the button does. Used by accessibility
* tools and torture tests. * tools and torture tests.
* *
* If `toggledAccessibilityLabel` is defined, this is used only when the
* button is not toggled on.
*
* @abstract * @abstract
*/ */
accessibilityLabel: string; accessibilityLabel: string;
/**
* This is the same as `accessibilityLabel`, replacing it when the button
* is toggled on.
*
* @abstract
*/
toggledAccessibilityLabel: string;
labelProps: Object; labelProps: Object;
/** /**
@ -144,10 +155,22 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
/** /**
* The text to display in the tooltip. Used only on web. * The text to display in the tooltip. Used only on web.
* *
* If `toggleTooltip` is defined, this is used only when the button is not
* toggled on.
*
* @abstract * @abstract
*/ */
tooltip: ?string; tooltip: ?string;
/**
* The text to display in the tooltip when the button is toggled on.
*
* Used only on web.
*
* @abstract
*/
toggledTooltip: ?string;
/** /**
* Initializes a new {@code AbstractButton} instance. * Initializes a new {@code AbstractButton} instance.
* *
@ -221,6 +244,24 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
|| this.label; || this.label;
} }
/**
* Gets the current accessibility label, taking the toggled state into
* account. If no toggled label is provided, the regular accessibility label
* will also be used in the toggled state.
*
* The accessibility label is not visible in the UI, it is meant to be
* used by assistive technologies, mainly screen readers.
*
* @private
* @returns {string}
*/
_getAccessibilityLabel() {
return (this._isToggled()
? this.toggledAccessibilityLabel
: this.accessibilityLabel
) || this.accessibilityLabel;
}
/** /**
* Gets the current styles, taking the toggled state into account. If no * Gets the current styles, taking the toggled state into account. If no
* toggled styles are provided, the regular styles will also be used in the * toggled styles are provided, the regular styles will also be used in the
@ -257,7 +298,9 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
* @returns {string} * @returns {string}
*/ */
_getTooltip() { _getTooltip() {
return this.tooltip || ''; return (this._isToggled() ? this.toggledTooltip : this.tooltip)
|| this.tooltip
|| '';
} }
/** /**
@ -324,7 +367,7 @@ export default class AbstractButton<P: Props, S: *> extends Component<P, S> {
render(): React$Node { render(): React$Node {
const props = { const props = {
...this.props, ...this.props,
accessibilityLabel: this.accessibilityLabel, accessibilityLabel: this._getAccessibilityLabel(),
elementAfter: this._getElementAfter(), elementAfter: this._getElementAfter(),
icon: this._getIcon(), icon: this._getIcon(),
label: this._getLabel(), label: this._getLabel(),