torch-glare 2.5.1 → 2.5.3

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 (38) hide show
  1. package/apps/lib/components/DataViews/data-views.tsx +1 -1
  2. package/apps/lib/components/DataViews/filters/filters.tsx +8 -12
  3. package/apps/lib/components/DataViews/header.tsx +5 -2
  4. package/apps/lib/components/DataViews/panel/section.tsx +3 -1
  5. package/apps/lib/components/DataViews/views/board-view.tsx +3 -1
  6. package/apps/lib/components/DataViews/views/inbox-view.tsx +4 -1
  7. package/apps/lib/components/DataViews/views/pane-views.tsx +5 -1
  8. package/apps/lib/components/DataViews/views/table-view.tsx +34 -4
  9. package/apps/lib/components/DataViews/views/tree-view.tsx +5 -3
  10. package/apps/lib/components/FormBuilder/context.ts +17 -26
  11. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +1 -1
  12. package/apps/lib/components/FormBuilder/form-builder.tsx +32 -172
  13. package/apps/lib/components/FormBuilder/index.ts +0 -4
  14. package/apps/lib/components/FormBuilder/submit.tsx +11 -2
  15. package/apps/lib/components/FormBuilder/types.ts +10 -16
  16. package/apps/lib/components/FormRenderer/FormDrawer.tsx +2 -2
  17. package/apps/lib/components/FormRenderer/detail.tsx +6 -6
  18. package/apps/lib/components/FormRenderer/form-renderer.tsx +167 -35
  19. package/apps/lib/components/{FormBuilder → FormRenderer}/header.tsx +12 -25
  20. package/apps/lib/components/FormRenderer/index.ts +4 -0
  21. package/apps/lib/components/FormRenderer/section.tsx +39 -0
  22. package/apps/lib/components/{FormBuilder → FormRenderer}/stepper.tsx +65 -22
  23. package/apps/lib/components/FormRenderer/types.ts +7 -7
  24. package/apps/lib/components/SectionBlock.tsx +11 -1
  25. package/apps/lib/components/Table.tsx +54 -29
  26. package/apps/lib/components/TreeFolder/TreeFolder.tsx +61 -61
  27. package/apps/lib/registry.json +5 -3
  28. package/apps/lib/tsconfig.tsbuildinfo +1 -1
  29. package/docs/components/data-views/index.md +7 -0
  30. package/docs/components/form-builder.md +65 -89
  31. package/docs/components/form-renderer.md +62 -26
  32. package/docs/components/form-summary.md +18 -3
  33. package/docs/components/section-block.md +1 -1
  34. package/docs/components/table.md +33 -0
  35. package/docs/how-to/forms-with-form-builder.md +47 -42
  36. package/docs/migration/changelog.md +3 -0
  37. package/docs/migration/form-builder-2.5.2.md +113 -0
  38. 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,13 +251,15 @@ 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
 
258
- Inside a drawer the fields default to a vertical (narrow) layout automatically.
260
+ Inside a drawer the fields default to a vertical (narrow) layout automatically. A drawer can be
261
+ wide, though — pass `fieldDirection="flexible"` to hand the decision back to the container query,
262
+ which goes label-beside-control once a field row passes the container `md` breakpoint.
259
263
 
260
264
  ---
261
265
 
@@ -322,7 +326,7 @@ export function InvoiceForm({ save }: { save: (v: Invoice) => Promise<void> }) {
322
326
  </FormSummary>
323
327
  }
324
328
  >
325
- <FormBuilder.Section title="Line items" color="Green">
329
+ <FormRenderer.Section title="Line items" color="Green">
326
330
  <FormBuilder.FieldArray
327
331
  name="items"
328
332
  label="Items"
@@ -342,12 +346,12 @@ export function InvoiceForm({ save }: { save: (v: Invoice) => Promise<void> }) {
342
346
  </>
343
347
  )}
344
348
  </FormBuilder.FieldArray>
345
- </FormBuilder.Section>
349
+ </FormRenderer.Section>
346
350
 
