formstand 0.24.0 → 0.25.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/CHANGELOG.md +76 -0
- package/README.md +1 -1
- package/dist/{createForm-BexUOCjZ.d.cts → createForm-CMVALnc3.d.cts} +1 -1
- package/dist/{createForm-BexUOCjZ.d.ts → createForm-CMVALnc3.d.ts} +1 -1
- package/dist/index.cjs +15 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -20
- package/dist/index.d.ts +36 -20
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,81 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.0 — 2026-11-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `useVariantFieldArray(form, unionPath, field)`, the array twin of
|
|
8
|
+
`useVariantField`: a `z.array` that lives in one variant of a
|
|
9
|
+
discriminated union sits at a path `useFieldArray` cannot take, since
|
|
10
|
+
`FieldPath` on a union offers only the keys every variant shares. The
|
|
11
|
+
hook binds `${unionPath}.${field}` and types the rows from the variants
|
|
12
|
+
that declare the array; `field` is a variant sub-path (`"lights"`,
|
|
13
|
+
`"spec.lights"`, or a row template for an array nested in another
|
|
14
|
+
variant array's rows), and a common-key array stays with plain
|
|
15
|
+
`useFieldArray`, which the variant hook rejects. Same return as
|
|
16
|
+
`useFieldArray`, row ids included. `createFormHooks` gains the bound
|
|
17
|
+
`use{Name}VariantFieldArray`, and the type `VariantArrayFieldPath` is
|
|
18
|
+
exported. formstand-cli emits it for arrays inside union variants.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- `createFormHooks(createForm(schema, options), name)` with the form
|
|
23
|
+
created inline collapsed every depth-typed bound hook (`useXField`,
|
|
24
|
+
`useXFieldArray`, `useXIsDirty`) to a `never` path: the inner call
|
|
25
|
+
inferred its depth from the outer call's still-unresolved depth
|
|
26
|
+
parameter, so the depth became the whole budget union. `createForm` and
|
|
27
|
+
`useForm` now take their depth from `pathDepth` alone (`NoInfer` on the
|
|
28
|
+
returned form), so the inline shape types like the const-form shape the
|
|
29
|
+
docs show, and an explicit `pathDepth` still infers its literal.
|
|
30
|
+
|
|
31
|
+
## formstand-cli 0.26.0 — 2026-11-12
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- An **array inside a union variant** generates instead of degrading to a
|
|
36
|
+
TODO, in both layouts and every kit: a `{Stem}Rows` component on
|
|
37
|
+
`useVariantFieldArray(form, unionPath, "lights")` (formstand 0.25), its
|
|
38
|
+
row leaves on the variant path (the Bound components in the single-file
|
|
39
|
+
layout, `useVariantField` on a row template in the module layout), the
|
|
40
|
+
empty item typed from the hook, and deeper lists under those rows bound
|
|
41
|
+
the same way. Under a union row item the row's own index renames to the
|
|
42
|
+
next hole for the extracted component, as nested lists already do. Still
|
|
43
|
+
a TODO: a union inside a variant, a union or tuple inside a variant
|
|
44
|
+
array's rows, and an array every variant shares (a plain path, left to
|
|
45
|
+
`useFieldArray`). Generated output with a variant array needs formstand
|
|
46
|
+
0.25 or newer.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- **Arrays of flat object rows generate as tables.** Where every row
|
|
51
|
+
field is a scalar within the path budget and none carries a component
|
|
52
|
+
override, the array renders as a table in both layouts and every kit:
|
|
53
|
+
one column per row field with
|
|
54
|
+
the label in the header (a description becomes the header's title), a
|
|
55
|
+
`{Stem}Row` component per row binding each cell from hoisted `useField`
|
|
56
|
+
hooks (`useVariantField` for an array inside a union variant) and
|
|
57
|
+
naming the control through `aria-label`, a Remove column, and the
|
|
58
|
+
array-level error plus the Add button under the table. antd's
|
|
59
|
+
data-driven `Table` gets one cell component per column. Rows holding a
|
|
60
|
+
container, scalar rows and rows with an overridden field keep the
|
|
61
|
+
cards, and the new `fields: { "<path>": { layout: "cards" } }` opts a
|
|
62
|
+
flat array back out; `layout: "table"` asserts one and errors, naming
|
|
63
|
+
the row field, where it cannot be built.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- The single-file layout's TODO for a container that still degrades inside
|
|
68
|
+
a row union's variant printed the hole-stripped naming path
|
|
69
|
+
(`"pavements.sub"`), which names no field a reader can find. It prints
|
|
70
|
+
the row template (`"pavements.${index}.sub"`), as the module layout
|
|
71
|
+
already did.
|
|
72
|
+
- Two usage walks passed the wrong budget when descending into an
|
|
73
|
+
array's rows, so anything two objects deep under a row was skipped: a
|
|
74
|
+
discriminated union there rendered its variant controls without
|
|
75
|
+
importing the prop builders they call, and a described leaf there was
|
|
76
|
+
handed a `description` prop the Bound components did not declare.
|
|
77
|
+
Both walks carry the real budget now.
|
|
78
|
+
|
|
3
79
|
## 0.24.0 — 2026-10-23
|
|
4
80
|
|
|
5
81
|
### Added
|
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ PATCH-ready payload of exactly what changed.
|
|
|
123
123
|
| Area | What's there | Docs |
|
|
124
124
|
| --- | --- | --- |
|
|
125
125
|
| Form instance | `createForm`, `setValue`/`setValues`, `reset`/`resetField`/`adoptValues`, `submit`/`handleSubmit`, `diff`/`dirtyFields`, `snapshot`/`restore`, array ops | [createForm & Form](https://scrumrot.github.io/formstand/documentation/api/) |
|
|
126
|
-
| Hooks | `useForm`, `useField`, `useFieldArray`, `useVariantField`, `useFormSelector`, `useFormValues`, the flag hooks, `createFormContext`, `createFormHooks` | [Hooks](https://scrumrot.github.io/formstand/documentation/api/hooks) |
|
|
126
|
+
| Hooks | `useForm`, `useField`, `useFieldArray`, `useVariantField`, `useVariantFieldArray`, `useFormSelector`, `useFormValues`, the flag hooks, `createFormContext`, `createFormHooks` | [Hooks](https://scrumrot.github.io/formstand/documentation/api/hooks) |
|
|
127
127
|
| Components | `TextField`, `NumberField`, `DateField`, `CheckboxField`, `SelectField`, the prop builders, `useNumberInput`, `focusField`/`focusFirstError` | [Components & bindings](https://scrumrot.github.io/formstand/documentation/api/components) |
|
|
128
128
|
| Validation | five modes plus `reValidateMode`, field-scoped passes, async refines with race handling, per-field `debounceMs` | [Validation](https://scrumrot.github.io/formstand/documentation/validation) |
|
|
129
129
|
| Utilities | `parsePath`/`getAtPath`/`setAtPath`, `validateSync`/`validateAsync`, `persistForm`, and the full type list | [Utilities & types](https://scrumrot.github.io/formstand/documentation/api/utilities) |
|
|
@@ -202,7 +202,7 @@ type Form<TSchema extends z.ZodType, D extends PathDepth = DefaultPathDepth> = R
|
|
|
202
202
|
snapshot: () => FormState<z.input<TSchema>>;
|
|
203
203
|
restore: (snapshot: FormState<z.input<TSchema>>) => void;
|
|
204
204
|
}>;
|
|
205
|
-
declare const createForm: <TSchema extends z.ZodType, D extends PathDepth = DefaultPathDepth>(schema: TSchema, options: CreateFormOptions<TSchema, D>) => Form<TSchema, D
|
|
205
|
+
declare const createForm: <TSchema extends z.ZodType, D extends PathDepth = DefaultPathDepth>(schema: TSchema, options: CreateFormOptions<TSchema, D>) => Form<TSchema, NoInfer<D>>;
|
|
206
206
|
|
|
207
207
|
export { createForm as p, emptyValueForSchema as q, flattenIssues as r, isAsyncRequiredError as s, isClearableSchema as t, shouldValidateOn as u, validateAsync as v, validateSync as w };
|
|
208
208
|
export type { ArrayFieldPath as A, BoolMap as B, CreateFormOptions as C, DefaultPathDepth as D, ErrorMap as E, Form as F, InvalidSubmitHandler as I, PathDepth as P, ReadonlyStoreApi as R, SettledFieldValidationResult as S, ValidationMode as V, FormState as a, FieldValidationResult as b, FieldPath as c, FieldValue as d, ArrayItemOf as e, FieldSnapshot as f, FieldsValidationResult as g, ResetOptions as h, SettledFieldsValidationResult as i, SettledValidationResult as j, SubmitHandler as k, SubmitOptions as l, SubmitResult as m, ValidationResult as n, ValidationTrigger as o };
|
|
@@ -202,7 +202,7 @@ type Form<TSchema extends z.ZodType, D extends PathDepth = DefaultPathDepth> = R
|
|
|
202
202
|
snapshot: () => FormState<z.input<TSchema>>;
|
|
203
203
|
restore: (snapshot: FormState<z.input<TSchema>>) => void;
|
|
204
204
|
}>;
|
|
205
|
-
declare const createForm: <TSchema extends z.ZodType, D extends PathDepth = DefaultPathDepth>(schema: TSchema, options: CreateFormOptions<TSchema, D>) => Form<TSchema, D
|
|
205
|
+
declare const createForm: <TSchema extends z.ZodType, D extends PathDepth = DefaultPathDepth>(schema: TSchema, options: CreateFormOptions<TSchema, D>) => Form<TSchema, NoInfer<D>>;
|
|
206
206
|
|
|
207
207
|
export { createForm as p, emptyValueForSchema as q, flattenIssues as r, isAsyncRequiredError as s, isClearableSchema as t, shouldValidateOn as u, validateAsync as v, validateSync as w };
|
|
208
208
|
export type { ArrayFieldPath as A, BoolMap as B, CreateFormOptions as C, DefaultPathDepth as D, ErrorMap as E, Form as F, InvalidSubmitHandler as I, PathDepth as P, ReadonlyStoreApi as R, SettledFieldValidationResult as S, ValidationMode as V, FormState as a, FieldValidationResult as b, FieldPath as c, FieldValue as d, ArrayItemOf as e, FieldSnapshot as f, FieldsValidationResult as g, ResetOptions as h, SettledFieldsValidationResult as i, SettledValidationResult as j, SubmitHandler as k, SubmitOptions as l, SubmitResult as m, ValidationResult as n, ValidationTrigger as o };
|
package/dist/index.cjs
CHANGED
|
@@ -2243,6 +2243,14 @@ function useFieldArray(form, pathArg) {
|
|
|
2243
2243
|
]
|
|
2244
2244
|
);
|
|
2245
2245
|
}
|
|
2246
|
+
|
|
2247
|
+
// src/react/useVariantFieldArray.ts
|
|
2248
|
+
function useVariantFieldArray(form, unionPath, field) {
|
|
2249
|
+
return useFieldArray(
|
|
2250
|
+
form,
|
|
2251
|
+
`${unionPath}.${field}`
|
|
2252
|
+
);
|
|
2253
|
+
}
|
|
2246
2254
|
var useFormError = (form) => react$1.useStore(
|
|
2247
2255
|
form.store,
|
|
2248
2256
|
shallow.useShallow((state) => state.errors[""])
|
|
@@ -2321,6 +2329,11 @@ var createFormHooks = (form, name) => {
|
|
|
2321
2329
|
field
|
|
2322
2330
|
);
|
|
2323
2331
|
const useBoundFieldArray = (path) => useFieldArray(structural, path);
|
|
2332
|
+
const useBoundVariantFieldArray = (unionPath, field) => useVariantFieldArray(
|
|
2333
|
+
structural,
|
|
2334
|
+
unionPath,
|
|
2335
|
+
field
|
|
2336
|
+
);
|
|
2324
2337
|
const useBoundSelector = (selector) => useFormSelector(structural, selector);
|
|
2325
2338
|
const useBoundSelectorShallow = (selector) => useFormSelectorShallow(structural, selector);
|
|
2326
2339
|
const useBoundError = () => useFormError(structural);
|
|
@@ -2340,6 +2353,7 @@ var createFormHooks = (form, name) => {
|
|
|
2340
2353
|
[`use${prefix}Field`]: useBoundField,
|
|
2341
2354
|
[`use${prefix}VariantField`]: useBoundVariantField,
|
|
2342
2355
|
[`use${prefix}FieldArray`]: useBoundFieldArray,
|
|
2356
|
+
[`use${prefix}VariantFieldArray`]: useBoundVariantFieldArray,
|
|
2343
2357
|
[`use${prefix}Selector`]: useBoundSelector,
|
|
2344
2358
|
[`use${prefix}SelectorShallow`]: useBoundSelectorShallow,
|
|
2345
2359
|
[`use${prefix}Error`]: useBoundError,
|
|
@@ -2694,6 +2708,7 @@ exports.useNumberInput = useNumberInput;
|
|
|
2694
2708
|
exports.usePersistForm = usePersistForm;
|
|
2695
2709
|
exports.useSubmitCount = useSubmitCount;
|
|
2696
2710
|
exports.useVariantField = useVariantField;
|
|
2711
|
+
exports.useVariantFieldArray = useVariantFieldArray;
|
|
2697
2712
|
exports.validateAsync = validateAsync;
|
|
2698
2713
|
exports.validateSync = validateSync;
|
|
2699
2714
|
//# sourceMappingURL=index.cjs.map
|