@homebound/form-state 2.33.0 → 3.0.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.
Files changed (57) hide show
  1. package/dist/index.d.ts +437 -9
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +1109 -14
  4. package/dist/index.js.map +1 -0
  5. package/package.json +32 -35
  6. package/dist/FormStateApp.d.ts +0 -5
  7. package/dist/FormStateApp.js +0 -54
  8. package/dist/FormStateApp.test.d.ts +0 -1
  9. package/dist/FormStateApp.test.js +0 -26
  10. package/dist/config.d.ts +0 -78
  11. package/dist/config.js +0 -2
  12. package/dist/configBuilders.d.ts +0 -67
  13. package/dist/configBuilders.js +0 -115
  14. package/dist/configBuilders.test.d.ts +0 -1
  15. package/dist/configBuilders.test.js +0 -65
  16. package/dist/fields/deepEquals.d.ts +0 -7
  17. package/dist/fields/deepEquals.js +0 -53
  18. package/dist/fields/fragmentField.d.ts +0 -4
  19. package/dist/fields/fragmentField.js +0 -58
  20. package/dist/fields/listField.d.ts +0 -11
  21. package/dist/fields/listField.js +0 -355
  22. package/dist/fields/objectField.d.ts +0 -63
  23. package/dist/fields/objectField.js +0 -277
  24. package/dist/fields/valueField.d.ts +0 -81
  25. package/dist/fields/valueField.js +0 -244
  26. package/dist/formState.stories.d.ts +0 -4
  27. package/dist/formState.stories.js +0 -12
  28. package/dist/formState.test.d.ts +0 -11
  29. package/dist/formState.test.js +0 -2109
  30. package/dist/formStateDomain.d.ts +0 -47
  31. package/dist/formStateDomain.js +0 -28
  32. package/dist/mobx-behavior.test.d.ts +0 -1
  33. package/dist/mobx-behavior.test.js +0 -51
  34. package/dist/proxies.d.ts +0 -5
  35. package/dist/proxies.js +0 -20
  36. package/dist/rules.d.ts +0 -10
  37. package/dist/rules.js +0 -11
  38. package/dist/setupTests.d.ts +0 -1
  39. package/dist/setupTests.js +0 -15
  40. package/dist/stackoverlfow.d.ts +0 -17
  41. package/dist/stackoverlfow.js +0 -17
  42. package/dist/temporal.d.ts +0 -6
  43. package/dist/temporal.js +0 -34
  44. package/dist/temporal.test.d.ts +0 -1
  45. package/dist/temporal.test.js +0 -97
  46. package/dist/useFormState.d.ts +0 -82
  47. package/dist/useFormState.js +0 -158
  48. package/dist/useFormState.test.d.ts +0 -1
  49. package/dist/useFormState.test.js +0 -787
  50. package/dist/useFormStates.d.ts +0 -68
  51. package/dist/useFormStates.js +0 -101
  52. package/dist/useFormStates.test.d.ts +0 -1
  53. package/dist/useFormStates.test.js +0 -223
  54. package/dist/utils.d.ts +0 -52
  55. package/dist/utils.js +0 -198
  56. package/dist/utils.test.d.ts +0 -1
  57. package/dist/utils.test.js +0 -102
