@lobehub/ui 5.55.0 → 5.57.0
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/es/EditableText/ControlInput.mjs +2 -2
- package/es/EditableText/ControlInput.mjs.map +1 -1
- package/es/SearchBar/SearchBar.mjs +2 -2
- package/es/SearchBar/SearchBar.mjs.map +1 -1
- package/es/base-ui/Checkbox/Checkbox.d.mts +6 -2
- package/es/base-ui/Checkbox/Checkbox.mjs +2 -1
- package/es/base-ui/Checkbox/Checkbox.mjs.map +1 -1
- package/es/base-ui/Checkbox/CheckboxGroup.mjs +2 -2
- package/es/base-ui/Checkbox/CheckboxGroup.mjs.map +1 -1
- package/es/base-ui/Checkbox/index.d.mts +2 -2
- package/es/base-ui/ColorPicker/ColorPicker.mjs +4 -4
- package/es/base-ui/ColorPicker/ColorPicker.mjs.map +1 -1
- package/es/base-ui/DatePicker/style.mjs +1 -0
- package/es/base-ui/DatePicker/style.mjs.map +1 -1
- package/es/base-ui/Form/components/FormGroup.mjs +13 -5
- package/es/base-ui/Form/components/FormGroup.mjs.map +1 -1
- package/es/base-ui/Form/index.d.mts +3 -0
- package/es/base-ui/Form/index.mjs +3 -0
- package/es/base-ui/Form/index.mjs.map +1 -1
- package/es/base-ui/Form/style.mjs +32 -6
- package/es/base-ui/Form/style.mjs.map +1 -1
- package/es/base-ui/FormKit/Field.d.mts +9 -0
- package/es/base-ui/FormKit/Field.mjs +167 -0
- package/es/base-ui/FormKit/Field.mjs.map +1 -0
- package/es/base-ui/FormKit/Form.mjs +96 -0
- package/es/base-ui/FormKit/Form.mjs.map +1 -0
- package/es/base-ui/FormKit/List.d.mts +34 -0
- package/es/base-ui/FormKit/List.mjs +102 -0
- package/es/base-ui/FormKit/List.mjs.map +1 -0
- package/es/base-ui/FormKit/SubmitFooter.d.mts +6 -0
- package/es/base-ui/FormKit/SubmitFooter.mjs +36 -0
- package/es/base-ui/FormKit/SubmitFooter.mjs.map +1 -0
- package/es/base-ui/FormKit/binding.mjs +23 -0
- package/es/base-ui/FormKit/binding.mjs.map +1 -0
- package/es/base-ui/FormKit/context.d.mts +7 -0
- package/es/base-ui/FormKit/context.mjs +14 -0
- package/es/base-ui/FormKit/context.mjs.map +1 -0
- package/es/base-ui/FormKit/engine/tanstack.mjs +293 -0
- package/es/base-ui/FormKit/engine/tanstack.mjs.map +1 -0
- package/es/base-ui/FormKit/engine/types.d.mts +6 -0
- package/es/base-ui/FormKit/index.d.mts +31 -0
- package/es/base-ui/FormKit/index.mjs +28 -0
- package/es/base-ui/FormKit/index.mjs.map +1 -0
- package/es/base-ui/FormKit/instance.mjs +67 -0
- package/es/base-ui/FormKit/instance.mjs.map +1 -0
- package/es/base-ui/FormKit/schema.d.mts +33 -0
- package/es/base-ui/FormKit/schema.mjs +23 -0
- package/es/base-ui/FormKit/schema.mjs.map +1 -0
- package/es/base-ui/FormKit/style.mjs +119 -0
- package/es/base-ui/FormKit/style.mjs.map +1 -0
- package/es/base-ui/FormKit/type.d.mts +122 -0
- package/es/base-ui/FormKit/useForm.d.mts +10 -0
- package/es/base-ui/FormKit/useForm.mjs +54 -0
- package/es/base-ui/FormKit/useForm.mjs.map +1 -0
- package/es/base-ui/FormKit/useStoreSelector.mjs +25 -0
- package/es/base-ui/FormKit/useStoreSelector.mjs.map +1 -0
- package/es/base-ui/FormKit/useWatch.d.mts +7 -0
- package/es/base-ui/FormKit/useWatch.mjs +12 -0
- package/es/base-ui/FormKit/useWatch.mjs.map +1 -0
- package/es/base-ui/Input/Input.d.mts +6 -2
- package/es/base-ui/Input/Input.mjs +2 -1
- package/es/base-ui/Input/Input.mjs.map +1 -1
- package/es/base-ui/Input/InputNumber.d.mts +6 -2
- package/es/base-ui/Input/InputNumber.mjs +13 -6
- package/es/base-ui/Input/InputNumber.mjs.map +1 -1
- package/es/base-ui/Input/InputPassword.d.mts +6 -2
- package/es/base-ui/Input/InputPassword.mjs +4 -3
- package/es/base-ui/Input/InputPassword.mjs.map +1 -1
- package/es/base-ui/Input/TextArea.d.mts +6 -2
- package/es/base-ui/Input/TextArea.mjs +2 -1
- package/es/base-ui/Input/TextArea.mjs.map +1 -1
- package/es/base-ui/Input/index.d.mts +5 -5
- package/es/base-ui/Input/style.d.mts +4 -1
- package/es/base-ui/Input/style.mjs +21 -8
- package/es/base-ui/Input/style.mjs.map +1 -1
- package/es/base-ui/Modal/Modal.mjs +4 -8
- package/es/base-ui/Modal/Modal.mjs.map +1 -1
- package/es/base-ui/Slider/SliderWithInput.mjs +2 -2
- package/es/base-ui/Slider/SliderWithInput.mjs.map +1 -1
- package/es/base-ui/Switch/Switch.mjs +2 -2
- package/es/base-ui/Switch/Switch.mjs.map +1 -1
- package/es/base-ui/Text/style.d.mts +1 -1
- package/es/base-ui/Tree/TreeNode.mjs +2 -2
- package/es/base-ui/Tree/TreeNode.mjs.map +1 -1
- package/es/base-ui/index.d.mts +8 -8
- package/es/base-ui/index.mjs +6 -6
- package/es/chat/ChatInputArea/components/ChatInputAreaInner.mjs +2 -2
- package/es/chat/ChatInputArea/components/ChatInputAreaInner.mjs.map +1 -1
- package/es/chat/MessageInput/MessageInput.mjs +2 -2
- package/es/chat/MessageInput/MessageInput.mjs.map +1 -1
- package/es/chat/MessageModal/MessageModal.mjs +2 -2
- package/es/chat/MessageModal/MessageModal.mjs.map +1 -1
- package/es/eslint/index.d.mts +27 -3
- package/es/eslint/index.mjs +40 -2
- package/es/eslint/index.mjs.map +1 -1
- package/es/eslint/noInlineFormSchema.mjs +44 -0
- package/es/eslint/noInlineFormSchema.mjs.map +1 -0
- package/es/i18n/resources/en/form.d.mts +4 -0
- package/es/i18n/resources/en/form.mjs +4 -0
- package/es/i18n/resources/en/form.mjs.map +1 -1
- package/es/i18n/resources/zhCn/form.d.mts +4 -0
- package/es/i18n/resources/zhCn/form.mjs +4 -0
- package/es/i18n/resources/zhCn/form.mjs.map +1 -1
- package/es/node_modules/.pnpm/@eslint_core@0.17.0/node_modules/@eslint/core/dist/esm/types.d.mts +1139 -0
- package/es/node_modules/.pnpm/@types_estree@1.0.9/node_modules/@types/estree/index.d.mts +528 -0
- package/es/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.mts +201 -0
- package/es/node_modules/.pnpm/eslint@9.39.5_jiti@2.6.1_supports-color@10.2.2/node_modules/eslint/lib/types/index.d.mts +962 -0
- package/package.json +6 -1
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import isEqual from "fast-deep-equal";
|
|
2
|
+
import { FormApi, getBy, setBy } from "@tanstack/form-core";
|
|
3
|
+
//#region src/base-ui/FormKit/engine/tanstack.ts
|
|
4
|
+
const toEnginePath = (path) => path.replaceAll(/\.(\d+)(?=\.|$)/g, "[$1]");
|
|
5
|
+
const isSameOrNested = (a, b) => a === b || a.startsWith(`${b}.`) || b.startsWith(`${a}.`);
|
|
6
|
+
const isUnder = (path, root) => path === root || path.startsWith(`${root}.`);
|
|
7
|
+
const createTanstackEngine = (initialValues) => {
|
|
8
|
+
const form = new FormApi({ defaultValues: initialValues });
|
|
9
|
+
const fields = /* @__PURE__ */ new Map();
|
|
10
|
+
const fieldErrors = /* @__PURE__ */ new Map();
|
|
11
|
+
const formErrors = /* @__PURE__ */ new Map();
|
|
12
|
+
const serverErrors = /* @__PURE__ */ new Map();
|
|
13
|
+
const validating = /* @__PURE__ */ new Set();
|
|
14
|
+
const touched = /* @__PURE__ */ new Set();
|
|
15
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
16
|
+
const valueListeners = /* @__PURE__ */ new Set();
|
|
17
|
+
const snapshots = /* @__PURE__ */ new Map();
|
|
18
|
+
let formValidator;
|
|
19
|
+
let baseline = initialValues;
|
|
20
|
+
let dirtyCache;
|
|
21
|
+
let inflightSubmit;
|
|
22
|
+
let submitting = false;
|
|
23
|
+
let submitCount = 0;
|
|
24
|
+
let status = {
|
|
25
|
+
dirty: false,
|
|
26
|
+
submitCount: 0,
|
|
27
|
+
submitting: false
|
|
28
|
+
};
|
|
29
|
+
const notify = () => {
|
|
30
|
+
for (const listener of listeners) listener();
|
|
31
|
+
};
|
|
32
|
+
const storeSubscription = form.store.subscribe(notify);
|
|
33
|
+
const getValue = (path) => form.getFieldValue(toEnginePath(path));
|
|
34
|
+
const getValues = () => form.state.values;
|
|
35
|
+
const isTouched = (path) => {
|
|
36
|
+
for (const entry of touched) if (isSameOrNested(entry, path)) return true;
|
|
37
|
+
return false;
|
|
38
|
+
};
|
|
39
|
+
const errorOf = (path) => serverErrors.get(path) ?? fieldErrors.get(path) ?? formErrors.get(path);
|
|
40
|
+
const getField = (path) => {
|
|
41
|
+
const next = {
|
|
42
|
+
error: errorOf(path),
|
|
43
|
+
touched: isTouched(path),
|
|
44
|
+
validating: validating.has(path),
|
|
45
|
+
value: getValue(path)
|
|
46
|
+
};
|
|
47
|
+
const prev = snapshots.get(path);
|
|
48
|
+
if (prev && prev.error === next.error && prev.touched === next.touched && prev.validating === next.validating && Object.is(prev.value, next.value)) return prev;
|
|
49
|
+
snapshots.set(path, next);
|
|
50
|
+
return next;
|
|
51
|
+
};
|
|
52
|
+
const getStatus = () => {
|
|
53
|
+
const values = getValues();
|
|
54
|
+
if (dirtyCache?.values !== values || dirtyCache.baseline !== baseline) dirtyCache = {
|
|
55
|
+
baseline,
|
|
56
|
+
dirty: !isEqual(values, baseline),
|
|
57
|
+
values
|
|
58
|
+
};
|
|
59
|
+
const { dirty } = dirtyCache;
|
|
60
|
+
if (status.dirty !== dirty || status.submitting !== submitting || status.submitCount !== submitCount) status = {
|
|
61
|
+
dirty,
|
|
62
|
+
submitCount,
|
|
63
|
+
submitting
|
|
64
|
+
};
|
|
65
|
+
return status;
|
|
66
|
+
};
|
|
67
|
+
const shouldValidate = (path, trigger) => {
|
|
68
|
+
const mode = fields.get(path)?.registration.validateOn ?? "auto";
|
|
69
|
+
if (trigger === "submit") return true;
|
|
70
|
+
if (mode === "change") return true;
|
|
71
|
+
if (mode === "blur") return trigger === "blur";
|
|
72
|
+
if (mode === "submit") return false;
|
|
73
|
+
return trigger === "blur" || errorOf(path) !== void 0;
|
|
74
|
+
};
|
|
75
|
+
const setOrDelete = (map, path, error) => {
|
|
76
|
+
if (error === void 0) map.delete(path);
|
|
77
|
+
else map.set(path, error);
|
|
78
|
+
};
|
|
79
|
+
const runField = (path, withFormValidator) => {
|
|
80
|
+
const runtime = fields.get(path);
|
|
81
|
+
if (!runtime) return Promise.resolve();
|
|
82
|
+
runtime.token += 1;
|
|
83
|
+
const token = runtime.token;
|
|
84
|
+
const { validate } = runtime.registration;
|
|
85
|
+
if (!validate && !(withFormValidator && formValidator)) return Promise.resolve();
|
|
86
|
+
validating.add(path);
|
|
87
|
+
notify();
|
|
88
|
+
return (async () => {
|
|
89
|
+
const values = getValues();
|
|
90
|
+
const [fieldError, formResult] = await Promise.all([validate?.(getValue(path), values), withFormValidator ? formValidator?.(values) : void 0]);
|
|
91
|
+
if (runtime.token !== token || fields.get(path) !== runtime) return;
|
|
92
|
+
setOrDelete(fieldErrors, path, fieldError);
|
|
93
|
+
if (withFormValidator) setOrDelete(formErrors, path, formResult?.[path]);
|
|
94
|
+
validating.delete(path);
|
|
95
|
+
notify();
|
|
96
|
+
})();
|
|
97
|
+
};
|
|
98
|
+
const schedule = (path, trigger) => {
|
|
99
|
+
const runtime = fields.get(path);
|
|
100
|
+
if (!runtime || !shouldValidate(path, trigger)) return;
|
|
101
|
+
clearTimeout(runtime.timer);
|
|
102
|
+
const debounceMs = runtime.registration.debounceMs ?? 0;
|
|
103
|
+
if (trigger === "change" && debounceMs > 0) {
|
|
104
|
+
runtime.token += 1;
|
|
105
|
+
runtime.timer = setTimeout(() => void runField(path, true), debounceMs);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
runField(path, true);
|
|
109
|
+
};
|
|
110
|
+
const clearErrorsUnder = (path, inclusive = false) => {
|
|
111
|
+
for (const map of [
|
|
112
|
+
fieldErrors,
|
|
113
|
+
formErrors,
|
|
114
|
+
serverErrors
|
|
115
|
+
]) for (const key of map.keys()) if (inclusive ? isUnder(key, path) : key.startsWith(`${path}.`)) map.delete(key);
|
|
116
|
+
};
|
|
117
|
+
const resetTo = (values) => {
|
|
118
|
+
clearRuntimeState();
|
|
119
|
+
baseline = values;
|
|
120
|
+
form.reset(values);
|
|
121
|
+
notify();
|
|
122
|
+
};
|
|
123
|
+
const emitValueChange = (path, source) => {
|
|
124
|
+
for (const listener of valueListeners) listener({
|
|
125
|
+
path,
|
|
126
|
+
source
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
const afterUserChange = (path) => {
|
|
130
|
+
touched.add(path);
|
|
131
|
+
serverErrors.delete(path);
|
|
132
|
+
schedule(path, "change");
|
|
133
|
+
for (const [other, runtime] of fields) if (other !== path && runtime.registration.deps?.includes(path) && isTouched(other)) runField(other, true);
|
|
134
|
+
notify();
|
|
135
|
+
};
|
|
136
|
+
const validate = async (paths) => {
|
|
137
|
+
const values = getValues();
|
|
138
|
+
const formResult = (formValidator ? await formValidator(values) : void 0) ?? {};
|
|
139
|
+
const targets = paths ?? [.../* @__PURE__ */ new Set([...fields.keys(), ...Object.keys(formResult)])];
|
|
140
|
+
await Promise.all(targets.map((path) => runField(path, false)));
|
|
141
|
+
for (const path of targets) setOrDelete(formErrors, path, formResult[path]);
|
|
142
|
+
notify();
|
|
143
|
+
const errors = {};
|
|
144
|
+
for (const path of targets) {
|
|
145
|
+
const error = errorOf(path);
|
|
146
|
+
if (error !== void 0) errors[path] = error;
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
errors,
|
|
150
|
+
valid: Object.keys(errors).length === 0
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
const clearRuntimeState = () => {
|
|
154
|
+
for (const runtime of fields.values()) {
|
|
155
|
+
clearTimeout(runtime.timer);
|
|
156
|
+
runtime.token += 1;
|
|
157
|
+
}
|
|
158
|
+
fieldErrors.clear();
|
|
159
|
+
formErrors.clear();
|
|
160
|
+
serverErrors.clear();
|
|
161
|
+
validating.clear();
|
|
162
|
+
touched.clear();
|
|
163
|
+
};
|
|
164
|
+
const runSubmit = async (onSubmit) => {
|
|
165
|
+
submitCount += 1;
|
|
166
|
+
serverErrors.clear();
|
|
167
|
+
for (const path of fields.keys()) touched.add(path);
|
|
168
|
+
let values;
|
|
169
|
+
let result;
|
|
170
|
+
do {
|
|
171
|
+
values = getValues();
|
|
172
|
+
result = await validate();
|
|
173
|
+
} while (values !== getValues());
|
|
174
|
+
if (!result.valid) {
|
|
175
|
+
notify();
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
submitting = true;
|
|
179
|
+
notify();
|
|
180
|
+
try {
|
|
181
|
+
await onSubmit?.(values);
|
|
182
|
+
if (serverErrors.size > 0) return {
|
|
183
|
+
errors: Object.fromEntries(serverErrors),
|
|
184
|
+
valid: false
|
|
185
|
+
};
|
|
186
|
+
resetTo(getValues());
|
|
187
|
+
} finally {
|
|
188
|
+
submitting = false;
|
|
189
|
+
notify();
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
};
|
|
193
|
+
return {
|
|
194
|
+
blurField: (path) => {
|
|
195
|
+
touched.add(path);
|
|
196
|
+
schedule(path, "blur");
|
|
197
|
+
notify();
|
|
198
|
+
},
|
|
199
|
+
destroy: () => {
|
|
200
|
+
for (const runtime of fields.values()) clearTimeout(runtime.timer);
|
|
201
|
+
storeSubscription.unsubscribe();
|
|
202
|
+
listeners.clear();
|
|
203
|
+
valueListeners.clear();
|
|
204
|
+
},
|
|
205
|
+
getField,
|
|
206
|
+
getStatus,
|
|
207
|
+
getValue,
|
|
208
|
+
getValues,
|
|
209
|
+
isTouched,
|
|
210
|
+
moveItem: (path, from, to) => {
|
|
211
|
+
form.moveFieldValues(toEnginePath(path), from, to);
|
|
212
|
+
touched.add(path);
|
|
213
|
+
clearErrorsUnder(path);
|
|
214
|
+
emitValueChange(path, "user");
|
|
215
|
+
notify();
|
|
216
|
+
},
|
|
217
|
+
onValueChange: (listener) => {
|
|
218
|
+
valueListeners.add(listener);
|
|
219
|
+
return () => valueListeners.delete(listener);
|
|
220
|
+
},
|
|
221
|
+
pushItem: (path, item) => {
|
|
222
|
+
form.pushFieldValue(toEnginePath(path), item);
|
|
223
|
+
touched.add(path);
|
|
224
|
+
emitValueChange(path, "user");
|
|
225
|
+
notify();
|
|
226
|
+
},
|
|
227
|
+
registerField: (path, registration) => {
|
|
228
|
+
const runtime = {
|
|
229
|
+
registration,
|
|
230
|
+
token: 0
|
|
231
|
+
};
|
|
232
|
+
fields.set(path, runtime);
|
|
233
|
+
return () => {
|
|
234
|
+
if (fields.get(path) !== runtime) return;
|
|
235
|
+
clearTimeout(runtime.timer);
|
|
236
|
+
fields.delete(path);
|
|
237
|
+
fieldErrors.delete(path);
|
|
238
|
+
validating.delete(path);
|
|
239
|
+
snapshots.delete(path);
|
|
240
|
+
notify();
|
|
241
|
+
};
|
|
242
|
+
},
|
|
243
|
+
removeItem: (path, index) => {
|
|
244
|
+
form.removeFieldValue(toEnginePath(path), index);
|
|
245
|
+
touched.add(path);
|
|
246
|
+
clearErrorsUnder(path);
|
|
247
|
+
emitValueChange(path, "user");
|
|
248
|
+
notify();
|
|
249
|
+
},
|
|
250
|
+
reset: (values) => resetTo(values ?? baseline),
|
|
251
|
+
resetField: (path) => {
|
|
252
|
+
for (const [key, runtime] of fields) {
|
|
253
|
+
if (!isUnder(key, path)) continue;
|
|
254
|
+
clearTimeout(runtime.timer);
|
|
255
|
+
runtime.token += 1;
|
|
256
|
+
validating.delete(key);
|
|
257
|
+
}
|
|
258
|
+
for (const entry of touched) if (isUnder(entry, path)) touched.delete(entry);
|
|
259
|
+
clearErrorsUnder(path, true);
|
|
260
|
+
form.setFieldValue(toEnginePath(path), getBy(baseline, toEnginePath(path)), { dontUpdateMeta: true });
|
|
261
|
+
emitValueChange(path, "api");
|
|
262
|
+
notify();
|
|
263
|
+
},
|
|
264
|
+
setErrors: (errors) => {
|
|
265
|
+
for (const [path, error] of Object.entries(errors)) setOrDelete(serverErrors, path, error);
|
|
266
|
+
notify();
|
|
267
|
+
},
|
|
268
|
+
setFormValidator: (validator) => {
|
|
269
|
+
formValidator = validator;
|
|
270
|
+
},
|
|
271
|
+
setValue: (path, value, source) => {
|
|
272
|
+
form.setFieldValue(toEnginePath(path), value, { dontUpdateMeta: true });
|
|
273
|
+
if (source === "api") baseline = setBy(baseline, toEnginePath(path), () => value);
|
|
274
|
+
emitValueChange(path, source);
|
|
275
|
+
if (source === "user") afterUserChange(path);
|
|
276
|
+
},
|
|
277
|
+
submit: (onSubmit) => {
|
|
278
|
+
inflightSubmit ??= runSubmit(onSubmit).finally(() => {
|
|
279
|
+
inflightSubmit = void 0;
|
|
280
|
+
});
|
|
281
|
+
return inflightSubmit;
|
|
282
|
+
},
|
|
283
|
+
subscribe: (listener) => {
|
|
284
|
+
listeners.add(listener);
|
|
285
|
+
return () => listeners.delete(listener);
|
|
286
|
+
},
|
|
287
|
+
validate
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
//#endregion
|
|
291
|
+
export { createTanstackEngine };
|
|
292
|
+
|
|
293
|
+
//# sourceMappingURL=tanstack.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanstack.mjs","names":[],"sources":["../../../../src/base-ui/FormKit/engine/tanstack.ts"],"sourcesContent":["import { FormApi, getBy, setBy } from '@tanstack/form-core';\nimport isEqual from 'fast-deep-equal';\n\nimport type {\n ChangeSource,\n CreateEngine,\n FieldRegistration,\n FieldSnapshot,\n FormEngine,\n FormStatus,\n FormValidator,\n ValidateResult,\n ValidateTrigger,\n ValueChange,\n} from './types';\n\nconst toEnginePath = (path: string) => path.replaceAll(/\\.(\\d+)(?=\\.|$)/g, '[$1]');\n\nconst isSameOrNested = (a: string, b: string) =>\n a === b || a.startsWith(`${b}.`) || b.startsWith(`${a}.`);\n\nconst isUnder = (path: string, root: string) => path === root || path.startsWith(`${root}.`);\n\ninterface FieldRuntime {\n registration: FieldRegistration;\n timer?: ReturnType<typeof setTimeout>;\n token: number;\n}\n\nexport const createTanstackEngine: CreateEngine = (initialValues) => {\n const form = new FormApi({ defaultValues: initialValues });\n\n const fields = new Map<string, FieldRuntime>();\n const fieldErrors = new Map<string, string>();\n const formErrors = new Map<string, string>();\n const serverErrors = new Map<string, string>();\n const validating = new Set<string>();\n const touched = new Set<string>();\n const listeners = new Set<() => void>();\n const valueListeners = new Set<(change: ValueChange) => void>();\n const snapshots = new Map<string, FieldSnapshot>();\n\n let formValidator: FormValidator | undefined;\n let baseline = initialValues;\n let dirtyCache: { baseline: unknown; dirty: boolean; values: unknown } | undefined;\n let inflightSubmit: Promise<ValidateResult> | undefined;\n let submitting = false;\n let submitCount = 0;\n let status: FormStatus = { dirty: false, submitCount: 0, submitting: false };\n\n const notify = () => {\n for (const listener of listeners) listener();\n };\n const storeSubscription = form.store.subscribe(notify);\n\n const getValue = (path: string) => form.getFieldValue(toEnginePath(path) as never) as unknown;\n const getValues = () => form.state.values as Record<string, unknown>;\n const isTouched = (path: string) => {\n for (const entry of touched) if (isSameOrNested(entry, path)) return true;\n return false;\n };\n const errorOf = (path: string) =>\n serverErrors.get(path) ?? fieldErrors.get(path) ?? formErrors.get(path);\n\n const getField = (path: string): FieldSnapshot => {\n const next: FieldSnapshot = {\n error: errorOf(path),\n touched: isTouched(path),\n validating: validating.has(path),\n value: getValue(path),\n };\n const prev = snapshots.get(path);\n if (\n prev &&\n prev.error === next.error &&\n prev.touched === next.touched &&\n prev.validating === next.validating &&\n Object.is(prev.value, next.value)\n )\n return prev;\n snapshots.set(path, next);\n return next;\n };\n\n const getStatus = (): FormStatus => {\n const values = getValues();\n if (dirtyCache?.values !== values || dirtyCache.baseline !== baseline)\n dirtyCache = { baseline, dirty: !isEqual(values, baseline), values };\n const { dirty } = dirtyCache;\n if (\n status.dirty !== dirty ||\n status.submitting !== submitting ||\n status.submitCount !== submitCount\n )\n status = { dirty, submitCount, submitting };\n return status;\n };\n\n const shouldValidate = (path: string, trigger: ValidateTrigger) => {\n const mode = fields.get(path)?.registration.validateOn ?? 'auto';\n if (trigger === 'submit') return true;\n if (mode === 'change') return true;\n if (mode === 'blur') return trigger === 'blur';\n if (mode === 'submit') return false;\n return trigger === 'blur' || errorOf(path) !== undefined;\n };\n\n const setOrDelete = (map: Map<string, string>, path: string, error: string | undefined) => {\n if (error === undefined) map.delete(path);\n else map.set(path, error);\n };\n\n const runField = (path: string, withFormValidator: boolean): Promise<void> => {\n const runtime = fields.get(path);\n if (!runtime) return Promise.resolve();\n runtime.token += 1;\n const token = runtime.token;\n const { validate } = runtime.registration;\n if (!validate && !(withFormValidator && formValidator)) return Promise.resolve();\n\n validating.add(path);\n notify();\n return (async () => {\n const values = getValues();\n const [fieldError, formResult] = await Promise.all([\n validate?.(getValue(path), values),\n withFormValidator ? formValidator?.(values) : undefined,\n ]);\n if (runtime.token !== token || fields.get(path) !== runtime) return;\n setOrDelete(fieldErrors, path, fieldError);\n if (withFormValidator) setOrDelete(formErrors, path, formResult?.[path]);\n validating.delete(path);\n notify();\n })();\n };\n\n const schedule = (path: string, trigger: ValidateTrigger) => {\n const runtime = fields.get(path);\n if (!runtime || !shouldValidate(path, trigger)) return;\n clearTimeout(runtime.timer);\n const debounceMs = runtime.registration.debounceMs ?? 0;\n if (trigger === 'change' && debounceMs > 0) {\n runtime.token += 1;\n runtime.timer = setTimeout(() => void runField(path, true), debounceMs);\n return;\n }\n void runField(path, true);\n };\n\n const clearErrorsUnder = (path: string, inclusive = false) => {\n for (const map of [fieldErrors, formErrors, serverErrors])\n for (const key of map.keys())\n if (inclusive ? isUnder(key, path) : key.startsWith(`${path}.`)) map.delete(key);\n };\n\n const resetTo = (values: Record<string, unknown>) => {\n clearRuntimeState();\n baseline = values;\n form.reset(values);\n notify();\n };\n\n const emitValueChange = (path: string, source: ChangeSource) => {\n for (const listener of valueListeners) listener({ path, source });\n };\n\n const afterUserChange = (path: string) => {\n touched.add(path);\n serverErrors.delete(path);\n schedule(path, 'change');\n for (const [other, runtime] of fields) {\n if (other !== path && runtime.registration.deps?.includes(path) && isTouched(other))\n void runField(other, true);\n }\n notify();\n };\n\n const validate = async (paths?: string[]): Promise<ValidateResult> => {\n const values = getValues();\n const formResult = (formValidator ? await formValidator(values) : undefined) ?? {};\n const targets = paths ?? [...new Set([...fields.keys(), ...Object.keys(formResult)])];\n await Promise.all(targets.map((path) => runField(path, false)));\n for (const path of targets) setOrDelete(formErrors, path, formResult[path]);\n notify();\n const errors: Record<string, string> = {};\n for (const path of targets) {\n const error = errorOf(path);\n if (error !== undefined) errors[path] = error;\n }\n return { errors, valid: Object.keys(errors).length === 0 };\n };\n\n const clearRuntimeState = () => {\n for (const runtime of fields.values()) {\n clearTimeout(runtime.timer);\n runtime.token += 1;\n }\n fieldErrors.clear();\n formErrors.clear();\n serverErrors.clear();\n validating.clear();\n touched.clear();\n };\n\n const runSubmit = async (onSubmit?: (values: Record<string, unknown>) => unknown) => {\n submitCount += 1;\n serverErrors.clear();\n for (const path of fields.keys()) touched.add(path);\n let values: Record<string, unknown>;\n let result: ValidateResult;\n do {\n values = getValues();\n result = await validate();\n // Async validators must finish against unchanged values before submission.\n } while (values !== getValues());\n if (!result.valid) {\n notify();\n return result;\n }\n submitting = true;\n notify();\n try {\n await onSubmit?.(values);\n if (serverErrors.size > 0) return { errors: Object.fromEntries(serverErrors), valid: false };\n resetTo(getValues());\n } finally {\n submitting = false;\n notify();\n }\n return result;\n };\n\n const engine: FormEngine = {\n blurField: (path) => {\n touched.add(path);\n schedule(path, 'blur');\n notify();\n },\n destroy: () => {\n for (const runtime of fields.values()) clearTimeout(runtime.timer);\n storeSubscription.unsubscribe();\n listeners.clear();\n valueListeners.clear();\n },\n getField,\n getStatus,\n getValue,\n getValues,\n isTouched,\n moveItem: (path, from, to) => {\n form.moveFieldValues(toEnginePath(path) as never, from, to);\n touched.add(path);\n clearErrorsUnder(path);\n emitValueChange(path, 'user');\n notify();\n },\n onValueChange: (listener) => {\n valueListeners.add(listener);\n return () => valueListeners.delete(listener);\n },\n pushItem: (path, item) => {\n form.pushFieldValue(toEnginePath(path) as never, item as never);\n touched.add(path);\n emitValueChange(path, 'user');\n notify();\n },\n registerField: (path, registration) => {\n const runtime: FieldRuntime = { registration, token: 0 };\n fields.set(path, runtime);\n return () => {\n if (fields.get(path) !== runtime) return;\n clearTimeout(runtime.timer);\n fields.delete(path);\n fieldErrors.delete(path);\n validating.delete(path);\n snapshots.delete(path);\n notify();\n };\n },\n removeItem: (path, index) => {\n void form.removeFieldValue(toEnginePath(path) as never, index);\n touched.add(path);\n clearErrorsUnder(path);\n emitValueChange(path, 'user');\n notify();\n },\n reset: (values) => resetTo(values ?? baseline),\n resetField: (path) => {\n for (const [key, runtime] of fields) {\n if (!isUnder(key, path)) continue;\n clearTimeout(runtime.timer);\n runtime.token += 1;\n validating.delete(key);\n }\n for (const entry of touched) if (isUnder(entry, path)) touched.delete(entry);\n clearErrorsUnder(path, true);\n form.setFieldValue(toEnginePath(path) as never, getBy(baseline, toEnginePath(path)), {\n dontUpdateMeta: true,\n });\n emitValueChange(path, 'api');\n notify();\n },\n setErrors: (errors) => {\n for (const [path, error] of Object.entries(errors)) setOrDelete(serverErrors, path, error);\n notify();\n },\n setFormValidator: (validator) => {\n formValidator = validator;\n },\n setValue: (path, value, source) => {\n form.setFieldValue(toEnginePath(path) as never, value as never, { dontUpdateMeta: true });\n if (source === 'api') baseline = setBy(baseline, toEnginePath(path), () => value);\n emitValueChange(path, source);\n if (source === 'user') afterUserChange(path);\n },\n submit: (onSubmit) => {\n inflightSubmit ??= runSubmit(onSubmit).finally(() => {\n inflightSubmit = undefined;\n });\n return inflightSubmit;\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n validate,\n };\n\n return engine;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FlexBasicProps } from "../../Flex/type.mjs";
|
|
2
|
+
import "../../index.mjs";
|
|
3
|
+
import { FormDividerProps, FormFlatGroupProps, FormGroupProps, FormSubmitFooterProps, FormTitleProps } from "../Form/type.mjs";
|
|
4
|
+
import { FieldValidate, StandardSchema } from "./schema.mjs";
|
|
5
|
+
import { DeepPartial, FieldBinding, FieldPath, FieldPathValue, FieldRenderProps, FormFieldProps, FormGroupItem, FormInstance, FormProps, FormValidateResult, FormValues, SetValueOptions, UseFormOptions } from "./type.mjs";
|
|
6
|
+
import "../index.mjs";
|
|
7
|
+
import FormList, { FormListColumn, FormListField, FormListProps, FormListRenderProps } from "./List.mjs";
|
|
8
|
+
import _default from "./Field.mjs";
|
|
9
|
+
import SubmitFooter from "./SubmitFooter.mjs";
|
|
10
|
+
import { useFormInstance } from "./context.mjs";
|
|
11
|
+
import { useForm } from "./useForm.mjs";
|
|
12
|
+
import { useWatch } from "./useWatch.mjs";
|
|
13
|
+
//#region src/base-ui/FormKit/index.d.ts
|
|
14
|
+
declare const Form: {
|
|
15
|
+
<T extends FormValues>({ activeKey, children, className, classNames, collapsible, defaultActiveKey, footer, form, gap, itemMinWidth, items, itemsType, layout, onCollapse, ref, style, styles: customStyles, variant, ...rest }: FormProps<T>): import("react").JSX.Element;
|
|
16
|
+
displayName: string;
|
|
17
|
+
} & {
|
|
18
|
+
Divider: import("react").FC<FormDividerProps>;
|
|
19
|
+
Field: (<T extends FormValues = FormValues>(props: FormFieldProps<T>) => import("react").ReactNode) & {
|
|
20
|
+
displayName?: string;
|
|
21
|
+
};
|
|
22
|
+
FlatGroup: import("react").NamedExoticComponent<FormFlatGroupProps>;
|
|
23
|
+
Footer: import("react").FC<FlexBasicProps>;
|
|
24
|
+
Group: import("react").NamedExoticComponent<FormGroupProps>;
|
|
25
|
+
List: import("react").NamedExoticComponent<FormListProps>;
|
|
26
|
+
SubmitFooter: import("react").NamedExoticComponent<FormSubmitFooterProps>;
|
|
27
|
+
Title: import("react").FC<FormTitleProps>;
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { type DeepPartial, type FieldBinding, type FieldPath, type FieldPathValue, type FieldRenderProps, type FieldValidate, Form, Form as default, _default as FormField, type FormFieldProps, type FormGroupItem, type FormInstance, FormList, type FormListColumn, type FormListField, type FormListProps, type FormListRenderProps, type FormProps, SubmitFooter as FormSubmitFooter, type FormValidateResult, type FormValues, type SetValueOptions, type StandardSchema, type UseFormOptions, useForm, useFormInstance, useWatch };
|
|
31
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import FormDivider from "../Form/components/FormDivider.mjs";
|
|
3
|
+
import FormTitle from "../Form/components/FormTitle.mjs";
|
|
4
|
+
import FormFlatGroup from "../Form/components/FormFlatGroup.mjs";
|
|
5
|
+
import FormFooter from "../Form/components/FormFooter.mjs";
|
|
6
|
+
import FormGroup from "../Form/components/FormGroup.mjs";
|
|
7
|
+
import { useFormInstance } from "./context.mjs";
|
|
8
|
+
import FormField from "./Field.mjs";
|
|
9
|
+
import Form$1 from "./Form.mjs";
|
|
10
|
+
import FormList from "./List.mjs";
|
|
11
|
+
import SubmitFooter from "./SubmitFooter.mjs";
|
|
12
|
+
import { useForm } from "./useForm.mjs";
|
|
13
|
+
import { useWatch } from "./useWatch.mjs";
|
|
14
|
+
//#region src/base-ui/FormKit/index.ts
|
|
15
|
+
const Form = Object.assign(Form$1, {
|
|
16
|
+
Divider: FormDivider,
|
|
17
|
+
Field: FormField,
|
|
18
|
+
FlatGroup: FormFlatGroup,
|
|
19
|
+
Footer: FormFooter,
|
|
20
|
+
Group: FormGroup,
|
|
21
|
+
List: FormList,
|
|
22
|
+
SubmitFooter,
|
|
23
|
+
Title: FormTitle
|
|
24
|
+
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Form, Form as default, FormField, FormList, SubmitFooter as FormSubmitFooter, useForm, useFormInstance, useWatch };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["FormParent","FormSubmitFooter"],"sources":["../../../src/base-ui/FormKit/index.ts"],"sourcesContent":["'use client';\n\nimport FormDivider from '../Form/components/FormDivider';\nimport FormFlatGroup from '../Form/components/FormFlatGroup';\nimport FormFooter from '../Form/components/FormFooter';\nimport FormGroup from '../Form/components/FormGroup';\nimport FormTitle from '../Form/components/FormTitle';\nimport FormField from './Field';\nimport FormParent from './Form';\nimport FormList from './List';\nimport FormSubmitFooter from './SubmitFooter';\n\nexport const Form = Object.assign(FormParent, {\n Divider: FormDivider,\n Field: FormField,\n FlatGroup: FormFlatGroup,\n Footer: FormFooter,\n Group: FormGroup,\n List: FormList,\n SubmitFooter: FormSubmitFooter,\n Title: FormTitle,\n});\n\nexport { useFormInstance } from './context';\nexport type { FormListColumn, FormListField, FormListProps, FormListRenderProps } from './List';\nexport type {\n DeepPartial,\n FieldBinding,\n FieldPath,\n FieldPathValue,\n FieldRenderProps,\n FieldValidate,\n FormFieldProps,\n FormGroupItem,\n FormInstance,\n FormProps,\n FormValidateResult,\n FormValues,\n SetValueOptions,\n StandardSchema,\n UseFormOptions,\n} from './type';\nexport { useForm } from './useForm';\nexport { useWatch } from './useWatch';\nexport { FormField, FormList, FormSubmitFooter };\n\nexport default Form;\n"],"mappings":";;;;;;;;;;;;;;AAYA,MAAa,OAAO,OAAO,OAAOA,QAAY;CAC5C,SAAS;CACT,OAAO;CACP,WAAW;CACX,QAAQ;CACR,OAAO;CACP,MAAM;CACQC;CACd,OAAO;AACT,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createTanstackEngine } from "./engine/tanstack.mjs";
|
|
2
|
+
import { schemaToFormValidator } from "./schema.mjs";
|
|
3
|
+
//#region src/base-ui/FormKit/instance.ts
|
|
4
|
+
const internals = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
const getInternals = (form) => {
|
|
6
|
+
const found = internals.get(form);
|
|
7
|
+
if (!found) throw new Error("[@lobehub/ui/base-ui/form] form was not created by useForm");
|
|
8
|
+
return found;
|
|
9
|
+
};
|
|
10
|
+
const isPlainObject = (value) => {
|
|
11
|
+
if (typeof value !== "object" || value === null) return false;
|
|
12
|
+
const proto = Object.getPrototypeOf(value);
|
|
13
|
+
return proto === Object.prototype || proto === null;
|
|
14
|
+
};
|
|
15
|
+
const leafPaths = (value, prefix = "") => {
|
|
16
|
+
if (!isPlainObject(value) || prefix && Object.keys(value).length === 0) return prefix ? [prefix] : [];
|
|
17
|
+
return Object.entries(value).flatMap(([key, child]) => leafPaths(child, prefix ? `${prefix}.${key}` : key));
|
|
18
|
+
};
|
|
19
|
+
const getIn = (value, path) => path.split(".").reduce((acc, key) => acc == null ? void 0 : acc[key], value);
|
|
20
|
+
const setIn = (target, path, value) => {
|
|
21
|
+
const keys = path.split(".");
|
|
22
|
+
let cursor = target;
|
|
23
|
+
keys.slice(0, -1).forEach((key) => {
|
|
24
|
+
if (!isPlainObject(cursor[key])) cursor[key] = {};
|
|
25
|
+
cursor = cursor[key];
|
|
26
|
+
});
|
|
27
|
+
cursor[keys.at(-1)] = value;
|
|
28
|
+
};
|
|
29
|
+
const createFormInstance = ({ initialValues, schema, validateOn }) => {
|
|
30
|
+
const engine = createTanstackEngine(initialValues);
|
|
31
|
+
if (schema) engine.setFormValidator(schemaToFormValidator(schema));
|
|
32
|
+
const source = (options) => options?.asUser ? "user" : "api";
|
|
33
|
+
const form = {
|
|
34
|
+
getValue: ((name) => engine.getValue(name)),
|
|
35
|
+
getValues: () => engine.getValues(),
|
|
36
|
+
isDirty: () => engine.getStatus().dirty,
|
|
37
|
+
isTouched: (name) => engine.isTouched(name),
|
|
38
|
+
reset: (values) => engine.reset(values),
|
|
39
|
+
resetField: (name) => engine.resetField(name),
|
|
40
|
+
setErrors: (errors) => engine.setErrors(errors),
|
|
41
|
+
setSchema: (next) => engine.setFormValidator(next ? schemaToFormValidator(next) : void 0),
|
|
42
|
+
setValue: ((name, value, options) => engine.setValue(name, value, source(options))),
|
|
43
|
+
setValues: (values, options) => {
|
|
44
|
+
for (const path of leafPaths(values)) engine.setValue(path, getIn(values, path), source(options));
|
|
45
|
+
},
|
|
46
|
+
submit: () => engine.submit((values) => internals.get(form)?.onSubmit?.(values)),
|
|
47
|
+
subscribe: (selector, callback) => {
|
|
48
|
+
let selected = selector(engine.getValues());
|
|
49
|
+
return engine.subscribe(() => {
|
|
50
|
+
const next = selector(engine.getValues());
|
|
51
|
+
if (Object.is(next, selected)) return;
|
|
52
|
+
selected = next;
|
|
53
|
+
callback(next);
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
validate: (names) => engine.validate(names)
|
|
57
|
+
};
|
|
58
|
+
internals.set(form, {
|
|
59
|
+
engine,
|
|
60
|
+
validateOn
|
|
61
|
+
});
|
|
62
|
+
return form;
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
export { createFormInstance, getIn, getInternals, leafPaths, setIn };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=instance.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance.mjs","names":[],"sources":["../../../src/base-ui/FormKit/instance.ts"],"sourcesContent":["import { createTanstackEngine } from './engine/tanstack';\nimport type { FormEngine, ValidateOn } from './engine/types';\nimport { schemaToFormValidator } from './schema';\nimport type { FormInstance, FormValues } from './type';\n\ninterface InstanceInternals {\n engine: FormEngine;\n onSubmit?: (values: FormValues) => unknown;\n validateOn: ValidateOn;\n}\n\nconst internals = new WeakMap<object, InstanceInternals>();\n\nexport const getInternals = (form: object): InstanceInternals => {\n const found = internals.get(form);\n if (!found) throw new Error('[@lobehub/ui/base-ui/form] form was not created by useForm');\n return found;\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (typeof value !== 'object' || value === null) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n};\n\nexport const leafPaths = (value: unknown, prefix = ''): string[] => {\n if (!isPlainObject(value) || (prefix && Object.keys(value).length === 0))\n return prefix ? [prefix] : [];\n return Object.entries(value).flatMap(([key, child]) =>\n leafPaths(child, prefix ? `${prefix}.${key}` : key),\n );\n};\n\nexport const getIn = (value: unknown, path: string): unknown =>\n path\n .split('.')\n .reduce<unknown>((acc, key) => (acc == null ? undefined : (acc as any)[key]), value);\n\nexport const setIn = (target: Record<string, unknown>, path: string, value: unknown) => {\n const keys = path.split('.');\n let cursor: Record<string, unknown> = target;\n keys.slice(0, -1).forEach((key) => {\n if (!isPlainObject(cursor[key])) cursor[key] = {};\n cursor = cursor[key] as Record<string, unknown>;\n });\n cursor[keys.at(-1)!] = value;\n};\n\ninterface CreateOptions {\n initialValues: FormValues;\n schema?: Parameters<typeof schemaToFormValidator>[0];\n validateOn: ValidateOn;\n}\n\nexport const createFormInstance = <T extends FormValues>({\n initialValues,\n schema,\n validateOn,\n}: CreateOptions): FormInstance<T> => {\n const engine = createTanstackEngine(initialValues);\n if (schema) engine.setFormValidator(schemaToFormValidator(schema));\n const source = (options?: { asUser?: boolean }) => (options?.asUser ? 'user' : 'api');\n\n const form: FormInstance<T> = {\n getValue: ((name: string) => engine.getValue(name)) as FormInstance<T>['getValue'],\n getValues: () => engine.getValues() as T,\n isDirty: () => engine.getStatus().dirty,\n isTouched: (name) => engine.isTouched(name),\n reset: (values) => engine.reset(values),\n resetField: (name) => engine.resetField(name),\n setErrors: (errors) => engine.setErrors(errors as Record<string, string | undefined>),\n setSchema: (next) => engine.setFormValidator(next ? schemaToFormValidator(next) : undefined),\n setValue: ((name: string, value: unknown, options?: { asUser?: boolean }) =>\n engine.setValue(name, value, source(options))) as FormInstance<T>['setValue'],\n setValues: (values, options) => {\n for (const path of leafPaths(values))\n engine.setValue(path, getIn(values, path), source(options));\n },\n submit: () =>\n engine.submit((values) => internals.get(form)?.onSubmit?.(values)) as ReturnType<\n FormInstance<T>['submit']\n >,\n subscribe: (selector, callback) => {\n let selected = selector(engine.getValues() as T);\n return engine.subscribe(() => {\n const next = selector(engine.getValues() as T);\n if (Object.is(next, selected)) return;\n selected = next;\n callback(next);\n });\n },\n validate: (names) => engine.validate(names) as ReturnType<FormInstance<T>['validate']>,\n };\n\n internals.set(form, { engine, validateOn });\n return form;\n};\n"],"mappings":";;;AAWA,MAAM,4BAAY,IAAI,QAAmC;AAEzD,MAAa,gBAAgB,SAAoC;CAC/D,MAAM,QAAQ,UAAU,IAAI,IAAI;CAChC,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,4DAA4D;CACxF,OAAO;AACT;AAEA,MAAM,iBAAiB,UAAqD;CAC1E,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,QAAQ,OAAO,eAAe,KAAK;CACzC,OAAO,UAAU,OAAO,aAAa,UAAU;AACjD;AAEA,MAAa,aAAa,OAAgB,SAAS,OAAiB;CAClE,IAAI,CAAC,cAAc,KAAK,KAAM,UAAU,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,GACpE,OAAO,SAAS,CAAC,MAAM,IAAI,CAAC;CAC9B,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,WAC1C,UAAU,OAAO,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,CACpD;AACF;AAEA,MAAa,SAAS,OAAgB,SACpC,KACG,MAAM,GAAG,CAAC,CACV,QAAiB,KAAK,QAAS,OAAO,OAAO,KAAA,IAAa,IAAY,MAAO,KAAK;AAEvF,MAAa,SAAS,QAAiC,MAAc,UAAmB;CACtF,MAAM,OAAO,KAAK,MAAM,GAAG;CAC3B,IAAI,SAAkC;CACtC,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,SAAS,QAAQ;EACjC,IAAI,CAAC,cAAc,OAAO,IAAI,GAAG,OAAO,OAAO,CAAC;EAChD,SAAS,OAAO;CAClB,CAAC;CACD,OAAO,KAAK,GAAG,EAAE,KAAM;AACzB;AAQA,MAAa,sBAA4C,EACvD,eACA,QACA,iBACoC;CACpC,MAAM,SAAS,qBAAqB,aAAa;CACjD,IAAI,QAAQ,OAAO,iBAAiB,sBAAsB,MAAM,CAAC;CACjE,MAAM,UAAU,YAAoC,SAAS,SAAS,SAAS;CAE/E,MAAM,OAAwB;EAC5B,YAAY,SAAiB,OAAO,SAAS,IAAI;EACjD,iBAAiB,OAAO,UAAU;EAClC,eAAe,OAAO,UAAU,CAAC,CAAC;EAClC,YAAY,SAAS,OAAO,UAAU,IAAI;EAC1C,QAAQ,WAAW,OAAO,MAAM,MAAM;EACtC,aAAa,SAAS,OAAO,WAAW,IAAI;EAC5C,YAAY,WAAW,OAAO,UAAU,MAA4C;EACpF,YAAY,SAAS,OAAO,iBAAiB,OAAO,sBAAsB,IAAI,IAAI,KAAA,CAAS;EAC3F,YAAY,MAAc,OAAgB,YACxC,OAAO,SAAS,MAAM,OAAO,OAAO,OAAO,CAAC;EAC9C,YAAY,QAAQ,YAAY;GAC9B,KAAK,MAAM,QAAQ,UAAU,MAAM,GACjC,OAAO,SAAS,MAAM,MAAM,QAAQ,IAAI,GAAG,OAAO,OAAO,CAAC;EAC9D;EACA,cACE,OAAO,QAAQ,WAAW,UAAU,IAAI,IAAI,CAAC,EAAE,WAAW,MAAM,CAAC;EAGnE,YAAY,UAAU,aAAa;GACjC,IAAI,WAAW,SAAS,OAAO,UAAU,CAAM;GAC/C,OAAO,OAAO,gBAAgB;IAC5B,MAAM,OAAO,SAAS,OAAO,UAAU,CAAM;IAC7C,IAAI,OAAO,GAAG,MAAM,QAAQ,GAAG;IAC/B,WAAW;IACX,SAAS,IAAI;GACf,CAAC;EACH;EACA,WAAW,UAAU,OAAO,SAAS,KAAK;CAC5C;CAEA,UAAU,IAAI,MAAM;EAAE;EAAQ;CAAW,CAAC;CAC1C,OAAO;AACT"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/base-ui/FormKit/schema.d.ts
|
|
2
|
+
interface StandardSchemaIssue {
|
|
3
|
+
message: string;
|
|
4
|
+
path?: ReadonlyArray<PropertyKey | {
|
|
5
|
+
key: PropertyKey;
|
|
6
|
+
}>;
|
|
7
|
+
}
|
|
8
|
+
interface StandardSchema<Input = unknown, Output = Input> {
|
|
9
|
+
readonly '~standard': {
|
|
10
|
+
readonly types?: {
|
|
11
|
+
readonly input: Input;
|
|
12
|
+
readonly output: Output;
|
|
13
|
+
};
|
|
14
|
+
readonly validate: (value: unknown) => {
|
|
15
|
+
readonly issues?: undefined;
|
|
16
|
+
readonly value: Output;
|
|
17
|
+
} | {
|
|
18
|
+
readonly issues: ReadonlyArray<StandardSchemaIssue>;
|
|
19
|
+
} | Promise<{
|
|
20
|
+
readonly issues?: undefined;
|
|
21
|
+
readonly value: Output;
|
|
22
|
+
} | {
|
|
23
|
+
readonly issues: ReadonlyArray<StandardSchemaIssue>;
|
|
24
|
+
}>;
|
|
25
|
+
readonly vendor: string;
|
|
26
|
+
readonly version: 1;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
type InferSchemaInput<S> = S extends StandardSchema<infer I, any> ? I : never;
|
|
30
|
+
type FieldValidate = StandardSchema | ((value: any, values: any) => string | undefined | Promise<string | undefined>);
|
|
31
|
+
//#endregion
|
|
32
|
+
export { FieldValidate, InferSchemaInput, StandardSchema, StandardSchemaIssue };
|
|
33
|
+
//# sourceMappingURL=schema.d.mts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/base-ui/FormKit/schema.ts
|
|
2
|
+
const isStandardSchema = (value) => typeof value === "object" && value !== null && "~standard" in value;
|
|
3
|
+
const issuePath = (issue) => (issue.path ?? []).map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
|
|
4
|
+
const schemaToFormValidator = (schema) => async (values) => {
|
|
5
|
+
const result = await schema["~standard"].validate(values);
|
|
6
|
+
if (!result.issues) return void 0;
|
|
7
|
+
const errors = {};
|
|
8
|
+
for (const issue of result.issues) {
|
|
9
|
+
const path = issuePath(issue);
|
|
10
|
+
if (errors[path] === void 0) errors[path] = issue.message;
|
|
11
|
+
}
|
|
12
|
+
return errors;
|
|
13
|
+
};
|
|
14
|
+
const toFieldValidator = (validate) => {
|
|
15
|
+
if (!isStandardSchema(validate)) return validate;
|
|
16
|
+
return async (value) => {
|
|
17
|
+
return (await validate["~standard"].validate(value)).issues?.[0]?.message;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { isStandardSchema, schemaToFormValidator, toFieldValidator };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":[],"sources":["../../../src/base-ui/FormKit/schema.ts"],"sourcesContent":["import type { FieldValidator, FormValidator } from './engine/types';\n\nexport interface StandardSchemaIssue {\n message: string;\n path?: ReadonlyArray<PropertyKey | { key: PropertyKey }>;\n}\n\nexport interface StandardSchema<Input = unknown, Output = Input> {\n readonly '~standard': {\n readonly types?: { readonly input: Input; readonly output: Output };\n readonly validate: (\n value: unknown,\n ) =>\n | { readonly issues?: undefined; readonly value: Output }\n | { readonly issues: ReadonlyArray<StandardSchemaIssue> }\n | Promise<\n | { readonly issues?: undefined; readonly value: Output }\n | { readonly issues: ReadonlyArray<StandardSchemaIssue> }\n >;\n readonly vendor: string;\n readonly version: 1;\n };\n}\n\nexport type InferSchemaInput<S> = S extends StandardSchema<infer I, any> ? I : never;\n\nexport type FieldValidate =\n StandardSchema | ((value: any, values: any) => string | undefined | Promise<string | undefined>);\n\nexport const isStandardSchema = (value: unknown): value is StandardSchema =>\n typeof value === 'object' && value !== null && '~standard' in value;\n\nconst issuePath = (issue: StandardSchemaIssue) =>\n (issue.path ?? [])\n .map((segment) => String(typeof segment === 'object' ? segment.key : segment))\n .join('.');\n\nexport const schemaToFormValidator =\n (schema: StandardSchema): FormValidator =>\n async (values) => {\n const result = await schema['~standard'].validate(values);\n if (!result.issues) return undefined;\n const errors: Record<string, string> = {};\n for (const issue of result.issues) {\n const path = issuePath(issue);\n if (errors[path] === undefined) errors[path] = issue.message;\n }\n return errors;\n };\n\nexport const toFieldValidator = (validate: FieldValidate): FieldValidator => {\n if (!isStandardSchema(validate)) return validate;\n return async (value) => {\n const result = await validate['~standard'].validate(value);\n return result.issues?.[0]?.message;\n };\n};\n"],"mappings":";AA6BA,MAAa,oBAAoB,UAC/B,OAAO,UAAU,YAAY,UAAU,QAAQ,eAAe;AAEhE,MAAM,aAAa,WAChB,MAAM,QAAQ,CAAC,EAAA,CACb,KAAK,YAAY,OAAO,OAAO,YAAY,WAAW,QAAQ,MAAM,OAAO,CAAC,CAAC,CAC7E,KAAK,GAAG;AAEb,MAAa,yBACV,WACD,OAAO,WAAW;CAChB,MAAM,SAAS,MAAM,OAAO,YAAY,CAAC,SAAS,MAAM;CACxD,IAAI,CAAC,OAAO,QAAQ,OAAO,KAAA;CAC3B,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,SAAS,OAAO,QAAQ;EACjC,MAAM,OAAO,UAAU,KAAK;EAC5B,IAAI,OAAO,UAAU,KAAA,GAAW,OAAO,QAAQ,MAAM;CACvD;CACA,OAAO;AACT;AAEF,MAAa,oBAAoB,aAA4C;CAC3E,IAAI,CAAC,iBAAiB,QAAQ,GAAG,OAAO;CACxC,OAAO,OAAO,UAAU;EAEtB,QAAO,MADc,SAAS,YAAY,CAAC,SAAS,KAAK,EAAA,CAC3C,SAAS,EAAE,EAAE;CAC7B;AACF"}
|