Skip to content

Commit 7bb97f1

Browse files
authored
fix: v8 Combobox & Dropdown: add aria-invalid when errorMessage is set (#33529)
1 parent 0bfe0c7 commit 7bb97f1

File tree

9 files changed

+32
-6
lines changed

9 files changed

+32
-6
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "fix(Combobox and Dropdown): add aria-invalid when errorMessage is set",
4+
"packageName": "@fluentui/react",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

packages/react-experiments/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,6 +1837,7 @@ exports[`Pagination render comboBox Pagination correctly 1`] = `
18371837
<input
18381838
aria-autocomplete="both"
18391839
aria-expanded={false}
1840+
aria-invalid={false}
18401841
autoCapitalize="off"
18411842
autoComplete="off"
18421843
className=

packages/react/src/components/ComboBox/ComboBox.test.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,15 @@ describe('ComboBox', () => {
122122
expect(combobox.getAttribute('aria-disabled')).toEqual('true');
123123
});
124124

125+
it('sets alert message and aria-invalid when errorMessage is set', () => {
126+
const { getByRole } = render(
127+
<ComboBox label="Test label" options={DEFAULT_OPTIONS} errorMessage="This is an example error." />,
128+
);
129+
const alert = getByRole('alert');
130+
expect(alert.textContent).toBe('This is an example error.');
131+
expect(getByRole('combobox').getAttribute('aria-invalid')).toBe('true');
132+
});
133+
125134
it('Renders no selected item in default case', () => {
126135
const { getByRole } = render(<ComboBox options={DEFAULT_OPTIONS} />);
127136
expect(getByRole('combobox').getAttribute('value')).toEqual('');

packages/react/src/components/ComboBox/ComboBox.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,8 @@ class ComboBoxInternal extends React.Component<IComboBoxInternalProps, IComboBox
646646
'aria-label': ariaLabel && !label ? ariaLabel : undefined,
647647
};
648648

649+
const hasErrorMessage = errorMessage && errorMessage.length > 0 ? true : false;
650+
649651
return (
650652
<div
651653
data-ktp-target={true}
@@ -679,6 +681,7 @@ class ComboBoxInternal extends React.Component<IComboBoxInternalProps, IComboBox
679681
aria-activedescendant={ariaActiveDescendantValue}
680682
aria-required={required}
681683
aria-disabled={disabled}
684+
aria-invalid={hasErrorMessage}
682685
aria-controls={isOpen ? this._id + '-list' : undefined}
683686
spellCheck={false}
684687
defaultVisibleValue={this._currentVisibleValue}

packages/react/src/components/ComboBox/__snapshots__/ComboBox.test.tsx.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ exports[`ComboBox Renders correctly 1`] = `
145145
<input
146146
aria-autocomplete="both"
147147
aria-expanded="false"
148+
aria-invalid="false"
148149
autocapitalize="off"
149150
autocomplete="off"
150151
class=
@@ -495,6 +496,7 @@ exports[`ComboBox Renders correctly when open 1`] = `
495496
aria-autocomplete="both"
496497
aria-controls="ComboBox0-list"
497498
aria-expanded="true"
499+
aria-invalid="false"
498500
autocapitalize="off"
499501
autocomplete="off"
500502
class=
@@ -1333,6 +1335,7 @@ exports[`ComboBox Renders correctly when opened in multi-select mode 1`] = `
13331335
aria-autocomplete="both"
13341336
aria-controls="ComboBox0-list"
13351337
aria-expanded="true"
1338+
aria-invalid="false"
13361339
autocapitalize="off"
13371340
autocomplete="off"
13381341
class=
@@ -2266,6 +2269,7 @@ exports[`ComboBox renders with a Keytip correctly 1`] = `
22662269
aria-autocomplete="both"
22672270
aria-describedby="test-foo ktp-layer-id ktp-a"
22682271
aria-expanded="false"
2272+
aria-invalid="false"
22692273
autocapitalize="off"
22702274
autocomplete="off"
22712275
class=

packages/react/src/components/Dropdown/Dropdown.base.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ class DropdownInternal extends React.Component<IDropdownInternalProps, IDropdown
376376
aria-describedby={hasErrorMessage ? this._id + '-errorMessage' : undefined}
377377
aria-required={required}
378378
aria-disabled={disabled}
379+
aria-invalid={hasErrorMessage}
379380
aria-controls={isOpen ? this._listId : undefined}
380381
{...divProps}
381382
className={this._classNames.dropdown}
@@ -391,7 +392,6 @@ class DropdownInternal extends React.Component<IDropdownInternalProps, IDropdown
391392
className={this._classNames.title}
392393
aria-live={hasFocus ? 'polite' : undefined}
393394
aria-atomic={hasFocus ? true : undefined}
394-
aria-invalid={hasErrorMessage}
395395
>
396396
{
397397
// If option is selected render title, otherwise render the placeholder text

packages/react/src/components/Dropdown/Dropdown.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,12 +710,13 @@ describe('Dropdown', () => {
710710
expect(dropdownRoot.getAttribute('aria-labelledby')).not.toBeNull();
711711
});
712712

713-
it('sets role=error on included error message', () => {
713+
it('sets alert message and aria-invalid when errorMessage is set', () => {
714714
const { getByRole } = render(
715715
<Dropdown label="Test label" options={[]} id="sample-dropdown" errorMessage="This is an example error." />,
716716
);
717717
const alert = getByRole('alert');
718718
expect(alert.textContent).toBe('This is an example error.');
719+
expect(getByRole('combobox').getAttribute('aria-invalid')).toBe('true');
719720
});
720721
});
721722

packages/react/src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ exports[`Dropdown multi-select Renders correctly 1`] = `
88
<div
99
aria-expanded="false"
1010
aria-haspopup="listbox"
11+
aria-invalid="false"
1112
class=
1213
ms-Dropdown
1314
{
@@ -101,7 +102,6 @@ exports[`Dropdown multi-select Renders correctly 1`] = `
101102
tabindex="0"
102103
>
103104
<span
104-
aria-invalid="false"
105105
class=
106106
ms-Dropdown-title
107107
ms-Dropdown-titleIsPlaceHolder
@@ -939,6 +939,7 @@ exports[`Dropdown multi-select Renders correctly when open 1`] = `
939939
aria-controls="Dropdown0-list"
940940
aria-expanded="true"
941941
aria-haspopup="listbox"
942+
aria-invalid="false"
942943
class=
943944
ms-Dropdown
944945
is-open
@@ -1034,7 +1035,6 @@ exports[`Dropdown multi-select Renders correctly when open 1`] = `
10341035
>
10351036
<span
10361037
aria-atomic="true"
1037-
aria-invalid="false"
10381038
aria-live="polite"
10391039
class=
10401040
ms-Dropdown-title
@@ -1119,6 +1119,7 @@ exports[`Dropdown single-select Renders correctly 1`] = `
11191119
<div
11201120
aria-expanded="false"
11211121
aria-haspopup="listbox"
1122+
aria-invalid="false"
11221123
class=
11231124
ms-Dropdown
11241125
{
@@ -1212,7 +1213,6 @@ exports[`Dropdown single-select Renders correctly 1`] = `
12121213
tabindex="0"
12131214
>
12141215
<span
1215-
aria-invalid="false"
12161216
class=
12171217
ms-Dropdown-title
12181218
ms-Dropdown-titleIsPlaceHolder
@@ -1295,6 +1295,7 @@ exports[`Dropdown single-select Renders correctly when open 1`] = `
12951295
aria-controls="Dropdown0-list"
12961296
aria-expanded="true"
12971297
aria-haspopup="listbox"
1298+
aria-invalid="false"
12981299
class=
12991300
ms-Dropdown
13001301
is-open
@@ -1390,7 +1391,6 @@ exports[`Dropdown single-select Renders correctly when open 1`] = `
13901391
>
13911392
<span
13921393
aria-atomic="true"
1393-
aria-invalid="false"
13941394
aria-live="polite"
13951395
class=
13961396
ms-Dropdown-title

packages/react/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ exports[`TimePicker renders correctly 1`] = `
174174
aria-autocomplete="inline"
175175
aria-describedby="ComboBox0-error"
176176
aria-expanded={false}
177+
aria-invalid={false}
177178
aria-labelledby="ComboBox0-label"
178179
autoCapitalize="off"
179180
autoComplete="off"

0 commit comments

Comments
 (0)