diff --git a/packages/react-aria-components/example/index.css b/packages/react-aria-components/example/index.css
index 74c4762fa3e..64e6c5c6557 100644
--- a/packages/react-aria-components/example/index.css
+++ b/packages/react-aria-components/example/index.css
@@ -453,3 +453,12 @@ html {
opacity: 0.4;
}
}
+
+.textfieldExample {
+ display: flex;
+ flex-direction: column;
+
+ .errorMessage {
+ padding-bottom: 10px;
+ }
+}
diff --git a/packages/react-aria-components/src/FieldError.tsx b/packages/react-aria-components/src/FieldError.tsx
index a2df7238cc5..1e64f6c7124 100644
--- a/packages/react-aria-components/src/FieldError.tsx
+++ b/packages/react-aria-components/src/FieldError.tsx
@@ -40,9 +40,13 @@ const FieldErrorInner = forwardRef((props: FieldErrorProps, ref: ForwardedRef;
});
diff --git a/packages/react-aria-components/stories/TextField.stories.tsx b/packages/react-aria-components/stories/TextField.stories.tsx
index e5eb26ee354..1fa6a1609a9 100644
--- a/packages/react-aria-components/stories/TextField.stories.tsx
+++ b/packages/react-aria-components/stories/TextField.stories.tsx
@@ -10,8 +10,10 @@
* governing permissions and limitations under the License.
*/
-import {Input, Label, TextField} from 'react-aria-components';
+import {Button, FieldError, Form, Input, Label, TextField} from 'react-aria-components';
+import {classNames} from '@react-spectrum/utils';
import React from 'react';
+import styles from '../example/index.css';
export default {
title: 'React Aria Components'
@@ -25,3 +27,32 @@ export const TextfieldExample = () => {
);
};
+
+export const TextFieldSubmitExample = (args) => {
+ return (
+
+ );
+};
+
+TextFieldSubmitExample.story = {
+ argTypes: {
+ isInvalid: {
+ control: {
+ type: 'boolean'
+ }
+ }
+ },
+ parameters: {
+ description: {
+ 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).'
+ }
+ }
+};
diff --git a/packages/react-aria-components/test/TextField.test.js b/packages/react-aria-components/test/TextField.test.js
index f0f3bf26b06..52298c66fea 100644
--- a/packages/react-aria-components/test/TextField.test.js
+++ b/packages/react-aria-components/test/TextField.test.js
@@ -116,7 +116,7 @@ describe('TextField', () => {
);
let input = getByRole('textbox');
-
+
expect(input.closest('.react-aria-TextField')).not.toHaveAttribute('data-readonly');
rerender();
expect(input.closest('.react-aria-TextField')).toHaveAttribute('data-readonly');
@@ -128,7 +128,7 @@ describe('TextField', () => {
);
let input = getByRole('textbox');
-
+
expect(input.closest('.react-aria-TextField')).not.toHaveAttribute('data-required');
rerender();
expect(input.closest('.react-aria-TextField')).toHaveAttribute('data-required');
@@ -176,6 +176,24 @@ describe('TextField', () => {
expect(input.closest('.react-aria-TextField')).not.toHaveAttribute('data-invalid');
});
+ it('should not render the field error div if no error is provided and isInvalid is true', async () => {
+ let Component = component;
+ let {getByRole} = render(
+
+ );
+
+ let input = getByRole('textbox');
+ expect(input).toHaveAttribute('aria-invalid');
+ expect(input).toHaveAttribute('data-invalid');
+ expect(input).not.toHaveAttribute('aria-describedby');
+ });
+
it('supports customizing validation errors', async () => {
let Component = component;
let {getByRole, getByTestId} = render(