@kne/react-form-antd 4.0.2 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,80 +1,1524 @@
1
-
2
1
  # react-form-antd
3
2
 
4
-
5
3
  ### 描述
6
4
 
7
5
  把 @kne/react-form 表单校验逻辑应用到antd
8
6
 
9
-
10
7
  ### 安装
11
8
 
12
9
  ```shell
13
10
  npm i --save @kne/react-form-antd
14
11
  ```
15
12
 
16
-
17
13
  ### 概述
18
14
 
19
- #### 特点
15
+ 基于 @kne/react-form 封装的 Ant Design 表单组件库,提供完整的表单校验功能和丰富的表单字段组件。
16
+
17
+ #### 核心特性
18
+
19
+ - **UI分离设计** - UI与校验逻辑分离,可适配不同UI框架
20
+ - **分级校验规则** - 支持同步/异步校验,可配置校验规则优先级
21
+ - **事件驱动架构** - 通过事件机制实现灵活扩展,支持调试模式
22
+ - **复杂表单支持** - 支持 GroupList 动态表单、嵌套表单、子表单
23
+ - **完整字段组件** - 覆盖所有常用 Ant Design 表单组件
24
+ - **国际化支持** - 内置中英文提示信息
25
+
26
+ #### 支持的组件
27
+
28
+ **表单核心**
29
+ - Form - 表单容器组件
30
+
31
+ **基础字段**
32
+ - Input / Input.Password - 文本输入框
33
+ - InputNumber - 数字输入框
34
+ - TextArea - 多行文本
35
+
36
+ **选择器**
37
+ - Select - 下拉选择器
38
+ - TreeSelect - 树形选择器
39
+ - Cascader - 级联选择器
40
+
41
+ **日期时间**
42
+ - DatePicker - 日期选择器
43
+ - TimePicker - 时间选择器
44
+ - DatePickerToday - 快捷日期选择
45
+
46
+ **多选/单选**
47
+ - Checkbox - 复选框
48
+ - CheckboxGroup - 复选框组
49
+ - RadioGroup - 单选框组
50
+
51
+ **其他**
52
+ - Rate - 评分
53
+ - Slider - 滑动条
54
+ - Switch - 开关
55
+
56
+ **按钮**
57
+ - SubmitButton - 提交按钮
58
+ - ResetButton - 重置按钮
59
+ - CancelButton - 取消按钮
60
+
61
+ **高级功能**
62
+ - GroupList - 动态表单列表
63
+ - preset - 全局配置
20
64
 
21
- * UI分离,支持自定义UI框架。提供了antd的组件封装 @kne/react-form-antd 和 taro的组件封装 @kne/react-form-taro
22
- * 分级校验规则配置,校验规则支持异步校验
23
- * 事件驱动,方便灵活扩展。可以通过debug选项配置,通过触发事件顺序和参数轻松调试
24
- * 支持包含Group的复杂表单,子表单
65
+ #### 快速开始
66
+
67
+ ```bash
68
+ npm install @kne/react-form-antd antd
69
+ ```
70
+
71
+ ```jsx
72
+ import Form, { Input, SubmitButton } from '@kne/react-form-antd';
73
+
74
+ function MyForm() {
75
+ return (
76
+ <Form onSubmit={(data) => console.log(data)}>
77
+ <Input name="username" label="用户名" rule="REQ" />
78
+ <SubmitButton>提交</SubmitButton>
79
+ </Form>
80
+ );
81
+ }
82
+ ```
83
+
84
+ #### 校验规则
85
+
86
+ ```jsx
87
+ <Input name="field" rule="REQ" /> // 必填
88
+ <Input name="field" rule="LEN-2-10" /> // 长度2-10
89
+ <Input name="field" rule="REQ LEN-2-10" /> // 组合规则
90
+ ```
25
91
 
26
92
 
27
93
  ### 示例
28
94
 
29
95
  #### 示例代码
30
96
 
