torch-glare 2.5.0 → 2.5.2

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 (79) hide show
  1. package/apps/lib/components/DataViews/filters/filters.tsx +7 -11
  2. package/apps/lib/components/FormBuilder/context.ts +8 -25
  3. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +1 -1
  4. package/apps/lib/components/FormBuilder/form-builder.tsx +32 -172
  5. package/apps/lib/components/FormBuilder/index.ts +0 -4
  6. package/apps/lib/components/FormBuilder/types.ts +6 -16
  7. package/apps/lib/components/FormRenderer/FormDrawer.tsx +2 -2
  8. package/apps/lib/components/FormRenderer/detail.tsx +6 -6
  9. package/apps/lib/components/FormRenderer/form-renderer.tsx +155 -35
  10. package/apps/lib/components/{FormBuilder → FormRenderer}/header.tsx +12 -25
  11. package/apps/lib/components/FormRenderer/index.ts +4 -0
  12. package/apps/lib/components/FormRenderer/section.tsx +39 -0
  13. package/apps/lib/components/{FormBuilder → FormRenderer}/stepper.tsx +47 -19
  14. package/apps/lib/components/FormRenderer/types.ts +6 -6
  15. package/apps/lib/registry.json +62 -3
  16. package/apps/lib/tsconfig.tsbuildinfo +1 -1
  17. package/dist/bin/index.js +8 -4
  18. package/dist/bin/index.js.map +1 -1
  19. package/dist/src/commands/add.d.ts +3 -2
  20. package/dist/src/commands/add.d.ts.map +1 -1
  21. package/dist/src/commands/add.js +27 -35
  22. package/dist/src/commands/add.js.map +1 -1
  23. package/dist/src/commands/hook.d.ts.map +1 -1
  24. package/dist/src/commands/hook.js +23 -13
  25. package/dist/src/commands/hook.js.map +1 -1
  26. package/dist/src/commands/init.d.ts.map +1 -1
  27. package/dist/src/commands/init.js +6 -2
  28. package/dist/src/commands/init.js.map +1 -1
  29. package/dist/src/commands/layout.d.ts.map +1 -1
  30. package/dist/src/commands/layout.js +23 -13
  31. package/dist/src/commands/layout.js.map +1 -1
  32. package/dist/src/commands/provider.d.ts.map +1 -1
  33. package/dist/src/commands/provider.js +22 -12
  34. package/dist/src/commands/provider.js.map +1 -1
  35. package/dist/src/commands/utils.d.ts.map +1 -1
  36. package/dist/src/commands/utils.js +21 -28
  37. package/dist/src/commands/utils.js.map +1 -1
  38. package/dist/src/shared/copyComponentsRecursively.d.ts +5 -3
  39. package/dist/src/shared/copyComponentsRecursively.d.ts.map +1 -1
  40. package/dist/src/shared/copyComponentsRecursively.js +5 -6
  41. package/dist/src/shared/copyComponentsRecursively.js.map +1 -1
  42. package/dist/src/shared/getDependenciesAndInstallNestedComponents.js +1 -1
  43. package/dist/src/shared/getDependenciesAndInstallNestedComponents.js.map +1 -1
  44. package/dist/src/shared/installDependencies.d.ts +16 -1
  45. package/dist/src/shared/installDependencies.d.ts.map +1 -1
  46. package/dist/src/shared/installDependencies.js +41 -21
  47. package/dist/src/shared/installDependencies.js.map +1 -1
  48. package/dist/src/shared/installFromPlan.d.ts +23 -0
  49. package/dist/src/shared/installFromPlan.d.ts.map +1 -0
  50. package/dist/src/shared/installFromPlan.js +77 -0
  51. package/dist/src/shared/installFromPlan.js.map +1 -0
  52. package/dist/src/shared/resolveEntry.d.ts +21 -0
  53. package/dist/src/shared/resolveEntry.d.ts.map +1 -0
  54. package/dist/src/shared/resolveEntry.js +54 -0
  55. package/dist/src/shared/resolveEntry.js.map +1 -0
  56. package/dist/src/shared/suggestOtherCommand.d.ts +8 -0
  57. package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -0
  58. package/dist/src/shared/suggestOtherCommand.js +34 -0
  59. package/dist/src/shared/suggestOtherCommand.js.map +1 -0
  60. package/dist/src/shared/tailwindInit.d.ts +3 -1
  61. package/dist/src/shared/tailwindInit.d.ts.map +1 -1
  62. package/dist/src/shared/tailwindInit.js +3 -1
  63. package/dist/src/shared/tailwindInit.js.map +1 -1
  64. package/dist/src/shared/wireStylesheet.d.ts +32 -0
  65. package/dist/src/shared/wireStylesheet.d.ts.map +1 -0
  66. package/dist/src/shared/wireStylesheet.js +92 -0
  67. package/dist/src/shared/wireStylesheet.js.map +1 -0
  68. package/dist/src/types/main.d.ts +6 -0
  69. package/dist/src/types/main.d.ts.map +1 -1
  70. package/docs/components/form-builder.md +62 -88
  71. package/docs/components/form-renderer.md +61 -25
  72. package/docs/components/form-summary.md +18 -3
  73. package/docs/components/section-block.md +1 -1
  74. package/docs/how-to/forms-with-form-builder.md +44 -41
  75. package/docs/migration/changelog.md +3 -0
  76. package/docs/migration/form-builder-2.5.2.md +113 -0
  77. package/docs/reference/cli.md +28 -3
  78. package/docs/tutorials/getting-started.md +7 -0
  79. package/package.json +1 -1
