import { ObjectState } from "./objectField"; import { Rule } from "../rules"; /** * Form state for a primitive field in the form, i.e. its value but also touched/validation/etc. state. * * This API also provides hooks for form elements to call into, i.e. `blur()` and `set(...)` that will * update the field state and re-render, i.e. when including in an `ObjectState`-typed literal that is * an mobx `useLocalObservable`/observable. * * Note that `V` will always have `null | undefined` added to it by `FieldStates`, b/c most form fields * i.e. text boxes, can always be cleared out/deleted. */ export interface FieldState { /** The key in the parent object, i.e. `firstName` in `author: { firstName: string }`. */ readonly key: string; /** The current value of the field. */ value: V; readonly originalValue: V; touched: boolean; readOnly: boolean; loading: boolean; readonly required: boolean; readonly dirty: boolean; readonly valid: boolean; readonly focused: boolean; readonly isNewEntity: boolean; rules: Rule[]; readonly errors: string[]; /** Returns a subset of V with only the changed values. Currently not observable. */ readonly changedValue: V; /** Focuses the field. Disables changes from `ObjectState.set` calls. */ focus(): void; /** Blur marks the field as touched and triggers an auto-save. */ blur(): void; /** Triggers an auto-save; the caller (i.e. useFormState) should still dirty & valid check. */ maybeAutoSave(): void; set(value: V, opts?: SetOpts): void; /** Reverts back to the original value and resets dirty/touched. */ revertChanges(): void; /** * Accepts the current changed value (if any) as the original and resets dirty/touched. * * @deprecated Use `formState.update(ackedServerValue)` instead. `commitChanges` marks all current * changes as saved, which risks discarding a user's in-flight edits. Updating from the server ack gives * form-state a field-by-field audit of which changes were successfully saved. */ commitChanges(): void; /** Creates a new FieldState with a transformation of the value, i.e. string to int, or feet to inches. */ adapt(adapter: ValueAdapter): FieldState; } /** * Allows changing a type in the formState (like a string) to a different type in the UI (like a number). * * Or doing unit of measure conversions within the same type, like from meters to feet. */ export interface ValueAdapter { /** Converts the original FieldState's value `V` into new `V2` type. */ toValue(value: V): V2; /** Converts the adapted FieldState's value `V2` back into the original `V` type. */ fromValue(value: V2): V; } /** Public options for our `set` command. */ export interface SetOpts { /** Whether this `set` should trigger an auto-save; defaults to true. */ autoSave?: boolean; } /** Internal `.set` opts for conditionally that form-state internally percolates. */ export interface InternalSetOpts extends SetOpts { /** `resetting` is the code calling `.reset()` to revert to original values. */ resetting?: boolean; /** `refreshing` is when `useFormState` sees a new value. */ refreshing?: boolean; } export interface FieldStateInternal extends FieldState { set(value: V, opts?: InternalSetOpts): void; _isIdKey: boolean; _isDeleteKey: boolean; _isReadOnlyKey: boolean; _isLocalOnly: boolean; } export declare function newValueFieldState(parentCopy: T, parentInstance: T, parentState: () => ObjectState, key: K, rules: Rule[], isIdKey: boolean, isDeleteKey: boolean, isReadOnlyKey: boolean, isLocalOnly: boolean, computed: boolean, readOnly: boolean, strictOrder: boolean, maybeAutoSave: () => void): FieldState;