31
- - 这里填写示例标题
32
- - 这里填写示例说明
33
- - reactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
97
+ - 基础表单
98
+ - 展示表单的基本使用方法,包含各种表单字段和校验规则
99
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
100
+
101
+ ```jsx
102
+ const {default: Form, Input, InputNumber, Select, TextArea, Switch, Checkbox, CheckboxGroup, RadioGroup, DatePicker, TimePicker, Rate, Slider, SubmitButton} = _ReactFormAntd;
103
+ const {Flex, Space, Divider} = antd;
104
+ const {useState} = React;
105
+
106
+ const BaseExample = () => {
107
+ const [formData, setFormData] = useState(null);
108
+ return (
109
+ <Flex vertical gap={24}>
110
+ <Form
111
+ onSubmit={(data) => {
112
+ console.log('表单提交数据:', data);
113
+ setFormData(data);
114
+ }}
115
+ >
116
+ <Flex vertical gap={16}>
117
+ <Input name="username" label="用户名" rule="REQ" placeholder="请输入用户名" />
118
+ <Input.Password name="password" label="密码" rule="REQ LEN-6-20" placeholder="请输入6-20位密码" />
119
+ <InputNumber name="age" label="年龄" rule="REQ NUM" min={0} max={150} placeholder="请输入年龄" />
120
+ <Select
121
+ name="gender"
122
+ label="性别"
123
+ rule="REQ"
124
+ placeholder="请选择性别"
125
+ options={[
126
+ {label: '男', value: 'male'},
127
+ {label: '女', value: 'female'}
128
+ ]}
129
+ />
130
+ <TextArea name="description" label="个人简介" placeholder="请输入个人简介" rows={3} />
131
+ <RadioGroup name="status" label="状态" rule="REQ" options={[{label: '启用', value: 1}, {label: '禁用', value: 0}]} />
132
+ <CheckboxGroup
133
+ name="hobbies"
134
+ label="兴趣爱好"
135
+ options={[
136
+ {label: '阅读', value: 'reading'},
137
+ {label: '运动', value: 'sports'},
138
+ {label: '音乐', value: 'music'},
139
+ {label: '旅行', value: 'travel'}
140
+ ]}
141
+ />
142
+ <Switch name="subscribe" label="订阅通知" />
143
+ <Rate name="rating" label="评分" allowHalf />
144
+ <Slider name="progress" label="进度" />
145
+ <DatePicker name="birthday" label="出生日期" rule="REQ" />
146
+ <TimePicker name="appointmentTime" label="预约时间" />
147
+ <SubmitButton>提交表单</SubmitButton>
148
+ </Flex>
149
+ </Form>
150
+ {formData && (
151
+ <>
152
+ <Divider>提交数据</Divider>
153
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
154
+ </>
155
+ )}
156
+ </Flex>
157
+ );
158
+ };
159
+
160
+ render(<BaseExample />);
161
+
162
+ ```
163
+
164
+ - 表单类型和尺寸
165
+ - 展示表单的不同类型(default/inline/inner)和尺寸(small/middle/large)
166
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
167
+
168
+ ```jsx
169
+ const {default: Form, Input, SubmitButton} = _ReactFormAntd;
170
+ const {Flex, Card, Space} = antd;
171
+
172
+ const FormTypeExample = () => {
173
+ return (<Flex vertical gap={24}>
174
+ <Card title="Default 类型(默认)" size="small">
175
+ <Form type="default">
176
+ <Flex gap={16} vertical>
177
+ <Input name="name" label="姓名" rule="REQ"/>
178
+ <Input name="email" label="邮箱" rule="REQ"/>
179
+ </Flex>
180
+ <SubmitButton>提交</SubmitButton>
181
+ </Form>
182
+ </Card>
183
+
184
+ <Card title="Inline 类型(行内表单)" size="small">
185
+ <Form type="inline">
186
+ <Space wrap>
187
+ <Input name="keyword" label="关键词"/>
188
+ <Input name="author" label="作者"/>
189
+ </Space>
190
+ <SubmitButton style={{marginLeft: 8}}>搜索</SubmitButton>
191
+ </Form>
192
+ </Card>
193
+
194
+ <Card title="Inner 类型(内嵌表单)" size="small">
195
+ <Form type="inner">
196
+ <Flex gap={16} vertical>
197
+ <Input name="title" label="标题" rule="REQ"/>
198
+ <Input name="content" label="内容"/>
199
+ <SubmitButton>提交</SubmitButton>
200
+ </Flex>
201
+ </Form>
202
+ </Card>
203
+
204
+ <Card title="不同尺寸" size="small">
205
+ <Flex vertical gap={16}>
206
+ <Form size="small">
207
+ <Input name="smallField" label="Small 尺寸"/>
208
+ </Form>
209
+ <Form size="middle">
210
+ <Input name="middleField" label="Middle 尺寸(默认)"/>
211
+ </Form>
212
+ <Form size="large">
213
+ <Input name="largeField" label="Large 尺寸"/>
214
+ </Form>
215
+ </Flex>
216
+ </Card>
217
+ </Flex>);
218
+ };
219
+
220
+ render(<FormTypeExample/>);
221
+
222
+ ```
223
+
224
+ - 输入框组件
225
+ - 展示Input和InputNumber组件的各种用法
226
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
227
+
228
+ ```jsx
229
+ const {Input, InputNumber, TextArea} = _ReactFormAntd;
230
+ const {default: Form, SubmitButton} = _ReactFormAntd;
231
+ const {Flex, Card, Space, Divider} = antd;
232
+ const {useState} = React;
233
+
234
+ const InputExample = () => {
235
+ const [formData, setFormData] = useState(null);
236
+
237
+ return (
238
+ <Flex vertical gap={24}>
239
+ <Card title="Input 文本输入框" size="small">
240
+ <Form onSubmit={setFormData}>
241
+ <Flex vertical gap={16}>
242
+ <Input name="basicInput" label="基础输入" placeholder="请输入文本" />
243
+ <Input name="requiredInput" label="必填输入" rule="REQ" placeholder="此项为必填" />
244
+ <Input name="lengthInput" label="长度限制" rule="LEN-2-10" placeholder="长度需在2-10个字符之间" />
245
+ <Input name="realtimeInput" label="实时校验" realtime rule="REQ" placeholder="输入时实时校验" />
246
+ <Input.Password name="password" label="密码输入" rule="REQ LEN-6-20" placeholder="请输入6-20位密码" />
247
+ <Input.Password
248
+ name="confirmPassword"
249
+ label="确认密码"
250
+ rule="REQ LEN-6-20"
251
+ placeholder="请再次输入密码"
252
+ />
253
+ <Divider>带前缀/后缀</Divider>
254
+ <Input name="price" label="价格" addonBefore="¥" placeholder="请输入金额" />
255
+ <Input name="website" label="网址" addonAfter=".com" placeholder="请输入网站名称" />
256
+ </Flex>
257
+ </Form>
258
+ </Card>
259
+
260
+ <Card title="InputNumber 数字输入框" size="small">
261
+ <Form onSubmit={setFormData}>
262
+ <Flex vertical gap={16}>
263
+ <InputNumber name="basicNumber" label="基础数字" placeholder="请输入数字" />
264
+ <InputNumber name="ageNumber" label="年龄" min={0} max={150} placeholder="0-150" />
265
+ <InputNumber name="priceNumber" label="价格" min={0} step={0.01} precision={2} placeholder="请输入价格" />
266
+ <InputNumber name="quantityNumber" label="数量" min={1} max={999} step={10} placeholder="请输入数量" />
267
+ <InputNumber name="formatterNumber" label="格式化数字" formatter={(value) => &#96;¥ ${value}&#96;.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} parser={(value) => value.replace(/¥\s?|(,*)/g, '')} />
268
+ </Flex>
269
+ </Form>
270
+ </Card>
271
+
272
+ <Card title="TextArea 多行文本" size="small">
273
+ <Form onSubmit={setFormData}>
274
+ <Flex vertical gap={16}>
275
+ <TextArea name="basicTextArea" label="基础文本域" placeholder="请输入内容" rows={4} />
276
+ <TextArea name="limitedTextArea" label="字数限制" rule="LEN-0-200" placeholder="最多200字" rows={4} showCount maxLength={200} />
277
+ <TextArea name="autoTextArea" label="自适应高度" placeholder="自动调整高度" autoSize={{minRows: 2, maxRows: 6}} />
278
+ </Flex>
279
+ </Form>
280
+ </Card>
281
+
282
+ {formData && (
283
+ <Card title="表单数据" size="small">
284
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
285
+ </Card>
286
+ )}
287
+ </Flex>
288
+ );
289
+ };
290
+
291
+ render(<InputExample />);
292
+
293
+ ```
294
+
295
+ - 选择器组件
296
+ - 展示Select、TreeSelect、Cascader组件的使用方法
297
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
298
+
299
+ ```jsx
300
+ const {Select, TreeSelect, Cascader} = _ReactFormAntd;
301
+ const {default: Form, SubmitButton} = _ReactFormAntd;
302
+ const {Flex, Card, Divider} = antd;
303
+ const {useState} = React;
304
+
305
+ const SelectExample = () => {
306
+ const [formData, setFormData] = useState(null);
307
+
308
+ const treeData = [
309
+ {
310
+ title: 'Node1',
311
+ value: '0-0',
312
+ children: [
313
+ {title: 'Child Node1', value: '0-0-1'},
314
+ {title: 'Child Node2', value: '0-0-2'}
315
+ ]
316
+ },
317
+ {
318
+ title: 'Node2',
319
+ value: '0-1',
320
+ children: [
321
+ {title: 'Child Node3', value: '0-1-1'},
322
+ {title: 'Child Node4', value: '0-1-2'}
323
+ ]
324
+ }
325
+ ];
326
+
327
+ const cascaderOptions = [
328
+ {
329
+ label: '浙江省',
330
+ value: 'zhejiang',
331
+ children: [
332
+ {
333
+ label: '杭州市',
334
+ value: 'hangzhou',
335
+ children: [
336
+ {label: '西湖区', value: 'xihu'},
337
+ {label: '余杭区', value: 'yuhang'}
338
+ ]
339
+ },
340
+ {
341
+ label: '宁波市',
342
+ value: 'ningbo',
343
+ children: [
344
+ {label: '海曙区', value: 'haishu'},
345
+ {label: '江北区', value: 'jiangbei'}
346
+ ]
347
+ }
348
+ ]
349
+ },
350
+ {
351
+ label: '江苏省',
352
+ value: 'jiangsu',
353
+ children: [
354
+ {
355
+ label: '南京市',
356
+ value: 'nanjing',
357
+ children: [
358
+ {label: '玄武区', value: 'xuanwu'},
359
+ {label: '鼓楼区', value: 'gulou'}
360
+ ]
361
+ }
362
+ ]
363
+ }
364
+ ];
365
+
366
+ return (
367
+ <Flex vertical gap={24}>
368
+ <Card title="Select 选择器" size="small">
369
+ <Form onSubmit={setFormData}>
370
+ <Flex vertical gap={16}>
371
+ <Select
372
+ name="basicSelect"
373
+ label="单选"
374
+ placeholder="请选择"
375
+ options={[
376
+ {label: '选项一', value: 1},
377
+ {label: '选项二', value: 2},
378
+ {label: '选项三', value: 3}
379
+ ]}
380
+ />
381
+ <Select
382
+ name="requiredSelect"
383
+ label="必选"
384
+ rule="REQ"
385
+ placeholder="此项为必选"
386
+ options={[
387
+ {label: '选项A', value: 'a'},
388
+ {label: '选项B', value: 'b'},
389
+ {label: '选项C', value: 'c'}
390
+ ]}
391
+ />
392
+ <Select
393
+ name="multiSelect"
394
+ label="多选"
395
+ mode="multiple"
396
+ placeholder="请选择多个选项"
397
+ options={[
398
+ {label: '苹果', value: 'apple'},
399
+ {label: '香蕉', value: 'banana'},
400
+ {label: '橙子', value: 'orange'},
401
+ {label: '葡萄', value: 'grape'}
402
+ ]}
403
+ />
404
+ <Select
405
+ name="searchSelect"
406
+ label="可搜索"
407
+ showSearch
408
+ placeholder="输入关键词搜索"
409
+ filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
410
+ options={[
411
+ {label: '北京市', value: 'beijing'},
412
+ {label: '上海市', value: 'shanghai'},
413
+ {label: '广州市', value: 'guangzhou'},
414
+ {label: '深圳市', value: 'shenzhen'}
415
+ ]}
416
+ />
417
+ <Select
418
+ name="groupSelect"
419
+ label="分组选择"
420
+ placeholder="请选择"
421
+ >
422
+ <Select.OptGroup label="热门城市">
423
+ <Select.Option value="hot1">北京</Select.Option>
424
+ <Select.Option value="hot2">上海</Select.Option>
425
+ </Select.OptGroup>
426
+ <Select.OptGroup label="其他城市">
427
+ <Select.Option value="other1">杭州</Select.Option>
428
+ <Select.Option value="other2">成都</Select.Option>
429
+ </Select.OptGroup>
430
+ </Select>
431
+ </Flex>
432
+ </Form>
433
+ </Card>
434
+
435
+ <Card title="TreeSelect 树选择" size="small">
436
+ <Form onSubmit={setFormData}>
437
+ <Flex vertical gap={16}>
438
+ <TreeSelect
439
+ name="basicTreeSelect"
440
+ label="单选树"
441
+ placeholder="请选择"
442
+ treeData={treeData}
443
+ />
444
+ <TreeSelect
445
+ name="requiredTreeSelect"
446
+ label="必选树"
447
+ rule="REQ"
448
+ placeholder="此项为必选"
449
+ treeData={treeData}
450
+ />
451
+ <TreeSelect
452
+ name="multiTreeSelect"
453
+ label="多选树"
454
+ treeCheckable
455
+ placeholder="请选择多个"
456
+ treeData={treeData}
457
+ />
458
+ <TreeSelect
459
+ name="searchTreeSelect"
460
+ label="可搜索树"
461
+ showSearch
462
+ placeholder="输入关键词搜索"
463
+ treeData={treeData}
464
+ filterTreeNode={(node, value) => node.title.toLowerCase().indexOf(value.toLowerCase()) > -1}
465
+ />
466
+ </Flex>
467
+ </Form>
468
+ </Card>
469
+
470
+ <Card title="Cascader 级联选择" size="small">
471
+ <Form onSubmit={setFormData}>
472
+ <Flex vertical gap={16}>
473
+ <Cascader
474
+ name="basicCascader"
475
+ label="地区选择"
476
+ placeholder="请选择地区"
477
+ options={cascaderOptions}
478
+ />
479
+ <Cascader
480
+ name="requiredCascader"
481
+ label="必选地区"
482
+ rule="REQ"
483
+ placeholder="此项为必选"
484
+ options={cascaderOptions}
485
+ />
486
+ <Cascader
487
+ name="searchCascader"
488
+ label="可搜索"
489
+ showSearch
490
+ placeholder="支持搜索"
491
+ options={cascaderOptions}
492
+ />
493
+ </Flex>
494
+ </Form>
495
+ </Card>
496
+
497
+ {formData && (
498
+ <Card title="表单数据" size="small">
499
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
500
+ </Card>
501
+ )}
502
+ </Flex>
503
+ );
504
+ };
505
+
506
+ render(<SelectExample />);
507
+
508
+ ```
509
+
510
+ - 日期时间组件
511
+ - 展示DatePicker、TimePicker、DatePickerToday组件的使用方法
512
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
513
+
514
+ ```jsx
515
+ const {DatePicker, TimePicker, DatePickerToday} = _ReactFormAntd;
516
+ const {default: Form, SubmitButton} = _ReactFormAntd;
517
+ const {Flex, Card, Divider} = antd;
518
+ const {useState} = React;
519
+
520
+ const DatePickerExample = () => {
521
+ const [formData, setFormData] = useState(null);
522
+
523
+ return (
524
+ <Flex vertical gap={24}>
525
+ <Card title="DatePicker 日期选择" size="small">
526
+ <Form onSubmit={setFormData}>
527
+ <Flex vertical gap={16}>
528
+ <DatePicker name="basicDate" label="基础日期" placeholder="请选择日期" />
529
+ <DatePicker name="requiredDate" label="必选日期" rule="REQ" placeholder="此项为必选" />
530
+ <DatePicker name="formatDate" label="自定义格式" format="YYYY年MM月DD日" placeholder="请选择日期" />
531
+ <DatePicker name="disabledDate" label="禁用日期" placeholder="请选择日期" disabledDate={(current) => current && current < Date.now()} />
532
+ <Divider>日期范围选择</Divider>
533
+ <DatePicker.RangePicker name="dateRange" label="日期范围" placeholder={['开始日期', '结束日期']} />
534
+ <DatePicker.RangePicker name="requiredDateRange" label="必选范围" rule="REQ" placeholder={['开始日期', '结束日期']} />
535
+ <Divider>其他类型</Divider>
536
+ <DatePicker.MonthPicker name="monthPicker" label="月份选择" placeholder="请选择月份" />
537
+ <DatePicker.WeekPicker name="weekPicker" label="周选择" placeholder="请选择周" />
538
+ </Flex>
539
+ </Form>
540
+ </Card>
541
+
542
+ <Card title="TimePicker 时间选择" size="small">
543
+ <Form onSubmit={setFormData}>
544
+ <Flex vertical gap={16}>
545
+ <TimePicker name="basicTime" label="基础时间" placeholder="请选择时间" />
546
+ <TimePicker name="requiredTime" label="必选时间" rule="REQ" placeholder="此项为必选" />
547
+ <TimePicker name="formatTime" label="自定义格式" format="HH时mm分ss秒" placeholder="请选择时间" />
548
+ <TimePicker name="stepTime" label="步长设置" hourStep={1} minuteStep={15} secondStep={30} placeholder="请选择时间" />
549
+ <TimePicker.RangePicker name="timeRange" label="时间范围" placeholder={['开始时间', '结束时间']} />
550
+ </Flex>
551
+ </Form>
552
+ </Card>
553
+
554
+ <Card title="DatePickerToday 快捷日期" size="small">
555
+ <Form onSubmit={setFormData}>
556
+ <Flex vertical gap={16}>
557
+ <DatePickerToday name="basicToday" label="基础日期范围" />
558
+ <DatePickerToday name="requiredToday" label="必选范围" rule="REQ" />
559
+ <DatePickerToday
560
+ name="customSoFarText"
561
+ label="自定义至今文本"
562
+ soFarText="现在"
563
+ />
564
+ <DatePickerToday
565
+ name="customSoFarValue"
566
+ label="自定义至今值"
567
+ soFarText="至今"
568
+ soFarValue="PRESENT"
569
+ onChange={([start, end]) => {
570
+ if (end === 'PRESENT') {
571
+ console.log('用户选择了至今');
572
+ }
573
+ }}
574
+ />
575
+ </Flex>
576
+ </Form>
577
+ </Card>
578
+
579
+ {formData && (
580
+ <Card title="表单数据" size="small">
581
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
582
+ </Card>
583
+ )}
584
+ </Flex>
585
+ );
586
+ };
587
+
588
+ render(<DatePickerExample />);
589
+
590
+ ```
591
+
592
+ - 多选和单选组件
593
+ - 展示Checkbox、CheckboxGroup、RadioGroup组件的使用方法
594
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
595
+
596
+ ```jsx
597
+ const {Checkbox, CheckboxGroup, RadioGroup} = _ReactFormAntd;
598
+ const {default: Form, SubmitButton} = _ReactFormAntd;
599
+ const {Flex, Card, Divider, Space} = antd;
600
+ const {useState} = React;
601
+
602
+ const CheckboxRadioExample = () => {
603
+ const [formData, setFormData] = useState(null);
604
+
605
+ return (
606
+ <Flex vertical gap={24}>
607
+ <Card title="Checkbox 复选框" size="small">
608
+ <Form onSubmit={setFormData}>
609
+ <Flex vertical gap={16}>
610
+ <Checkbox name="agree" label="同意协议">我已阅读并同意《用户协议》</Checkbox>
611
+ <Checkbox name="subscribe" label="订阅">订阅新闻资讯</Checkbox>
612
+ <Checkbox name="requiredCheckbox" rule="REQ">此项为必选</Checkbox>
613
+ <Checkbox name="disabledCheckbox" disabled>禁用状态</Checkbox>
614
+ </Flex>
615
+ </Form>
616
+ </Card>
617
+
618
+ <Card title="CheckboxGroup 复选框组" size="small">
619
+ <Form onSubmit={setFormData}>
620
+ <Flex vertical gap={16}>
621
+ <CheckboxGroup
622
+ name="fruits"
623
+ label="喜欢的水果"
624
+ options={[
625
+ {label: '苹果', value: 'apple'},
626
+ {label: '香蕉', value: 'banana'},
627
+ {label: '橙子', value: 'orange'},
628
+ {label: '葡萄', value: 'grape'}
629
+ ]}
630
+ />
631
+ <CheckboxGroup
632
+ name="requiredFruits"
633
+ label="必选水果"
634
+ rule="REQ"
635
+ options={[
636
+ {label: '苹果', value: 'apple'},
637
+ {label: '香蕉', value: 'banana'}
638
+ ]}
639
+ />
640
+ <CheckboxGroup
641
+ name="interests"
642
+ label="兴趣爱好"
643
+ options={[
644
+ {label: '阅读', value: 'reading'},
645
+ {label: '运动', value: 'sports'},
646
+ {label: '音乐', value: 'music'},
647
+ {label: '旅行', value: 'travel'},
648
+ {label: '摄影', value: 'photography'},
649
+ {label: '游戏', value: 'gaming'}
650
+ ]}
651
+ />
652
+ </Flex>
653
+ </Form>
654
+ </Card>
655
+
656
+ <Card title="RadioGroup 单选框组" size="small">
657
+ <Form onSubmit={setFormData}>
658
+ <Flex vertical gap={16}>
659
+ <RadioGroup
660
+ name="gender"
661
+ label="性别"
662
+ options={[
663
+ {label: '男', value: 'male'},
664
+ {label: '女', value: 'female'}
665
+ ]}
666
+ />
667
+ <RadioGroup
668
+ name="requiredGender"
669
+ label="必选性别"
670
+ rule="REQ"
671
+ options={[
672
+ {label: '男', value: 'male'},
673
+ {label: '女', value: 'female'}
674
+ ]}
675
+ />
676
+ <RadioGroup
677
+ name="size"
678
+ label="尺寸"
679
+ optionType="button"
680
+ buttonStyle="solid"
681
+ options={[
682
+ {label: '小', value: 'small'},
683
+ {label: '中', value: 'middle'},
684
+ {label: '大', value: 'large'}
685
+ ]}
686
+ />
687
+ <RadioGroup
688
+ name="status"
689
+ label="状态"
690
+ optionType="button"
691
+ options={[
692
+ {label: '启用', value: 1},
693
+ {label: '禁用', value: 0}
694
+ ]}
695
+ />
696
+ </Flex>
697
+ </Form>
698
+ </Card>
699
+
700
+ {formData && (
701
+ <Card title="表单数据" size="small">
702
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
703
+ </Card>
704
+ )}
705
+ </Flex>
706
+ );
707
+ };
708
+
709
+ render(<CheckboxRadioExample />);
710
+
711
+ ```
712
+
713
+ - 评分和滑块组件
714
+ - 展示Rate、Slider、Switch组件的使用方法
715
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
716
+
717
+ ```jsx
718
+ const {Rate, Slider, Switch} = _ReactFormAntd;
719
+ const {default: Form, SubmitButton} = _ReactFormAntd;
720
+ const {Flex, Card, Divider} = antd;
721
+ const {useState} = React;
722
+
723
+ const RateSliderExample = () => {
724
+ const [formData, setFormData] = useState(null);
725
+
726
+ return (
727
+ <Flex vertical gap={24}>
728
+ <Card title="Rate 评分" size="small">
729
+ <Form onSubmit={setFormData}>
730
+ <Flex vertical gap={16}>
731
+ <Rate name="basicRate" label="基础评分" />
732
+ <Rate name="requiredRate" label="必选评分" rule="REQ" />
733
+ <Rate name="halfRate" label="半星评分" allowHalf />
734
+ <Rate name="customRate" label="自定义数量" count={10} />
735
+ <Rate name="disabledRate" label="禁用状态" disabled defaultValue={3} />
736
+ <Rate name="clearRate" label="可清除" allowClear />
737
+ <Rate name="charRate" label="自定义字符" character="A" allowHalf />
738
+ <Rate name="heartRate" label="心形评分" character="♥" allowHalf style={{color: 'red'}} />
739
+ </Flex>
740
+ </Form>
741
+ </Card>
742
+
743
+ <Card title="Slider 滑动条" size="small">
744
+ <Form onSubmit={setFormData}>
745
+ <Flex vertical gap={16}>
746
+ <Slider name="basicSlider" label="基础滑动条" />
747
+ <Slider name="rangeSlider" label="范围滑动条" range defaultValue={[20, 50]} />
748
+ <Slider name="stepSlider" label="步长设置" step={10} defaultValue={30} />
749
+ <Slider name="marksSlider" label="带标记" marks={{0: '0°C', 26: '26°C', 37: '37°C', 100: '100°C'}} defaultValue={37} />
750
+ <Slider name="minMaxSlider" label="范围限制" min={0} max={1000} defaultValue={100} />
751
+ <Slider name="disabledSlider" label="禁用状态" disabled defaultValue={30} />
752
+ <Slider name="verticalSlider" label="垂直方向" vertical style={{height: 200}} />
753
+ </Flex>
754
+ </Form>
755
+ </Card>
756
+
757
+ <Card title="Switch 开关" size="small">
758
+ <Form onSubmit={setFormData}>
759
+ <Flex vertical gap={16}>
760
+ <Switch name="basicSwitch" label="基础开关" />
761
+ <Switch name="requiredSwitch" label="必选开关" rule="REQ" />
762
+ <Switch name="textSwitch" label="带文字" checkedChildren="开" unCheckedChildren="关" />
763
+ <Switch name="disabledSwitch" label="禁用状态" disabled defaultChecked />
764
+ <Switch name="smallSwitch" label="小尺寸" size="small" />
765
+ <Switch name="loadingSwitch" label="加载中" loading />
766
+ </Flex>
767
+ </Form>
768
+ </Card>
769
+
770
+ {formData && (
771
+ <Card title="表单数据" size="small">
772
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
773
+ </Card>
774
+ )}
775
+ </Flex>
776
+ );
777
+ };
778
+
779
+ render(<RateSliderExample />);
780
+
781
+ ```
782
+
783
+ - 表单校验
784
+ - 展示表单的各种校验规则和自定义校验
785
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
786
+
787
+ ```jsx
788
+ const {default: Form, Input, InputNumber, SubmitButton, preset, RULES} = _ReactFormAntd;
789
+ const {Flex, Card, Divider, Alert, Space, Button, Typography} = antd;
790
+ const {Text} = Typography;
791
+ const {useState, useEffect} = React;
792
+
793
+ const ValidationExample = () => {
794
+ const [formData, setFormData] = useState(null);
795
+ const formRef = React.useRef();
796
+
797
+ // 配置自定义校验规则
798
+ useEffect(() => {
799
+ preset({
800
+ rules: Object.assign({}, RULES, {
801
+ // 自定义密码强度规则(带参数)
802
+ PASSWORD_STRENGTH: (value, level, {data}) => {
803
+ if (!value) return {result: true, errMsg: ''};
804
+ const strength = value.length >= 6 ? (value.length >= 10 ? 3 : 2) : 1;
805
+ const hasNumber = /\d/.test(value);
806
+ const hasLetter = /[a-zA-Z]/.test(value);
807
+ const hasSpecial = /[!@#$%^&*]/.test(value);
808
+ const score = (hasNumber ? 1 : 0) + (hasLetter ? 1 : 0) + (hasSpecial ? 1 : 0);
809
+ const finalStrength = strength + score;
810
+ return {
811
+ result: finalStrength >= (level || 2),
812
+ errMsg: finalStrength < (level || 2) ? &#96;密码强度不足,当前强度: ${finalStrength}&#96; : '',
813
+ data: {strength: finalStrength}
814
+ };
815
+ }, // 确认密码规则(使用数据联动)
816
+ CONFIRM_PASSWORD: (value, {data}) => {
817
+ return {
818
+ result: value === data.password, errMsg: '两次输入的密码不一致'
819
+ };
820
+ }, // 异步验证规则:用户名唯一性检查
821
+ CHECK_USERNAME: async (value, {field}) => {
822
+ if (!value) return {result: true, errMsg: ''};
823
+ // 模拟已存在的用户名
824
+ const existingUsernames = ['admin', 'test', 'user', 'root'];
825
+ console.log(&#96;开始验证用户名: ${value}&#96;);
826
+ await new Promise(resolve => setTimeout(resolve, 1000));
827
+ console.log(&#96;验证完成用户名: ${value}&#96;);
828
+ const exists = existingUsernames.includes(value.toLowerCase());
829
+ return {
830
+ result: !exists, errMsg: exists ? '该用户名已被占用' : ''
831
+ };
832
+ }
833
+ })
834
+ });
835
+ }, []);
836
+
837
+ return (<Flex vertical gap={24}>
838
+ <Card title="内置校验规则" size="small">
839
+ <Form onSubmit={setFormData}>
840
+ <Flex vertical gap={16}>
841
+ <Alert
842
+ message="内置规则: REQ(必填), TEL(手机号), EMAIL(邮箱), LEN-最小-最大(长度限制)"
843
+ type="info"
844
+ showIcon
845
+ />
846
+ <Input name="required" label="必填字段" rule="REQ" placeholder="此项为必填"/>
847
+ <Input name="tel" label="手机号" rule="REQ TEL" placeholder="请输入手机号"/>
848
+ <Input name="email" label="邮箱" rule="REQ EMAIL" placeholder="请输入邮箱"/>
849
+ <Input name="length" label="长度限制" rule="REQ LEN-2-10" placeholder="长度需在2-10个字符之间"/>
850
+ <Input name="combined" label="组合规则" rule="REQ LEN-4-20 EMAIL"
851
+ placeholder="必填 + 长度4-20 + 邮箱格式"/>
852
+ </Flex>
853
+ </Form>
854
+ </Card>
855
+
856
+ <Card title="自定义校验规则" size="small">
857
+ <Form onSubmit={setFormData}>
858
+ <Flex vertical gap={16}>
859
+ <Alert
860
+ message="通过 preset 配置自定义规则,支持正则、函数、异步函数三种形式"
861
+ type="info"
862
+ showIcon
863
+ />
864
+ <Input
865
+ name="password"
866
+ label="密码"
867
+ rule="REQ LEN-6-20 PASSWORD_STRENGTH-3"
868
+ placeholder="请输入密码(需要高强度)"
869
+ />
870
+ <Input
871
+ name="confirmPassword"
872
+ label="确认密码"
873
+ rule="REQ CONFIRM_PASSWORD"
874
+ placeholder="请再次输入密码"
875
+ />
876
+ </Flex>
877
+ </Form>
878
+ </Card>
879
+
880
+ <Card title="异步校验规则" size="small">
881
+ <Form onSubmit={setFormData}>
882
+ <Flex vertical gap={16}>
883
+ <Alert
884
+ message="支持异步验证,如远程接口校验用户名唯一性"
885
+ type="info"
886
+ showIcon
887
+ />
888
+ <Text type="secondary">已占用的用户名: admin, test, user, root</Text>
889
+ <Input
890
+ name="username"
891
+ label="用户名"
892
+ rule="REQ LEN-3-20 CHECK_USERNAME"
893
+ placeholder="请输入用户名(会异步校验唯一性)"
894
+ />
895
+ </Flex>
896
+ </Form>
897
+ </Card>
898
+
899
+ <Card title="实时校验" size="small">
900
+ <Form onSubmit={setFormData}>
901
+ <Flex vertical gap={16}>
902
+ <Alert
903
+ message="realtime 属性会在输入时实时校验,不需要等待失焦"
904
+ type="info"
905
+ showIcon
906
+ />
907
+ <Input name="realtimeInput" label="实时校验" realtime rule="REQ LEN-2-10"
908
+ placeholder="输入时实时校验"/>
909
+ <Input name="normalInput" label="普通校验" rule="REQ LEN-2-10" placeholder="失焦时校验"/>
910
+ </Flex>
911
+ </Form>
912
+ </Card>
913
+
914
+ <Card title="表单操作 API" size="small">
915
+ <Form ref={formRef} onSubmit={setFormData}>
916
+ <Flex vertical gap={16}>
917
+ <Input name="field1" label="字段1" rule="REQ" placeholder="测试字段1"/>
918
+ <Input name="field2" label="字段2" rule="LEN-0-20" placeholder="测试字段2"/>
919
+ </Flex>
920
+ </Form>
921
+ <Divider/>
922
+ <Space wrap>
923
+ <Button onClick={() => formRef.current?.setFormData({field1: '预设值', field2: '测试数据'})}>
924
+ 设置表单值
925
+ </Button>
926
+ <Button onClick={() => console.log('表单数据:', formRef.current?.getFormData())}>
927
+ 获取表单值
928
+ </Button>
929
+ <Button onClick={() => formRef.current?.reset()}>重置表单</Button>
930
+ <Button onClick={() => formRef.current?.validateAll()}>手动校验</Button>
931
+ </Space>
932
+ </Card>
933
+
934
+ {formData && (<Card title="提交数据" size="small">
935
+ <pre style={{
936
+ background: '#f5f5f5', padding: 12, borderRadius: 4
937
+ }}>{JSON.stringify(formData, null, 2)}</pre>
938
+ </Card>)}
939
+ </Flex>);
940
+ };
941
+
942
+ render(<ValidationExample/>);
943
+
944
+ ```
945
+
946
+ - 动态表单
947
+ - 展示GroupList动态表单的使用方法
948
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
34
949
 
