@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 CHANGED
@@ -181,6 +181,8 @@ function Form({
181
181
  const pendingChangedFields = react.useRef(/* @__PURE__ */ new Set());
182
182
  const pendingAffectedFields = react.useRef(/* @__PURE__ */ new Set());
183
183
  const executionVersionRef = react.useRef(0);
184
+ const fieldDebouncersRef = react.useRef(/* @__PURE__ */ new Map());
185
+ const getOrCreateDebouncedRef = react.useRef();
184
186
  const registerField = react.useCallback((name) => {
185
187
  fieldRegistry.current.add(name);
186
188
  setRegisteredFields(new Set(fieldRegistry.current));
@@ -281,8 +283,11 @@ function Form({
281
283
  for (const field of affected) {
282
284
  pendingAffectedFields.current.add(field);
283
285
  }
284
- if (inputConfig?.debounce === false) {
286
+ const fieldDebounce = inputConfig?.debounce;
287
+ if (fieldDebounce === false) {
285
288
  executeAutoSaveRef.current?.();
289
+ } else if (typeof fieldDebounce === "number") {
290
+ getOrCreateDebouncedRef.current?.(fieldDebounce)();
286
291
  } else {
287
292
  debouncedSubmitRef.current?.();
288
293
  }
@@ -423,53 +428,67 @@ function Form({
423
428
  return;
424
429
  }
425
430
  }
426
- const formState = methods.formState;
427
- if (Object.keys(formState.errors).length > 0) {
428
- return;
429
- }
430
431
  const values = methods.getValues();
431
432
  await handleSubmit(values);
432
433
  }, [methods, handleSubmit, waitForFieldValidation]);
433
434
  executeAutoSaveRef.current = executeAutoSave;
435
+ const getOrCreateDebounced = react.useCallback(
436
+ (ms) => {
437
+ const cached = fieldDebouncersRef.current.get(ms);
438
+ if (cached) return cached;
439
+ const debouncedFn = lodashEs.debounce(() => {
440
+ executeAutoSaveRef.current?.();
441
+ }, ms);
442
+ const fn = Object.assign(debouncedFn, {
443
+ pending: () => false
444
+ // lodash debounce tracks pending internally
445
+ });
446
+ fieldDebouncersRef.current.set(ms, fn);
447
+ return fn;
448
+ },
449
+ []
450
+ );
451
+ getOrCreateDebouncedRef.current = getOrCreateDebounced;
434
452
  react.useEffect(() => {
453
+ return () => {
454
+ fieldDebouncersRef.current.forEach((fn) => fn.cancel());
455
+ fieldDebouncersRef.current.clear();
456
+ };
457
+ }, [getOrCreateDebounced]);
458
+ const debouncedSubmit = react.useMemo(() => {
435
459
  if (debounceMs === false) {
436
- const immediateFn = Object.assign(
460
+ return Object.assign(
437
461
  () => {
438
- executeAutoSave();
462
+ executeAutoSaveRef.current?.();
439
463
  },
440
464
  {
441
465
  cancel: () => {
442
466
  },
443
467
  // No-op for immediate function
444
- flush: () => executeAutoSave(),
468
+ flush: () => executeAutoSaveRef.current?.(),
445
469
  // Execute immediately on flush
446
470
  pending: () => false
447
471
  // Never pending when immediate
448
472
  }
449
473
  );
450
- debouncedSubmitRef.current = immediateFn;
451
- return () => {
452
- };
453
474
  }
454
475
  const debouncedFn = lodashEs.debounce(() => {
455
- executeAutoSave();
476
+ executeAutoSaveRef.current?.();
456
477
  }, debounceMs);
457
- const fn = Object.assign(debouncedFn, {
478
+ return Object.assign(debouncedFn, {
458
479
  pending: () => false
459
480
  // lodash debounce handles this internally
460
481
  });
461
- debouncedSubmitRef.current = fn;
482
+ }, [debounceMs]);
483
+ debouncedSubmitRef.current = debouncedSubmit;
484
+ react.useEffect(() => {
462
485
  return () => {
463
- debouncedFn.cancel();
486
+ debouncedSubmit.cancel();
464
487
  };
465
- }, [executeAutoSave, debounceMs]);
488
+ }, [debouncedSubmit]);
466
489
  const submitImmediate = react.useCallback(() => {
467
- if (debouncedSubmitRef.current?.flush) {
468
- debouncedSubmitRef.current.flush();
469
- } else {
470
- executeAutoSave();
471
- }
472
- }, [executeAutoSave]);
490
+ debouncedSubmitRef.current?.flush();
491
+ }, []);
473
492
  const unusedFields = react.useMemo(() => {
474
493
  const allFields = Object.keys(config);
475
494
  return allFields.filter((name) => !registeredFields.has(name));
@@ -508,7 +527,7 @@ function Form({
508
527
  setFieldValidating,
509
528
  getFormState,
510
529
  onSubmit,
511
- debouncedSubmit: debouncedSubmitRef.current,
530
+ debouncedSubmit,
512
531
  submitImmediate,
513
532
  unusedFields,
514
533
  methods
@@ -527,6 +546,7 @@ function Form({
527
546
  setFieldValidating,
528
547
  getFormState,
529
548
  onSubmit,
549
+ debouncedSubmit,
530
550
  submitImmediate,
531
551
  unusedFields,
532
552
  methods