@formisch/qwik 0.1.0 → 0.1.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.
Files changed (66) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +392 -0
  3. package/dist/index.qwik.js +697 -0
  4. package/package.json +9 -17
  5. package/lib/components/Field/Field.qwik.cjs +0 -14
  6. package/lib/components/Field/Field.qwik.mjs +0 -14
  7. package/lib/components/FieldArray/FieldArray.qwik.cjs +0 -14
  8. package/lib/components/FieldArray/FieldArray.qwik.mjs +0 -14
  9. package/lib/components/Form/Form.qwik.cjs +0 -36
  10. package/lib/components/Form/Form.qwik.mjs +0 -36
  11. package/lib/hooks/useField/useField.qwik.cjs +0 -48
  12. package/lib/hooks/useField/useField.qwik.mjs +0 -48
  13. package/lib/hooks/useFieldArray/useFieldArray.qwik.cjs +0 -18
  14. package/lib/hooks/useFieldArray/useFieldArray.qwik.mjs +0 -18
  15. package/lib/hooks/useForm_/useForm_.qwik.cjs +0 -52
  16. package/lib/hooks/useForm_/useForm_.qwik.mjs +0 -35
  17. package/lib/hooks/usePathSignal/usePathSignal.qwik.cjs +0 -18
  18. package/lib/hooks/usePathSignal/usePathSignal.qwik.mjs +0 -18
  19. package/lib/hooks/useResolvedQrl/useResolvedQrl.qwik.cjs +0 -14
  20. package/lib/hooks/useResolvedQrl/useResolvedQrl.qwik.mjs +0 -14
  21. package/lib/index.qwik.cjs +0 -30
  22. package/lib/index.qwik.mjs +0 -30
  23. package/lib/packages/core/dist/index.qwik.qwik.cjs +0 -401
  24. package/lib/packages/core/dist/index.qwik.qwik.mjs +0 -379
  25. package/lib/packages/methods/dist/index.qwik.qwik.cjs +0 -178
  26. package/lib/packages/methods/dist/index.qwik.qwik.mjs +0 -178
  27. package/lib-types/components/Field/Field.d.ts +0 -16
  28. package/lib-types/components/Field/index.d.ts +0 -1
  29. package/lib-types/components/FieldArray/FieldArray.d.ts +0 -16
  30. package/lib-types/components/FieldArray/index.d.ts +0 -1
  31. package/lib-types/components/Form/Form.d.ts +0 -8
  32. package/lib-types/components/Form/index.d.ts +0 -1
  33. package/lib-types/components/Lifecycle/Lifecycle.d.ts +0 -6
  34. package/lib-types/components/Lifecycle/index.d.ts +0 -1
  35. package/lib-types/components/counter/counter.d.ts +0 -1
  36. package/lib-types/components/index.d.ts +0 -3
  37. package/lib-types/components/logo/logo.d.ts +0 -1
  38. package/lib-types/entry.dev.d.ts +0 -2
  39. package/lib-types/entry.ssr.d.ts +0 -14
  40. package/lib-types/hooks/index.d.ts +0 -3
  41. package/lib-types/hooks/useField/index.d.ts +0 -1
  42. package/lib-types/hooks/useField/useField.d.ts +0 -7
  43. package/lib-types/hooks/useField/useField_2.d.ts +0 -7
  44. package/lib-types/hooks/useFieldArray/index.d.ts +0 -1
  45. package/lib-types/hooks/useFieldArray/useFieldArray.d.ts +0 -7
  46. package/lib-types/hooks/useForm/index.d.ts +0 -1
  47. package/lib-types/hooks/useForm/useForm copy.d.ts +0 -9
  48. package/lib-types/hooks/useForm/useForm.d.ts +0 -5
  49. package/lib-types/hooks/useForm$/index.d.ts +0 -1
  50. package/lib-types/hooks/useForm$/useForm$.d.ts +0 -5
  51. package/lib-types/hooks/useFormStore/index.d.ts +0 -1
  52. package/lib-types/hooks/useFormStore/useFormStore.d.ts +0 -5
  53. package/lib-types/hooks/useLiveSignal copy/index.d.ts +0 -1
  54. package/lib-types/hooks/useLiveSignal copy/useLiveSignal.d.ts +0 -2
  55. package/lib-types/hooks/usePathSignal/index.d.ts +0 -1
  56. package/lib-types/hooks/usePathSignal/usePathSignal.d.ts +0 -3
  57. package/lib-types/hooks/useResolvedQrl/index.d.ts +0 -1
  58. package/lib-types/hooks/useResolvedQrl/useResolvedQrl.d.ts +0 -2
  59. package/lib-types/index.d.ts +0 -4
  60. package/lib-types/root.d.ts +0 -2
  61. package/lib-types/types/field.d.ts +0 -38
  62. package/lib-types/types/form.d.ts +0 -11
  63. package/lib-types/types/index.d.ts +0 -2
  64. package/lib-types/utils/createInternalSignal/createInternalSignal.d.ts +0 -3
  65. package/lib-types/utils/createInternalSignal/index.d.ts +0 -1
  66. package/lib-types/utils/index.d.ts +0 -0
