Skip to content

Commit e0ac8d5

Browse files
fix(fuselage-forms): missing role alert on FieldError (#1921)
Co-authored-by: Douglas Fabris <devfabris@gmail.com>
1 parent 5bb4f85 commit e0ac8d5

File tree

5 files changed

+88
-15
lines changed

5 files changed

+88
-15
lines changed

.changeset/wicked-lights-buy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@rocket.chat/fuselage-forms': patch
3+
---
4+
5+
fix(fuselage-forms): missing `role alert` on `FieldError`

packages/fuselage-forms/src/Field/Field.stories.tsx

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,13 @@ export const WithUrlInput: StoryFn<typeof Field> = () => (
235235

236236
export const WithSelect: StoryFn<typeof Field> = () => (
237237
<Field>
238-
<FieldRow>
239-
<FieldLabel required>
240-
Example Select
241-
<FieldLabelInfo title='with extra info in a tooltip' />
242-
</FieldLabel>
243-
</FieldRow>
238+
<FieldLabel required>
239+
Example Select
240+
<FieldLabelInfo title='with extra info in a tooltip' />
241+
</FieldLabel>
242+
<FieldDescription>
243+
You can select a single option from a list of options
244+
</FieldDescription>
244245
<FieldRow>
245246
<Select
246247
options={[
@@ -257,13 +258,7 @@ export const WithSelect: StoryFn<typeof Field> = () => (
257258
]}
258259
/>
259260
</FieldRow>
260-
261-
<FieldRow>
262-
<FieldDescription>
263-
You can select a single option from a list of options
264-
</FieldDescription>
265-
<FieldError>You failed to enter a valid value</FieldError>
266-
</FieldRow>
261+
<FieldError>You failed to enter a valid value</FieldError>
267262
<FieldRow>
268263
<FieldHint>This should help the user enter a valid value</FieldHint>
269264
<FieldLink href='#'>Link to more information</FieldLink>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { render } from '@testing-library/react';
2+
3+
import { TextInput } from '../Inputs';
4+
5+
import { Field, FieldLabel, FieldError } from '.';
6+
7+
it('should have an alert element', () => {
8+
const { container } = render(
9+
<Field>
10+
<FieldLabel>Test Field</FieldLabel>
11+
<TextInput />
12+
<FieldError>Error message</FieldError>
13+
</Field>,
14+
);
15+
16+
expect(container).toContainElement(container.querySelector('[role="alert"]'));
17+
});
18+
19+
it('should have an id that matches the aria-describedby on the input', () => {
20+
const { container } = render(
21+
<Field>
22+
<FieldLabel>Test Field</FieldLabel>
23+
<TextInput />
24+
<FieldError>Error message</FieldError>
25+
</Field>,
26+
);
27+
28+
const input = container.querySelector('input');
29+
const ariaDescribedBy = input?.getAttribute('aria-describedby');
30+
expect(ariaDescribedBy).toBeTruthy();
31+
32+
const errorElement = container.querySelector('[role="alert"]');
33+
const errorId = errorElement?.getAttribute('id');
34+
35+
expect(ariaDescribedBy).toContain(errorId);
36+
});
37+
38+
it('should set aria-invalid="true" on the input when error is present', () => {
39+
const { container } = render(
40+
<Field>
41+
<FieldLabel>Test Field</FieldLabel>
42+
<TextInput />
43+
<FieldError>Error message</FieldError>
44+
</Field>,
45+
);
46+
47+
const input = container.querySelector('input');
48+
expect(input).toHaveAttribute('aria-invalid', 'true');
49+
});
50+
51+
it('should set aria-invalid="false" on the input when no error is present', () => {
52+
const { container } = render(
53+
<Field>
54+
<FieldLabel>Test Field</FieldLabel>
55+
<TextInput />
56+
</Field>,
57+
);
58+
59+
const input = container.querySelector('input');
60+
expect(input).toHaveAttribute('aria-invalid', 'false');
61+
});

packages/fuselage-forms/src/Field/FieldError.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ type FieldErrorProps = { children: ReactNode } & ComponentProps<
99

1010
const FieldError = ({ children, ...props }: FieldErrorProps) => {
1111
const id = useFieldDescriptorId('error');
12-
1312
return (
14-
<FieldErrorComponent {...props} id={id}>
13+
<FieldErrorComponent {...props} id={id} role='alert'>
1514
{children}
1615
</FieldErrorComponent>
1716
);

packages/fuselage-forms/src/__snapshots__/test.spec.tsx.snap

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ exports[`renders WithCheckbox without crashing 1`] = `
6666
<span
6767
class="rcx-box rcx-box--full rcx-field__error"
6868
id="react-aria-:r7:-error"
69+
role="alert"
6970
>
7071
You failed to enter a valid value
7172
</span>
@@ -146,6 +147,7 @@ exports[`renders WithEmailInput without crashing 1`] = `
146147
<span
147148
class="rcx-box rcx-box--full rcx-field__error"
148149
id="react-aria-:r1:-error"
150+
role="alert"
149151
>
150152
You failed to enter a valid value
151153
</span>
@@ -284,6 +286,7 @@ exports[`renders WithMultiSelect without crashing 1`] = `
284286
<span
285287
class="rcx-box rcx-box--full rcx-field__error"
286288
id="react-aria-:rb:-error"
289+
role="alert"
287290
>
288291
You failed to enter a valid value
289292
</span>
@@ -364,6 +367,7 @@ exports[`renders WithNumberInput without crashing 1`] = `
364367
<span
365368
class="rcx-box rcx-box--full rcx-field__error"
366369
id="react-aria-:r9:-error"
370+
role="alert"
367371
>
368372
You failed to enter a valid value
369373
</span>
@@ -458,6 +462,7 @@ exports[`renders WithPasswordInput without crashing 1`] = `
458462
<span
459463
class="rcx-box rcx-box--full rcx-field__error"
460464
id="react-aria-:r2:-error"
465+
role="alert"
461466
>
462467
You failed to enter a valid value
463468
</span>
@@ -549,6 +554,7 @@ exports[`renders WithRadioButton without crashing 1`] = `
549554
<span
550555
class="rcx-box rcx-box--full rcx-field__error"
551556
id="react-aria-:r5:-error"
557+
role="alert"
552558
>
553559
You failed to enter a valid value
554560
</span>
@@ -629,6 +635,7 @@ exports[`renders WithSearchInput without crashing 1`] = `
629635
<span
630636
class="rcx-box rcx-box--full rcx-field__error"
631637
id="react-aria-:r3:-error"
638+
role="alert"
632639
>
633640
You failed to enter a valid value
634641
</span>
@@ -750,6 +757,7 @@ exports[`renders WithSlider without crashing 1`] = `
750757
<span
751758
class="rcx-box rcx-box--full rcx-field__error"
752759
id="react-aria-:rc:-error"
760+
role="alert"
753761
>
754762
You failed to enter a valid value
755763
</span>
@@ -830,6 +838,7 @@ exports[`renders WithTelephoneInput without crashing 1`] = `
830838
<span
831839
class="rcx-box rcx-box--full rcx-field__error"
832840
id="react-aria-:r8:-error"
841+
role="alert"
833842
>
834843
You failed to enter a valid value
835844
</span>
@@ -910,6 +919,7 @@ exports[`renders WithTextArea without crashing 1`] = `
910919
<span
911920
class="rcx-box rcx-box--full rcx-field__error"
912921
id="react-aria-:r4:-error"
922+
role="alert"
913923
>
914924
You failed to enter a valid value
915925
</span>
@@ -990,6 +1000,7 @@ exports[`renders WithTextInput without crashing 1`] = `
9901000
<span
9911001
class="rcx-box rcx-box--full rcx-field__error"
9921002
id="react-aria-:r0:-error"
1003+
role="alert"
9931004
>
9941005
You failed to enter a valid value
9951006
</span>
@@ -1081,6 +1092,7 @@ exports[`renders WithToggleSwitch without crashing 1`] = `
10811092
<span
10821093
class="rcx-box rcx-box--full rcx-field__error"
10831094
id="react-aria-:r6:-error"
1095+
role="alert"
10841096
>
10851097
You failed to enter a valid value
10861098
</span>
@@ -1161,6 +1173,7 @@ exports[`renders WithUrlInput without crashing 1`] = `
11611173
<span
11621174
class="rcx-box rcx-box--full rcx-field__error"
11631175
id="react-aria-:ra:-error"
1176+
role="alert"
11641177
>
11651178
You failed to enter a valid value
11661179
</span>

0 commit comments

Comments
 (0)