remix-validated-form 4.5.2 → 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 (38) hide show
  1. package/.turbo/turbo-build.log +8 -9
  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 +177 -14
  11. package/browser/server.d.ts +2 -2
  12. package/browser/server.js +1 -1
  13. package/dist/remix-validated-form.cjs.js +12 -3
  14. package/dist/remix-validated-form.cjs.js.map +1 -1
  15. package/dist/remix-validated-form.es.js +361 -131
  16. package/dist/remix-validated-form.es.js.map +1 -1
  17. package/dist/remix-validated-form.umd.js +12 -3
  18. package/dist/remix-validated-form.umd.js.map +1 -1
  19. package/dist/types/index.d.ts +1 -0
  20. package/dist/types/internal/hooks.d.ts +1 -0
  21. package/dist/types/internal/state/arrayUtil.d.ts +12 -0
  22. package/dist/types/internal/state/controlledFields.d.ts +1 -0
  23. package/dist/types/internal/state/createFormStore.d.ts +31 -1
  24. package/dist/types/internal/state/fieldArray.d.ts +28 -0
  25. package/dist/types/server.d.ts +2 -2
  26. package/package.json +1 -3
  27. package/src/ValidatedForm.tsx +0 -3
  28. package/src/index.ts +6 -0
  29. package/src/internal/hooks.ts +9 -4
  30. package/src/internal/logic/nestedObjectToPathObject.ts +63 -0
  31. package/src/internal/state/arrayUtil.ts +399 -0
  32. package/src/internal/state/controlledFields.ts +39 -43
  33. package/src/internal/state/createFormStore.ts +288 -20
  34. package/src/internal/state/fieldArray.tsx +155 -0
  35. package/src/server.ts +1 -1
  36. package/vite.config.ts +1 -1
  37. package/dist/types/internal/state/controlledFieldStore.d.ts +0 -26
  38. package/src/internal/state/controlledFieldStore.ts +0 -112
@@ -31,7 +31,6 @@ var __objRest = (source, exclude) => {
31
31
  };
32
32
  import React, { createContext, useDebugValue, useContext, useCallback, useEffect, useMemo, useRef, useLayoutEffect, useState } from "react";
33
33
  import { useActionData, useMatches, useTransition, Form, useSubmit } from "@remix-run/react";
