@fairys/valtio-form-basic 0.0.13 → 1.0.1
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 +933 -2
- package/esm/common/instance/index.d.ts +25 -5
- package/esm/common/instance/index.js +33 -13
- package/esm/common/utils/index.d.ts +6 -0
- package/esm/common/utils/index.js +10 -1
- package/esm/form/form.d.ts +8 -32
- package/esm/form/form.item.d.ts +35 -13
- package/esm/form/form.item.js +27 -2
- package/esm/form/form.js +2 -1
- package/lib/common/instance/index.d.ts +25 -5
- package/lib/common/instance/index.js +42 -16
- package/lib/common/utils/index.d.ts +6 -0
- package/lib/common/utils/index.js +12 -0
- package/lib/form/form.d.ts +8 -32
- package/lib/form/form.item.d.ts +35 -13
- package/lib/form/form.item.js +27 -2
- package/lib/form/form.js +2 -1
- package/package.json +1 -1
- package/src/common/instance/index.ts +69 -18
- package/src/common/utils/index.ts +19 -0
- package/src/form/form.item.tsx +88 -5
- package/src/form/form.tsx +17 -3
package/README.md
CHANGED
|
@@ -1,10 +1,941 @@
|
|
|
1
1
|
# valtio-form-basic
|
|
2
2
|
|
|
3
|
-
使用 valtio 实现的表单基础库, 使其更加便捷,同时支持`PC`、`H5`、`Taro`,同时也更加灵活。
|
|
4
|
-
|
|
3
|
+
使用 valtio 实现的表单基础库, 使其更加便捷,同时支持`PC`、`H5`、`Taro`、`RN`,同时也更加灵活。
|
|
5
4
|
|
|
6
5
|
## 安装
|
|
7
6
|
|
|
8
7
|
```bash
|
|
9
8
|
npm install @fairys/valtio-form-basic # yarn add @fairys/valtio-form-basic # pnpm add @fairys/valtio-form-basic
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 类型
|
|
12
|
+
|
|
13
|
+
### 类型方法
|
|
14
|
+
|
|
15
|
+
```ts title="src/common/interface.ts"
|
|
16
|
+
export type MObject<T> = {
|
|
17
|
+
[K in keyof T]: T[K];
|
|
18
|
+
};
|
|
19
|
+
export type MakeFieldRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 实例
|
|
23
|
+
|
|
24
|
+
```ts title="src/common/instance/index.ts"
|
|
25
|
+
import { MObject } from '../interface';
|
|
26
|
+
import { RuleItem, ValidateFieldsError, Values } from 'async-validator';
|
|
27
|
+
import { FairysValtioFormAttrsProps } from '../../form/form';
|
|
28
|
+
/**表单实例*/
|
|
29
|
+
export declare class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>> {
|
|
30
|
+
/***
|
|
31
|
+
* 判断值是否为代理对象
|
|
32
|
+
* @param value 值
|
|
33
|
+
* @returns 是否为代理对象
|
|
34
|
+
*/
|
|
35
|
+
isValtioProxy: (value: any) => boolean;
|
|
36
|
+
/**状态*/
|
|
37
|
+
state: T;
|
|
38
|
+
/**
|
|
39
|
+
* 错误信息
|
|
40
|
+
*/
|
|
41
|
+
errorState: Record<PropertyKey, string[]>;
|
|
42
|
+
/**隐藏状态*/
|
|
43
|
+
hideState: Record<PropertyKey, boolean>;
|
|
44
|
+
/**初始化表单值*/
|
|
45
|
+
ctor: (options?: {
|
|
46
|
+
formData?: Partial<T>;
|
|
47
|
+
hideState?: Record<PropertyKey, boolean>;
|
|
48
|
+
initFormDataType?: FairysValtioFormAttrsProps["initFormDataType"];
|
|
49
|
+
}) => void;
|
|
50
|
+
/**
|
|
51
|
+
* 更新数据
|
|
52
|
+
* @param state 更新数据对象
|
|
53
|
+
* @param isValidate 是否验证(可选)
|
|
54
|
+
*/
|
|
55
|
+
updated: <M = T>(state: Partial<M>, isValidate?: boolean) => void;
|
|
56
|
+
/**根据路径设置值
|
|
57
|
+
* @param path 值路径
|
|
58
|
+
* @param value 值
|
|
59
|
+
*/
|
|
60
|
+
updatedValueByPaths: (path: PropertyKey, value: any) => void;
|
|
61
|
+
/**
|
|
62
|
+
* 更新行数据的隐藏信息
|
|
63
|
+
* @param objectHideInfo 行数据隐藏信息对象
|
|
64
|
+
*/
|
|
65
|
+
updatedHideInfo: (objectHideInfo: Record<PropertyKey, boolean>) => this;
|
|
66
|
+
/**
|
|
67
|
+
* 清理隐藏信息
|
|
68
|
+
*/
|
|
69
|
+
clearHideInfo: (fields?: PropertyKey[]) => this;
|
|
70
|
+
/**
|
|
71
|
+
* 更新行数据的错误信息
|
|
72
|
+
* @param objectErrorInfo 行数据错误信息对象
|
|
73
|
+
*/
|
|
74
|
+
updatedErrorInfo: (objectErrorInfo: Record<PropertyKey, string[]>) => this;
|
|
75
|
+
/**
|
|
76
|
+
* 清理错误信息
|
|
77
|
+
*/
|
|
78
|
+
clearErrorInfo: (fields?: PropertyKey[]) => this;
|
|
79
|
+
/**
|
|
80
|
+
* 清理所有数据
|
|
81
|
+
*/
|
|
82
|
+
clear: () => void;
|
|
83
|
+
/**由表单项挂载规则,(根据表单项的字段存储路径对应校验规则)*/
|
|
84
|
+
mountRules: Record<PropertyKey, RuleItem[]>;
|
|
85
|
+
/**移除表单项挂载规则*/
|
|
86
|
+
removeRules: (name: PropertyKey) => void;
|
|
87
|
+
/**表单项规则*/
|
|
88
|
+
rules: Record<PropertyKey, RuleItem[]>;
|
|
89
|
+
/**表单项名称到路径映射*/
|
|
90
|
+
nameToPaths: Record<PropertyKey, PropertyKey[]>;
|
|
91
|
+
/**验证表单项规则
|
|
92
|
+
* @param fields 要验证的字段(可选)
|
|
93
|
+
* @param isReturn 是否返回验证结果(可选)
|
|
94
|
+
*/
|
|
95
|
+
validate: (fields?: PropertyKey[], isReturn?: boolean) => Promise<ValidateFieldsError | Values>;
|
|
96
|
+
/**
|
|
97
|
+
* 验证某些前缀的字段
|
|
98
|
+
* @param prefix 前缀字段数组
|
|
99
|
+
* @param isReturn 是否返回验证结果(可选)
|
|
100
|
+
*/
|
|
101
|
+
validatePrefixFields: (prefix: string[], isReturn?: boolean) => Promise<ValidateFieldsError | Values>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
***声明实例***
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
/**声明实例*/
|
|
110
|
+
export declare function useFairysValtioFormInstance<T extends MObject<T> = Record<string, any>>(instance?: FairysValtioFormInstance<T>): FairysValtioFormInstance<T>;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
***表单实例上下文***
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
/**表单实例上下文*/
|
|
117
|
+
export declare const FairysValtioFormInstanceContext: import("react").Context<FairysValtioFormInstance<any>>;
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
***获取表单实例上下文***
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
/**获取表单实例上下文*/
|
|
124
|
+
export declare function useFairysValtioFormInstanceContext<T extends MObject<T> = Record<string, any>>(): FairysValtioFormInstance<T>;
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
***状态取值***
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
/**状态取值*/
|
|
131
|
+
export declare function useFairysValtioFormInstanceContextState<T extends MObject<T> = Record<string, any>>(): [T, Record<PropertyKey, string[]>, FairysValtioFormInstance<T>, any, any];
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
***隐藏组件状态取值***
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
/**隐藏组件状态取值*/
|
|
138
|
+
export declare function useFairysValtioFormInstanceContextHideState<T extends MObject<T> = Record<string, any>>(): [Record<PropertyKey, boolean>, FairysValtioFormInstance<T>, any];
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
### 获取父级表单项`name`属性值
|
|
143
|
+
|
|
144
|
+
```ts title="src/common/hooks/index.ts"
|
|
145
|
+
export interface FairysValtioFormParentAttrsState {
|
|
146
|
+
name?: string;
|
|
147
|
+
}
|
|
148
|
+
/***
|
|
149
|
+
* 父级属性
|
|
150
|
+
*/
|
|
151
|
+
export declare class FairysValtioFormParentAttrs {
|
|
152
|
+
state: FairysValtioFormParentAttrsState;
|
|
153
|
+
updated: (attrs: Record<string, any>) => void;
|
|
154
|
+
/***更新父级字段值*/
|
|
155
|
+
updatedName: (name?: string, parentName?: string) => void;
|
|
156
|
+
}
|
|
157
|
+
export interface FairysValtioFormAttrsNameOptions {
|
|
158
|
+
name?: string;
|
|
159
|
+
/**是否拼接父级字段名*/
|
|
160
|
+
isJoinParentField?: boolean;
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
***初始化父级属性*****
|
|
165
|
+
```ts
|
|
166
|
+
/**初始化父级属性*/
|
|
167
|
+
export declare const useFairysValtioFormParentAttrs: (instance?: FairysValtioFormParentAttrs) => FairysValtioFormParentAttrs;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
***父级属性上下文***
|
|
171
|
+
```ts
|
|
172
|
+
/***父级属性上下文*/
|
|
173
|
+
export declare const FairysValtioFormParentAttrsContext: import("react").Context<FairysValtioFormParentAttrs>;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
***获取父级属性实例***
|
|
177
|
+
```ts
|
|
178
|
+
/**获取父级属性实例*/
|
|
179
|
+
export declare const useFairysValtioFormParentAttrsContext: () => FairysValtioFormParentAttrs;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
***获取父级属性状态***
|
|
183
|
+
```ts
|
|
184
|
+
/**获取父级属性状态*/
|
|
185
|
+
export declare const useFairysValtioFormParentAttrsState: () => readonly [{
|
|
186
|
+
readonly name?: string;
|
|
187
|
+
}, FairysValtioFormParentAttrs];
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
***获取属性名和路径***
|
|
192
|
+
```ts
|
|
193
|
+
/**获取属性名和路径*/
|
|
194
|
+
export declare const useFairysValtioFormAttrsName: (options?: FairysValtioFormAttrsNameOptions) => {
|
|
195
|
+
formAttrsNameInstance: FairysValtioFormParentAttrs;
|
|
196
|
+
parentName: string;
|
|
197
|
+
name: string;
|
|
198
|
+
paths: (number | symbol)[] | (string | number)[];
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### useId
|
|
203
|
+
|
|
204
|
+
```ts title="src/common/hooks/index.ts"
|
|
205
|
+
export declare const useId: (suffix?: string) => string;
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### form
|
|
209
|
+
|
|
210
|
+
```ts title="src/form/form.tsx"
|
|
211
|
+
import { MObject } from '../common/interface';
|
|
212
|
+
import { FairysValtioFormInstance } from '../common/instance';
|
|
213
|
+
import { type ReactNode } from 'react';
|
|
214
|
+
import { FairysValtioFormLayoutAttrsProps } from './layout';
|
|
215
|
+
import { RuleItem } from 'async-validator';
|
|
216
|
+
export interface FairysValtioFormAttrsProps<T extends MObject<T> = Record<string, any>> extends FairysValtioFormLayoutAttrsProps {
|
|
217
|
+
/**表单实例*/
|
|
218
|
+
form?: FairysValtioFormInstance<T>;
|
|
219
|
+
/**子元素*/
|
|
220
|
+
children: ReactNode;
|
|
221
|
+
/**表单项规则(如果表单项没有指定规则,则使用全局规则,如果表单项指定规则,则使用表单项规则)*/
|
|
222
|
+
rules?: Record<PropertyKey, RuleItem[]>;
|
|
223
|
+
/**表单初始值*/
|
|
224
|
+
formData?: FairysValtioFormInstance<T>['state'];
|
|
225
|
+
/**表单隐藏状态*/
|
|
226
|
+
hideState?: FairysValtioFormInstance<T>['hideState'];
|
|
227
|
+
/**
|
|
228
|
+
* 初始化表单数据类型,默认值为 deepCopy
|
|
229
|
+
* - deepCopy:使用深度拷贝初始化表单数据
|
|
230
|
+
* - immutable:直接使用对象(注意:当传递的不是`valtio`的`proxy`对象时,会使用`valtio`中的`proxy`声明)
|
|
231
|
+
*/
|
|
232
|
+
initFormDataType?: 'deepCopy' | 'immutable';
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* 表单属性处理
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
*
|
|
239
|
+
* ```tsx
|
|
240
|
+
import { useFairysValtioForm } from "@fairys/valtio-form"
|
|
241
|
+
import type { FairysValtioFormAttrProps } from "@fairys/valtio-form"
|
|
242
|
+
export interface FormProps extends FairysValtioFormAttrProps{}
|
|
243
|
+
|
|
244
|
+
export const Form = (props: FormProps) => {
|
|
245
|
+
const { formInstance,children, ...rest } = useFairysValtioForm(props)
|
|
246
|
+
return (
|
|
247
|
+
<FairysValtioFormInstanceContext.Provider value={formInstance}>
|
|
248
|
+
<布局组件 {...rest}>{children}</布局组件>
|
|
249
|
+
</FairysValtioFormInstanceContext.Provider>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
export declare function useFairysValtioForm<T extends MObject<T> = Record<string, any>>(props: FairysValtioFormAttrsProps<T>, ref: React.Ref<FairysValtioFormInstance<T>>): Omit<FairysValtioFormAttrsProps<T>, "initFormDataType" | "form" | "rules" | "formData" | "hideState" | "onValuesChange"> & {
|
|
255
|
+
formInstance: FairysValtioFormInstance<T>;
|
|
256
|
+
};
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### formItem
|
|
260
|
+
|
|
261
|
+
```ts title="src/form/form.item.tsx"
|
|
262
|
+
/**表单项*/
|
|
263
|
+
import { MObject } from '../common/interface';
|
|
264
|
+
import React from 'react';
|
|
265
|
+
import { FairysValtioFormInstance } from '../common/instance';
|
|
266
|
+
import { FairysValtioFormLayoutContextOptions } from './layout';
|
|
267
|
+
import { FairysValtioFormParentAttrs } from '../common/hooks';
|
|
268
|
+
import { RuleItem } from 'async-validator';
|
|
269
|
+
export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = Record<string, any>> {
|
|
270
|
+
/**平台*/
|
|
271
|
+
platform?: 'pc' | 'rn' | 'taro';
|
|
272
|
+
/**
|
|
273
|
+
* 表单项名称 ,字段需要和存储的字段路径一致
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* 路径中的值为 number 类型时,会创建一个空数组。路径中的值为 string 类型时,会创建一个空对象。最后一个直接赋值
|
|
277
|
+
*
|
|
278
|
+
* 默认:"name"
|
|
279
|
+
* 嵌套字段:"name.a.doc" ===> { name: { a: { doc: undefined } } }
|
|
280
|
+
* 嵌套字段:"name[1].a.doc" ===> { name: [{}, { a: { doc: undefined } }] }
|
|
281
|
+
* 嵌套字段:"name.a[2].doc" ===> { name: { a: [{}, {}, { doc: undefined }] } }
|
|
282
|
+
*/
|
|
283
|
+
name?: string;
|
|
284
|
+
/**表单项标签*/
|
|
285
|
+
label?: string;
|
|
286
|
+
/**传递组件字段*/
|
|
287
|
+
valuePropName?: string;
|
|
288
|
+
/**取值字段(默认 valuePropName字段值)*/
|
|
289
|
+
getValuePath?: string;
|
|
290
|
+
/**自定义获取值*/
|
|
291
|
+
getValueFromEvent?: (event: any, form: FairysValtioFormInstance<T>) => any;
|
|
292
|
+
/**值格式化*/
|
|
293
|
+
formatValue?: (value: any, form: FairysValtioFormInstance<T>, event: any) => any;
|
|
294
|
+
/**触发数据更新之后触发(用于数据联动之类的)*/
|
|
295
|
+
onAfterUpdate?: (value: any, form: FairysValtioFormInstance<T>, event: any) => void;
|
|
296
|
+
/**事件名称*/
|
|
297
|
+
trigger?: string;
|
|
298
|
+
className?: string;
|
|
299
|
+
style?: React.CSSProperties;
|
|
300
|
+
labelClassName?: string;
|
|
301
|
+
labelStyle?: React.CSSProperties;
|
|
302
|
+
bodyClassName?: string;
|
|
303
|
+
bodyStyle?: React.CSSProperties;
|
|
304
|
+
children?: React.ReactNode;
|
|
305
|
+
/**规则校验失败错误提示位置*/
|
|
306
|
+
errorLayout?: FairysValtioFormLayoutContextOptions['errorLayout'];
|
|
307
|
+
/**label显示模式*/
|
|
308
|
+
labelMode?: FairysValtioFormLayoutContextOptions['labelMode'];
|
|
309
|
+
/**额外内容*/
|
|
310
|
+
extra?: React.ReactNode;
|
|
311
|
+
/**底部提示内容*/
|
|
312
|
+
helpText?: React.ReactNode;
|
|
313
|
+
/**
|
|
314
|
+
* 表单项占据列数
|
|
315
|
+
* @default 1
|
|
316
|
+
*/
|
|
317
|
+
colSpan?: number;
|
|
318
|
+
/**
|
|
319
|
+
* 表单项占据行数
|
|
320
|
+
* @default 1
|
|
321
|
+
*/
|
|
322
|
+
rowSpan?: number;
|
|
323
|
+
/**是否必填*/
|
|
324
|
+
isRequired?: boolean;
|
|
325
|
+
/**是否显示冒号*/
|
|
326
|
+
showColon?: boolean;
|
|
327
|
+
/**底部显示边框*/
|
|
328
|
+
itemBorderType?: FairysValtioFormLayoutContextOptions['itemBorderType'];
|
|
329
|
+
/**边框颜色*/
|
|
330
|
+
itemBorderColor?: React.CSSProperties['borderColor'];
|
|
331
|
+
/**是否校验失败时显示红色边框*/
|
|
332
|
+
isInvalidBorderRed?: boolean;
|
|
333
|
+
/**是否校验失败时显示红色文本*/
|
|
334
|
+
isInvalidTextRed?: boolean;
|
|
335
|
+
/**输入框属性*/
|
|
336
|
+
attrs?: any;
|
|
337
|
+
/**是否拼接父级字段名*/
|
|
338
|
+
isJoinParentField?: boolean;
|
|
339
|
+
/**校验规则*/
|
|
340
|
+
rules?: RuleItem[];
|
|
341
|
+
/**卸载移除数据值
|
|
342
|
+
* @default true
|
|
343
|
+
*/
|
|
344
|
+
isRemoveValueOnUnmount?: boolean;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
***表单项属性参数处理***
|
|
350
|
+
|
|
351
|
+
```ts
|
|
352
|
+
/**
|
|
353
|
+
* 处理表单表单项属性
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
*
|
|
357
|
+
* ```tsx
|
|
358
|
+
import { Fragment } from 'react'
|
|
359
|
+
import { useFairysValtioFormItemAttrs , FairysValtioFormParentAttrsContext } from "@fairys/valtio-form"
|
|
360
|
+
import type { FairysValtioFormItemAttrsProps } from "@fairys/valtio-form"
|
|
361
|
+
export interface FormItemProps extends FairysValtioFormItemAttrsProps{}
|
|
362
|
+
|
|
363
|
+
export const FormItem = (props: FormItemProps) => {
|
|
364
|
+
const { label, extra, helpText } = props
|
|
365
|
+
const {
|
|
366
|
+
itemClassName, itemStyle, containerClassName, itemLabelClassName, itemLabelStyle,
|
|
367
|
+
itemBodyClassName, itemBodyStyle, itemInputClassName, itemExtraClassName, errorClassName, helpClassName,
|
|
368
|
+
isInvalid, itemBorderType, children, error,formAttrsNameInstance
|
|
369
|
+
} = useFairysValtioFormItemAttrs(props)
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
|
|
373
|
+
<View className={itemClassName} style={itemStyle}>
|
|
374
|
+
<View className={containerClassName}>
|
|
375
|
+
<View className={itemLabelClassName} style={itemLabelStyle}>
|
|
376
|
+
{label}
|
|
377
|
+
</View>
|
|
378
|
+
<View className={itemBodyClassName} style={itemBodyStyle}>
|
|
379
|
+
<View className={itemInputClassName}>
|
|
380
|
+
{children}
|
|
381
|
+
</View>
|
|
382
|
+
{extra ? <View className={itemExtraClassName}>{extra}</View> : <Fragment />}
|
|
383
|
+
{itemBorderType === 'body' && isInvalid ? <View className={errorClassName}>{error}</View> : <Fragment />}
|
|
384
|
+
</View>
|
|
385
|
+
</View>
|
|
386
|
+
{helpText ? <View className={helpClassName}>{helpText}</View> : <Fragment />}
|
|
387
|
+
{isInvalid && itemBorderType !== 'body' ? <View className={errorClassName}>{error}</View> : <Fragment />}
|
|
388
|
+
</View>
|
|
389
|
+
</FairysValtioFormParentAttrsContext.Provider>
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
* ```
|
|
393
|
+
*
|
|
394
|
+
*/
|
|
395
|
+
export declare function useFairysValtioFormItemAttrs<T extends MObject<T> = Record<string, any>>(props: FairysValtioFormItemAttrsProps<T>): FairysValtioFormItemAttrsReturn<T>;
|
|
396
|
+
export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> = Record<string, any>> {
|
|
397
|
+
/**表单项值*/
|
|
398
|
+
value?: any;
|
|
399
|
+
/**是否校验错误*/
|
|
400
|
+
isInvalid: boolean;
|
|
401
|
+
/**边框类型*/
|
|
402
|
+
itemBorderType: FairysValtioFormLayoutContextOptions['itemBorderType'];
|
|
403
|
+
/**值改变事件*/
|
|
404
|
+
onValueChange: (event: any) => void;
|
|
405
|
+
/**当前表单项占据列数*/
|
|
406
|
+
colSpan: number;
|
|
407
|
+
/**当前表单项占据行数*/
|
|
408
|
+
rowSpan: number;
|
|
409
|
+
/**列数*/
|
|
410
|
+
colCount: number;
|
|
411
|
+
/**标签显示模式*/
|
|
412
|
+
labelMode: FairysValtioFormLayoutContextOptions['labelMode'];
|
|
413
|
+
/**错误提示位置*/
|
|
414
|
+
errorLayout: FairysValtioFormLayoutContextOptions['errorLayout'];
|
|
415
|
+
/**是否必填*/
|
|
416
|
+
isRequired: boolean;
|
|
417
|
+
/**表单状态*/
|
|
418
|
+
state: T;
|
|
419
|
+
/**错误状态*/
|
|
420
|
+
errorState: Record<PropertyKey, string[]>;
|
|
421
|
+
/**表单实例*/
|
|
422
|
+
formInstance: FairysValtioFormInstance<T>;
|
|
423
|
+
/**错误信息*/
|
|
424
|
+
error?: string[];
|
|
425
|
+
/**拼接父级字段名后得到的表单项名称*/
|
|
426
|
+
_name?: string;
|
|
427
|
+
/**表单项名称*/
|
|
428
|
+
name?: string;
|
|
429
|
+
/**表单项ID*/
|
|
430
|
+
id?: string;
|
|
431
|
+
/**表单项路径*/
|
|
432
|
+
paths?: (string | number)[];
|
|
433
|
+
/**父级字段名*/
|
|
434
|
+
parentName?: string;
|
|
435
|
+
/**表单属性名实例*/
|
|
436
|
+
formAttrsNameInstance: FairysValtioFormParentAttrs;
|
|
437
|
+
/**表单项类名*/
|
|
438
|
+
itemClassName: string;
|
|
439
|
+
/**表单项样式*/
|
|
440
|
+
itemStyle: React.CSSProperties;
|
|
441
|
+
/**容器类名*/
|
|
442
|
+
containerClassName: string;
|
|
443
|
+
/**标签类名*/
|
|
444
|
+
itemLabelClassName: string;
|
|
445
|
+
/**标签样式*/
|
|
446
|
+
itemLabelStyle: React.CSSProperties;
|
|
447
|
+
/**体类名*/
|
|
448
|
+
itemBodyClassName: string;
|
|
449
|
+
/**体样式*/
|
|
450
|
+
itemBodyStyle: React.CSSProperties;
|
|
451
|
+
/**输入框类名*/
|
|
452
|
+
itemInputClassName: string;
|
|
453
|
+
/**额外内容类名*/
|
|
454
|
+
itemExtraClassName: string;
|
|
455
|
+
/**错误提示类名*/
|
|
456
|
+
errorClassName: string;
|
|
457
|
+
/**帮助提示类名*/
|
|
458
|
+
helpClassName: string;
|
|
459
|
+
/**子元素*/
|
|
460
|
+
children?: React.ReactNode;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
***没有样式的表单项属性,仅返回基础输入组件参数***
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
/**
|
|
469
|
+
* 没有样式的表单项属性,仅返回基础输入组件参数
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
*
|
|
473
|
+
*```tsx
|
|
474
|
+
import { Fragment } from 'react'
|
|
475
|
+
import { useFairysValtioFormItemAttrs, FairysValtioFormParentAttrsContext } from "@fairys/valtio-form"
|
|
476
|
+
import type { FairysValtioFormItemAttrsProps } from "@fairys/valtio-form"
|
|
477
|
+
export interface FormItemProps extends FairysValtioFormItemAttrsProps{}
|
|
478
|
+
|
|
479
|
+
export const FormItem = (props: FormItemProps) => {
|
|
480
|
+
const { children , formAttrsNameInstance } = useFairysValtioFormItemNoStyleAttrs(props)
|
|
481
|
+
return <FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
|
|
482
|
+
{children}
|
|
483
|
+
</FairysValtioFormParentAttrsContext.Provider>
|
|
484
|
+
}
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
export declare function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = Record<string, any>>(props: FairysValtioFormItemAttrsProps<T>): FairysValtioFormItemNoStyleAttrsReturn<T>;
|
|
488
|
+
export interface FairysValtioFormItemNoStyleAttrsReturn<T extends MObject<T> = Record<string, any>> {
|
|
489
|
+
/**表单项值*/
|
|
490
|
+
value?: any;
|
|
491
|
+
/**是否校验错误*/
|
|
492
|
+
isInvalid: boolean;
|
|
493
|
+
/**是否必填*/
|
|
494
|
+
isRequired: boolean;
|
|
495
|
+
/**错误信息*/
|
|
496
|
+
error?: string[];
|
|
497
|
+
/**值改变事件*/
|
|
498
|
+
onValueChange: (event: any) => void;
|
|
499
|
+
/**表单状态*/
|
|
500
|
+
state: T;
|
|
501
|
+
/**错误状态*/
|
|
502
|
+
errorState: Record<PropertyKey, string[]>;
|
|
503
|
+
/**表单实例*/
|
|
504
|
+
formInstance: FairysValtioFormInstance<T>;
|
|
505
|
+
/**拼接父级字段名后得到的表单项名称*/
|
|
506
|
+
_name?: string;
|
|
507
|
+
/**表单项名称*/
|
|
508
|
+
name?: string;
|
|
509
|
+
/**表单项ID*/
|
|
510
|
+
id?: string;
|
|
511
|
+
/**表单项路径*/
|
|
512
|
+
paths?: (string | number)[];
|
|
513
|
+
/**父级字段名*/
|
|
514
|
+
parentName?: string;
|
|
515
|
+
/**表单属性名实例*/
|
|
516
|
+
formAttrsNameInstance: FairysValtioFormParentAttrs;
|
|
517
|
+
/**子元素*/
|
|
518
|
+
children?: React.ReactNode;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### layout
|
|
524
|
+
|
|
525
|
+
```ts title="src/form/layout.tsx"
|
|
526
|
+
export interface FairysValtioFormLayoutContextOptions {
|
|
527
|
+
/**平台*/
|
|
528
|
+
platform?: 'pc' | 'rn' | 'taro';
|
|
529
|
+
/**列数据*/
|
|
530
|
+
colCount?: number;
|
|
531
|
+
/**规则校验失败错误提示位置*/
|
|
532
|
+
errorLayout?: 'bottom-left' | 'bottom-right' | 'top-right' | 'top-left' | 'left-border-top' | 'right-border-top';
|
|
533
|
+
/**
|
|
534
|
+
* label显示模式
|
|
535
|
+
* @platform taro 支持 between
|
|
536
|
+
*/
|
|
537
|
+
labelMode?: 'left' | 'top' | 'between';
|
|
538
|
+
/**表单项 className*/
|
|
539
|
+
formItemClassName?: string;
|
|
540
|
+
/**表单项 style*/
|
|
541
|
+
formItemStyle?: React.CSSProperties;
|
|
542
|
+
/**表单项 label className*/
|
|
543
|
+
formItemLabelClassName?: string;
|
|
544
|
+
/**表单项 label style*/
|
|
545
|
+
formItemLabelStyle?: React.CSSProperties;
|
|
546
|
+
/**表单项 body className*/
|
|
547
|
+
formItemBodyClassName?: string;
|
|
548
|
+
/**表单项 body style*/
|
|
549
|
+
formItemBodyStyle?: React.CSSProperties;
|
|
550
|
+
/**
|
|
551
|
+
* 底部边框类型
|
|
552
|
+
*/
|
|
553
|
+
itemBorderType?: 'bottom' | 'body' | 'none';
|
|
554
|
+
/**边框颜色*/
|
|
555
|
+
itemBorderColor?: React.CSSProperties['borderColor'];
|
|
556
|
+
/**是否校验失败时显示红色边框*/
|
|
557
|
+
isInvalidBorderRed?: boolean;
|
|
558
|
+
/**是否校验失败时显示红色文本*/
|
|
559
|
+
isInvalidTextRed?: boolean;
|
|
560
|
+
/**是否显示冒号*/
|
|
561
|
+
showColon?: boolean;
|
|
562
|
+
}
|
|
563
|
+
export interface FairysValtioFormLayoutAttrsProps extends FairysValtioFormLayoutContextOptions {
|
|
564
|
+
/**
|
|
565
|
+
* @description gap 属性是用来设置网格行与列之间的间隙,该属性是row-gap and column-gap的简写形式。
|
|
566
|
+
*/
|
|
567
|
+
gap?: string | number;
|
|
568
|
+
/**标题*/
|
|
569
|
+
title?: React.ReactNode;
|
|
570
|
+
/**额外内容*/
|
|
571
|
+
extra?: React.ReactNode;
|
|
572
|
+
/**内容*/
|
|
573
|
+
children?: React.ReactNode;
|
|
574
|
+
/**是否占据整行*/
|
|
575
|
+
isAllColSpan?: boolean;
|
|
576
|
+
className?: string;
|
|
577
|
+
style?: React.CSSProperties;
|
|
578
|
+
/**头部ClassName*/
|
|
579
|
+
headerClassName?: string;
|
|
580
|
+
/**头部样式*/
|
|
581
|
+
headerStyle?: React.CSSProperties;
|
|
582
|
+
/**内容ClassName*/
|
|
583
|
+
bodyClassName?: string;
|
|
584
|
+
/**内容样式*/
|
|
585
|
+
bodyStyle?: React.CSSProperties;
|
|
586
|
+
/**是否边框*/
|
|
587
|
+
bordered?: boolean;
|
|
588
|
+
/**显示阴影*/
|
|
589
|
+
boxShadow?: boolean;
|
|
590
|
+
/**最后一个是否显示底部边框*/
|
|
591
|
+
lastItemBordered?: boolean;
|
|
592
|
+
}
|
|
593
|
+
export declare class FairysValtioFormLayoutInstance {
|
|
594
|
+
state: FairysValtioFormLayoutContextOptions;
|
|
595
|
+
updated: (options?: FairysValtioFormLayoutContextOptions) => void;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
***初始化布局实例***
|
|
601
|
+
|
|
602
|
+
```ts
|
|
603
|
+
export declare const useFairysValtioFormLayoutInstance: (instance?: FairysValtioFormLayoutInstance) => FairysValtioFormLayoutInstance;
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
***创建布局上下文***
|
|
607
|
+
|
|
608
|
+
```ts
|
|
609
|
+
export declare const FairysValtioFormLayoutContext: import("react").Context<FairysValtioFormLayoutInstance>;
|
|
610
|
+
```
|
|
611
|
+
***获取布局上下文***
|
|
612
|
+
|
|
613
|
+
```ts
|
|
614
|
+
export declare const useFairysValtioFormLayoutContext: () => [FairysValtioFormLayoutContextOptions, FairysValtioFormLayoutInstance];
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
***布局参数处理***
|
|
618
|
+
|
|
619
|
+
```ts
|
|
620
|
+
/**
|
|
621
|
+
* 布局属性处理
|
|
622
|
+
*
|
|
623
|
+
* @example
|
|
624
|
+
*
|
|
625
|
+
* ```tsx
|
|
626
|
+
import { Fragment } from 'react'
|
|
627
|
+
import { useFairysValtioFormLayoutAttrs, FairysValtioFormLayoutContext } from "@fairys/valtio-form"
|
|
628
|
+
import type { FairysValtioFormLayoutAttrsProps } from "@fairys/valtio-form"
|
|
629
|
+
|
|
630
|
+
export interface LayoutProps extends FairysValtioFormLayoutAttrsProps {}
|
|
631
|
+
|
|
632
|
+
export const Layout = (props: LayoutProps) => {
|
|
633
|
+
const { children, title, extra } = props
|
|
634
|
+
const {
|
|
635
|
+
formLayoutInstance,
|
|
636
|
+
layoutName, layoutStyle,
|
|
637
|
+
headerName, headerStyle,
|
|
638
|
+
headerTitleName, headerExtraName,
|
|
639
|
+
bodyName, bodyStyle
|
|
640
|
+
} = useFairysValtioFormLayoutAttrs(props)
|
|
641
|
+
|
|
642
|
+
return (
|
|
643
|
+
<FairysValtioFormLayoutContext.Provider value={formLayoutInstance}>
|
|
644
|
+
<div className={layoutName} style={layoutStyle}>
|
|
645
|
+
<div>
|
|
646
|
+
{title || extra ? (
|
|
647
|
+
<div style={headerStyle} className={headerName}>
|
|
648
|
+
<div className={headerTitleName}>{title}</div>
|
|
649
|
+
<div className={headerExtraName}>{extra}</div>
|
|
650
|
+
</div>
|
|
651
|
+
) : (
|
|
652
|
+
<Fragment />
|
|
653
|
+
)}
|
|
654
|
+
</div>
|
|
655
|
+
<div className={bodyName} style={bodyStyle}>
|
|
656
|
+
{children}
|
|
657
|
+
</div>
|
|
658
|
+
</div>
|
|
659
|
+
</FairysValtioFormLayoutContext.Provider>
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
* ```
|
|
663
|
+
*/
|
|
664
|
+
export declare function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttrsProps): FairysValtioFormLayoutAttrsReturn;
|
|
665
|
+
export interface FairysValtioFormLayoutAttrsReturn {
|
|
666
|
+
/**列数*/
|
|
667
|
+
colCount: number;
|
|
668
|
+
/**规则校验失败错误提示位置*/
|
|
669
|
+
errorLayout: string;
|
|
670
|
+
/**
|
|
671
|
+
* label显示模式
|
|
672
|
+
* @platform taro 支持 between
|
|
673
|
+
*/
|
|
674
|
+
labelMode: string;
|
|
675
|
+
/**
|
|
676
|
+
* 底部边框类型
|
|
677
|
+
*/
|
|
678
|
+
itemBorderType: string;
|
|
679
|
+
/**表单布局实例*/
|
|
680
|
+
formLayoutInstance: FairysValtioFormLayoutInstance;
|
|
681
|
+
/**布局ClassName*/
|
|
682
|
+
layoutName: string;
|
|
683
|
+
/**布局样式*/
|
|
684
|
+
layoutStyle: React.CSSProperties;
|
|
685
|
+
/**头部ClassName*/
|
|
686
|
+
headerName: string;
|
|
687
|
+
/**头部样式*/
|
|
688
|
+
headerStyle: React.CSSProperties;
|
|
689
|
+
/**头部标题ClassName*/
|
|
690
|
+
headerTitleName: string;
|
|
691
|
+
/**头部额外内容ClassName*/
|
|
692
|
+
headerExtraName: string;
|
|
693
|
+
/**内容ClassName*/
|
|
694
|
+
bodyName: string;
|
|
695
|
+
/**内容样式*/
|
|
696
|
+
bodyStyle: React.CSSProperties;
|
|
697
|
+
}
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### utils
|
|
701
|
+
|
|
702
|
+
```ts title="src/common/utils/index.ts"
|
|
703
|
+
/***
|
|
704
|
+
* 设置值
|
|
705
|
+
* @param object 任意对象
|
|
706
|
+
* @param paths 值路径
|
|
707
|
+
* @param nextValue 新值
|
|
708
|
+
*
|
|
709
|
+
* @description
|
|
710
|
+
* 值不存在时,当 paths 路径中的值为 number 类型时,会创建一个空数组。当 paths 路径中的值为 string 类型时,会创建一个空对象。
|
|
711
|
+
*/
|
|
712
|
+
export declare function set<T>(state: any, paths: PropertyKey[], nextValue: T): any;
|
|
713
|
+
/***
|
|
714
|
+
* 获取值
|
|
715
|
+
* @param value 任意值
|
|
716
|
+
* @param segments 键路径
|
|
717
|
+
*/
|
|
718
|
+
export declare function get<TDefault = unknown>(value: any, segments: PropertyKey[]): TDefault;
|
|
719
|
+
/***
|
|
720
|
+
* 格式化路径,将路径中的数组索引转换为数字
|
|
721
|
+
* @param path 路径
|
|
722
|
+
* @returns 格式化后的路径
|
|
723
|
+
*/
|
|
724
|
+
export declare function formatePath(path: PropertyKey): (number | symbol)[] | (string | number)[];
|
|
725
|
+
/***
|
|
726
|
+
* 移除值
|
|
727
|
+
* @param value 任意值
|
|
728
|
+
* @param segments 键路径
|
|
729
|
+
*/
|
|
730
|
+
export declare function removeValueByPaths(value: any, segments: PropertyKey[]): void;
|
|
731
|
+
/**格式化属性名*/
|
|
732
|
+
export declare function formateName(name?: string, parentName?: string): string;
|
|
733
|
+
/***
|
|
734
|
+
* 是否为对象
|
|
735
|
+
* @param x 任意值
|
|
736
|
+
* @returns 是否为对象
|
|
737
|
+
*/
|
|
738
|
+
export declare const isObject: (x: unknown) => x is object;
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
## 使用基础表单组件
|
|
743
|
+
|
|
744
|
+
### 布局组件
|
|
745
|
+
|
|
746
|
+
```tsx
|
|
747
|
+
|
|
748
|
+
import { Fragment } from 'react';
|
|
749
|
+
import type { FairysValtioFormLayoutAttrsProps } from '@fairys/valtio-form-basic';
|
|
750
|
+
import { FairysValtioFormLayoutContext, useFairysValtioFormLayoutAttrs } from '@fairys/valtio-form-basic';
|
|
751
|
+
export interface FormLayoutProps extends FairysValtioFormLayoutAttrsProps { }
|
|
752
|
+
|
|
753
|
+
export function FormLayout(props: FormLayoutProps) {
|
|
754
|
+
const { children, title, extra } = props;
|
|
755
|
+
const {
|
|
756
|
+
formLayoutInstance,
|
|
757
|
+
layoutName,
|
|
758
|
+
layoutStyle,
|
|
759
|
+
headerName,
|
|
760
|
+
headerStyle,
|
|
761
|
+
headerTitleName,
|
|
762
|
+
headerExtraName,
|
|
763
|
+
bodyName,
|
|
764
|
+
bodyStyle,
|
|
765
|
+
} = useFairysValtioFormLayoutAttrs(props);
|
|
766
|
+
|
|
767
|
+
return (
|
|
768
|
+
<FairysValtioFormLayoutContext.Provider value={formLayoutInstance}>
|
|
769
|
+
<div className={layoutName} style={layoutStyle}>
|
|
770
|
+
{title || extra ? (
|
|
771
|
+
<div style={headerStyle} className={headerName}>
|
|
772
|
+
<div className={headerTitleName}>{title}</div>
|
|
773
|
+
<div className={headerExtraName}>{extra}</div>
|
|
774
|
+
</div>
|
|
775
|
+
) : (
|
|
776
|
+
<Fragment />
|
|
777
|
+
)}
|
|
778
|
+
<div className={bodyName} style={bodyStyle}>
|
|
779
|
+
{children}
|
|
780
|
+
</div>
|
|
781
|
+
</div>
|
|
782
|
+
</FairysValtioFormLayoutContext.Provider>
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### 表单组件
|
|
789
|
+
|
|
790
|
+
```tsx
|
|
791
|
+
import React from 'react';
|
|
792
|
+
import { FormLayout } from './layout';
|
|
793
|
+
import {
|
|
794
|
+
useFairysValtioForm,
|
|
795
|
+
FairysValtioFormInstanceContext,
|
|
796
|
+
useFairysValtioFormInstance,
|
|
797
|
+
useFairysValtioFormInstanceContext,
|
|
798
|
+
useFairysValtioFormInstanceContextState,
|
|
799
|
+
useFairysValtioFormInstanceContextHideState,
|
|
800
|
+
} from '@fairys/valtio-form-basic';
|
|
801
|
+
import type { FairysValtioFormAttrsProps, FairysValtioFormInstance, MObject } from '@fairys/valtio-form-basic';
|
|
802
|
+
|
|
803
|
+
export interface FormProps<T extends MObject<T> = Record<string, any>> extends FairysValtioFormAttrsProps<T> {}
|
|
804
|
+
|
|
805
|
+
function FormBase<T extends MObject<T> = Record<string, any>>(
|
|
806
|
+
props: FormProps<T>,
|
|
807
|
+
ref: React.Ref<FairysValtioFormInstance<T>>,
|
|
808
|
+
) {
|
|
809
|
+
const {
|
|
810
|
+
formInstance,
|
|
811
|
+
children,
|
|
812
|
+
colCount = 4,
|
|
813
|
+
labelMode = 'top',
|
|
814
|
+
errorLayout = 'bottom-left',
|
|
815
|
+
itemBorderType = 'none',
|
|
816
|
+
platform = 'pc',
|
|
817
|
+
...rest
|
|
818
|
+
} = useFairysValtioForm(props, ref);
|
|
819
|
+
return (
|
|
820
|
+
<FairysValtioFormInstanceContext.Provider value={formInstance}>
|
|
821
|
+
<FormLayout
|
|
822
|
+
{...rest}
|
|
823
|
+
colCount={colCount}
|
|
824
|
+
labelMode={labelMode}
|
|
825
|
+
itemBorderType={itemBorderType}
|
|
826
|
+
errorLayout={errorLayout}
|
|
827
|
+
platform={platform}
|
|
828
|
+
>
|
|
829
|
+
{children}
|
|
830
|
+
</FormLayout>
|
|
831
|
+
</FairysValtioFormInstanceContext.Provider>
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
export const Form = React.forwardRef(FormBase)
|
|
835
|
+
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
### 表单项
|
|
839
|
+
|
|
840
|
+
```tsx
|
|
841
|
+
import { Fragment } from 'react';
|
|
842
|
+
import type { FairysValtioFormItemAttrsProps, MObject } from '@fairys/valtio-form-basic';
|
|
843
|
+
import {
|
|
844
|
+
useFairysValtioFormItemAttrs,
|
|
845
|
+
useFairysValtioFormInstanceContextHideState,
|
|
846
|
+
useFairysValtioFormItemNoStyleAttrs,
|
|
847
|
+
FairysValtioFormParentAttrsContext,
|
|
848
|
+
} from '@fairys/valtio-form-basic';
|
|
849
|
+
|
|
850
|
+
export interface FormItemProps<T extends MObject<T> = Record<string, any>>
|
|
851
|
+
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>,
|
|
852
|
+
FairysValtioFormItemAttrsProps {
|
|
853
|
+
/**是否使用控制隐藏的表单项*/
|
|
854
|
+
isHide?: boolean;
|
|
855
|
+
/**是否使用无样式表单项*/
|
|
856
|
+
noStyle?: boolean;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**普通表单项*/
|
|
860
|
+
export function FormItemBase<T extends MObject<T> = Record<string, any>>(
|
|
861
|
+
props: Omit<FormItemProps<T>, 'isHide' | 'noStyle'>,
|
|
862
|
+
) {
|
|
863
|
+
const { label, extra, helpText } = props;
|
|
864
|
+
const {
|
|
865
|
+
itemClassName,
|
|
866
|
+
itemStyle,
|
|
867
|
+
containerClassName,
|
|
868
|
+
itemLabelClassName,
|
|
869
|
+
itemLabelStyle,
|
|
870
|
+
itemBodyClassName,
|
|
871
|
+
itemBodyStyle,
|
|
872
|
+
itemInputClassName,
|
|
873
|
+
itemExtraClassName,
|
|
874
|
+
errorClassName,
|
|
875
|
+
helpClassName,
|
|
876
|
+
isInvalid,
|
|
877
|
+
children,
|
|
878
|
+
error,
|
|
879
|
+
formAttrsNameInstance,
|
|
880
|
+
id,
|
|
881
|
+
} = useFairysValtioFormItemAttrs(props);
|
|
882
|
+
|
|
883
|
+
return (
|
|
884
|
+
<div className={itemClassName} style={itemStyle}>
|
|
885
|
+
<div className={containerClassName}>
|
|
886
|
+
{label ? (
|
|
887
|
+
<label htmlFor={id} className={itemLabelClassName} style={itemLabelStyle}>
|
|
888
|
+
{label}
|
|
889
|
+
</label>
|
|
890
|
+
) : (
|
|
891
|
+
<Fragment />
|
|
892
|
+
)}
|
|
893
|
+
<div className={itemBodyClassName} style={itemBodyStyle}>
|
|
894
|
+
<FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
|
|
895
|
+
<div className={itemInputClassName}>{children}</div>
|
|
896
|
+
</FairysValtioFormParentAttrsContext.Provider>
|
|
897
|
+
{extra ? <div className={itemExtraClassName}>{extra}</div> : <Fragment />}
|
|
898
|
+
</div>
|
|
899
|
+
</div>
|
|
900
|
+
{helpText ? <div className={helpClassName}>{helpText}</div> : <Fragment />}
|
|
901
|
+
{isInvalid ? <div className={errorClassName}>{error}</div> : <Fragment />}
|
|
902
|
+
</div>
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
/**控制隐藏的表单项*/
|
|
906
|
+
export function FormHideItem<T extends MObject<T> = Record<string, any>>(
|
|
907
|
+
props: Omit<FormItemProps<T>, 'isHide' | 'noStyle'>,
|
|
908
|
+
) {
|
|
909
|
+
const [state] = useFairysValtioFormInstanceContextHideState();
|
|
910
|
+
const isHide = state[props.name];
|
|
911
|
+
if (isHide) {
|
|
912
|
+
return <Fragment />;
|
|
913
|
+
}
|
|
914
|
+
return <FormItemBase<T> {...props} />;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**无样式表单项*/
|
|
918
|
+
export function FormItemNoStyle<T extends MObject<T> = Record<string, any>>(
|
|
919
|
+
props: Omit<FormItemProps<T>, 'isHide' | 'noStyle'>,
|
|
920
|
+
) {
|
|
921
|
+
const { children, formAttrsNameInstance } = useFairysValtioFormItemNoStyleAttrs(props);
|
|
922
|
+
return (
|
|
923
|
+
<FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
|
|
924
|
+
{children}
|
|
925
|
+
</FairysValtioFormParentAttrsContext.Provider>
|
|
926
|
+
);
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**表单项基础组件(根据isHide和noStyle判断是否使用控制隐藏的表单项和无样式表单项)*/
|
|
930
|
+
export function FormItem<T extends MObject<T> = Record<string, any>>(props: FormItemProps<T>) {
|
|
931
|
+
const { isHide, noStyle, ...rest } = props;
|
|
932
|
+
if (isHide) {
|
|
933
|
+
return <FormHideItem<T> {...rest} />;
|
|
934
|
+
}
|
|
935
|
+
if (noStyle) {
|
|
936
|
+
return <FormItemNoStyle<T> {...rest} />;
|
|
937
|
+
}
|
|
938
|
+
return <FormItemBase<T> {...rest} />;
|
|
939
|
+
}
|
|
940
|
+
|
|
10
941
|
```
|