@formality-ui/react 0.2.0 → 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 +76 -43
- 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 +77 -44
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
-
|
|
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
|
-
|
|
460
|
+
return Object.assign(
|
|
437
461
|
() => {
|
|
438
|
-
|
|
462
|
+
executeAutoSaveRef.current?.();
|
|
439
463
|
},
|
|
440
464
|
{
|
|
441
465
|
cancel: () => {
|
|
442
466
|
},
|
|
443
467
|
// No-op for immediate function
|
|
444
|
-
flush: () =>
|
|
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
|
-
|
|
476
|
+
executeAutoSaveRef.current?.();
|
|
456
477
|
}, debounceMs);
|
|
457
|
-
|
|
478
|
+
return Object.assign(debouncedFn, {
|
|
458
479
|
pending: () => false
|
|
459
480
|
// lodash debounce handles this internally
|
|
460
481
|
});
|
|
461
|
-
|
|
482
|
+
}, [debounceMs]);
|
|
483
|
+
debouncedSubmitRef.current = debouncedSubmit;
|
|
484
|
+
react.useEffect(() => {
|
|
462
485
|
return () => {
|
|
463
|
-
|
|
486
|
+
debouncedSubmit.cancel();
|
|
464
487
|
};
|
|
465
|
-
}, [
|
|
488
|
+
}, [debouncedSubmit]);
|
|
466
489
|
const submitImmediate = react.useCallback(() => {
|
|
467
|
-
|
|
468
|
-
|
|
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
|
|
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
|
|
@@ -562,11 +582,18 @@ function useInferredInputs(options) {
|
|
|
562
582
|
selectProps,
|
|
563
583
|
formDefaultFieldProps,
|
|
564
584
|
providerDefaultFieldProps,
|
|
565
|
-
conditions
|
|
566
|
-
subscribesTo
|
|
585
|
+
conditions,
|
|
586
|
+
subscribesTo
|
|
567
587
|
} = options;
|
|
588
|
+
const signature = JSON.stringify({
|
|
589
|
+
selectProps,
|
|
590
|
+
formDefaultFieldProps,
|
|
591
|
+
providerDefaultFieldProps,
|
|
592
|
+
conditions,
|
|
593
|
+
subscribesTo
|
|
594
|
+
});
|
|
568
595
|
return react.useMemo(() => {
|
|
569
|
-
const inferred = [...subscribesTo];
|
|
596
|
+
const inferred = [...subscribesTo ?? []];
|
|
570
597
|
if (providerDefaultFieldProps) {
|
|
571
598
|
inferred.push(...core.inferFieldsFromDescriptor(providerDefaultFieldProps));
|
|
572
599
|
}
|
|
@@ -576,17 +603,11 @@ function useInferredInputs(options) {
|
|
|
576
603
|
if (selectProps) {
|
|
577
604
|
inferred.push(...core.inferFieldsFromDescriptor(selectProps));
|
|
578
605
|
}
|
|
579
|
-
if (conditions.length > 0) {
|
|
606
|
+
if (conditions && conditions.length > 0) {
|
|
580
607
|
inferred.push(...core.inferFieldsFromConditions(conditions));
|
|
581
608
|
}
|
|
582
609
|
return [...new Set(inferred)];
|
|
583
|
-
}, [
|
|
584
|
-
providerDefaultFieldProps,
|
|
585
|
-
formDefaultFieldProps,
|
|
586
|
-
selectProps,
|
|
587
|
-
conditions,
|
|
588
|
-
subscribesTo
|
|
589
|
-
]);
|
|
610
|
+
}, [signature]);
|
|
590
611
|
}
|
|
591
612
|
|
|
592
613
|
// src/hooks/useConditions.ts
|
|
@@ -1121,17 +1142,29 @@ function Field({
|
|
|
1121
1142
|
}
|
|
1122
1143
|
});
|
|
1123
1144
|
const Component = inputConfig.component;
|
|
1145
|
+
const isHostComponent = typeof inputConfig.component === "string";
|
|
1124
1146
|
const template = inputConfig.template ?? providerConfig.inputTemplates[type] ?? providerConfig.defaultInputTemplate;
|
|
1125
1147
|
const TemplateComponent = template;
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1148
|
+
let renderedField;
|
|
1149
|
+
if (TemplateComponent) {
|
|
1150
|
+
renderedField = /* @__PURE__ */ jsxRuntime.jsx(
|
|
1151
|
+
TemplateComponent,
|
|
1152
|
+
{
|
|
1153
|
+
Field: Component,
|
|
1154
|
+
fieldProps: finalProps,
|
|
1155
|
+
fieldState,
|
|
1156
|
+
formState
|
|
1157
|
+
}
|
|
1158
|
+
);
|
|
1159
|
+
} else if (isHostComponent) {
|
|
1160
|
+
const { forwardRef: hostRef, ...restHostProps } = finalProps;
|
|
1161
|
+
renderedField = react.createElement(inputConfig.component, {
|
|
1162
|
+
...restHostProps,
|
|
1163
|
+
ref: hostRef
|
|
1164
|
+
});
|
|
1165
|
+
} else {
|
|
1166
|
+
renderedField = /* @__PURE__ */ jsxRuntime.jsx(Component, { ...finalProps });
|
|
1167
|
+
}
|
|
1135
1168
|
if (typeof children === "function") {
|
|
1136
1169
|
const result = children({
|
|
1137
1170
|
fieldState,
|