Skip to content

Commit 8ba2942

Browse files
committed
fix: role and aria-selected a11y error
1 parent e6bb287 commit 8ba2942

File tree

5 files changed

+94
-19
lines changed

5 files changed

+94
-19
lines changed

src/OptionList.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
288288
};
289289
}
290290

291+
const a11yOptionProps = {
292+
role: 'option',
293+
};
294+
291295
const renderItem = (index: number) => {
292296
const item = memoFlattenOptions[index];
293297
if (!item) {
@@ -304,6 +308,7 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
304308
{...attrs}
305309
key={index}
306310
{...getItemAriaProps(item, index)}
311+
{...a11yOptionProps}
307312
aria-selected={isAriaSelected(value)}
308313
>
309314
{value}
@@ -398,7 +403,8 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
398403
<div
399404
{...pickAttrs(passedProps)}
400405
{...(!virtual ? getItemAriaProps(item, itemIndex) : {})}
401-
aria-selected={isAriaSelected(value)}
406+
aria-selected={virtual ? undefined : isAriaSelected(value)}
407+
{...(!virtual ? a11yOptionProps : {})}
402408
className={optionClassName}
403409
title={optionTitle}
404410
onMouseMove={() => {

tests/Accessibility.test.tsx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,87 @@ describe('Select.Accessibility', () => {
132132
});
133133
expectOpen(container);
134134
});
135+
136+
// https://github.com/ant-design/ant-design/issues/53713
137+
describe('Select ARIA attributes', () => {
138+
it('should have correct aria and role attributes in virtual true', () => {
139+
render(
140+
<Select
141+
id="virtual-select"
142+
open={true}
143+
options={[
144+
{
145+
value: '123',
146+
},
147+
{
148+
value: '1234',
149+
},
150+
{
151+
value: '12345',
152+
},
153+
]}
154+
/>,
155+
);
156+
157+
const dropdown = document.querySelector('#virtual-select_list');
158+
expect(dropdown).toHaveAttribute('role', 'listbox');
159+
160+
const options = dropdown.querySelectorAll('div');
161+
options.forEach((option) => {
162+
// 每个 option 应该有 role="option"
163+
expect(option).toHaveAttribute('role', 'option');
164+
165+
// 如果有 aria-selected,确保值是 true/false
166+
const ariaSelected = option.getAttribute('aria-selected');
167+
if (ariaSelected !== null) {
168+
expect(['true', 'false']).toContain(ariaSelected);
169+
}
170+
});
171+
172+
const rcVirtual = document.querySelector('.rc-virtual-list-holder-inner');
173+
expect(rcVirtual).not.toHaveAttribute('role');
174+
const rcOptionItem = rcVirtual.querySelectorAll('.rc-select-item-option');
175+
176+
rcOptionItem.forEach((option) => {
177+
expect(option).not.toHaveAttribute('role');
178+
expect(option).not.toHaveAttribute('aria-selected');
179+
});
180+
});
181+
182+
it('should have correct aria and role attributes in virtual false', () => {
183+
render(
184+
<Select
185+
id="virtual-select"
186+
open
187+
virtual={false}
188+
options={[
189+
{
190+
value: '123',
191+
},
192+
{
193+
value: '1234',
194+
},
195+
{
196+
value: '12345',
197+
},
198+
]}
199+
/>,
200+
);
201+
202+
const dropdown = document.querySelector('#virtual-select_list');
203+
expect(dropdown).toHaveAttribute('role', 'listbox');
204+
205+
const options = dropdown.querySelectorAll('.rc-select-item-option');
206+
options.forEach((option) => {
207+
// 每个 option 应该有 role="option"
208+
expect(option).toHaveAttribute('role', 'option');
209+
210+
// 如果有 aria-selected,确保值是 true/false
211+
const ariaSelected = option.getAttribute('aria-selected');
212+
if (ariaSelected !== null) {
213+
expect(['true', 'false']).toContain(ariaSelected);
214+
}
215+
});
216+
});
217+
});
135218
});

tests/__snapshots__/OptionList.test.tsx.snap

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ exports[`OptionList renders correctly virtual 1`] = `
1010
<div
1111
aria-selected="false"
1212
id="undefined_list_0"
13-
role="presentation"
13+
role="option"
1414
/>
1515
<div
1616
aria-label="value-1"
@@ -23,7 +23,7 @@ exports[`OptionList renders correctly virtual 1`] = `
2323
<div
2424
aria-selected="false"
2525
id="undefined_list_2"
26-
role="presentation"
26+
role="option"
2727
/>
2828
</div>
2929
<div
@@ -45,7 +45,6 @@ exports[`OptionList renders correctly virtual 1`] = `
4545
</div>
4646
<div
4747
aria-label="value-1"
48-
aria-selected="true"
4948
class="rc-select-item rc-select-item-option rc-select-item-option-grouped rc-select-item-option-active rc-select-item-option-selected"
5049
title="1"
5150
>
@@ -73,7 +72,6 @@ exports[`OptionList renders correctly virtual 1`] = `
7372
group2
7473
</div>
7574
<div
76-
aria-selected="false"
7775
class="rc-select-item rc-select-item-option rc-select-item-option-grouped"
7876
title="2"
7977
>

