@formality-ui/react 0.2.1 → 0.2.2
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/dist/index.cjs +43 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +43 -23
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -581,7 +581,15 @@ interface FormProps<TFieldValues extends FieldValues = FieldValues> {
|
|
|
581
581
|
record?: Partial<TFieldValues>;
|
|
582
582
|
/** Enable auto-save on field changes */
|
|
583
583
|
autoSave?: boolean;
|
|
584
|
-
/**
|
|
584
|
+
/**
|
|
585
|
+
* Form-level auto-save debounce, used as the fallback for any field whose
|
|
586
|
+
* `InputConfig.debounce` is unset.
|
|
587
|
+
* - `false` — submit immediately (no debounce timer).
|
|
588
|
+
* - `number` — delay auto-save by this many milliseconds (default: 1000).
|
|
589
|
+
*
|
|
590
|
+
* A field can override its own cadence via `InputConfig.debounce`
|
|
591
|
+
* (`false` for immediate, or a number for a per-field delay).
|
|
592
|
+
*/
|
|
585
593
|
debounce?: number | false;
|
|
586
594
|
/** Form-level validation */
|
|
587
595
|
validate?: (values: Partial<TFieldValues>) => Record<string, string> | Promise<Record<string, string>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -581,7 +581,15 @@ interface FormProps<TFieldValues extends FieldValues = FieldValues> {
|
|
|
581
581
|
record?: Partial<TFieldValues>;
|
|
582
582
|
/** Enable auto-save on field changes */
|
|
583
583
|
autoSave?: boolean;
|
|
584
|
-
/**
|
|
584
|
+
/**
|
|
585
|
+
* Form-level auto-save debounce, used as the fallback for any field whose
|
|
586
|
+
* `InputConfig.debounce` is unset.
|
|
587
|
+
* - `false` — submit immediately (no debounce timer).
|
|
588
|
+
* - `number` — delay auto-save by this many milliseconds (default: 1000).
|
|
589
|
+
*
|
|
590
|
+
* A field can override its own cadence via `InputConfig.debounce`
|
|
591
|
+
* (`false` for immediate, or a number for a per-field delay).
|
|
592
|
+
*/
|
|
585
593
|
debounce?: number | false;
|
|
586
594
|
/** Form-level validation */
|
|
587
595
|
validate?: (values: Partial<TFieldValues>) => Record<string, string> | Promise<Record<string, string>>;
|
package/dist/index.js
CHANGED
|
@@ -179,6 +179,8 @@ function Form({
|
|
|
179
179
|
const pendingChangedFields = useRef(/* @__PURE__ */ new Set());
|
|
180
180
|
const pendingAffectedFields = useRef(/* @__PURE__ */ new Set());
|
|
181
181
|
const executionVersionRef = useRef(0);
|
|
182
|
+
const fieldDebouncersRef = useRef(/* @__PURE__ */ new Map());
|
|
183
|
+
const getOrCreateDebouncedRef = useRef();
|
|
182
184
|
const registerField = useCallback((name) => {
|
|
183
185
|
fieldRegistry.current.add(name);
|
|
184
186
|
setRegisteredFields(new Set(fieldRegistry.current));
|
|
@@ -279,8 +281,11 @@ function Form({
|
|
|
279
281
|
for (const field of affected) {
|
|
280
282
|
pendingAffectedFields.current.add(field);
|
|
281
283
|
}
|
|
282
|
-
|
|
284
|
+
const fieldDebounce = inputConfig?.debounce;
|
|
285
|
+
if (fieldDebounce === false) {
|
|
283
286
|
executeAutoSaveRef.current?.();
|
|
287
|
+
} else if (typeof fieldDebounce === "number") {
|
|
288
|
+
getOrCreateDebouncedRef.current?.(fieldDebounce)();
|
|
284
289
|
} else {
|
|
285
290
|
debouncedSubmitRef.current?.();
|
|
286
291
|
}
|
|
@@ -421,53 +426,67 @@ function Form({
|
|
|
421
426
|
return;
|
|
422
427
|
}
|
|
423
428
|
}
|
|
424
|
-
const formState = methods.formState;
|
|
425
|
-
if (Object.keys(formState.errors).length > 0) {
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
429
|
const values = methods.getValues();
|
|
429
430
|
await handleSubmit(values);
|
|
430
431
|
}, [methods, handleSubmit, waitForFieldValidation]);
|
|
431
432
|
executeAutoSaveRef.current = executeAutoSave;
|
|
433
|
+
const getOrCreateDebounced = useCallback(
|
|
434
|
+
(ms) => {
|
|
435
|
+
const cached = fieldDebouncersRef.current.get(ms);
|
|
436
|
+
if (cached) return cached;
|
|
437
|
+
const debouncedFn = debounce(() => {
|
|
438
|
+
executeAutoSaveRef.current?.();
|
|
439
|
+
}, ms);
|
|
440
|
+
const fn = Object.assign(debouncedFn, {
|
|
441
|
+
pending: () => false
|
|
442
|
+
// lodash debounce tracks pending internally
|
|
443
|
+
});
|
|
444
|
+
fieldDebouncersRef.current.set(ms, fn);
|
|
445
|
+
return fn;
|
|
446
|
+
},
|
|
447
|
+
[]
|
|
448
|
+
);
|
|
449
|
+
getOrCreateDebouncedRef.current = getOrCreateDebounced;
|
|
432
450
|
useEffect(() => {
|
|
451
|
+
return () => {
|
|
452
|
+
fieldDebouncersRef.current.forEach((fn) => fn.cancel());
|
|
453
|
+
fieldDebouncersRef.current.clear();
|
|
454
|
+
};
|
|
455
|
+
}, [getOrCreateDebounced]);
|
|
456
|
+
const debouncedSubmit = useMemo(() => {
|
|
433
457
|
if (debounceMs === false) {
|
|
434
|
-
|
|
458
|
+
return Object.assign(
|
|
435
459
|
() => {
|
|
436
|
-
|
|
460
|
+
executeAutoSaveRef.current?.();
|
|
437
461
|
},
|
|
438
462
|
{
|
|
439
463
|
cancel: () => {
|
|
440
464
|
},
|
|
441
465
|
// No-op for immediate function
|
|
442
|
-
flush: () =>
|
|
466
|
+
flush: () => executeAutoSaveRef.current?.(),
|
|
443
467
|
// Execute immediately on flush
|
|
444
468
|
pending: () => false
|
|
445
469
|
// Never pending when immediate
|
|
446
470
|
}
|
|
447
471
|
);
|
|
448
|
-
debouncedSubmitRef.current = immediateFn;
|
|
449
|
-
return () => {
|
|
450
|
-
};
|
|
451
472
|
}
|
|
452
473
|
const debouncedFn = debounce(() => {
|
|
453
|
-
|
|
474
|
+
executeAutoSaveRef.current?.();
|
|
454
475
|
}, debounceMs);
|
|
455
|
-
|
|
476
|
+
return Object.assign(debouncedFn, {
|
|
456
477
|
pending: () => false
|
|
457
478
|
// lodash debounce handles this internally
|
|
458
479
|
});
|
|
459
|
-
|
|
480
|
+
}, [debounceMs]);
|
|
481
|
+
debouncedSubmitRef.current = debouncedSubmit;
|
|
482
|
+
useEffect(() => {
|
|
460
483
|
return () => {
|
|
461
|
-
|
|
484
|
+
debouncedSubmit.cancel();
|
|
462
485
|
};
|
|
463
|
-
}, [
|
|
486
|
+
}, [debouncedSubmit]);
|
|
464
487
|
const submitImmediate = useCallback(() => {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
} else {
|
|
468
|
-
executeAutoSave();
|
|
469
|
-
}
|
|
470
|
-
}, [executeAutoSave]);
|
|
488
|
+
debouncedSubmitRef.current?.flush();
|
|
489
|
+
}, []);
|
|
471
490
|
const unusedFields = useMemo(() => {
|
|
472
491
|
const allFields = Object.keys(config);
|
|
473
492
|
return allFields.filter((name) => !registeredFields.has(name));
|
|
@@ -506,7 +525,7 @@ function Form({
|
|
|
506
525
|
setFieldValidating,
|
|
507
526
|
getFormState,
|
|
508
527
|
onSubmit,
|
|
509
|
-
debouncedSubmit
|
|
528
|
+
debouncedSubmit,
|
|
510
529
|
submitImmediate,
|
|
511
530
|
unusedFields,
|
|
512
531
|
methods
|
|
@@ -525,6 +544,7 @@ function Form({
|
|
|
525
544
|
setFieldValidating,
|
|
526
545
|
getFormState,
|
|
527
546
|
onSubmit,
|
|
547
|
+
debouncedSubmit,
|
|
528
548
|
submitImmediate,
|
|
529
549
|
unusedFields,
|
|
530
550
|
methods
|