formstand 0.4.1 → 0.5.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 CHANGED
@@ -1,5 +1,110 @@
1
1
  # Changelog
2
2
 
3
+ ## formstand-cli Unreleased
4
+
5
+ - Generated array hooks drop the explicit item type
6
+ (`useFieldArray(form, "items")`): formstand ≥ 0.5 infers it from the
7
+ schema through the path — and rejects the old explicit spelling on typed
8
+ forms. On formstand 0.4 the generated code still compiles, with untyped
9
+ items.
10
+ - Generated shadcn output defines one `ariaInvalid` helper (used by the
11
+ inlined adapters and the select trigger) instead of repeating the ternary
12
+ four times, and the generated `FieldError` computes the message once —
13
+ cosmetic; runtime behavior unchanged. Internally the MUI and shadcn
14
+ backends now share their emitted snippets (error helper, `BoundFieldProps`,
15
+ the leaf switch), so the generators can't drift.
16
+
17
+ ## 0.5.0 — 2026-07-09
18
+
19
+ ### Breaking
20
+
21
+ - `useFieldArray` infers the item type from a `Form<TSchema>` and a typed
22
+ path — `useFieldArray(form, "users")` (and template paths like
23
+ `` `albums.${index}.tracks` ``) needs no type argument, and `push`/`insert`
24
+ are typed against the schema's item. Consequently the old explicit
25
+ `useFieldArray<TItem>(form, path)` spelling is a **compile error on typed
26
+ forms** (drop the generic); it remains the way to bind schema-less
27
+ `FieldFormApi` forms, where there is nothing to infer from. A non-array
28
+ path types the items as `never`; a typo'd path is rejected against the
29
+ full `FieldPath` union, like `useField`. Path selectors return
30
+ `UseFieldArrayReturn<unknown>` (dynamic paths carry no type), also like
31
+ `useField`.
32
+
33
+ ### Fixed (site only)
34
+
35
+ - The deployed playground bundled two copies of React (the formstand alias
36
+ reaches outside the examples package, so its imports resolved the repo
37
+ root's copy) — every tab crashed at startup with a null hooks
38
+ dispatcher. The examples build now dedupes react/zustand/zod and CI
39
+ asserts the bundle holds exactly one React.
40
+
41
+ ### Docs & examples (no package changes)
42
+
43
+ - The playground demos bind shadcn's `Input`/`Textarea` with the library's
44
+ own exported `textInputProps`/`numberInputProps` — the shadcn adapter now
45
+ covers only the Radix dialect, and the "field has an error" predicate
46
+ lives once in `examples/src/fieldErrors.ts` (shared by both adapters).
47
+ - The copy-in shadcn kit is trimmed to what the demos render (Badge/Button
48
+ variants, dead peer-disabled label classes) and every component exports a
49
+ `Readonly` props type.
50
+
51
+ ## formstand-cli 0.2.1 — 2026-07-09
52
+
53
+ ### Fixed
54
+
55
+ - Leaf-free schemas (no scalar fields anywhere, e.g. an object of empty
56
+ objects) no longer generate non-compiling output in the `mui` and
57
+ `shadcn` backends — the emitted `BoundFieldProps` type referenced
58
+ `FieldFormApi` without importing it. All three backends now have a
59
+ leaf-free typecheck test.
60
+ - The shadcn backend's generated output is additionally typechecked in CI
61
+ against the repo's real Radix-based components (not just the structural
62
+ stub), so a shadcn/Radix prop-contract change fails our suite instead of
63
+ the consumer's build.
64
+
65
+ ### Docs & examples (no library package changes)
66
+
67
+ - Playground: the page chrome stylesheet is unlayered again — cascade
68
+ layers can't be transpiled, so pre-15.4 WebKit (the es2019 target's
69
+ audience) was losing every tab's styling; its selectors are class-scoped,
70
+ so the shadcn utilities are unaffected. The layer-order statement now
71
+ pins Tailwind's canonical `components` slot below `utilities`.
72
+ - shadcn kit: sliders take an `aria-label` routed to the Radix Thumb (the
73
+ Root is a `<span>`, so `htmlFor`/`id` never named it); radio-group items
74
+ show error styling via `group-aria-invalid` (Radix doesn't propagate the
75
+ Root's `aria-invalid` to items); the Team demo's rows are memoized with
76
+ stable handlers so keystrokes in one row stop re-rendering the rest.
77
+ - Publish workflow: `--provenance` is explicit again (fail-closed — the
78
+ automatic path silently skips attestation when conditions aren't met) and
79
+ the Node pin is `>=24.8`, the first line whose bundled npm meets trusted
80
+ publishing's 11.5.1 floor. CI asserts the root and examples lockfiles
81
+ agree on the deduped UI packages, so the smoke test can't silently
82
+ certify a different build than the deployed playground.
83
+
84
+ ## formstand-cli 0.2.0 — 2026-07-08
85
+
86
+ ### Added
87
+
88
+ - `--ui shadcn`: generates forms against [shadcn/ui](https://ui.shadcn.com/)
89
+ conventions — components imported from the app's `@/components/ui/*` alias
90
+ (what `npx shadcn add` scaffolds), an inlined adapter speaking the Radix
91
+ dialect (`onCheckedChange`/`onValueChange`, dropdown-close as the blur
92
+ trigger), and `aria-invalid` error styling with a message line. Generated
93
+ output is typechecked in CI against the library source and a structural
94
+ stub of the shadcn components, like the other backends.
95
+ - `emitShadcnForm` joins the programmatic API.
96
+
97
+ ### Docs & examples (no library package changes)
98
+
99
+ - Four shadcn/ui playground demos (Signup, Checkout, Settings, Team) plus
100
+ the formstand→shadcn adapter pattern they showcase —
101
+ `examples/src/shadcn/shadcnAdapter.ts` bridges `useField` to both native
102
+ inputs and the Radix-based widgets (Checkbox, Switch, Select, Slider,
103
+ RadioGroup).
104
+ - The playground carries its own copy-in shadcn component kit under a
105
+ scoped Tailwind 4 setup (no preflight; the plain-CSS and MUI demos are
106
+ untouched).
107
+
3
108
  ## 0.4.1 — 2026-07-08
4
109
 
5
110
  ### Fixed
package/dist/index.cjs CHANGED
@@ -1429,7 +1429,7 @@ var reconcileIds = (prev, nextItems) => {
1429
1429
  counter: prev.counter + Math.max(0, unmatched - leftover.length)
1430
1430
  };
1431
1431
  };
1432
- var useFieldArray = (form, pathArg) => {
1432
+ function useFieldArray(form, pathArg) {
1433
1433
  const path = react$1.useStore(
1434
1434
  form.store,
1435
1435
  (state) => typeof pathArg === "function" ? pathArg(state) : pathArg
@@ -1494,7 +1494,7 @@ var useFieldArray = (form, pathArg) => {
1494
1494
  }),
1495
1495
  [fields, items, error, push, remove, insert, move, swap]
1496
1496
  );
1497
- };
1497
+ }
1498
1498
 
1499
1499
  exports.CheckboxField = CheckboxField;
1500
1500
  exports.NumberField = NumberField;