forms
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFilamentPHP Forms Generation Skill
FilamentPHP 表单生成技能
Overview
概述
This skill generates FilamentPHP v4 form schemas with proper field configurations, validation rules, relationships, and layout components.
本技能可生成具备正确字段配置、验证规则、关联关系和布局组件的FilamentPHP v4表单架构。
Documentation Reference
文档参考
CRITICAL: Before generating forms, read:
/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/forms//home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/schemas/
重要提示: 在生成表单前,请阅读:
/home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/forms//home/mwguerra/projects/mwguerra/claude-code-plugins/filament-specialist/skills/docs/references/schemas/
Workflow
工作流程
Step 1: Analyze Requirements
步骤1:分析需求
Identify:
- Field types needed
- Validation rules
- Relationships (belongsTo, hasMany, etc.)
- Layout preferences (sections, tabs, columns)
- Conditional visibility
- Custom formatting
确定:
- 所需的字段类型
- 验证规则
- 关联关系(belongsTo、hasMany等)
- 布局偏好(区块、标签页、列)
- 条件可见性
- 自定义格式化
Step 2: Read Documentation
步骤2:查阅文档
Navigate to forms documentation and extract:
- Exact field class names
- Available methods and options
- Validation integration patterns
- Relationship handling
浏览表单文档并提取:
- 准确的字段类名
- 可用的方法和选项
- 验证集成模式
- 关联关系处理方式
Step 3: Generate Schema
步骤3:生成架构
Build the form schema with proper structure:
php
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
public static function form(Form $form): Form
{
return $form
->schema([
// Fields organized in sections/fieldsets
]);
}构建结构规范的表单架构:
php
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
public static function form(Form $form): Form
{
return $form
->schema([
// Fields organized in sections/fieldsets
]);
}Schema Organization Requirement
架构组织要求
CRITICAL: All form schemas MUST be organized using layout components. Never place fields directly at the root level of a form schema.
重要提示: 所有表单架构必须使用布局组件进行组织。绝对不能将字段直接放在表单架构的根层级。
Minimum Organization Rules
最低组织规则
- Always use Sections or Fieldsets - Every form must have at least one Section or Fieldset wrapping its fields
- Group related fields - Fields that belong together logically should be in the same Section/Fieldset
- Use descriptive labels - Sections and Fieldsets should have meaningful titles
- Consider collapsibility - Make sections collapsible when forms are long
- 始终使用Section或Fieldset - 每个表单必须至少有一个Section或Fieldset来包裹字段
- 分组相关字段 - 逻辑上相关的字段应放在同一个Section/Fieldset中
- 使用描述性标签 - Section和Fieldset应具有有意义的标题
- 考虑可折叠性 - 当表单内容较长时,将区块设置为可折叠
Recommended Hierarchy
推荐层级结构
Form Schema
├── Section: "Primary Information"
│ ├── Fieldset: "Basic Details" (optional grouping)
│ │ ├── TextInput: name
│ │ └── TextInput: email
│ └── Fieldset: "Contact" (optional grouping)
│ ├── TextInput: phone
│ └── TextInput: address
├── Section: "Settings"
│ ├── Toggle: is_active
│ └── Select: status
└── Section: "Media" (collapsible)
└── FileUpload: avatarForm Schema
├── Section: "Primary Information"
│ ├── Fieldset: "Basic Details" (optional grouping)
│ │ ├── TextInput: name
│ │ └── TextInput: email
│ └── Fieldset: "Contact" (optional grouping)
│ ├── TextInput: phone
│ └── TextInput: address
├── Section: "Settings"
│ ├── Toggle: is_active
│ └── Select: status
└── Section: "Media" (collapsible)
└── FileUpload: avatarBad Example (DO NOT DO THIS)
错误示例(严禁这样做)
php
// ❌ WRONG: Fields at root level without organization
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('name'),
TextInput::make('email'),
TextInput::make('phone'),
Toggle::make('is_active'),
FileUpload::make('avatar'),
]);
}php
// ❌ WRONG: Fields at root level without organization
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('name'),
TextInput::make('email'),
TextInput::make('phone'),
Toggle::make('is_active'),
FileUpload::make('avatar'),
]);
}Good Example (ALWAYS DO THIS)
正确示例(必须这样做)
php
// ✅ CORRECT: Fields organized in sections
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('Personal Information')
->description('Basic user details')
->schema([
TextInput::make('name')
->required()
->maxLength(255),
TextInput::make('email')
->email()
->required(),
TextInput::make('phone')
->tel(),
]),
Section::make('Settings')
->schema([
Toggle::make('is_active')
->label('Active')
->default(true),
]),
Section::make('Profile Image')
->collapsible()
->schema([
FileUpload::make('avatar')
->image()
->disk('public')
->directory('avatars'),
]),
]);
}php
// ✅ CORRECT: Fields organized in sections
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('Personal Information')
->description('Basic user details')
->schema([
TextInput::make('name')
->required()
->maxLength(255),
TextInput::make('email')
->email()
->required(),
TextInput::make('phone')
->tel(),
]),
Section::make('Settings')
->schema([
Toggle::make('is_active')
->label('Active')
->default(true),
]),
Section::make('Profile Image')
->collapsible()
->schema([
FileUpload::make('avatar')
->image()
->disk('public')
->directory('avatars'),
]),
]);
}When to Use Section vs Fieldset
Section与Fieldset的使用场景区分
| Component | Use Case |
|---|---|
| Section | Major logical groupings, can have description, icon, collapsible |
| Fieldset | Smaller sub-groupings within a section, lighter visual weight |
| Tabs | When sections are numerous and would cause scrolling |
| Grid | Column layout within sections (not a replacement for sections) |
| 组件 | 使用场景 |
|---|---|
| Section | 主要逻辑分组,可包含描述、图标、可折叠属性 |
| Fieldset | Section内的小型子分组,视觉权重更轻 |
| Tabs | 当区块数量过多导致需要滚动时使用 |
| Grid | Section内的列布局(不能替代Section) |
Complex Form Example
复杂表单示例
php
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('Product Details')
->icon('heroicon-o-cube')
->schema([
Fieldset::make('Basic Information')
->schema([
TextInput::make('name')
->required()
->maxLength(255),
TextInput::make('sku')
->required()
->unique(ignoreRecord: true),
])
->columns(2),
Fieldset::make('Pricing')
->schema([
TextInput::make('price')
->numeric()
->prefix('$')
->required(),
TextInput::make('compare_at_price')
->numeric()
->prefix('$'),
])
->columns(2),
RichEditor::make('description')
->columnSpanFull(),
]),
Section::make('Inventory')
->icon('heroicon-o-archive-box')
->collapsible()
->schema([
TextInput::make('quantity')
->numeric()
->default(0),
Toggle::make('track_inventory')
->default(true),
]),
Section::make('Media')
->icon('heroicon-o-photo')
->collapsible()
->collapsed()
->schema([
FileUpload::make('images')
->multiple()
->image()
->reorderable(),
]),
]);
}php
public static function form(Form $form): Form
{
return $form
->schema([
Section::make('Product Details')
->icon('heroicon-o-cube')
->schema([
Fieldset::make('Basic Information')
->schema([
TextInput::make('name')
->required()
->maxLength(255),
TextInput::make('sku')
->required()
->unique(ignoreRecord: true),
])
->columns(2),
Fieldset::make('Pricing')
->schema([
TextInput::make('price')
->numeric()
->prefix('$')
->required(),
TextInput::make('compare_at_price')
->numeric()
->prefix('$'),
])
->columns(2),
RichEditor::make('description')
->columnSpanFull(),
]),
Section::make('Inventory')
->icon('heroicon-o-archive-box')
->collapsible()
->schema([
TextInput::make('quantity')
->numeric()
->default(0),
Toggle::make('track_inventory')
->default(true),
]),
Section::make('Media')
->icon('heroicon-o-photo')
->collapsible()
->collapsed()
->schema([
FileUpload::make('images')
->multiple()
->image()
->reorderable(),
]),
]);
}Complete Field Reference
完整字段参考
Text Input Fields
文本输入字段
php
// Basic text input
TextInput::make('name')
->required()
->maxLength(255)
->placeholder('Enter name...')
->helperText('This will be displayed publicly')
->prefixIcon('heroicon-o-user');
// Email input
TextInput::make('email')
->email()
->required()
->unique(ignoreRecord: true);
// Password input
TextInput::make('password')
->password()
->required()
->confirmed()
->minLength(8);
// Numeric input
TextInput::make('price')
->numeric()
->prefix('$')
->minValue(0)
->maxValue(10000)
->step(0.01);
// Phone input
TextInput::make('phone')
->tel()
->telRegex('/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\.\/0-9]*$/');
// URL input
TextInput::make('website')
->url()
->suffixIcon('heroicon-o-globe-alt');php
// Basic text input
TextInput::make('name')
->required()
->maxLength(255)
->placeholder('Enter name...')
->helperText('This will be displayed publicly')
->prefixIcon('heroicon-o-user');
// Email input
TextInput::make('email')
->email()
->required()
->unique(ignoreRecord: true);
// Password input
TextInput::make('password')
->password()
->required()
->confirmed()
->minLength(8);
// Numeric input
TextInput::make('price')
->numeric()
->prefix('$')
->minValue(0)
->maxValue(10000)
->step(0.01);
// Phone input
TextInput::make('phone')
->tel()
->telRegex('/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\.\/0-9]*$/');
// URL input
TextInput::make('website')
->url()
->suffixIcon('heroicon-o-globe-alt');Textarea Fields
文本域字段
php
// Basic textarea
Textarea::make('description')
->rows(5)
->cols(20)
->minLength(10)
->maxLength(1000)
->columnSpanFull();
// Auto-resize textarea
Textarea::make('content')
->autosize()
->columnSpanFull();php
// Basic textarea
Textarea::make('description')
->rows(5)
->cols(20)
->minLength(10)
->maxLength(1000)
->columnSpanFull();
// Auto-resize textarea
Textarea::make('content')
->autosize()
->columnSpanFull();Rich Text Editors
富文本编辑器
php
// Rich editor
RichEditor::make('content')
->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'codeBlock',
'h2',
'h3',
'italic',
'link',
'orderedList',
'redo',
'strike',
'underline',
'undo',
])
->columnSpanFull();
// Markdown editor
MarkdownEditor::make('content')
->toolbarButtons([
'bold',
'bulletList',
'codeBlock',
'edit',
'italic',
'link',
'orderedList',
'preview',
'strike',
])
->columnSpanFull();php
// Rich editor
RichEditor::make('content')
->toolbarButtons([
'blockquote',
'bold',
'bulletList',
'codeBlock',
'h2',
'h3',
'italic',
'link',
'orderedList',
'redo',
'strike',
'underline',
'undo',
])
->columnSpanFull();
// Markdown editor
MarkdownEditor::make('content')
->toolbarButtons([
'bold',
'bulletList',
'codeBlock',
'edit',
'italic',
'link',
'orderedList',
'preview',
'strike',
])
->columnSpanFull();Select Fields
选择字段
php
// Basic select
Select::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->default('draft')
->required();
// Searchable select
Select::make('country')
->options(Country::pluck('name', 'id'))
->searchable()
->preload();
// Multiple select
Select::make('tags')
->multiple()
->options(Tag::pluck('name', 'id'))
->searchable();
// BelongsTo relationship
Select::make('author_id')
->relationship('author', 'name')
->searchable()
->preload()
->createOptionForm([
TextInput::make('name')
->required(),
TextInput::make('email')
->email()
->required(),
]);
// BelongsToMany relationship
Select::make('categories')
->relationship('categories', 'name')
->multiple()
->preload();php
// Basic select
Select::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->default('draft')
->required();
// Searchable select
Select::make('country')
->options(Country::pluck('name', 'id'))
->searchable()
->preload();
// Multiple select
Select::make('tags')
->multiple()
->options(Tag::pluck('name', 'id'))
->searchable();
// BelongsTo relationship
Select::make('author_id')
->relationship('author', 'name')
->searchable()
->preload()
->createOptionForm([
TextInput::make('name')
->required(),
TextInput::make('email')
->email()
->required(),
]);
// BelongsToMany relationship
Select::make('categories')
->relationship('categories', 'name')
->multiple()
->preload();Boolean Fields
布尔字段
php
// Toggle switch
Toggle::make('is_active')
->label('Active')
->default(true)
->onColor('success')
->offColor('danger');
// Checkbox
Checkbox::make('terms_accepted')
->label('I accept the terms and conditions')
->required()
->accepted();
// Checkbox list
CheckboxList::make('permissions')
->options([
'create' => 'Create',
'read' => 'Read',
'update' => 'Update',
'delete' => 'Delete',
])
->columns(2);
// Radio buttons
Radio::make('plan')
->options([
'basic' => 'Basic Plan',
'pro' => 'Pro Plan',
'enterprise' => 'Enterprise Plan',
])
->descriptions([
'basic' => 'Best for individuals',
'pro' => 'Best for small teams',
'enterprise' => 'Best for large organizations',
])
->required();php
// Toggle switch
Toggle::make('is_active')
->label('Active')
->default(true)
->onColor('success')
->offColor('danger');
// Checkbox
Checkbox::make('terms_accepted')
->label('I accept the terms and conditions')
->required()
->accepted();
// Checkbox list
CheckboxList::make('permissions')
->options([
'create' => 'Create',
'read' => 'Read',
'update' => 'Update',
'delete' => 'Delete',
])
->columns(2);
// Radio buttons
Radio::make('plan')
->options([
'basic' => 'Basic Plan',
'pro' => 'Pro Plan',
'enterprise' => 'Enterprise Plan',
])
->descriptions([
'basic' => 'Best for individuals',
'pro' => 'Best for small teams',
'enterprise' => 'Best for large organizations',
])
->required();Date and Time Fields
日期与时间字段
php
// Date picker
DatePicker::make('birth_date')
->native(false)
->displayFormat('d/m/Y')
->maxDate(now())
->closeOnDateSelection();
// DateTime picker
DateTimePicker::make('published_at')
->native(false)
->displayFormat('d/m/Y H:i')
->seconds(false)
->timezone('America/New_York');
// Time picker
TimePicker::make('start_time')
->native(false)
->seconds(false)
->minutesStep(15);php
// Date picker
DatePicker::make('birth_date')
->native(false)
->displayFormat('d/m/Y')
->maxDate(now())
->closeOnDateSelection();
// DateTime picker
DateTimePicker::make('published_at')
->native(false)
->displayFormat('d/m/Y H:i')
->seconds(false)
->timezone('America/New_York');
// Time picker
TimePicker::make('start_time')
->native(false)
->seconds(false)
->minutesStep(15);File Upload Fields
文件上传字段
php
// Basic file upload
FileUpload::make('attachment')
->disk('public')
->directory('attachments')
->acceptedFileTypes(['application/pdf', 'image/*'])
->maxSize(10240)
->downloadable()
->openable();
// Image upload with preview
FileUpload::make('avatar')
->image()
->imageEditor()
->circleCropper()
->disk('public')
->directory('avatars')
->visibility('public');
// Multiple files
FileUpload::make('gallery')
->multiple()
->reorderable()
->appendFiles()
->image()
->disk('public')
->directory('gallery');
// Spatie Media Library
SpatieMediaLibraryFileUpload::make('images')
->collection('images')
->multiple()
->reorderable();php
// Basic file upload
FileUpload::make('attachment')
->disk('public')
->directory('attachments')
->acceptedFileTypes(['application/pdf', 'image/*'])
->maxSize(10240)
->downloadable()
->openable();
// Image upload with preview
FileUpload::make('avatar')
->image()
->imageEditor()
->circleCropper()
->disk('public')
->directory('avatars')
->visibility('public');
// Multiple files
FileUpload::make('gallery')
->multiple()
->reorderable()
->appendFiles()
->image()
->disk('public')
->directory('gallery');
// Spatie Media Library
SpatieMediaLibraryFileUpload::make('images')
->collection('images')
->multiple()
->reorderable();Complex Fields
复杂字段
php
// Repeater (HasMany inline editing)
Repeater::make('items')
->relationship()
->schema([
TextInput::make('name')
->required(),
TextInput::make('quantity')
->numeric()
->required(),
TextInput::make('price')
->numeric()
->prefix('$'),
])
->columns(3)
->defaultItems(1)
->addActionLabel('Add Item')
->reorderable()
->collapsible();
// Builder (flexible content)
Builder::make('content')
->blocks([
Builder\Block::make('heading')
->schema([
TextInput::make('content')
->label('Heading')
->required(),
Select::make('level')
->options([
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
]),
]),
Builder\Block::make('paragraph')
->schema([
RichEditor::make('content')
->required(),
]),
Builder\Block::make('image')
->schema([
FileUpload::make('url')
->image()
->required(),
TextInput::make('alt')
->label('Alt text'),
]),
])
->columnSpanFull();
// Key-Value pairs
KeyValue::make('metadata')
->keyLabel('Property')
->valueLabel('Value')
->addActionLabel('Add Property')
->reorderable();
// Tags input
TagsInput::make('tags')
->suggestions([
'laravel',
'filament',
'php',
])
->splitKeys(['Tab', ',']);php
// Repeater (HasMany inline editing)
Repeater::make('items')
->relationship()
->schema([
TextInput::make('name')
->required(),
TextInput::make('quantity')
->numeric()
->required(),
TextInput::make('price')
->numeric()
->prefix('$'),
])
->columns(3)
->defaultItems(1)
->addActionLabel('Add Item')
->reorderable()
->collapsible();
// Builder (flexible content)
Builder::make('content')
->blocks([
Builder\Block::make('heading')
->schema([
TextInput::make('content')
->label('Heading')
->required(),
Select::make('level')
->options([
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
]),
]),
Builder\Block::make('paragraph')
->schema([
RichEditor::make('content')
->required(),
]),
Builder\Block::make('image')
->schema([
FileUpload::make('url')
->image()
->required(),
TextInput::make('alt')
->label('Alt text'),
]),
])
->columnSpanFull();
// Key-Value pairs
KeyValue::make('metadata')
->keyLabel('Property')
->valueLabel('Value')
->addActionLabel('Add Property')
->reorderable();
// Tags input
TagsInput::make('tags')
->suggestions([
'laravel',
'filament',
'php',
])
->splitKeys(['Tab', ',']);Hidden and Special Fields
隐藏与特殊字段
php
// Hidden field
Hidden::make('user_id')
->default(auth()->id());
// Placeholder (display only)
Placeholder::make('created_at')
->label('Created')
->content(fn ($record): string => $record?->created_at?->diffForHumans() ?? '-');
// View field (custom blade view)
View::make('custom-field')
->view('filament.forms.custom-field');php
// Hidden field
Hidden::make('user_id')
->default(auth()->id());
// Placeholder (display only)
Placeholder::make('created_at')
->label('Created')
->content(fn ($record): string => $record?->created_at?->diffForHumans() ?? '-');
// View field (custom blade view)
View::make('custom-field')
->view('filament.forms.custom-field');Layout Components
布局组件
Section
Section
php
Section::make('Personal Information')
->description('Enter your personal details')
->icon('heroicon-o-user')
->collapsible()
->collapsed(false)
->schema([
// Fields
]);php
Section::make('Personal Information')
->description('Enter your personal details')
->icon('heroicon-o-user')
->collapsible()
->collapsed(false)
->schema([
// Fields
]);Fieldset
Fieldset
php
Fieldset::make('Address')
->schema([
TextInput::make('street'),
TextInput::make('city'),
TextInput::make('state'),
TextInput::make('zip'),
])
->columns(2);php
Fieldset::make('Address')
->schema([
TextInput::make('street'),
TextInput::make('city'),
TextInput::make('state'),
TextInput::make('zip'),
])
->columns(2);Tabs
Tabs
php
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('General')
->icon('heroicon-o-information-circle')
->schema([
// General fields
]),
Tabs\Tab::make('Media')
->icon('heroicon-o-photo')
->schema([
// Media fields
]),
Tabs\Tab::make('SEO')
->icon('heroicon-o-magnifying-glass')
->schema([
// SEO fields
]),
])
->columnSpanFull();php
Tabs::make('Tabs')
->tabs([
Tabs\Tab::make('General')
->icon('heroicon-o-information-circle')
->schema([
// General fields
]),
Tabs\Tab::make('Media')
->icon('heroicon-o-photo')
->schema([
// Media fields
]),
Tabs\Tab::make('SEO')
->icon('heroicon-o-magnifying-glass')
->schema([
// SEO fields
]),
])
->columnSpanFull();Grid and Columns
网格与列
php
Grid::make()
->schema([
TextInput::make('first_name')
->columnSpan(1),
TextInput::make('last_name')
->columnSpan(1),
TextInput::make('email')
->columnSpanFull(),
])
->columns(2);php
Grid::make()
->schema([
TextInput::make('first_name')
->columnSpan(1),
TextInput::make('last_name')
->columnSpan(1),
TextInput::make('email')
->columnSpanFull(),
])
->columns(2);Split Layout
拆分布局
php
Split::make([
Section::make('Main Content')
->schema([
// Primary fields
]),
Section::make('Sidebar')
->schema([
// Secondary fields
])
->grow(false),
]);php
Split::make([
Section::make('Main Content')
->schema([
// Primary fields
]),
Section::make('Sidebar')
->schema([
// Secondary fields
])
->grow(false),
]);Validation
验证
php
TextInput::make('email')
->email()
->required()
->unique(table: User::class, ignoreRecord: true)
->rules(['required', 'email', 'max:255']);
TextInput::make('slug')
->required()
->unique(ignoreRecord: true)
->rules([
fn (): Closure => function (string $attribute, $value, Closure $fail) {
if (str_contains($value, ' ')) {
$fail('Slug cannot contain spaces.');
}
},
]);php
TextInput::make('email')
->email()
->required()
->unique(table: User::class, ignoreRecord: true)
->rules(['required', 'email', 'max:255']);
TextInput::make('slug')
->required()
->unique(ignoreRecord: true)
->rules([
fn (): Closure => function (string $attribute, $value, Closure $fail) {
if (str_contains($value, ' ')) {
$fail('Slug cannot contain spaces.');
}
},
]);Conditional Visibility
条件可见性
php
Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
])
->live();
TextInput::make('company_name')
->visible(fn (Get $get): bool => $get('type') === 'company');
TextInput::make('tax_id')
->hidden(fn (Get $get): bool => $get('type') !== 'company');php
Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
])
->live();
TextInput::make('company_name')
->visible(fn (Get $get): bool => $get('type') === 'company');
TextInput::make('tax_id')
->hidden(fn (Get $get): bool => $get('type') !== 'company');Output
输出结果
Generated forms include:
- Proper imports (including Section, Fieldset as needed)
- Type declarations
- Schema organized in Sections/Fieldsets (mandatory)
- Validation rules
- Layout structure with columns where appropriate
- Relationship handling
- Conditional logic
- Collapsible sections for optional/secondary content
生成的表单包含:
- 正确的导入语句(包括所需的Section、Fieldset等)
- 类型声明
- 基于Section/Fieldset组织的架构(必填)
- 验证规则
- 合理使用列的布局结构
- 关联关系处理
- 条件逻辑
- 针对可选/次要内容的可折叠区块