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.
- package/.turbo/turbo-build.log +8 -8
- package/browser/ValidatedForm.js +0 -3
- package/browser/index.d.ts +1 -0
- package/browser/index.js +1 -0
- package/browser/internal/hooks.d.ts +1 -0
- package/browser/internal/hooks.js +3 -4
- package/browser/internal/state/controlledFields.d.ts +1 -0
- package/browser/internal/state/controlledFields.js +17 -29
- package/browser/internal/state/createFormStore.d.ts +31 -1
- package/browser/internal/state/createFormStore.js +175 -8
- package/dist/remix-validated-form.cjs.js +4 -4
- package/dist/remix-validated-form.cjs.js.map +1 -1
- package/dist/remix-validated-form.es.js +336 -126
- package/dist/remix-validated-form.es.js.map +1 -1
- package/dist/remix-validated-form.umd.js +4 -4
- package/dist/remix-validated-form.umd.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/internal/hooks.d.ts +1 -0
- package/dist/types/internal/state/arrayUtil.d.ts +12 -0
- package/dist/types/internal/state/controlledFields.d.ts +1 -0
- package/dist/types/internal/state/createFormStore.d.ts +31 -1
- package/dist/types/internal/state/fieldArray.d.ts +28 -0
- package/package.json +1 -1
- package/src/ValidatedForm.tsx +0 -3
- package/src/index.ts +6 -0
- package/src/internal/hooks.ts +9 -4
- package/src/internal/logic/nestedObjectToPathObject.ts +63 -0
- package/src/internal/state/arrayUtil.ts +399 -0
- package/src/internal/state/controlledFields.ts +39 -43
- package/src/internal/state/createFormStore.ts +286 -10
- package/src/internal/state/fieldArray.tsx +155 -0
- package/dist/types/internal/state/controlledFieldStore.d.ts +0 -26
- 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,
|
|
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 =
|
|
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,
|
|
1907
|
+
store.setState = (updater, replace2, ...a2) => {
|
|
1903
1908
|
const nextState = typeof updater === "function" ? fn(updater) : updater;
|
|
1904
|
-
return set2(nextState,
|
|
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
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
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
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
}
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
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 = (
|
|
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 =
|
|
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(
|
|
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 =
|
|
2199
|
-
return defaultValues.map((val) => get_1(val, name)).hydrateTo(
|
|
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 =
|
|
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
|
-
|
|
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
|
|
2259
|
-
const resolveUpdate =
|
|
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 =
|
|
2267
|
-
const 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(
|
|
2270
|
-
return () => unregister(
|
|
2414
|
+
register(field);
|
|
2415
|
+
return () => unregister(field);
|
|
2271
2416
|
}, [context.formId, field, register, unregister]);
|
|
2272
|
-
|
|
2273
|
-
|
|
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 =
|
|
2279
|
-
return useCallback((field, value) => 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
|
-
|
|
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
|