remix-validated-form
Version:
Form component and utils for easy form validation in remix
71 lines (70 loc) • 2.64 kB
JavaScript
import create from "zustand";
import { immer } from "zustand/middleware/immer";
export const useControlledFieldStore = create()(immer((set, get) => ({
forms: {},
register: (formId, field) => set((state) => {
if (!state.forms[formId]) {
state.forms[formId] = {};
}
if (state.forms[formId][field]) {
state.forms[formId][field].refCount++;
}
else {
state.forms[formId][field] = {
refCount: 1,
value: undefined,
hydrated: false,
valueUpdatePromise: undefined,
resolveValueUpdate: undefined,
};
}
}),
unregister: (formId, field) => set((state) => {
var _a;
const formState = (_a = state.forms) === null || _a === void 0 ? void 0 : _a[formId];
const fieldState = formState === null || formState === void 0 ? void 0 : formState[field];
if (!fieldState)
return;
fieldState.refCount--;
if (fieldState.refCount === 0)
delete formState[field];
}),
getField: (formId, field) => {
var _a, _b;
return (_b = (_a = get().forms) === null || _a === void 0 ? void 0 : _a[formId]) === null || _b === void 0 ? void 0 : _b[field];
},
setValue: (formId, field, value) => set((state) => {
var _a, _b;
const fieldState = (_b = (_a = state.forms) === null || _a === void 0 ? void 0 : _a[formId]) === null || _b === void 0 ? void 0 : _b[field];
if (!fieldState)
return;
fieldState.value = value;
const promise = new Promise((resolve) => {
fieldState.resolveValueUpdate = resolve;
});
fieldState.valueUpdatePromise = promise;
}),
hydrateWithDefault: (formId, field, defaultValue) => set((state) => {
var _a;
const fieldState = (_a = state.forms[formId]) === null || _a === void 0 ? void 0 : _a[field];
if (!fieldState)
return;
fieldState.value = defaultValue;
fieldState.defaultValue = defaultValue;
fieldState.hydrated = true;
}),
awaitValueUpdate: async (formId, field) => {
var _a;
await ((_a = get().getField(formId, field)) === null || _a === void 0 ? void 0 : _a.valueUpdatePromise);
},
reset: (formId) => set((state) => {
const formState = state.forms[formId];
if (!formState)
return;
Object.values(formState).forEach((field) => {
if (!field)
return;
field.value = field.defaultValue;
});
}),
})));