Skip to content

Commit d341b75

Browse files
ellingemrchief
authored andcommitted
fix: Adjust aria labels to reference selections(#275)
and ensure "Remove" label is read by Screen readers
1 parent ed74a78 commit d341b75

File tree

14 files changed

+92
-26
lines changed

14 files changed

+92
-26
lines changed

__snapshots__/src/index.test.js.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@ Generated by [AVA](https://ava.li).
1616
className="dropdown"
1717
>
1818
<Trigger
19+
clientId="rdts"
1920
onTrigger={Function {}}
2021
showDropdown={true}
22+
tags={[]}
2123
texts={{}}
2224
>
2325
<Input
26+
clientId="rdts"
2427
inputRef={Function inputRef {}}
2528
onBlur={Function {}}
2629
onFocus={Function {}}
@@ -177,12 +180,15 @@ Generated by [AVA](https://ava.li).
177180
className="dropdown"
178181
>
179182
<Trigger
183+
clientId="rdts"
180184
disabled={true}
181185
onTrigger={Function {}}
182186
showDropdown={false}
187+
tags={[]}
183188
texts={{}}
184189
>
185190
<Input
191+
clientId="rdts"
186192
disabled={true}
187193
inputRef={Function inputRef {}}
188194
onBlur={Function {}}
@@ -287,21 +293,25 @@ Generated by [AVA](https://ava.li).
287293
className="dropdown radio-select"
288294
>
289295
<Trigger
296+
clientId="rdts"
290297
mode="radioSelect"
291298
onTrigger={Function {}}
292299
showDropdown={false}
300+
tags={[]}
293301
texts={{}}
294302
>
295303
<a
296304
"aria-expanded"="false"
297305
"aria-haspopup"="tree"
298306
className="dropdown-trigger arrow bottom"
307+
id="rdts_trigger"
299308
onClick={Function {}}
300309
onKeyDown={Function {}}
301310
role="button"
302311
tabIndex={0}
303312
>
304313
<Input
314+
clientId="rdts"
305315
inputRef={Function inputRef {}}
306316
mode="radioSelect"
307317
onBlur={Function {}}
@@ -426,20 +436,24 @@ Generated by [AVA](https://ava.li).
426436
className="dropdown"
427437
>
428438
<Trigger
439+
clientId="rdts"
429440
onTrigger={Function {}}
430441
showDropdown={false}
442+
tags={[]}
431443
texts={{}}
432444
>
433445
<a
434446
"aria-expanded"="false"
435447
"aria-haspopup"="tree"
436448
className="dropdown-trigger arrow bottom"
449+
id="rdts_trigger"
437450
onClick={Function {}}
438451
onKeyDown={Function {}}
439452
role="button"
440453
tabIndex={0}
441454
>
442455
<Input
456+
clientId="rdts"
443457
inputRef={Function inputRef {}}
444458
onBlur={Function {}}
445459
onFocus={Function {}}
@@ -486,11 +500,14 @@ Generated by [AVA](https://ava.li).
486500
className="dropdown"
487501
>
488502
<Trigger
503+
clientId="rdts"
489504
onTrigger={Function {}}
490505
showDropdown={true}
506+
tags={[]}
491507
texts={{}}
492508
>
493509
<Input
510+
clientId="rdts"
494511
inputRef={Function inputRef {}}
495512
onBlur={Function {}}
496513
onFocus={Function {}}

__snapshots__/src/index.test.js.snap

90 Bytes
Binary file not shown.

__snapshots__/src/tag/index.test.js.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ Generated by [AVA](https://ava.li).
99
> Snapshot 1
1010
1111
<span
12+
"aria-label"="hello"
1213
className="tag"
1314
id="abc_tag"
1415
>
1516
hello
1617
<button
1718
"aria-label"="Remove"
18-
"aria-labelledby"="abc_tag"
19+
"aria-labelledby"="abc_button abc_tag"
1920
className="tag-remove"
21+
id="abc_button"
2022
onClick={Function {}}
2123
onKeyDown={Function {}}
2224
onKeyUp={Function {}}
19 Bytes
Binary file not shown.

__snapshots__/src/trigger/index.test.js.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Generated by [AVA](https://ava.li).
1212
"aria-expanded"="false"
1313
"aria-haspopup"="tree"
1414
className="dropdown-trigger arrow bottom"
15+
id="rtds_trigger"
1516
onClick={Function {}}
1617
onKeyDown={Function {}}
1718
role="button"
15 Bytes
Binary file not shown.

docs/src/stories/Options/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class WithOptions extends PureComponent {
7070
</select>
7171
</div>
7272
<div style={{ marginBottom: '10px' }}>
73-
<label htmlFor={showDropdown}>ShowDropdown: </label>
73+
<label htmlFor={showDropdown}>Show dropdown: </label>
7474
<select
7575
id="showDropdown"
7676
value={showDropdown}
@@ -123,6 +123,7 @@ class WithOptions extends PureComponent {
123123
disabled={disabled}
124124
readOnly={readOnly}
125125
showDropdown={showDropdown}
126+
texts={{ label: 'Demo Dropdown' }}
126127
/>
127128
</div>
128129
</div>

src/a11y/index.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
1-
export function getAriaLabel(label) {
2-
if (!label) return undefined
1+
export function getAriaLabel(label, additionalLabelledBy) {
2+
const attributes = getAriaAttributeForLabel(label)
33

4-
if (label && label[0] === '#') {
5-
/* See readme for label. When label starts with # it references ids of dom nodes instead.
6-
When used on aria-labelledby, they should be referenced without a starting hash/# */
7-
return { 'aria-labelledby': label.replace(/#/g, '') }
4+
if (additionalLabelledBy) {
5+
attributes['aria-labelledby'] = `${attributes['aria-labelledby'] || ''} ${additionalLabelledBy}`.trim()
6+
}
7+
8+
return attributes
9+
}
10+
11+
function getAriaAttributeForLabel(label) {
12+
if (!label) return {}
13+
14+
/* See readme for label. When label starts with # it references ids of dom nodes instead.
15+
When used on aria-labelledby, they should be referenced without a starting hash/# */
16+
if (label[0] === '#') {
17+
return { 'aria-labelledby': label.substring(1).replace(/ #/g, ' ') }
818
}
919
return { 'aria-label': label }
1020
}

src/index.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,11 @@ class DropdownTreeSelect extends Component {
277277

278278
render() {
279279
const { disabled, readOnly, mode, texts } = this.props
280-
const { showDropdown, currentFocus } = this.state
280+
const { showDropdown, currentFocus, tags } = this.state
281281

282282
const activeDescendant = currentFocus ? `${currentFocus}_li` : undefined
283283

284-
const commonProps = { disabled, readOnly, activeDescendant, texts, mode }
284+
const commonProps = { disabled, readOnly, activeDescendant, texts, mode, clientId: this.clientId }
285285

286286
return (
287287
<div
@@ -298,12 +298,12 @@ class DropdownTreeSelect extends Component {
298298
{ 'radio-select': mode === 'radioSelect' }
299299
)}
300300
>
301-
<Trigger onTrigger={this.onTrigger} showDropdown={showDropdown} {...commonProps}>
301+
<Trigger onTrigger={this.onTrigger} showDropdown={showDropdown} {...commonProps} tags={tags}>
302302
<Input
303303
inputRef={el => {
304304
this.searchInput = el
305305
}}
306-
tags={this.state.tags}
306+
tags={tags}
307307
onInputChange={this.onInputChange}
308308
onFocus={this.onInputFocus}
309309
onBlur={this.onInputBlur}
@@ -327,7 +327,6 @@ class DropdownTreeSelect extends Component {
327327
onNodeToggle={this.onNodeToggle}
328328
mode={mode}
329329
showPartiallySelected={this.props.showPartiallySelected}
330-
clientId={this.clientId}
331330
{...commonProps}
332331
/>
333332
)}

src/index.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,19 @@ test('adds aria-label when having label on search input', t => {
290290
t.deepEqual(wrapper.find('.search').prop('aria-labelledby'), undefined)
291291
t.deepEqual(wrapper.find('.search').prop('aria-label'), 'hello world')
292292
})
293+
294+
test('appends selected tags to aria-labelledby with provided aria-labelledby', t => {
295+
const { tree } = t.context
296+
tree[0].checked = true
297+
const wrapper = mount(<DropdownTreeSelect id="rdts" data={tree} texts={{ label: '#hello #world' }} />)
298+
t.deepEqual(wrapper.find('.dropdown-trigger').prop('aria-labelledby'), 'hello world rdts-0_tag')
299+
t.deepEqual(wrapper.find('.dropdown-trigger').prop('aria-label'), undefined)
300+
})
301+
302+
test('appends selected tags to aria-labelledby with text label', t => {
303+
const { tree } = t.context
304+
tree[0].checked = true
305+
const wrapper = mount(<DropdownTreeSelect id="rdts" data={tree} texts={{ label: 'hello world' }} />)
306+
t.deepEqual(wrapper.find('.dropdown-trigger').prop('aria-labelledby'), 'rdts_trigger rdts-0_tag')
307+
t.deepEqual(wrapper.find('.dropdown-trigger').prop('aria-label'), 'hello world')
308+
})

0 commit comments

Comments
 (0)