@formality-ui/react 0.3.1 → 0.4.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.d.cts CHANGED
@@ -133,6 +133,15 @@ interface ReactInputConfig<TValue = unknown> extends Omit<InputConfig<TValue>, "
133
133
  *
134
134
  * The generic `V` defaults to `FieldValues`; pass your form's values type for
135
135
  * slightly tighter checking on path-based rules.
136
+ *
137
+ * The §6.4 field-level override fields (`defaultValue`, `debounce`,
138
+ * `parser`, `formatter`, `valueField`, `getSubmitField`) are inherited
139
+ * from core `FieldConfig` unchanged. They override their `InputConfig`
140
+ * counterparts when `!== undefined`, using the single
141
+ * `resolveFieldOverType` rule (§6.4.0). The field-level
142
+ * `parser`/`formatter` stay `string | ((value: unknown) => unknown)` —
143
+ * NOT generified over `TValue` (per-field `TValue` is a future
144
+ * enhancement, §3.2.1).
136
145
  */
137
146
  interface ReactFieldConfig<V extends FieldValues = FieldValues> extends Omit<FieldConfig, "rules"> {
138
147
  /** react-hook-form register options forwarded to the field's Controller. */
package/dist/index.d.ts CHANGED
@@ -133,6 +133,15 @@ interface ReactInputConfig<TValue = unknown> extends Omit<InputConfig<TValue>, "
133
133
  *
134
134
  * The generic `V` defaults to `FieldValues`; pass your form's values type for
135
135
  * slightly tighter checking on path-based rules.
136
+ *
137
+ * The §6.4 field-level override fields (`defaultValue`, `debounce`,
138
+ * `parser`, `formatter`, `valueField`, `getSubmitField`) are inherited
139
+ * from core `FieldConfig` unchanged. They override their `InputConfig`
140
+ * counterparts when `!== undefined`, using the single
141
+ * `resolveFieldOverType` rule (§6.4.0). The field-level
142
+ * `parser`/`formatter` stay `string | ((value: unknown) => unknown)` —
143
+ * NOT generified over `TValue` (per-field `TValue` is a future
144
+ * enhancement, §3.2.1).
136
145
  */
137
146
  interface ReactFieldConfig<V extends FieldValues = FieldValues> extends Omit<FieldConfig, "rules"> {
138
147
  /** react-hook-form register options forwarded to the field's Controller. */
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { createContext, useContext, useMemo, useRef, useState, useCallback, useE
2
2
  import { jsx, Fragment } from 'react/jsx-runtime';
3
3
  import { useForm, FormProvider, useWatch, Controller, useFormContext as useFormContext$1 } from 'react-hook-form';
4
4
  import { debounce } from 'lodash-es';
5
- import { resolveAllInitialValues, buildFormContext, evaluateDescriptor, resolveFormTitle, transformFieldName, extractValueField, inferFieldsFromDescriptor, inferFieldsFromConditions, evaluateConditions, buildFieldContext, resolveInputConfig, resolveLabel, runValidator, resolveErrorMessage, parse, format, mergeFieldProps, sortFieldsByOrder } from '@formality-ui/core';
5
+ import { resolveAllInitialValues, resolveFieldOverType, buildFormContext, evaluateDescriptor, resolveFormTitle, transformFieldName, extractValueField, inferFieldsFromDescriptor, inferFieldsFromConditions, evaluateConditions, buildFieldContext, resolveInputConfig, resolveLabel, runValidator, resolveErrorMessage, parse, format, mergeFieldProps, sortFieldsByOrder } from '@formality-ui/core';
6
6
 
7
7
  // src/context/ConfigContext.ts
8
8
  var defaultConfigContext = {
@@ -277,7 +277,11 @@ function Form({
277
277
  for (const field of affected) {
278
278
  pendingAffectedFields.current.add(field);
279
279
  }
280
- const fieldDebounce = inputConfig?.debounce;
280
+ const fieldConfig = config[name];
281
+ const fieldDebounce = resolveFieldOverType(
282
+ fieldConfig?.debounce,
283
+ inputConfig?.debounce
284
+ );
281
285
  if (fieldDebounce === false) {
282
286
  executeAutoSaveRef.current?.();
283
287
  } else if (typeof fieldDebounce === "number") {
@@ -287,7 +291,7 @@ function Form({
287
291
  }
288
292
  }
289
293
  },
290
- [autoSave, getAffectedFields]
294
+ [autoSave, getAffectedFields, config]
291
295
  );
292
296
  const setFieldValidating = useCallback(
293
297
  (name, isValidating) => {
@@ -591,13 +595,17 @@ function transformValuesForSubmit(values, config, inputs) {
591
595
  const fieldConfig = config[name];
592
596
  const type = fieldConfig?.type ?? "textField";
593
597
  const inputConfig = inputs[type];
594
- if (inputConfig) {
595
- const submitName = transformFieldName(name, inputConfig.getSubmitField);
596
- const submitValue = extractValueField(value, inputConfig.valueField);
597
- result[submitName] = submitValue;
598
- } else {
599
- result[name] = value;
600
- }
598
+ const effectiveGetSubmitField = resolveFieldOverType(
599
+ fieldConfig?.getSubmitField,
600
+ inputConfig?.getSubmitField
601
+ );
602
+ const effectiveValueField = resolveFieldOverType(
603
+ fieldConfig?.valueField,
604
+ inputConfig?.valueField
605
+ );
606
+ const submitName = transformFieldName(name, effectiveGetSubmitField);
607
+ const submitValue = extractValueField(value, effectiveValueField);
608
+ result[submitName] = submitValue;
601
609
  }
602
610
  return result;
603
611
  }
@@ -1074,8 +1082,22 @@ function useField({
1074
1082
  groupContext.state.isVisible
1075
1083
  ]);
1076
1084
  const label = useMemo(() => {
1077
- return resolveLabel(name, fieldConfig, fieldSelectProps, restProps);
1078
- }, [name, fieldConfig, fieldSelectProps, restProps]);
1085
+ return resolveLabel(
1086
+ name,
1087
+ fieldConfig,
1088
+ fieldSelectProps,
1089
+ restProps,
1090
+ providerSelectProps,
1091
+ formSelectProps
1092
+ );
1093
+ }, [
1094
+ name,
1095
+ fieldConfig,
1096
+ fieldSelectProps,
1097
+ restProps,
1098
+ providerSelectProps,
1099
+ formSelectProps
1100
+ ]);
1079
1101
  const passSubscriptionsEnabled = fieldConfig.passSubscriptions === true;
1080
1102
  const provideStateEnabled = fieldConfig.provideState === true;
1081
1103
  const subscribedWatchNames = useMemo(
@@ -1154,23 +1176,25 @@ function useField({
1154
1176
  name,
1155
1177
  setFieldValidating
1156
1178
  ]);
1179
+ const effectiveParser = useMemo(
1180
+ () => resolveFieldOverType(fieldConfig.parser, inputConfig.parser),
1181
+ [fieldConfig.parser, inputConfig.parser]
1182
+ );
1183
+ const effectiveFormatter = useMemo(
1184
+ () => resolveFieldOverType(fieldConfig.formatter, inputConfig.formatter),
1185
+ [fieldConfig.formatter, inputConfig.formatter]
1186
+ );
1157
1187
  const handleChange = useCallback(
1158
1188
  (onChange) => (newValue) => {
1159
1189
  const parsedValue = parse(
1160
1190
  newValue,
1161
- inputConfig.parser,
1191
+ effectiveParser,
1162
1192
  providerConfig.parsers
1163
1193
  );
1164
1194
  onChange(parsedValue);
1165
1195
  changeField(name, parsedValue, inputConfig);
1166
1196
  },
1167
- [
1168
- inputConfig.parser,
1169
- providerConfig.parsers,
1170
- changeField,
1171
- name,
1172
- inputConfig
1173
- ]
1197
+ [effectiveParser, providerConfig.parsers, changeField, name, inputConfig]
1174
1198
  );
1175
1199
  const fieldStateRef = useRef(
1176
1200
  {}
@@ -1188,7 +1212,7 @@ function useField({
1188
1212
  render: ({ field, fieldState, formState }) => {
1189
1213
  const formattedValue = format(
1190
1214
  field.value,
1191
- inputConfig.formatter,
1215
+ effectiveFormatter,
1192
1216
  providerConfig.formatters
1193
1217
  );
1194
1218
  const stateInjection = {};