remix-validated-form 4.5.4 → 4.6.0-beta.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.
Files changed (33) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/browser/ValidatedForm.js +0 -3
  3. package/browser/index.d.ts +1 -0
  4. package/browser/index.js +1 -0
  5. package/browser/internal/hooks.d.ts +1 -0
  6. package/browser/internal/hooks.js +3 -4
  7. package/browser/internal/state/controlledFields.d.ts +1 -0
  8. package/browser/internal/state/controlledFields.js +17 -29
  9. package/browser/internal/state/createFormStore.d.ts +31 -1
  10. package/browser/internal/state/createFormStore.js +175 -8
  11. package/dist/remix-validated-form.cjs.js +4 -4
  12. package/dist/remix-validated-form.cjs.js.map +1 -1
  13. package/dist/remix-validated-form.es.js +336 -126
  14. package/dist/remix-validated-form.es.js.map +1 -1
  15. package/dist/remix-validated-form.umd.js +4 -4
  16. package/dist/remix-validated-form.umd.js.map +1 -1
  17. package/dist/types/index.d.ts +1 -0
  18. package/dist/types/internal/hooks.d.ts +1 -0
  19. package/dist/types/internal/state/arrayUtil.d.ts +12 -0
  20. package/dist/types/internal/state/controlledFields.d.ts +1 -0
  21. package/dist/types/internal/state/createFormStore.d.ts +31 -1
  22. package/dist/types/internal/state/fieldArray.d.ts +28 -0
  23. package/package.json +1 -1
  24. package/src/ValidatedForm.tsx +0 -3
  25. package/src/index.ts +6 -0
  26. package/src/internal/hooks.ts +9 -4
  27. package/src/internal/logic/nestedObjectToPathObject.ts +63 -0
  28. package/src/internal/state/arrayUtil.ts +399 -0
  29. package/src/internal/state/controlledFields.ts +39 -43
  30. package/src/internal/state/createFormStore.ts +286 -10
  31. package/src/internal/state/fieldArray.tsx +155 -0
  32. package/dist/types/internal/state/controlledFieldStore.d.ts +0 -26
  33. package/src/internal/state/controlledFieldStore.ts +0 -112
@@ -1407,14 +1407,19 @@ const hydratable = {
1407
1407
  hydratedData,
1408
1408
  from
1409
1409
  };
