@formality-ui/react 0.2.4 → 0.3.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/dist/index.js CHANGED
@@ -147,6 +147,7 @@ function Form({
147
147
  record,
148
148
  autoSave = false,
149
149
  debounce: debounceMs = 1e3,
150
+ mode,
150
151
  validate
151
152
  }) {
152
153
  const providerConfig = useConfigContext();
@@ -161,12 +162,18 @@ function Form({
161
162
  return result;
162
163
  }, [providerConfig.inputs, formConfig.inputs]);
163
164
  const defaultValues = useMemo(() => {
164
- return resolveAllInitialValues(config, mergedInputs, record ?? {});
165
+ const resolved = resolveAllInitialValues(config, mergedInputs, record ?? {});
166
+ const baseline = { ...record ?? {}, ...resolved };
167
+ for (const fieldName of Object.keys(config)) {
168
+ if (!(fieldName in baseline)) baseline[fieldName] = void 0;
169
+ }
170
+ return baseline;
165
171
  }, [config, mergedInputs, record]);
166
172
  const methods = useForm({
167
- mode: "onChange",
173
+ mode: mode ?? "onChange",
168
174
  defaultValues,
169
- values: record
175
+ values: defaultValues
176
+ // was: `record as any` — see baseline comment above
170
177
  });
171
178
  const fieldRegistry = useRef(/* @__PURE__ */ new Set());
172
179
  const [registeredFields, setRegisteredFields] = useState(
@@ -332,8 +339,10 @@ function Form({
332
339
  }, [methods, config, record, defaultValues]);
333
340
  const handleSubmit = useCallback(
334
341
  async (values, overrideOnSubmit) => {
335
- for (const [, isValidating] of validatingFields.current) {
336
- if (isValidating) return;
342
+ for (const [fieldName, isValidating] of validatingFields.current) {
343
+ if (!isValidating) continue;
344
+ const subscribers = invertedSubscriptions.current.get(fieldName);
345
+ if (subscribers && subscribers.size > 0) return;
337
346
  }
338
347
  if (validate) {
339
348
  const errors = await validate(values);
@@ -404,9 +413,20 @@ function Form({
404
413
  if (!validationsComplete || executionVersionRef.current !== executionVersion) {
405
414
  return;
406
415
  }
407
- for (const fieldName of changedFields) {
408
- const fieldState = methods.getFieldState(fieldName);
409
- if (fieldState.error) {
416
+ const changedArray = [...changedFields];
417
+ if (changedArray.length > 0) {
418
+ const changedValid = await methods.trigger(changedArray);
419
+ if (executionVersionRef.current !== executionVersion) {
420
+ return;
421
+ }
422
+ if (!changedValid) {
423
+ return;
424
+ }
425
+ const changedValidationsComplete = await waitForFieldValidation(
426
+ changedArray,
427
+ executionVersion
428
+ );
429
+ if (!changedValidationsComplete || executionVersionRef.current !== executionVersion) {
410
430
  return;
411
431
  }
412
432
  }
@@ -920,13 +940,12 @@ function useSubscriptions(fieldName, subscriptions) {
920
940
  };
921
941
  }, [fieldName, subscriptions, addSubscription, removeSubscription]);
922
942
  }
923
- function Field({
943
+ function useField({
924
944
  name,
925
945
  type: typeProp,
926
946
  disabled: disabledProp,
927
947
  hidden: hiddenProp,
928
948
  children,
929
- shouldRegister = true,
930
949
  inputConfig: inputConfigProp,
931
950
  ...restProps
932
951
  }) {
@@ -934,8 +953,6 @@ function Field({
934
953
  config,
935
954
  formConfig,
936
955
  methods,
937
- registerField,
938
- unregisterField,
939
956
  registerWatcherSetter,
940
957
  unregisterWatcherSetter,
941
958
  changeField,
@@ -964,12 +981,6 @@ function Field({
964
981
  };
965
982
  return inputConfigProp ? { ...baseInputConfig, ...inputConfigProp } : baseInputConfig;
966
983
  }, [type, providerConfig.inputs, formConfig.inputs, inputConfigProp]);
967
- useEffect(() => {
968
- if (shouldRegister) {
969
- registerField(name);
970
- return () => unregisterField(name);
971
- }
972
- }, [name, shouldRegister, registerField, unregisterField]);
973
984
  const [watchers, setWatchers] = useState({});
974
985
  useEffect(() => {
975
986
  registerWatcherSetter(name, setWatchers);
@@ -1182,10 +1193,14 @@ function Field({
1182
1193
  inputConfig
1183
1194
  ]
1184
1195
  );
1185
- if (!isVisible) {
1186
- return null;
1187
- }
1188
- return /* @__PURE__ */ jsx(
1196
+ const fieldStateRef = useRef(
1197
+ {}
1198
+ );
1199
+ const formStateRef = useRef(
1200
+ {}
1201
+ );
1202
+ const fieldPropsRef = useRef({});
1203
+ const renderedField = isVisible ? /* @__PURE__ */ jsx(
1189
1204
  Controller,
1190
1205
  {
1191
1206
  control: methods.control,
@@ -1236,13 +1251,16 @@ function Field({
1236
1251
  ...stateInjection
1237
1252
  }
1238
1253
  });
1254
+ fieldStateRef.current = fieldState;
1255
+ formStateRef.current = formState;
1256
+ fieldPropsRef.current = finalProps;
1239
1257
  const Component = inputConfig.component;
1240
1258
  const isHostComponent = typeof inputConfig.component === "string";
1241
1259
  const template = inputConfig.template ?? providerConfig.inputTemplates[type] ?? providerConfig.defaultInputTemplate;
1242
1260
  const TemplateComponent = template;
1243
- let renderedField;
1261
+ let renderedFieldEl;
1244
1262
  if (TemplateComponent) {
1245
- renderedField = /* @__PURE__ */ jsx(
1263
+ renderedFieldEl = /* @__PURE__ */ jsx(
1246
1264
  TemplateComponent,
1247
1265
  {
1248
1266
  Field: Component,
@@ -1265,27 +1283,64 @@ function Field({
1265
1283
  strippedHostProps[key] = value;
1266
1284
  }
1267
1285
  }
1268
- renderedField = createElement(inputConfig.component, {
1286
+ renderedFieldEl = createElement(inputConfig.component, {
1269
1287
  ...strippedHostProps,
1270
1288
  ref: finalProps.forwardRef
1271
1289
  });
1272
1290
  } else {
1273
- renderedField = /* @__PURE__ */ jsx(Component, { ...finalProps });
1291
+ renderedFieldEl = /* @__PURE__ */ jsx(Component, { ...finalProps });
1274
1292
  }
1275
1293
  if (typeof children === "function") {
1276
1294
  const result = children({
1277
1295
  fieldState,
1278
- renderedField,
1296
+ renderedField: renderedFieldEl,
1279
1297
  fieldProps: finalProps,
1280
1298
  watchers,
1281
1299
  formState
1282
1300
  });
1283
1301
  return /* @__PURE__ */ jsx(Fragment, { children: result });
1284
1302
  }
1285
- return renderedField;
1303
+ return renderedFieldEl;
1286
1304
  }
1287
1305
  }
1288
- );
1306
+ ) : null;
1307
+ return {
1308
+ fieldState: fieldStateRef.current,
1309
+ renderedField,
1310
+ fieldProps: fieldPropsRef.current,
1311
+ watchers,
1312
+ formState: formStateRef.current
1313
+ };
1314
+ }
1315
+
1316
+ // src/components/Field.tsx
1317
+ function Field({
1318
+ name,
1319
+ type: typeProp,
1320
+ disabled: disabledProp,
1321
+ hidden: hiddenProp,
1322
+ children,
1323
+ shouldRegister = true,
1324
+ inputConfig: inputConfigProp,
1325
+ ...restProps
1326
+ }) {
1327
+ const { registerField, unregisterField } = useFormContext();
1328
+ useEffect(() => {
1329
+ if (shouldRegister) {
1330
+ registerField(name);
1331
+ return () => unregisterField(name);
1332
+ }
1333
+ }, [name, shouldRegister, registerField, unregisterField]);
1334
+ const { renderedField } = useField({
1335
+ name,
1336
+ type: typeProp,
1337
+ disabled: disabledProp,
1338
+ hidden: hiddenProp,
1339
+ children,
1340
+ inputConfig: inputConfigProp,
1341
+ ...restProps
1342
+ });
1343
+ return renderedField;
1289
1344
  }
1290
1345
  function FieldGroup({ name, children }) {
1291
1346
  const { formConfig } = useFormContext();
@@ -1429,6 +1484,6 @@ function defineInputs(inputs) {
1429
1484
  return inputs;
1430
1485
  }
1431
1486
 
1432
- export { ConfigContext, Field, FieldGroup, Form, FormContext, FormalityProvider, GroupContext, UnusedFields, defineInputs, makeDeepProxyState, makeProxyState, useConditions, useConfigContext, useFormContext, useFormState, useGroupContext, useInferredInputs, usePropsEvaluation, useSubscriptions };
1487
+ export { ConfigContext, Field, FieldGroup, Form, FormContext, FormalityProvider, GroupContext, UnusedFields, defineInputs, makeDeepProxyState, makeProxyState, useConditions, useConfigContext, useField, useFormContext, useFormState, useGroupContext, useInferredInputs, usePropsEvaluation, useSubscriptions };
1433
1488
  //# sourceMappingURL=index.js.map
1434
1489
  //# sourceMappingURL=index.js.map