@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/esm/form/layout.js
CHANGED
|
@@ -6,7 +6,7 @@ class FairysValtioFormLayoutInstance {
|
|
|
6
6
|
colCount: 1,
|
|
7
7
|
errorLayout: 'right-bottom',
|
|
8
8
|
labelMode: 'between',
|
|
9
|
-
|
|
9
|
+
itemBorderType: 'bottom'
|
|
10
10
|
});
|
|
11
11
|
updated = (options = {})=>{
|
|
12
12
|
const keys = Object.keys(options);
|
|
@@ -43,8 +43,11 @@ function useFairysValtioFormLayoutAttrs(props) {
|
|
|
43
43
|
const parent_formItemLabelStyle = state.formItemLabelStyle;
|
|
44
44
|
const parent_formItemBodyClassName = state.formItemBodyClassName;
|
|
45
45
|
const parent_formItemBodyStyle = state.formItemBodyStyle;
|
|
46
|
-
const parent_borderedType = state.
|
|
47
|
-
const
|
|
46
|
+
const parent_borderedType = state.itemBorderType || 'bottom';
|
|
47
|
+
const parent_itemBorderColor = state.itemBorderColor;
|
|
48
|
+
const parent_isInvalidBorderRed = state.isInvalidBorderRed;
|
|
49
|
+
const parent_showColon = state.showColon;
|
|
50
|
+
const { colCount = parent_colCount, errorLayout = parent_errorLayout, labelMode = parent_labelMode, formItemClassName = parent_formItemClassName, formItemStyle = parent_formItemStyle, formItemLabelClassName = parent_formItemLabelClassName, formItemLabelStyle = parent_formItemLabelStyle, formItemBodyClassName = parent_formItemBodyClassName, formItemBodyStyle = parent_formItemBodyStyle, itemBorderType = parent_borderedType, itemBorderColor = parent_itemBorderColor, lastItemBordered = true, isInvalidBorderRed = parent_isInvalidBorderRed, showColon = parent_showColon, gap, isAllColSpan = false, className, style, headerClassName, headerStyle, bodyClassName, bodyStyle, bordered, boxShadow } = props;
|
|
48
51
|
useMemo(()=>formLayoutInstance.updated({
|
|
49
52
|
colCount,
|
|
50
53
|
errorLayout,
|
|
@@ -55,7 +58,10 @@ function useFairysValtioFormLayoutAttrs(props) {
|
|
|
55
58
|
formItemLabelStyle,
|
|
56
59
|
formItemBodyClassName,
|
|
57
60
|
formItemBodyStyle,
|
|
58
|
-
|
|
61
|
+
itemBorderType,
|
|
62
|
+
itemBorderColor,
|
|
63
|
+
isInvalidBorderRed,
|
|
64
|
+
showColon
|
|
59
65
|
}), [
|
|
60
66
|
colCount,
|
|
61
67
|
errorLayout,
|
|
@@ -66,11 +72,14 @@ function useFairysValtioFormLayoutAttrs(props) {
|
|
|
66
72
|
formItemLabelStyle,
|
|
67
73
|
formItemBodyClassName,
|
|
68
74
|
formItemBodyStyle,
|
|
69
|
-
|
|
75
|
+
itemBorderType,
|
|
76
|
+
itemBorderColor,
|
|
77
|
+
isInvalidBorderRed,
|
|
78
|
+
showColon
|
|
70
79
|
]);
|
|
71
|
-
const layoutCls = useMemo(()=>clsx("fairys-valtio-form-layout fairystaroform__text-_zkh1_12px_zhk2_ fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-
|
|
80
|
+
const layoutCls = useMemo(()=>clsx("fairys-valtio-form-layout fairystaroform__text-_zkh1_12px_zhk2_ fairystaroform__w-full fairystaroform__box-border fairystaroform__rounded-_zkh1_4px_zhk2_", {
|
|
72
81
|
'fairys-valtio-form-layout-all-col-span': isAllColSpan,
|
|
73
|
-
'fairys-
|
|
82
|
+
'fairys-valtio-form-layout-box-shadow': boxShadow,
|
|
74
83
|
'fairystaroform__border fairystaroform__border-solid fairystaroform__border-gray-200': bordered,
|
|
75
84
|
'fairys-valtio-form-layout-last-item-no-border': !lastItemBordered
|
|
76
85
|
}, className), [
|
|
@@ -107,7 +116,7 @@ function useFairysValtioFormLayoutAttrs(props) {
|
|
|
107
116
|
colCount,
|
|
108
117
|
errorLayout,
|
|
109
118
|
labelMode,
|
|
110
|
-
|
|
119
|
+
itemBorderType,
|
|
111
120
|
formLayoutInstance,
|
|
112
121
|
layoutName: layoutCls,
|
|
113
122
|
layoutStyle: style,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/***
|
|
2
|
+
* 设置值
|
|
3
|
+
* @param object 任意对象
|
|
4
|
+
* @param paths 值路径
|
|
5
|
+
* @param nextValue 新值
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* 值不存在时,当 paths 路径中的值为 number 类型时,会创建一个空数组。当 paths 路径中的值为 string 类型时,会创建一个空对象。
|
|
9
|
+
*/
|
|
10
|
+
export declare function set<T>(state: any, paths: PropertyKey[], nextValue: T): any;
|
|
11
|
+
/***
|
|
12
|
+
* 获取值
|
|
13
|
+
* @param value 任意值
|
|
14
|
+
* @param segments 键路径
|
|
15
|
+
*/
|
|
16
|
+
export declare function get<TDefault = unknown>(value: any, segments: PropertyKey[]): TDefault;
|
|
17
|
+
/***
|
|
18
|
+
* 格式化路径,将路径中的数组索引转换为数字
|
|
19
|
+
* @param path 路径
|
|
20
|
+
* @returns 格式化后的路径
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatePath(path: PropertyKey): (number | symbol)[] | (string | number)[];
|
|
23
|
+
/**格式化属性名*/
|
|
24
|
+
export declare function formateName(name?: string, parentName?: string): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
function set(state, paths, nextValue) {
|
|
2
|
+
const _keys = [
|
|
3
|
+
...paths
|
|
4
|
+
];
|
|
5
|
+
let current = state;
|
|
6
|
+
const length = _keys.length - 1;
|
|
7
|
+
for(let i = 0; i <= length; i++){
|
|
8
|
+
const key = _keys[i];
|
|
9
|
+
const _current = current[key];
|
|
10
|
+
const nextKey = _keys[i + 1];
|
|
11
|
+
if (void 0 === _current && 'number' == typeof nextKey) current[key] = [];
|
|
12
|
+
else if (void 0 === _current && 'string' == typeof nextKey) current[key] = {};
|
|
13
|
+
if (i === length) current[key] = nextValue;
|
|
14
|
+
else current = current[key];
|
|
15
|
+
}
|
|
16
|
+
return state;
|
|
17
|
+
}
|
|
18
|
+
function get(value, segments) {
|
|
19
|
+
let current = value;
|
|
20
|
+
for (const key of segments)current = current?.[key];
|
|
21
|
+
return current;
|
|
22
|
+
}
|
|
23
|
+
function formatePath(path) {
|
|
24
|
+
if ('string' != typeof path) return [
|
|
25
|
+
path
|
|
26
|
+
];
|
|
27
|
+
return path.split(/[\.]/g).reduce((pre, next)=>{
|
|
28
|
+
if (/\[[0-9]+\]$/.test(next)) {
|
|
29
|
+
const _next = next.split(/\[/);
|
|
30
|
+
let _nextValue = [];
|
|
31
|
+
for(let index = 0; index < _next.length; index++){
|
|
32
|
+
const element = _next[index];
|
|
33
|
+
if (/\]$/.test(element)) {
|
|
34
|
+
const _v = element.replace(/\]$/, '');
|
|
35
|
+
const v = Number.parseInt(_v);
|
|
36
|
+
if (_v.length !== `${v}`.length || Number.isNaN(v)) _nextValue.push(_v);
|
|
37
|
+
else _nextValue.push(v);
|
|
38
|
+
} else _nextValue.push(element);
|
|
39
|
+
}
|
|
40
|
+
return [
|
|
41
|
+
...pre,
|
|
42
|
+
..._nextValue
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
return [
|
|
46
|
+
...pre,
|
|
47
|
+
next
|
|
48
|
+
];
|
|
49
|
+
}, []).map((item)=>{
|
|
50
|
+
if ('string' == typeof item) return item.trim();
|
|
51
|
+
return item;
|
|
52
|
+
}).filter((item)=>'' !== item);
|
|
53
|
+
}
|
|
54
|
+
function formateName(name, parentName) {
|
|
55
|
+
if (parentName && name) return parentName + '.' + name;
|
|
56
|
+
if (parentName) return parentName;
|
|
57
|
+
if (name) return name;
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
export { formateName, formatePath, get, set };
|
package/esm/index.d.ts
CHANGED
package/esm/index.js
CHANGED
package/esm/styles/index.css
CHANGED
|
@@ -166,8 +166,8 @@
|
|
|
166
166
|
border-bottom-color: rgb(229 231 235 / var(--un-border-bottom-opacity));
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
.fairystaroform__rounded-
|
|
170
|
-
border-radius:
|
|
169
|
+
.fairystaroform__rounded-_zkh1_4px_zhk2_ {
|
|
170
|
+
border-radius: 4px;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
.fairystaroform__border-solid {
|
|
@@ -248,11 +248,11 @@
|
|
|
248
248
|
display: inline-block;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
.fairys-valtio-form-layout.fairys-form-layout-all-col-span {
|
|
251
|
+
.fairys-valtio-form-layout.fairys-valtio-form-layout-all-col-span {
|
|
252
252
|
grid-column: 1 / -1;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
.fairys-valtio-form-layout.fairys-form-layout-box-shadow {
|
|
255
|
+
.fairys-valtio-form-layout.fairys-valtio-form-layout-box-shadow {
|
|
256
256
|
box-shadow: 0 6px 16px -8px #00000014, 0 9px 28px #0000000d, 0 12px 48px 16px #00000008;
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -260,7 +260,11 @@
|
|
|
260
260
|
margin-top: 12px;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
.fairys-valtio-form-layout-last-item-no-border > .fairys-valtio-form-layout-body > .fairys-valtio-form-item:last-child, .fairys-valtio-form-layout-last-item-no-border > .fairys-valtio-form-layout-body > .fairys-valtio-form-item:last-child > .fairys-valtio-form-item-container > .fairys-valtio-form-item-body {
|
|
263
|
+
.fairys-valtio-form-layout-last-item-no-border > .fairys-valtio-form-layout-body > .fairys-valtio-form-item:last-child:not(.fairys-valtio-form-item-invalid-border-red), .fairys-valtio-form-layout-last-item-no-border > .fairys-valtio-form-layout-body > .fairys-valtio-form-item:last-child > .fairys-valtio-form-item-container > .fairys-valtio-form-item-body:not(.fairys-valtio-form-item-invalid-border-red) {
|
|
264
264
|
border-bottom: 0;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
+
.fairys-valtio-form-item-invalid-border-red {
|
|
268
|
+
border-bottom-color: red !important;
|
|
269
|
+
}
|
|
270
|
+
|
package/lib/index.js
CHANGED
|
@@ -6,6 +6,9 @@ var __webpack_modules__ = {
|
|
|
6
6
|
"./form/form": function(module) {
|
|
7
7
|
module.exports = require("./form/form.js");
|
|
8
8
|
},
|
|
9
|
+
"./form/hooks": function(module) {
|
|
10
|
+
module.exports = require("./form/hooks/index.js");
|
|
11
|
+
},
|
|
9
12
|
"./form/instance": function(module) {
|
|
10
13
|
module.exports = require("./form/instance/index.js");
|
|
11
14
|
},
|
|
@@ -56,28 +59,34 @@ function __webpack_require__(moduleId) {
|
|
|
56
59
|
var __webpack_exports__ = {};
|
|
57
60
|
(()=>{
|
|
58
61
|
__webpack_require__.r(__webpack_exports__);
|
|
59
|
-
var
|
|
62
|
+
var _form_hooks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./form/hooks");
|
|
63
|
+
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
64
|
+
for(var __WEBPACK_IMPORT_KEY__ in _form_hooks__WEBPACK_IMPORTED_MODULE_0__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
65
|
+
return _form_hooks__WEBPACK_IMPORTED_MODULE_0__[key];
|
|
66
|
+
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
67
|
+
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
68
|
+
var _form_instance__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./form/instance");
|
|
60
69
|
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
61
|
-
for(var __WEBPACK_IMPORT_KEY__ in
|
|
62
|
-
return
|
|
70
|
+
for(var __WEBPACK_IMPORT_KEY__ in _form_instance__WEBPACK_IMPORTED_MODULE_1__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
71
|
+
return _form_instance__WEBPACK_IMPORTED_MODULE_1__[key];
|
|
63
72
|
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
64
73
|
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
65
|
-
var
|
|
74
|
+
var _form_layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./form/layout");
|
|
66
75
|
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
67
|
-
for(var __WEBPACK_IMPORT_KEY__ in
|
|
68
|
-
return
|
|
76
|
+
for(var __WEBPACK_IMPORT_KEY__ in _form_layout__WEBPACK_IMPORTED_MODULE_2__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
77
|
+
return _form_layout__WEBPACK_IMPORTED_MODULE_2__[key];
|
|
69
78
|
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
70
79
|
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
71
|
-
var
|
|
80
|
+
var _form_form__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./form/form");
|
|
72
81
|
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
73
|
-
for(var __WEBPACK_IMPORT_KEY__ in
|
|
74
|
-
return
|
|
82
|
+
for(var __WEBPACK_IMPORT_KEY__ in _form_form__WEBPACK_IMPORTED_MODULE_3__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
83
|
+
return _form_form__WEBPACK_IMPORTED_MODULE_3__[key];
|
|
75
84
|
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
76
85
|
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
77
|
-
var
|
|
86
|
+
var _form_form_item__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./form/form.item");
|
|
78
87
|
var __WEBPACK_REEXPORT_OBJECT__ = {};
|
|
79
|
-
for(var __WEBPACK_IMPORT_KEY__ in
|
|
80
|
-
return
|
|
88
|
+
for(var __WEBPACK_IMPORT_KEY__ in _form_form_item__WEBPACK_IMPORTED_MODULE_4__)if ("default" !== __WEBPACK_IMPORT_KEY__) __WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = (function(key) {
|
|
89
|
+
return _form_form_item__WEBPACK_IMPORTED_MODULE_4__[key];
|
|
81
90
|
}).bind(0, __WEBPACK_IMPORT_KEY__);
|
|
82
91
|
__webpack_require__.d(__webpack_exports__, __WEBPACK_REEXPORT_OBJECT__);
|
|
83
92
|
})();
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"author": "SunLxy <1011771396@qq.com>",
|
|
4
4
|
"description": "使用 valtio 实现的表单基础库, 使其更加便捷,同时支持`PC`、`H5`、`Taro`,同时也更加灵活。",
|
|
5
5
|
"homepage": "https://github.com/autumn-fairy-tales/fairys-taro-react",
|
|
6
|
-
"version": "0.0.
|
|
6
|
+
"version": "0.0.9",
|
|
7
7
|
"main": "lib/index.js",
|
|
8
8
|
"types": "esm/index.d.ts",
|
|
9
9
|
"module": "esm/index.js",
|
|
@@ -35,4 +35,4 @@
|
|
|
35
35
|
"@types/react": "~18.2.21",
|
|
36
36
|
"react": "^18.0.0"
|
|
37
37
|
}
|
|
38
|
-
}
|
|
38
|
+
}
|
package/src/form/form.item.tsx
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
/**表单项*/
|
|
2
2
|
|
|
3
3
|
import { MObject } from 'interface';
|
|
4
|
-
import React, { useMemo } from 'react';
|
|
4
|
+
import React, { useEffect, useMemo } from 'react';
|
|
5
5
|
import clsx from 'clsx';
|
|
6
6
|
import { useFairysValtioFormInstanceContextState, FairysValtioFormInstance } from './instance';
|
|
7
7
|
import { useFairysValtioFormLayoutContext, FairysValtioFormLayoutContextOptions } from './layout';
|
|
8
|
+
import { FairysValtioFormParentAttrs, useFairysValtioFormAttrsName } from './hooks';
|
|
9
|
+
import { get } from './utils';
|
|
10
|
+
import { RuleItem } from 'async-validator';
|
|
8
11
|
|
|
9
12
|
export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* 表单项名称 ,字段需要和存储的字段路径一致
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* 路径中的值为 number 类型时,会创建一个空数组。路径中的值为 string 类型时,会创建一个空对象。最后一个直接赋值
|
|
18
|
+
*
|
|
19
|
+
* 默认:"name"
|
|
20
|
+
* 嵌套字段:"name.a.doc" ===> { name: { a: { doc: undefined } } }
|
|
21
|
+
* 嵌套字段:"name[1].a.doc" ===> { name: [{}, { a: { doc: undefined } }] }
|
|
22
|
+
* 嵌套字段:"name.a[2].doc" ===> { name: { a: [{}, {}, { doc: undefined }] } }
|
|
23
|
+
*/
|
|
24
|
+
name?: string;
|
|
12
25
|
/**表单项标签*/
|
|
13
26
|
label?: string;
|
|
14
27
|
/**传递组件字段*/
|
|
@@ -51,9 +64,17 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
|
|
|
51
64
|
/**是否显示冒号*/
|
|
52
65
|
showColon?: boolean;
|
|
53
66
|
/**底部显示边框*/
|
|
54
|
-
|
|
67
|
+
itemBorderType?: FairysValtioFormLayoutContextOptions['itemBorderType'];
|
|
68
|
+
/**边框颜色*/
|
|
69
|
+
itemBorderColor?: React.CSSProperties['borderColor'];
|
|
70
|
+
/**是否校验失败时显示红色边框*/
|
|
71
|
+
isInvalidBorderRed?: boolean;
|
|
55
72
|
/**输入框属性*/
|
|
56
73
|
attrs?: any;
|
|
74
|
+
/**是否拼接父级字段名*/
|
|
75
|
+
isJoinParentField?: boolean;
|
|
76
|
+
/**校验规则*/
|
|
77
|
+
rules?: RuleItem[];
|
|
57
78
|
}
|
|
58
79
|
|
|
59
80
|
/**
|
|
@@ -63,7 +84,7 @@ export interface FairysValtioFormItemAttrsProps<T extends MObject<T> = object> {
|
|
|
63
84
|
*
|
|
64
85
|
* ```tsx
|
|
65
86
|
import { Fragment } from 'react'
|
|
66
|
-
import { useFairysValtioFormItemAttrs } from "@fairys/valtio-form"
|
|
87
|
+
import { useFairysValtioFormItemAttrs , FairysValtioFormParentAttrsContext } from "@fairys/valtio-form"
|
|
67
88
|
import type { FairysValtioFormItemAttrsProps } from "@fairys/valtio-form"
|
|
68
89
|
export interface FormItemProps extends FairysValtioFormItemAttrsProps{}
|
|
69
90
|
|
|
@@ -72,10 +93,11 @@ export const FormItem = (props: FormItemProps) => {
|
|
|
72
93
|
const {
|
|
73
94
|
itemClassName, itemStyle, containerClassName, itemLabelClassName, itemLabelStyle,
|
|
74
95
|
itemBodyClassName, itemBodyStyle, itemInputClassName, itemExtraClassName, errorClassName, helpClassName,
|
|
75
|
-
isInvalid,
|
|
96
|
+
isInvalid, itemBorderType, children, error,formAttrsNameInstance
|
|
76
97
|
} = useFairysValtioFormItemAttrs(props)
|
|
77
98
|
|
|
78
99
|
return (
|
|
100
|
+
<FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
|
|
79
101
|
<View className={itemClassName} style={itemStyle}>
|
|
80
102
|
<View className={containerClassName}>
|
|
81
103
|
<View className={itemLabelClassName} style={itemLabelStyle}>
|
|
@@ -86,12 +108,13 @@ export const FormItem = (props: FormItemProps) => {
|
|
|
86
108
|
{children}
|
|
87
109
|
</View>
|
|
88
110
|
{extra ? <View className={itemExtraClassName}>{extra}</View> : <Fragment />}
|
|
89
|
-
{
|
|
111
|
+
{itemBorderType === 'body' && isInvalid ? <View className={errorClassName}>{error}</View> : <Fragment />}
|
|
90
112
|
</View>
|
|
91
113
|
</View>
|
|
92
114
|
{helpText ? <View className={helpClassName}>{helpText}</View> : <Fragment />}
|
|
93
|
-
{isInvalid &&
|
|
115
|
+
{isInvalid && itemBorderType !== 'body' ? <View className={errorClassName}>{error}</View> : <Fragment />}
|
|
94
116
|
</View>
|
|
117
|
+
</FairysValtioFormParentAttrsContext.Provider>
|
|
95
118
|
);
|
|
96
119
|
}
|
|
97
120
|
* ```
|
|
@@ -100,7 +123,7 @@ export const FormItem = (props: FormItemProps) => {
|
|
|
100
123
|
export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(props: FairysValtioFormItemAttrsProps<T>) {
|
|
101
124
|
const [layoutAttrs] = useFairysValtioFormLayoutContext();
|
|
102
125
|
const colCount = layoutAttrs.colCount || 1;
|
|
103
|
-
const parent_borderedType = layoutAttrs.
|
|
126
|
+
const parent_borderedType = layoutAttrs.itemBorderType || 'bottom';
|
|
104
127
|
const parent_errorLayout = layoutAttrs.errorLayout || 'right-bottom';
|
|
105
128
|
const parent_formItemClassName = layoutAttrs.formItemClassName;
|
|
106
129
|
const parent_formItemLabelClassName = layoutAttrs.formItemLabelClassName;
|
|
@@ -109,6 +132,10 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
109
132
|
const parent_formItemBodyClassName = layoutAttrs.formItemBodyClassName;
|
|
110
133
|
const parent_formItemBodyStyle = layoutAttrs.formItemBodyStyle;
|
|
111
134
|
const parent_labelMode = layoutAttrs.labelMode || 'between';
|
|
135
|
+
const parent_itemBorderColor = layoutAttrs.itemBorderColor;
|
|
136
|
+
const parent_isInvalidBorderRed = layoutAttrs.isInvalidBorderRed;
|
|
137
|
+
const parent_showColon = layoutAttrs.showColon;
|
|
138
|
+
|
|
112
139
|
const {
|
|
113
140
|
name,
|
|
114
141
|
valuePropName = 'value',
|
|
@@ -128,14 +155,34 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
128
155
|
colSpan = 1,
|
|
129
156
|
rowSpan = 1,
|
|
130
157
|
isRequired: _isRequired,
|
|
131
|
-
|
|
158
|
+
itemBorderType = parent_borderedType,
|
|
132
159
|
attrs = {},
|
|
133
|
-
showColon =
|
|
160
|
+
showColon = parent_showColon,
|
|
161
|
+
itemBorderColor = parent_itemBorderColor,
|
|
162
|
+
isInvalidBorderRed = parent_isInvalidBorderRed,
|
|
163
|
+
isJoinParentField = true,
|
|
164
|
+
rules,
|
|
134
165
|
} = props;
|
|
166
|
+
|
|
167
|
+
const {
|
|
168
|
+
name: _name,
|
|
169
|
+
paths,
|
|
170
|
+
parentName,
|
|
171
|
+
formAttrsNameInstance,
|
|
172
|
+
} = useFairysValtioFormAttrsName({ name, isJoinParentField });
|
|
135
173
|
const [state, errorState, formInstance] = useFairysValtioFormInstanceContextState<T>();
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
174
|
+
const value = useMemo(() => get(state, paths), [state, paths]);
|
|
175
|
+
const error = errorState[_name];
|
|
176
|
+
formInstance.nameToPaths[_name] = paths;
|
|
177
|
+
/**挂载校验规则*/
|
|
178
|
+
if (Array.isArray(rules) && rules.length) {
|
|
179
|
+
formInstance.mountRules[_name] = rules;
|
|
180
|
+
}
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
return () => {
|
|
183
|
+
formInstance.removeRules(_name);
|
|
184
|
+
};
|
|
185
|
+
}, [_name]);
|
|
139
186
|
|
|
140
187
|
const onValueChange = (event: any) => {
|
|
141
188
|
let value = event;
|
|
@@ -148,7 +195,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
148
195
|
if (typeof formatValue === 'function') {
|
|
149
196
|
value = formatValue(value, formInstance, event);
|
|
150
197
|
}
|
|
151
|
-
formInstance.
|
|
198
|
+
formInstance.updatedValueByPaths(_name, value);
|
|
152
199
|
if (typeof onAfterUpdate === 'function') {
|
|
153
200
|
onAfterUpdate(value, formInstance, event);
|
|
154
201
|
}
|
|
@@ -185,14 +232,16 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
185
232
|
return clsx(
|
|
186
233
|
'fairys-valtio-form-item fairystaroform__p-[4px] fairystaroform__text-[12px] fairystaroform__relative fairystaroform__flex fairystaroform__flex-col fairystaroform__box-border fairystaroform__break-all',
|
|
187
234
|
{
|
|
235
|
+
'fairys-valtio-form-item-invalid': isInvalid,
|
|
236
|
+
'fairys-valtio-form-item-invalid-border-red': isInvalid && isInvalidBorderRed && itemBorderType === 'bottom',
|
|
188
237
|
'fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200':
|
|
189
|
-
|
|
238
|
+
itemBorderType === 'bottom',
|
|
190
239
|
[labelMode]: labelMode,
|
|
191
240
|
},
|
|
192
|
-
className,
|
|
193
241
|
parent_formItemClassName,
|
|
242
|
+
className,
|
|
194
243
|
);
|
|
195
|
-
}, [className, parent_formItemClassName, labelMode,
|
|
244
|
+
}, [className, parent_formItemClassName, labelMode, itemBorderType, isInvalid, isInvalidBorderRed]);
|
|
196
245
|
|
|
197
246
|
/**表单项容器类名*/
|
|
198
247
|
const itemContainer_cls = useMemo(() => {
|
|
@@ -235,12 +284,13 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
235
284
|
'fairystaroform__flex-row fairystaroform__justify-end': labelMode === 'between' || labelMode === 'top',
|
|
236
285
|
'fairystaroform__flex-row': labelMode === 'top',
|
|
237
286
|
'fairystaroform__border-b fairystaroform__border-b-solid fairystaroform__border-b-gray-200 ':
|
|
238
|
-
|
|
287
|
+
itemBorderType === 'body',
|
|
288
|
+
'fairys-valtio-form-item-invalid-border-red': isInvalid && isInvalidBorderRed && itemBorderType === 'body',
|
|
239
289
|
},
|
|
240
|
-
bodyClassName,
|
|
241
290
|
parent_formItemBodyClassName,
|
|
291
|
+
bodyClassName,
|
|
242
292
|
);
|
|
243
|
-
}, [bodyClassName, labelMode,
|
|
293
|
+
}, [bodyClassName, labelMode, itemBorderType, parent_formItemBodyClassName, isInvalid, isInvalidBorderRed]);
|
|
244
294
|
|
|
245
295
|
// 表单项输入类名
|
|
246
296
|
const itemInput_cls = useMemo(() => {
|
|
@@ -297,7 +347,7 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
297
347
|
return {
|
|
298
348
|
value,
|
|
299
349
|
isInvalid,
|
|
300
|
-
|
|
350
|
+
itemBorderType,
|
|
301
351
|
onValueChange,
|
|
302
352
|
colSpan,
|
|
303
353
|
rowSpan,
|
|
@@ -309,14 +359,28 @@ export function useFairysValtioFormItemAttrs<T extends MObject<T> = object>(prop
|
|
|
309
359
|
errorState,
|
|
310
360
|
formInstance,
|
|
311
361
|
error,
|
|
362
|
+
_name,
|
|
363
|
+
name,
|
|
364
|
+
paths,
|
|
365
|
+
parentName,
|
|
366
|
+
formAttrsNameInstance,
|
|
312
367
|
// ================================================================================
|
|
313
368
|
itemClassName: item_cls,
|
|
314
|
-
itemStyle: {
|
|
369
|
+
itemStyle: {
|
|
370
|
+
...(itemBorderColor && itemBorderType === 'bottom' ? { borderBottomColor: itemBorderColor } : {}),
|
|
371
|
+
...(parent_formItemStyle || {}),
|
|
372
|
+
...styleBase,
|
|
373
|
+
...(style || {}),
|
|
374
|
+
},
|
|
315
375
|
containerClassName: itemContainer_cls,
|
|
316
376
|
itemLabelClassName: itemLabel_cls,
|
|
317
377
|
itemLabelStyle: { ...(parent_formItemLabelStyle || {}), ...(labelStyle || {}) },
|
|
318
378
|
itemBodyClassName: itemBody_cls,
|
|
319
|
-
itemBodyStyle: {
|
|
379
|
+
itemBodyStyle: {
|
|
380
|
+
...(itemBorderColor && itemBorderType === 'body' ? { borderBottomColor: itemBorderColor } : {}),
|
|
381
|
+
...(parent_formItemBodyStyle || {}),
|
|
382
|
+
...(bodyStyle || {}),
|
|
383
|
+
},
|
|
320
384
|
itemInputClassName: itemInput_cls,
|
|
321
385
|
itemExtraClassName: itemExtra_cls,
|
|
322
386
|
errorClassName: itemError_cls,
|
|
@@ -329,31 +393,41 @@ export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> = object>
|
|
|
329
393
|
/**表单项值*/
|
|
330
394
|
value?: any;
|
|
331
395
|
/**是否校验错误*/
|
|
332
|
-
isInvalid
|
|
396
|
+
isInvalid: boolean;
|
|
333
397
|
/**边框类型*/
|
|
334
|
-
|
|
398
|
+
itemBorderType: FairysValtioFormLayoutContextOptions['itemBorderType'];
|
|
335
399
|
/**值改变事件*/
|
|
336
|
-
onValueChange
|
|
400
|
+
onValueChange: (event: any) => void;
|
|
337
401
|
/**当前表单项占据列数*/
|
|
338
|
-
colSpan
|
|
402
|
+
colSpan: number;
|
|
339
403
|
/**当前表单项占据行数*/
|
|
340
|
-
rowSpan
|
|
404
|
+
rowSpan: number;
|
|
341
405
|
/**列数*/
|
|
342
|
-
colCount
|
|
406
|
+
colCount: number;
|
|
343
407
|
/**标签显示模式*/
|
|
344
|
-
labelMode
|
|
408
|
+
labelMode: FairysValtioFormLayoutContextOptions['labelMode'];
|
|
345
409
|
/**错误提示位置*/
|
|
346
|
-
errorLayout
|
|
410
|
+
errorLayout: FairysValtioFormLayoutContextOptions['errorLayout'];
|
|
347
411
|
/**是否必填*/
|
|
348
|
-
isRequired
|
|
412
|
+
isRequired: boolean;
|
|
349
413
|
/**表单状态*/
|
|
350
|
-
state
|
|
414
|
+
state: T;
|
|
351
415
|
/**错误状态*/
|
|
352
|
-
errorState
|
|
416
|
+
errorState: Record<PropertyKey, string[]>;
|
|
353
417
|
/**表单实例*/
|
|
354
|
-
formInstance
|
|
418
|
+
formInstance: FairysValtioFormInstance<T>;
|
|
355
419
|
/**错误信息*/
|
|
356
420
|
error?: string[];
|
|
421
|
+
/**拼接父级字段名后得到的表单项名称*/
|
|
422
|
+
_name?: string;
|
|
423
|
+
/**表单项名称*/
|
|
424
|
+
name?: string;
|
|
425
|
+
/**表单项路径*/
|
|
426
|
+
paths?: (string | number)[];
|
|
427
|
+
/**父级字段名*/
|
|
428
|
+
parentName?: string;
|
|
429
|
+
/**表单属性名实例*/
|
|
430
|
+
formAttrsNameInstance: FairysValtioFormParentAttrs;
|
|
357
431
|
// =========================================
|
|
358
432
|
/**表单项类名*/
|
|
359
433
|
itemClassName: string;
|
|
@@ -380,3 +454,97 @@ export interface FairysValtioFormItemAttrsReturn<T extends MObject<T> = object>
|
|
|
380
454
|
/**子元素*/
|
|
381
455
|
children?: React.ReactNode;
|
|
382
456
|
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* 没有样式的表单项属性,仅返回基础输入组件参数
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
*
|
|
463
|
+
*```tsx
|
|
464
|
+
import { Fragment } from 'react'
|
|
465
|
+
import { useFairysValtioFormItemAttrs, FairysValtioFormParentAttrsContext } from "@fairys/valtio-form"
|
|
466
|
+
import type { FairysValtioFormItemAttrsProps } from "@fairys/valtio-form"
|
|
467
|
+
export interface FormItemProps extends FairysValtioFormItemAttrsProps{}
|
|
468
|
+
|
|
469
|
+
export const FormItem = (props: FormItemProps) => {
|
|
470
|
+
const { children , formAttrsNameInstance } = useFairysValtioFormItemNoStyleAttrs(props)
|
|
471
|
+
return <FairysValtioFormParentAttrsContext.Provider value={formAttrsNameInstance}>
|
|
472
|
+
{children}
|
|
473
|
+
</FairysValtioFormParentAttrsContext.Provider>
|
|
474
|
+
}
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
export function useFairysValtioFormItemNoStyleAttrs<T extends MObject<T> = object>(
|
|
478
|
+
props: FairysValtioFormItemAttrsProps<T>,
|
|
479
|
+
) {
|
|
480
|
+
const {
|
|
481
|
+
name,
|
|
482
|
+
valuePropName = 'value',
|
|
483
|
+
getValueFromEvent,
|
|
484
|
+
formatValue,
|
|
485
|
+
onAfterUpdate,
|
|
486
|
+
trigger = 'onChange',
|
|
487
|
+
children,
|
|
488
|
+
attrs = {},
|
|
489
|
+
isJoinParentField = true,
|
|
490
|
+
rules,
|
|
491
|
+
} = props;
|
|
492
|
+
const [state, errorState, formInstance] = useFairysValtioFormInstanceContextState<T>();
|
|
493
|
+
const {
|
|
494
|
+
name: _name,
|
|
495
|
+
paths,
|
|
496
|
+
parentName,
|
|
497
|
+
formAttrsNameInstance,
|
|
498
|
+
} = useFairysValtioFormAttrsName({ name, isJoinParentField });
|
|
499
|
+
const value = useMemo(() => get(state, paths), [state, paths]);
|
|
500
|
+
const error = errorState[_name];
|
|
501
|
+
formInstance.nameToPaths[_name] = paths;
|
|
502
|
+
/**挂载校验规则*/
|
|
503
|
+
if (Array.isArray(rules) && rules.length) {
|
|
504
|
+
formInstance.mountRules[_name] = rules;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
useEffect(() => {
|
|
508
|
+
return () => {
|
|
509
|
+
formInstance.removeRules(_name);
|
|
510
|
+
};
|
|
511
|
+
}, [_name]);
|
|
512
|
+
|
|
513
|
+
const onValueChange = (event: any) => {
|
|
514
|
+
let value = event;
|
|
515
|
+
const target = event?.detail || event?.target;
|
|
516
|
+
if (typeof getValueFromEvent === 'function') {
|
|
517
|
+
value = getValueFromEvent(event, formInstance);
|
|
518
|
+
} else if (event && target && typeof target === 'object' && valuePropName in target) {
|
|
519
|
+
value = target.valuePropName;
|
|
520
|
+
}
|
|
521
|
+
if (typeof formatValue === 'function') {
|
|
522
|
+
value = formatValue(value, formInstance, event);
|
|
523
|
+
}
|
|
524
|
+
formInstance.updatedValueByPaths(_name, value);
|
|
525
|
+
if (typeof onAfterUpdate === 'function') {
|
|
526
|
+
onAfterUpdate(value, formInstance, event);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
/**基础组件参数*/
|
|
530
|
+
const baseControl = {
|
|
531
|
+
...attrs,
|
|
532
|
+
name,
|
|
533
|
+
[valuePropName]: value,
|
|
534
|
+
[trigger]: onValueChange,
|
|
535
|
+
};
|
|
536
|
+
return {
|
|
537
|
+
value,
|
|
538
|
+
error,
|
|
539
|
+
onValueChange,
|
|
540
|
+
state,
|
|
541
|
+
errorState,
|
|
542
|
+
formInstance,
|
|
543
|
+
_name,
|
|
544
|
+
name,
|
|
545
|
+
paths,
|
|
546
|
+
parentName,
|
|
547
|
+
formAttrsNameInstance,
|
|
548
|
+
children: React.isValidElement(children) ? React.cloneElement(children, { ...baseControl }) : children,
|
|
549
|
+
};
|
|
550
|
+
}
|