@@ -33,8 +33,8 @@ Three components, layered:
33
33
 
34
34
  | Component | Use it for | When |
35
35
  | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
36
- | **`FormBuilder`** | The form itself — fields authored as JSX children. Owns react-hook-form, validation, sections, steppers. | Always. This is the base. |
37
- | **`FormRenderer`** | Wraps `FormBuilder` to add **chrome**: page-vs-drawer display, the title header, an `actions` slot for the Save, and a `summary` slot. | Real forms — prefer it over raw `FormBuilder`. |
36
+ | **`FormBuilder`** | The fields themselves, authored as JSX children. Owns react-hook-form and validation — and nothing else: no cards, no header, no frame. | Always. This is the base. |
37
+ | **`FormRenderer`** | All the **chrome**: page-vs-drawer display, the title header, an `actions` slot for the Save, the titled `Section` cards, the stepper, and a `summary` slot. | Real forms — prefer it over raw `FormBuilder`. |
38
38
  | **`FormSummary`** | A read-only **calculation panel beside the form** — totals that recompute live as the user types. | Invoices, orders, anything with a "conclusion". |
39
39
 
40
40
  Validation is **resolver-agnostic**: pass any react-hook-form resolver
@@ -96,31 +96,34 @@ export function ItemForm({
96
96
  header={{ title: "New item", variant: "new" }}
97
97
  actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
98
98
  >
99
- <FormBuilder.Section title="Identity" color="Blue">
99
+ <FormRenderer.Section title="Identity" color="Blue">
100
100
  <FormBuilder.Text name="name" label="Name" required placeholder="e.g. Acme Widget" />
101
101
  <FormBuilder.Textarea name="description" label="Description" fullWidth />
102
- </FormBuilder.Section>
102
+ </FormRenderer.Section>
103
103
 
104
- <FormBuilder.Section title="Classification" color="Red">
104
+ <FormRenderer.Section title="Classification" color="Red">
105
105
  <FormBuilder.Select name="category" label="Category" required options={CATEGORY} />
106
106
  <FormBuilder.Currency name="price" label="Base price" currencySymbol="$" />
107
- </FormBuilder.Section>
107
+ </FormRenderer.Section>
108
108
 
109
- <FormBuilder.Section title="Settings" color="Purple">
109
+ <FormRenderer.Section title="Settings" color="Purple">
110
110
  <FormBuilder.SwitchBox name="active" label="Active" subLabel="Enabled" />
111
111
  <FormBuilder.Checkbox name="agree" label="I agree to the terms" required />
112
- </FormBuilder.Section>
112
+ </FormRenderer.Section>
113
113
  </FormRenderer>
114
114
  );
115
115
  }