35
950
  ```jsx
36
- const {Button} = antd;
37
- const {default: Form, Select, Input, Group, GroupList, SubmitButton, DatePickerToday, Rate, Slider} = reactFormAntd;
38
- const {useRef} = React;
39
-
40
- const Example = () => {
41
- const addButton = useRef();
42
- return <Form debug>
43
- <Select name="select" label="哈哈哈" options={[{label: 'sss', value: 1}]}/>
44
- <Input name="name" label="名称" realtime rule="REQ LEN-0-4"/>
45
- <Input.Password name="password" label="密码"/>
46
- <Rate name="rate" label="评分"/>
47
- <Slider name="slider" label="滑动条"/>
48
- <br/>
49
- <Input name="target[0].name" label="名称"/>
50
- <Input name="target[0].des" label="描述"/>
51
- <Input name="target[1].name" label="名称"/>
52
- <Input name="target[1].des" label="描述"/>
53
- <br/>
54
- <div>
55
- <Button onClick={() => {
56
- addButton.current.onAdd();
57
- }}>添加</Button>
58
- </div>
59
- <GroupList name="list" ref={addButton}>
60
- {({onRemove}) => {
61
- return <div>
62
- <Button onClick={onRemove}>删除</Button>
63
- <Input name="name" label="名称"/>
64
- <Input name="des" label="描述"/>
65
- </div>;
66
- }}
67
- </GroupList>
68
- <DatePickerToday label="时间" name="time" selectToday={true}/>
69
- <SubmitButton>提交</SubmitButton>
70
- </Form>
951
+ const {default: Form, Input, Select, GroupList, SubmitButton} = _ReactFormAntd;
952
+ const {Flex, Card, Space, Button, Divider} = antd;
953
+ const {useState, useRef} = React;
954
+
955
+ const GroupListExample = () => {
956
+ const [formData, setFormData] = useState(null);
957
+ const addButtonRef = useRef();
958
+
959
+ return (
960
+ <Flex vertical gap={24}>
961
+ <Card title="基础动态表单" size="small">
962
+ <Form onSubmit={setFormData}>
963
+ <Flex vertical gap={16}>
964
+ <GroupList name="members">
965
+ {({index, onRemove}) => (
966
+ <Space key={index} style={{display: 'flex', marginBottom: 8}} align="baseline">
967
+ <span>成员 {index + 1}:</span>
968
+ <Input name="name" placeholder="姓名" rule="REQ" />
969
+ <Input name="email" placeholder="邮箱" rule="REQ" />
970
+ <Button danger onClick={onRemove}>删除</Button>
971
+ </Space>
972
+ )}
973
+ </GroupList>
974
+ <SubmitButton>提交</SubmitButton>
975
+ </Flex>
976
+ </Form>
977
+ </Card>
978
+
979
+ <Card title="复杂动态表单" size="small">
980
+ <Form onSubmit={setFormData}>
981
+ <Flex vertical gap={16}>
982
+ <Space>
983
+ <Button type="primary" onClick={() => addButtonRef.current?.onAdd()}>
984
+ 添加联系人
985
+ </Button>
986
+ </Space>
987
+ <GroupList name="contacts" ref={addButtonRef} defaultLength={1}>
988
+ {({index, onRemove, onAdd}) => (
989
+ <Card key={index} title={&#96;联系人 ${index + 1}&#96;} size="small" extra={<Button danger size="small" onClick={onRemove}>删除</Button>}>
990
+ <Flex vertical gap={12}>
991
+ <Input name="name" label="姓名" rule="REQ" placeholder="请输入姓名" />
992
+ <Input name="phone" label="电话" rule="REQ" placeholder="请输入电话" />
993
+ <Input name="email" label="邮箱" placeholder="请输入邮箱" />
994
+ <Select
995
+ name="type"
996
+ label="类型"
997
+ rule="REQ"
998
+ placeholder="请选择类型"
999
+ options={[
1000
+ {label: '主要联系人', value: 'primary'},
1001
+ {label: '次要联系人', value: 'secondary'},
1002
+ {label: '紧急联系人', value: 'emergency'}
1003
+ ]}
1004
+ />
1005
+ <Input name="address" label="地址" placeholder="请输入地址" />
1006
+ </Flex>
1007
+ </Card>
1008
+ )}
1009
+ </GroupList>
1010
+ <SubmitButton>提交</SubmitButton>
1011
+ </Flex>
1012
+ </Form>
1013
+ </Card>
1014
+
1015
+ <Card title="嵌套表单" size="small">
1016
+ <Form onSubmit={setFormData}>
1017
+ <Flex vertical gap={16}>
1018
+ <Input name="projectName" label="项目名称" rule="REQ" placeholder="请输入项目名称" />
1019
+ <Divider>项目成员</Divider>
1020
+ <GroupList name="team">
1021
+ {({index, onRemove}) => (
1022
+ <Card key={index} size="small" title={&#96;成员 ${index + 1}&#96;} extra={<Button danger size="small" onClick={onRemove}>删除</Button>}>
1023
+ <Flex vertical gap={12}>
1024
+ <Input name="memberName" label="成员姓名" rule="REQ" />
1025
+ <Select
1026
+ name="role"
1027
+ label="角色"
1028
+ rule="REQ"
1029
+ options={[
1030
+ {label: '负责人', value: 'leader'},
1031
+ {label: '开发', value: 'developer'},
1032
+ {label: '测试', value: 'tester'}
1033
+ ]}
1034
+ />
1035
+ <GroupList name="tasks">
1036
+ {({index: taskIndex, onRemove: taskRemove}) => (
1037
+ <Space key={taskIndex} style={{display: 'flex', alignItems: 'center'}}>
1038
+ <span>任务 {taskIndex + 1}:</span>
1039
+ <Input name="taskName" placeholder="任务名称" rule="REQ" />
1040
+ <Button danger size="small" onClick={taskRemove}>删除</Button>
1041
+ </Space>
1042
+ )}
1043
+ </GroupList>
1044
+ </Flex>
1045
+ </Card>
1046
+ )}
1047
+ </GroupList>
1048
+ <SubmitButton>提交</SubmitButton>
1049
+ </Flex>
1050
+ </Form>
1051
+ </Card>
1052
+
1053
+ {formData && (
1054
+ <Card title="表单数据" size="small">
1055
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4, maxHeight: 300, overflow: 'auto'}}>{JSON.stringify(formData, null, 2)}</pre>
1056
+ </Card>
1057
+ )}
1058
+ </Flex>
1059
+ );
71
1060
  };
72
1061
 
73
- render(<Example/>);
1062
+ render(<GroupListExample />);
74
1063
 
75
1064
  ```
