Form Control
Build accessible and styled form controls with proper labeling and validation states.
Overview
FormControl provides a consistent way to build form fields with proper accessibility, labeling, help text, and error states. It automatically manages ARIA attributes and ensures screen readers can understand the form structure.
AccessibleARIA SupportValidation ReadyTypeScript
Basic Usage
Simple Form Control
The most basic form control with label and helper text.
import { FormControl, Input, Button } from '@akitectio/aki-ui'
function BasicForm() {
return (
<form className="space-y-4">
<FormControl>
<FormControl.Label>Email Address</FormControl.Label>
<Input
type="email"
placeholder="Enter your email"
required
/>
<FormControl.HelperText>
We'll never share your email with anyone else.
</FormControl.HelperText>
</FormControl>
<FormControl>
<FormControl.Label>Password</FormControl.Label>
<Input
type="password"
placeholder="Enter password"
required
/>
</FormControl>
<Button type="submit">Submit</Button>
</form>
)
}
Validation States
Form Validation
Handle validation states with error messages and visual feedback.
import { FormControl, Input, Button } from '@akitectio/aki-ui'
import { useState } from 'react'
function ValidatedForm() {
const [errors, setErrors] = useState<Record<string, string>>({})
const validateField = (name: string, value: string) => {
switch (name) {
case 'email':
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
? '' : 'Please enter a valid email address'
case 'password':
return value.length >= 8
? '' : 'Password must be at least 8 characters'
default:
return ''
}
}
return (
<form className="space-y-4">
<FormControl isInvalid={!!errors.email}>
<FormControl.Label>Email Address</FormControl.Label>
<Input
type="email"
name="email"
onChange={(e) => {
const error = validateField('email', e.target.value)
setErrors(prev => ({ ...prev, email: error }))
}}
/>
{errors.email && (
<FormControl.ErrorMessage>
{errors.email}
</FormControl.ErrorMessage>
)}
</FormControl>
<FormControl isInvalid={!!errors.password}>
<FormControl.Label>Password</FormControl.Label>
<Input
type="password"
name="password"
onChange={(e) => {
const error = validateField('password', e.target.value)
setErrors(prev => ({ ...prev, password: error }))
}}
/>
{errors.password && (
<FormControl.ErrorMessage>
{errors.password}
</FormControl.ErrorMessage>
)}
</FormControl>
</form>
)
}
API Reference
FormControl Props
Prop | Type | Default | Description |
---|---|---|---|
isRequired | boolean | false | Whether the field is required |
isInvalid | boolean | false | Whether the field has validation errors |
isDisabled | boolean | false | Whether the field is disabled |
Subcomponents
FormControl.Label
Accessible label for the form control. Automatically links to the input field.
FormControl.HelperText
Additional help text to guide users. Appears below the input field.
FormControl.ErrorMessage
Error message displayed when validation fails. Automatically styled with error colors.
Best Practices
Do
- • Always provide clear, descriptive labels
- • Use helper text for additional context
- • Implement real-time validation feedback
- • Group related fields logically
- • Test with screen readers
Don't
- • Use placeholder text as labels
- • Hide important validation messages
- • Make error messages too technical
- • Disable form submission unnecessarily
- • Forget to handle loading states