@@ -0,0 +1,697 @@
1
+ import * as v from "valibot";
2
+ import { $, Slot, component$, createComputed$, createSignal, implicit$FirstArg, untrack, useComputed$, useConstant, useSignal, useTask$ } from "@qwik.dev/core";
3
+ import { jsx } from "@qwik.dev/core/jsx-runtime";
4
+
5
+ //#region ../../packages/core/dist/index.qwik.js
6
+ const framework = "qwik";
7
+ function createId() {
8
+ return Math.random().toString(36).slice(2);
9
+ }
10
+ function batch(fn) {
11
+ return fn();
12
+ }
13
+ /**
14
+ * TODO: Add comment
15
+ * TODO: Should this stay in /primitives or move to /utils?
16
+ */
17
+ function initializeFieldStore(internalFieldStore, schema, initialInput, path) {
18
+ if (framework === "qwik" && schema.type === "lazy" || schema.type === "object_with_rest" || schema.type === "record" || schema.type === "tuple_with_rest" || schema.type === "promise") throw new Error(`"${schema.type}" schema is not supported`);
19
+ else if (schema.type === "lazy") initializeFieldStore(internalFieldStore, schema.getter(void 0), initialInput, path);
20
+ else if (schema.type === "exact_optional" || schema.type === "non_nullable" || schema.type === "non_nullish" || schema.type === "non_optional" || schema.type === "nullable" || schema.type === "nullish" || schema.type === "optional" || schema.type === "undefinedable") initializeFieldStore(internalFieldStore, schema.wrapped, initialInput ?? v.getDefault(schema), path);
21
+ else if (schema.type === "intersect" || schema.type === "union" || schema.type === "variant") for (const schemaOption of schema.options) initializeFieldStore(internalFieldStore, schemaOption, initialInput, path);
22
+ else {
23
+ internalFieldStore.schema = schema;
24
+ internalFieldStore.name = JSON.stringify(path);
25
+ internalFieldStore.elements = [];
26
+ internalFieldStore.errors = createSignal(null);
27
+ if (schema.type === "array" || schema.type === "loose_tuple" || schema.type === "strict_tuple" || schema.type === "tuple") {
28
+ if (internalFieldStore.kind && internalFieldStore.kind !== "array") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "array"`);
29
+ internalFieldStore.kind = "array";
30
+ if (internalFieldStore.kind === "array") {
31
+ internalFieldStore.children ??= [];
32
+ if (schema.type === "array") {
33
+ if (initialInput) for (let index = 0; index < initialInput.length; index++) {
34
+ internalFieldStore.children[index] = {};
35
+ path.push(index);
36
+ initializeFieldStore(internalFieldStore.children[index], schema.item, initialInput[index], path);
37
+ path.pop();
38
+ }
39
+ } else for (let index = 0; index < schema.items; index++) {
40
+ internalFieldStore.children[index] = {};
41
+ path.push(index);
42
+ initializeFieldStore(internalFieldStore.children[index], schema.items[index], initialInput && initialInput[index], path);
43
+ path.pop();
44
+ }
45
+ const initialItems = internalFieldStore.children.map(createId);
46
+ internalFieldStore.initialItems = createSignal(initialItems);
47
+ internalFieldStore.startItems = createSignal(initialItems);
48
+ internalFieldStore.items = createSignal(initialItems);
49
+ internalFieldStore.isTouched = createSignal(false);
50
+ internalFieldStore.isDirty = createSignal(false);
51
+ }
52
+ } else if (schema.type === "loose_object" || schema.type === "object" || schema.type === "strict_object") {
53
+ if (internalFieldStore.kind && internalFieldStore.kind !== "object") throw new Error(`Store initialized as "${internalFieldStore.kind}" cannot be reinitialized as "object"`);
54
+ internalFieldStore.kind = "object";
55
+ if (internalFieldStore.kind === "object") {
56
+ internalFieldStore.children ??= {};
57
+ for (const key in schema.entries) {
58
+ internalFieldStore.children[key] = {};
59
+ path.push(key);
60
+ initializeFieldStore(internalFieldStore.children[key], schema.entries[key], initialInput && initialInput[key], path);
61
+ path.pop();
62
+ }
63
+ }
64
+ } else {
65
+ internalFieldStore.kind = "value";
66
+ if (internalFieldStore.kind === "value") {
67
+ internalFieldStore.initialInput = createSignal(initialInput);
68
+ internalFieldStore.startInput = createSignal(initialInput);
69
+ internalFieldStore.input = createSignal(initialInput);
70
+ internalFieldStore.isTouched = createSignal(false);
71
+ internalFieldStore.isDirty = createSignal(false);
72
+ }
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Copies the deeply nested state (signal values) from one array item to another.
78
+ * This includes the `isTouched`, `isDirty`, `startInput`, `input`, `startItems`, and `items` properties.
79
+ * Recursively walks through the field stores and copies all signal values.
80
+ *
81
+ * @param internalArrayStore - The field store of the array (not the array item)
82
+ * @param fromIndex - The source index to copy from
83
+ * @param toIndex - The destination index to copy to
84
+ */
85
+ function copyItemState(fromInternalFieldStore, toInternalFieldStore) {
86
+ batch(() => {
87
+ untrack(() => {
88
+ if (fromInternalFieldStore.kind === "array" && toInternalFieldStore.kind === "array") {
89
+ const fromItems = fromInternalFieldStore.items.value;
90
+ toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
91
+ toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
92
+ toInternalFieldStore.startItems.value = fromInternalFieldStore.startItems.value;
93
+ toInternalFieldStore.items.value = fromItems;
94
+ let path;
95
+ for (let index = 0; index < fromItems.length; index++) {
96
+ if (!toInternalFieldStore.children[index]) {
97
+ path ??= JSON.parse(toInternalFieldStore.name);
98
+ toInternalFieldStore.children[index] = {};
99
+ path.push(index);
100
+ initializeFieldStore(toInternalFieldStore.children[index], toInternalFieldStore.schema.item, void 0, path);
101
+ path.pop();
102
+ }
103
+ copyItemState(fromInternalFieldStore.children[index], toInternalFieldStore.children[index]);
104
+ }
105
+ } else if (fromInternalFieldStore.kind === "object" && toInternalFieldStore.kind === "object") for (const key in fromInternalFieldStore.children) copyItemState(fromInternalFieldStore.children[key], toInternalFieldStore.children[key]);
106
+ else if (fromInternalFieldStore.kind === "value" && toInternalFieldStore.kind === "value") {
107
+ toInternalFieldStore.isTouched.value = fromInternalFieldStore.isTouched.value;
108
+ toInternalFieldStore.isDirty.value = fromInternalFieldStore.isDirty.value;
109
+ toInternalFieldStore.startInput.value = fromInternalFieldStore.startInput.value;
110
+ toInternalFieldStore.input.value = fromInternalFieldStore.input.value;
111
+ }
112
+ });
113
+ });
114
+ }
115
+ /**
116
+ * Resets the state of an array item (signal values) deeply nested.
117
+ * Sets `isTouched` and `isDirty` to `false` and `startInput`, `input`,
118
+ * `startItems` and `items` to the new input.
119
+ * Keeps the `initialInput` and `initialItems` state unchanged for form reset functionality.
120
+ *
121
+ * @param internalFieldStore - The field store of the array item
122
+ * @param initialInput - The new input value (can be any type including array or object)
123
+ */
124
+ function resetItemState(internalFieldStore, initialInput) {
125
+ batch(() => {
126
+ if (internalFieldStore.kind === "array") {
127
+ internalFieldStore.isTouched.value = false;
128
+ internalFieldStore.isDirty.value = false;
129
+ if (initialInput) {
130
+ const newItems = initialInput.map(createId);
131
+ internalFieldStore.startItems.value = newItems;
132
+ internalFieldStore.items.value = newItems;
133
+ for (let index = 0; index < initialInput.length; index++) if (internalFieldStore.children[index]) resetItemState(internalFieldStore.children[index], initialInput[index]);
134
+ } else {
135
+ internalFieldStore.startItems.value = [];
136
+ internalFieldStore.items.value = [];
137
+ }
138
+ } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) resetItemState(internalFieldStore.children[key], initialInput?.[key]);
139
+ else {
140
+ internalFieldStore.isTouched.value = false;
141
+ internalFieldStore.isDirty.value = false;
142
+ internalFieldStore.startInput.value = initialInput;
143
+ internalFieldStore.input.value = initialInput;
144
+ }
145
+ });
146
+ }
147
+ /**
148
+ * Swaps the deeply nested state (signal values) between two field stores.
149
+ * This includes the `isTouched`, `isDirty`, `startInput`, `input`, `startItems`, and `items` properties.
150
+ * Recursively walks through the field stores and swaps all signal values.
151
+ *
152
+ * @param firstInternalFieldStore - The first field store to swap
153
+ * @param secondInternalFieldStore - The second field store to swap
154
+ */
155
+ function swapItemState(firstInternalFieldStore, secondInternalFieldStore) {
156
+ batch(() => {
157
+ untrack(() => {
158
+ if (firstInternalFieldStore.kind === "array" && secondInternalFieldStore.kind === "array") {
159
+ const firstItems = firstInternalFieldStore.items.value;
160
+ const secondItems = secondInternalFieldStore.items.value;
161
+ const tempIsTouched = firstInternalFieldStore.isTouched.value;
162
+ firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
163
+ secondInternalFieldStore.isTouched.value = tempIsTouched;
164
+ const tempIsDirty = firstInternalFieldStore.isDirty.value;
165
+ firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
166
+ secondInternalFieldStore.isDirty.value = tempIsDirty;
167
+ const tempStartItems = firstInternalFieldStore.startItems.value;
168
+ firstInternalFieldStore.startItems.value = secondInternalFieldStore.startItems.value;
169
+ secondInternalFieldStore.startItems.value = tempStartItems;
170
+ firstInternalFieldStore.items.value = secondItems;
171
+ secondInternalFieldStore.items.value = firstItems;
172
+ const maxLength = Math.max(firstItems.length, secondItems.length);
173
+ let firstPath;
174
+ let secondPath;
175
+ for (let index = 0; index < maxLength; index++) {
176
+ if (!firstInternalFieldStore.children[index]) {
177
+ firstPath ??= JSON.parse(firstInternalFieldStore.name);
178
+ firstInternalFieldStore.children[index] = {};
179
+ firstPath.push(index);
180
+ initializeFieldStore(firstInternalFieldStore.children[index], firstInternalFieldStore.schema.item, void 0, firstPath);
181
+ firstPath.pop();
182
+ }
183
+ if (!secondInternalFieldStore.children[index]) {
184
+ secondPath ??= JSON.parse(secondInternalFieldStore.name);
185
+ secondInternalFieldStore.children[index] = {};
186
+ secondPath.push(index);
187
+ initializeFieldStore(secondInternalFieldStore.children[index], secondInternalFieldStore.schema.item, void 0, secondPath);
188
+ secondPath.pop();
189
+ }
190
+ swapItemState(firstInternalFieldStore.children[index], secondInternalFieldStore.children[index]);
191
+ }
192
+ } else if (firstInternalFieldStore.kind === "object" && secondInternalFieldStore.kind === "object") for (const key in firstInternalFieldStore.children) swapItemState(firstInternalFieldStore.children[key], secondInternalFieldStore.children[key]);
193
+ else if (firstInternalFieldStore.kind === "value" && secondInternalFieldStore.kind === "value") {
194
+ const tempIsTouched = firstInternalFieldStore.isTouched.value;
195
+ firstInternalFieldStore.isTouched.value = secondInternalFieldStore.isTouched.value;
196
+ secondInternalFieldStore.isTouched.value = tempIsTouched;
197
+ const tempIsDirty = firstInternalFieldStore.isDirty.value;
198
+ firstInternalFieldStore.isDirty.value = secondInternalFieldStore.isDirty.value;
199
+ secondInternalFieldStore.isDirty.value = tempIsDirty;
200
+ const tempStartInput = firstInternalFieldStore.startInput.value;
201
+ firstInternalFieldStore.startInput.value = secondInternalFieldStore.startInput.value;
202
+ secondInternalFieldStore.startInput.value = tempStartInput;
203
+ const tempInput = firstInternalFieldStore.input.value;
204
+ firstInternalFieldStore.input.value = secondInternalFieldStore.input.value;
205
+ secondInternalFieldStore.input.value = tempInput;
206
+ }
207
+ });
208
+ });
209
+ }
210
+ function getFieldInput(internalFieldStore) {
211
+ if (internalFieldStore.kind === "array") {
212
+ const value = [];
213
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
214
+ return value;
215
+ }
216
+ if (internalFieldStore.kind === "object") {
217
+ const value = {};
218
+ for (const key in internalFieldStore.children) value[key] = getFieldInput(internalFieldStore.children[key]);
219
+ return value;
220
+ }
221
+ return internalFieldStore.input.value;
222
+ }
223
+ /**
224
+ * Returns the current input of the element.
225
+ *
226
+ * @param element The field element.
227
+ * @param interalFieldStore The interal field store.
228
+ *
229
+ * @returns The element input.
230
+ */
231
+ function getElementInput(element, internalFieldStore) {
232
+ if (element.options && element.multiple) return [...element.options].filter((option) => option.selected && !option.disabled).map((option) => option.value);
233
+ if (element.type === "checkbox") {
234
+ const options = document.getElementsByName(element.name);
235
+ if (options.length > 1) return [...options].filter((option) => option.checked).map((option) => option.value);
236
+ return element.checked;
237
+ }
238
+ if (element.type === "radio") {
239
+ const prevValue = untrack(() => getFieldInput(internalFieldStore));
240
+ if (element.checked) return [...prevValue, element.value];
241
+ return prevValue.filter((value) => value !== element.value);
242
+ }
243
+ if (element.type === "file") {
244
+ if (element.multiple) return [...element.files];
245
+ return element.files[0];
246
+ }
247
+ return element.value;
248
+ }
249
+ function getFieldBool(internalFieldStore, type) {
250
+ if (internalFieldStore.kind === "array") {
251
+ if (internalFieldStore[type].value) return true;
252
+ for (let index = 0; index < internalFieldStore.items.value.length; index++) if (getFieldBool(internalFieldStore.children[index], type)) return true;
253
+ return false;
254
+ }
255
+ if (internalFieldStore.kind == "object") {
256
+ if (type === "errors" && internalFieldStore[type].value) return true;
257
+ for (const key in internalFieldStore.children) if (getFieldBool(internalFieldStore.children[key], type)) return true;
258
+ return false;
259
+ }
260
+ return !!internalFieldStore[type].value;
261
+ }
262
+ function getFieldStore(internalFormStore, path) {
263
+ let internalFieldStore = internalFormStore;
264
+ for (const key of path) internalFieldStore = internalFieldStore.children[key];
265
+ return internalFieldStore;
266
+ }
267
+ function setFieldBool(internalFieldStore, type, bool) {
268
+ batch(() => {
269
+ if (internalFieldStore.kind === "array") {
270
+ internalFieldStore[type].value = bool;
271
+ for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) setFieldBool(internalFieldStore.children[index], type, bool);
272
+ } else if (internalFieldStore.kind == "object") for (const key in internalFieldStore.children) setFieldBool(internalFieldStore.children[key], type, bool);
273
+ else internalFieldStore[type].value = bool;
274
+ });
275
+ }
276
+ function setFieldInput(internalFieldStore, input) {
277
+ batch(() => {
278
+ if (internalFieldStore.kind === "array") {
279
+ const items = untrack(() => internalFieldStore.items.value);
280
+ if (input.length < items.length) internalFieldStore.items.value = items.slice(0, input.length);
281
+ else if (input.length > items.length) {
282
+ if (input.length > internalFieldStore.children.length) {
283
+ const path = JSON.parse(internalFieldStore.name);
284
+ for (let index = internalFieldStore.children.length; index < input.length; index++) {
285
+ internalFieldStore.children[index] = {};
286
+ path.push(index);
287
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, input[index], path);
288
+ path.pop();
289
+ }
290
+ }
291
+ internalFieldStore.items.value = [...items, ...input.slice(items.length).map(createId)];
292
+ }
293
+ for (let index = 0; index < items.length; index++) setFieldInput(internalFieldStore.children[index], input[index]);
294
+ internalFieldStore.isDirty.value = untrack(() => internalFieldStore.startItems.value).length !== items.length;
295
+ } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setFieldInput(internalFieldStore.children[key], input[key]);
296
+ else {
297
+ internalFieldStore.input.value = input;
298
+ const startInput = untrack(() => internalFieldStore.startInput.value);
299
+ internalFieldStore.isDirty.value = startInput !== input && (startInput !== void 0 || input !== "" && !Number.isNaN(input));
300
+ }
301
+ });
302
+ }
303
+ function setInitialFieldInput(internalFieldStore, initialInput) {
304
+ batch(() => {
305
+ if (internalFieldStore.kind === "array") {
306
+ if (initialInput.length > internalFieldStore.children.length) {
307
+ const path = JSON.parse(internalFieldStore.name);
308
+ for (let index = internalFieldStore.children.length; index < initialInput.length; index++) {
309
+ internalFieldStore.children[index] = {};
310
+ path.push(index);
311
+ initializeFieldStore(internalFieldStore.children[index], internalFieldStore.schema.item, initialInput[index], path);
312
+ path.pop();
313
+ }
314
+ }
315
+ internalFieldStore.initialItems.value = initialInput.map(createId);
316
+ for (let index = 0; index < internalFieldStore.children.length; index++) setInitialFieldInput(internalFieldStore.children[index], initialInput?.[index]);
317
+ } else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) setInitialFieldInput(internalFieldStore.children[key], initialInput?.[key]);
318
+ else internalFieldStore.initialInput.value = initialInput;
319
+ });
320
+ }
321
+ function walkFieldStore(internalFieldStore, callback) {
322
+ callback(internalFieldStore);
323
+ if (internalFieldStore.kind === "array") for (let index = 0; index < untrack(() => internalFieldStore.items.value).length; index++) walkFieldStore(internalFieldStore.children[index], callback);
324
+ else if (internalFieldStore.kind === "object") for (const key in internalFieldStore.children) walkFieldStore(internalFieldStore.children[key], callback);
325
+ }
326
+ function createFormStore(config, validate$1) {
327
+ const store = {};
328
+ initializeFieldStore(store, config.schema, config.initialInput, []);
329
+ store.validateOn = config.validateOn ?? "submit";
330
+ store.revalidateOn = config.revalidateOn ?? "input";
331
+ store.validate = validate$1;
332
+ store.isSubmitting = createSignal(false);
333
+ store.isSubmitted = createSignal(false);
334
+ store.isValidating = createSignal(false);
335
+ return store;
336
+ }
337
+ async function validateFormInput(internalFormStore, config) {
338
+ internalFormStore.validators++;
339
+ internalFormStore.isValidating.value = true;
340
+ const result = await internalFormStore.validate(untrack(() => getFieldInput(internalFormStore)));
341
+ let rootErrors;
342
+ let nestedErrors;
343
+ if (result.issues) {
344
+ nestedErrors = {};
345
+ for (const issue of result.issues) if (issue.path) {
346
+ const path = [];
347
+ for (const pathItem of issue.path) {
348
+ const key = pathItem.key;
349
+ const keyType = typeof key;
350
+ const itemType = pathItem.type;
351
+ if (keyType !== "string" && keyType !== "number" || itemType === "map" || itemType === "set") break;
352
+ path.push(key);
353
+ }
354
+ const name = JSON.stringify(path);
355
+ const fieldErrors = nestedErrors[name];
356
+ if (fieldErrors) fieldErrors.push(issue.message);
357
+ else nestedErrors[name] = [issue.message];
358
+ } else if (rootErrors) rootErrors.push(issue.message);
359
+ else rootErrors = [issue.message];
360
+ }
361
+ let shouldFocus = config?.shouldFocus ?? false;
362
+ batch(() => {
363
+ walkFieldStore(internalFormStore, (internalFieldStore) => {
364
+ if (internalFieldStore.name === "[]") internalFieldStore.errors.value = rootErrors ?? null;
365
+ else {
366
+ const fieldErrors = nestedErrors?.[internalFieldStore.name] ?? null;
367
+ internalFieldStore.errors.value = fieldErrors;
368
+ if (shouldFocus && fieldErrors) {
369
+ internalFieldStore.elements[0]?.focus();
370
+ shouldFocus = false;
371
+ }
372
+ }
373
+ });
374
+ internalFormStore.validators--;
375
+ internalFormStore.isValidating.value = internalFormStore.validators > 0;
376
+ });
377
+ return result;
378
+ }
379
+ function validateIfRequired(internalFormStore, internalFieldStore, validationModes) {
380
+ if (validationModes === (internalFormStore.validateOn === "initial" || (internalFormStore.validateOn === "submit" ? untrack(() => internalFormStore.isSubmitted.value) : untrack(() => getFieldBool(internalFieldStore, "errors"))) ? internalFormStore.revalidateOn : internalFormStore.validateOn)) validateFormInput(internalFormStore);
381
+ }
382
+ const INTERNAL = "~internal";
383
+
384
+ //#endregion
385
+ //#region ../../packages/methods/dist/index.qwik.js
386
+ function focus(config) {
387
+ getFieldStore(config.form[INTERNAL], config.path).elements[0]?.focus();
388
+ }
389
+ function getAllErrors(form) {
390
+ let allErrors = null;
391
+ walkFieldStore(form[INTERNAL], (internalFieldStore) => {
392
+ const errors = internalFieldStore.errors.value;
393
+ if (errors) if (allErrors) allErrors.push(...errors);
394
+ else allErrors = [...errors];
395
+ });
396
+ return allErrors;
397
+ }
398
+ function getErrors(form, config) {
399
+ return (config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value;
400
+ }
401
+ function getInput(form, config) {
402
+ return getFieldInput(config?.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]);
403
+ }
404
+ function insert(form, config) {
405
+ const internalFormStore = form[INTERNAL];
406
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
407
+ const items = untrack(() => internalArrayStore.items.value);
408
+ const insertIndex = config.at === void 0 ? items.length : config.at;
409
+ if (insertIndex >= 0 && insertIndex <= items.length) batch(() => {
410
+ const newItems = [...items];
411
+ newItems.splice(insertIndex, 0, createId());
412
+ internalArrayStore.items.value = newItems;
413
+ for (let index = items.length; index > insertIndex; index--) copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
414
+ if (!internalArrayStore.children[insertIndex]) {
415
+ const path = JSON.parse(internalArrayStore.name);
416
+ internalArrayStore.children[insertIndex] = {};
417
+ path.push(insertIndex);
418
+ initializeFieldStore(internalArrayStore.children[insertIndex], internalArrayStore.schema.item, config.initialInput, path);
419
+ } else resetItemState(internalArrayStore.children[insertIndex], config.initialInput);
420
+ internalArrayStore.isTouched.value = true;
421
+ internalArrayStore.isDirty.value = true;
422
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
423
+ });
424
+ }
425
+ function move(form, config) {
426
+ const internalFormStore = form[INTERNAL];
427
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
428
+ const items = untrack(() => internalArrayStore.items.value);
429
+ if (config.from >= 0 && config.from <= items.length - 1 && config.to >= 0 && config.to <= items.length - 1 && config.from !== config.to) batch(() => {
430
+ const newItems = [...items];
431
+ newItems.splice(config.to, 0, newItems.splice(config.from, 1)[0]);
432
+ internalArrayStore.items.value = newItems;
433
+ const tempInternalFieldStore = {};
434
+ initializeFieldStore(tempInternalFieldStore, internalArrayStore.schema.item, void 0, []);
435
+ copyItemState(internalArrayStore.children[config.from < config.to ? config.from : config.to], tempInternalFieldStore);
436
+ if (config.from < config.to) for (let index = config.from; index < config.to; index++) copyItemState(internalArrayStore.children[index + 1], internalArrayStore.children[index]);
437
+ else for (let index = config.from; index > config.to; index--) copyItemState(internalArrayStore.children[index - 1], internalArrayStore.children[index]);
438
+ copyItemState(tempInternalFieldStore, internalArrayStore.children[config.from < config.to ? config.to : config.from]);
439
+ internalArrayStore.isTouched.value = true;
440
+ internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
441
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
442
+ });
443
+ }
444
+ function remove(form, config) {
445
+ const internalFormStore = form[INTERNAL];
446
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
447
+ const items = untrack(() => internalArrayStore.items.value);
448
+ if (config.at >= 0 && config.at <= items.length - 1) batch(() => {
449
+ const newItems = [...items];
450
+ newItems.splice(config.at, 1);
451
+ internalArrayStore.items.value = newItems;
452
+ for (let index = config.at; index < items.length - 1; index++) copyItemState(internalArrayStore.children[index + 1], internalArrayStore.children[index]);
453
+ internalArrayStore.isTouched.value = true;
454
+ internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
455
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
456
+ });
457
+ }
458
+ function replace(form, config) {
459
+ const internalFormStore = form[INTERNAL];
460
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
461
+ const items = untrack(() => internalArrayStore.items.value);
462
+ if (config.at >= 0 && config.at <= items.length - 1) batch(() => {
463
+ const newItems = [...items];
464
+ newItems[config.at] = createId();
465
+ internalArrayStore.items.value = newItems;
466
+ resetItemState(internalArrayStore.children[config.at], config.initialInput);
467
+ internalArrayStore.isTouched.value = true;
468
+ internalArrayStore.isDirty.value = true;
469
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
470
+ });
471
+ }
472
+ function reset(form, config) {
473
+ batch(() => {
474
+ untrack(() => {
475
+ const internalFormStore = form[INTERNAL];
476
+ const internalFieldStore = config?.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
477
+ if (config?.initialInput) setInitialFieldInput(internalFieldStore, config.initialInput);
478
+ walkFieldStore(internalFieldStore, (internalFieldStore$1) => {
479
+ if (!config?.keepErrors) internalFieldStore$1.errors.value = null;
480
+ if (internalFieldStore$1.kind === "array") {
481
+ internalFieldStore$1.startItems.value = internalFieldStore$1.initialItems.value;
482
+ if (!config?.keepInput || internalFieldStore$1.startItems.value.length === internalFieldStore$1.items.value.length) internalFieldStore$1.items.value = internalFieldStore$1.initialItems.value;
483
+ if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
484
+ internalFieldStore$1.isDirty.value = internalFieldStore$1.startItems.value !== internalFieldStore$1.items.value;
485
+ } else if (internalFieldStore$1.kind === "value") {
486
+ internalFieldStore$1.startInput.value = internalFieldStore$1.initialInput.value;
487
+ if (!config?.keepInput) internalFieldStore$1.input.value = internalFieldStore$1.initialInput.value;
488
+ if (!config?.keepTouched) internalFieldStore$1.isTouched.value = false;
489
+ internalFieldStore$1.isDirty.value = internalFieldStore$1.startInput.value !== internalFieldStore$1.input.value;
490
+ for (const element of internalFieldStore$1.elements) if (element.type === "file") element.value = "";
491
+ }
492
+ });
493
+ if (!config?.path) {
494
+ if (!config?.keepSubmitted) internalFormStore.isSubmitted.value = false;
495
+ if (internalFormStore.validateOn === "initial") validateFormInput(internalFormStore);
496
+ }
497
+ });
498
+ });
499
+ }
500
+ function setErrors(form, config) {
501
+ (config.path ? getFieldStore(form[INTERNAL], config.path) : form[INTERNAL]).errors.value = config.errors;
502
+ }
503
+ function setInput(form, config) {
504
+ batch(() => {
505
+ const internalFormStore = form[INTERNAL];
506
+ const internalFieldStore = config.path ? getFieldStore(internalFormStore, config.path) : internalFormStore;
507
+ setFieldBool(internalFieldStore, "isTouched", true);
508
+ setFieldInput(internalFieldStore, config.input);
509
+ validateIfRequired(internalFormStore, internalFieldStore, "input");
510
+ });
511
+ }
512
+ function submit(form) {
513
+ form[INTERNAL].element?.requestSubmit();
514
+ }
515
+ function swap(form, config) {
516
+ const internalFormStore = form[INTERNAL];
517
+ const internalArrayStore = getFieldStore(internalFormStore, config.path);
518
+ const items = untrack(() => internalArrayStore.items.value);
519
+ if (config.at >= 0 && config.at <= items.length - 1 && config.and >= 0 && config.and <= items.length - 1 && config.at !== config.and) batch(() => {
520
+ const newItems = [...items];
521
+ const tempItemId = newItems[config.at];
522
+ newItems[config.at] = newItems[config.and];
523
+ newItems[config.and] = tempItemId;
524
+ internalArrayStore.items.value = newItems;
525
+ swapItemState(internalArrayStore.children[config.at], internalArrayStore.children[config.and]);
526
+ internalArrayStore.isTouched.value = true;
527
+ internalArrayStore.isDirty.value = internalArrayStore.startItems.value.join() !== newItems.join();
528
+ validateIfRequired(internalFormStore, internalArrayStore, "input");
529
+ });
530
+ }
531
+ function validate(form, config) {
532
+ return validateFormInput(form[INTERNAL], config);
533
+ }
534
+
535
+ //#endregion
536
+ //#region src/hooks/usePathSignal/usePathSignal.ts
537
+ function isEqual(a, b) {
538
+ if (a.length !== b.length) return false;
539
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
540
+ return true;
541
+ }
542
+ function usePathSignal(path) {
543
+ const signal = useSignal(path);
544
+ if (!isEqual(signal.value, path)) signal.value = path;
545
+ return signal;
546
+ }
547
+
548
+ //#endregion
549
+ //#region src/hooks/useField/useField.ts
550
+ function useField(form, config) {
551
+ const pathSignal = usePathSignal(config.path);
552
+ const internalFieldStore = useComputed$(() => getFieldStore(form[INTERNAL], pathSignal.value));
553
+ useTask$(({ track, cleanup }) => {
554
+ track(internalFieldStore);
555
+ cleanup(() => {
556
+ internalFieldStore.value.elements = internalFieldStore.value.elements.filter((element) => element.isConnected);
557
+ });
558
+ });
559
+ return useConstant(() => ({
560
+ path: pathSignal,
561
+ input: createComputed$(() => getFieldInput(internalFieldStore.value)),
562
+ errors: createComputed$(() => internalFieldStore.value.errors.value),
563
+ isTouched: createComputed$(() => getFieldBool(internalFieldStore.value, "isTouched")),
564
+ isDirty: createComputed$(() => getFieldBool(internalFieldStore.value, "isDirty")),
565
+ isValid: createComputed$(() => !getFieldBool(internalFieldStore.value, "errors")),
566
+ props: {
567
+ get name() {
568
+ return internalFieldStore.value.name;
569
+ },
570
+ autofocus: !!internalFieldStore.value.errors.value,
571
+ ref: $((element) => {
572
+ internalFieldStore.value.elements.push(element);
573
+ }),
574
+ onFocus$: $(() => {
575
+ setFieldBool(internalFieldStore.value, "isTouched", true);
576
+ validateIfRequired(form[INTERNAL], internalFieldStore.value, "touch");
577
+ }),
578
+ onInput$: $((_, element) => {
579
+ const nextValue = getElementInput(element, internalFieldStore.value);
580
+ setFieldInput(internalFieldStore.value, nextValue);
581
+ validateIfRequired(form[INTERNAL], internalFieldStore.value, "input");
582
+ }),
583
+ onChange$: $(() => {
584
+ validateIfRequired(form[INTERNAL], internalFieldStore.value, "change");
585
+ }),
586
+ onBlur$: $(() => {
587
+ validateIfRequired(form[INTERNAL], internalFieldStore.value, "blur");
588
+ })
589
+ }
590
+ }));
591
+ }
592
+
593
+ //#endregion
594
+ //#region src/hooks/useFieldArray/useFieldArray.ts
595
+ function useFieldArray(form, config) {
596
+ const pathSignal = usePathSignal(config.path);
597
+ const internalFieldStore = useComputed$(() => getFieldStore(form[INTERNAL], pathSignal.value));
598
+ return useConstant(() => ({
599
+ path: pathSignal,
600
+ items: createComputed$(() => internalFieldStore.value.items.value),
601
+ errors: createComputed$(() => internalFieldStore.value.errors.value),
602
+ isTouched: createComputed$(() => getFieldBool(internalFieldStore.value, "isTouched")),
603
+ isDirty: createComputed$(() => getFieldBool(internalFieldStore.value, "isDirty")),
604
+ isValid: createComputed$(() => !getFieldBool(internalFieldStore.value, "errors"))
605
+ }));
606
+ }
607
+
608
+ //#endregion
609
+ //#region src/hooks/useResolvedQrl/useResolvedQrl.ts
610
+ function useResolvedQrl(qrl) {
611
+ const store = useSignal();
612
+ const resolved = qrl.resolved ?? store.value;
613
+ if (!resolved) throw qrl.resolve().then((resolved$1) => {
614
+ store.value = resolved$1;
615
+ });
616
+ return resolved;
617
+ }
618
+
619
+ //#endregion
620
+ //#region src/hooks/useForm$/useForm$.ts
621
+ function useFormQrl(configQrl) {
622
+ const config = useResolvedQrl(configQrl);
623
+ const form = useConstant(() => {
624
+ const internalFormStore = createFormStore({
625
+ ...config,
626
+ schema: JSON.parse(JSON.stringify(config.schema))
627
+ }, $(async (input) => v.safeParseAsync((await configQrl.resolve()).schema, input)));
628
+ return {
629
+ [INTERNAL]: internalFormStore,
630
+ isSubmitting: internalFormStore.isSubmitting,
631
+ isSubmitted: internalFormStore.isSubmitted,
632
+ isValidating: internalFormStore.isValidating,
633
+ isTouched: createComputed$(() => getFieldBool(internalFormStore, "isTouched")),
634
+ isDirty: createComputed$(() => getFieldBool(internalFormStore, "isDirty")),
635
+ isValid: createComputed$(() => !getFieldBool(internalFormStore, "errors")),
636
+ errors: internalFormStore.errors
637
+ };
638
+ });
639
+ const validateOn = config.validateOn;
640
+ useTask$(async () => {
641
+ if (validateOn === "initial") await validateFormInput(form[INTERNAL]);
642
+ });
643
+ return form;
644
+ }
645
+ const useForm$ = implicit$FirstArg(useFormQrl);
646
+
647
+ //#endregion
648
+ //#region src/components/Field/Field.tsx
649
+ /**
650
+ * Headless form field that provides reactive properties and state.
651
+ */
652
+ const Field = component$(({ of, path, render$ }) => {
653
+ const field = useField(of, { path });
654
+ const render = useResolvedQrl(render$);
655
+ return render(field);
656
+ });
657
+
658
+ //#endregion
659
+ //#region src/components/FieldArray/FieldArray.tsx
660
+ /**
661
+ * Headless field array that provides reactive properties and state.
662
+ */
663
+ const FieldArray = component$(({ of, path, render$ }) => {
664
+ const field = useFieldArray(of, { path });
665
+ const render = useResolvedQrl(render$);
666
+ return render(field);
667
+ });
668
+
669
+ //#endregion
670
+ //#region src/components/Form/Form.tsx
671
+ const Form = component$(({ of, onSubmit$,...other }) => {
672
+ return /* @__PURE__ */ jsx("form", {
673
+ ...other,
674
+ noValidate: true,
675
+ "preventdefault:submit": true,
676
+ ref: (element) => {
677
+ of[INTERNAL].element = element;
678
+ },
679
+ onSubmit$: async (event) => {
680
+ const internalFormStore = of[INTERNAL];
681
+ internalFormStore.isSubmitted.value = true;
682
+ internalFormStore.isSubmitting.value = true;
683
+ try {
684
+ const result = await validateFormInput(internalFormStore, { shouldFocus: true });
685
+ if (result.success) await onSubmit$(result.output, event);
686
+ } catch (error) {
687
+ internalFormStore.errors.value = [error instanceof Error ? error.message : "An unknown error has occurred."];
688
+ } finally {
689
+ internalFormStore.isSubmitting.value = false;
690
+ }
691
+ },
692
+ children: /* @__PURE__ */ jsx(Slot, {})
693
+ });
694
+ });
695
+
696
+ //#endregion
697
+ export { Field, FieldArray, Form, focus, getAllErrors, getErrors, getInput, insert, move, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, useForm$, useFormQrl, validate };