react-dynamic-form-builder-reactquery
Version:
A flexible and powerful dynamic form builder for React with Ant Design - 23 components, responsive layout, React Query integration, field dependencies, conditional fields, full TypeScript support
578 lines (509 loc) โข 15.2 kB
Markdown
# ๐ Layout & Positioning Guide
## แแแแแชแแแแแ แแแแกแ แแ แแแแแแแแแแก แกแ แฃแแ แแแแแแแแแแ
### ๐ฏ แซแแ แแแแแ แแแแชแแคแชแแ
แคแแ แแ แแงแแแแแก **Ant Design Grid System**-แก (24 column layout).
## 1๏ธโฃ Form-Level Layout
### Layout Types
```typescript
const formConfig: FormConfig = {
layout: 'vertical', // Labels แแแแแ
// layout: 'horizontal', // Labels แแแ แชแฎแแแ
// layout: 'inline', // แงแแแแแคแแ แ แแ แ แฎแแแแ
columns: 2, // แ แแแแแ แกแแแขแแ แแแแงแแก
}
```
## 2๏ธโฃ Field-Level Positioning
### Basic Span (แกแแแขแแแแก แ แแแแแแแแ)
```typescript
{
name: 'firstName',
span: 12, // แแแฎแแแแ แ แกแแแแแ (12/24)
}
{
name: 'fullWidth',
span: 24, // แกแ แฃแแ แกแแแแแ
}
{
name: 'third',
span: 8, // แแ แแ แแแกแแแแแ (8/24)
}
```
### Offset (แชแแ แแแแ แแแแแแ แแแ แชแฎแแแแแ)
```typescript
{
name: 'centered',
span: 12,
offset: 6, // 6 แกแแแขแ แชแแ แแแแแ แแแ แชแฎแแแแแ, แจแแแแแ 12 แกแแแขแ แแแแ
}
```
### Push & Pull (แแแแแแแก แแแแแแแแแแแแ)
```typescript
{
name: 'first',
span: 12,
push: 12, // แแแแแแแแแแแ แแแ แฏแแแแ 12 แกแแแขแแ
},
{
name: 'second',
span: 12,
pull: 12, // แแแแแแแแแแแ แแแ แชแฎแแแ 12 แกแแแขแแ
}
// แแก แแแแแแ แแแชแแแแแ แแแแแแแแก!
```
### Custom Styles
```typescript
{
name: 'customField',
span: 12,
style: {
padding: '0 10px',
background: '#f0f0f0',
},
formItemStyle: {
marginBottom: '32px',
border: '1px solid #ddd',
}
}
```
### Label & Wrapper Layout (Horizontal Layout-แแกแแแแก)
```typescript
{
name: 'horizontalField',
label: 'Label',
labelCol: { span: 6 }, // Label แแแแแแแก 6 แกแแแขแก
wrapperCol: { span: 18 }, // Input แแแแแแแก 18 แกแแแขแก
}
```
## 3๏ธโฃ แแ แแฅแขแแแฃแแ แแแแแแแแแแ
### แแแแแแแแ 1: 2-Column Layout
```typescript
const formConfig = {
columns: 2,
fields: [
{ name: 'firstName', span: 12 }, // แแแ แชแฎแแแ แกแแแขแ
{ name: 'lastName', span: 12 }, // แแแ แฏแแแแ แกแแแขแ
{ name: 'email', span: 24 }, // แกแ แฃแแ แกแแแแแ
]
}
```
### แแแแแแแแ 2: 3-Column Layout
```typescript
const formConfig = {
columns: 3,
fields: [
{ name: 'field1', span: 8 },
{ name: 'field2', span: 8 },
{ name: 'field3', span: 8 },
]
}
```
### แแแแแแแแ 3: แแแแแแแฅแกแฃแ แ Layout
```typescript
const formConfig = {
fields: [
// แกแ แฃแแ แกแแแแแ
{ name: 'title', span: 24 },
// 2 แแแแ แแแแแแ แแ
{ name: 'firstName', span: 12 },
{ name: 'lastName', span: 12 },
// 3 แแแแ แแแแแแ แแ
{ name: 'day', span: 8 },
{ name: 'month', span: 8 },
{ name: 'year', span: 8 },
// 1/3 + 2/3
{ name: 'code', span: 8 },
{ name: 'description', span: 16 },
// แชแแแขแ แจแ แแแแแแแกแแแฃแแ แแแแ
{ name: 'centered', span: 12, offset: 6 },
]
}
```
### แแแแแแแแ 4: Responsive Layout (Mobile-Friendly) โญ
```typescript
import { ResponsiveSpan } from 'react-dynamic-form-builder';
const formConfig = {
fields: [
{
name: 'responsiveField',
label: 'Responsive Field',
type: 'input',
// Mobile (xs): แกแ แฃแแ แกแแแแแ
// Tablet (sm/md): แแแฎแแแแ แ
// Desktop (lg+): แแแกแแแแแ
span: { xs: 24, sm: 12, md: 12, lg: 8 } as ResponsiveSpan,
},
{
name: 'firstName',
span: { xs: 24, sm: 12, lg: 8 },
},
{
name: 'lastName',
span: { xs: 24, sm: 12, lg: 8 },
},
{
name: 'email',
span: { xs: 24, sm: 24, lg: 8 },
}
]
}
```
### แแแแแแแแ 4.1: Responsive Offset แแ Push/Pull
```typescript
const formConfig = {
fields: [
{
name: 'centeredOnDesktop',
type: 'input',
// Mobile-แแ แกแ แฃแแ แกแแแแแ, Desktop-แแ แชแแแขแ แจแ
span: { xs: 24, lg: 12 },
offset: { xs: 0, lg: 6 }, // Desktop-แแ แชแแแขแ แแ แแแ
},
{
name: 'pushPullExample',
span: { xs: 24, md: 12 },
push: { md: 12 }, // Tablet-แแ แแ แแแแแ แแแแแแแแแแแแ
}
]
}
```
### แแแแแแแแ 5: Form with Sections
```typescript
const formConfig = {
columns: 2,
sections: [
{
title: 'Section 1',
fields: [
{ name: 'field1', span: 12 },
{ name: 'field2', span: 12 },
]
},
{
title: 'Section 2 - Full Width',
fields: [
{ name: 'field3', span: 24 },
]
}
]
}
```
## 4๏ธโฃ Grid Examples
### 24-Column Grid แแแแฃแแแแแแชแแ:
```
|--1--|--2--|--3--|--4--|--5--|--6--|--7--|--8--|--9--|--10-|--11-|--12-|--13-|--14-|--15-|--16-|--17-|--18-|--19-|--20-|--21-|--22-|--23-|--24-|
```
**span: 24** - แกแ แฃแแ แกแแแแแ
```
|============================================================================|
```
**span: 12** - แแแฎแแแแ แ
```
|=====================================| |
```
**span: 8** - แแ แแ แแแกแแแแแ
```
|========================| | |
```
**span: 6** - แแ แแ แแแแแฎแแแ
```
|==================| | | |
```
## 5๏ธโฃ Advanced Techniques
### แแกแแแแขแ แแฃแแ Layout
```typescript
{
fields: [
{ name: 'small', span: 6 },
{ name: 'large', span: 18 },
]
}
```
### แแแแแแแก แแแฏแแฃแคแแแ
```typescript
{
fields: [
{ name: 'group1field1', span: 8, group: 'group1' },
{ name: 'group1field2', span: 8, group: 'group1' },
{ name: 'group1field3', span: 8, group: 'group1' },
{ name: 'group2field1', span: 12, group: 'group2' },
{ name: 'group2field2', span: 12, group: 'group2' },
]
}
```
### CSS Grid Alternative
```typescript
{
name: 'customGrid',
span: 24,
style: {
display: 'grid',
gridTemplateColumns: 'repeat(3, 1fr)',
gap: '16px',
}
}
```
## 6๏ธโฃ Best Practices
### โ
DO:
- แแแแแแงแแแแ `columns` prop simple layouts-แแกแแแแก
- แแแแแแงแแแแ `span` แแแแแแฃแแ แแแแแกแแแแก individual control-แแกแแแแก
- แแแแชแแแแ consistency แแแแแแแแแแจแ
- แแแแแแงแแแแ `offset` centering-แแกแแแแก
- แแแแแแงแแแแ sections complex forms-แแกแแแแก
### โ DON'T:
- แแ แแแแแแงแแแแ span > 24
- แแ แแแแแแฌแงแแ mobile responsiveness
- แแ แแแแแแแแ แซแแแแแ แแแขแแแ แแฃแแ layouts
## 7๏ธโฃ Cheat Sheet
| แ แแก แแแแแ | แ แแแแ แแแแแแแ |
|-----------|---------------|
| 2 แแแแ แแแแแแ แแ | `span: 12` แแ แแแแก |
| 3 แแแแ แแแแแแ แแ | `span: 8` แงแแแแแก |
| 4 แแแแ แแแแแแ แแ | `span: 6` แงแแแแแก |
| แกแ แฃแแ แกแแแแแ | `span: 24` |
| แชแแแขแ แแ แแแ | `span: 12, offset: 6` |
| 1/3 + 2/3 | `span: 8` แแ `span: 16` |
| 1/4 + 3/4 | `span: 6` แแ `span: 18` |
## 8๏ธโฃ Live Example
```typescript
const complexForm: FormConfig = {
layout: 'vertical',
columns: 1,
sections: [
{
title: 'แแแ แแแ แแแคแแ แแแชแแ',
fields: [
// แกแ แฃแแ แกแแแแแ
{ name: 'avatar', type: 'upload', span: 24 },
// 2 แแแแ แแแแแแ แแ
{ name: 'firstName', type: 'input', span: 12 },
{ name: 'lastName', type: 'input', span: 12 },
// 3 แแแแ (แแแแแแแแแก แแแ แแฆแ)
{ name: 'day', type: 'select', span: 8, placeholder: 'DD' },
{ name: 'month', type: 'select', span: 8, placeholder: 'MM' },
{ name: 'year', type: 'select', span: 8, placeholder: 'YYYY' },
]
},
{
title: 'แกแแแแแขแแฅแขแ',
fields: [
// แกแ แฃแแ แกแแแแแ email
{ name: 'email', type: 'email', span: 24 },
// 1/3 country code + 2/3 phone
{
name: 'countryCode',
type: 'select',
span: 8,
style: { paddingRight: '8px' }
},
{
name: 'phone',
type: 'phone',
span: 16,
style: { paddingLeft: '8px' }
},
]
}
]
};
```
## 9๏ธโฃ ๐ฑ Responsive Design - Mobile-Friendly
### Breakpoint แกแแกแขแแแ
Ant Design Grid แแงแแแแแก แจแแแแแ breakpoint-แแแก:
| Breakpoint | แแแ แแแแก แแแแ | แแแฌแงแแแแแแแ | แแแแแงแแแแแ |
|-----------|-------------|-------------|------------|
| **xs** | <576px | Mobile | แกแ แฃแแ แกแแแแแ (24) |
| **sm** | โฅ576px | Large Mobile/Small Tablet | 12 แแ 24 |
| **md** | โฅ768px | Tablet | 12, 8 |
| **lg** | โฅ992px | Desktop | 8, 6, 12 |
| **xl** | โฅ1200px | Large Desktop | 6, 8 |
| **xxl** | โฅ1600px | Extra Large | 6, 4 |
### Responsive Best Practices โญ
#### 1. Mobile-First Approach
```typescript
// โ
แแแ แแ: Mobile-แแแ Desktop-แแกแแแ
{
name: 'field',
span: { xs: 24, sm: 12, lg: 8 }
// xs: mobile - แกแ แฃแแ แกแแแแแ
// sm: tablet - แแแฎแแแแ แ
// lg: desktop - แแแกแแแแแ
}
// โ แชแฃแแ: แซแแแแแ แแแแ แ breakpoint
{
name: 'field',
span: { xs: 24, sm: 20, md: 16, lg: 12, xl: 10, xxl: 8 }
}
```
#### 2. แกแแแ แแ Responsive แแแขแแ แแแแ
**แแแขแแ แแ A: แกแ แฃแแ แกแแแแแ โ แแแฎแแแแ แ โ แแแกแแแแแ**
```typescript
{
fields: [
{
name: 'name',
span: { xs: 24, sm: 12, lg: 8 },
},
{
name: 'email',
span: { xs: 24, sm: 12, lg: 8 },
},
{
name: 'phone',
span: { xs: 24, sm: 12, lg: 8 },
},
]
}
// Mobile: 3 แแแแ แแ แแแแแแแแก แฅแแแจ
// Tablet: 2 แกแแแขแแ (name/email โ phone)
// Desktop: 3 แกแแแขแแ
```
**แแแขแแ แแ B: แกแ แฃแแ แกแแแแแ โ แแแฎแแแแ แ**
```typescript
{
fields: [
{
name: 'firstName',
span: { xs: 24, md: 12 },
},
{
name: 'lastName',
span: { xs: 24, md: 12 },
},
]
}
// Mobile & Small Tablet: แแแ แขแแแแแฃแ แแ
// Desktop: 2 แกแแแขแแ
```
**แแแขแแ แแ C: Title แกแ แฃแแ, แแแแแแ responsive**
```typescript
{
fields: [
{
name: 'title',
type: 'input',
span: 24, // แงแแแแแแแแก แกแ แฃแแ แกแแแแแ
},
{
name: 'category',
span: { xs: 24, sm: 12, lg: 6 },
},
{
name: 'status',
span: { xs: 24, sm: 12, lg: 6 },
},
{
name: 'priority',
span: { xs: 24, sm: 12, lg: 6 },
},
{
name: 'assignee',
span: { xs: 24, sm: 12, lg: 6 },
},
]
}
```
#### 3. แแแแแแแฅแกแฃแ แ Responsive Form
```typescript
import { FormConfig, ResponsiveSpan } from 'react-dynamic-form-builder';
const responsiveForm: FormConfig = {
layout: 'vertical', // Mobile-แแ vertical แฃแแแแแกแแ
sections: [
{
title: 'แแแ แแแ แแแคแแ แแแชแแ',
fields: [
{
name: 'avatar',
type: 'upload',
span: 24, // แงแแแแแแแแก แกแ แฃแแ
},
{
name: 'firstName',
type: 'input',
span: { xs: 24, sm: 12 } as ResponsiveSpan,
},
{
name: 'lastName',
type: 'input',
span: { xs: 24, sm: 12 },
},
{
name: 'email',
type: 'email',
span: { xs: 24, md: 12 },
},
{
name: 'phone',
type: 'phone',
span: { xs: 24, md: 12 },
},
]
},
{
title: 'แแแกแแแแ แแ',
fields: [
{
name: 'country',
type: 'select',
span: { xs: 24, sm: 12, lg: 8 },
},
{
name: 'city',
type: 'select',
span: { xs: 24, sm: 12, lg: 8 },
},
{
name: 'district',
type: 'select',
span: { xs: 24, sm: 24, lg: 8 },
},
{
name: 'street',
type: 'input',
span: 24,
},
]
}
]
};
```
#### 4. Responsive Centering
```typescript
{
name: 'submitButton',
type: 'custom',
// Mobile: แกแ แฃแแ แกแแแแแ
// Desktop: แชแแแขแ แจแ 12 แกแแแขแ
span: { xs: 24, lg: 12 },
offset: { xs: 0, lg: 6 },
}
```
### Mobile UX Tips ๐ฑ
1. **Mobile-แแ แงแแแแแแแแก `span: 24`** - แแ แแ แแแแ แแ แ์คแแ
2. **Tablet-แแแ แแฌแงแ แแแงแแคแ** - `sm: 12` แแ `md: 12`
3. **Desktop-แแ 3-4 แกแแแขแ แแแฅแกแแแฃแ** - `lg: 8` แแ `lg: 6`
4. **Vertical layout Mobile-แแ** - แฃแแแแแกแ UX
5. **Horizontal layout Desktop-แแ** - แแแแแแแแฃแ แ แกแแแ แชแ
### แจแแฏแแแแแ
```typescript
// โ
แแแแแแฃแ แ Responsive แแแขแแ แแ
const perfectResponsive = {
fields: [
{
name: 'anyField',
span: {
xs: 24, // Mobile: แกแ แฃแแ แกแแแแแ
sm: 12, // Tablet: แแแฎแแแแ แ
lg: 8, // Desktop: แแแกแแแแแ
}
}
]
}
// Mobile First!
// แแฅแแแ แงแแแแแแแแก แฃแแแ แแคแแฅแ แแ:
// 1. แ แแแแ แแแแแแงแฃแ แแแ Mobile-แแ?
// 2. แ แแแแ แแแแแแงแฃแ แแแ Tablet-แแ?
// 3. แ แแแแ แแแแแแงแฃแ แแแ Desktop-แแ?
```
แแก แกแแกแขแแแ แแแซแแแแ **แกแ แฃแ แแแแขแ แแแก** แคแแ แแแก แแแแแแแแแแแ แแ **แแแฅแกแแแแแฃแ Responsive/Mobile-Friendly แคแฃแแฅแชแแแแแแก**! ๐จ๐ฑ