76
1065
 
1066
+ - 表单按钮
1067
+ - 展示SubmitButton、ResetButton、CancelButton的使用方法
1068
+ - _ReactFormAntd(@kne/current-lib_react-form-antd),(@kne/current-lib_react-form-antd/dist/index.css),antd(antd)
1069
+
1070
+ ```jsx
1071
+ const {default: Form, Input, SubmitButton, ResetButton, CancelButton} = _ReactFormAntd;
1072
+ const {Flex, Card, Space, Divider, message, Button, Alert} = antd;
1073
+ const {useState} = React;
1074
+
1075
+ const ButtonsExample = () => {
1076
+ const [formData, setFormData] = useState(null);
1077
+ const [loading, setLoading] = useState(false);
1078
+
1079
+ const handleSubmit = (data) => {
1080
+ console.log('提交数据:', data);
1081
+ setFormData(data);
1082
+ setLoading(true);
1083
+ // 模拟异步提交
1084
+ setTimeout(() => {
1085
+ setLoading(false);
1086
+ message.success('提交成功!');
1087
+ }, 1500);
1088
+ };
1089
+
1090
+ return (
1091
+ <Flex vertical gap={24}>
1092
+ <Card title="SubmitButton 提交按钮" size="small">
1093
+ <Form onSubmit={handleSubmit}>
1094
+ <Flex vertical gap={16}>
1095
+ <Input name="username" label="用户名" rule="REQ" placeholder="请输入用户名" />
1096
+ <Input.Password name="password" label="密码" rule="REQ" placeholder="请输入密码" />
1097
+ <Divider>提交按钮类型</Divider>
1098
+ <Space wrap>
1099
+ <SubmitButton>默认提交</SubmitButton>
1100
+ <SubmitButton type="default">Default类型</SubmitButton>
1101
+ <SubmitButton type="dashed">Dashed类型</SubmitButton>
1102
+ <SubmitButton type="primary" loading={loading}>带加载状态</SubmitButton>
1103
+ </Space>
1104
+ <Divider>实时校验模式</Divider>
1105
+ <Alert message="realtime属性为true时,表单未通过校验时按钮禁用" type="info" showIcon style={{marginBottom: 16}} />
1106
+ <SubmitButton realtime>实时校验提交</SubmitButton>
1107
+ </Flex>
1108
+ </Form>
1109
+ </Card>
1110
+
1111
+ <Card title="ResetButton 重置按钮" size="small">
1112
+ <Form>
1113
+ <Flex vertical gap={16}>
1114
+ <Input name="field1" label="字段1" placeholder="输入后点击重置" />
1115
+ <Input name="field2" label="字段2" placeholder="输入后点击重置" />
1116
+ <Space>
1117
+ <ResetButton>重置表单</ResetButton>
1118
+ <ResetButton type="primary">Primary重置</ResetButton>
1119
+ <ResetButton danger>Danger重置</ResetButton>
1120
+ </Space>
1121
+ </Flex>
1122
+ </Form>
1123
+ </Card>
1124
+
1125
+ <Card title="CancelButton 取消按钮" size="small">
1126
+ <Form cache="form-cache-key">
1127
+ <Flex vertical gap={16}>
1128
+ <Alert message="CancelButton用于清除表单缓存,配合Form的cache属性使用" type="info" showIcon />
1129
+ <Input name="cachedField1" label="缓存字段1" placeholder="输入后会缓存" />
1130
+ <Input name="cachedField2" label="缓存字段2" placeholder="输入后会缓存" />
1131
+ <Space>
1132
+ <CancelButton onClick={() => message.info('取消并清除缓存')}>取消</CancelButton>
1133
+ <CancelButton type="default">Default取消</CancelButton>
1134
+ </Space>
1135
+ </Flex>
1136
+ </Form>
1137
+ </Card>
1138
+
1139
+ <Card title="完整表单示例" size="small">
1140
+ <Form
1141
+ cache="complete-form"
1142
+ onSubmit={handleSubmit}
1143
+ >
1144
+ <Flex vertical gap={16}>
1145
+ <Input name="name" label="姓名" rule="REQ" placeholder="请输入姓名" />
1146
+ <Input name="email" label="邮箱" rule="REQ" placeholder="请输入邮箱" />
1147
+ <Input name="phone" label="电话" placeholder="请输入电话" />
1148
+ <Divider>表单操作</Divider>
1149
+ <Space>
1150
+ <SubmitButton type="primary">提交</SubmitButton>
1151
+ <ResetButton>重置</ResetButton>
1152
+ <CancelButton>取消</CancelButton>
1153
+ </Space>
1154
+ </Flex>
1155
+ </Form>
1156
+ </Card>
1157
+
1158
+ {formData && (
1159
+ <Card title="提交数据" size="small">
1160
+ <pre style={{background: '#f5f5f5', padding: 12, borderRadius: 4}}>{JSON.stringify(formData, null, 2)}</pre>
1161
+ </Card>
1162
+ )}
1163
+ </Flex>
1164
+ );
1165
+ };
1166
+
1167
+ render(<ButtonsExample />);
1168
+
1169
+ ```
77
1170
 