tests/__snapshots__/Select.test.tsx.snap

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ exports[`Select.Basic does not filter when filterOption value is false 1`] = `
4242
style="display: flex; flex-direction: column;"
4343
>
4444
<div
45-
aria-selected="false"
4645
class="rc-select-item rc-select-item-option rc-select-item-option-active"
4746
title="1"
4847
>
@@ -63,7 +62,6 @@ exports[`Select.Basic does not filter when filterOption value is false 1`] = `
6362
</span>
6463
</div>
6564
<div
66-
aria-selected="false"
6765
class="rc-select-item rc-select-item-option"
6866
title="2"
6967
>
@@ -418,7 +416,6 @@ exports[`Select.Basic render should support fieldName 1`] = `
418416
groupLabel
419417
</div>
420418
<div
421-
aria-selected="false"
422419
class="rc-select-item rc-select-item-option rc-select-item-option-grouped rc-select-item-option-active"
423420
title="label"
424421
>
@@ -465,7 +462,6 @@ exports[`Select.Basic render should support fieldName 2`] = `
465462
groupLabel
466463
</div>
467464
<div
468-
aria-selected="false"
469465
class="rc-select-item rc-select-item-option rc-select-item-option-grouped rc-select-item-option-active"
470466
title="label"
471467
>
@@ -512,7 +508,6 @@ exports[`Select.Basic render should support fieldName 3`] = `
512508
groupLabel
513509
</div>
514510
<div
515-
aria-selected="false"
516511
class="rc-select-item rc-select-item-option rc-select-item-option-grouped rc-select-item-option-active"
517512
title="label"
518513
>
@@ -580,7 +575,6 @@ exports[`Select.Basic should contain falsy children 1`] = `
580575
style="display: flex; flex-direction: column;"
581576
>
582577
<div
583-
aria-selected="true"
584578
class="rc-select-item rc-select-item-option rc-select-item-option-active rc-select-item-option-selected"
585579
title="1"
586580
>
@@ -603,7 +597,6 @@ exports[`Select.Basic should contain falsy children 1`] = `
603597
</span>
604598
</div>
605599
<div
606-
aria-selected="false"
607600
class="rc-select-item rc-select-item-option"
608601
title="2"
609602
>
@@ -679,7 +672,6 @@ exports[`Select.Basic should render custom dropdown correctly 1`] = `
679672
style="display: flex; flex-direction: column;"
680673
>
681674
<div
682-
aria-selected="false"
683675
class="rc-select-item rc-select-item-option rc-select-item-option-active"
684676
title="1"
685677
>
@@ -700,7 +692,6 @@ exports[`Select.Basic should render custom dropdown correctly 1`] = `
700692
</span>
701693
</div>
702694
<div
703-
aria-selected="false"
704695
class="rc-select-item rc-select-item-option"
705696
title="2"
706697
>

tests/__snapshots__/Tags.test.tsx.snap

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ exports[`Select.Tags OptGroup renders correctly 1`] = `
114114
<div
115115
aria-selected="false"
116116
id="test-id_list_0"
117-
role="presentation"
117+
role="option"
118118
/>
119119
<div
120120
aria-label="Jack"
@@ -127,7 +127,7 @@ exports[`Select.Tags OptGroup renders correctly 1`] = `
127127
<div
128128
aria-selected="false"
129129
id="test-id_list_2"
130-
role="presentation"
130+
role="option"
131131
/>
132132
</div>
133133
<div
@@ -150,7 +150,6 @@ exports[`Select.Tags OptGroup renders correctly 1`] = `
150150
Manager
151151
</div>
152152
<div
153-
aria-selected="true"
154153
class="rc-select-item rc-select-item-option rc-select-item-option-grouped rc-select-item-option-active rc-select-item-option-selected"
155154
title="Jack"
156155
>
@@ -179,7 +178,6 @@ exports[`Select.Tags OptGroup renders correctly 1`] = `
179178
Engineer
180179
</div>
181180
<div
182-
aria-selected="false"
183181
class="rc-select-item rc-select-item-option rc-select-item-option-grouped"
184182
title="yiminghe"
185183
>
@@ -200,7 +198,6 @@ exports[`Select.Tags OptGroup renders correctly 1`] = `
200198
</span>
201199
</div>
202200
<div
203-
aria-selected="true"
204201
class="rc-select-item rc-select-item-option rc-select-item-option-selected"
205202
title="foo"
206203
>

0 commit comments

Comments
 (0)