| name | Formily Ant Design Components |
| description | This skill should be used when the user asks to "use formily with ant design", "formily antd components", "formily ant design integration", "formily form layout", "formily form.item", "formily antd forms", or "integrate formily with ant design". |
| version | 1.0.0 |
Formily Ant Design Components
This skill provides comprehensive guidance for integrating Formily with Ant Design components. Focus on form layouts, field components, validation, and common patterns when using Formily with Ant Design in TypeScript.
Installation
Install Formily Ant Design packages:
npm install @formily/antd @formily/core @formily/react
npm install antd
Install required types for TypeScript:
npm install -D @types/react @types/react-dom
Basic Setup
Configure Formily with Ant Design:
import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Form, FormItem, Input, Select, DatePicker } from '@formily/antd'
// Create schema field component
const SchemaField = createSchemaField({
components: {
Form,
FormItem,
Input,
Select,
DatePicker
}
})
// Create form instance
const form = createForm()
Form Layout Patterns
Basic Form Layout
import { Form } from '@formily/antd'
const BasicForm = () => {
return (
<Form form={form} labelCol={6} wrapperCol={16}>
{/* Form fields */}
</Form>
)
}
Grid Layout
import { Form } from '@formily/antd'
import { Row, Col } from 'antd'
const GridLayout = () => {
return (
<Form form={form}>
<Row gutter={16}>
<Col span={12}>
<SchemaField name="firstName">
<FormItem label="First Name">
<Input placeholder="Enter first name" />
</FormItem>
</SchemaField>
</Col>
<Col span={12}>
<SchemaField name="lastName">
<FormItem label="Last Name">
<Input placeholder="Enter last name" />
</FormItem>
</SchemaField>
</Col>
</Row>
</Form>
)
}
Tabs Layout
import { Form } from '@formily/antd'
import { Tabs } from 'antd'
const { TabPane } = Tabs
const TabsLayout = () => {
return (
<Form form={form}>
<Tabs defaultActiveKey="basic">
<TabPane tab="Basic Info" key="basic">
<SchemaField name="name">
<FormItem label="Name">
<Input />
</FormItem>
</SchemaField>
</TabPane>
<TabPane tab="Advanced" key="advanced">
<SchemaField name="settings">
<FormItem label="Settings">
<Input />
</FormItem>
</SchemaField>
</TabPane>
</Tabs>
</Form>
)
}
Common Ant Design Components
Input Components
// Text Input
<SchemaField name="username">
<FormItem label="Username">
<Input
placeholder="Enter username"
prefix={<UserOutlined />}
/>
</FormItem>
</SchemaField>
// Password Input
<SchemaField name="password">
<FormItem label="Password">
<Input.Password
placeholder="Enter password"
visibilityToggle
/>
</FormItem>
</SchemaField>
// Textarea
<SchemaField name="description">
<FormItem label="Description">
<Input.TextArea
rows={4}
placeholder="Enter description"
showCount
maxLength={500}
/>
</FormItem>
</SchemaField>
Select Components
// Basic Select
<SchemaField name="country">
<FormItem label="Country">
<Select placeholder="Select country">
<Select.Option value="us">United States</Select.Option>
<Select.Option value="uk">United Kingdom</Select.Option>
<Select.Option value="ca">Canada</Select.Option>
</Select>
</FormItem>
</SchemaField>
// Multi Select
<SchemaField name="skills">
<FormItem label="Skills">
<Select
mode="multiple"
placeholder="Select skills"
options={[
{ label: 'JavaScript', value: 'js' },
{ label: 'TypeScript', value: 'ts' },
{ label: 'React', value: 'react' }
]}
/>
</FormItem>
</SchemaField>
// Searchable Select
<SchemaField name="city">
<FormItem label="City">
<Select
showSearch
placeholder="Search city"
filterOption={(input, option) =>
option?.children.toLowerCase().includes(input.toLowerCase())
}
>
<Select.Option value="nyc">New York</Select.Option>
<Select.Option value="la">Los Angeles</Select.Option>
<Select.Option value="chi">Chicago</Select.Option>
</Select>
</FormItem>
</SchemaField>
Date and Time Components
import { DatePicker, TimePicker, RangePicker } from '@formily/antd'
// Date Picker
<SchemaField name="birthDate">
<FormItem label="Birth Date">
<DatePicker
style={{ width: '100%' }}
format="YYYY-MM-DD"
/>
</FormItem>
</SchemaField>
// Date Range Picker
<SchemaField name="dateRange">
<FormItem label="Date Range">
<RangePicker
style={{ width: '100%' }}
format="YYYY-MM-DD"
/>
</FormItem>
</SchemaField>
// Time Picker
<SchemaField name="appointmentTime">
<FormItem label="Appointment Time">
<TimePicker
style={{ width: '100%' }}
format="HH:mm"
/>
</FormItem>
</SchemaField>
Checkbox and Radio Components
// Single Checkbox
<SchemaField name="agreeToTerms">
<FormItem>
<Checkbox>
I agree to the terms and conditions
</Checkbox>
</FormItem>
</SchemaField>
// Checkbox Group
<SchemaField name="interests">
<FormItem label="Interests">
<Checkbox.Group>
<Checkbox value="sports">Sports</Checkbox>
<Checkbox value="music">Music</Checkbox>
<Checkbox value="travel">Travel</Checkbox>
</Checkbox.Group>
</FormItem>
</SchemaField>
// Radio Group
<SchemaField name="gender">
<FormItem label="Gender">
<Radio.Group>
<Radio value="male">Male</Radio>
<Radio value="female">Female</Radio>
<Radio value="other">Other</Radio>
</Radio.Group>
</FormItem>
</SchemaField>
Number Input
import { InputNumber } from '@formily/antd
<SchemaField name="age">
<FormItem label="Age">
<InputNumber
style={{ width: '100%' }}
min={0}
max={120}
placeholder="Enter age"
/>
</FormItem>
</SchemaField>
<SchemaField name="price">
<FormItem label="Price">
<InputNumber
style={{ width: '100%' }}
min={0}
precision={2}
prefix="$"
placeholder="0.00"
/>
</FormItem>
</SchemaField>
Switch and Slider
import { Switch, Slider } from '@formily/antd
// Switch
<SchemaField name="notifications">
<FormItem label="Email Notifications">
<Switch />
</FormItem>
</SchemaField>
// Slider
<SchemaField name="volume">
<FormItem label="Volume">
<Slider
min={0}
max={100}
marks={{
0: '0',
50: '50',
100: '100'
}}
/>
</FormItem>
</SchemaField>
Form Validation with Ant Design
Built-in Validation
const form = createForm({
schema: {
type: 'object',
properties: {
email: {
type: 'string',
title: 'Email',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-validator': [
{ required: true, message: 'Email is required' },
{ format: 'email', message: 'Invalid email format' }
]
},
password: {
type: 'string',
title: 'Password',
'x-decorator': 'FormItem',
'x-component': 'Input.Password',
'x-validator': [
{ required: true, message: 'Password is required' },
{ min: 8, message: 'Password must be at least 8 characters' }
]
}
}
}
})
Custom Validation Messages
const validationSchema = {
username: {
required: true,
message: 'Username is required'
},
email: {
type: 'email',
message: 'Please enter a valid email address'
},
phone: {
pattern: /^[0-9]{10}$/,
message: 'Phone number must be 10 digits'
}
}
Schema-Driven Forms
Complete Schema Example
import React from 'react'
import { createForm } from '@formily/core'
import { FormProvider, createSchemaField } from '@formily/react'
import { Form, FormItem, Input, Select, DatePicker, Button } from '@formily/antd'
const schema = {
type: 'object',
properties: {
basicInfo: {
type: 'object',
title: 'Basic Information',
'x-decorator': 'FormItem',
'x-component': 'Card',
properties: {
firstName: {
type: 'string',
title: 'First Name',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-validator': [{ required: true, message: 'Required' }]
},
lastName: {
type: 'string',
title: 'Last Name',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-validator': [{ required: true, message: 'Required' }]
},
email: {
type: 'string',
title: 'Email',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-validator': [
{ required: true, message: 'Required' },
{ format: 'email', message: 'Invalid email' }
]
},
birthDate: {
type: 'string',
title: 'Birth Date',
'x-decorator': 'FormItem',
'x-component': 'DatePicker'
}
}
},
preferences: {
type: 'object',
title: 'Preferences',
'x-decorator': 'FormItem',
'x-component': 'Card',
properties: {
language: {
type: 'string',
title: 'Language',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
options: [
{ label: 'English', value: 'en' },
{ label: 'Spanish', value: 'es' },
{ label: 'French', value: 'fr' }
]
}
},
timezone: {
type: 'string',
title: 'Timezone',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
showSearch: true,
options: [
{ label: 'UTC-8 (PST)', value: 'utc-8' },
{ label: 'UTC-5 (EST)', value: 'utc-5' },
{ label: 'UTC+0 (GMT)', value: 'utc-0' }
]
}
}
}
}
}
}
const SchemaForm = () => {
const form = createForm()
const SchemaField = createSchemaField({
components: {
Form,
FormItem,
Input,
Select,
DatePicker,
Card,
Button
}
})
return (
<FormProvider form={form}>
<Form labelCol={6} wrapperCol={16}>
<SchemaField schema={schema} />
<Form.Item wrapperCol={{ offset: 6, span: 16 }}>
<Button type="primary" onClick={() => form.submit()}>
Submit
</Button>
</Form.Item>
</Form>
</FormProvider>
)
}
Form Actions
Submit and Reset
import { Button, Space } from 'antd'
const FormActions = () => {
const handleSubmit = async () => {
try {
await form.validate()
const values = form.values
console.log('Form submitted:', values)
} catch (errors) {
console.error('Validation errors:', errors)
}
}
const handleReset = () => {
form.reset()
}
return (
<Form.Item wrapperCol={{ offset: 6, span: 16 }}>
<Space>
<Button type="primary" onClick={handleSubmit}>
Submit
</Button>
<Button onClick={handleReset}>
Reset
</Button>
</Space>
</Form.Item>
)
}
Advanced Patterns
Dynamic Form Sections
const DynamicForm = () => {
const form = createForm({
effects: () => {
onFieldChange('hasExperience', ['value'], (field) => {
form.setFieldState('experienceDetails', state => {
state.display = field.value
})
})
}
})
return (
<Form form={form}>
<SchemaField name="hasExperience">
<FormItem>
<Checkbox>Has relevant experience</Checkbox>
</FormItem>
</SchemaField>
<SchemaField name="experienceDetails" style={{ display: 'none' }}>
<FormItem label="Experience Details">
<Input.TextArea rows={4} />
</FormItem>
</SchemaField>
</Form>
)
}
Array Fields
import { ArrayCards } from '@formily/antd
const ArrayForm = () => {
const schema = {
type: 'object',
properties: {
contacts: {
type: 'array',
title: 'Emergency Contacts',
'x-decorator': 'FormItem',
'x-component': 'ArrayCards',
'x-component-props': {
title: 'Contact',
addition: 'Add Contact'
},
items: {
type: 'object',
properties: {
name: {
type: 'string',
title: 'Name',
'x-decorator': 'FormItem',
'x-component': 'Input'
},
phone: {
type: 'string',
title: 'Phone',
'x-decorator': 'FormItem',
'x-component': 'Input'
},
relationship: {
type: 'string',
title: 'Relationship',
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
options: [
{ label: 'Parent', value: 'parent' },
{ label: 'Sibling', value: 'sibling' },
{ label: 'Spouse', value: 'spouse' }
]
}
}
}
}
}
}
}
const SchemaField = createSchemaField({
components: {
Form,
FormItem,
Input,
Select,
ArrayCards
}
})
return (
<FormProvider form={form}>
<Form>
<SchemaField schema={schema} />
</Form>
</FormProvider>
)
}
Additional Resources
Example Files
examples/antd-form-layouts.tsx- Complete form layout examplesexamples/validation-patterns.tsx- Advanced validation patterns
Reference Files
references/component-mapping.md- Ant Design component mapping referencereferences/styling-guide.md- Form styling and theming guide
Common Ant Design Components
- Input, Input.Password, Input.TextArea
- Select, Select.OptGroup
- DatePicker, DatePicker.RangePicker, TimePicker
- Checkbox, Checkbox.Group
- Radio, Radio.Group, Radio.Button
- Switch, Slider, InputNumber
- Upload, Rate, Mentions
Best Practices
- Use consistent spacing with
labelColandwrapperColprops - Group related fields using Card or Divider components
- Provide clear labels and placeholders for better UX
- Use proper validation messages that guide users
- Leverage Form.Item for consistent label positioning and error display
- Use Grid system for complex multi-column layouts
- Implement loading states for async operations
- Test responsive behavior on different screen sizes