@fairys/valtio-form-basic 0.0.8 → 0.0.10
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 +9 -4
- package/esm/form/form.item.d.ts +88 -21
- package/esm/form/form.item.js +124 -32
- package/esm/form/hooks/index.d.ts +34 -0
- package/esm/form/hooks/index.js +57 -0
- package/esm/form/instance/index.d.ts +21 -4
- package/esm/form/instance/index.js +52 -23
- package/esm/form/layout.d.ts +17 -5
- package/esm/form/layout.js +26 -14
- 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 +36 -10
- package/lib/index.js +21 -12
- package/package.json +2 -2
- package/src/form/form.item.tsx +236 -52
- package/src/form/form.tsx +3 -18
- package/src/form/hooks/index.tsx +78 -0
- package/src/form/instance/index.ts +69 -33
- package/src/form/layout.tsx +47 -17
- package/src/form/utils/index.ts +108 -0
- package/src/index.tsx +1 -0
- package/src/styles/index.css +18 -4
|
@@ -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,56 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
110
119
|
};
|
|
111
120
|
|
|
112
121
|
// ===================================================规则处理================================================================
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
+
/**验证表单项规则
|
|
133
|
+
* @param fields 要验证的字段(可选)
|
|
120
134
|
* @param isReturn 是否返回验证结果(可选)
|
|
121
135
|
*/
|
|
122
136
|
validate = async (fields?: PropertyKey[], isReturn: boolean = true): Promise<ValidateFieldsError | Values> => {
|
|
123
|
-
|
|
137
|
+
const rules = {
|
|
138
|
+
...this.rules,
|
|
139
|
+
...this.mountRules,
|
|
140
|
+
};
|
|
141
|
+
// 根据字段路径获取对应的值
|
|
124
142
|
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
|
-
|
|
143
|
+
const _values: Record<PropertyKey, any> = {};
|
|
144
|
+
/**所有要验证的字段*/
|
|
145
|
+
let _fields = Object.keys(rules) as PropertyKey[];
|
|
146
|
+
/**最后要验证的规则*/
|
|
147
|
+
let _lastRules: Record<PropertyKey, RuleItem[]> = {};
|
|
148
|
+
/**是否指定了字段*/
|
|
149
|
+
let isPropsFields = false;
|
|
150
|
+
// 如果指定了字段,则只验证指定的字段
|
|
151
|
+
if (Array.isArray(fields) && fields.length) {
|
|
152
|
+
_fields = [...fields];
|
|
153
|
+
isPropsFields = true;
|
|
154
|
+
for (let index = 0; index < fields.length; index++) {
|
|
155
|
+
const field = fields[index];
|
|
156
|
+
const paths = this.nameToPaths[field];
|
|
157
|
+
_lastRules[field] = rules[field];
|
|
158
|
+
_values[field] = get(_formData, paths ? paths : formatePath(field as string));
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
isPropsFields = false;
|
|
162
|
+
_lastRules = { ...rules };
|
|
163
|
+
// 通过规则进行获取那些字段需要验证
|
|
164
|
+
for (let index = 0; index < _fields.length; index++) {
|
|
165
|
+
const field = _fields[index];
|
|
166
|
+
const paths = this.nameToPaths[field];
|
|
167
|
+
_values[field] = get(_formData, paths);
|
|
144
168
|
}
|
|
145
|
-
}
|
|
146
|
-
if (!isNeedValidate) {
|
|
147
|
-
console.warn('no rules to validate');
|
|
148
|
-
return Promise.resolve({ ..._formData });
|
|
149
169
|
}
|
|
150
170
|
return new Promise((resolve, reject) => {
|
|
151
|
-
new AsyncValidator({ ...rules }).validate({ ...
|
|
171
|
+
new AsyncValidator({ ...rules }).validate({ ..._values }, (errors, fields) => {
|
|
152
172
|
for (let index = 0; index < _fields.length; index++) {
|
|
153
173
|
const field = _fields[index];
|
|
154
174
|
const fidError = Array.isArray(errors) ? errors.filter((item) => item.field === field) : undefined;
|
|
@@ -162,12 +182,28 @@ export class FairysValtioFormInstance<T extends MObject<T> = Record<string, any>
|
|
|
162
182
|
if (errors) {
|
|
163
183
|
reject({ errors, fields });
|
|
164
184
|
} else {
|
|
165
|
-
|
|
185
|
+
/**如果是指定字段,直接返回字段值*/
|
|
186
|
+
if (isPropsFields) {
|
|
187
|
+
resolve({ ...fields });
|
|
188
|
+
} else {
|
|
189
|
+
resolve({ ..._formData });
|
|
190
|
+
}
|
|
166
191
|
}
|
|
167
192
|
}
|
|
168
193
|
});
|
|
169
194
|
});
|
|
170
195
|
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* 验证某些前缀的字段
|
|
199
|
+
* @param prefix 前缀字段数组
|
|
200
|
+
* @param isReturn 是否返回验证结果(可选)
|
|
201
|
+
*/
|
|
202
|
+
validatePrefixFields = async (prefix: string[], isReturn: boolean = true): Promise<ValidateFieldsError | Values> => {
|
|
203
|
+
const fields = Object.keys(this.rules) as PropertyKey[];
|
|
204
|
+
const _fields = fields.filter((item) => prefix.some((p) => item.toString().startsWith(p)));
|
|
205
|
+
return this.validate(_fields, isReturn);
|
|
206
|
+
};
|
|
171
207
|
}
|
|
172
208
|
|
|
173
209
|
/**声明实例*/
|
package/src/form/layout.tsx
CHANGED
|
@@ -6,7 +6,7 @@ export interface FairysValtioFormLayoutContextOptions {
|
|
|
6
6
|
/**列数据*/
|
|
7
7
|
colCount?: number;
|
|
8
8
|
/**规则校验失败错误提示位置*/
|
|
9
|
-
errorLayout?: 'left
|
|
9
|
+
errorLayout?: 'bottom-left' | 'bottom-right' | 'top-right' | 'top-left' | 'left-border-top' | 'right-border-top';
|
|
10
10
|
/**
|
|
11
11
|
* label显示模式
|
|
12
12
|
* @platform taro 支持 between
|
|
@@ -27,7 +27,15 @@ 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
|
+
isInvalidTextRed?: boolean;
|
|
37
|
+
/**是否显示冒号*/
|
|
38
|
+
showColon?: boolean;
|
|
31
39
|
}
|
|
32
40
|
|
|
33
41
|
export interface FairysValtioFormLayoutAttrsProps extends FairysValtioFormLayoutContextOptions {
|
|
@@ -64,9 +72,9 @@ export interface FairysValtioFormLayoutAttrsProps extends FairysValtioFormLayout
|
|
|
64
72
|
export class FairysValtioFormLayoutInstance {
|
|
65
73
|
state = proxy<FairysValtioFormLayoutContextOptions>({
|
|
66
74
|
colCount: 1,
|
|
67
|
-
errorLayout: 'right
|
|
75
|
+
errorLayout: 'bottom-right',
|
|
68
76
|
labelMode: 'between',
|
|
69
|
-
|
|
77
|
+
itemBorderType: 'bottom',
|
|
70
78
|
});
|
|
71
79
|
updated = (options: FairysValtioFormLayoutContextOptions = {}) => {
|
|
72
80
|
const keys = Object.keys(options);
|
|
@@ -148,7 +156,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
148
156
|
const formLayoutInstance = useFairysValtioFormLayoutInstance();
|
|
149
157
|
const [state] = useFairysValtioFormLayoutContext();
|
|
150
158
|
const parent_colCount = state.colCount || 1;
|
|
151
|
-
const parent_errorLayout = state.errorLayout || 'right
|
|
159
|
+
const parent_errorLayout = state.errorLayout || 'bottom-right';
|
|
152
160
|
const parent_labelMode = state.labelMode || 'between';
|
|
153
161
|
const parent_formItemClassName = state.formItemClassName;
|
|
154
162
|
const parent_formItemStyle = state.formItemStyle;
|
|
@@ -156,7 +164,11 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
156
164
|
const parent_formItemLabelStyle = state.formItemLabelStyle;
|
|
157
165
|
const parent_formItemBodyClassName = state.formItemBodyClassName;
|
|
158
166
|
const parent_formItemBodyStyle = state.formItemBodyStyle;
|
|
159
|
-
const parent_borderedType = state.
|
|
167
|
+
const parent_borderedType = state.itemBorderType || 'bottom';
|
|
168
|
+
const parent_itemBorderColor = state.itemBorderColor;
|
|
169
|
+
const parent_isInvalidBorderRed = state.isInvalidBorderRed;
|
|
170
|
+
const parent_isInvalidTextRed = state.isInvalidTextRed;
|
|
171
|
+
const parent_showColon = state.showColon;
|
|
160
172
|
|
|
161
173
|
const {
|
|
162
174
|
colCount = parent_colCount,
|
|
@@ -168,8 +180,12 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
168
180
|
formItemLabelStyle = parent_formItemLabelStyle,
|
|
169
181
|
formItemBodyClassName = parent_formItemBodyClassName,
|
|
170
182
|
formItemBodyStyle = parent_formItemBodyStyle,
|
|
171
|
-
|
|
183
|
+
itemBorderType = parent_borderedType,
|
|
184
|
+
itemBorderColor = parent_itemBorderColor,
|
|
172
185
|
lastItemBordered = true,
|
|
186
|
+
isInvalidBorderRed = parent_isInvalidBorderRed,
|
|
187
|
+
isInvalidTextRed = parent_isInvalidTextRed,
|
|
188
|
+
showColon = parent_showColon,
|
|
173
189
|
gap,
|
|
174
190
|
isAllColSpan = false,
|
|
175
191
|
className,
|
|
@@ -194,7 +210,11 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
194
210
|
formItemLabelStyle,
|
|
195
211
|
formItemBodyClassName,
|
|
196
212
|
formItemBodyStyle,
|
|
197
|
-
|
|
213
|
+
itemBorderType,
|
|
214
|
+
itemBorderColor,
|
|
215
|
+
isInvalidBorderRed,
|
|
216
|
+
isInvalidTextRed,
|
|
217
|
+
showColon,
|
|
198
218
|
}),
|
|
199
219
|
[
|
|
200
220
|
colCount,
|
|
@@ -206,17 +226,21 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
206
226
|
formItemLabelStyle,
|
|
207
227
|
formItemBodyClassName,
|
|
208
228
|
formItemBodyStyle,
|
|
209
|
-
|
|
229
|
+
itemBorderType,
|
|
230
|
+
itemBorderColor,
|
|
231
|
+
isInvalidBorderRed,
|
|
232
|
+
isInvalidTextRed,
|
|
233
|
+
showColon,
|
|
210
234
|
],
|
|
211
235
|
);
|
|
212
236
|
|
|
213
237
|
const layoutCls = useMemo(
|
|
214
238
|
() =>
|
|
215
239
|
clsx(
|
|
216
|
-
`fairys-valtio-form-layout fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-
|
|
240
|
+
`fairys-valtio-form-layout fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-[12px] fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-[8px]`,
|
|
217
241
|
{
|
|
218
242
|
'fairys-valtio-form-layout-all-col-span': isAllColSpan,
|
|
219
|
-
'fairys-
|
|
243
|
+
'fairys-valtio-form-layout-box-shadow': boxShadow,
|
|
220
244
|
'fairystaroform__border fairystaroform__border-solid fairystaroform__border-gray-200': bordered,
|
|
221
245
|
'fairys-valtio-form-layout-last-item-no-border': !lastItemBordered,
|
|
222
246
|
},
|
|
@@ -227,7 +251,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
227
251
|
const headerCls = useMemo(
|
|
228
252
|
() =>
|
|
229
253
|
clsx(
|
|
230
|
-
`fairys-valtio-form-layout-header fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-[
|
|
254
|
+
`fairys-valtio-form-layout-header fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__flex fairystaroform__justify-between fairystaroform__items-center fairystaroform__flex-row fairystaroform__py-[10px] fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 fairystaroform__box-border`,
|
|
231
255
|
{
|
|
232
256
|
'fairystaroform__px-[8px]': bordered || boxShadow,
|
|
233
257
|
'fairystaroform__px-[4px]': !bordered && !boxShadow,
|
|
@@ -239,15 +263,21 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
239
263
|
const headerTitleCls = useMemo(
|
|
240
264
|
() =>
|
|
241
265
|
clsx(
|
|
242
|
-
`fairys-valtio-form-layout-header-title fairystaroform__text-[14px] fairystaroform__font-bold fairystaroform__box-border`,
|
|
266
|
+
`fairys-valtio-form-layout-header-title fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__text-[14px] fairystaroform__font-bold fairystaroform__box-border`,
|
|
267
|
+
),
|
|
268
|
+
[],
|
|
269
|
+
);
|
|
270
|
+
const headerExtraCls = useMemo(
|
|
271
|
+
() =>
|
|
272
|
+
clsx(
|
|
273
|
+
`fairys-valtio-form-layout-header-extra fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__box-border`,
|
|
243
274
|
),
|
|
244
275
|
[],
|
|
245
276
|
);
|
|
246
|
-
const headerExtraCls = useMemo(() => clsx(`fairys-valtio-form-layout-header-extra fairystaroform__box-border`), []);
|
|
247
277
|
|
|
248
278
|
const body_base = useMemo(() => {
|
|
249
279
|
return clsx(
|
|
250
|
-
'fairys-valtio-form-layout-body fairystaroform__px-[8px] fairystaroform__w-full fairystaroform__grid fairystaroform__gap-[2px] fairystaroform__box-border',
|
|
280
|
+
'fairys-valtio-form-layout-body fairystaroform__transition-all fairystaroform__duration-300 fairystaroform__px-[8px] fairystaroform__w-full fairystaroform__grid fairystaroform__gap-[2px] fairystaroform__box-border',
|
|
251
281
|
bodyClassName,
|
|
252
282
|
);
|
|
253
283
|
}, [bodyClassName]);
|
|
@@ -270,7 +300,7 @@ export function useFairysValtioFormLayoutAttrs(props: FairysValtioFormLayoutAttr
|
|
|
270
300
|
colCount,
|
|
271
301
|
errorLayout,
|
|
272
302
|
labelMode,
|
|
273
|
-
|
|
303
|
+
itemBorderType,
|
|
274
304
|
formLayoutInstance,
|
|
275
305
|
//======================
|
|
276
306
|
layoutName: layoutCls,
|
|
@@ -299,7 +329,7 @@ export interface FairysValtioFormLayoutAttrsReturn {
|
|
|
299
329
|
/**
|
|
300
330
|
* 底部边框类型
|
|
301
331
|
*/
|
|
302
|
-
|
|
332
|
+
itemBorderType: string;
|
|
303
333
|
/**表单布局实例*/
|
|
304
334
|
formLayoutInstance: FairysValtioFormLayoutInstance;
|
|
305
335
|
/**布局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,25 @@
|
|
|
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
|
+
}
|
|
48
|
+
|
|
49
|
+
.fairys-valtio-form-item-invalid-text-red > .fairys-valtio-form-item-container > .fairys-valtio-form-item-label,
|
|
50
|
+
.fairys-valtio-form-item-invalid-text-red
|
|
51
|
+
> .fairys-valtio-form-item-container
|
|
52
|
+
> .fairys-valtio-form-item-body
|
|
53
|
+
> .fairys-valtio-form-item-body-input {
|
|
54
|
+
color: red !important;
|
|
55
|
+
}
|