116
116
  ```
117
117
 
118
- `FormBuilder.Section` groups fields in a `SectionBlock` (`color` is one of `Blue`, `Yellow`,
118
+ `FormRenderer.Section` groups fields in a `SectionBlock` (`color` is one of `Blue`, `Yellow`,
119
119
  `Green`, `Red`, `Orange`, `Purple`, `Pink`, `Gray`). It also takes `icon`, `action`
120
120
  (right-aligned buttons on the title row) and `variant` — `variant="Table"` switches to the
121
121
  full-bleed table shell that `FormBuilder.Table` uses internally. Pass the Save via `actions` — a
122
- `FormBuilder.Submit`, which is loading-aware; it renders in the header action pill. (With raw
123
- `FormBuilder`, put the same `FormBuilder.Submit` in a `FormBuilder.Header`.)
122
+ `FormBuilder.Submit`, which is loading-aware; it renders in the header action pill.
123
+
124
+ > The section card belongs to `FormRenderer`, not `FormBuilder`: it is presentation, and it groups
125
+ > read-only detail rows just as happily as fields. A bare `<FormBuilder>` renders its fields with
126
+ > no card around them.
124
127
 
125
128
  ### Field types
126
129
 
@@ -168,8 +171,7 @@ whatever you pass to `actions` — put the Save there:
168
171
  auto-targets the form (via a form-id context), so it submits even though the header renders
169
172
  _outside_ the `<form>`.
170
173
 
171
- If you use raw `FormBuilder`, the same bar is `FormBuilder.Header` with a `FormBuilder.Submit`
172
- child.
174
+ There is no header on raw `FormBuilder` the title bar is FormRenderer's.
173
175
 
174
176
  ---
175
177
 
@@ -194,19 +196,19 @@ checked** in the rail even after you navigate back — a live error still shows
194
196
  header={{ title: "New item", variant: "new" }}
195
197
  actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
196
198
  >
197
- <FormBuilder.Stepper>
198
- <FormBuilder.Step title="Identity">
199
- <FormBuilder.Section title="Identity" color="Blue">
199
+ <FormRenderer.Stepper>
200
+ <FormRenderer.Step title="Identity">
201
+ <FormRenderer.Section title="Identity" color="Blue">
200
202
  <FormBuilder.Text name="name" label="Name" required />
201
- </FormBuilder.Section>
202
- </FormBuilder.Step>
203
+ </FormRenderer.Section>
204
+ </FormRenderer.Step>
203
205
 
204
- <FormBuilder.Step title="Classification">
205
- <FormBuilder.Section title="Classification" color="Red">
206
+ <FormRenderer.Step title="Classification">
207
+ <FormRenderer.Section title="Classification" color="Red">
206
208
  <FormBuilder.Select name="category" label="Category" required options={CATEGORY} />
207
- </FormBuilder.Section>
208
- </FormBuilder.Step>
209
- </FormBuilder.Stepper>
209
+ </FormRenderer.Section>
210
+ </FormRenderer.Step>
211
+ </FormRenderer.Stepper>
210
212
  </FormRenderer>
211
213
  ```
212
214
 
@@ -249,9 +251,9 @@ it renders in the drawer header, with no manual `id` / `form={id}` wiring:
249
251
  defaultValues={DEFAULTS}
250
252
  actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
251
253
  >
252
- <FormBuilder.Section title="Identity" color="Blue">
254
+ <FormRenderer.Section title="Identity" color="Blue">
253
255
 
254
- </FormBuilder.Section>
256
+ </FormRenderer.Section>
255
257
  </FormRenderer>
