remix-validated-form 4.5.2 → 4.6.0-beta.0

Sign up to get free protection for your applications and to get access to all the features.
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