kmod-cli 1.7.2 → 1.7.3
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
CHANGED
|
@@ -38,69 +38,70 @@ npx kumod add --all # add all component
|
|
|
38
38
|
npx kumod add button # add button component
|
|
39
39
|
#...any other command
|
|
40
40
|
```
|
|
41
|
-
## Components
|
|
42
|
-
|
|
43
|
-
- access-denied
|
|
44
|
-
- api-service
|
|
45
|
-
- breadcumb
|
|
46
|
-
- button
|
|
47
|
-
- calculate
|
|
48
|
-
- calendar
|
|
49
|
-
- color-by-text
|
|
50
|
-
- column-table
|
|
51
|
-
- config
|
|
52
|
-
- count-down
|
|
53
|
-
- count-input
|
|
54
|
-
- data-table
|
|
55
|
-
- date-input
|
|
56
|
-
- date-range-picker
|
|
57
|
-
- datetime-picker
|
|
58
|
-
- fade-on-scroll
|
|
59
|
-
- feature-config
|
|
60
|
-
- feature-guard
|
|
61
|
-
- gradient-outline
|
|
62
|
-
- gradient-svg
|
|
63
|
-
- grid-layout
|
|
64
|
-
- hash-aes
|
|
65
|
-
- hydrate-guard
|
|
66
|
-
- idb
|
|
67
|
-
- image
|
|
68
|
-
- input
|
|
69
|
-
- keys
|
|
70
|
-
- kookies
|
|
71
|
-
- label
|
|
72
|
-
- lib
|
|
73
|
-
- list-map
|
|
74
|
-
- loader-slash-gradient
|
|
75
|
-
- masonry-gallery
|
|
76
|
-
- modal
|
|
77
|
-
- multi-select
|
|
78
|
-
- non-hydration
|
|
79
|
-
- period-input
|
|
80
|
-
- popover
|
|
81
|
-
- portal
|
|
82
|
-
- query
|
|
83
|
-
- rbac
|
|
84
|
-
- readme
|
|
85
|
-
- refine-provider
|
|
86
|
-
- safe-action
|
|
87
|
-
- segments-circle
|
|
88
|
-
- select
|
|
89
|
-
- simple-validate
|
|
90
|
-
- single-select
|
|
91
|
-
- spam-guard
|
|
92
|
-
- storage
|
|
93
|
-
- stripe-effect
|
|
94
|
-
- stroke-circle
|
|
95
|
-
- switch
|
|
96
|
-
- table
|
|
97
|
-
- text-hover-effect
|
|
98
|
-
- time-picker
|
|
99
|
-
- time-picker-input
|
|
100
|
-
- time-picker-utils
|
|
101
|
-
- timout-loader
|
|
102
|
-
- toast
|
|
103
|
-
- utils
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
- access-denied
|
|
44
|
+
- api-service
|
|
45
|
+
- breadcumb
|
|
46
|
+
- button
|
|
47
|
+
- calculate
|
|
48
|
+
- calendar
|
|
49
|
+
- color-by-text
|
|
50
|
+
- column-table
|
|
51
|
+
- config
|
|
52
|
+
- count-down
|
|
53
|
+
- count-input
|
|
54
|
+
- data-table
|
|
55
|
+
- date-input
|
|
56
|
+
- date-range-picker
|
|
57
|
+
- datetime-picker
|
|
58
|
+
- fade-on-scroll
|
|
59
|
+
- feature-config
|
|
60
|
+
- feature-guard
|
|
61
|
+
- gradient-outline
|
|
62
|
+
- gradient-svg
|
|
63
|
+
- grid-layout
|
|
64
|
+
- hash-aes
|
|
65
|
+
- hydrate-guard
|
|
66
|
+
- idb
|
|
67
|
+
- image
|
|
68
|
+
- input
|
|
69
|
+
- keys
|
|
70
|
+
- kookies
|
|
71
|
+
- label
|
|
72
|
+
- lib
|
|
73
|
+
- list-map
|
|
74
|
+
- loader-slash-gradient
|
|
75
|
+
- masonry-gallery
|
|
76
|
+
- modal
|
|
77
|
+
- multi-select
|
|
78
|
+
- non-hydration
|
|
79
|
+
- period-input
|
|
80
|
+
- popover
|
|
81
|
+
- portal
|
|
82
|
+
- query
|
|
83
|
+
- rbac
|
|
84
|
+
- readme
|
|
85
|
+
- refine-provider
|
|
86
|
+
- safe-action
|
|
87
|
+
- segments-circle
|
|
88
|
+
- select
|
|
89
|
+
- simple-validate
|
|
90
|
+
- single-select
|
|
91
|
+
- spam-guard
|
|
92
|
+
- storage
|
|
93
|
+
- stripe-effect
|
|
94
|
+
- stroke-circle
|
|
95
|
+
- switch
|
|
96
|
+
- table
|
|
97
|
+
- text-hover-effect
|
|
98
|
+
- time-picker
|
|
99
|
+
- time-picker-input
|
|
100
|
+
- time-picker-utils
|
|
101
|
+
- timout-loader
|
|
102
|
+
- toast
|
|
103
|
+
- utils
|
|
104
|
+
|
|
104
105
|
## Contributing
|
|
105
106
|
|
|
106
107
|
Contributions are welcome! Please open issues or pull requests.
|
|
@@ -83,19 +83,20 @@ export const REGEXS = {
|
|
|
83
83
|
uuid: /[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}/,
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
interface ValidationRule {
|
|
86
|
+
export interface ValidationRule<V = unknown> {
|
|
87
87
|
required?: boolean;
|
|
88
88
|
pattern?: RegExp;
|
|
89
|
-
custom?: (value: string) => boolean;
|
|
90
89
|
minLength?: number;
|
|
91
90
|
maxLength?: number;
|
|
92
91
|
errorMessage?: string;
|
|
92
|
+
custom?: (value: V) => boolean;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
export type ValidationRules<T> = Partial<{
|
|
96
|
-
[K in keyof T]: ValidationRule
|
|
96
|
+
[K in keyof T]: ValidationRule<T[K]>;
|
|
97
97
|
}>;
|
|
98
98
|
|
|
99
|
+
|
|
99
100
|
type ValidationErrors<T> = {
|
|
100
101
|
[K in keyof T]?: string;
|
|
101
102
|
};
|
|
@@ -107,32 +108,48 @@ export const useFormValidator = <T extends Record<string, any>>(
|
|
|
107
108
|
const [values, setValues] = useState<T>(initialValues);
|
|
108
109
|
const [errors, setErrors] = useState<ValidationErrors<T>>({});
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
const validateField = <K extends keyof T>(
|
|
112
|
+
field: K,
|
|
113
|
+
value: T[K]
|
|
114
|
+
): string | undefined => {
|
|
115
|
+
const rules = validationRules[field];
|
|
116
|
+
if (!rules) return undefined;
|
|
117
|
+
|
|
118
|
+
if (rules.required) {
|
|
119
|
+
if (
|
|
120
|
+
value === '' ||
|
|
121
|
+
value === null ||
|
|
122
|
+
value === undefined
|
|
123
|
+
) {
|
|
124
|
+
return rules.errorMessage || 'This field is required.';
|
|
116
125
|
}
|
|
126
|
+
}
|
|
117
127
|
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
if (rules.pattern && typeof value === 'string') {
|
|
129
|
+
if (!rules.pattern.test(value)) {
|
|
130
|
+
return rules.errorMessage || 'Invalid format.';
|
|
120
131
|
}
|
|
132
|
+
}
|
|
121
133
|
|
|
122
|
-
|
|
134
|
+
if (rules.minLength && typeof value === 'string') {
|
|
135
|
+
if (value.length < rules.minLength) {
|
|
123
136
|
return rules.errorMessage || `Minimum length is ${rules.minLength}.`;
|
|
124
137
|
}
|
|
138
|
+
}
|
|
125
139
|
|
|
126
|
-
|
|
140
|
+
if (rules.maxLength && typeof value === 'string') {
|
|
141
|
+
if (value.length > rules.maxLength) {
|
|
127
142
|
return rules.errorMessage || `Maximum length is ${rules.maxLength}.`;
|
|
128
143
|
}
|
|
144
|
+
}
|
|
129
145
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
146
|
+
if (rules.custom && !rules.custom(value)) {
|
|
147
|
+
return rules.errorMessage || 'Invalid value.';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return undefined;
|
|
151
|
+
};
|
|
133
152
|
|
|
134
|
-
return undefined;
|
|
135
|
-
};
|
|
136
153
|
|
|
137
154
|
const validateAllFields = (): boolean => {
|
|
138
155
|
const newErrors: ValidationErrors<T> = {};
|
|
@@ -152,28 +169,30 @@ export const useFormValidator = <T extends Record<string, any>>(
|
|
|
152
169
|
};
|
|
153
170
|
|
|
154
171
|
// validate array of fields
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
172
|
+
const validateFields = (fields: readonly (keyof T)[]): boolean => {
|
|
173
|
+
const newErrors: ValidationErrors<T> = {};
|
|
174
|
+
let isValid = true;
|
|
158
175
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
176
|
+
for (const field of fields) {
|
|
177
|
+
const value = values[field];
|
|
178
|
+
const error = validateField(field, value);
|
|
179
|
+
if (error) {
|
|
180
|
+
isValid = false;
|
|
181
|
+
newErrors[field] = error;
|
|
166
182
|
}
|
|
183
|
+
}
|
|
167
184
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
185
|
+
setErrors(prev => ({ ...prev, ...newErrors }));
|
|
186
|
+
return isValid;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
const handleChange = <K extends keyof T>(field: K, value: T[K]) => {
|
|
191
|
+
setValues(prev => ({ ...prev, [field]: value }));
|
|
192
|
+
const error = validateField(field, value);
|
|
193
|
+
setErrors(prev => ({ ...prev, [field]: error }));
|
|
194
|
+
};
|
|
171
195
|
|
|
172
|
-
const handleChange = <K extends keyof T>(field: K, value: T[K]) => {
|
|
173
|
-
setValues({...values, [field]: value});
|
|
174
|
-
const error = validateField(field, value);
|
|
175
|
-
setErrors({...errors, [field]: error});
|
|
176
|
-
};
|
|
177
196
|
|
|
178
197
|
return {
|
|
179
198
|
values,
|