256
258
  ```
257
259
 
@@ -322,7 +324,7 @@ export function InvoiceForm({ save }: { save: (v: Invoice) => Promise<void> }) {
322
324
  </FormSummary>
323
325
  }
324
326
  >
325
- <FormBuilder.Section title="Line items" color="Green">
327
+ <FormRenderer.Section title="Line items" color="Green">
326
328
  <FormBuilder.FieldArray
327
329
  name="items"
328
330
  label="Items"
@@ -342,12 +344,12 @@ export function InvoiceForm({ save }: { save: (v: Invoice) => Promise<void> }) {
342
344
  </>
343
345
  )}
344
346
  </FormBuilder.FieldArray>
345
- </FormBuilder.Section>
347
+ </FormRenderer.Section>
346
348
 
347
- <FormBuilder.Section title="Rates" color="Purple">
349
+ <FormRenderer.Section title="Rates" color="Purple">
348
350
  <FormBuilder.Number name="taxRate" label="Tax rate (%)" />
349
351
  <FormBuilder.Number name="iqdRate" label="USD → IQD rate" />
350
- </FormBuilder.Section>
352
+ </FormRenderer.Section>
351
353
  </FormRenderer>
352
354
  );
353
355
  }
@@ -358,7 +360,7 @@ Row options: `emphasized` (the primary result), `currency` + `tone`
358
360
  button), `format` (override the number formatting), `value` (a static row).
359
361
 
360
362
  The panel is **read-only** — it contributes nothing to the submitted values. On a page it sits
361
- beside the form (a `summary` **plus** a `FormBuilder.Stepper` becomes three columns: nav ·
363
+ beside the form (a `summary` **plus** a `FormRenderer.Stepper` becomes three columns: nav ·
362
364
  fields · summary).
363
365
 
364
366
  ---
@@ -385,9 +387,9 @@ drawer's tray, beside the form:
385
387
  </FormSummary>
386
388
  }
387
389
  >
388
- <FormBuilder.Section title="Identity" color="Blue">
390
+ <FormRenderer.Section title="Identity" color="Blue">
389
391
 
390
- </FormBuilder.Section>
392
+ </FormRenderer.Section>
391
393
  </FormRenderer>
392
394
  ```
393
395
 
@@ -396,12 +398,11 @@ drawer's tray, beside the form:
396
398
  ## 8. A detail (view) page — sidebar tabs, not a form
397
399
 
398
400
  Sometimes you want to **display** a record, not edit it. Give `FormRenderer` `FormRenderer.Sidebar`
401
+ + `FormRenderer.Tab` children (instead of fields) and it switches to a display-only detail page: a
402
+ left **sidebar** where each item swaps in its matching tab panel — no `<form>`, no submit. The
403
+ sidebar sits where a stepper's rail would; only the active panel shows.
399
404
 
400
- - `FormRenderer.Tab` children (instead of fields) and it switches to a display-only detail page: a
401
- left **sidebar** where each item swaps in its matching tab panel — no `<form>`, no submit. The
402
- sidebar sits where a stepper's rail would; only the active panel shows.
403
-
404
- **Every tab's content is `FormBuilder.Section` blocks.** Inside a Section, use the default
405
+ **Every tab's content is `FormRenderer.Section` blocks.** Inside a Section, use the default
405
406
  `FormRenderer.Grid` + `FormRenderer.Row` display cells (the read-only counterpart of form fields), or
406
407
  render **your own component** — anything goes inside a Section.
407
408
 
@@ -422,19 +423,19 @@ render **your own component** — anything goes inside a Section.
422
423
 
423
424
  {/* Default display cells */}
424
425
  <FormRenderer.Tab value="overview">
425
- <FormBuilder.Section title="Main Information" color="Blue">
426
+ <FormRenderer.Section title="Main Information" color="Blue">
426
427
  <FormRenderer.Grid columns={2}>
427
428
  <FormRenderer.Row label="PO Number" value={record.poNumber} />