34
- import { json } from "@remix-run/server-runtime";
35
34
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
36
35
  function listCacheClear$1() {
37
36
  this.__data__ = [];
@@ -1408,14 +1407,19 @@ const hydratable = {
1408
1407
  hydratedData,
1409
1408
  from
1410
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;
1411
1415
  const createStoreImpl = (createState) => {
1412
1416
  let state;
1413
1417
  const listeners = /* @__PURE__ */ new Set();
1414
- const setState = (partial, replace) => {
1418
+ const setState = (partial, replace2) => {
1415
1419
  const nextState = typeof partial === "function" ? partial(state) : partial;
1416
1420
  if (nextState !== state) {
1417
1421
  const previousState = state;
1418
- state = replace ? nextState : Object.assign({}, state, nextState);
1422
+ state = replace2 ? nextState : Object.assign({}, state, nextState);
1419
1423
  listeners.forEach((listener) => listener(state, previousState));
1420
1424
  }
1421
1425
  };
@@ -1900,80 +1904,88 @@ an.applyPatches.bind(an);
1900
1904
  an.createDraft.bind(an);
1901
1905
  an.finishDraft.bind(an);
1902
1906
  const immerImpl = (initializer) => (set2, get2, store) => {
1903
- store.setState = (updater, replace, ...a2) => {
1907
+ store.setState = (updater, replace2, ...a2) => {
1904
1908
  const nextState = typeof updater === "function" ? fn(updater) : updater;
1905
- return set2(nextState, replace, ...a2);
1909
+ return set2(nextState, replace2, ...a2);
1906
1910
  };
1907
1911
  return initializer(store.setState, get2, store);
1908
1912
  };
1909
1913
  const immer = immerImpl;
1910
- const useControlledFieldStore = create$1()(immer((set2, get2) => ({
1911
- forms: {},
1912
- register: (formId, field) => set2((state) => {
1913
- if (!state.forms[formId]) {
1914
- state.forms[formId] = {};
1915
- }
1916
- if (state.forms[formId][field]) {
1917
- state.forms[formId][field].refCount++;
1918
- } else {
1919
- state.forms[formId][field] = {
1920
- refCount: 1,
1921
- value: void 0,
1922
- hydrated: false,
1923
- valueUpdatePromise: void 0,
1924
- resolveValueUpdate: void 0
1925
- };
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);
1926
1967
  }
1927
- }),
1928
- unregister: (formId, field) => set2((state) => {
1929
- var _a;
1930
- const formState = (_a = state.forms) == null ? void 0 : _a[formId];
1931
- const fieldState = formState == null ? void 0 : formState[field];
1932
- if (!fieldState)
1933
- return;
1934
- fieldState.refCount--;
1935
- if (fieldState.refCount === 0)
1936
- delete formState[field];
1937
- }),
1938
- getField: (formId, field) => {
1939
- var _a, _b;
1940
- return (_b = (_a = get2().forms) == null ? void 0 : _a[formId]) == null ? void 0 : _b[field];
1941
- },
1942
- setValue: (formId, field, value) => set2((state) => {
1943
- var _a, _b;
1944
- const fieldState = (_b = (_a = state.forms) == null ? void 0 : _a[formId]) == null ? void 0 : _b[field];
1945
- if (!fieldState)
1946
- return;
1947
- fieldState.value = value;
1948
- const promise = new Promise((resolve) => {
1949
- fieldState.resolveValueUpdate = resolve;
1950
- });
1951
- fieldState.valueUpdatePromise = promise;
1952
- }),
1953
- hydrateWithDefault: (formId, field, defaultValue) => set2((state) => {
1954
- var _a;
1955
- const fieldState = (_a = state.forms[formId]) == null ? void 0 : _a[field];
1956
- if (!fieldState)
1957
- return;
1958
- fieldState.value = defaultValue;
1959
- fieldState.defaultValue = defaultValue;
1960
- fieldState.hydrated = true;
1961
- }),
1962
- awaitValueUpdate: async (formId, field) => {
1963
- var _a;
1964
- await ((_a = get2().getField(formId, field)) == null ? void 0 : _a.valueUpdatePromise);
1965
- },
1966
- reset: (formId) => set2((state) => {
1967
- const formState = state.forms[formId];
1968
- if (!formState)
1969
- return;
1970
- Object.values(formState).forEach((field) => {
1971
- if (!field)
1972
- return;
1973
- field.value = field.defaultValue;
1974
- });
1975
- })
1976
- })));
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
+ };
1977
1989
  const noOp = () => {
1978
1990
  };
1979
1991
  const defaultFormState = {
@@ -1990,9 +2002,9 @@ const defaultFormState = {
1990
2002
  setFieldError: noOp,
1991
2003
  setFieldErrors: noOp,
1992
2004
  clearFieldError: noOp,
2005
+ currentDefaultValues: {},
1993
2006
  reset: () => noOp,
1994
2007
  syncFormProps: noOp,
1995
- setHydrated: noOp,
1996
2008
  setFormElement: noOp,
1997
2009
  validateField: async () => null,
1998
2010
  validate: async () => {
@@ -2002,15 +2014,40 @@ const defaultFormState = {
2002
2014
  throw new Error("Submit called before form was initialized.");
2003
2015
  },
2004
2016
  resetFormElement: noOp,
2005
- 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
+ }
2006
2042
  };
2007
- const createFormState = (formId, set2, get2) => ({
2043
+ const createFormState = (set2, get2) => ({
2008
2044
  isHydrated: false,
2009
2045
  isSubmitting: false,
2010
2046
  hasBeenSubmitted: false,
2011
2047
  touchedFields: {},
2012
2048
  fieldErrors: {},
2013
2049
  formElement: null,
2050
+ currentDefaultValues: {},
2014
2051
  isValid: () => Object.keys(get2().fieldErrors).length === 0,
2015
2052
  startSubmit: () => set2((state) => {
2016
2053
  state.isSubmitting = true;
@@ -2032,17 +2069,22 @@ const createFormState = (formId, set2, get2) => ({
2032
2069
  delete state.fieldErrors[fieldName];
2033
2070
  }),
2034
2071
  reset: () => set2((state) => {
2072
+ var _a, _b;
2035
2073
  state.fieldErrors = {};
2036
2074
  state.touchedFields = {};
2037
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;
2038
2079
  }),
2039
2080
  syncFormProps: (props) => set2((state) => {
2081
+ if (!state.isHydrated) {
2082
+ state.controlledFields.values = props.defaultValues;
2083
+ state.currentDefaultValues = props.defaultValues;
2084
+ }
2040
2085
  state.formProps = props;
2041
2086
  state.isHydrated = true;
2042
2087
  }),
2043
- setHydrated: () => set2((state) => {
2044
- state.isHydrated = true;
2045
- }),
2046
2088
  setFormElement: (formElement) => {
2047
2089
  if (get2().formElement === formElement)
2048
2090
  return;
@@ -2056,7 +2098,7 @@ const createFormState = (formId, set2, get2) => ({
2056
2098
  invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
2057
2099
  const validator = (_a = get2().formProps) == null ? void 0 : _a.validator;
2058
2100
  invariant(validator, "Cannot validator. This is probably a bug in remix-validated-form.");
2059
- 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));
2060
2102
  const { error } = await validator.validateField(new FormData(formElement), field);
2061
2103
  if (error) {
2062
2104
  get2().setFieldError(field, error);
@@ -2080,16 +2122,139 @@ const createFormState = (formId, set2, get2) => ({
2080
2122
  submit: () => {
2081
2123
  const formElement = get2().formElement;
2082
2124
  invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
2083
- formElement.submit();
2125
+ formElement.requestSubmit();
2084
2126
  },
2085
2127
  getValues: () => {
2086
- const formElement = get2().formElement;
2087
- invariant(formElement, "Cannot find reference to form. This is probably a bug in remix-validated-form.");
2088
- return new FormData(formElement);
2128
+ var _a;
2129
+ return new FormData((_a = get2().formElement) != null ? _a : void 0);
2089
2130
  },
2090
2131
  resetFormElement: () => {
2091
2132
  var _a;
2092
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
+ }
2093
2258
  }
2094
2259
  });
2095
2260
  const useRootFormStore = create$1()(immer((set2, get2) => ({
@@ -2107,7 +2272,7 @@ const useRootFormStore = create$1()(immer((set2, get2) => ({
2107
2272
  if (get2().forms[formId])
2108
2273
  return;
2109
2274
  set2((state) => {
2110
- 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]);
2111
2276
  });
2112
2277
  }
2113
2278
  })));
@@ -2195,10 +2360,11 @@ const useClearError = (context) => {
2195
2360
  const { formId } = context;
2196
2361
  return useFormStore(formId, (state) => state.clearFieldError);
2197
2362
  };
2363
+ const useCurrentDefaultValueForField = (formId, field) => useFormStore(formId, (state) => get_1(state.currentDefaultValues, field));
2198
2364
  const useFieldDefaultValue = (name, context) => {
2199
2365
  const defaultValues = useDefaultValuesForForm(context);
2200
- const state = useSyncedDefaultValues(context.formId);
2201
- 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);
2202
2368
  };
2203
2369
  const useInternalIsSubmitting = (formId) => useFormStore(formId, (state) => state.isSubmitting);
2204
2370
  const useInternalIsValid = (formId) => useFormStore(formId, (state) => state.isValid());
@@ -2232,53 +2398,33 @@ const useFormSubactionProp = (formId) => useFormStore(formId, (state) => {
2232
2398
  });
2233
2399
  const useFormValues = (formId) => useFormStore(formId, (state) => state.getValues);
2234
2400
  const useControlledFieldValue = (context, field) => {
2235
- const value = useControlledFieldStore((state) => {
2236
- var _a;
2237
- return (_a = state.getField(context.formId, field)) == null ? void 0 : _a.value;
2238
- });
2401
+ const value = useFormStore(context.formId, (state) => state.controlledFields.getValue(field));
2239
2402
  const isFormHydrated = useFormStore(context.formId, (state) => state.isHydrated);
2240
2403
  const defaultValue = useFieldDefaultValue(field, context);
2241
- const isFieldHydrated = useControlledFieldStore((state) => {
2242
- var _a, _b;
2243
- return (_b = (_a = state.getField(context.formId, field)) == null ? void 0 : _a.hydrated) != null ? _b : false;
2244
- });
2245
- const hydrateWithDefault = useControlledFieldStore((state) => state.hydrateWithDefault);
2246
- useEffect(() => {
2247
- if (isFormHydrated && !isFieldHydrated) {
2248
- hydrateWithDefault(context.formId, field, defaultValue);
2249
- }
2250
- }, [
2251
- context.formId,
2252
- defaultValue,
2253
- field,
2254
- hydrateWithDefault,
2255
- isFieldHydrated,
2256
- isFormHydrated
2257
- ]);
2258
- return isFieldHydrated ? value : defaultValue;
2404
+ return isFormHydrated ? value : defaultValue;
2259
2405
  };
2260
- const useControllableValue = (context, field) => {
2261
- const resolveUpdate = useControlledFieldStore((state) => {
2262
- var _a;
2263
- return (_a = state.getField(context.formId, field)) == null ? void 0 : _a.resolveValueUpdate;
2264
- });
2406
+ const useRegisterControlledField = (context, field) => {
2407
+ const resolveUpdate = useFormStore(context.formId, (state) => state.controlledFields.valueUpdateResolvers[field]);
2265
2408
  useEffect(() => {
2266
2409
  resolveUpdate == null ? void 0 : resolveUpdate();
2267
2410
  }, [resolveUpdate]);
2268
- const register = useControlledFieldStore((state) => state.register);
2269
- 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);
2270
2413
  useEffect(() => {
2271
- register(context.formId, field);
2272
- return () => unregister(context.formId, field);
2414
+ register(field);
2415
+ return () => unregister(field);
2273
2416
  }, [context.formId, field, register, unregister]);
2274
- const setControlledFieldValue = useControlledFieldStore((state) => state.setValue);
2275
- 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]);
2276
2422
  const value = useControlledFieldValue(context, field);
2277
2423
  return [value, setValue];
2278
2424
  };
2279
2425
  const useUpdateControllableValue = (formId) => {
2280
- const setValue = useControlledFieldStore((state) => state.setValue);
2281
- 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]);
2282
2428
  };
2283
2429
  const useIsSubmitting = (formId) => {
2284
2430
  const formContext = useInternalFormContext(formId, "useIsSubmitting");
@@ -2343,6 +2489,28 @@ const useUpdateControlledField = (formId) => {
2343
2489
  const context = useInternalFormContext(formId, "useControlField");
2344
2490
  return useUpdateControllableValue(context.formId);
2345
2491
  };
2492
+ /**
2493
+ * @remix-run/server-runtime v1.6.5
2494
+ *
2495
+ * Copyright (c) Remix Software Inc.
2496
+ *
2497
+ * This source code is licensed under the MIT license found in the
2498
+ * LICENSE.md file in the root directory of this source tree.
2499
+ *
2500
+ * @license MIT
2501
+ */
2502
+ const json = (data, init = {}) => {
2503
+ let responseInit = typeof init === "number" ? {
2504
+ status: init
2505
+ } : init;
2506
+ let headers = new Headers(responseInit.headers);
2507
+ if (!headers.has("Content-Type")) {
2508
+ headers.set("Content-Type", "application/json; charset=utf-8");
2509
+ }
2510
+ return new Response(JSON.stringify(data), __spreadProps(__spreadValues({}, responseInit), {
2511
+ headers
2512
+ }));
2513
+ };
2346
2514
  function validationError(error, repopulateFields, init) {
2347
2515
  return json({
2348
2516
  fieldErrors: error.fieldErrors,
@@ -2623,7 +2791,7 @@ function ValidatedForm(_a) {
2623
2791
  resetAfterSubmit = false,
2624
2792
  disableFocusOnError,
2625
2793
  method,
2626
- replace,
2794
+ replace: replace2,
2627
2795
  id
2628
2796
  } = _b, rest = __objRest(_b, [
2629
2797
  "validator",
@@ -2660,7 +2828,6 @@ function ValidatedForm(_a) {
2660
2828
  const setFieldErrors = useSetFieldErrors(formId);
2661
2829
  const setFieldError = useFormStore(formId, (state) => state.setFieldError);
2662
2830
  const reset = useFormStore(formId, (state) => state.reset);
2663
- const resetControlledFields = useControlledFieldStore((state) => state.reset);
2664
2831
  const startSubmit = useFormStore(formId, (state) => state.startSubmit);
2665
2832
  const endSubmit = useFormStore(formId, (state) => state.endSubmit);
2666
2833
  const syncFormProps = useFormStore(formId, (state) => state.syncFormProps);
@@ -2726,7 +2893,7 @@ function ValidatedForm(_a) {
2726
2893
  if (fetcher)
2727
2894
  fetcher.submit(submitter || e2.currentTarget);
2728
2895
  else
2729
- submit(submitter || target, { replace });
2896
+ submit(submitter || target, { replace: replace2 });
2730
2897
  }
2731
2898
  };
2732
2899
  return /* @__PURE__ */ React.createElement(Form$1, __spreadProps(__spreadValues({
@@ -2735,7 +2902,7 @@ function ValidatedForm(_a) {
2735
2902
  id,
2736
2903
  action,
2737
2904
  method,
2738
- replace,
2905
+ replace: replace2,
2739
2906
  onSubmit: (e2) => {
2740
2907
  e2.preventDefault();
2741
2908
  handleSubmit(e2, e2.currentTarget, e2.nativeEvent);
@@ -2745,7 +2912,6 @@ function ValidatedForm(_a) {
2745
2912
  if (event.defaultPrevented)
2746
2913
  return;
2747
2914
  reset();
2748
- resetControlledFields(formId);
2749
2915
  }
2750
2916
  }), /* @__PURE__ */ React.createElement(InternalFormContext.Provider, {
2751
2917
  value: contextValue
@@ -2762,11 +2928,6 @@ function ValidatedForm(_a) {
2762
2928
  name: FORM_ID_FIELD
2763
2929
  }), children)));
2764
2930
  }
2765
- var baseSet = _baseSet;
2766
- function set(object, path, value) {
2767
- return object == null ? object : baseSet(object, path, value);
2768
- }
2769
- var set_1 = set;
2770
2931
  const objectFromPathEntries = (entries) => {
2771
2932
  const map = new MultiValueMap();
2772
2933
  entries.forEach(([key, value]) => map.add(key, value));
@@ -2910,5 +3071,74 @@ const useFormContext = (formId) => {
2910
3071
  getValues
2911
3072
  ]);
2912
3073
  };
2913
- 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 };
2914
3144
  //# sourceMappingURL=remix-validated-form.es.js.map