@fairys/valtio-form-basic 0.0.8 → 0.0.9
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/esm/form/form.d.ts +6 -2
- package/esm/form/form.item.d.ts +84 -19
- package/esm/form/form.item.js +103 -18
- package/esm/form/hooks/index.d.ts +34 -0
- package/esm/form/hooks/index.js +57 -0
- package/esm/form/instance/index.d.ts +14 -6
- package/esm/form/instance/index.js +47 -23
- package/esm/form/layout.d.ts +12 -3
- package/esm/form/layout.js +17 -8
- package/esm/form/utils/index.d.ts +24 -0
- package/esm/form/utils/index.js +60 -0
- package/esm/index.d.ts +1 -0
- package/esm/index.js +1 -0
- package/esm/styles/index.css +9 -5
- package/lib/index.js +21 -12
- package/package.json +2 -2
- package/src/form/form.item.tsx +204 -36
- package/src/form/form.tsx +2 -17
- package/src/form/hooks/index.tsx +78 -0
- package/src/form/instance/index.ts +57 -35
- package/src/form/layout.tsx +28 -10
- package/src/form/utils/index.ts +108 -0
- package/src/index.tsx +1 -0
- package/src/styles/index.css +10 -4
package/src/form/form.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { MObject } from 'interface';
|
|
|
2
2
|
import { FairysValtioFormInstance, useFairysValtioFormInstance } from './instance';
|
|
3
3
|
import { useMemo, type ReactNode } from 'react';
|
|
4
4
|
import { FairysValtioFormLayoutAttrsProps } from './layout';
|
|
5
|
+
import { RuleItem } from 'async-validator';
|
|
5
6
|
|
|
6
7
|
export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> extends FairysValtioFormLayoutAttrsProps {
|
|
7
8
|
/**表单实例*/
|
|
@@ -9,7 +10,7 @@ export interface FairysValtioFormAttrsProps<T extends MObject<T> = object> exten
|
|
|
9
10
|
/**子元素*/
|
|
10
11
|
children: ReactNode;
|
|
11
12
|
/**表单项规则*/
|
|
12
|
-
rules?:
|
|
13
|
+
rules?: Record<PropertyKey, RuleItem[]>;
|
|
13
14
|
/**表单初始值*/
|
|
14
15
|
formData?: FairysValtioFormInstance<T>['state'];
|
|
15
16
|
/**表单隐藏状态*/
|
|
@@ -49,20 +50,4 @@ export function useFairysValtioForm<T extends MObject<T> = object>(props: Fairys
|
|
|
49
50
|
...rest,
|
|
50
51
|
formInstance,
|
|
51
52
|
};
|
|
52
|
-
// return (
|
|
53
|
-
// <FairysValtioFormInstanceContext.Provider value={formInstance}>
|
|
54
|
-
// <FairysValtioFormLayout {...rest}>{children}</FairysValtioFormLayout>
|
|
55
|
-
// </FairysValtioFormInstanceContext.Provider>
|
|
56
|
-
// );
|
|
57
53
|
}
|
|
58
|
-
|
|
59
|
-
// /**初始化实例*/
|
|
60
|
-
// FairysValtioForm.useForm = useFairysValtioFormInstance;
|
|
61
|
-
// /**获取状态*/
|
|
62
|
-
// FairysValtioForm.useFormState = useFairysValtioFormInstanceContextState;
|
|
63
|
-
// /**获取隐藏状态*/
|
|
64
|
-
// FairysValtioForm.useFormHideState = useFairysValtioFormInstanceContextHideState;
|
|
65
|
-
// /**获取上下文实例*/
|
|
66
|
-
// FairysValtioForm.useFormInstance = useFairysValtioFormInstanceContext;
|
|
67
|
-
// /**表单项*/
|
|
68
|
-
// FairysValtioForm.useFormItemAttrs = useFairysValtioFormItemAttrs;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useRef, createContext, useContext, useMemo } from 'react';
|
|
2
|
+
import { proxy, useSnapshot } from 'valtio';
|
|
3
|
+
import { formatePath, formateName } from 'form/utils';
|
|
4
|
+
export interface FairysValtioFormParentAttrsState {
|
|
5
|
+
name?: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/***
|
|
9
|
+
* 父级属性
|
|
10
|
+
*/
|
|
11
|
+
export class FairysValtioFormParentAttrs {
|
|
12
|
+
state = proxy<FairysValtioFormParentAttrsState>({
|
|
13
|
+
name: '',
|
|
14
|
+
});
|
|
15
|
+
// ===================================================更新状态================================================================
|
|
16
|
+
updated = (attrs: Record<string, any>) => {
|
|
17
|
+
this.state = { ...this.state, ...attrs };
|
|
18
|
+
};
|
|
19
|
+
/***更新父级字段值*/
|
|
20
|
+
updatedName = (name?: string, parentName?: string) => {
|
|
21
|
+
this.state.name = formateName(name, parentName);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**初始化父级属性*/
|
|
26
|
+
export const useFairysValtioFormParentAttrs = (instance?: FairysValtioFormParentAttrs) => {
|
|
27
|
+
const parentAttrs = useRef<FairysValtioFormParentAttrs>();
|
|
28
|
+
if (!parentAttrs.current) {
|
|
29
|
+
if (instance) {
|
|
30
|
+
parentAttrs.current = instance;
|
|
31
|
+
} else {
|
|
32
|
+
parentAttrs.current = new FairysValtioFormParentAttrs();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return parentAttrs.current;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/***父级属性上下文*/
|
|
39
|
+
export const FairysValtioFormParentAttrsContext = createContext<FairysValtioFormParentAttrs>(
|
|
40
|
+
new FairysValtioFormParentAttrs(),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
/***获取父级属性实例*/
|
|
44
|
+
export const useFairysValtioFormParentAttrsContext = () => useContext(FairysValtioFormParentAttrsContext);
|
|
45
|
+
|
|
46
|
+
/***获取父级属性状态*/
|
|
47
|
+
export const useFairysValtioFormParentAttrsState = () => {
|
|
48
|
+
const instance = useFairysValtioFormParentAttrsContext();
|
|
49
|
+
const state = useSnapshot(instance.state);
|
|
50
|
+
return [state, instance] as const;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export interface FairysValtioFormAttrsNameOptions {
|
|
54
|
+
name?: string;
|
|
55
|
+
/**是否拼接父级字段名*/
|
|
56
|
+
isJoinParentField?: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/***获取属性名和路径*/
|
|
60
|
+
export const useFairysValtioFormAttrsName = (options: FairysValtioFormAttrsNameOptions = {}) => {
|
|
61
|
+
const { name, isJoinParentField = true } = options;
|
|
62
|
+
const formAttrsNameInstance = useFairysValtioFormParentAttrs();
|
|
63
|
+
const [state] = useFairysValtioFormParentAttrsState();
|
|
64
|
+
const parentName = state.name;
|
|
65
|
+
const _name = useMemo(
|
|
66
|
+
() => (isJoinParentField ? formateName(name, parentName) : name),
|
|
67
|
+
[name, parentName, isJoinParentField],
|
|
68
|
+
);
|
|
69
|
+
const _paths = useMemo(() => formatePath(_name), [_name]);
|
|
70
|
+
useMemo(() => formAttrsNameInstance.updatedName(_name), [_name]);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
formAttrsNameInstance,
|
|
74
|
+
parentName,
|
|
75
|
+
name: _name,
|
|
76
|
+
paths: _paths,
|
|
77
|
+
};
|
|
78
|
+
};
|
|
@@ -3,6 +3,7 @@ import { createContext, useContext, useRef } from 'react';
|
|
|
3
3
|
import { proxy, ref, snapshot, useSnapshot } from 'valtio';
|
|
4
4
|
import AsyncValidator, { RuleItem, ValidateFieldsError, Values } from 'async-validator';
|
|
5
5
|
import { copy } from 'fast-copy';
|
|
6
|
+
import { formatePath, get, set } from 'form/utils';
|
|
6
7
|
|
|
7
8
|
/**表单实例*/
|
|
8
9
|
export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>> {
|
|
@@ -42,6 +43,14 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
42
43
|
}
|
|
43
44
|
};
|
|
44
45
|
|
|
46
|
+
/**根据路径设置值
|
|
47
|
+
* @param path 值路径
|
|
48
|
+
* @param value 值
|
|
49
|
+
*/
|
|
50
|
+
updatedValueByPaths = (path: PropertyKey, value: any) => {
|
|
51
|
+
set(this.state, formatePath(path), value);
|
|
52
|
+
this.validate([path], false);
|
|
53
|
+
};
|
|
45
54
|
// ===================================================隐藏状态================================================================
|
|
46
55
|
/**
|
|
47
56
|
* 更新行数据的隐藏信息
|
|
@@ -110,45 +119,53 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
110
119
|
};
|
|
111
120
|
|
|
112
121
|
// ===================================================规则处理================================================================
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
/**由表单项挂载规则,(根据表单项的字段存储路径对应校验规则)*/
|
|
123
|
+
mountRules: Record<PropertyKey, RuleItem[]> = {};
|
|
124
|
+
/**移除表单项挂载规则*/
|
|
125
|
+
removeRules = (name: PropertyKey) => {
|
|
126
|
+
delete this.mountRules[name];
|
|
127
|
+
};
|
|
128
|
+
/**表单项规则*/
|
|
129
|
+
rules: Record<PropertyKey, RuleItem[]> = {};
|
|
130
|
+
/**表单项名称到路径映射*/
|
|
131
|
+
nameToPaths: Record<PropertyKey, PropertyKey[]> = {};
|
|
132
|
+
/**验证表单项规则*/
|
|
122
133
|
validate = async (fields?: PropertyKey[], isReturn: boolean = true): Promise<ValidateFieldsError | Values> => {
|
|
123
|
-
|
|
134
|
+
const rules = {
|
|
135
|
+
...this.rules,
|
|
136
|
+
...this.mountRules,
|
|
137
|
+
};
|
|
138
|
+
// 根据字段路径获取对应的值
|
|
124
139
|
const _formData = snapshot(this.state) as T;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
const _values: Record<PropertyKey, any> = {};
|
|
141
|
+
/**所有要验证的字段*/
|
|
142
|
+
let _fields = Object.keys(rules) as PropertyKey[];
|
|
143
|
+
/**最后要验证的规则*/
|
|
144
|
+
let _lastRules: Record<PropertyKey, RuleItem[]> = {};
|
|
145
|
+
/**是否指定了字段*/
|
|
146
|
+
let isPropsFields = false;
|
|
147
|
+
// 如果指定了字段,则只验证指定的字段
|
|
148
|
+
if (Array.isArray(fields) && fields.length) {
|
|
149
|
+
_fields = [...fields];
|
|
150
|
+
isPropsFields = true;
|
|
151
|
+
for (let index = 0; index < fields.length; index++) {
|
|
152
|
+
const field = fields[index];
|
|
153
|
+
const paths = this.nameToPaths[field];
|
|
154
|
+
_lastRules[field] = rules[field];
|
|
155
|
+
_values[field] = get(_formData, paths ? paths : formatePath(field as string));
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
isPropsFields = false;
|
|
159
|
+
_lastRules = { ...rules };
|
|
160
|
+
// 通过规则进行获取那些字段需要验证
|
|
161
|
+
for (let index = 0; index < _fields.length; index++) {
|
|
162
|
+
const field = _fields[index];
|
|
163
|
+
const paths = this.nameToPaths[field];
|
|
164
|
+
_values[field] = get(_formData, paths);
|
|
144
165
|
}
|
|
145
|
-
}
|
|
146
|
-
if (!isNeedValidate) {
|
|
147
|
-
console.warn('no rules to validate');
|
|
148
|
-
return Promise.resolve({ ..._formData });
|
|
149
166
|
}
|
|
150
167
|
return new Promise((resolve, reject) => {
|
|
151
|
-
new AsyncValidator({ ...rules }).validate({ ...
|
|
168
|
+
new AsyncValidator({ ...rules }).validate({ ..._values }, (errors, fields) => {
|
|
152
169
|
for (let index = 0; index < _fields.length; index++) {
|
|
153
170
|
const field = _fields[index];
|
|
154
171
|
const fidError = Array.isArray(errors) ? errors.filter((item) => item.field === field) : undefined;
|
|
@@ -162,7 +179,12 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
162
179
|
if (errors) {
|
|
163
180
|
reject({ errors, fields });
|
|
164
181
|
} else {
|
|
165
|
-
|
|
182
|
+
/**如果是指定字段,直接返回字段值*/
|
|
183
|
+
if (isPropsFields) {
|
|
184
|
+
resolve({ ...fields });
|
|
185
|
+
} else {
|
|
186
|
+
resolve({ ..._formData });
|
|
187
|
+
}
|
|
166
188
|
}
|
|
167
189
|
}
|
|
168
190
|
});
|
package/src/form/layout.tsx
CHANGED
|
@@ -27,7 +27,13 @@ export interface FairysValtioFormLayoutContextOptions {
|
|
|
27
27
|
/**
|
|
28
28
|
* 底部边框类型
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
itemBorderType?: 'bottom' | 'body';
|
|
31
|
+
/**边框颜色*/
|
|
32
|
+
itemBorderColor?: React.CSSProperties['borderColor'];
|
|
33
|
+
/**是否校验失败时显示红色边框*/
|
|
34
|
+
isInvalidBorderRed?: boolean;
|
|
35
|
+
/**是否显示冒号*/
|
|
36
|
+
showColon?: boolean;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
export interface FairysValtioFormLayoutAttrsProps extends FairysValtioFormLayoutContextOptions {
|
|
@@ -66,7 +72,7 @@ export class FairysValtioFormLayoutInstance {
|
|
|
66
72
|
colCount: 1,
|
|
67
73
|
errorLayout: 'right-bottom',
|
|
68
74
|
labelMode: 'between',
|
|
69
|
-
|
|
75
|
+
itemBorderType: 'bottom',
|
|
70
76
|
});
|
|
71
77
|
updated = (options: FairysValtioFormLayoutContextOptions = {}) => {
|
|
72
78
|
const keys = Object.keys(options);
|
|
@@ -156,7 +162,10 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
156
162
|
const parent_formItemLabelStyle = state.formItemLabelStyle;
|
|
157
163
|
const parent_formItemBodyClassName = state.formItemBodyClassName;
|
|
158
164
|
const parent_formItemBodyStyle = state.formItemBodyStyle;
|
|
159
|
-
const parent_borderedType = state.
|
|
165
|
+
const parent_borderedType = state.itemBorderType || 'bottom';
|
|
166
|
+
const parent_itemBorderColor = state.itemBorderColor;
|
|
167
|
+
const parent_isInvalidBorderRed = state.isInvalidBorderRed;
|
|
168
|
+
const parent_showColon = state.showColon;
|
|
160
169
|
|
|
161
170
|
const {
|
|
162
171
|
colCount = parent_colCount,
|
|
@@ -168,8 +177,11 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
168
177
|
formItemLabelStyle = parent_formItemLabelStyle,
|
|
169
178
|
formItemBodyClassName = parent_formItemBodyClassName,
|
|
170
179
|
formItemBodyStyle = parent_formItemBodyStyle,
|
|
171
|
-
|
|
180
|
+
itemBorderType = parent_borderedType,
|
|
181
|
+
itemBorderColor = parent_itemBorderColor,
|
|
172
182
|
lastItemBordered = true,
|
|
183
|
+
isInvalidBorderRed = parent_isInvalidBorderRed,
|
|
184
|
+
showColon = parent_showColon,
|
|
173
185
|
gap,
|
|
174
186
|
isAllColSpan = false,
|
|
175
187
|
className,
|
|
@@ -194,7 +206,10 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
194
206
|
formItemLabelStyle,
|
|
195
207
|
formItemBodyClassName,
|
|
196
208
|
formItemBodyStyle,
|
|
197
|
-
|
|
209
|
+
itemBorderType,
|
|
210
|
+
itemBorderColor,
|
|
211
|
+
isInvalidBorderRed,
|
|
212
|
+
showColon,
|
|
198
213
|
}),
|
|
199
214
|
[
|
|
200
215
|
colCount,
|
|
@@ -206,17 +221,20 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
206
221
|
formItemLabelStyle,
|
|
207
222
|
formItemBodyClassName,
|
|
208
223
|
formItemBodyStyle,
|
|
209
|
-
|
|
224
|
+
itemBorderType,
|
|
225
|
+
itemBorderColor,
|
|
226
|
+
isInvalidBorderRed,
|
|
227
|
+
showColon,
|
|
210
228
|
],
|
|
211
229
|
);
|
|
212
230
|
|
|
213
231
|
const layoutCls = useMemo(
|
|
214
232
|
() =>
|
|
215
233
|
clsx(
|
|
216
|
-
`fairys-valtio-form-layout fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-
|
|
234
|
+
`fairys-valtio-form-layout fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-[4px]`,
|
|
217
235
|
{
|
|
218
236
|
'fairys-valtio-form-layout-all-col-span': isAllColSpan,
|
|
219
|
-
'fairys-
|
|
237
|
+
'fairys-valtio-form-layout-box-shadow': boxShadow,
|
|
220
238
|
'fairystaroform__border fairystaroform__border-solid fairystaroform__border-gray-200': bordered,
|
|
221
239
|
'fairys-valtio-form-layout-last-item-no-border': !lastItemBordered,
|
|
222
240
|
},
|
|
@@ -270,7 +288,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
270
288
|
colCount,
|
|
271
289
|
errorLayout,
|
|
272
290
|
labelMode,
|
|
273
|
-
|
|
291
|
+
itemBorderType,
|
|
274
292
|
formLayoutInstance,
|
|
275
293
|
//======================
|
|
276
294
|
layoutName: layoutCls,
|
|
@@ -299,7 +317,7 @@ export interface FairysValtioFormLayoutAttrsReturn {
|
|
|
299
317
|
/**
|
|
300
318
|
* 底部边框类型
|
|
301
319
|
*/
|
|
302
|
-
|
|
320
|
+
itemBorderType: string;
|
|
303
321
|
/**表单布局实例*/
|
|
304
322
|
formLayoutInstance: FairysValtioFormLayoutInstance;
|
|
305
323
|
/**布局ClassName*/
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/***
|
|
2
|
+
* 设置值
|
|
3
|
+
* @param object 任意对象
|
|
4
|
+
* @param paths 值路径
|
|
5
|
+
* @param nextValue 新值
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* 值不存在时,当 paths 路径中的值为 number 类型时,会创建一个空数组。当 paths 路径中的值为 string 类型时,会创建一个空对象。
|
|
9
|
+
*/
|
|
10
|
+
export function set<T>(state: any, paths: PropertyKey[], nextValue: T) {
|
|
11
|
+
const _keys = [...paths];
|
|
12
|
+
let current: any = state;
|
|
13
|
+
const length = _keys.length - 1;
|
|
14
|
+
for (let i = 0; i <= length; i++) {
|
|
15
|
+
const key = _keys[i];
|
|
16
|
+
const _current = current[key];
|
|
17
|
+
// 应该判断下一个key的类型,而不是当前key的类型
|
|
18
|
+
const nextKey = _keys[i + 1];
|
|
19
|
+
/**
|
|
20
|
+
* 如果下一个key不存在,且key是数字,那么创建一个空数组
|
|
21
|
+
*/
|
|
22
|
+
if (typeof _current === 'undefined' && typeof nextKey === 'number') {
|
|
23
|
+
current[key] = [];
|
|
24
|
+
} else if (typeof _current === 'undefined' && typeof nextKey === 'string') {
|
|
25
|
+
/**
|
|
26
|
+
* 如果下一个key不存在,且key是字符串,那么创建一个空对象
|
|
27
|
+
*/
|
|
28
|
+
current[key] = {};
|
|
29
|
+
}
|
|
30
|
+
// 判断最后一个,直接赋值
|
|
31
|
+
if (i === length) {
|
|
32
|
+
current[key] = nextValue;
|
|
33
|
+
} else {
|
|
34
|
+
current = current[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return state;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/***
|
|
41
|
+
* 获取值
|
|
42
|
+
* @param value 任意值
|
|
43
|
+
* @param segments 键路径
|
|
44
|
+
*/
|
|
45
|
+
export function get<TDefault = unknown>(value: any, segments: PropertyKey[]): TDefault {
|
|
46
|
+
let current: any = value;
|
|
47
|
+
for (const key of segments) {
|
|
48
|
+
current = current?.[key];
|
|
49
|
+
}
|
|
50
|
+
return current;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/***
|
|
54
|
+
* 格式化路径,将路径中的数组索引转换为数字
|
|
55
|
+
* @param path 路径
|
|
56
|
+
* @returns 格式化后的路径
|
|
57
|
+
*/
|
|
58
|
+
export function formatePath(path: PropertyKey) {
|
|
59
|
+
if (typeof path !== 'string') {
|
|
60
|
+
return [path];
|
|
61
|
+
}
|
|
62
|
+
return path
|
|
63
|
+
.split(/[\.]/g)
|
|
64
|
+
.reduce((pre, next) => {
|
|
65
|
+
if (/\[[0-9]+\]$/.test(next)) {
|
|
66
|
+
const _next = next.split(/\[/);
|
|
67
|
+
let _nextValue: (string | number)[] = [];
|
|
68
|
+
for (let index = 0; index < _next.length; index++) {
|
|
69
|
+
const element = _next[index];
|
|
70
|
+
if (/\]$/.test(element)) {
|
|
71
|
+
// 去掉数组索引的方括号
|
|
72
|
+
const _v = element.replace(/\]$/, '');
|
|
73
|
+
// 转换为数字
|
|
74
|
+
const v = Number.parseInt(_v);
|
|
75
|
+
/**判断转换后和转换前的长度是否一致,一致则说明是数字*/
|
|
76
|
+
if (_v.length === `${v}`.length && !Number.isNaN(v)) {
|
|
77
|
+
_nextValue.push(v);
|
|
78
|
+
} else {
|
|
79
|
+
_nextValue.push(_v);
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
_nextValue.push(element);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return [...pre, ..._nextValue];
|
|
86
|
+
}
|
|
87
|
+
return [...pre, next];
|
|
88
|
+
}, [] as (string | number)[])
|
|
89
|
+
.map((item) => {
|
|
90
|
+
if (typeof item === 'string') {
|
|
91
|
+
return item.trim();
|
|
92
|
+
}
|
|
93
|
+
return item;
|
|
94
|
+
})
|
|
95
|
+
.filter((item) => item !== '');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**格式化属性名*/
|
|
99
|
+
export function formateName(name?: string, parentName?: string) {
|
|
100
|
+
if (parentName && name) {
|
|
101
|
+
return parentName + '.' + name;
|
|
102
|
+
} else if (parentName) {
|
|
103
|
+
return parentName;
|
|
104
|
+
} else if (name) {
|
|
105
|
+
return name;
|
|
106
|
+
}
|
|
107
|
+
return '';
|
|
108
|
+
}
|
package/src/index.tsx
CHANGED
package/src/styles/index.css
CHANGED
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
box-sizing: border-box;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
.fairys-valtio-form-layout.fairys-form-layout-all-col-span {
|
|
22
|
+
.fairys-valtio-form-layout.fairys-valtio-form-layout-all-col-span {
|
|
23
23
|
grid-column: 1 / -1;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
.fairys-valtio-form-layout.fairys-form-layout-box-shadow {
|
|
26
|
+
.fairys-valtio-form-layout.fairys-valtio-form-layout-box-shadow {
|
|
27
27
|
box-shadow: 0 6px 16px -8px #00000014, 0 9px 28px #0000000d, 0 12px 48px 16px #00000008;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -31,11 +31,17 @@
|
|
|
31
31
|
margin-top: 12px;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
.fairys-valtio-form-layout-last-item-no-border
|
|
34
|
+
.fairys-valtio-form-layout-last-item-no-border
|
|
35
|
+
> .fairys-valtio-form-layout-body
|
|
36
|
+
> .fairys-valtio-form-item:last-child:not(.fairys-valtio-form-item-invalid-border-red),
|
|
35
37
|
.fairys-valtio-form-layout-last-item-no-border
|
|
36
38
|
> .fairys-valtio-form-layout-body
|
|
37
39
|
> .fairys-valtio-form-item:last-child
|
|
38
40
|
> .fairys-valtio-form-item-container
|
|
39
|
-
> .fairys-valtio-form-item-body {
|
|
41
|
+
> .fairys-valtio-form-item-body:not(.fairys-valtio-form-item-invalid-border-red) {
|
|
40
42
|
border-bottom: 0px;
|
|
41
43
|
}
|
|
44
|
+
|
|
45
|
+
.fairys-valtio-form-item-invalid-border-red {
|
|
46
|
+
border-bottom-color: red !important;
|
|
47
|
+
}
|