Skip to content

Commit ac59b10

Browse files
authored
fix(buttons): Add aria-pressed to stateful Buttons (#4650)
* update stateful buttons with aria-pressed * update stateful button tests * add release notes * update docs with aria-pressed info * make stateful buttons interactive * update tests
1 parent e119810 commit ac59b10

File tree

6 files changed

+51
-8
lines changed

6 files changed

+51
-8
lines changed

RELEASENOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010

1111
## Release 2.15.5 - April 29, 2021
1212

13+
## Components
14+
### [Buttons](https://www.lightningdesignsystem.com/components/buttons)
15+
#### Added
16+
- Added `aria-pressed` attribute to stateful Button variants
17+
1318
## Release 2.15.4 - April 27, 2021
1419

1520
## Release 2.15.3 - April 15, 2021

ui/components/buttons/RELEASENOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
# Buttons Release Notes
44

55
<!-- ## [Unreleased] -->
6+
## 2.15.5
7+
8+
### Added
9+
10+
- Added `aria-pressed` attribute to stateful Button variants
611

712
## 2.15.0
813

ui/components/buttons/__tests__/__snapshots__/snapshot.spec.jsx.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ exports[`Button renders an outline brand button 1`] = `
113113
exports[`Dual Stateful Button renders a disabled dual stateful button 1`] = `
114114
<button
115115
aria-live="assertive"
116+
aria-pressed="false"
116117
className="slds-button slds-button_neutral slds-button_dual-stateful"
117118
disabled={true}
118119
onClick={[Function]}
@@ -149,6 +150,7 @@ exports[`Dual Stateful Button renders a disabled dual stateful button 1`] = `
149150
exports[`Dual Stateful Button renders a not-pressed dual stateful button 1`] = `
150151
<button
151152
aria-live="assertive"
153+
aria-pressed="false"
152154
className="slds-button slds-button_neutral slds-button_dual-stateful"
153155
onClick={[Function]}
154156
>
@@ -184,6 +186,7 @@ exports[`Dual Stateful Button renders a not-pressed dual stateful button 1`] = `
184186
exports[`Dual Stateful Button renders a pressed dual stateful button 1`] = `
185187
<button
186188
aria-live="assertive"
189+
aria-pressed="true"
187190
className="slds-button slds-button_neutral slds-button_dual-stateful slds-is-pressed"
188191
onClick={[Function]}
189192
>
@@ -219,8 +222,11 @@ exports[`Dual Stateful Button renders a pressed dual stateful button 1`] = `
219222
exports[`Stateful Button renders a not-selected stateful button 1`] = `
220223
<button
221224
aria-live="assertive"
225+
aria-pressed="false"
222226
className="slds-button slds-button_neutral slds-button_stateful slds-not-selected"
227+
onBlur={[Function]}
223228
onClick={[Function]}
229+
onFocus={[Function]}
224230
>
225231
<span
226232
className="slds-text-not-selected"
@@ -267,8 +273,11 @@ exports[`Stateful Button renders a not-selected stateful button 1`] = `
267273
exports[`Stateful Button renders a selected and focused stateful button 1`] = `
268274
<button
269275
aria-live="assertive"
276+
aria-pressed="true"
270277
className="slds-button slds-button_neutral slds-button_stateful slds-is-selected-clicked"
278+
onBlur={[Function]}
271279
onClick={[Function]}
280+
onFocus={[Function]}
272281
>
273282
<span
274283
className="slds-text-not-selected"
@@ -315,8 +324,11 @@ exports[`Stateful Button renders a selected and focused stateful button 1`] = `
315324
exports[`Stateful Button renders a selected stateful button 1`] = `
316325
<button
317326
aria-live="assertive"
327+
aria-pressed="true"
318328
className="slds-button slds-button_neutral slds-button_stateful slds-is-selected"
329+
onBlur={[Function]}
319330
onClick={[Function]}
331+
onFocus={[Function]}
320332
>
321333
<span
322334
className="slds-text-not-selected"

ui/components/buttons/docs.mdx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,12 @@ The button contains three spans with classes that hide or show the content of th
210210

211211
<Blockquote type="a11y" header="Accessibility Requirement">
212212
<p>
213-
Be sure to include the attribute <code>aria-live="assertive"</code> on the
213+
The stateful button should have <code>aria-pressed="true"</code> or <code>"false"</code> and the accessible label
214+
should be static and describe the pressed state, so for example a "follow" button
215+
would always say "follow" and the sense that you are "following" is actually derived
216+
from <code>aria-pressed</code> being true.
217+
218+
Also, be sure to include the attribute <code>aria-live="assertive"</code> on the
214219
button. The <code>aria-live="assertive"</code> attribute means the value of
215220
the <code>&lt;span&gt;</code> inside the button will be spoken whenever it
216221
changes.
@@ -258,7 +263,12 @@ The button contains two spans. Each span contains display text and a correspondi
258263

259264
<Blockquote type="a11y" header="Accessibility Requirement">
260265
<p>
261-
Be sure to include the attribute <code>aria-live="assertive"</code> on the
266+
The stateful button should have <code>aria-pressed="true"</code> or <code>"false"</code> and the accessible label
267+
should be static and describe the pressed state, so for example a "follow" button
268+
would always say "follow" and the sense that you are "following" is actually derived
269+
from <code>aria-pressed</code> being true.
270+
271+
Also, be sure to include the attribute <code>aria-live="assertive"</code> on the
262272
button. The <code>aria-live="assertive"</code> attribute means the value of
263273
the <code>&lt;span&gt;</code> inside the button will be spoken whenever it
264274
changes.

ui/components/buttons/dual-stateful/example.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
22
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
33

4-
import React from 'react';
4+
import React, { useState } from 'react';
55
import PropTypes from 'prop-types';
66
import SvgIcon from '../../../shared/svg-icon';
77
import classNames from 'classnames';
@@ -43,15 +43,18 @@ PressedText.propTypes = {
4343

4444
const DualStatefulButton = props => {
4545
const { isDisabled, isPressed } = props;
46+
const [buttonSelected, setButtonSelected] = useState(isPressed);
4647

4748
return (
4849
<Button
4950
isNeutral
5051
className={classNames('slds-button_dual-stateful', {
51-
'slds-is-pressed': isPressed
52+
'slds-is-pressed': buttonSelected
5253
})}
5354
disabled={isDisabled}
5455
aria-live="assertive"
56+
aria-pressed={Boolean(buttonSelected).toString()}
57+
onClick={() => setButtonSelected(!buttonSelected)}
5558
>
5659
<DefaultText>Follow</DefaultText>
5760
<PressedText>Following</PressedText>

ui/components/buttons/stateful/example.jsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
22
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license
33

4-
import React from 'react';
4+
import React, { useState } from 'react';
55
import PropTypes from 'prop-types';
66
import SvgIcon from '../../../shared/svg-icon';
77
import classNames from 'classnames';
@@ -15,17 +15,25 @@ export let StatefulButton = props => {
1515
isSelected,
1616
isSelectedClicked
1717
} = props;
18+
const [buttonSelected, setButtonSelected] = useState(
19+
isSelected || isSelectedClicked
20+
);
21+
const [buttonFocused, setButtonFocused] = useState(isSelectedClicked);
1822

1923
return (
2024
<Button
2125
className={classNames('slds-button_stateful', className, {
22-
'slds-not-selected': isNotSelected,
23-
'slds-is-selected': isSelected,
24-
'slds-is-selected-clicked': isSelectedClicked
26+
'slds-not-selected': !buttonSelected,
27+
'slds-is-selected': buttonSelected && !buttonFocused,
28+
'slds-is-selected-clicked': buttonSelected && buttonFocused
2529
})}
2630
disabled={disabled}
2731
aria-live="assertive"
32+
aria-pressed={Boolean(buttonSelected).toString()}
2833
isNeutral
34+
onBlur={() => setButtonFocused(false)}
35+
onFocus={() => setButtonFocused(true)}
36+
onClick={() => setButtonSelected(!buttonSelected)}
2937
>
3038
<span className="slds-text-not-selected">
3139
<SvgIcon

0 commit comments

Comments
 (0)