torch-glare 2.4.3 → 2.4.4

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.
@@ -226,6 +226,9 @@ automatically.
226
226
  > [FormRenderer](./form-renderer.md) (pass `fieldDirection="vertical"` to the
227
227
  > form), or use `FormRenderer` with `display="drawer"`.
228
228
 
229
+ > Building a **detail page** with a sidebar of tabs (not a form)? That lives on `FormRenderer`
230
+ > (`FormRenderer.Sidebar` / `.Tab`) — see the FormRenderer docs. `FormBuilder` itself stays form-only.
231
+
229
232
  ## Calculation panel
230
233
 
231
234
  To show computed totals **beside** the form, render a [FormSummary](./form-summary.md)
@@ -16,6 +16,10 @@ takes care of the surrounding concerns:
16
16
  - the **absolute title header** + action bar (page display),
17
17
  - **vertical field layout** inside a drawer.
18
18
 
19
+ FormRenderer has **two modes**: a **form** (author fields as children, as below), or a display-only
20
+ **detail page** — give it `FormRenderer.Sidebar` + `FormRenderer.Tab` children instead of fields and the
21
+ sidebar swaps `FormBuilder.Section` panels (no `<form>`, no submit — see [Detail tabs](#detail-tabs-sidebar)).
22
+
19
23
  FormRenderer never manufactures a Submit — **you compose the Save and hand it to `actions`**.
20
24
  It renders in the form's header action pill (page) or the drawer header (drawer), and a bare
21
25
  `<FormBuilder.Submit>` auto-targets this form (even though the header sits outside the `<form>`).
@@ -60,7 +64,7 @@ import { FormBuilder } from "@/components/FormBuilder";
60
64
  | Prop | Type | Notes |
61
65
  | -------------------------------------------------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
62
66
  | `children` | `ReactNode` | The form body — `FormBuilder.Section` / field / `FormBuilder.Stepper` JSX. |
63
- | `onSubmit` / `onInvalid` | fns | Submit / validation-fail callbacks. |
67
+ | `onSubmit?` / `onInvalid?` | fns | Submit / validation-fail callbacks. Optional — a detail-tabs view has no form, so omit them there. |
64
68
  | `resolver` | `Resolver` | Any react-hook-form resolver, e.g. `zodResolver(schema)`. |
65
69
  | `defaultValues` / `values` | `DefaultValues` / `T` | Initial values; `values` re-syncs on change (edit). |
66
70
  | `loading` / `resetOnSuccess` | `boolean` | Forwarded to `FormBuilder`. |
@@ -119,6 +123,57 @@ error overrides it to red. You still pass just the Submit; the nav is wired for
119
123
  </FormRenderer>
120
124
  ```
121
125
 
126
+ ## Detail tabs (sidebar)
127
+
128
+ Give FormRenderer `FormRenderer.Sidebar` + `FormRenderer.Tab` children (instead of fields) and it
129
+ switches to a **display-only detail page**: a left **sidebar** where each item swaps in its matching
130
+ tab panel — no `<form>`, no submit. The sidebar sits **where a stepper's rail would**, and only the
131
+ active panel shows (built on the same Radix Tabs primitive shadcn uses, so it's keyboard-accessible).
132
+ Pair it with `header` (`variant="detail"` → a "View" badge) + `actions` (Print / Approve / …).
133
+
134
+ Each `Tab` holds read-only `FormBuilder.Section` blocks; `FormRenderer.Grid` + `FormRenderer.Row` lay
135
+ out the label/value display cells (the display counterpart of form fields).
136
+
137
+ ```tsx
138
+ <FormRenderer
139
+ header={{ title: "Order DE-344", variant: "detail" }}
140
+ actions={<Button variant="BorderStyle">Print</Button>}
141
+ >
142
+ {/* The rail — one Item per tab, tied to a Tab by `value`. */}
143
+ <FormRenderer.Sidebar>
144
+ <FormRenderer.Sidebar.Item value="overview" icon={<i className="ri-layout-grid-line" />}>
145
+ Overview
146
+ </FormRenderer.Sidebar.Item>
147
+ <FormRenderer.Sidebar.Item value="items" icon={<i className="ri-table-line" />}>
148
+ Items Table
149
+ </FormRenderer.Sidebar.Item>
150
+ </FormRenderer.Sidebar>
151
+
152
+ {/* One panel per tab — read-only Section blocks. */}
153
+ <FormRenderer.Tab value="overview">
154
+ <FormBuilder.Section title="Main Information" color="Blue">
155
+ <FormRenderer.Grid>
156
+ <FormRenderer.Row label="PO Number" value="PO-000123" />
157
+ <FormRenderer.Row label="Status" value={<Badge label="Submitted" color="yellow" />} />
158
+ </FormRenderer.Grid>
159
+ </FormBuilder.Section>
160
+ </FormRenderer.Tab>
161
+
162
+ <FormRenderer.Tab value="items">…</FormRenderer.Tab>
163
+ </FormRenderer>
164
+ ```
165
+
166
+ | Component | Props | Renders |
167
+ | -------------- | -------------------------- | ------------------------------------------------------------------ |
168
+ | `Sidebar` | `children` | The tab rail (a Radix `Tabs.List`), fixed at the stepper's place. |
169
+ | `Sidebar.Item` | `value`, `icon?`, children | A rail nav row (a `Tabs.Trigger`); the active one is a black pill. |
170
+ | `Tab` | `value`, children | A content panel (a `Tabs.Content`) shown when its tab is active. |
171
+ | `Grid` | `columns?` (1–3), children | A padded grid of display `Row`s (default 2 columns). |
172
+ | `Row` | `label`, `value` | A read-only label/value display cell. |
173
+
174
+ The first `Tab` is active by default. Only the active panel is visible; the rail stays fixed while the
175
+ content column scrolls.
176
+
122
177
  ## Summary panel
123
178
 
124
179
  Pass a hoisted `useForm` as `form` and a `FormSummary` as `summary` — FormRenderer binds
@@ -391,6 +391,60 @@ drawer's tray, beside the form:
391
391
 
392
392
  ---
393
393
 
394
+ ## 8. A detail (view) page — sidebar tabs, not a form
395
+
396
+ Sometimes you want to **display** a record, not edit it. Give `FormRenderer` `FormRenderer.Sidebar`
397
+
398
+ - `FormRenderer.Tab` children (instead of fields) and it switches to a display-only detail page: a
399
+ left **sidebar** where each item swaps in its matching tab panel — no `<form>`, no submit. The
400
+ sidebar sits where a stepper's rail would; only the active panel shows.
401
+
402
+ **Every tab's content is `FormBuilder.Section` blocks.** Inside a Section, use the default
403
+ `FormRenderer.Grid` + `FormRenderer.Row` display cells (the read-only counterpart of form fields), or
404
+ render **your own component** — anything goes inside a Section.
405
+
406
+ ```tsx
407
+ <FormRenderer
408
+ header={{ title: "Order DE-344", variant: "detail" }} // "View" badge
409
+ actions={<Button variant="BorderStyle">Print</Button>}
410
+ >
411
+ {/* Rail — each Item's `value` ties to a Tab. */}
412
+ <FormRenderer.Sidebar>
413
+ <FormRenderer.Sidebar.Item value="overview" icon={<i className="ri-layout-grid-line" />}>
414
+ Overview
415
+ </FormRenderer.Sidebar.Item>
416
+ <FormRenderer.Sidebar.Item value="activity" icon={<i className="ri-pulse-line" />}>
417
+ Activity log
418
+ </FormRenderer.Sidebar.Item>
419
+ </FormRenderer.Sidebar>
420
+
421
+ {/* Default display cells */}
422
+ <FormRenderer.Tab value="overview">
423
+ <FormBuilder.Section title="Main Information" color="Blue">
424
+ <FormRenderer.Grid columns={2}>
425
+ <FormRenderer.Row label="PO Number" value={record.poNumber} />
426
+ <FormRenderer.Row label="Status" value={<Badge label="Submitted" color="yellow" />} />
427
+ </FormRenderer.Grid>
428
+ </FormBuilder.Section>
429
+ </FormRenderer.Tab>
430
+
431
+ {/* Or bring your own component — still inside a Section */}
432
+ <FormRenderer.Tab value="activity">
433
+ <FormBuilder.Section title="Activity log" color="Green">
434
+ <YourTimeline items={record.activity} />
435
+ </FormBuilder.Section>
436
+ </FormRenderer.Tab>
437
+ </FormRenderer>
438
+ ```
439
+
440
+ `FormRenderer.Grid` takes `columns` (1–3, default 2) and spans the full section width; `FormRenderer.Row`
441
+ takes `label` + `value` (any node). The first `Tab` is active by default.
442
+
443
+ > Generating one? Call the `create-form` tool with `layout="detail"` — it returns this exact wiring
444
+ > with your fields pre-filled as display rows.
445
+
446
+ ---
447
+
394
448
  ## Gotchas
395
449
 
396
450
  - **Hoisting `useForm` disables the remount-`key` reset.** Once the form instance lives in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torch-glare",
3
- "version": "2.4.3",
3
+ "version": "2.4.4",
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.",