dynamicformdjx-react 0.0.5 → 0.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
@@ -2,12 +2,19 @@
2
2
 
3
3
  基于 **React** 的动态表单输入组件。
4
4
 
5
- [//]: # (React 版本)
5
+ [Document](https://xczcdjx.github.io/dynamicFormDoc/react/install.html)
6
6
 
7
- Vue3 版本 [Document](https://xczcdjx.github.io/dynamicFormDoc/)
7
+ [Vue3 版本](https://www.npmjs.com/package/dynamicformdjx)
8
8
 
9
- [Vue2 版本](https://www.npmjs.com/package/dynamicformdjx-vue2) (正在适配)
9
+ [Vue2 版本](https://www.npmjs.com/package/dynamicformdjx-vue2) (后续适配)
10
10
 
11
+ ## 概述
12
+
13
+ `DynamicForm` 一个灵活且动态的表单组件,使用数组,简化模版操作,提供多种hook快速操作表单等。
14
+
15
+ - 简化节点代码,快速处理表单
16
+ - 提供render2函数渲染表单项,使用函数渲染值或自定义Component函数
17
+ - 提供多种hooks函数,快速处理数据值
11
18
 
12
19
  ## 安装
13
20
 
@@ -20,22 +27,267 @@ yarn add dynamicformdjx-react
20
27
  pnpm add dynamicformdjx-react
21
28
  ```
22
29
 
23
- ### 基本使用
30
+ ### 动态表单
31
+
32
+ #### 与Antd配合
33
+
34
+ > 需配合antd v5+ 版本以上
35
+
36
+ ##### 简单表单
37
+
38
+ > 更多render函数请等待后续更新,可直接使用下方自定义渲染
39
+
40
+ ```tsx
41
+ import {useRef, useState} from "react";
42
+ import {Button, Input, Radio} from "antd";
43
+ import {AdDynamicForm, type adDynamicFormRef, renderInput} from "dynamicformdjx-react/antd";
44
+ import {omitFormCommonKey, OmitValue, useDyForm, useReactiveForm} from "dynamicformdjx-react";
45
+ import type {PresetType} from "dynamicformdjx-react/types";
46
+ import type {Rule} from "antd/es/form";
47
+
48
+ type RowProps = {
49
+ username: string
50
+ password: string
51
+ desc: string
52
+ preset: string
53
+ }
54
+ const SimpleForm = () => {
55
+ const [presetType, setPresetType] = useState<PresetType>('fullRow')
56
+ const [formItems, setFormItems] = useReactiveForm<RowProps, Rule | Rule[]>([
57
+ {
58
+ key: "username",
59
+ label: "用户名",
60
+ value: "",
61
+ allowClear: true,
62
+ rule: [{required: true, message: 'Please input your username!', validateTrigger: 'onBlur'}],
63
+ render2: f => renderInput({}, f),
64
+ span: 12
65
+ },
66
+ {
67
+ key: "password",
68
+ label: "密码",
69
+ required: true,
70
+ value: "",
71
+ render2: (f) => <Input.Password placeholder="请输入密码" {...OmitValue(f, omitFormCommonKey)}/>,
72
+ span: 8,
73
+ offset: 2,
74
+ sort: 0
75
+ },
76
+ {
77
+ key: "preset",
78
+ label: "表格预设",
79
+ value: "fullRow",
80
+ render2: (f) => <Radio.Group
81
+ value={f.value}
82
+ options={[
83
+ {value: 'fullRow', label: 'row'},
84
+ {value: 'grid', label: 'grid'},
85
+ ]}
86
+ onChange={(v) => {
87
+ setPresetType(v.target.value)
88
+ }}
89
+ />,
90
+ }
91
+ ])
92
+ const useForm = useDyForm([formItems, setFormItems])
93
+ const antdFormRef = useRef<adDynamicFormRef>(null)
94
+ const rules: Partial<Record<keyof RowProps, Rule | Rule[]>> = {
95
+ desc: [{required: true, message: '请输入详情'}]
96
+ }
97
+ return (
98
+ <div className='dynamicFormTest'>
99
+ <AdDynamicForm ref={antdFormRef} rules={rules} validateTrigger={null} items={formItems}
100
+ preset={presetType}/>
101
+ <div className="footer" style={{
102
+ display: 'flex',
103
+ gap: '5px'
104
+ }}>
105
+ <Button color={'green'} variant={'outlined'} onClick={() => {
106
+ // const res=antdFormRef.current?.getResult?.()
107
+ const res = useForm.getValues()
108
+ console.log(res)
109
+ }}>getData</Button>
110
+ <Button color={'orange'} variant={'outlined'} onClick={() => {
111
+ useForm.setValues({
112
+ username: 'antd',
113
+ password: 'I love you'
114
+ })
115
+ }}>setData</Button>
116
+ <Button color={'blue'} variant={'outlined'} onClick={() => {
117
+ antdFormRef.current?.validator().then(v => {
118
+ console.log(v)
119
+ }).catch(r => {
120
+ console.log(r)
121
+ })
122
+ }}>validator</Button>
123
+ <Button color={'red'} variant={'outlined'} onClick={() => {
124
+ useForm.onReset()
125
+ }}>reset</Button>
126
+ <Button variant={'outlined'} onClick={() => {
127
+ useForm.setDisabled(true)
128
+ }}>setDisabled</Button>
129
+ </div>
130
+ </div>
131
+ );
132
+ };
133
+
134
+ export default SimpleForm;
135
+
136
+ ```
137
+
138
+ ##### 自定义表单
139
+
140
+ ```tsx
141
+ import {useRef} from "react";
142
+ import {Button, Input, Select} from "antd";
143
+ import {
144
+ DynamicInput,
145
+ type dynamicInputRef,
146
+ omitFormCommonKey,
147
+ OmitValue,
148
+ useDyForm,
149
+ useReactiveForm
150
+ } from "dynamicformdjx-react";
151
+ import {AdDynamicForm, type adDynamicFormRef} from "dynamicformdjx-react/antd";
152
+ import type {Rule} from "antd/es/form";
153
+
154
+ type RowProps = {
155
+ username: string
156
+ job: string
157
+ json: object
158
+ }
159
+ const CustomForm = () => {
160
+ const [formItems, setFormItems] = useReactiveForm<RowProps, Rule | Rule[]>([
161
+ {
162
+ key: "username",
163
+ label: "用户名",
164
+ value: "",
165
+ allowClear: true,
166
+ render2: (f) => <Input placeholder="请输入姓名" {...OmitValue(f, omitFormCommonKey)}/>,
167
+ rule: [
168
+ {
169
+ required: true,
170
+ message: 'Please confirm your username!',
171
+ },
172
+ {
173
+ validator: async (_, value) => {
174
+ if (!value) return; // 交给 required 处理
175
+ if (value.length < 3) {
176
+ throw new Error('至少 3 个字符');
177
+ }
178
+ },
179
+ }
180
+ ],
181
+ },
182
+ {
183
+ key: "job",
184
+ label: "职位",
185
+ value: "",
186
+ required: true,
187
+ render2: (f) => <Select
188
+ style={{
189
+ width: '100%'
190
+ }}
191
+ options={[
192
+ {value: 'jack', label: 'Jack'},
193
+ {value: 'lucy', label: 'Lucy'},
194
+ {value: 'Yiminghe', label: 'yiminghe'},
195
+ {value: 'disabled', label: 'Disabled', disabled: true},
196
+ ]}
197
+ />,
198
+ },
199
+ {
200
+ key: "json",
201
+ label: "Json",
202
+ value: {},
203
+ isCustom: true,
204
+ rule: [
205
+ {
206
+ required: true,
207
+ message: 'json 不能为空'
208
+ },
209
+ {
210
+ validator: async (_, value) => {
211
+ if (!value || Object.keys(value).length === 0) {
212
+ throw new Error('json 不能为空');
213
+ }
214
+ },
215
+ }
216
+ ],
217
+ render2: f => {
218
+ return <DynamicInput ref={dynamicInputRef} value={f.value} onChange={(v: object) => {
219
+ f.value = v
220
+ }} isController/>
221
+ },
222
+ },
223
+ ])
224
+ const useForm = useDyForm([formItems, setFormItems])
225
+ const antdFormRef = useRef<adDynamicFormRef>(null)
226
+ const dynamicInputRef = useRef<dynamicInputRef>(null)
227
+ return (
228
+ <div className='dynamicFormTest'>
229
+ <AdDynamicForm ref={antdFormRef} items={formItems}/>
230
+ <div className="footer" style={{
231
+ display: 'flex',
232
+ gap: '5px'
233
+ }}>
234
+ <Button color={'green'} variant={'outlined'} onClick={() => {
235
+ // const res=antdFormRef.current?.getResult?.()
236
+ const res = useForm.getValues()
237
+ console.log(res)
238
+ }}>getData</Button>
239
+ <Button color={'orange'} variant={'outlined'} onClick={() => {
240
+ useForm.setValues({
241
+ username: 'antd',
242
+ job: 'jack'
243
+ })
244
+ dynamicInputRef.current?.onSet?.({
245
+ a: 'Hello world',
246
+ b: 1314,
247
+ c: [5, 2, 0]
248
+ })
249
+ }}>setData</Button>
250
+ <Button color={'blue'} variant={'outlined'} onClick={() => {
251
+ antdFormRef.current?.validator().then(v => {
252
+ console.log(v)
253
+ }).catch(r => {
254
+ console.error(r)
255
+ })
256
+ }}>validator</Button>
257
+ <Button color={'red'} variant={'outlined'} onClick={() => {
258
+ useForm.onReset()
259
+ dynamicInputRef.current?.onSet?.({})
260
+ }}>reset</Button>
261
+ </div>
262
+ </div>
263
+ );
264
+ };
265
+
266
+ export default CustomForm;
267
+
268
+ ```
269
+
270
+ ### 动态录入
271
+
272
+ > 此录入无需组件库依赖
273
+
274
+ ### 1.单组件
275
+
24
276
  ```tsx
25
277
  import {useState} from "react";
26
- import {DynamicInput,dynamicFormRef} from "dynamicformdjx-react";
278
+ import {DynamicInput, dynamicFormRef} from "dynamicformdjx-react";
27
279
 
28
280
  function App() {
29
- const [obj,setObj]=useState<Record<string, any>>({
281
+ const [obj, setObj] = useState<Record<string, any>>({
30
282
  a: 'Hello world',
31
283
  b: 1314,
32
284
  c: [5, 2, 0]
33
285
  });
34
- const dynamicInputRef=useRef<dynamicFormRef>(null)
286
+ const dynamicInputRef = useRef<dynamicFormRef>(null)
35
287
  return (<div>
36
288
  <DynamicInput ref={dynamicInputRef} isController value={obj} onChange={(e) => setObj(e)}/>
37
289
  <pre>
38
- {JSON.stringify(obj,null, 2)}
290
+ {JSON.stringify(obj, null, 2)}
39
291
  </pre>
40
292
  <div>
41
293
  <button onClick={() => {
@@ -51,12 +303,14 @@ function App() {
51
303
  export default App
52
304
  ```
53
305
 
54
- ### 级联基本使用
306
+ ### 2.级联基本使用
307
+
55
308
  ```tsx
56
309
  import {useState} from "react";
57
- import {DynamicCascadeInput,dynamicCascadeInputRef} from "dynamicformdjx-react";
58
- const App=()=>{
59
- const [obj,setObj]=useState<Record<string, any>>({
310
+ import {DynamicCascadeInput, dynamicCascadeInputRef} from "dynamicformdjx-react";
311
+
312
+ const App = () => {
313
+ const [obj, setObj] = useState<Record<string, any>>({
60
314
  a: {
61
315
  b: {
62
316
  c: {
@@ -69,16 +323,16 @@ const App=()=>{
69
323
  aa: [5, 2, 0],
70
324
  aaa: 1314
71
325
  });
72
- const dynamicInputRef=useRef<dynamicCascadeInputRef>(null)
326
+ const dynamicInputRef = useRef<dynamicCascadeInputRef>(null)
73
327
  return (<div>
74
328
  <DynamicCascadeInput ref={dynamicInputRef} isController value={obj} onChange={(e) => setObj(e)}/>
75
329
  <pre>
76
- {JSON.stringify(obj,null, 2)}
330
+ {JSON.stringify(obj, null, 2)}
77
331
  </pre>
78
332
  <div>
79
333
  <button onClick={() => {
80
334
  dynamicInputRef.current?.onSet?.({
81
- test:'hello world'
335
+ test: 'hello world'
82
336
  })
83
337
  }}>setData
84
338
  </button>
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ import { FormProps, RowProps } from 'antd';
3
+ import { Rule } from 'antd/es/form';
4
+ import { DyFormItem } from '../types/form';
5
+ import { ExposeDyFType, PresetType } from '../types';
6
+ type RulesMap = Record<string, Rule | Rule[]>;
7
+ type AdDynamicFormProps = {
8
+ header?: () => ReactNode;
9
+ footer?: () => ReactNode;
10
+ items: DyFormItem[];
11
+ preset?: PresetType;
12
+ formConfig?: FormProps;
13
+ gridConfig?: RowProps;
14
+ validateTrigger?: string | null;
15
+ rules?: RulesMap;
16
+ };
17
+ declare const AdDynamicForm: import('react').ForwardRefExoticComponent<AdDynamicFormProps & import('react').RefAttributes<ExposeDyFType>>;
18
+ export default AdDynamicForm;
@@ -0,0 +1,5 @@
1
+ import { DyFormItem } from '../../types/form';
2
+ import { PasswordProps, TextAreaProps, InputProps } from 'antd/es/input';
3
+ export declare function renderInput(optionProps: PasswordProps, rf?: DyFormItem): JSX.Element;
4
+ export declare function renderInput(optionProps: TextAreaProps, rf?: DyFormItem): JSX.Element;
5
+ export declare function renderInput(optionProps?: InputProps, rf?: DyFormItem): JSX.Element;