Skip to content

Form

The Form component is a lightweight wrapper around the native HTML <form> element. It provides consistent styling, spacing, and structure for building forms. It extends all standard form attributes, so you can attach onSubmit, action, method, and any other native form props.

Import

import { Form } from '@nim-ui/components';

Usage

Basic Form

View Code
<Form onSubmit={handleSubmit}>
<Input placeholder="Enter your name" />
<Input type="email" placeholder="Enter your email" />
<Button type="submit" variant="primary">
Submit
</Button>
</Form>

Form Layouts

Vertical Layout (Default)

Vertical Form Layout

View Code
<Form onSubmit={handleSubmit}>
<Input placeholder="First name" />
<Input placeholder="Last name" />
<Input type="email" placeholder="Email address" />
<Textarea placeholder="Your message" rows={4} />
<Button type="submit" variant="primary">
Send Message
</Button>
</Form>

Inline Fields

Form with Inline Fields

View Code
<Form onSubmit={handleSubmit}>
<div className="flex gap-4">
<Input placeholder="First name" />
<Input placeholder="Last name" />
</div>
<Input type="email" placeholder="Email address" />
<Button type="submit" variant="primary">
Create Account
</Button>
</Form>

With Select and Checkbox

Complete Form

View Code
<Form onSubmit={handleSubmit}>
<Input placeholder="Full name" />
<Input type="email" placeholder="Email" />
<Select
options={[
{ value: 'personal', label: 'Personal' },
{ value: 'business', label: 'Business' },
{ value: 'enterprise', label: 'Enterprise' },
]}
placeholder="Select plan"
/>
<Checkbox label="I agree to the terms and conditions" />
<Button type="submit" variant="primary" fullWidth>
Sign Up
</Button>
</Form>

With Validation Errors

Form with Errors

View Code
<Form onSubmit={handleSubmit}>
<Input
placeholder="Email"
type="email"
error={errors.email}
/>
<Input
placeholder="Password"
type="password"
error={errors.password}
/>
<Button type="submit" variant="primary" fullWidth>
Log In
</Button>
</Form>

Props

The Form component extends React.FormHTMLAttributes<HTMLFormElement>, so it accepts all standard HTML form attributes in addition to the following:

Name Type Default Description
onSubmit (event: React.FormEvent<HTMLFormElement>) => void - Submit event handler. Call event.preventDefault() to handle submission in JavaScript.
action string - URL to submit the form to when using native form submission
method 'get' | 'post' - HTTP method for native form submission
className string - Additional CSS classes to apply to the form element
children * ReactNode - Form content including inputs, selects, buttons, and other form elements

Usage Examples

Login Form

import { useState } from 'react';
import { Form, Input, Button, Checkbox } from '@nim-ui/components';
function LoginForm() {
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState<Record<string, string>>({});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
const formData = new FormData(e.currentTarget as HTMLFormElement);
const email = formData.get('email') as string;
const password = formData.get('password') as string;
try {
await login(email, password);
} catch (err) {
setErrors({ email: 'Invalid email or password' });
} finally {
setLoading(false);
}
};
return (
<Form onSubmit={handleSubmit}>
<Input
name="email"
type="email"
placeholder="Email"
error={errors.email}
/>
<Input
name="password"
type="password"
placeholder="Password"
error={errors.password}
/>
<Checkbox label="Remember me" name="remember" />
<Button type="submit" variant="primary" fullWidth loading={loading}>
Sign In
</Button>
</Form>
);
}

Contact Form

import { Form, Input, Textarea, Select, Button } from '@nim-ui/components';
function ContactForm() {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.currentTarget as HTMLFormElement);
await sendContactMessage(Object.fromEntries(formData));
};
return (
<Form onSubmit={handleSubmit}>
<div className="flex gap-4">
<Input name="firstName" placeholder="First name" />
<Input name="lastName" placeholder="Last name" />
</div>
<Input name="email" type="email" placeholder="Email address" />
<Select
name="subject"
placeholder="What is this about?"
options={[
{ value: 'general', label: 'General Inquiry' },
{ value: 'support', label: 'Technical Support' },
{ value: 'billing', label: 'Billing' },
{ value: 'feedback', label: 'Feedback' },
]}
/>
<Textarea
name="message"
placeholder="Your message..."
rows={6}
/>
<Button type="submit" variant="primary">
Send Message
</Button>
</Form>
);
}

Multi-step Form

import { useState } from 'react';
import { Form, Input, Button } from '@nim-ui/components';
function MultiStepForm() {
const [step, setStep] = useState(1);
return (
<Form onSubmit={handleFinalSubmit}>
{step === 1 && (
<>
<Input name="name" placeholder="Full name" />
<Input name="email" type="email" placeholder="Email" />
<Button variant="primary" onClick={() => setStep(2)}>
Next
</Button>
</>
)}
{step === 2 && (
<>
<Input name="company" placeholder="Company" />
<Input name="role" placeholder="Your role" />
<div className="flex gap-4">
<Button variant="outline" onClick={() => setStep(1)}>
Back
</Button>
<Button type="submit" variant="primary">
Submit
</Button>
</div>
</>
)}
</Form>
);
}

Accessibility

The Form component follows accessibility best practices:

  • Uses the semantic <form> HTML element
  • Supports native form validation attributes on child inputs
  • Works with screen readers by maintaining proper form landmark semantics
  • All child form elements should include associated labels (see FormField)
  • Error messages are announced to screen readers via aria-live regions
  • FormField - Labeled field wrapper with error and helper text
  • Input - Text input field
  • Select - Dropdown selection
  • Textarea - Multi-line text input
  • Checkbox - Boolean checkbox input
  • Button - Form submit button