@formality-ui/react 0.2.5 → 0.3.1

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
@@ -162,12 +162,25 @@ function Form({
162
162
  return result;
163
163
  }, [providerConfig.inputs, formConfig.inputs]);
164
164
  const defaultValues = useMemo(() => {
165
- return resolveAllInitialValues(config, mergedInputs, record ?? {});
165
+ const resolved = resolveAllInitialValues(
166
+ config,
167
+ mergedInputs,
168
+ record ?? {}
169
+ );
170
+ const baseline = {
171
+ ...record ?? {},
172
+ ...resolved
173
+ };
174
+ for (const fieldName of Object.keys(config)) {
175
+ if (!(fieldName in baseline)) baseline[fieldName] = void 0;
176
+ }
177
+ return baseline;
166
178
  }, [config, mergedInputs, record]);
167
179
  const methods = useForm({
168
180
  mode: mode ?? "onChange",
169
181
  defaultValues,
170
- values: record
182
+ values: defaultValues
183
+ // was: `record as any` — see baseline comment above
171
184
  });
172
185
  const fieldRegistry = useRef(/* @__PURE__ */ new Set());
173
186
  const [registeredFields, setRegisteredFields] = useState(
@@ -195,11 +208,6 @@ function Form({
195
208
  invertedSubscriptions.current.set(target, /* @__PURE__ */ new Set());
196
209
  }
197
210
  invertedSubscriptions.current.get(target).add(subscriber);
198
- if (process.env.NODE_ENV !== "production") {
199
- console.warn(
200
- `[Formality Subscription] "${subscriber}" added to watch "${target}"`
201
- );
202
- }
203
211
  const setter = watcherSetters.current.get(target);
204
212
  if (setter) {
205
213
  setter((prev) => ({ ...prev, [subscriber]: true }));
@@ -212,20 +220,7 @@ function Form({
212
220
  }, []);
213
221
  const removeSubscription = useCallback(
214
222
  (target, subscriber) => {
215
- const subscribers = invertedSubscriptions.current.get(target);
216
- const subscriptionExists = subscribers?.has(subscriber) ?? false;
217
223
  invertedSubscriptions.current.get(target)?.delete(subscriber);
218
- if (process.env.NODE_ENV !== "production") {
219
- if (subscriptionExists) {
220
- console.warn(
221
- `[Formality Subscription] "${subscriber}" removed from watching "${target}"`
222
- );
223
- } else {
224
- console.warn(
225
- `[Formality Subscription] WARNING: Double-cleanup attempt - "${subscriber}" was not watching "${target}"`
226
- );
227
- }
228
- }
229
224
  const setter = watcherSetters.current.get(target);
230
225
  if (setter) {
231
226
  setter((prev) => {
@@ -333,8 +328,10 @@ function Form({
333
328
  }, [methods, config, record, defaultValues]);
334
329
  const handleSubmit = useCallback(
335
330
  async (values, overrideOnSubmit) => {
336
- for (const [, isValidating] of validatingFields.current) {
337
- if (isValidating) return;
331
+ for (const [fieldName, isValidating] of validatingFields.current) {
332
+ if (!isValidating) continue;
333
+ const subscribers = invertedSubscriptions.current.get(fieldName);
334
+ if (subscribers && subscribers.size > 0) return;
338
335
  }
339
336
  if (validate) {
340
337
  const errors = await validate(values);
@@ -910,20 +907,10 @@ function useSubscriptions(fieldName, subscriptions) {
910
907
  runSubscriptionsRef.current.set(currentRunId, [...subscriptions]);
911
908
  subscriptions.forEach((target) => {
912
909
  addSubscription(target, fieldName);
913
- if (process.env.NODE_ENV !== "production") {
914
- console.warn(
915
- `[Formality Subscription] Run ${currentRunId}: "${fieldName}" subscribing to "${target}"`
916
- );
917
- }
918
910
  });
919
911
  return () => {
920
912
  const thisRunSubscriptions = runSubscriptionsRef.current.get(currentRunId);
921
913
  if (thisRunSubscriptions) {
922
- if (process.env.NODE_ENV !== "production") {
923
- console.warn(
924
- `[Formality Subscription] Run ${currentRunId}: "${fieldName}" cleaning up [${thisRunSubscriptions.join(", ")}]`
925
- );
926
- }
927
914
  [...thisRunSubscriptions].reverse().forEach((target) => {
928
915
  removeSubscription(target, fieldName);
929
916
  });
@@ -932,13 +919,12 @@ function useSubscriptions(fieldName, subscriptions) {
932
919
  };
933
920
  }, [fieldName, subscriptions, addSubscription, removeSubscription]);
934
921
  }
935
- function Field({
922
+ function useField({
936
923
  name,
937
924
  type: typeProp,
938
925
  disabled: disabledProp,
939
926
  hidden: hiddenProp,
940
927
  children,
941
- shouldRegister = true,
942
928
  inputConfig: inputConfigProp,
943
929
  ...restProps
944
930
  }) {
@@ -946,8 +932,6 @@ function Field({
946
932
  config,
947
933
  formConfig,
948
934
  methods,
949
- registerField,
950
- unregisterField,
951
935
  registerWatcherSetter,
952
936
  unregisterWatcherSetter,
953
937
  changeField,
@@ -976,12 +960,6 @@ function Field({
976
960
  };
977
961
  return inputConfigProp ? { ...baseInputConfig, ...inputConfigProp } : baseInputConfig;
978
962
  }, [type, providerConfig.inputs, formConfig.inputs, inputConfigProp]);
979
- useEffect(() => {
980
- if (shouldRegister) {
981
- registerField(name);
982
- return () => unregisterField(name);
983
- }
984
- }, [name, shouldRegister, registerField, unregisterField]);
985
963
  const [watchers, setWatchers] = useState({});
986
964
  useEffect(() => {
987
965
  registerWatcherSetter(name, setWatchers);
@@ -1194,10 +1172,14 @@ function Field({
1194
1172
  inputConfig
1195
1173
  ]
1196
1174
  );
1197
- if (!isVisible) {
1198
- return null;
1199
- }
1200
- return /* @__PURE__ */ jsx(
1175
+ const fieldStateRef = useRef(
1176
+ {}
1177
+ );
1178
+ const formStateRef = useRef(
1179
+ {}
1180
+ );
1181
+ const fieldPropsRef = useRef({});
1182
+ const renderedField = isVisible ? /* @__PURE__ */ jsx(
1201
1183
  Controller,
1202
1184
  {
1203
1185
  control: methods.control,
@@ -1248,13 +1230,16 @@ function Field({
1248
1230
  ...stateInjection
1249
1231
  }
1250
1232
  });
1233
+ fieldStateRef.current = fieldState;
1234
+ formStateRef.current = formState;
1235
+ fieldPropsRef.current = finalProps;
1251
1236
  const Component = inputConfig.component;
1252
1237
  const isHostComponent = typeof inputConfig.component === "string";
1253
1238
  const template = inputConfig.template ?? providerConfig.inputTemplates[type] ?? providerConfig.defaultInputTemplate;
1254
1239
  const TemplateComponent = template;
1255
- let renderedField;
1240
+ let renderedFieldEl;
1256
1241
  if (TemplateComponent) {
1257
- renderedField = /* @__PURE__ */ jsx(
1242
+ renderedFieldEl = /* @__PURE__ */ jsx(
1258
1243
  TemplateComponent,
1259
1244
  {
1260
1245
  Field: Component,
@@ -1277,27 +1262,64 @@ function Field({
1277
1262
  strippedHostProps[key] = value;
1278
1263
  }
1279
1264
  }
1280
- renderedField = createElement(inputConfig.component, {
1265
+ renderedFieldEl = createElement(inputConfig.component, {
1281
1266
  ...strippedHostProps,
1282
1267
  ref: finalProps.forwardRef
1283
1268
  });
1284
1269
  } else {
1285
- renderedField = /* @__PURE__ */ jsx(Component, { ...finalProps });
1270
+ renderedFieldEl = /* @__PURE__ */ jsx(Component, { ...finalProps });
1286
1271
  }
1287
1272
  if (typeof children === "function") {
1288
1273
  const result = children({
1289
1274
  fieldState,
1290
- renderedField,
1275
+ renderedField: renderedFieldEl,
1291
1276
  fieldProps: finalProps,
1292
1277
  watchers,
1293
1278
  formState
1294
1279
  });
1295
1280
  return /* @__PURE__ */ jsx(Fragment, { children: result });
1296
1281
  }
1297
- return renderedField;
1282
+ return renderedFieldEl;
1298
1283
  }
1299
1284
  }
1300
- );
1285
+ ) : null;
1286
+ return {
1287
+ fieldState: fieldStateRef.current,
1288
+ renderedField,
1289
+ fieldProps: fieldPropsRef.current,
1290
+ watchers,
1291
+ formState: formStateRef.current
1292
+ };
1293
+ }
1294
+
1295
+ // src/components/Field.tsx
1296
+ function Field({
1297
+ name,
1298
+ type: typeProp,
1299
+ disabled: disabledProp,
1300
+ hidden: hiddenProp,
1301
+ children,
1302
+ shouldRegister = true,
1303
+ inputConfig: inputConfigProp,
1304
+ ...restProps
1305
+ }) {
1306
+ const { registerField, unregisterField } = useFormContext();
1307
+ useEffect(() => {
1308
+ if (shouldRegister) {
1309
+ registerField(name);
1310
+ return () => unregisterField(name);
1311
+ }
1312
+ }, [name, shouldRegister, registerField, unregisterField]);
1313
+ const { renderedField } = useField({
1314
+ name,
1315
+ type: typeProp,
1316
+ disabled: disabledProp,
1317
+ hidden: hiddenProp,
1318
+ children,
1319
+ inputConfig: inputConfigProp,
1320
+ ...restProps
1321
+ });
1322
+ return renderedField;
1301
1323
  }
1302
1324
  function FieldGroup({ name, children }) {
1303
1325
  const { formConfig } = useFormContext();
@@ -1441,6 +1463,6 @@ function defineInputs(inputs) {
1441
1463
  return inputs;
1442
1464
  }
1443
1465
 
1444
- export { ConfigContext, Field, FieldGroup, Form, FormContext, FormalityProvider, GroupContext, UnusedFields, defineInputs, makeDeepProxyState, makeProxyState, useConditions, useConfigContext, useFormContext, useFormState, useGroupContext, useInferredInputs, usePropsEvaluation, useSubscriptions };
1466
+ export { ConfigContext, Field, FieldGroup, Form, FormContext, FormalityProvider, GroupContext, UnusedFields, defineInputs, makeDeepProxyState, makeProxyState, useConditions, useConfigContext, useField, useFormContext, useFormState, useGroupContext, useInferredInputs, usePropsEvaluation, useSubscriptions };
1445
1467
  //# sourceMappingURL=index.js.map
1446
1468
  //# sourceMappingURL=index.js.map