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(