taro-form-react 0.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.
@@ -0,0 +1,87 @@
1
+ .tfr-form-item-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ justify-content: start;
5
+ width: 100%;
6
+ box-sizing: border-box;
7
+ }
8
+
9
+ .tfr-form-item-container-horizontal {
10
+ align-items: flex-end;
11
+ }
12
+
13
+ .tfr-form-item-inner {
14
+ position: relative;
15
+ display: flex;
16
+ width: 100%;
17
+ gap: 16rpx;
18
+ box-sizing: border-box;
19
+ }
20
+
21
+ .tfr-form-item-inner-horizontal {
22
+ flex-direction: row;
23
+ align-items: start;
24
+ justify-content: start;
25
+ }
26
+
27
+ .tfr-form-item-inner-vertical {
28
+ flex-direction: column;
29
+ align-items: start;
30
+ justify-content: start;
31
+ }
32
+
33
+ .tfr-form-item-error-text {
34
+ color: #FF4D4F;
35
+ font-size: 28rpx;
36
+ margin-top: 8rpx;
37
+ box-sizing: border-box;
38
+ }
39
+
40
+ .tfr-form-label {
41
+ display: flex;
42
+ flex-direction: row;
43
+ align-items: center;
44
+ position: relative;
45
+ }
46
+
47
+ .tfr-form-label-no-asterisk-space {
48
+ left: -10rpx;
49
+ }
50
+
51
+ .tfr-form-label-label {
52
+ font-size: 28rpx;
53
+ display: inline-block;
54
+ position: relative;
55
+ white-space: nowrap;
56
+ box-sizing: border-box;
57
+ }
58
+
59
+ .tfr-form-label-label::before {
60
+ content: '*';
61
+ color: #FF4D4F;
62
+ margin-right: 4rpx;
63
+ font-size: 28rpx;
64
+ font-family: 'SimSun', 'sans-serif';
65
+ }
66
+
67
+ .tfr-form-label-label.tfr-small.tfr-show-asterisk::before {
68
+ display: inline-block;
69
+ }
70
+
71
+ .tfr-form-label-label.tfr-small.tfr-hide-asterisk::before {
72
+ display: none;
73
+ }
74
+
75
+ .tfr-form-label-label.tfr-normal.tfr-show-asterisk::before {
76
+ opacity: 1;
77
+ }
78
+
79
+ .tfr-form-label-label.ntfr-ormal.tfr-hide-asterisk::before {
80
+ opacity: 0;
81
+ }
82
+
83
+ .tfr-form-label-colon {
84
+ font-size: 28rpx;
85
+ position: relative;
86
+ white-space: nowrap;
87
+ }
@@ -0,0 +1,7 @@
1
+ import type { NamePath } from "../types";
2
+
3
+ export const namePathToString = (name: NamePath) => {
4
+ return name
5
+ .map(item => (typeof item === "number" ? `[${item}]` : `.${item}`))
6
+ .join("");
7
+ };
@@ -0,0 +1,55 @@
1
+ import { isEmpty } from "@/utils/tools";
2
+
3
+ import type { Rule } from "../types";
4
+
5
+ export const validateRules = async (value: any, rules: Rule[], validateFirst: boolean | "parallel" = false) => {
6
+ const errors = [] as string[];
7
+
8
+ const validateRule = async (rule: Rule) => {
9
+ switch (true) {
10
+ case "required" in rule:
11
+ if (isEmpty(value)) {
12
+ return rule.message;
13
+ }
14
+ break;
15
+ case "pattern" in rule:
16
+ if (!isEmpty(value) && !rule.pattern.test(value)) {
17
+ return rule.message;
18
+ }
19
+ break;
20
+ case "max" in rule:
21
+ if (!isEmpty(value) && value.length > (rule.max ?? Infinity)) {
22
+ return rule.message;
23
+ }
24
+ break;
25
+ case "min" in rule:
26
+ if (!isEmpty(value) && value.length < (rule.min ?? -Infinity)) {
27
+ return rule.message;
28
+ }
29
+ break;
30
+ case "validator" in rule:
31
+ if (!isEmpty(value)) {
32
+ return await rule.validator(value);
33
+ }
34
+ }
35
+ };
36
+
37
+ if (validateFirst === "parallel") {
38
+ const results = await Promise.all(rules.map(rule => validateRule(rule)));
39
+ for (const error of results) {
40
+ if (error) {
41
+ errors.push(error);
42
+ }
43
+ }
44
+ } else {
45
+ for (const rule of rules) {
46
+ const error = await validateRule(rule);
47
+ if (error) {
48
+ errors.push(error);
49
+ if (validateFirst) return errors;
50
+ }
51
+ }
52
+ }
53
+
54
+ return errors.length ? errors : undefined;
55
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * 检查给定的值是否为空。
3
+ *
4
+ * @param {any} value - 需要检查的值。
5
+ * @returns {boolean} 如果值未定义、为null、为空字符串、为空数组或为空对象,则返回true,否则返回false。
6
+ */
7
+ export const isEmpty = (value: any): boolean => {
8
+ return (
9
+ value === undefined ||
10
+ value === null ||
11
+ value === "" ||
12
+ (Array.isArray(value) && value.length === 0) ||
13
+ (typeof value === "object" && Object.keys(value).length === 0)
14
+ );
15
+ };
16
+
17
+ /**
18
+ * 过滤对象中的 undefined 和 null 值。
19
+ * @param {T} object - 要过滤的对象。
20
+ * @param {boolean} [filterNull=false] - 是否过滤 null 值。
21
+ * @returns {T} - 过滤后的对象。
22
+ * @template T
23
+ */
24
+ export function filterUndefined<T extends Record<string, any>> (object: T, filterNull: boolean = false): T {
25
+ return Object.entries(object).reduce((acc, [key, value]) => {
26
+ if (value !== undefined && (filterNull ? value !== null : true)) {
27
+ acc[key] = value;
28
+ }
29
+ return acc;
30
+ }, {} as any);
31
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2017",
4
+ "module": "ESNext",
5
+ "removeComments": true,
6
+ "preserveConstEnums": true,
7
+ "moduleResolution": "node",
8
+ "experimentalDecorators": true,
9
+ "noImplicitAny": false,
10
+ "allowSyntheticDefaultImports": true,
11
+ "outDir": "lib",
12
+ "noUnusedLocals": false,
13
+ "noUnusedParameters": false,
14
+ "strictNullChecks": true,
15
+ "sourceMap": true,
16
+ "baseUrl": ".",
17
+ "rootDir": ".",
18
+ "jsx": "react-jsx",
19
+ "allowJs": true,
20
+ "resolveJsonModule": true,
21
+ "skipLibCheck": true,
22
+ "incremental": true,
23
+ "typeRoots": [
24
+ "node_modules/@types"
25
+ ],
26
+ "paths": {
27
+ "@/*": [
28
+ "src/*"
29
+ ]
30
+ },
31
+ },
32
+ "include": [
33
+ "./src",
34
+ ],
35
+ "exclude": [
36
+ "node_modules/*",
37
+ "dist/*",
38
+ ],
39
+ "compileOnSave": false
40
+ }