Overview
Solarecliente provides a complete set of form components with built-in validation, error handling, and accessibility features. All form components integrate seamlessly with popular form libraries like React Hook Form and Formik.
The base Form component provides form state management and submission handling.
Basic Usage
import { Form } from '@/components/forms' ;
function ClientForm () {
const handleSubmit = ( data ) => {
console . log ( 'Form data:' , data );
};
return (
< Form onSubmit = { handleSubmit } >
{ /* Form fields */ }
</ Form >
);
}
Props
Callback function invoked when form is submitted with validated data
Initial values for form fields
Validation schema (Yup or Zod)
Additional CSS classes to apply to the form
The Input component supports various input types with validation and error display.
Text Input
Email Input
Password Input
Number Input
< Input
name = "clientName"
label = "Client Name"
placeholder = "Enter client name"
required
/>
< Input
name = "email"
type = "email"
label = "Email Address"
placeholder = "[email protected] "
required
/>
< Input
name = "password"
type = "password"
label = "Password"
showPasswordToggle
required
/>
< Input
name = "panelCount"
type = "number"
label = "Number of Panels"
min = { 1 }
max = { 100 }
step = { 1 }
/>
Unique identifier for the input field
Label text displayed above the input
Input type: text, email, password, number, tel, url
Placeholder text displayed when input is empty
Whether the field is required
Whether the input is disabled
Error message to display below the input
Helper text displayed below the input
Select Component
Dropdown select component with support for single and multi-select.
Single Select
Multi Select
With Groups
< Select
name = "status"
label = "Client Status"
options = { [
{ value: 'active' , label: 'Active' },
{ value: 'inactive' , label: 'Inactive' },
{ value: 'pending' , label: 'Pending' },
]}
placeholder="Select status"
/>
Select Props
Array of options with value and label properties
Enable multi-select functionality
Enable search/filter functionality
Show clear button to reset selection
Textarea Component
Multi-line text input for longer content.
< Textarea
name = "notes"
label = "Additional Notes"
placeholder = "Enter any additional information"
rows = { 4 }
maxLength = { 500 }
/>
Textarea Props
Number of visible text rows
Display character counter
Checkbox Component
< Checkbox
name = "terms"
label = "I agree to the terms and conditions"
required
/>
Checkbox Group
< CheckboxGroup
name = "features"
label = "Required Features"
options = { [
{ value: 'monitoring' , label: 'Real-time Monitoring' },
{ value: 'analytics' , label: 'Analytics Dashboard' },
{ value: 'alerts' , label: 'Email Alerts' },
]}
/>
Radio Component
< RadioGroup
name = "installationType"
label = "Installation Type"
options = { [
{ value: 'residential' , label: 'Residential' },
{ value: 'commercial' , label: 'Commercial' },
{ value: 'industrial' , label: 'Industrial' },
]}
required
/>
DatePicker Component
< DatePicker
name = "installationDate"
label = "Installation Date"
minDate = {new Date ()}
format = "MM/DD/YYYY"
placeholder = "Select date"
/>
DatePicker Props
format
string
default: "MM/DD/YYYY"
Date display format
Using Zod Schema
import { z } from 'zod' ;
import { useForm } from '@/hooks/useForm' ;
const clientSchema = z . object ({
name: z . string (). min ( 2 , 'Name must be at least 2 characters' ),
email: z . string (). email ( 'Invalid email address' ),
phone: z . string (). regex ( / ^ \d {10} $ / , 'Phone must be 10 digits' ),
installationDate: z . date (). min ( new Date (), 'Date must be in the future' ),
panelCount: z . number (). min ( 1 ). max ( 100 ),
});
function ClientForm () {
const { register , handleSubmit , errors } = useForm ({
schema: clientSchema ,
});
return (
< Form onSubmit = { handleSubmit } >
< Input
{ ... register (' name ')}
label = "Client Name"
error = {errors.name?. message }
/>
< Input
{ ... register (' email ')}
type = "email"
label = "Email"
error = {errors.email?. message }
/>
{ /* Additional fields */ }
</ Form >
);
}
Custom Validation
const validatePhone = ( value : string ) => {
if ( ! / ^ \d {10} $ / . test ( value )) {
return 'Phone number must be 10 digits' ;
}
return true ;
};
< Input
name = "phone"
label = "Phone Number"
validate = { validatePhone }
/>
import { Form , Input , Select , DatePicker , Textarea , Button } from '@/components' ;
import { z } from 'zod' ;
const schema = z . object ({
clientName: z . string (). min ( 2 ),
email: z . string (). email (),
phone: z . string (). regex ( / ^ \d {10} $ / ),
serviceType: z . string (),
installationDate: z . date (),
panelCount: z . number (). min ( 1 ). max ( 100 ),
notes: z . string (). optional (),
});
function NewClientForm () {
const handleSubmit = async ( data ) => {
try {
await createClient ( data );
toast . success ( 'Client created successfully' );
} catch ( error ) {
toast . error ( 'Failed to create client' );
}
};
return (
< Form
validationSchema = { schema }
onSubmit = { handleSubmit }
className = "max-w-2xl mx-auto"
>
< div className = "grid grid-cols-2 gap-4" >
< Input
name = "clientName"
label = "Client Name"
placeholder = "John Doe"
required
/>
< Input
name = "email"
type = "email"
label = "Email Address"
placeholder = "[email protected] "
required
/>
< Input
name = "phone"
type = "tel"
label = "Phone Number"
placeholder = "1234567890"
required
/>
< Select
name = "serviceType"
label = "Service Type"
options = { [
{ value: 'installation' , label: 'Installation' },
{ value: 'maintenance' , label: 'Maintenance' },
{ value: 'repair' , label: 'Repair' },
]}
required
/>
<DatePicker
name="installationDate"
label="Installation Date"
minDate={new Date()}
required
/>
<Input
name="panelCount"
type="number"
label="Number of Panels"
min={1}
max={100}
required
/>
</div>
<Textarea
name="notes"
label="Additional Notes"
placeholder="Any special requirements or notes"
rows={4}
/>
<div className="flex gap-3 justify-end">
<Button type="button" variant="secondary">
Cancel
</Button>
<Button type="submit" variant="primary">
Create Client
</Button>
</div>
</Form>
);
}
Best Practices
Validate Early Use client-side validation to provide immediate feedback to users
Clear Error Messages Write descriptive error messages that help users fix issues
Accessibility Always include proper labels and ARIA attributes for screen readers
Loading States Disable form inputs and show loading indicators during submission