Active Foundation · Example
Validation and the error state
Validation and the error stateClient
Full source examples/ui/field-validation.tsx
// apps/docs/examples/ui/field-validation.tsx'use client';
import {useState, type FormEvent} from 'react';
import {Button} from '@workspace/active-ui/components/primitives/button';import { Field, FieldDescription, FieldError, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Input} from '@workspace/active-ui/components/primitives/input';
/** The application's own rule and message: the field only shows them. */function validateEmail(value: string): string | null { if (value.trim() === '') return 'Enter your email address.'; if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) { return 'Enter an email address like name@example.com.'; } return null;}
/** * Validation on submit, then on every change. `data-invalid` on `Field` * styles the whole field; `aria-invalid` on the control tells assistive * technology; `aria-describedby` points at the description and the error, * which `FieldError` announces (`role="alert"`). */export default function FieldValidation() { const [value, setValue] = useState(''); const [error, setError] = useState<string | null>(null); const [submitted, setSubmitted] = useState(false); const [sent, setSent] = useState(false);
const onSubmit = (event: FormEvent) => { event.preventDefault(); const message = validateEmail(value); setSubmitted(true); setError(message); setSent(message === null); };
return ( <form onSubmit={onSubmit} noValidate className="flex max-w-sm flex-col gap-4" > <Field data-invalid={error ? true : undefined}> <FieldLabel htmlFor="validation-email"> Email <span aria-hidden className="text-destructive"> * </span> <span className="sr-only">(required)</span> </FieldLabel> <Input id="validation-email" type="email" autoComplete="email" value={value} aria-invalid={error ? true : undefined} aria-describedby={ error ? 'validation-email-description validation-email-error' : 'validation-email-description' } onChange={(event) => { setValue(event.target.value); setSent(false); if (submitted) setError(validateEmail(event.target.value)); }} /> <FieldDescription id="validation-email-description"> We send the confirmation to this address. </FieldDescription> {error ? ( <FieldError id="validation-email-error">{error}</FieldError> ) : null} </Field> <div className="flex items-center gap-3"> <Button type="submit">Send confirmation</Button> {sent ? ( <span role="status" className="text-sm"> Sent to {value}. </span> ) : null} </div> </form> );}