428
429
  <FormRenderer.Row label="Status" value={<Badge label="Submitted" color="yellow" />} />
429
430
  </FormRenderer.Grid>
430
- </FormBuilder.Section>
431
+ </FormRenderer.Section>
431
432
  </FormRenderer.Tab>
432
433
 
433
434
  {/* Or bring your own component — still inside a Section */}
434
435
  <FormRenderer.Tab value="activity">
435
- <FormBuilder.Section title="Activity log" color="Green">
436
+ <FormRenderer.Section title="Activity log" color="Green">
436
437
  <YourTimeline items={record.activity} />
437
- </FormBuilder.Section>
438
+ </FormRenderer.Section>
438
439
  </FormRenderer.Tab>
439
440
  </FormRenderer>
440
441
  ```
@@ -465,3 +466,5 @@ takes `label` + `value` (any node). The first `Tab` is active by default.
465
466
  - [FormBuilder](../components/form-builder.md) — every field type and its value shape
466
467
  - [FormRenderer](../components/form-renderer.md) — display, header, `actions`, `summary`
467
468
  - [FormSummary](../components/form-summary.md) — the calculation panel
469
+ - [FormBuilder 2.5.2 migration](../migration/form-builder-2.5.2.md) — what moved from
470
+ `FormBuilder` to `FormRenderer`, and the rename table
@@ -26,6 +26,9 @@ npx torch-glare@latest add Button
26
26
 
27
27
  ## Release notes
28
28
 
29
+ - **v2.5.2** — **breaking**: `FormBuilder` now holds only the fields; the section cards, title
30
+ header and stepper moved to `FormRenderer`. See
31
+ [FormBuilder 2.5.2](./form-builder-2.5.2.md) for the rename table.
29
32
  - **v1.1.16** — see [CHANGELOG-1.1.16.md](../CHANGELOG-1.1.16.md) (adds `TextEditor`,
30
33
  `ChartBlockTool`, and related components).
31
34
 
@@ -0,0 +1,113 @@
1
+ ---
2
+ title: FormBuilder 2.5.2 — the chrome moved to FormRenderer
3
+ description: FormBuilder now holds only the fields. The section cards, title header and stepper moved to FormRenderer. What to rename, and why.
4
+ group: migration
5
+ keywords:
6
+ [migration, breaking, form-builder, form-renderer, section, stepper, header, 2.5.2, upgrade]
7
+ ---
8
+
9
+ # FormBuilder 2.5.2 — the chrome moved to FormRenderer
10
+
11
+ **`FormBuilder` is now the fields and nothing else.** Everything drawn *around* the fields —
12
+ titled section cards, the page title header, the stepper and its rail, the page gutters, the
13
+ scroll shell, the summary column — now lives on [`FormRenderer`](../components/form-renderer.md).
14
+
15
+ ## Why
16
+
17
+ The split was already documented this way; the code just did not honour it. `FormBuilder` owned a
18
+ `rounded-2xl` page shell, a title header that a *child element* switched on, a stepper rail, and a
19
+ `conclusion` panel rendered outside its own `<form>` — while its own doc comment described it as
20
+ "drawer-unaware". The tell was the `layout="bare"` prop: page framing had been baked in, and
21
+ anything embedding a form (a 260px settings rail, a `DataViews` filter panel) needed an escape
22
+ hatch to turn it off.
23
+
24
+ Now there is nothing to escape. A bare `<FormBuilder>` renders a `<form>` and your fields, and
25
+ fills whatever it is placed in. `FormRenderer` draws the page.
26
+
27
+ ## What to rename
28
+
29
+ | Before | After |
30
+ | ----------------------- | ------------------------ |
31
+ | `FormBuilder.Section` | `FormRenderer.Section` |
32
+ | `FormBuilder.Stepper` | `FormRenderer.Stepper` |
33
+ | `FormBuilder.Step` | `FormRenderer.Step` |
34
+ | `FormBuilder.Back` | `FormRenderer.Back` |
35
+ | `FormBuilder.Next` | `FormRenderer.Next` |
36
+ | `FormBuilder.Header` | `FormRenderer`'s `header` prop (see below) |
37
+
38
+ **`FormBuilder.Submit` does not move.** It is the form's own submit button and still
39
+ auto-associates with the `<form>` by id, so it works from the header action bar as before.
40
+
41
+ ### Two root props are gone
42
+
43
+ | Removed | Replacement |
44
+ | --------------------------- | ------------------------------------------------------------------ |
45
+ | `layout="page" \| "bare"` | Nothing — bare is the only behaviour. The 1100px cap and 48px gutters are `FormRenderer`'s. Delete the prop. |
46
+ | `conclusion={<FormSummary/>}` | `FormRenderer`'s `summary` prop. |
47
+
48
+ `className` now lands on the `<form>` element itself rather than an outer page wrapper. On
49
+ `FormRenderer` it still lands on the outermost element, so `className="min-h-0 flex-1"` behaves
50
+ exactly as before.
51
+
52
+ ### `FormBuilder.Header` → the `header` prop
53
+
54
+ The header was a child that silently reconfigured the root into a scroll-shell layout. It is now
55
+ a prop, so a child can no longer change the page around it:
56
+
57
+ ```tsx
58
+ // Before
59
+ <FormBuilder onSubmit={save} resolver={r} defaultValues={d}>
60
+ <FormBuilder.Header title="Item" variant="new">
61
+ <FormBuilder.Submit>Save</FormBuilder.Submit>
62
+ </FormBuilder.Header>
63
+ <FormBuilder.Section title="Identity" color="Blue">
64
+ <FormBuilder.Text name="name" label="Name" required />
65
+ </FormBuilder.Section>
66
+ </FormBuilder>
67
+
68
+ // After
69
+ <FormRenderer
70
+ onSubmit={save}
71
+ resolver={r}
72
+ defaultValues={d}
73
+ header={{ title: "Item", variant: "new" }}
74
+ actions={<FormBuilder.Submit>Save</FormBuilder.Submit>}
75
+ >
76
+ <FormRenderer.Section title="Identity" color="Blue">
77
+ <FormBuilder.Text name="name" label="Name" required />
78
+ </FormRenderer.Section>
79
+ </FormRenderer>
80
+ ```
81
+
82
+ ## Doing the upgrade
83
+
84
+ There is no compatibility shim: the removed parts are gone, so **TypeScript finds every call site
85
+ for you**. Re-run the CLI, then let the compiler drive:
86
+
87
+ ```bash
88
+ npx torch-glare@latest add FormBuilder FormRenderer --force
89
+ npx tsc --noEmit
90
+ ```
91
+
92
+ Each error is one of the renames in the table above. If a form used raw `FormBuilder` for a real
93
+ page, wrap it in `FormRenderer` — that is where its header, gutters and section cards now come
94
+ from.
95
+
96
+ ### Field layout is unchanged
97
+
98
+ `FieldSection` — the per-field row (label · control · hint) that every field draws for itself — did
99
+ **not** move, and no field component changed. After the rename, fields land on exactly the same
100
+ pixels; only the `<form>` element's own box changed, because the gutters that used to sit inside it
101
+ now sit outside it.
102
+
103
+ ## Installing
104
+
105
+ `FormRenderer` still depends on `FormBuilder`, never the reverse — `add FormRenderer` pulls both.
106
+
107
+ The registry moved to match. `FormBuilder` **dropped** `FormStepper` and `HeaderBar`, so
108
+ `add FormBuilder` on its own now installs a smaller tree: the fields, and no chrome. `FormRenderer`
109
+ **gained** those two plus `SectionBlock` and `Button`.
110
+
111
+ Note that `FormBuilder` **keeps** its `SectionBlock` dependency even though `FormRenderer.Section`
112
+ moved away — `FormBuilder.Table` renders a `SectionBlock variant="Table"` shell of its own, so a
113
+ standalone `add FormBuilder` still gets a working table field.
@@ -23,7 +23,7 @@ Run a command **without** a name to pick from an interactive list.
23
23
 
24
24
  | Command | Description |
25
25
  | --- | --- |
26
- | `init` | Create `glare.json` and set up Tailwind. Run once per project. |
26
+ | `init` | Create `glare.json`, install the Tailwind packages, **and wire your stylesheet**. Run once per project. |
27
27
  | `add [Component]` | Copy a component **and its dependencies** into your project. |
28
28
  | `hook [hook]` | Copy a hook (usually pulled in automatically as a dependency). |
29
29
  | `util [util]` | Copy a utility (e.g. `cn`, usually pulled in automatically). |
@@ -32,6 +32,8 @@ Run a command **without** a name to pick from an interactive list.
32
32
  | `update` | Re-sync everything already installed with the latest templates. |
33
33
 
34
34
  Component names are **case-sensitive PascalCase** — `add DatePicker`, not `add datepicker`.
35
+ Every command takes a **bare name** — `hook useDragDrop`, not `hook useDragDrop.tsx` — and every one
36
+ accepts `-f, --force`.
35
37
 
36
38
  ## `init`
37
39
 
@@ -39,7 +41,23 @@ Component names are **case-sensitive PascalCase** — `add DatePicker`, not `add
39
41
  npx torch-glare@latest init