package/dist/index.d.ts CHANGED
@@ -1,9 +1,437 @@
1
- export { f } from "./configBuilders";
2
- export { type FragmentField } from "./fields/fragmentField";
3
- export { type ListFieldState } from "./fields/listField";
4
- export { createObjectState, type Fragment, type ObjectState, fragment } from "./fields/objectField";
5
- export { type FieldState, type ValueAdapter } from "./fields/valueField";
6
- export { required, type Rule } from "./rules";
7
- export { type FormObjectState, useFormState } from "./useFormState";
8
- export { useFormStates } from "./useFormStates";
9
- export { type ObjectConfig } from "./config";
1
+ import { Temporal } from "temporal-polyfill";
2
+ //#region src/fields/fragmentField.d.ts
3
+ interface FragmentField<V> {
4
+ value: V;
5
+ }
6
+ //#endregion
7
+ //#region src/rules.d.ts
8
+ /** A validation rule, given the value and name, return the error string if valid, or undefined if valid. */
9
+ type Rule<V> = (opts: {
10
+ value: V;
11
+ key: string;
12
+ originalValue: V;
13
+ }) => string | undefined;
14
+ /** A rule that validates `value` is not `undefined`, `null`, or empty string. */
15
+ export declare const required: <V>({ value: v }: {
16
+ value: V;
17
+ }) => string | undefined;
18
+ //#endregion
19
+ //#region src/fields/valueField.d.ts
20
+ /**
21
+ * Form state for a primitive field in the form, i.e. its value but also touched/validation/etc. state.
22
+ *
23
+ * This API also provides hooks for form elements to call into, i.e. `blur()` and `set(...)` that will
24
+ * update the field state and re-render, i.e. when including in an `ObjectState`-typed literal that is
25
+ * an mobx `useLocalObservable`/observable.
26
+ *
27
+ * Note that `V` will always have `null | undefined` added to it by `FieldStates`, b/c most form fields
28
+ * i.e. text boxes, can always be cleared out/deleted.
29
+ */
30
+ interface FieldState<V> {
31
+ /** The key in the parent object, i.e. `firstName` in `author: { firstName: string }`. */
32
+ readonly key: string;
33
+ /** The current value of the field. */
34
+ value: V;
35
+ readonly originalValue: V;
36
+ touched: boolean;
37
+ readOnly: boolean;
38
+ loading: boolean;
39
+ readonly required: boolean;
40
+ readonly dirty: boolean;
41
+ readonly valid: boolean;
42
+ readonly focused: boolean;
43
+ readonly isNewEntity: boolean;
44
+ rules: Rule<V>[];
45
+ readonly errors: string[];
46
+ /** Returns a subset of V with only the changed values. Currently not observable. */
47
+ readonly changedValue: V;
48
+ /** Focuses the field. Disables changes from `ObjectState.set` calls. */
49
+ focus(): void;
50
+ /** Blur marks the field as touched and triggers an auto-save. */
51
+ blur(): void;
52
+ /** Triggers an auto-save; the caller (i.e. useFormState) should still dirty & valid check. */
53
+ maybeAutoSave(): void;
54
+ set(value: V, opts?: SetOpts): void;
55
+ /** Reverts back to the original value and resets dirty/touched. */
56
+ revertChanges(): void;
57
+ /**
58
+ * Accepts the current changed value (if any) as the original and resets dirty/touched.
59
+ *
60
+ * @deprecated Use `formState.update(ackedServerValue)` instead. `commitChanges` marks all current
61
+ * changes as saved, which risks discarding a user's in-flight edits. Updating from the server ack gives
62
+ * form-state a field-by-field audit of which changes were successfully saved.
63
+ */
64
+ commitChanges(): void;
65
+ /** Creates a new FieldState with a transformation of the value, i.e. string to int, or feet to inches. */
66
+ adapt<V2>(adapter: ValueAdapter<V, V2>): FieldState<V2>;
67
+ }
68
+ /**
69
+ * Allows changing a type in the formState (like a string) to a different type in the UI (like a number).
70
+ *
71
+ * Or doing unit of measure conversions within the same type, like from meters to feet.
72
+ */
73
+ interface ValueAdapter<V, V2 = V> {
74
+ /** Converts the original FieldState's value `V` into new `V2` type. */
75
+ toValue(value: V): V2;
76
+ /** Converts the adapted FieldState's value `V2` back into the original `V` type. */
77
+ fromValue(value: V2): V;
78
+ }
79
+ /** Public options for our `set` command. */
80
+ interface SetOpts {
81
+ /** Whether this `set` should trigger an auto-save; defaults to true. */
82
+ autoSave?: boolean;
83
+ }
84
+ //#endregion
85
+ //#region src/fields/listField.d.ts
86
+ /** Form state for list of children, i.e. `U` is a `Book` in a form with a `books: Book[]`. */
87
+ interface ListFieldState<U> extends FieldState<U[]> {
88
+ readonly rows: ReadonlyArray<ObjectState<U>>;
89
+ add(value: U, index?: number): void;
90
+ remove(indexOrValue: number | U): void;
91
+ }
92
+ //#endregion
93
+ //#region src/temporal.d.ts
94
+ type SupportedTemporal = Temporal.PlainDate | Temporal.ZonedDateTime;
95
+ //#endregion
96
+ //#region src/useFormState.d.ts
97
+ type Query<I> = {
98
+ data: I;
99
+ loading: boolean;
100
+ error?: any;
101
+ };
102
+ type InputAndMap<T, I> = {
103
+ input: I;
104
+ map?: (input: Exclude<I, null | undefined>) => T;
105
+ ifUndefined?: T;
106
+ onlyOnce?: boolean;
107
+ };
108
+ type QueryAndMap<T, I> = {
109
+ query: Query<I>;
110
+ map: (input: Exclude<I, null | undefined>) => T;
111
+ ifUndefined?: T;
112
+ };
113
+ /**
114
+ * The opts has for `useFormState`.
115
+ *
116
+ * @typeparam T the form type, which is usually as close as possible to your *GraphQL input*
117
+ * @typeparam I the *form input* type, which is usually the *GraphQL output* type, i.e. the type of the response from your GraphQL query
118
+ */
119
+ type UseFormStateOpts<T, I> = {
120
+ /** The form configuration, should be a module-level const or useMemo'd. */
121
+ config: ObjectConfig<T>;
122
+ /**
123
+ * Provides the form's initial value.
124
+ *
125
+ * User's can either:
126
+ *
127
+ * - Provide no initial value (don't set `init` at all)
128
+ * - Provide an initial value that already matches the form type `T` (i.e. set `init: data`)
129
+ * - Provide an initial value from an object that _almost_ matches the form type `T`,
130
+ * but needs to be mapped from it's input type `I` to the form type
131
+ * (i.e. set `init: { input: data, map: (data) => ...}`).
132
+ *
133
+ * The value of using the 3rd option is that: a) we internally `useMemo` on the identity of the
134
+ * `init.input` (i.e. a response from an Apollo hook) and don't require the `map` function
135
+ * to have a stable identity, and also b) we will null-check/undefined-check `init.input` and
136
+ * only call `init.map` if it's set, otherwise we'll use `init.ifDefined` or `{}`, saving you
137
+ * from having to null check within your `init.map` function.
138
+ */
139
+ init?: InputAndMap<T, I> | QueryAndMap<T, I>;
140
+ /**
141
+ * A hook to add custom, cross-field validation rules that can be difficult to setup directly in the config DSL.
142
+ *
143
+ * Does not need to be stable/useMemo'd.
144
+ */
145
+ addRules?: (state: ObjectState<T>) => void;
146
+ /** Whether the form should be read only, when changed it won't re-create the whole form. */
147
+ readOnly?: boolean;
148
+ /**
149
+ * Whether the form is loading.
150
+ *
151
+ * Note that we also will infer loading from `init.input === undefined` or `init.query.loading`,
152
+ * so you only need to set this directly if you're not using either of those conventions.
153
+ */
154
+ loading?: boolean;
155
+ /**
156
+ * Fired when the form should auto-save, i.e. after a) blur and b) all fields are valid.
157
+ *
158
+ * Does not need to be stable/useMemo'd.
159
+ */
160
+ autoSave?: (state: ObjectState<T>) => Promise<unknown>;
161
+ };
162
+ type FormObjectState<T, I> = ObjectState<T> & {
163
+ /**
164
+ * Refreshes the form with a server-acked value, i.e. `form.update(savedAuthor)`.
165
+ *
166
+ * This is intended for save callbacks that need `form.dirty` to become `false` immediately, before the
167
+ * normal query/cache refresh has a chance to rerender `useFormState`. Pass the value returned by the
168
+ * server so the form can map it through `init.map` and then do a field-by-field refresh of only the
169
+ * changes the server has acknowledged.
170
+ */
171
+ update(input: Exclude<I, null | undefined>): void;
172
+ };
173
+ /**
174
+ * Creates a formState instance for editing in a form.
175
+ */
176
+ export declare function useFormState<T, I>(opts: UseFormStateOpts<T, I>): FormObjectState<T, I>;
177
+ //#endregion
178
+ //#region src/utils.d.ts
179
+ type Builtin = Date | Function | SupportedTemporal | Uint8Array | string | number | boolean;
180
+ type OmitIf<Base, Condition> = Pick<Base, { [Key in keyof Base]: Base[Key] extends Condition ? never : Key; }[keyof Base]>;
181
+ //#endregion
182
+ //#region src/fields/objectField.d.ts
183
+ /**
184
+ * Wraps a given input/on-the-wire type `T` for editing in a form.
185
+ *
186
+ * We basically mimic every field in `T` (i.e. `firstName`, `lastName`, etc.) but decorate them
187
+ * with form-specific state like `touched`, `dirty`, `errors`, etc.
188
+ *
189
+ * The intent is that, after ensuring all fields are `valid`/etc., callers can take the
190
+ * result of this `objectState.value` (or `objectState.originalValue` for the non-proxy version) and
191
+ * have exactly the on-the-wire type `T` that they need to submit to the backend, without doing the
192
+ * manual mapping of "data that was in the form controls" into "data that the backend wants".
193
+ *
194
+ * Note that this can be hierarchical by having a field of `ListFieldState` that
195
+ * themselves each wrap an `ObjectState`, i.e.:
196
+ *
197
+ * ```
198
+ * ObjectState for author
199
+ * - firstName: FieldState
200
+ * - lastName: FieldState
201
+ * - rows: ListFieldState
202
+ * - [0]: ObjectState for book 1
203
+ * - title: FieldState
204
+ * - [1]: ObjectState for book 2
205
+ * - title: FieldState
206
+ * ```
207
+ */
208
+ type ObjectState<T> = FieldStates<T> & FieldState<T> & {
209
+ /** Sets the state of fields in `state`. */
210
+ set(state: Partial<T>, opts?: SetOpts): void;
211
+ /** Returns whether the object can be saved, i.e. is valid, but also as a side-effect marks touched. */
212
+ canSave(): boolean;
213
+ };
214
+ declare const fragmentSym: unique symbol;
215
+ type Fragment<V> = V & {
216
+ [fragmentSym]: true;
217
+ };
218
+ export declare function fragment<V>(value: V): Fragment<V>;
219
+ /** For a given input type `T`, decorate each field into the "field state" type that holds our form-relevant state, i.e. valid/touched/etc. */
220
+ type FieldStates<T> = { [K in keyof T]-?: T[K] extends Fragment<infer V> ? FragmentField<V> : T[K] extends Array<infer U> | null | undefined ? [U] extends [Builtin] ? FieldState<T[K]> : ListFieldState<U> : T[K] extends Builtin | null | undefined ? FieldState<T[K]> : ObjectState<T[K]>; };
221
+ /**
222
+ * Creates a new `ObjectState` for a given form object `T` given config rules in `config`.
223
+ *
224
+ * The returned `ObjectState` can be used in a mobx `useLocalObservable` to drive an
225
+ * interactive form that tracks the current valid/touched/etc. state of both each
226
+ * individual fields as well as the top-level form/object itself.
227
+ */
228
+ export declare function createObjectState<T>(config: ObjectConfig<T>, instance: T, opts?: {
229
+ maybeAutoSave?: () => void;
230
+ }): ObjectState<T>;
231
+ //#endregion
232
+ //#region src/config.d.ts
233
+ /**
234
+ * Config rules for each field in `T` that we're editing in a form.
235
+ *
236
+ * Basically every field is either a value/primitive or a list, and this `ObjectConfig` lets
237
+ * the caller define field-specific behavior, i.e. validation rules.
238
+ */
239
+ type ObjectConfig<T> = { [P in keyof OmitIf<T, Function>]: T[P] extends Fragment<infer V> ? FragmentFieldConfig : T[P] extends Array<infer U> | null | undefined ? U extends Builtin ? ValueFieldConfig<T[P]> : ListFieldConfig<U> : ValueFieldConfig<T[P]> | ObjectFieldConfig<T[P]>; };
240
+ /** Field configuration for an opaque value that we don't actually want to include. */
241
+ type FragmentFieldConfig = {
242
+ type: "fragment";
243
+ };
244
+ /** Field configuration for primitive values, i.e. strings/numbers/Dates/user-defined types. */
245
+ type ValueFieldConfig<V> = {
246
+ type: "value";
247
+ rules?: Rule<V | null | undefined>[];
248
+ /**
249
+ * If true, marks this field as the id, which will be used for things like "always include in changedValue".
250
+ *
251
+ * Defaults to true for fields named `id`.
252
+ */
253
+ isIdKey?: boolean;
254
+ /** If true, and this value is used on an entity in a list, the entity won't count towards the list validity. */
255
+ isDeleteKey?: boolean;
256
+ /** If true, the entity that contains this value will be treated as read only. */
257
+ isReadOnlyKey?: boolean;
258
+ /** If true, we ignore field in dirty checks. */
259
+ isLocalOnly?: boolean;
260
+ /**
261
+ * Marks a field as being backed by a mobx class computed field.
262
+ *
263
+ * Note that it might still be settable (some computed have setters), but we do
264
+ * exclude from the `reset` operation, i.e. we assume resetting other non-computed fields
265
+ * will effectively reset this field as well.
266
+ */
267
+ computed?: boolean;
268
+ /** Marks a field as being initially read-only, i.e. `field.readOnly = true/false` can change this default. */
269
+ readOnly?: boolean;
270
+ /** Marks an array field to be order agnostic when determining changed/dirty states, defaults true. */
271
+ strictOrder?: false;
272
+ };
273
+ /** Field configuration for list values, i.e. `U` is `Book` in a form with `books: Book[]`. */
274
+ type ListFieldConfig<U> = {
275
+ type: "list";
276
+ /** Rules that can run on the full list of children. */
277
+ rules?: Rule<readonly ObjectState<U>[]>[];
278
+ /** Config for each child's form state, i.e. each book. */
279
+ config: ObjectConfig<U>;
280
+ /**
281
+ * What the server-side update behavior is for this collection.
282
+ *
283
+ * When exhaustive, we include all rows in `changedValue` so that we
284
+ * don't orhan unchanged rows.
285
+ *
286
+ * When incremental, we only include changed rows in `changedValue`.
287
+ *
288
+ * When deep-exhaustive, we include all rows in `changedValue` and also
289
+ * all fields in the child entities, i.e. not just placeholder `{ id: "b:1" }`
290
+ * values for otherwise-unchanged children.
291
+ *
292
+ * Defaults to `exhaustive` b/c that is the safest and also Joist's
293
+ * default behavior.
294
+ */
295
+ update?: "exhaustive" | "incremental" | "deep-exhaustive";
296
+ /** Set to not consider the order of the list when evaluating changed/dirty states, defaults true. */
297
+ strictOrder?: false;
298
+ };
299
+ type ObjectFieldConfig<U> = {
300
+ type: "object";
301
+ /** Marks an object as a reference, which means we'll only include it's `id` in `changedValue` output. */
302
+ reference?: boolean;
303
+ /** Config for the child's form state, i.e. each book. */
304
+ config: ObjectConfig<U>;
305
+ };
306
+ //#endregion
307
+ //#region src/configBuilders.d.ts
308
+ /**
309
+ * Provides a Zod-ish API for building form configs.
310
+ */
311
+ export declare const f: {
312
+ /** Creates the top-level config for a form, like an author or book. */
313
+ config<T>(fields: ObjectConfigBuilderFields<T>): ObjectConfig<T>;
314
+ /** Creates the config DSL for an object, like an author or book. */
315
+ object<T>(fields: ObjectConfigBuilderFields<T>): ObjectConfigBuilder<T>;
316
+ /** Creates the config DSL for an list of objects, like an author's list of books. */
317
+ list<U>(fields: ObjectConfigBuilderFields<U>): ListFieldConfigBuilder<U>;
318
+ /** Creates the config DSL for a primitive value, like a first name or phone number. */
319
+ value<V>(): ValueFieldConfigBuilder<V>;
320
+ /** A shortcut for creating a child object with a single `id` key. */
321
+ reference<V extends {
322
+ id?: unknown;
323
+ }>(fields?: ObjectConfigBuilderFields<V>): ObjectConfigBuilder<V>;
324
+ /** A shorthand for creating a computed value. */
325
+ computed<V>(): ValueFieldConfigBuilder<V>;
326
+ };
327
+ /**
328
+ * Defines the fields that should be passed into `f.object({ ... })` for fhe form type `T`.
329
+ *
330
+ * This is basically a map of `key` in `T` to `f.value()`, `f.list()`, or `f.object()`
331
+ * DSL objects that define the runtime structure/fields of the form.
332
+ */
333
+ type ObjectConfigBuilderFields<T> = { [P in keyof OmitIf<T, Function>]: T[P] extends Fragment<infer V> ? FragmentFieldConfigBuilder : T[P] extends Array<infer U> | null | undefined ? U extends Builtin ? ValueFieldConfigBuilder<T[P]> : ListFieldConfigBuilder<U> : ValueFieldConfigBuilder<T[P]> | ObjectConfigBuilder<T[P]>; };
334
+ interface FragmentFieldConfigBuilder {
335
+ build(): FragmentFieldConfig;
336
+ }
337
+ /** Provides a fluent DSL for building up an object's config. */
338
+ declare class ObjectConfigBuilder<T> {
339
+ private config;
340
+ constructor(fields: ObjectConfigBuilderFields<T>);
341
+ ref(): this;
342
+ build(): ObjectFieldConfig<T>;
343
+ }
344
+ /** Provides a fluent DSL for building up a value's config. */
345
+ declare class ValueFieldConfigBuilder<V> {
346
+ private config;
347
+ /** Marks the field as required. */
348
+ req(): this;
349
+ /** Marks the field as read only. */
350
+ readOnly(): this;
351
+ /** Marks the field as local only. */
352
+ localOnly(): this;
353
+ /** Appends `rules` to the field's validation rules. */
354
+ rules(rules: Rule<V | null | undefined>[]): this;
355
+ /** Marks the field as computed. */
356
+ computed(): this;
357
+ build(): ValueFieldConfig<V>;
358
+ }
359
+ /** Provides a fluent DSL for building up a list's config. */
360
+ declare class ListFieldConfigBuilder<U> {
361
+ private config;
362
+ constructor(fields: ObjectConfigBuilderFields<U>);
363
+ /** Appends `rule` to the field's validation rules. */
364
+ rule(rule: Rule<readonly ObjectState<U>[]>): this;
365
+ /** Appends `rules` to the field's validation rules. */
366
+ rules(rules: Rule<readonly ObjectState<U>[]>[]): this;
367
+ build(): ListFieldConfig<U>;
368
+ }
369
+ //#endregion
370
+ //#region src/useFormStates.d.ts
371
+ /**
372
+ * The opts has for `useFormStates`.
373
+ *
374
+ * @typeparam T the form type, which is usually as close as possible to your *GraphQL input*
375
+ * @typeparam I the *form input* type, which is usually the *GraphQL output* type, i.e. the type of the response from your GraphQL query
376
+ */
377
+ type UseFormStatesOpts<T, I> = {
378
+ /**
379
+ * The config to use for each form state.
380
+ *
381
+ * Should be stable/useMemo'd.
382
+ */
383
+ config: ObjectConfig<T>;
384
+ /**
385
+ * Fired for each individual `ObjectState` when it's had a value change.
386
+ *
387
+ * Does not need to be stable/useMemo'd.
388
+ */
389
+ autoSave?: (state: ObjectState<T>) => Promise<void>;
390
+ /**
391
+ * A hook to add custom, cross-field validation rules that can be difficult to setup directly in the config DSL.
392
+ *
393
+ * This will be called once-per `ObjectState` instance, and so is effectively a `useEffect` hook with
394
+ * a `[config, objectState]` dependency.
395
+ *
396
+ * Does not need to be stable/useMemo'd.
397
+ */
398
+ addRules?: (state: ObjectState<T>) => void;
399
+ /**
400
+ * Given an input to `getFormState`, returns the identity value that we'll cache that value's form state on.
401
+ *
402
+ * Does not need to be stable/useMemo'd.
403
+ */
404
+ getId: (v: I) => string;
405
+ /**
406
+ * Maps an input to `getFormState` to the actual form shape `T`.
407
+ *
408
+ * Does not need to be stable/useMemo'd.
409
+ */
410
+ map?: (input: Exclude<I, null | undefined>) => T;
411
+ /**
412
+ * Sets all `ObjectState`s to readOnly.
413
+ */
414
+ readOnly?: boolean;
415
+ };
416
+ type UseFormStatesHook<T, I> = {
417
+ getFormState: (input: I, opts?: {
418
+ readOnly?: boolean;
419
+ }) => ObjectState<T>;
420
+ };
421
+ /**
422
+ * A hook to manage many "mini-forms" on a single page, typically one form per row
423
+ * in a table.
424
+ *
425
+ * This hook basically provides the page/table with a cache, so each table row naively ask "what's
426
+ * the form state for this given row's data?" and get back a new-or-existing `ObjectState` instance
427
+ * that, if already existing, still has any of the user's WIP changes.
428
+ *
429
+ * Each mini-form/row can have its own autoSave calls, independent of the other rows.
430
+ *
431
+ * @typeparam T the form type, which is usually as close as possible to your *GraphQL input*
432
+ * @typeparam I the *form input* type, which is usually the *GraphQL output* type, i.e. the type of the response from your GraphQL query
433
+ */
434
+ export declare function useFormStates<T, I = T>(opts: UseFormStatesOpts<T, I>): UseFormStatesHook<T, I>;
435
+ //#endregion
436
+ export type { FieldState, FormObjectState, Fragment, FragmentField, ListFieldState, ObjectConfig, ObjectState, Rule, ValueAdapter };
437
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/fields/fragmentField.ts","../src/rules.ts","../src/fields/valueField.ts","../src/fields/listField.ts","../src/temporal.ts","../src/useFormState.ts","../src/utils.ts","../src/fields/objectField.ts","../src/config.ts","../src/configBuilders.ts","../src/useFormStates.ts"],"mappings":"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"}