@formality-ui/react 0.2.3 → 0.2.5

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
@@ -149,6 +149,7 @@ function Form({
149
149
  record,
150
150
  autoSave = false,
151
151
  debounce: debounceMs = 1e3,
152
+ mode,
152
153
  validate
153
154
  }) {
154
155
  const providerConfig = useConfigContext();
@@ -166,7 +167,7 @@ function Form({
166
167
  return core.resolveAllInitialValues(config, mergedInputs, record ?? {});
167
168
  }, [config, mergedInputs, record]);
168
169
  const methods = reactHookForm.useForm({
169
- mode: "onChange",
170
+ mode: mode ?? "onChange",
170
171
  defaultValues,
171
172
  values: record
172
173
  });
@@ -406,9 +407,20 @@ function Form({
406
407
  if (!validationsComplete || executionVersionRef.current !== executionVersion) {
407
408
  return;
408
409
  }
409
- for (const fieldName of changedFields) {
410
- const fieldState = methods.getFieldState(fieldName);
411
- if (fieldState.error) {
410
+ const changedArray = [...changedFields];
411
+ if (changedArray.length > 0) {
412
+ const changedValid = await methods.trigger(changedArray);
413
+ if (executionVersionRef.current !== executionVersion) {
414
+ return;
415
+ }
416
+ if (!changedValid) {
417
+ return;
418
+ }
419
+ const changedValidationsComplete = await waitForFieldValidation(
420
+ changedArray,
421
+ executionVersion
422
+ );
423
+ if (!changedValidationsComplete || executionVersionRef.current !== executionVersion) {
412
424
  return;
413
425
  }
414
426
  }
@@ -1088,6 +1100,40 @@ function Field({
1088
1100
  const label = react.useMemo(() => {
1089
1101
  return core.resolveLabel(name, fieldConfig, fieldSelectProps, restProps);
1090
1102
  }, [name, fieldConfig, fieldSelectProps, restProps]);
1103
+ const passSubscriptionsEnabled = fieldConfig.passSubscriptions === true;
1104
+ const provideStateEnabled = fieldConfig.provideState === true;
1105
+ const subscribedWatchNames = react.useMemo(
1106
+ () => passSubscriptionsEnabled && allSubscriptions.length > 0 ? allSubscriptions : [],
1107
+ [passSubscriptionsEnabled, allSubscriptions]
1108
+ );
1109
+ const subscribedValues = reactHookForm.useWatch({
1110
+ control: methods.control,
1111
+ name: subscribedWatchNames.length > 0 ? subscribedWatchNames : []
1112
+ });
1113
+ const subscribedState = react.useMemo(() => {
1114
+ if (!passSubscriptionsEnabled || subscribedWatchNames.length === 0) {
1115
+ return void 0;
1116
+ }
1117
+ const result = {};
1118
+ const values = Array.isArray(subscribedValues) ? subscribedValues : [subscribedValues];
1119
+ subscribedWatchNames.forEach((fieldName, i) => {
1120
+ const fs = methods.getFieldState(fieldName);
1121
+ result[fieldName] = makeProxyState({
1122
+ value: values[i],
1123
+ isTouched: fs.isTouched,
1124
+ isDirty: fs.isDirty,
1125
+ isValidating: fs.isValidating,
1126
+ error: fs.error,
1127
+ invalid: fs.invalid
1128
+ });
1129
+ });
1130
+ return result;
1131
+ }, [
1132
+ passSubscriptionsEnabled,
1133
+ subscribedWatchNames,
1134
+ subscribedValues,
1135
+ methods
1136
+ ]);
1091
1137
  const validationRules = react.useMemo(() => {
1092
1138
  return {
1093
1139
  ...fieldConfig.rules,
@@ -1165,6 +1211,24 @@ function Field({
1165
1211
  inputConfig.formatter,
1166
1212
  providerConfig.formatters
1167
1213
  );
1214
+ const stateInjection = {};
1215
+ if (provideStateEnabled) {
1216
+ stateInjection[providerConfig.defaultSubscriptionPropName] = makeProxyState({
1217
+ value: field.value,
1218
+ isTouched: fieldState.isTouched,
1219
+ isDirty: fieldState.isDirty,
1220
+ isValidating: fieldState.isValidating,
1221
+ error: fieldState.error,
1222
+ invalid: fieldState.invalid
1223
+ });
1224
+ }
1225
+ if (passSubscriptionsEnabled && subscribedState) {
1226
+ const subsPropName = fieldConfig.passSubscriptionsAs ?? providerConfig.defaultSubscriptionPropName;
1227
+ stateInjection[subsPropName] = subscribedState;
1228
+ }
1229
+ if (provideStateEnabled || passSubscriptionsEnabled) {
1230
+ stateInjection.formState = formState;
1231
+ }
1168
1232
  const finalProps = core.mergeFieldProps({
1169
1233
  providerDefaultFieldProps: providerConfig.defaultFieldProps,
1170
1234
  providerSelectDefaultFieldProps: providerSelectProps,
@@ -1182,7 +1246,8 @@ function Field({
1182
1246
  [inputConfig.inputFieldProp ?? "value"]: formattedValue,
1183
1247
  onChange: handleChange(field.onChange),
1184
1248
  onBlur: field.onBlur,
1185
- forwardRef: field.ref
1249
+ forwardRef: field.ref,
1250
+ ...stateInjection
1186
1251
  }
1187
1252
  });
1188
1253
  const Component = inputConfig.component;
@@ -1201,10 +1266,22 @@ function Field({
1201
1266
  }
1202
1267
  );
1203
1268
  } else if (isHostComponent) {
1204
- const { forwardRef: hostRef, ...restHostProps } = finalProps;
1269
+ const subsPropName = fieldConfig.passSubscriptionsAs ?? providerConfig.defaultSubscriptionPropName;
1270
+ const strippedHostProps = {};
1271
+ const nonDomKeys = /* @__PURE__ */ new Set([
1272
+ "forwardRef",
1273
+ "formState",
1274
+ "state",
1275
+ subsPropName
1276
+ ]);
1277
+ for (const [key, value] of Object.entries(finalProps)) {
1278
+ if (!nonDomKeys.has(key)) {
1279
+ strippedHostProps[key] = value;
1280
+ }
1281
+ }
1205
1282
  renderedField = react.createElement(inputConfig.component, {
1206
- ...restHostProps,
1207
- ref: hostRef
1283
+ ...strippedHostProps,
1284
+ ref: finalProps.forwardRef
1208
1285
  });
1209
1286
  } else {
1210
1287
  renderedField = /* @__PURE__ */ jsxRuntime.jsx(Component, { ...finalProps });