78
1171
  ### API
79
1172
 
1173
+ #### 属性
1174
+
1175
+ | 属性 | 类型 | 默认值 | 描述 |
1176
+ |---------------|------------------------------------|---------------------|--------------------------------|
1177
+ | type | `'default' \| 'inline' \| 'inner'` | `'default'` | 表单类型 |
1178
+ | size | `'small' \| 'middle' \| 'large'` | `'middle'` | 表单尺寸 |
1179
+ | className | `string` | - | 自定义类名 |
1180
+ | cache | `string` | - | 表单缓存标识,用于表单数据缓存 |
1181
+ | enterSubmit | `boolean` | `false` | 是否支持回车提交 |
1182
+ | scrollToError | `boolean` | `true` | 校验失败时是否滚动到错误字段 |
1183
+ | scrollProps | `object` | `{block: 'center'}` | 滚动配置,参考 Element.scrollIntoView |
1184
+ | onSubmit | `function` | - | 表单提交回调函数 |
1185
+
1186
+ ---
1187
+
1188
+ ### Input 输入框
1189
+
1190
+ 文本输入框组件,支持密码输入。
1191
+
1192
+ #### 属性
1193
+
1194
+ | 属性 | 类型 | 默认值 | 描述 |
1195
+ |-------------|-----------|---------|----------|
1196
+ | name | `string` | - | 字段名称(必填) |
1197
+ | label | `string` | - | 字段标签 |
1198
+ | rule | `string` | - | 校验规则 |
1199
+ | realtime | `boolean` | `false` | 是否实时校验 |
1200
+ | placeholder | `string` | - | 占位文本 |
1201
+ | disabled | `boolean` | `false` | 是否禁用 |
1202
+
1203
+ #### Input.Password 密码输入框
1204
+
1205
+ 与 Input 属性相同,显示为密码输入框。
1206
+
1207
+ ---
1208
+
1209
+ ### InputNumber 数字输入框
1210
+
1211
+ #### 属性
1212
+
1213
+ | 属性 | 类型 | 默认值 | 描述 |
1214
+ |-----------|------------|-----|----------|
1215
+ | name | `string` | - | 字段名称(必填) |
1216
+ | label | `string` | - | 字段标签 |
1217
+ | rule | `string` | - | 校验规则 |
1218
+ | min | `number` | - | 最小值 |
1219
+ | max | `number` | - | 最大值 |
1220
+ | step | `number` | `1` | 步长 |
1221
+ | precision | `number` | - | 小数精度 |
1222
+ | formatter | `function` | - | 格式化显示值 |
1223
+ | parser | `function` | - | 解析输入值 |
1224
+
1225
+ ---
1226
+
1227
+ ### TextArea 多行文本
1228
+
1229
+ #### 属性
1230
+
1231
+ | 属性 | 类型 | 默认值 | 描述 |
1232
+ |-----------|---------------------|---------|----------|
1233
+ | name | `string` | - | 字段名称(必填) |
1234
+ | label | `string` | - | 字段标签 |
1235
+ | rule | `string` | - | 校验规则 |
1236
+ | rows | `number` | `4` | 行数 |
1237
+ | maxLength | `number` | - | 最大字符数 |
1238
+ | showCount | `boolean` | `false` | 是否显示字符数 |
1239
+ | autoSize | `boolean \| object` | `false` | 自适应高度 |
1240
+
1241
+ ---
1242
+
1243
+ ### Select 选择器
1244
+
1245
+ #### 属性
1246
+
1247
+ | 属性 | 类型 | 默认值 | 描述 |
1248
+ |--------------|------------------------|---------|-------------------------|
1249
+ | name | `string` | - | 字段名称(必填) |
1250
+ | label | `string` | - | 字段标签 |
1251
+ | rule | `string` | - | 校验规则 |
1252
+ | options | `array` | - | 选项数据 `[{label, value}]` |
1253
+ | mode | `'multiple' \| 'tags'` | - | 模式 |
1254
+ | showSearch | `boolean` | `false` | 是否可搜索 |
1255
+ | filterOption | `function` | - | 搜索过滤函数 |
1256
+
1257
+ ---
1258
+
1259
+ ### TreeSelect 树选择
1260
+
1261
+ #### 属性
1262
+
1263
+ | 属性 | 类型 | 默认值 | 描述 |
1264
+ |---------------|-----------|---------|----------|
1265
+ | name | `string` | - | 字段名称(必填) |
1266
+ | label | `string` | - | 字段标签 |
1267
+ | rule | `string` | - | 校验规则 |
1268
+ | treeData | `array` | - | 树形数据 |
1269
+ | treeCheckable | `boolean` | `false` | 是否可多选 |
1270
+ | showSearch | `boolean` | `false` | 是否可搜索 |
1271
+
1272
+ ---
1273
+
1274
+ ### Cascader 级联选择
1275
+
1276
+ #### 属性
1277
+
1278
+ | 属性 | 类型 | 默认值 | 描述 |
1279
+ |------------|-----------|---------|----------|
1280
+ | name | `string` | - | 字段名称(必填) |
1281
+ | label | `string` | - | 字段标签 |
1282
+ | rule | `string` | - | 校验规则 |
1283
+ | options | `array` | - | 级联数据 |
1284
+ | showSearch | `boolean` | `false` | 是否可搜索 |
1285
+
1286
+ ---
1287
+
1288
+ ### DatePicker 日期选择
1289
+
1290
+ #### 属性
1291
+
1292
+ | 属性 | 类型 | 默认值 | 描述 |
1293
+ |--------------|---------------------|----------------|----------|
1294
+ | name | `string` | - | 字段名称(必填) |
1295
+ | label | `string` | - | 字段标签 |
1296
+ | rule | `string` | - | 校验规则 |
1297
+ | format | `string` | `'YYYY-MM-DD'` | 日期格式 |
1298
+ | disabledDate | `function` | - | 禁用日期函数 |
1299
+ | showTime | `boolean \| object` | `false` | 是否显示时间选择 |
1300
+
1301
+ #### DatePicker.RangePicker 日期范围
1302
+
1303
+ #### DatePicker.MonthPicker 月份选择
1304
+
1305
+ #### DatePicker.WeekPicker 周选择
1306
+
1307
+ ---
1308
+
1309
+ ### TimePicker 时间选择
1310
+
1311
+ #### 属性
80
1312
 
