Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 157x 125x 20x 20x 20x 20x 20x 20x 20x 2x 18x 20x 21x 114x 9x 9x 9x 4x 17x 11x 11x 3x 3x 11x 2x 2x 2x 2x | import type { FieldErrors, FormStateSnapshot, FormValues, NormalizedFormSchema } from "../schema/types";
import { getInitialValues } from "../schema/normalizeSchema";
function cloneValues(values: FormValues): FormValues {
return { ...values };
}
function cloneErrors(errors: FieldErrors): FieldErrors {
return Object.fromEntries(Object.entries(errors).map(([fieldName, messages]) => [fieldName, [...messages]]));
}
function areEqualValues(left: unknown, right: unknown): boolean {
return left === right;
}
export interface FormState {
getValues(): FormValues;
getInitialValues(): FormValues;
getSnapshot(visibleFields?: string[]): FormStateSnapshot;
setValue(fieldName: string, value: FormValues[string]): void;
setValues(values: FormValues): void;
markTouched(fieldName: string): void;
setErrors(errors: FieldErrors): void;
reset(): void;
}
export function createFormState(schema: NormalizedFormSchema, initialValues: FormValues = {}): FormState {
const initial = getInitialValues(schema, initialValues);
let values = cloneValues(initial);
const touchedFields = new Set<string>();
const dirtyFields = new Set<string>();
let errors: FieldErrors = {};
function recomputeDirty(fieldName: string): void {
if (areEqualValues(values[fieldName], initial[fieldName])) {
dirtyFields.delete(fieldName);
} else {
dirtyFields.add(fieldName);
}
}
return {
getValues() {
return cloneValues(values);
},
getInitialValues() {
return cloneValues(initial);
},
getSnapshot(visibleFields: string[] = schema.fieldOrder) {
return {
values: cloneValues(values),
touchedFields: [...touchedFields],
dirtyFields: [...dirtyFields],
errors: cloneErrors(errors),
isValid: Object.keys(errors).length === 0,
visibleFields: [...visibleFields]
};
},
setValue(fieldName, value) {
Iif (!schema.fieldMap.has(fieldName)) {
return;
}
values = {
...values,
[fieldName]: value
};
recomputeDirty(fieldName);
},
setValues(nextValues) {
schema.fieldOrder.forEach((fieldName) => {
if (Object.prototype.hasOwnProperty.call(nextValues, fieldName)) {
values[fieldName] = nextValues[fieldName];
recomputeDirty(fieldName);
}
});
},
markTouched(fieldName) {
Eif (schema.fieldMap.has(fieldName)) {
touchedFields.add(fieldName);
}
},
setErrors(nextErrors) {
errors = cloneErrors(nextErrors);
},
reset() {
values = cloneValues(initial);
touchedFields.clear();
dirtyFields.clear();
errors = {};
}
};
}
|