FormField
The FormField component wraps individual form controls with a label, optional helper text, error messages, and a required indicator. It handles the association between the label and its input via htmlFor, ensuring proper accessibility.
Import
import { FormField } from '@nim-ui/components';Usage
Basic FormField
View Code
<FormField label="Email address" name="email"></FormField>Required Field
Required FormField
View Code
<FormField label="Full name" name="fullName" required> <Input placeholder="Enter your full name" /></FormField>With Helper Text
FormField with Helper Text
View Code
<FormField label="Password" name="password" helperText="Must be at least 8 characters with one uppercase letter and one number."> <Input type="password" placeholder="Enter password" /></FormField>With Error Message
FormField with Error
View Code
<FormField label="Email" name="email" error="Please enter a valid email address." required></FormField>With Select
FormField with Select
View Code
<FormField label="Country" name="country" required> <Select options={[ { value: 'us', label: 'United States' }, { value: 'uk', label: 'United Kingdom' }, { value: 'ca', label: 'Canada' }, { value: 'au', label: 'Australia' }, ]} placeholder="Select your country" /></FormField>With Textarea
FormField with Textarea
View Code
<FormField label="Bio" name="bio" helperText="Write a short description about yourself. Maximum 500 characters."> <Textarea placeholder="Tell us about yourself..." rows={4} /></FormField>Complete Form Example
Form with Multiple FormFields
View Code
<Form onSubmit={handleSubmit}> <FormField label="First name" name="firstName" required> <Input placeholder="Jane" /> </FormField> <FormField label="Last name" name="lastName" required> <Input placeholder="Doe" /> </FormField> <FormField label="Email" name="email" required helperText="We will never share your email."> </FormField> <FormField label="Role" name="role"> <Select options={[ { value: 'dev', label: 'Developer' }, { value: 'designer', label: 'Designer' }, { value: 'pm', label: 'Product Manager' }, ]} placeholder="Select your role" /> </FormField> <FormField label="Message" name="message"> <Textarea placeholder="Anything else you'd like to share?" rows={3} /> </FormField> <Button type="submit" variant="primary">Submit</Button></Form>Props
| Name | Type | Default | Description |
|---|---|---|---|
label * | string | - | Label text displayed above the form control |
name * | string | - | Used for the htmlFor attribute to associate the label with its form control |
error | string | - | Error message displayed in red below the form control |
helperText | string | - | Helper text displayed in gray below the form control. Hidden when an error is present. |
required | boolean | false | When true, displays a red asterisk (*) next to the label |
children * | ReactNode | - | The form control element (Input, Select, Textarea, etc.) |
className | string | - | Additional CSS classes to apply to the wrapper element |
Usage Examples
Registration Form
import { useState } from 'react';import { Form, FormField, Input, Select, Checkbox, Button } from '@nim-ui/components';
function RegistrationForm() { const [errors, setErrors] = useState<Record<string, string>>({});
const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); const formData = new FormData(e.currentTarget as HTMLFormElement); const validationErrors = validateRegistration(formData);
if (Object.keys(validationErrors).length > 0) { setErrors(validationErrors); return; }
createAccount(formData); };
return ( <Form onSubmit={handleSubmit}> <div className="flex gap-4"> <FormField label="First name" name="firstName" required error={errors.firstName}> <Input name="firstName" placeholder="Jane" /> </FormField> <FormField label="Last name" name="lastName" required error={errors.lastName}> <Input name="lastName" placeholder="Doe" /> </FormField> </div>
<FormField label="Email" name="email" required error={errors.email} > </FormField>
<FormField label="Password" name="password" required error={errors.password} helperText="At least 8 characters with a mix of letters and numbers." > <Input name="password" type="password" placeholder="Create a password" /> </FormField>
<FormField label="Company" name="company"> <Input name="company" placeholder="Your company (optional)" /> </FormField>
<FormField label="Role" name="role" required error={errors.role}> <Select name="role" placeholder="Select your role" options={[ { value: 'developer', label: 'Developer' }, { value: 'designer', label: 'Designer' }, { value: 'manager', label: 'Product Manager' }, { value: 'other', label: 'Other' }, ]} /> </FormField>
<Checkbox label="I agree to the terms of service" name="terms" />
<Button type="submit" variant="primary" fullWidth> Create Account </Button> </Form> );}Settings Form
function ProfileSettings() { return ( <Form onSubmit={handleSave}> <FormField label="Display name" name="displayName" required> <Input name="displayName" defaultValue="Jane Doe" /> </FormField>
<FormField label="Bio" name="bio" helperText="Brief description for your profile. Maximum 200 characters." > <Textarea name="bio" defaultValue="Frontend developer & design enthusiast" rows={3} /> </FormField>
<FormField label="Website" name="website" helperText="Include the full URL with https://"> <Input name="website" type="url" placeholder="https://yoursite.com" /> </FormField>
<Button type="submit" variant="primary"> Save Changes </Button> </Form> );}Accessibility
The FormField component ensures proper accessibility for form controls:
- The
labelis rendered as an HTML<label>element associated with the input viahtmlFormatching thenameprop - Required fields include
aria-required="true"in addition to the visual asterisk - Error messages are connected to the input via
aria-describedbyso screen readers announce them - Helper text is also connected via
aria-describedbyfor screen reader users - When both error and helper text are provided, the error takes precedence to avoid confusion
- The red asterisk on required fields includes
aria-hidden="true"since the requirement is communicated programmatically