1410
+ var baseSet = _baseSet;
1411
+ function set(object, path, value) {
1412
+ return object == null ? object : baseSet(object, path, value);
1413
+ }
1414
+ var set_1 = set;
1410
1415
  const createStoreImpl = (createState) => {
1411
1416
  let state;
1412
1417
  const listeners = /* @__PURE__ */ new Set();
1413
- const setState = (partial, replace) => {
1418
+ const setState = (partial, replace2) => {
1414
1419
  const nextState = typeof partial === "function" ? partial(state) : partial;
1415
1420
  if (nextState !== state) {
1416
1421
  const previousState = state;
1417
- state = replace ? nextState : Object.assign({}, state, nextState);
1422
+ state = replace2 ? nextState : Object.assign({}, state, nextState);
1418
1423
  listeners.forEach((listener) => listener(state, previousState));
1419
1424
  }
1420
1425
  };
@@ -1899,80 +1904,88 @@ an.applyPatches.bind(an);
1899
1904
  an.createDraft.bind(an);
1900
1905
  an.finishDraft.bind(an);
1901
1906
  const immerImpl = (initializer) => (set2, get2, store) => {
1902
- store.setState = (updater, replace, ...a2) => {
1907
+ store.setState = (updater, replace2, ...a2) => {
1903
1908
  const nextState = typeof updater === "function" ? fn(updater) : updater;
1904
- return set2(nextState, replace, ...a2);
1909
+ return set2(nextState, replace2, ...a2);
1905
1910
  };
1906
1911
  return initializer(store.setState, get2, store);
1907
1912
  };
1908
1913
  const immer = immerImpl;
1909
- const useControlledFieldStore = create$1()(immer((set2, get2) => ({
1910
- forms: {},
1911
- register: (formId, field) => set2((state) => {
1912
- if (!state.forms[formId]) {
1913
- state.forms[formId] = {};
1914
- }
1915
- if (state.forms[formId][field]) {
1916
- state.forms[formId][field].refCount++;
1917
- } else {
1918
- state.forms[formId][field] = {
1919
- refCount: 1,
1920
- value: void 0,
1921
- hydrated: false,
1922
- valueUpdatePromise: void 0,
1923
- resolveValueUpdate: void 0
1924
- };
1914
+ const getArray = (values, field) => {
1915
+ const value = get_1(values, field);
1916
+ if (value === void 0 || value === null) {
1917
+ const newValue = [];
1918
+ set_1(values, field, newValue);
1919
+ return newValue;
1920
+ }
1921
+ invariant(Array.isArray(value), `FieldArray: defaultValue value for ${field} must be an array, null, or undefined`);
1922
+ return value;
1923
+ };
1924
+ const swap = (array, indexA, indexB) => {
1925
+ const itemA = array[indexA];
1926
+ const itemB = array[indexB];
1927
+ const hasItemA = indexA in array;
1928
+ const hasItemB = indexB in array;
1929
+ if (hasItemA) {
1930
+ array[indexB] = itemA;
1931
+ } else {
1932
+ delete array[indexB];
1933
+ }
1934
+ if (hasItemB) {
1935
+ array[indexA] = itemB;
1936
+ } else {
1937
+ delete array[indexA];
1938
+ }
1939
+ };
1940
+ function sparseSplice(array, start, deleteCount, item) {
1941
+ if (array.length < start && item) {
1942
+ array.length = start;
1943
+ }
1944
+ if (arguments.length === 4)
1945
+ return array.splice(start, deleteCount, item);
1946
+ return array.splice(start, deleteCount);
1947
+ }
1948
+ const move = (array, from2, to) => {
1949
+ const [item] = sparseSplice(array, from2, 1);
1950
+ sparseSplice(array, to, 0, item);
1951
+ };
1952
+ const insert = (array, index, value) => {
1953
+ sparseSplice(array, index, 0, value);
1954
+ };
1955
+ const remove = (array, index) => {
1956
+ sparseSplice(array, index, 1);
1957
+ };
1958
+ const replace = (array, index, value) => {
1959
+ sparseSplice(array, index, 1, value);
1960
+ };
1961
+ const mutateAsArray = (field, obj, mutate) => {
1962
+ const beforeKeys = /* @__PURE__ */ new Set();
1963
+ const arr = [];
1964
+ for (const [key, value] of Object.entries(obj)) {
1965
+ if (key.startsWith(field) && key !== field) {
1966
+ beforeKeys.add(key);
1925
1967
  }
1926
- }),
1927
- unregister: (formId, field) => set2((state) => {
1928
- var _a;
1929
- const formState = (_a = state.forms) == null ? void 0 : _a[formId];
1930
- const fieldState = formState == null ? void 0 : formState[field];
1931
- if (!fieldState)
1932
- return;
1933
- fieldState.refCount--;
1934
- if (fieldState.refCount === 0)
1935
- delete formState[field];
1936
- }),
1937
- getField: (formId, field) => {
1938
- var _a, _b;
1939
- return (_b = (_a = get2().forms) == null ? void 0 : _a[formId]) == null ? void 0 : _b[field];
1940
- },
1941
- setValue: (formId, field, value) => set2((state) => {
1942
- var _a, _b;
1943
- const fieldState = (_b = (_a = state.forms) == null ? void 0 : _a[formId]) == null ? void 0 : _b[field];
1944
- if (!fieldState)
1945
- return;
1946
- fieldState.value = value;
1947
- const promise = new Promise((resolve) => {
1948
- fieldState.resolveValueUpdate = resolve;
1949
- });
1950
- fieldState.valueUpdatePromise = promise;
1951
- }),
1952
- hydrateWithDefault: (formId, field, defaultValue) => set2((state) => {
1953
- var _a;
1954
- const fieldState = (_a = state.forms[formId]) == null ? void 0 : _a[field];
1955
- if (!fieldState)
1956
- return;
1957
- fieldState.value = defaultValue;
1958
- fieldState.defaultValue = defaultValue;
1959
- fieldState.hydrated = true;
1960
- }),
1961
- awaitValueUpdate: async (formId, field) => {
1962
- var _a;
1963
- await ((_a = get2().getField(formId, field)) == null ? void 0 : _a.valueUpdatePromise);
1964
- },
1965
- reset: (formId) => set2((state) => {
1966
- const formState = state.forms[formId];
1967
- if (!formState)
1968
- return;
1969
- Object.values(formState).forEach((field) => {
1970
- if (!field)
1971
- return;
1972
- field.value = field.defaultValue;
1973
- });
1974
- })
1975
- })));
1968
+ set_1(arr, key.substring(field.length), value);
1969
+ }
1970
+ mutate(arr);
1971
+ for (const key of beforeKeys) {
1972
+ delete obj[key];
1973
+ }
1974
+ const newKeys = getDeepArrayPaths(arr);
1975
+ for (const key of newKeys) {
1976
+ const val = get_1(arr, key);
1977
+ obj[`${field}${key}`] = val;
1978
+ }
1979
+ };
1980
+ const getDeepArrayPaths = (obj, basePath = "") => {
1981
+ if (Array.isArray(obj)) {
1982
+ return obj.flatMap((item, index) => getDeepArrayPaths(item, `${basePath}[${index}]`));
1983
+ }
1984
+ if (typeof obj === "object") {
1985
+ return Object.keys(obj).flatMap((key) => getDeepArrayPaths(obj[key], `${basePath}.${key}`));
1986
+ }
1987
+ return [basePath];
1988
+ };
1976
1989
  const noOp = () => {
1977
1990
  };
1978
1991
  const defaultFormState = {
@@ -1989,9 +2002,9 @@ const defaultFormState = {
1989
2002
  setFieldError: noOp,
1990
2003
  setFieldErrors: noOp,
1991
2004
  clearFieldError: noOp,
2005
+ currentDefaultValues: {},
1992
2006
  reset: () => noOp,
1993
2007
  syncFormProps: noOp,
1994
- setHydrated: noOp,
1995
2008
  setFormElement: noOp,
1996
2009
  validateField: async () => null,
1997
2010
  validate: async () => {
@@ -2001,15 +2014,40 @@ const defaultFormState = {
2001
2014
  throw new Error("Submit called before form was initialized.");
2002
2015
  },
2003
2016
  resetFormElement: noOp,
2004
- getValues: () => new FormData()
2017
+ getValues: () => new FormData(),
2018
+ controlledFields: {
2019
+ values: {},
2020
+ refCounts: {},
2021
+ valueUpdatePromises: {},
2022
+ valueUpdateResolvers: {},
2023
+ register: noOp,
2024
+ unregister: noOp,
2025
+ setValue: noOp,
2026
+ getValue: noOp,
2027
+ kickoffValueUpdate: noOp,
2028
+ awaitValueUpdate: async () => {
2029
+ throw new Error("AwaitValueUpdate called before form was initialized.");
2030
+ },
2031
+ array: {
2032
+ push: noOp,
2033
+ swap: noOp,
2034
+ move: noOp,
2035
+ insert: noOp,
2036
+ unshift: noOp,
2037
+ remove: noOp,
2038
+ pop: noOp,
2039
+ replace: noOp
2040
+ }
2041
+ }
2005
2042
  };
2006
- const createFormState = (formId, set2, get2) => ({
2043
+ const createFormState = (set2, get2) => ({
2007
2044
  isHydrated: false,
2008
2045
  isSubmitting: false,
2009
2046
  hasBeenSubmitted: false,
2010
2047
  touchedFields: {},
2011
2048
  fieldErrors: {},
2012
2049
  formElement: null,
2050
+ currentDefaultValues: {},
2013
2051
  isValid: () => Object.keys(get2().fieldErrors).length === 0,
2014
2052
  startSubmit: () => set2((state) => {
2015
2053
  state.isSubmitting = true;
@@ -2031,17 +2069,22 @@ const createFormState = (formId, set2, get2) => ({
2031
2069
  delete state.fieldErrors[fieldName];
2032
2070
  }),
2033
2071
  reset: () => set2((state) => {
2072
+ var _a, _b;
2034
2073
  state.fieldErrors = {};
2035
2074
  state.touchedFields = {};
2036
2075
  state.hasBeenSubmitted = false;
2076
+ const nextDefaults = (_b = (_a = state.formProps) == null ? void 0 : _a.defaultValues) != null ? _b : {};
2077
+ state.controlledFields.values = nextDefaults;
2078
+ state.currentDefaultValues = nextDefaults;
2037
2079
  }),
2038
2080
  syncFormProps: (props) => set2((state) => {
2081
+ if (!state.isHydrated) {
2082
+ state.controlledFields.values = props.defaultValues;
2083
+ state.currentDefaultValues = props.defaultValues;
2084
+ }
2039
2085
  state.formProps = props;
2040
2086
  state.isHydrated = true;
2041
2087
  }),
2042
- setHydrated: () => set2((state) => {
2043
- state.isHydrated = true;
2044
- }),
2045
2088
  setFormElement: (formElement) => {
2046
2089
  if (get2().formElement === formElement)
2047
2090
  return;
@@ -2055,7 +2098,7 @@ const createFormState = (formId, set2, get2) => ({
2055
2098
  invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
2056
2099
  const validator = (_a = get2().formProps) == null ? void 0 : _a.validator;
2057
2100
  invariant(validator, "Cannot validator. This is probably a bug in remix-validated-form.");
2058
- await ((_c = (_b = useControlledFieldStore.getState()).awaitValueUpdate) == null ? void 0 : _c.call(_b, formId, field));
2101
+ await ((_c = (_b = get2().controlledFields).awaitValueUpdate) == null ? void 0 : _c.call(_b, field));
2059
2102
  const { error } = await validator.validateField(new FormData(formElement), field);
2060
2103
  if (error) {
2061
2104
  get2().setFieldError(field, error);
@@ -2088,6 +2131,130 @@ const createFormState = (formId, set2, get2) => ({
2088
2131
  resetFormElement: () => {
2089
2132
  var _a;
2090
2133
  return (_a = get2().formElement) == null ? void 0 : _a.reset();
2134
+ },
2135
+ controlledFields: {
2136
+ values: {},
2137
+ refCounts: {},
2138
+ valueUpdatePromises: {},
2139
+ valueUpdateResolvers: {},
2140
+ register: (fieldName) => {
2141
+ set2((state) => {
2142
+ var _a;
2143
+ const current = (_a = state.controlledFields.refCounts[fieldName]) != null ? _a : 0;
2144
+ state.controlledFields.refCounts[fieldName] = current + 1;
2145
+ });
2146
+ },
2147
+ unregister: (fieldName) => {
2148
+ if (get2() === null || get2() === void 0)
2149
+ return;
2150
+ set2((state) => {
2151
+ var _a, _b, _c;
2152
+ const current = (_a = state.controlledFields.refCounts[fieldName]) != null ? _a : 0;
2153
+ if (current > 1) {
2154
+ state.controlledFields.refCounts[fieldName] = current - 1;
2155
+ return;
2156
+ }
2157
+ const isNested = Object.keys(state.controlledFields.refCounts).some((key) => fieldName.startsWith(key) && key !== fieldName);
2158
+ if (!isNested) {
2159
+ set_1(state.controlledFields.values, fieldName, get_1((_b = state.formProps) == null ? void 0 : _b.defaultValues, fieldName));
2160
+ set_1(state.currentDefaultValues, fieldName, get_1((_c = state.formProps) == null ? void 0 : _c.defaultValues, fieldName));
2161
+ }
2162
+ delete state.controlledFields.refCounts[fieldName];
2163
+ });
2164
+ },
2165
+ getValue: (fieldName) => get_1(get2().controlledFields.values, fieldName),
2166
+ setValue: (fieldName, value) => {
2167
+ set2((state) => {
2168
+ set_1(state.controlledFields.values, fieldName, value);
2169
+ });
2170
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2171
+ },
2172
+ kickoffValueUpdate: (fieldName) => {
2173
+ const clear = () => set2((state) => {
2174
+ delete state.controlledFields.valueUpdateResolvers[fieldName];
2175
+ delete state.controlledFields.valueUpdatePromises[fieldName];
2176
+ });
2177
+ set2((state) => {
2178
+ const promise = new Promise((resolve) => {
2179
+ state.controlledFields.valueUpdateResolvers[fieldName] = resolve;
2180
+ }).then(clear);
2181
+ state.controlledFields.valueUpdatePromises[fieldName] = promise;
2182
+ });
2183
+ },
2184
+ awaitValueUpdate: async (fieldName) => {
2185
+ await get2().controlledFields.valueUpdatePromises[fieldName];
2186
+ },
2187
+ array: {
2188
+ push: (fieldName, item) => {
2189
+ set2((state) => {
2190
+ getArray(state.controlledFields.values, fieldName).push(item);
2191
+ getArray(state.currentDefaultValues, fieldName).push(item);
2192
+ });
2193
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2194
+ },
2195
+ swap: (fieldName, indexA, indexB) => {
2196
+ set2((state) => {
2197
+ swap(getArray(state.controlledFields.values, fieldName), indexA, indexB);
2198
+ swap(getArray(state.currentDefaultValues, fieldName), indexA, indexB);
2199
+ mutateAsArray(fieldName, state.touchedFields, (array) => swap(array, indexA, indexB));
2200
+ mutateAsArray(fieldName, state.fieldErrors, (array) => swap(array, indexA, indexB));
2201
+ });
2202
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2203
+ },
2204
+ move: (fieldName, from2, to) => {
2205
+ set2((state) => {
2206
+ move(getArray(state.controlledFields.values, fieldName), from2, to);
2207
+ move(getArray(state.currentDefaultValues, fieldName), from2, to);
2208
+ mutateAsArray(fieldName, state.touchedFields, (array) => move(array, from2, to));
2209
+ mutateAsArray(fieldName, state.fieldErrors, (array) => move(array, from2, to));
2210
+ });
2211
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2212
+ },
2213
+ insert: (fieldName, index, item) => {
2214
+ set2((state) => {
2215
+ insert(getArray(state.controlledFields.values, fieldName), index, item);
2216
+ insert(getArray(state.currentDefaultValues, fieldName), index, item);
2217
+ mutateAsArray(fieldName, state.touchedFields, (array) => insert(array, index, false));
2218
+ mutateAsArray(fieldName, state.fieldErrors, (array) => insert(array, index, void 0));
2219
+ });
2220
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2221
+ },
2222
+ remove: (fieldName, index) => {
2223
+ set2((state) => {
2224
+ remove(getArray(state.controlledFields.values, fieldName), index);
2225
+ remove(getArray(state.currentDefaultValues, fieldName), index);
2226
+ mutateAsArray(fieldName, state.touchedFields, (array) => remove(array, index));
2227
+ mutateAsArray(fieldName, state.fieldErrors, (array) => remove(array, index));
2228
+ });
2229
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2230
+ },
2231
+ pop: (fieldName) => {
2232
+ set2((state) => {
2233
+ getArray(state.controlledFields.values, fieldName).pop();
2234
+ getArray(state.currentDefaultValues, fieldName).pop();
2235
+ mutateAsArray(fieldName, state.touchedFields, (array) => array.pop());
2236
+ mutateAsArray(fieldName, state.fieldErrors, (array) => array.pop());
2237
+ });
2238
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2239
+ },
2240
+ unshift: (fieldName, value) => {
2241
+ set2((state) => {
2242
+ getArray(state.controlledFields.values, fieldName).unshift(value);
2243
+ getArray(state.currentDefaultValues, fieldName).unshift(value);
2244
+ mutateAsArray(fieldName, state.touchedFields, (array) => array.unshift(false));
2245
+ mutateAsArray(fieldName, state.fieldErrors, (array) => array.unshift(void 0));
2246
+ });
2247
+ },
2248
+ replace: (fieldName, index, item) => {
2249
+ set2((state) => {
2250
+ replace(getArray(state.controlledFields.values, fieldName), index, item);
2251
+ replace(getArray(state.currentDefaultValues, fieldName), index, item);
2252
+ mutateAsArray(fieldName, state.touchedFields, (array) => replace(array, index, item));
2253
+ mutateAsArray(fieldName, state.fieldErrors, (array) => replace(array, index, item));
2254
+ });
2255
+ get2().controlledFields.kickoffValueUpdate(fieldName);
2256
+ }
2257
+ }
2091
2258
  }
2092
2259
  });
2093
2260
  const useRootFormStore = create$1()(immer((set2, get2) => ({
@@ -2105,7 +2272,7 @@ const useRootFormStore = create$1()(immer((set2, get2) => ({
2105
2272
  if (get2().forms[formId])
2106
2273
  return;
2107
2274
  set2((state) => {
2108
- state.forms[formId] = createFormState(formId, (setter) => set2((state2) => setter(state2.forms[formId])), () => get2().forms[formId]);
2275
+ state.forms[formId] = createFormState((setter) => set2((state2) => setter(state2.forms[formId])), () => get2().forms[formId]);
2109
2276
  });
2110
2277
  }
2111
2278
  })));
@@ -2193,10 +2360,11 @@ const useClearError = (context) => {
2193
2360
  const { formId } = context;
2194
2361
  return useFormStore(formId, (state) => state.clearFieldError);
2195
2362
  };
2363
+ const useCurrentDefaultValueForField = (formId, field) => useFormStore(formId, (state) => get_1(state.currentDefaultValues, field));
2196
2364
  const useFieldDefaultValue = (name, context) => {
2197
2365
  const defaultValues = useDefaultValuesForForm(context);
2198
- const state = useSyncedDefaultValues(context.formId);
2199
- return defaultValues.map((val) => get_1(val, name)).hydrateTo(get_1(state, name));
2366
+ const state = useCurrentDefaultValueForField(context.formId, name);
2367
+ return defaultValues.map((val) => get_1(val, name)).hydrateTo(state);
2200
2368
  };
2201
2369
  const useInternalIsSubmitting = (formId) => useFormStore(formId, (state) => state.isSubmitting);
2202
2370
  const useInternalIsValid = (formId) => useFormStore(formId, (state) => state.isValid());
@@ -2230,53 +2398,33 @@ const useFormSubactionProp = (formId) => useFormStore(formId, (state) => {
2230
2398
  });
2231
2399
  const useFormValues = (formId) => useFormStore(formId, (state) => state.getValues);
2232
2400
  const useControlledFieldValue = (context, field) => {
2233
- const value = useControlledFieldStore((state) => {
2234
- var _a;
2235
- return (_a = state.getField(context.formId, field)) == null ? void 0 : _a.value;
2236
- });
2401
+ const value = useFormStore(context.formId, (state) => state.controlledFields.getValue(field));
2237
2402
  const isFormHydrated = useFormStore(context.formId, (state) => state.isHydrated);
2238
2403
  const defaultValue = useFieldDefaultValue(field, context);
2239
- const isFieldHydrated = useControlledFieldStore((state) => {
2240
- var _a, _b;
2241
- return (_b = (_a = state.getField(context.formId, field)) == null ? void 0 : _a.hydrated) != null ? _b : false;
2242
- });
2243
- const hydrateWithDefault = useControlledFieldStore((state) => state.hydrateWithDefault);
2244
- useEffect(() => {
2245
- if (isFormHydrated && !isFieldHydrated) {
2246
- hydrateWithDefault(context.formId, field, defaultValue);
2247
- }
2248
- }, [
2249
- context.formId,
2250
- defaultValue,
2251
- field,
2252
- hydrateWithDefault,
2253
- isFieldHydrated,
2254
- isFormHydrated
2255
- ]);
2256
- return isFieldHydrated ? value : defaultValue;
2404
+ return isFormHydrated ? value : defaultValue;
2257
2405
  };
2258
- const useControllableValue = (context, field) => {
2259
- const resolveUpdate = useControlledFieldStore((state) => {
2260
- var _a;
2261
- return (_a = state.getField(context.formId, field)) == null ? void 0 : _a.resolveValueUpdate;
2262
- });
2406
+ const useRegisterControlledField = (context, field) => {
2407
+ const resolveUpdate = useFormStore(context.formId, (state) => state.controlledFields.valueUpdateResolvers[field]);
2263
2408
  useEffect(() => {
2264
2409
  resolveUpdate == null ? void 0 : resolveUpdate();
2265
2410
  }, [resolveUpdate]);
2266
- const register = useControlledFieldStore((state) => state.register);
2267
- const unregister = useControlledFieldStore((state) => state.unregister);
2411
+ const register = useFormStore(context.formId, (state) => state.controlledFields.register);
2412
+ const unregister = useFormStore(context.formId, (state) => state.controlledFields.unregister);
2268
2413
  useEffect(() => {
2269
- register(context.formId, field);
2270
- return () => unregister(context.formId, field);
2414
+ register(field);
2415
+ return () => unregister(field);
2271
2416
  }, [context.formId, field, register, unregister]);
2272
- const setControlledFieldValue = useControlledFieldStore((state) => state.setValue);
2273
- const setValue = useCallback((value2) => setControlledFieldValue(context.formId, field, value2), [context.formId, field, setControlledFieldValue]);
2417
+ };
2418
+ const useControllableValue = (context, field) => {
2419
+ useRegisterControlledField(context, field);
2420
+ const setControlledFieldValue = useFormStore(context.formId, (state) => state.controlledFields.setValue);
2421
+ const setValue = useCallback((value2) => setControlledFieldValue(field, value2), [field, setControlledFieldValue]);
2274
2422
  const value = useControlledFieldValue(context, field);
2275
2423
  return [value, setValue];
2276
2424
  };
2277
2425
  const useUpdateControllableValue = (formId) => {
2278
- const setValue = useControlledFieldStore((state) => state.setValue);
2279
- return useCallback((field, value) => setValue(formId, field, value), [formId, setValue]);
2426
+ const setValue = useFormStore(formId, (state) => state.controlledFields.setValue);
2427
+ return useCallback((field, value) => setValue(field, value), [setValue]);
2280
2428
  };
2281
2429
  const useIsSubmitting = (formId) => {
2282
2430
  const formContext = useInternalFormContext(formId, "useIsSubmitting");
@@ -2643,7 +2791,7 @@ function ValidatedForm(_a) {
2643
2791
  resetAfterSubmit = false,
2644
2792
  disableFocusOnError,
2645
2793
  method,
2646
- replace,
2794
+ replace: replace2,
2647
2795
  id
2648
2796
  } = _b, rest = __objRest(_b, [
2649
2797
  "validator",
@@ -2680,7 +2828,6 @@ function ValidatedForm(_a) {
2680
2828
  const setFieldErrors = useSetFieldErrors(formId);
2681
2829
  const setFieldError = useFormStore(formId, (state) => state.setFieldError);
2682
2830
  const reset = useFormStore(formId, (state) => state.reset);
2683
- const resetControlledFields = useControlledFieldStore((state) => state.reset);
2684
2831
  const startSubmit = useFormStore(formId, (state) => state.startSubmit);
2685
2832
  const endSubmit = useFormStore(formId, (state) => state.endSubmit);
2686
2833
  const syncFormProps = useFormStore(formId, (state) => state.syncFormProps);
@@ -2746,7 +2893,7 @@ function ValidatedForm(_a) {
2746
2893
  if (fetcher)
2747
2894
  fetcher.submit(submitter || e2.currentTarget);
2748
2895
  else
2749
- submit(submitter || target, { replace });
2896
+ submit(submitter || target, { replace: replace2 });
2750
2897
  }
2751
2898
  };
2752
2899
  return /* @__PURE__ */ React.createElement(Form$1, __spreadProps(__spreadValues({
@@ -2755,7 +2902,7 @@ function ValidatedForm(_a) {
2755
2902
  id,
2756
2903
  action,
2757
2904
  method,
2758
- replace,
2905
+ replace: replace2,
2759
2906
  onSubmit: (e2) => {
2760
2907
  e2.preventDefault();
2761
2908
  handleSubmit(e2, e2.currentTarget, e2.nativeEvent);
@@ -2765,7 +2912,6 @@ function ValidatedForm(_a) {
2765
2912
  if (event.defaultPrevented)
2766
2913
  return;
2767
2914
  reset();
2768
- resetControlledFields(formId);
2769
2915
  }
2770
2916
  }), /* @__PURE__ */ React.createElement(InternalFormContext.Provider, {
2771
2917
  value: contextValue
@@ -2782,11 +2928,6 @@ function ValidatedForm(_a) {
2782
2928
  name: FORM_ID_FIELD
2783
2929
  }), children)));
2784
2930
  }
2785
- var baseSet = _baseSet;
2786
- function set(object, path, value) {
2787
- return object == null ? object : baseSet(object, path, value);
2788
- }
2789
- var set_1 = set;
2790
2931
  const objectFromPathEntries = (entries) => {
2791
2932
  const map = new MultiValueMap();
2792
2933
  entries.forEach(([key, value]) => map.add(key, value));
@@ -2930,5 +3071,74 @@ const useFormContext = (formId) => {
2930
3071
  getValues
2931
3072
  ]);
2932
3073
  };
2933
- export { ValidatedForm, createValidator, setFormDefaults, useControlField, useField, useFormContext, useIsSubmitting, useIsValid, useUpdateControlledField, validationError };
3074
+ const useInternalFieldArray = (context, field, validationBehavior) => {
3075
+ const value = useFieldDefaultValue(field, context);
3076
+ useRegisterControlledField(context, field);
3077
+ const hasBeenSubmitted = useInternalHasBeenSubmitted(context.formId);
3078
+ const validateField = useValidateField(context.formId);
3079
+ const error = useFieldError(field, context);
3080
+ const resolvedValidationBehavior = __spreadValues({
3081
+ initial: "onSubmit",
3082
+ whenSubmitted: "onChange"
3083
+ }, validationBehavior);
3084
+ const behavior = hasBeenSubmitted ? resolvedValidationBehavior.whenSubmitted : resolvedValidationBehavior.initial;
3085
+ const maybeValidate = useCallback(() => {
3086
+ if (behavior === "onChange") {
3087
+ validateField(field);
3088
+ }
3089
+ }, [behavior, field, validateField]);
3090
+ invariant(value === void 0 || value === null || Array.isArray(value), `FieldArray: defaultValue value for ${field} must be an array, null, or undefined`);
3091
+ const arr = useFormStore(context.formId, (state) => state.controlledFields.array);
3092
+ const helpers = useMemo(() => ({
3093
+ push: (item) => {
3094
+ arr.push(field, item);
3095
+ maybeValidate();
3096
+ },
3097
+ swap: (indexA, indexB) => {
3098
+ arr.swap(field, indexA, indexB);
3099
+ maybeValidate();
3100
+ },
3101
+ move: (from2, to) => {
3102
+ arr.move(field, from2, to);
3103
+ maybeValidate();
3104
+ },
3105
+ insert: (index, value2) => {
3106
+ arr.insert(field, index, value2);
3107
+ maybeValidate();
3108
+ },
3109
+ unshift: (value2) => {
3110
+ arr.unshift(field, value2);
3111
+ maybeValidate();
3112
+ },
3113
+ remove: (index) => {
3114
+ arr.remove(field, index);
3115
+ maybeValidate();
3116
+ },
3117
+ pop: () => {
3118
+ arr.pop(field);
3119
+ maybeValidate();
3120
+ },
3121
+ replace: (index, value2) => {
3122
+ arr.replace(field, index, value2);
3123
+ maybeValidate();
3124
+ }
3125
+ }), [arr, field, maybeValidate]);
3126
+ const arrayValue = useMemo(() => value != null ? value : [], [value]);
3127
+ return [arrayValue, helpers, error];
3128
+ };
3129
+ function useFieldArray(name, { formId, validationBehavior } = {}) {
3130
+ const context = useInternalFormContext(formId, "FieldArray");
3131
+ return useInternalFieldArray(context, name, validationBehavior);
3132
+ }
3133
+ const FieldArray = ({
3134
+ name,
3135
+ children,
3136
+ formId,
3137
+ validationBehavior
3138
+ }) => {
3139
+ const context = useInternalFormContext(formId, "FieldArray");
3140
+ const [value, helpers, error] = useInternalFieldArray(context, name, validationBehavior);
3141
+ return children(value, helpers, error);
3142
+ };
3143
+ export { FieldArray, ValidatedForm, createValidator, setFormDefaults, useControlField, useField, useFieldArray, useFormContext, useIsSubmitting, useIsValid, useUpdateControlledField, validationError };
2934
3144
  //# sourceMappingURL=remix-validated-form.es.js.map