1313
+ | 属性 | 类型 | 默认值 | 描述 |
1314
+ |------------|----------|--------------|----------|
1315
+ | name | `string` | - | 字段名称(必填) |
1316
+ | label | `string` | - | 字段标签 |
1317
+ | rule | `string` | - | 校验规则 |
1318
+ | format | `string` | `'HH:mm:ss'` | 时间格式 |
1319
+ | hourStep | `number` | - | 小时步长 |
1320
+ | minuteStep | `number` | - | 分钟步长 |
1321
+ | secondStep | `number` | - | 秒步长 |
1322
+
1323
+ #### TimePicker.RangePicker 时间范围
1324
+
1325
+ ---
1326
+
1327
+ ### DatePickerToday 快捷日期
1328
+
1329
+ 带有快捷选项的日期范围选择组件,支持"至今"选项。返回值为数组 `[startDate, endDate]`,当选择"至今"时,endDate 值为
1330
+ `soFarValue`。
1331
+
1332
+ #### 属性
1333
+
1334
+ | 属性 | 类型 | 默认值 | 描述 |
1335
+ |------------|------------|-----------|--------------------------------|
1336
+ | name | `string` | - | 字段名称(必填) |
1337
+ | label | `string` | - | 字段标签 |
1338
+ | rule | `string` | - | 校验规则 |
1339
+ | soFarText | `string` | `'至今'` | "至今"按钮显示的文本 |
1340
+ | soFarValue | `string` | `'soFar'` | 选择"至今"时的结束日期值,可通过此值判断是否选择了至今 |
1341
+ | onChange | `function` | - | 值变化回调 `([start, end]) => void` |
1342
+
1343
+ #### 返回值说明
1344
+
1345
+ 组件返回一个数组 `[startDate, endDate]`:
1346
+
1347
+ - `startDate`: 开始日期,ISO 格式字符串(如 `'2024-01-01T00:00:00.000Z'`)
1348
+ - `endDate`: 结束日期,ISO 格式字符串,或 `soFarValue`(默认 `'soFar'`)
1349
+
1350
+ ---
1351
+
1352
+ ### Checkbox 复选框
1353
+
1354
+ #### 属性
1355
+
1356
+ | 属性 | 类型 | 默认值 | 描述 |
1357
+ |----------|-----------|---------|----------|
1358
+ | name | `string` | - | 字段名称(必填) |
1359
+ | label | `string` | - | 字段标签 |
1360
+ | rule | `string` | - | 校验规则 |
1361
+ | disabled | `boolean` | `false` | 是否禁用 |
1362
+
1363
+ ---
1364
+
1365
+ ### CheckboxGroup 复选框组
1366
+
1367
+ #### 属性
1368
+
1369
+ | 属性 | 类型 | 默认值 | 描述 |
1370
+ |----------|-----------|---------|-------------------------|
1371
+ | name | `string` | - | 字段名称(必填) |
1372
+ | label | `string` | - | 字段标签 |
1373
+ | rule | `string` | - | 校验规则 |
1374
+ | options | `array` | - | 选项数据 `[{label, value}]` |
1375
+ | disabled | `boolean` | `false` | 是否禁用 |
1376
+
1377
+ ---
1378
+
1379
+ ### RadioGroup 单选框组
1380
+
1381
+ #### 属性
1382
+
1383
+ | 属性 | 类型 | 默认值 | 描述 |
1384
+ |-------------|-------------------------|-------------|-------------------------|
1385
+ | name | `string` | - | 字段名称(必填) |
1386
+ | label | `string` | - | 字段标签 |
1387
+ | rule | `string` | - | 校验规则 |
1388
+ | options | `array` | - | 选项数据 `[{label, value}]` |
1389
+ | optionType | `'default' \| 'button'` | `'default'` | 选项类型 |
1390
+ | buttonStyle | `'outline' \| 'solid'` | `'outline'` | 按钮样式 |
1391
+
1392
+ ---
1393
+
1394
+ ### Rate 评分
1395
+
1396
+ #### 属性
1397
+
1398
+ | 属性 | 类型 | 默认值 | 描述 |
1399
+ |------------|-------------|---------|----------|
1400
+ | name | `string` | - | 字段名称(必填) |
1401
+ | label | `string` | - | 字段标签 |
1402
+ | rule | `string` | - | 校验规则 |
1403
+ | count | `number` | `5` | 星星数量 |
1404
+ | allowHalf | `boolean` | `false` | 是否允许半星 |
1405
+ | allowClear | `boolean` | `true` | 是否允许清除 |
1406
+ | character | `ReactNode` | - | 自定义字符 |
1407
+ | disabled | `boolean` | `false` | 是否禁用 |
1408
+
1409
+ ---
1410
+
1411
+ ### Slider 滑动条
1412
+
1413
+ #### 属性
1414
+
1415
+ | 属性 | 类型 | 默认值 | 描述 |
1416
+ |----------|-----------|---------|----------|
1417
+ | name | `string` | - | 字段名称(必填) |
1418
+ | label | `string` | - | 字段标签 |
1419
+ | rule | `string` | - | 校验规则 |
1420
+ | min | `number` | `0` | 最小值 |
1421
+ | max | `number` | `100` | 最大值 |
1422
+ | step | `number` | `1` | 步长 |
1423
+ | range | `boolean` | `false` | 是否为范围选择 |
1424
+ | marks | `object` | - | 刻度标记 |
1425
+ | vertical | `boolean` | `false` | 是否垂直 |
1426
+ | disabled | `boolean` | `false` | 是否禁用 |
1427
+
1428
+ ---
1429
+
1430
+ ### Switch 开关
1431
+
1432
+ #### 属性
1433
+
1434
+ | 属性 | 类型 | 默认值 | 描述 |
1435
+ |-------------------|------------------------|-------------|----------|
1436
+ | name | `string` | - | 字段名称(必填) |
1437
+ | label | `string` | - | 字段标签 |
1438
+ | rule | `string` | - | 校验规则 |
1439
+ | checkedChildren | `ReactNode` | - | 选中时的内容 |
1440
+ | unCheckedChildren | `ReactNode` | - | 未选中时的内容 |
1441
+ | disabled | `boolean` | `false` | 是否禁用 |
1442
+ | size | `'default' \| 'small'` | `'default'` | 开关尺寸 |
1443
+
1444
+ ---
1445
+
1446
+ ### SubmitButton 提交按钮
1447
+
1448
+ #### 属性
1449
+
1450
+ | 属性 | 类型 | 默认值 | 描述 |
1451
+ |----------|-----------|-------------|------------------|
1452
+ | type | `string` | `'primary'` | 按钮类型 |
1453
+ | realtime | `boolean` | `false` | 是否实时校验(未通过时禁用按钮) |
1454
+ | disabled | `boolean` | `false` | 是否禁用 |
1455
+ | loading | `boolean` | `false` | 是否加载中 |
1456
+
1457
+ ---
1458
+
1459
+ ### ResetButton 重置按钮
1460
+
1461
+ #### 属性
1462
+
1463
+ 继承 Ant Design Button 的所有属性。
1464
+
1465
+ ---
1466
+
1467
+ ### CancelButton 取消按钮
1468
+
1469
+ 用于清除表单缓存,需配合 Form 的 cache 属性使用。
1470
+
1471
+ #### 属性
1472
+
1473
+ 继承 Ant Design Button 的所有属性。
1474
+
1475
+ | 属性 | 类型 | 默认值 | 描述 |
1476
+ |---------|------------|-----|------|
1477
+ | onClick | `function` | - | 点击回调 |
1478
+
1479
+ ---
1480
+
1481
+ ### GroupList 动态表单列表
1482
+
1483
+ #### 属性
1484
+
1485
+ | 属性 | 类型 | 默认值 | 描述 |
1486
+ |---------------|----------|-----|----------|
1487
+ | name | `string` | - | 字段名称(必填) |
1488
+ | defaultLength | `number` | `0` | 默认项数 |
1489
+
1490
+ #### 子组件参数
1491
+
1492
+ | 参数 | 类型 | 描述 |
1493
+ |----------|------------|-------|
1494
+ | index | `number` | 当前项索引 |
1495
+ | onRemove | `function` | 删除当前项 |
1496
+ | onAdd | `function` | 添加新项 |
1497
+
1498
+ ---
1499
+
1500
+ ### preset 预设配置
1501
+
1502
+ 用于全局配置表单规则和默认属性。
1503
+
1504
+ ```javascript
1505
+ import {preset} from '@kne/react-form-antd';
1506
+
1507
+ preset({
1508
+ type: 'default', // 默认表单类型
1509
+ size: 'middle', // 默认表单尺寸
1510
+ rules: { // 自定义校验规则
1511
+ PHONE: {
1512
+ reg: /^1[3-9]\d{9}$/,
1513
+ message: '请输入正确的手机号码'
1514
+ }
1515
+ },
1516
+ field: { // 字段默认属性
1517
+ Input: {
1518
+ defaultProps: {
1519
+ autoComplete: 'off'
1520
+ }
1521
+ }
1522
+ }
1523
+ });
1524
+ ```