Form
Used for collecting, validating, and submitting form data.
When to Use
- Need to create a data entry form
- Need to validate user input
- Need to submit data
- Need to dynamically add/remove form fields
Examples
Basic Usage
The simplest usage, getting form data via onFinish.
Live Editor
function Demo() { const handleFinish = (values) => { console.log('Form data:', values); alert(JSON.stringify(values, null, 2)); }; return ( <Form onFinish={handleFinish}> <FormItem name="username" label="Username" rules={[{ required: true, message: 'Please enter username' }]} > <Input placeholder="Please enter username" /> </FormItem> <FormItem name="email" label="Email" rules={[ { required: true, message: 'Please enter email' }, { type: 'email', message: 'Please enter a valid email address' }, ]} > <Input placeholder="Please enter email" /> </FormItem> <FormItem> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> ); }
Result
Loading...
Form Layout
Set form layout using the layout prop.
Live Editor
function Demo() { const [layout, setLayout] = React.useState('vertical'); return ( <div> <Group style={{ marginBottom: '24px' }}> <Button onClick={() => setLayout('horizontal')}>Horizontal</Button> <Button onClick={() => setLayout('vertical')}>Vertical</Button> <Button onClick={() => setLayout('inline')}>Inline</Button> </Group> <Form layout={layout} onFinish={(values) => console.log(values)}> <FormItem name="name" label="Name" rules={[{ required: true }]}> <Input /> </FormItem> <FormItem name="age" label="Age"> <Input /> </FormItem> <FormItem> <Button type="submit">Submit</Button> </FormItem> </Form> </div> ); }
Result
Loading...
Form Validation
Supports multiple validation rules.
Live Editor
function Demo() { const handleFinish = (values) => { alert('Validation passed: ' + JSON.stringify(values)); }; return ( <Form onFinish={handleFinish}> <FormItem name="username" label="Username" rules={[ { required: true, message: 'Username is required' }, { min: 3, message: 'Username must be at least 3 characters' }, { max: 20, message: 'Username must be at most 20 characters' }, ]} > <Input /> </FormItem> <FormItem name="password" label="Password" rules={[ { required: true, message: 'Password is required' }, { min: 6, message: 'Password must be at least 6 characters' }, ]} > <InputPassword /> </FormItem> <FormItem name="confirm" label="Confirm Password" dependencies={['password']} rules={[ { required: true, message: 'Please confirm password' }, ({ getFieldValue }) => ({ validator(_, value) { if (!value || getFieldValue('password') === value) { return Promise.resolve(); } return Promise.reject(new Error('Passwords do not match')); }, }), ]} > <InputPassword /> </FormItem> <FormItem> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> ); }
Result
Loading...
Dynamic Form Items
Use FormList to implement dynamic add/remove form items.
Live Editor
function Demo() { const { Add, Trash } = KubedIcons; return ( <Form onFinish={(values) => console.log(values)}> <FormList name="users"> {(fields, { add, remove }) => ( <> {fields.map(({ key, name, ...restField }) => ( <Group key={key} style={{ marginBottom: '12px' }}> <FormItem {...restField} name={[name, 'firstName']} label="First Name" rules={[{ required: true, message: 'Please enter first name' }]} style={{ marginBottom: 0, flex: 1 }} > <Input /> </FormItem> <FormItem {...restField} name={[name, 'lastName']} label="Last Name" rules={[{ required: true, message: 'Please enter last name' }]} style={{ marginBottom: 0, flex: 1 }} > <Input /> </FormItem> <Button variant="text" color="error" onClick={() => remove(name)}> <Trash size={16} /> </Button> </Group> ))} <Button onClick={() => add()} leftIcon={<Add size={16} />}> Add User </Button> </> )} </FormList> <FormItem style={{ marginTop: '24px' }}> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> ); }
Result
Loading...
Form Methods
Use the useForm Hook to get a form instance and call form methods.
Live Editor
function Demo() { const [form] = useForm(); const handleFill = () => { form.setFieldsValue({ username: 'admin', email: 'admin@example.com', }); }; const handleReset = () => { form.resetFields(); }; const handleGetValues = () => { const values = form.getFieldsValue(); alert(JSON.stringify(values, null, 2)); }; return ( <div> <Group style={{ marginBottom: '16px' }}> <Button onClick={handleFill}>Fill Data</Button> <Button onClick={handleReset}>Reset</Button> <Button onClick={handleGetValues}>Get Values</Button> </Group> <Form form={form} onFinish={(values) => console.log(values)}> <FormItem name="username" label="Username" rules={[{ required: true }]}> <Input /> </FormItem> <FormItem name="email" label="Email" rules={[{ required: true, type: 'email' }]}> <Input /> </FormItem> <FormItem> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> </div> ); }
Result
Loading...
Checkbox Group
Using CheckboxGroup in forms.
Live Editor
function Demo() { return ( <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}> <FormItem name="permissions" label="Permissions" rules={[{ required: true, message: 'Please select permissions' }]}> <CheckboxGroup> <Checkbox label="Read" value="read" /> <Checkbox label="Write" value="write" /> <Checkbox label="Delete" value="delete" /> <Checkbox label="Execute" value="execute" /> </CheckboxGroup> </FormItem> <FormItem> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> ); }
Result
Loading...
Grid Layout
Using Grid component for complex form layouts.
Live Editor
function Demo() { return ( <Form onFinish={(values) => console.log(values)}> <Row gutter={[16, 16]}> <Col span={12}> <FormItem name="firstName" label="First Name" rules={[{ required: true }]}> <Input /> </FormItem> </Col> <Col span={12}> <FormItem name="lastName" label="Last Name" rules={[{ required: true }]}> <Input /> </FormItem> </Col> <Col span={12}> <FormItem name="email" label="Email" rules={[{ required: true, type: 'email' }]}> <Input /> </FormItem> </Col> <Col span={12}> <FormItem name="phone" label="Phone" rules={[{ required: true }]}> <Input /> </FormItem> </Col> <Col span={24}> <FormItem name="address" label="Address"> <Textarea /> </FormItem> </Col> </Row> <FormItem> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> ); }
Result
Loading...
Help Text and Tooltip
Add additional information using help and tooltip props.
Live Editor
function Demo() { const { Question } = KubedIcons; return ( <Form onFinish={(values) => console.log(values)}> <FormItem name="username" label="Username" help="Username is used to log in to the system" rules={[{ required: true }]} > <Input /> </FormItem> <FormItem name="apiKey" label="API Key" tooltip="API key is used for API authentication, please keep it secure" rules={[{ required: true }]} > <Input /> </FormItem> <FormItem> <Button type="submit" variant="filled" color="primary"> Submit </Button> </FormItem> </Form> ); }
Result
Loading...
API
Form Props
| Property | Description | Type | Default |
|---|---|---|---|
| form | Form instance, created by useForm | FormInstance | - |
| name | Form name | string | - |
| layout | Form layout | 'horizontal' | 'vertical' | 'inline' | 'vertical' |
| labelAlign | Label alignment | 'left' | 'right' | 'right' |
| labelCol | Label grid layout | ColProps | {span: 4} |
| wrapperCol | Input control grid layout | ColProps | {span: 14} |
| size | Form component size | KubedSizes | 'sm' |
| initialValues | Form initial values | object | - |
| onFinish | Callback when form submit passes validation | (values: any) => void | - |
| onFinishFailed | Callback when form submit fails validation | (errorInfo: ValidateErrorEntity) => void | - |
| onValuesChange | Callback when field value updates | (changedValues, allValues) => void | - |
| validateMessages | Validation message templates | ValidateMessages | - |
| scrollToFirstError | Auto scroll to first error field on submit failure | boolean | Options | false |
| others | Native attributes | HTMLAttributes<HTMLFormElement> | - |
info
About Form Layout:
horizontal: Horizontal layout, label and control on same linevertical: Vertical layout, label and control stacked vertically (default)inline: Inline layout, all form items on one line
About Form Instance:
- Use
useForm()Hook to create form instance - Form instance provides rich methods to manipulate the form
FormItem Props
| Property | Description | Type | Default |
|---|---|---|---|
| name | Field name | string | string[] | - |
| label | Label text | ReactNode | - |
| rules | Validation rules | Rule[] | - |
| required | Whether field is required | boolean | false |
| help | Help text | ReactNode | - |
| tooltip | Tooltip (shown on hover) | ReactNode | - |
| dependencies | Dependent fields | string[] | - |
| valuePropName | Value property name of child node | string | 'value' |
| initialValue | Initial value | any | - |
| others | Native attributes | HTMLAttributes<HTMLElement> | - |
info
About Validation Rules:
required: Whether field is requiredtype: Field type (string,number,email,url, etc.)min/max: Minimum/maximum length or valuepattern: Regular expressionvalidator: Custom validation functionmessage: Error message
About dependencies:
- When dependent fields update, current field validation is triggered
- Commonly used for confirm password scenarios
FormList
Used to render dynamic form item lists.
<FormList name="users">
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<FormItem key={field.key} {...field}>
<Input />
</FormItem>
))}
<Button onClick={() => add()}>Add</Button>
</>
)}
</FormList>
Form Instance Methods
| Method | Description | Type |
|---|---|---|
| getFieldValue | Get value of specific field | (name: string) => any |
| getFieldsValue | Get values of all fields | () => any |
| setFieldValue | Set value of specific field | (name: string, value: any) => void |
| setFieldsValue | Set values of multiple fields | (values: any) => void |
| resetFields | Reset form | (fields?: string[]) => void |
| validateFields | Trigger form validation | (nameList?: string[]) => Promise<any> |
| submit | Submit form | () => void |
| scrollToField | Scroll to specific field | (name: string, options?: Options) => void |
Usage Guidelines
Form Validation
Common validation rule examples:
// Required
{ required: true, message: 'This field is required' }
// Email
{ type: 'email', message: 'Please enter a valid email address' }
// Length limit
{ min: 3, max: 20, message: 'Length must be between 3 and 20 characters' }
// Regular expression
{ pattern: /^1[3-9]\d{9}$/, message: 'Please enter a valid phone number' }
// Custom validation
{
validator: (_, value) => {
if (value && value < 18) {
return Promise.reject('Age must be greater than 18');
}
return Promise.resolve();
}
}
Dynamic Forms
Implementing dynamic forms with FormList:
<FormList name="members">
{(fields, { add, remove }) => (
<>
{fields.map((field, index) => (
<Row key={field.key}>
<Col span={10}>
<FormItem {...field} name={[field.name, 'name']}>
<Input />
</FormItem>
</Col>
<Col span={10}>
<FormItem {...field} name={[field.name, 'age']}>
<Input />
</FormItem>
</Col>
<Col span={4}>
<Button onClick={() => remove(field.name)}>Delete</Button>
</Col>
</Row>
))}
<Button onClick={() => add()}>Add Member</Button>
</>
)}
</FormList>
Form Linkage
Implementing form linkage via dependencies and custom validation:
<FormItem name="country" label="Country">
<Select />
</FormItem>
<FormItem
name="province"
label="Province"
dependencies={['country']}
rules={[
({ getFieldValue }) => ({
validator(_, value) {
const country = getFieldValue('country');
if (country === 'China' && !value) {
return Promise.reject('Please select province');
}
return Promise.resolve();
},
}),
]}
>
<Select />
</FormItem>