347
- <FormBuilder.Section title="Rates" color="Purple">
351
+ <FormRenderer.Section title="Rates" color="Purple">
348
352
  <FormBuilder.Number name="taxRate" label="Tax rate (%)" />
349
353
  <FormBuilder.Number name="iqdRate" label="USD → IQD rate" />
350
- </FormBuilder.Section>
354
+ </FormRenderer.Section>
351
355
  </FormRenderer>
352
356
  );
353
357
  }
@@ -358,7 +362,7 @@ Row options: `emphasized` (the primary result), `currency` + `tone`
358
362
  button), `format` (override the number formatting), `value` (a static row).
359
363
 
360
364
  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 ·
365
+ beside the form (a `summary` **plus** a `FormRenderer.Stepper` becomes three columns: nav ·
362
366
  fields · summary).
363
367
 
364
368
  ---
@@ -385,9 +389,9 @@ drawer's tray, beside the form:
385
389
  </FormSummary>
386
390
  }
387
391
  >
388
- <FormBuilder.Section title="Identity" color="Blue">
392
+ <FormRenderer.Section title="Identity" color="Blue">
389
393
  …
390
- </FormBuilder.Section>
394
+ </FormRenderer.Section>
391
395
  </FormRenderer>
392
396
  ```
393
397
 
@@ -396,12 +400,11 @@ drawer's tray, beside the form:
396
400
  ## 8. A detail (view) page — sidebar tabs, not a form
397
401
 
398
402
  Sometimes you want to **display** a record, not edit it. Give `FormRenderer` `FormRenderer.Sidebar`
403
+ + `FormRenderer.Tab` children (instead of fields) and it switches to a display-only detail page: a
404
+ left **sidebar** where each item swaps in its matching tab panel — no `<form>`, no submit. The
405
+ sidebar sits where a stepper's rail would; only the active panel shows.
399
406
 
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
407
+ **Every tab's content is `FormRenderer.Section` blocks.** Inside a Section, use the default
405
408
  `FormRenderer.Grid` + `FormRenderer.Row` display cells (the read-only counterpart of form fields), or
406
409
  render **your own component** — anything goes inside a Section.
407
410
 
@@ -422,19 +425,19 @@ render **your own component** — anything goes inside a Section.
422
425
 
423
426
  {/* Default display cells */}
424
427
  <FormRenderer.Tab value="overview">
425
- <FormBuilder.Section title="Main Information" color="Blue">
428
+ <FormRenderer.Section title="Main Information" color="Blue">
426
429
  <FormRenderer.Grid columns={2}>
427
430
  <FormRenderer.Row label="PO Number" value={record.poNumber} />
428
431
  <FormRenderer.Row label="Status" value={<Badge label="Submitted" color="yellow" />} />
429
432
  </FormRenderer.Grid>
430
- </FormBuilder.Section>
433
+ </FormRenderer.Section>
431
434
  </FormRenderer.Tab>
432
435
 
433
436
  {/* Or bring your own component — still inside a Section */}
434
437
  <FormRenderer.Tab value="activity">
435
- <FormBuilder.Section title="Activity log" color="Green">
438
+ <FormRenderer.Section title="Activity log" color="Green">
436
439
  <YourTimeline items={record.activity} />
437
- </FormBuilder.Section>
440
+ </FormRenderer.Section>
438
441
  </FormRenderer.Tab>
439
442
  </FormRenderer>
440
443
  ```
@@ -465,3 +468,5 @@ takes `label` + `value` (any node). The first `Tab` is active by default.
465
468
  - [FormBuilder](../components/form-builder.md) — every field type and its value shape
466
469
  - [FormRenderer](../components/form-renderer.md) — display, header, `actions`, `summary`
467
470
  - [FormSummary](../components/form-summary.md) — the calculation panel
471
+ - [FormBuilder 2.5.2 migration](../migration/form-builder-2.5.2.md) — what moved from
472
+ `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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torch-glare",
3
- "version": "2.5.1",
3
+ "version": "2.5.3",
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.",