40
42
  ```
41
43
 
42
- Creates `glare.json` and configures Tailwind. `glare.json` controls where files are copied:
44
+ Three things, in order:
45
+
46
+ 1. Creates `glare.json`.
47
+ 2. Installs the Tailwind packages the design system needs, using your detected package manager.
48
+ 3. **Wires your entry stylesheet** — `app/globals.css`, `src/app/globals.css`, `src/index.css`,
49
+ `styles/globals.css` — with the `@import`/`@plugin` block. Re-running is safe: if the block is
50
+ already there it says so and changes nothing.
51
+
52
+ On Tailwind v3 the plugins belong in `tailwind.config.*` instead. `init` prints the snippet rather
53
+ than editing that file, since its shape is yours.
54
+
55
+ > Without step 3 the project builds cleanly and renders every component **unstyled** — the design
56
+ > tokens simply resolve to nothing. If that happens, check that `@import "tailwindcss"` is the
57
+ > first line: CSS requires imports to precede other at-rules, so an import placed after a `@plugin`
58
+ > is silently dropped.
59
+
60
+ `glare.json` controls where files are copied:
43
61
 
44
62
  ```json
45
63
  {
@@ -68,7 +86,14 @@ export function Example() {
68
86
  }
69
87
  ```
70
88
 
71
- Existing files are never overwritten; use `update` to re-sync.
89
+ It ends with a summary `✅ DataViews → ./: 56 installed (56 items).` — so a partial install is
90
+ visible rather than something you discover at build time.
91
+
92
+ Dependencies come from the generated `registry.json`, resolved in one pass, so each item is copied
93
+ exactly once however many things import it.
94
+
95
+ Existing files are never overwritten. Use `--force` to re-copy — it applies to **the whole
96
+ dependency closure**, not just the component you named — or `update` to re-sync everything.
72
97
 
73
98
  ## `update`
74
99
 
@@ -32,6 +32,13 @@ Before you begin, make sure you have:
32
32
 
33
33
  ---
34
34
 
35
+ > **If you plan to build forms**, add the validation packages the guides use — no component
36
+ > imports them, so the CLI does not install them for you:
37
+ >
38
+ > ```bash
39
+ > npm install zod @hookform/resolvers
40
+ > ```
41
+
35
42
  ## Step 1: Initialize TORCH Glare
36
43
 
37
44
  Run the following command to initialize your project:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torch-glare",
3
- "version": "2.5.0",
3
+ "version": "2.5.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "A copy-in React component library (TypeScript + Radix UI + Tailwind CSS). Its CLI copies component source directly into your project — you own the code.",