Skip to content

Commit a0fd70f

Browse files
authored
fix(data-tables): Add aria label attributes to Data Tables (#4623)
* add captions to base data tables * add captions to data table in card * make caption a prop on Table * add captions to advanced data table * add captions to fixed header data table * add captions to hidden header data table * add captions to advanced data table * add captions to miscellaneous HTML tables * add captions to tree grid * add test for captions * add aria-labelledby and aria-label to data-table * add release notes * change captions to aria-label * add docs * update tests * change captions to labels on raw table examples * update tree grid * add/update tree grid tests
1 parent 8853192 commit a0fd70f

File tree

20 files changed

+462
-50
lines changed

20 files changed

+462
-50
lines changed

ui/components/cards/base/example.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@ const headerAction = (
2929
);
3030

3131
const bodyTable = (
32-
<Table isFixedLayout isBordered hasNoRowHover hasCellBuffer type="advanced">
32+
<Table
33+
isFixedLayout
34+
isBordered
35+
hasNoRowHover
36+
hasCellBuffer
37+
type="advanced"
38+
ariaLabel="Example table in a Card"
39+
>
3340
<THead>
3441
<THeadTr>
3542
<ColumnTh>

ui/components/data-tables/RELEASENOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
<!-- ## [Unreleased] -->
66

7+
# 2.15.1
8+
9+
- Added `<caption>`, and alternatively, `aria-labelledby` and `aria-label` to allow adding additional table context for screen readers
710
# 2.14.0
811

912
### Added

ui/components/data-tables/__tests__/__snapshots__/index.spec.jsx.snap

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,15 +1691,15 @@ exports[`AdvancedDataTableHead component should set sort direction 1`] = `
16911691
<input
16921692
aria-labelledby="check-select-all-label column-group-header"
16931693
defaultChecked={null}
1694-
id="checkbox-unique-id-1"
1694+
id="checkbox-unique-id-15"
16951695
name="options"
16961696
tabIndex="-1"
16971697
type="checkbox"
1698-
value="checkbox-unique-id-1"
1698+
value="checkbox-unique-id-15"
16991699
/>
17001700
<label
17011701
className="slds-checkbox__label"
1702-
htmlFor="checkbox-unique-id-1"
1702+
htmlFor="checkbox-unique-id-15"
17031703
id="check-select-all-label"
17041704
>
17051705
<span
@@ -1775,7 +1775,7 @@ exports[`AdvancedDataTableHead component should set sort direction 1`] = `
17751775
<input
17761776
aria-label="Name column width"
17771777
className="slds-resizable__input slds-assistive-text"
1778-
id="cell-resize-handle-1"
1778+
id="cell-resize-handle-21"
17791779
max="1000"
17801780
min="20"
17811781
tabIndex="-1"
@@ -2226,6 +2226,40 @@ exports[`Data table component should render a base table 1`] = `
22262226
/>
22272227
`;
22282228

2229+
exports[`Data table component should render a table with a caption with aria-label 1`] = `
2230+
<table
2231+
aria-label="Example caption"
2232+
aria-multiselectable={null}
2233+
className="slds-table"
2234+
role={null}
2235+
/>
2236+
`;
2237+
2238+
exports[`Data table component should render a table with a caption with aria-labelledby 1`] = `
2239+
Array [
2240+
<h2
2241+
id="element-with-table-label"
2242+
>
2243+
Example data table of Opportunities
2244+
</h2>,
2245+
<h3
2246+
id="other-element-with-table-label"
2247+
>
2248+
Using
2249+
<code>
2250+
aria-labelledby
2251+
</code>
2252+
, instead of aria-label
2253+
</h3>,
2254+
<table
2255+
aria-labelledby="element-with-table-label other-element-with-table-label"
2256+
aria-multiselectable={null}
2257+
className="slds-table"
2258+
role={null}
2259+
/>,
2260+
]
2261+
`;
2262+
22292263
exports[`Data table component should render a table with borders 1`] = `
22302264
<table
22312265
aria-multiselectable={null}
@@ -3310,7 +3344,7 @@ Array [
33103344
<input
33113345
aria-label="Column Name column width"
33123346
className="slds-resizable__input slds-assistive-text"
3313-
id="cell-resize-handle-1"
3347+
id="cell-resize-handle-7"
33143348
max="1000"
33153349
min="20"
33163350
tabIndex="-1"

ui/components/data-tables/__tests__/index.spec.jsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,25 @@ describe('Data table component', () => {
9191

9292
it('should render a table with passed styles', () =>
9393
matchesMarkup(<Table style={{ width: '10rem' }} type="base" />));
94+
95+
it('should render a table with a caption with aria-label', () =>
96+
matchesMarkup(<Table type="base" ariaLabel="Example caption" />));
97+
98+
it('should render a table with a caption with aria-labelledby', () =>
99+
matchesMarkup(
100+
<>
101+
<h2 id="element-with-table-label">
102+
Example data table of Opportunities
103+
</h2>
104+
<h3 id="other-element-with-table-label">
105+
Using <code>aria-labelledby</code>, instead of aria-label
106+
</h3>
107+
<Table
108+
type="base"
109+
ariaLabelledBy="element-with-table-label other-element-with-table-label"
110+
/>
111+
</>
112+
));
94113
});
95114

96115
describe('THead Component', () => {

ui/components/data-tables/advanced/example.jsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export default (
146146
isResizable
147147
selectionType="multiple"
148148
type="advanced"
149+
ariaLabel="Example default advanced table of Opportunities"
149150
>
150151
<Thead columns={columns} />
151152
<TBody>
@@ -172,6 +173,7 @@ export let states = [
172173
isResizable
173174
selectionType="multiple"
174175
type="advanced"
176+
ariaLabel="Example advanced table of Opportunities with cell focused"
175177
>
176178
<Thead columns={columns} />
177179
<TBody>
@@ -198,6 +200,7 @@ export let states = [
198200
isResizable
199201
selectionType="multiple"
200202
type="advanced"
203+
ariaLabel="Example advanced table of Opportunities in actionable mode"
201204
>
202205
<Thead actionableMode columns={columns} />
203206
<TBody>
@@ -224,6 +227,7 @@ export let states = [
224227
isResizable
225228
selectionType="multiple"
226229
type="advanced"
230+
ariaLabel="Example advanced table of Opportunities in actionable mode with row selected"
227231
>
228232
<Thead actionableMode columns={columns} />
229233
<TBody>
@@ -250,6 +254,7 @@ export let states = [
250254
isResizable
251255
selectionType="multiple"
252256
type="advanced"
257+
ariaLabel="Example advanced table of Opportunities in actionable mode with all rows selected"
253258
>
254259
<Thead actionableMode columns={columns} selectAll />
255260
<TBody>
@@ -276,6 +281,7 @@ export let states = [
276281
isResizable
277282
selectionType="multiple"
278283
type="advanced"
284+
ariaLabel="Example advanced table of Opportunities in actionable mode with ascending column sorting"
279285
>
280286
<Thead columns={columns} actionableMode sortDirection="ascending" />
281287
<TBody>
@@ -302,6 +308,7 @@ export let states = [
302308
isResizable
303309
selectionType="multiple"
304310
type="advanced"
311+
ariaLabel="Example advanced table of Opportunities in actionable mode with descending column sorting"
305312
>
306313
<Thead columns={columns} actionableMode sortDirection="descending" />
307314
<TBody>
@@ -328,6 +335,7 @@ export let states = [
328335
isResizable
329336
selectionType="multiple"
330337
type="advanced"
338+
ariaLabel="Example advanced table of Opportunities in actionable mode with resized column"
331339
>
332340
<Thead columns={columns} actionableMode singleColumnWidth="300px" />
333341
<TBody>
@@ -357,6 +365,7 @@ export let examples = [
357365
isResizable
358366
selectionType="multiple"
359367
type="advanced"
368+
ariaLabel="Example advanced table of Opportunities with header icon and menu button"
360369
>
361370
<Thead
362371
columnHeaderIcons={columnHeaderIcons}
@@ -386,6 +395,7 @@ export let examples = [
386395
isResizable
387396
selectionType="multiple"
388397
type="advanced"
398+
ariaLabel="Example advanced table of Opportunities with header menu button"
389399
>
390400
<Thead columns={columns} hasMenus />
391401
<TBody>
@@ -411,6 +421,7 @@ export let examples = [
411421
isResizable
412422
selectionType="multiple"
413423
type="advanced"
424+
ariaLabel="Example advanced table of Opportunities with cell icon"
414425
>
415426
<Thead columns={columns} />
416427
<TBody>
@@ -437,6 +448,7 @@ export let examples = [
437448
isResizable
438449
selectionType="multiple"
439450
type="advanced"
451+
ariaLabel="Example advanced table as product listing"
440452
>
441453
<Thead columns={productColumns} actionableMode hasNoRowSelection />
442454
<TBody>
@@ -457,7 +469,13 @@ export let examples = [
457469
id: 'radio-group',
458470
label: 'Radio Group',
459471
element: (
460-
<Table isBordered isFixedLayout isResizable type="advanced">
472+
<Table
473+
isBordered
474+
isFixedLayout
475+
isResizable
476+
type="advanced"
477+
ariaLabel="Example advanced table as radio group"
478+
>
461479
<Thead columns={columns} hasSingleRowSelect />
462480
<TBody>
463481
{rows.map((row, i) => (
@@ -476,7 +494,13 @@ export let examples = [
476494
id: 'data-table-no-borders',
477495
label: 'No borders',
478496
element: (
479-
<Table isFixedLayout isResizable selectionType="multiple" type="advanced">
497+
<Table
498+
isFixedLayout
499+
isResizable
500+
selectionType="multiple"
501+
type="advanced"
502+
ariaLabel="Example advanced table with no borders"
503+
>
480504
<Thead columns={columns} />
481505
<TBody>
482506
{rows.map((row, i) => (
@@ -500,6 +524,7 @@ export let examples = [
500524
isBordered
501525
selectionType="multiple"
502526
type="advanced"
527+
ariaLabel="Example advanced headless table"
503528
>
504529
<Thead isHidden columns={columns} />
505530
<TBody>
@@ -519,7 +544,12 @@ export let examples = [
519544
id: 'data-table-headless-no-borders',
520545
label: 'Headless with no borders',
521546
element: (
522-
<Table hasHiddenHeader selectionType="multiple" type="advanced">
547+
<Table
548+
hasHiddenHeader
549+
selectionType="multiple"
550+
type="advanced"
551+
ariaLabel="Example advanced headless border-less table"
552+
>
523553
<Thead isHidden columns={columns} />
524554
<TBody>
525555
{rows.map((row, i) => (

0 commit comments

Comments
 (0)