torch-glare 2.5.2 → 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.
@@ -188,6 +188,13 @@ Each takes `id`, `label` and `icon` to control how it appears in the switcher, s
188
188
  be registered twice with different data. Full props are under
189
189
  [API Reference](#api-reference) — one heading per part.
190
190
 
191
+ Two things `DataViews.Table` does for you that you would otherwise wire by hand: its column header
192
+ **stays put while the rows scroll under it**, and the view draws **its own border and radius**, so it
193
+ reads as a separated surface like the inbox and tree panels rather than filling the shell edge to
194
+ edge. Long column labels truncate with an ellipsis instead of wrapping the header row onto a second
195
+ line. Inside `DataViews.Tree`, the same table drops that border — the tree's pane already draws one,
196
+ and two would nest a pixel apart.
197
+
191
198
  ### The tree's pane
192
199
 
193
200
  Pick a node and the pane beside it lists what that node holds. Its header names the selected node
@@ -55,7 +55,9 @@ Everything drawn *around* the fields lives in **[FormRenderer](./form-renderer.m
55
55
  > author the fields as `FormBuilder.*` children — FormRenderer just wraps them.
56
56
 
57
57
  `FormBuilder.Submit` is the one non-field part that stays here — see
58
- [Field components](#field-components) for what it does.
58
+ [Field components](#field-components) for what it does. It renders the **primary action**: the blue
59
+ filled button. There is deliberately no `variant` prop — a form has one primary action, and letting
60
+ each call site pick a style is how that stops being true.
59
61
 
60
62
  ## Installation
61
63
 
@@ -82,7 +84,7 @@ import { FormBuilder } from "@/components/FormBuilder";
82
84
  | `defaultValues` | `DefaultValues` | Initial values (create). |
83
85
  | `values` | `T` | Controlled values (edit) — the form re-syncs when this changes. |
84
86
  | `loading` | `boolean` | Submit shows a spinner; inputs disable. |
85
- | `fieldDirection` | `'horizontal' \| 'vertical'` | Row layout (auto-vertical inside a drawer). |
87
+ | `fieldDirection` | `'horizontal' \| 'vertical' \| 'flexible'` | Row layout. Unset is responsive; a `FormRenderer` drawer pins `'vertical'`, and `'flexible'` asks for the responsive layout back. |
86
88
  | `resetOnSuccess` | `boolean` | Reset to defaults after a successful submit. |
87
89
  | `form` | `UseFormReturn` | A hoisted `useForm` to bind to — pass when something outside the form must read the same values. |
88
90
  | `id` | `string` | Sets the underlying `<form id>`, so a button outside the form can submit it via `form={id}` (e.g. a drawer header's Save). |
@@ -100,7 +100,7 @@ import { FormBuilder } from "@/components/FormBuilder";
100
100
  | `resolver` | `Resolver` | Any react-hook-form resolver, e.g. `zodResolver(schema)`. |
101
101
  | `defaultValues` / `values` | `DefaultValues` / `T` | Initial values; `values` re-syncs on change (edit). |
102
102
  | `loading` / `resetOnSuccess` | `boolean` | Forwarded to `FormBuilder`. |
103
- | `fieldDirection` | `'horizontal' \| 'vertical'` | Defaults to vertical inside a drawer. |
103
+ | `fieldDirection` | `'horizontal' \| 'vertical' \| 'flexible'` | Unset means responsive: stacked, then label-beside-control once the field row passes the container `md` breakpoint. A drawer defaults to `'vertical'` pass `'flexible'` there to get the responsive layout back. |
104
104
  | `form` | `UseFormReturn<T>` | A hoisted `useForm` to bind to — pass when a sibling (e.g. a `summary` `FormSummary`) must read the same live values; the caller owns `resolver`/`defaultValues` on it. Omit to let FormRenderer create its own. |
105
105
  | `className` | `string` | Lands on FormRenderer's outermost element (page display) — e.g. `"min-h-0 flex-1"` to fill a flex column. Note this is the page frame, not the `<form>`; `FormBuilder`'s own `className` lands on the `<form>` element itself. |
106
106
  | `display` | `'page' \| 'drawer'` | `'drawer'` wraps the form in `FormDrawer`. |
@@ -363,6 +363,39 @@ function ResizableTable() {
363
363
  | `className` | `string` | - | Additional CSS classes |
364
364
  | `children` | `React.ReactNode` | - | Header rows |
365
365
 
366
+ #### Sticky header
367
+
368
+ `TableHeader` carries `position: sticky; top: 0`, so a table inside a vertically scrolling container
369
+ can keep its header in view while the rows move under it. Sticky keeps the element in normal flow,
370
+ so it changes nothing in a table that does not scroll.
371
+
372
+ It needs two things from you.
373
+
374
+ **Pass `overflow-visible`.** Sticky resolves against the **nearest scrollport**, and `Table` defaults
375
+ to `overflow-hidden` — which makes the table itself a scrollport, so the header pins to a box that
376
+ never scrolls and appears not to stick. Turning that clipping off binds it to your scroller instead.
377
+
378
+ Only do this when your scroller is `min-w-0` (or otherwise width-constrained). That default clipping
379
+ is also what stops a `w-auto` table wider than its container from pushing the whole page wide, so
380
+ opting out without a constrained scroller trades a sticky header for a horizontal scrollbar.
381
+
382
+ **Give the header an opaque background** — see below.
383
+
384
+ ```tsx
385
+ {/* `min-w-0` so a wide table scrolls in here rather than widening the layout */}
386
+ <div className="min-w-0 max-h-[400px] overflow-auto">
387
+ <Table className="w-full overflow-visible">
388
+ <TableHeader className="bg-background-presentation-form-base">
389
+ ...
390
+ ```
391
+
392
+ The default header background is translucent, which was fine when nothing ever passed beneath it.
393
+ Once rows scroll under a stuck header they read through it, so give
394
+ the header the opaque colour of whatever surface it sits on — `Table` cannot pick one for you,
395
+ since forcing a surface would recolour every table not on it. `DataViews`' table view is the worked
396
+ example: it paints the surface token as the background colour and re-applies the header tint as a
397
+ `background-image`, which stacks above it, landing on the exact colour the header always had.
398
+
366
399
  ### TableBody Props
367
400
 
368
401
  | Prop | Type | Default | Description |
@@ -257,7 +257,9 @@ it renders in the drawer header, with no manual `id` / `form={id}` wiring:
257
257
  </FormRenderer>
258
258
  ```
259
259
 
260
- 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.
261
263
 
262
264
  ---
263
265
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "torch-glare",
3
- "version": "2.5.2",
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.",