Skip to content

Commit 56515c9

Browse files
authored
Render nothing if isInvalid and no error message is provided (#6099)
* Update FieldError so it doesnt render anything if isInvalid is controlled but no error message is provided * adding test and updating story
1 parent 30c1d0a commit 56515c9

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

packages/react-aria-components/example/index.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,3 +453,12 @@ html {
453453
opacity: 0.4;
454454
}
455455
}
456+
457+
.textfieldExample {
458+
display: flex;
459+
flex-direction: column;
460+
461+
.errorMessage {
462+
padding-bottom: 10px;
463+
}
464+
}

packages/react-aria-components/src/FieldError.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,13 @@ const FieldErrorInner = forwardRef((props: FieldErrorProps, ref: ForwardedRef<HT
4040
let renderProps = useRenderProps({
4141
...props,
4242
defaultClassName: 'react-aria-FieldError',
43-
defaultChildren: validation.validationErrors.join(' '),
43+
defaultChildren: validation.validationErrors.length === 0 ? undefined : validation.validationErrors.join(' '),
4444
values: validation
4545
});
4646

47+
if (renderProps.children == null) {
48+
return null;
49+
}
50+
4751
return <Text slot="errorMessage" {...renderProps} ref={ref} />;
4852
});

packages/react-aria-components/stories/TextField.stories.tsx

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {Input, Label, TextField} from 'react-aria-components';
13+
import {Button, FieldError, Form, Input, Label, TextField} from 'react-aria-components';
14+
import {classNames} from '@react-spectrum/utils';
1415
import React from 'react';
16+
import styles from '../example/index.css';
1517

1618
export default {
1719
title: 'React Aria Components'
@@ -25,3 +27,32 @@ export const TextfieldExample = () => {
2527
</TextField>
2628
);
2729
};
30+
31+
export const TextFieldSubmitExample = (args) => {
32+
return (
33+
<Form>
34+
<TextField className={classNames(styles, 'textfieldExample')} name="email" type="email" isRequired {...args}>
35+
<Label>Email</Label>
36+
<Input />
37+
<FieldError className={classNames(styles, 'errorMessage')} />
38+
</TextField>
39+
<Button type="submit">Submit</Button>
40+
<Button type="reset">Reset</Button>
41+
</Form>
42+
);
43+
};
44+
45+
TextFieldSubmitExample.story = {
46+
argTypes: {
47+
isInvalid: {
48+
control: {
49+
type: 'boolean'
50+
}
51+
}
52+
},
53+
parameters: {
54+
description: {
55+
data: 'Non controlled isInvalid should render the default error message (aka just hit submit and see that it appears). Controlled isInvalid=true should not render the error message div (aka no padding should appear between the input and the buttons).'
56+
}
57+
}
58+
};

packages/react-aria-components/test/TextField.test.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ describe('TextField', () => {
116116
);
117117

118118
let input = getByRole('textbox');
119-
119+
120120
expect(input.closest('.react-aria-TextField')).not.toHaveAttribute('data-readonly');
121121
rerender(<TestTextField input={component} isReadOnly />);
122122
expect(input.closest('.react-aria-TextField')).toHaveAttribute('data-readonly');
@@ -128,7 +128,7 @@ describe('TextField', () => {
128128
);
129129

130130
let input = getByRole('textbox');
131-
131+
132132
expect(input.closest('.react-aria-TextField')).not.toHaveAttribute('data-required');
133133
rerender(<TestTextField input={component} isRequired />);
134134
expect(input.closest('.react-aria-TextField')).toHaveAttribute('data-required');
@@ -176,6 +176,24 @@ describe('TextField', () => {
176176
expect(input.closest('.react-aria-TextField')).not.toHaveAttribute('data-invalid');
177177
});
178178

179+
it('should not render the field error div if no error is provided and isInvalid is true', async () => {
180+
let Component = component;
181+
let {getByRole} = render(
182+
<form data-testid="form">
183+
<TextField isRequired isInvalid>
184+
<Label>Test</Label>
185+
<Component />
186+
<FieldError />
187+
</TextField>
188+
</form>
189+
);
190+
191+
let input = getByRole('textbox');
192+
expect(input).toHaveAttribute('aria-invalid');
193+
expect(input).toHaveAttribute('data-invalid');
194+
expect(input).not.toHaveAttribute('aria-describedby');
195+
});
196+
179197
it('supports customizing validation errors', async () => {
180198
let Component = component;
181199
let {getByRole, getByTestId} = render(

0 commit comments

Comments
 (0)