From 5065f2562947128553bea1390ed154991cf5f124 Mon Sep 17 00:00:00 2001 From: Josh Farrant Date: Mon, 2 Dec 2024 16:08:59 +0000 Subject: [PATCH] Update docs form validation example to demonstrate best-practise when submitting a form in an invalid state (#834) * update docs validation example to demonstrate best-practise when submitting a form in an invalid state * tidy up example * update copy --- apps/docs/content/components/FormControl.mdx | 80 ++++++++++---------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/apps/docs/content/components/FormControl.mdx b/apps/docs/content/components/FormControl.mdx index 64fab5fcf..8845ea03a 100644 --- a/apps/docs/content/components/FormControl.mdx +++ b/apps/docs/content/components/FormControl.mdx @@ -9,7 +9,7 @@ description: Use the form control component to display form inputs alongside lab import InlineCode from '@primer/gatsby-theme-doctocat/src/components/inline-code' import {PropTableValues} from '../../src/components' import {Label} from '@primer/react' -import {Heading, Text} from '@primer/react-brand' +import {Button, Heading, Text} from '@primer/react-brand' import {SearchIcon} from '@primer/octicons-react' import {Link} from 'gatsby' @@ -228,52 +228,54 @@ Labels should only be visually hidden when the context is clear from the input i The following example demonstrates declarative form validation in [controlled mode](https://reactjs.org/docs/forms.html#controlled-components). -Try changing the input value to to `monalisa` to show the `success` state. +When the form is submitted with an invalid value, the invalid input receives focus to help the user correct the error. This is especially important for users navigating the form using a screen reader. + +More information on form validation best practices can be found in the [Primer UI Patterns documentation](https://primer.style/ui-patterns/forms/overview#validation). + +Try changing the input value to `monalisa` and submitting the form to show the `success` state. ```javascript live noinline const App = () => { - const [value, setValue] = React.useState() - const [validationState, setValidationState] = React.useState() - - React.useEffect(() => { - const defaultHandle = 'mona lisa' - setValue(defaultHandle) - validate(defaultHandle) - }, []) - - const validate = (inputValue) => { - if (/\s/g.test(inputValue)) { - setValidationState('error') - } else { - setValidationState('success') - } - } + const inputRef = React.useRef(null) + const [value, setValue] = React.useState('mona lisa') + const [isValid, setIsValid] = React.useState(false) + + const onChange = (e) => setValue(e.target.value) + + const onSubmit = (e) => { + e.preventDefault() + const valid = !value.includes(' ') + setIsValid(valid) - const handleChange = (event) => { - event.preventDefault() - if (!event.target.value) { - setValue(undefined) - setValidationState(undefined) - return + if (!valid) { + inputRef.current.focus() } - setValue(event.target.value) - validate(event.target.value) } return ( - - GitHub handle - - {validationState && validationState === 'error' && ( - - GitHub handles cannot contain spaces.{' '} - {value && `Did you mean "${value.replaceAll(' ', '')}"`} - - )} - {validationState && validationState === 'success' && ( - Valid name - )} - +
+ + + GitHub handle + + {isValid && ( + Valid name + )} + {!isValid && ( + + GitHub handles cannot contain spaces.{' '} + {value && `Did you mean "${value.replaceAll(' ', '')}"`} + + )} + + + +
) }