torch-glare 2.5.2 → 2.5.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.
- package/apps/lib/components/ActionButton.tsx +39 -6
- package/apps/lib/components/Badge.tsx +5 -2
- package/apps/lib/components/BadgeField.tsx +1 -1
- package/apps/lib/components/Button.tsx +4 -4
- package/apps/lib/components/Calendar.tsx +7 -17
- package/apps/lib/components/ColorPicker.tsx +1 -1
- package/apps/lib/components/DataViews/data-views.tsx +1 -1
- package/apps/lib/components/DataViews/filters/filters.tsx +1 -1
- package/apps/lib/components/DataViews/header.tsx +5 -2
- package/apps/lib/components/DataViews/panel/section.tsx +3 -1
- package/apps/lib/components/DataViews/views/board-view.tsx +3 -1
- package/apps/lib/components/DataViews/views/inbox-view.tsx +4 -1
- package/apps/lib/components/DataViews/views/pane-views.tsx +5 -1
- package/apps/lib/components/DataViews/views/table-view.tsx +67 -8
- package/apps/lib/components/DataViews/views/tree-view.tsx +5 -3
- package/apps/lib/components/Drawer.tsx +18 -1
- package/apps/lib/components/FormBuilder/context.ts +9 -1
- package/apps/lib/components/FormBuilder/submit.tsx +11 -2
- package/apps/lib/components/FormBuilder/types.ts +5 -1
- package/apps/lib/components/FormRenderer/form-renderer.tsx +15 -3
- package/apps/lib/components/FormRenderer/stepper.tsx +35 -14
- package/apps/lib/components/FormRenderer/types.ts +1 -1
- package/apps/lib/components/Input.tsx +19 -4
- package/apps/lib/components/Popover.tsx +93 -55
- package/apps/lib/components/SearchableSelect.tsx +12 -11
- package/apps/lib/components/SearchableTree.tsx +10 -11
- package/apps/lib/components/SearchableTreeDialog.tsx +10 -11
- package/apps/lib/components/SectionBlock.tsx +14 -2
- package/apps/lib/components/Select.tsx +35 -11
- package/apps/lib/components/SimpleSelect.tsx +2 -2
- package/apps/lib/components/SlideDatePicker.tsx +17 -4
- package/apps/lib/components/Stepper.tsx +329 -180
- package/apps/lib/components/Switch.tsx +2 -2
- package/apps/lib/components/Table.tsx +55 -30
- package/apps/lib/components/Textarea.tsx +29 -4
- package/apps/lib/components/TreeDropDown.tsx +18 -6
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +61 -61
- package/apps/lib/registry.json +7 -16
- package/apps/lib/tsconfig.tsbuildinfo +1 -1
- package/docs/components/action-button.md +3 -1
- package/docs/components/data-views/index.md +7 -0
- package/docs/components/form-builder.md +4 -2
- package/docs/components/form-renderer.md +1 -1
- package/docs/components/stepper.md +119 -24
- package/docs/components/table.md +33 -0
- package/docs/how-to/forms-with-form-builder.md +3 -1
- package/docs/reference/tailwind-plugins.md +42 -0
- package/docs/tutorials/getting-started.md +32 -11
- package/package.json +1 -1
- package/apps/lib/components/FormStepper.tsx +0 -272
- package/docs/components/form-stepper.md +0 -250
|
@@ -378,8 +378,10 @@ Inherits all variants from the Button component:
|
|
|
378
378
|
### Base Styles
|
|
379
379
|
|
|
380
380
|
- **Square dimensions**: Equal width and height for perfect icon centering
|
|
381
|
-
- **Rounded corners**: 4px
|
|
381
|
+
- **Rounded corners**: `radius/sm` (4px) at XS and S, `radius/lg` (8px) at M
|
|
382
382
|
- **Icon-only design**: Optimized padding for icon display
|
|
383
|
+
- **Action colours**: `action-secondary` at rest, `action-hover` on hover and
|
|
384
|
+
`action-disabled` when disabled — applied unless you pass an explicit `variant`
|
|
383
385
|
- **Inherits Button styles**: All Button component styles and behaviors
|
|
384
386
|
|
|
385
387
|
### Custom Styling
|
|
@@ -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'`
|
|
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'` |
|
|
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`. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Stepper
|
|
3
|
-
description:
|
|
3
|
+
description: The pill-shaped multi-step indicator — three semantic types (default, success, negative), horizontal or vertical, three sizes. Composed of Stepper, Step, StepIndicator, StepConnector and StepLabel.
|
|
4
4
|
component: true
|
|
5
5
|
group: Forms
|
|
6
6
|
keywords: [stepper, steps, wizard, progress, multi-step, vertical, horizontal]
|
|
@@ -8,9 +8,11 @@ keywords: [stepper, steps, wizard, progress, multi-step, vertical, horizontal]
|
|
|
8
8
|
|
|
9
9
|
# Stepper
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The step-progress component for wizards, onboarding flows, and multi-section forms, drawn as the Figma `FormStepper-1.0` pill. Each step has a semantic `type` — `default`, `success`, `negative` — and a selected state derived from `activeStep` or set explicitly per `Step`.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Not to be confused with `FormRenderer.Stepper`, which is the wizard *behaviour* (step state, validation, Back/Next) and renders this component as its rail.
|
|
14
|
+
|
|
15
|
+
The component is composed of `Stepper`, `Step`, `StepIndicator`, `StepConnector` and `StepLabel`. It is the single stepper in the library — the former `FormStepper` merged into it, so its types, states and badge live here alongside the orientation, sizes and connector.
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
16
18
|
|
|
@@ -33,7 +35,6 @@ import {
|
|
|
33
35
|
StepIndicator,
|
|
34
36
|
StepConnector,
|
|
35
37
|
StepLabel,
|
|
36
|
-
StepDescription,
|
|
37
38
|
} from '@/components/Stepper'
|
|
38
39
|
```
|
|
39
40
|
|
|
@@ -73,7 +74,7 @@ export function BasicStepper() {
|
|
|
73
74
|
}
|
|
74
75
|
```
|
|
75
76
|
|
|
76
|
-
State derivation: `index
|
|
77
|
+
State derivation: `index === activeStep` → selected. Pass `selected` on a `Step` to override it, and `type` to mark a step as `success` or `negative`.
|
|
77
78
|
|
|
78
79
|
## Examples
|
|
79
80
|
|
|
@@ -85,7 +86,6 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
85
86
|
<StepIndicator />
|
|
86
87
|
<div>
|
|
87
88
|
<StepLabel>Create account</StepLabel>
|
|
88
|
-
<StepDescription>Email and password.</StepDescription>
|
|
89
89
|
</div>
|
|
90
90
|
</Step>
|
|
91
91
|
<StepConnector />
|
|
@@ -93,7 +93,6 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
93
93
|
<StepIndicator />
|
|
94
94
|
<div>
|
|
95
95
|
<StepLabel>Verify email</StepLabel>
|
|
96
|
-
<StepDescription>Check your inbox for a code.</StepDescription>
|
|
97
96
|
</div>
|
|
98
97
|
</Step>
|
|
99
98
|
<StepConnector />
|
|
@@ -101,7 +100,6 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
101
100
|
<StepIndicator />
|
|
102
101
|
<div>
|
|
103
102
|
<StepLabel>Done</StepLabel>
|
|
104
|
-
<StepDescription>You're all set.</StepDescription>
|
|
105
103
|
</div>
|
|
106
104
|
</Step>
|
|
107
105
|
</Stepper>
|
|
@@ -116,7 +114,7 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
116
114
|
<StepLabel>Account</StepLabel>
|
|
117
115
|
</Step>
|
|
118
116
|
<StepConnector />
|
|
119
|
-
<Step index={1}
|
|
117
|
+
<Step index={1} type="negative">
|
|
120
118
|
<StepIndicator />
|
|
121
119
|
<StepLabel>Payment</StepLabel>
|
|
122
120
|
</Step>
|
|
@@ -133,7 +131,7 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
133
131
|
### Custom indicators
|
|
134
132
|
|
|
135
133
|
```tsx
|
|
136
|
-
<Step index={0}
|
|
134
|
+
<Step index={0} type="success">
|
|
137
135
|
<StepIndicator
|
|
138
136
|
completedIcon={<i className="ri-shield-check-line" />}
|
|
139
137
|
errorIcon={<i className="ri-shield-cross-line" />}
|
|
@@ -145,9 +143,108 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
145
143
|
### Sizes
|
|
146
144
|
|
|
147
145
|
```tsx
|
|
148
|
-
<Stepper size="S" activeStep={1}> {/*
|
|
149
|
-
<Stepper size="M" activeStep={1}> {/* 28px — default */} </Stepper>
|
|
150
|
-
<Stepper size="L" activeStep={1}> {/* 34px */} </Stepper>
|
|
146
|
+
<Stepper size="S" activeStep={1}> {/* 24px pill, 20px indicator */} </Stepper>
|
|
147
|
+
<Stepper size="M" activeStep={1}> {/* 28px pill, 24px indicator — default, the size Figma draws */} </Stepper>
|
|
148
|
+
<Stepper size="L" activeStep={1}> {/* 34px pill, 30px indicator */} </Stepper>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Step Types
|
|
152
|
+
|
|
153
|
+
Three semantic types. `success` and `negative` add a small status badge on the indicator (check / info icon) and use filled colors when selected. `default` uses a gray ring at rest, blue ring on hover, and a solid blue fill when selected.
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
export function StepTypes() {
|
|
157
|
+
return (
|
|
158
|
+
<Stepper>
|
|
159
|
+
<Step index={0} type="default" selected={false}>
|
|
160
|
+
<StepIndicator />
|
|
161
|
+
<StepLabel>Default</StepLabel>
|
|
162
|
+
</Step>
|
|
163
|
+
<Step index={1} type="success" selected={false}>
|
|
164
|
+
<StepIndicator />
|
|
165
|
+
<StepLabel>Success</StepLabel>
|
|
166
|
+
</Step>
|
|
167
|
+
<Step index={2} type="negative" selected={false}>
|
|
168
|
+
<StepIndicator />
|
|
169
|
+
<StepLabel>Negative</StepLabel>
|
|
170
|
+
</Step>
|
|
171
|
+
</Stepper>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Selected state
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
export function SelectedSteps() {
|
|
180
|
+
return (
|
|
181
|
+
<Stepper>
|
|
182
|
+
<Step index={0} type="default" selected>
|
|
183
|
+
<StepIndicator />
|
|
184
|
+
<StepLabel>Default</StepLabel>
|
|
185
|
+
</Step>
|
|
186
|
+
<Step index={1} type="success" selected>
|
|
187
|
+
<StepIndicator />
|
|
188
|
+
<StepLabel>Success</StepLabel>
|
|
189
|
+
</Step>
|
|
190
|
+
<Step index={2} type="negative" selected>
|
|
191
|
+
<StepIndicator />
|
|
192
|
+
<StepLabel>Negative</StepLabel>
|
|
193
|
+
</Step>
|
|
194
|
+
</Stepper>
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### RTL direction
|
|
200
|
+
|
|
201
|
+
The pill, label spacing, and indicator badge all flip under `dir="rtl"`.
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
export function RTLStepper() {
|
|
205
|
+
return (
|
|
206
|
+
<div dir="rtl">
|
|
207
|
+
<Stepper>
|
|
208
|
+
<Step index={0} type="default" selected>
|
|
209
|
+
<StepIndicator />
|
|
210
|
+
<StepLabel>افتراضي</StepLabel>
|
|
211
|
+
</Step>
|
|
212
|
+
<Step index={1} type="success">
|
|
213
|
+
<StepIndicator />
|
|
214
|
+
<StepLabel>نجاح</StepLabel>
|
|
215
|
+
</Step>
|
|
216
|
+
<Step index={2} type="negative">
|
|
217
|
+
<StepIndicator />
|
|
218
|
+
<StepLabel>خطأ</StepLabel>
|
|
219
|
+
</Step>
|
|
220
|
+
</Stepper>
|
|
221
|
+
</div>
|
|
222
|
+
)
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Custom badge icon
|
|
227
|
+
|
|
228
|
+
`StepIndicator.badgeIcon` overrides the default check / info icon for `success` / `negative` types.
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
<Step index={0} type="success" selected>
|
|
232
|
+
<StepIndicator badgeIcon={<i className="ri-shield-check-line" />} />
|
|
233
|
+
<StepLabel>Verified</StepLabel>
|
|
234
|
+
</Step>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Custom indicator content
|
|
238
|
+
|
|
239
|
+
Children of `StepIndicator` replace the auto-rendered step number.
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
<Step index={0} type="default" selected>
|
|
243
|
+
<StepIndicator>
|
|
244
|
+
<i className="ri-user-line" />
|
|
245
|
+
</StepIndicator>
|
|
246
|
+
<StepLabel>Account</StepLabel>
|
|
247
|
+
</Step>
|
|
151
248
|
```
|
|
152
249
|
|
|
153
250
|
## API Reference
|
|
@@ -166,15 +263,14 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
166
263
|
| Prop | Type | Default | Description |
|
|
167
264
|
| ------------- | --------- | ------- | ------------------------------------------------------------ |
|
|
168
265
|
| `index` | `number` | `0` | Zero-based step index. Compared with `Stepper.activeStep`. |
|
|
169
|
-
| `
|
|
170
|
-
| `
|
|
171
|
-
| `isError` | `boolean` | — | Force the error state. Overrides active and completed. |
|
|
266
|
+
| `type` | `'default' \| 'success' \| 'negative'` | `'default'` | Semantic state. `success`/`negative` fill the indicator and add a corner badge. |
|
|
267
|
+
| `selected` | `boolean` | `index === activeStep` | Force the selected state. |
|
|
172
268
|
|
|
173
269
|
### StepIndicator
|
|
174
270
|
|
|
175
271
|
| Prop | Type | Default | Description |
|
|
176
272
|
| --------------- | ----------- | ------- | ------------------------------------------------- |
|
|
177
|
-
| `icon` | `ReactNode` | — | Replaces the step number
|
|
273
|
+
| `icon` | `ReactNode` | — | Replaces the step number. |
|
|
178
274
|
| `completedIcon` | `ReactNode` | — | Replaces the default check icon when completed. |
|
|
179
275
|
| `errorIcon` | `ReactNode` | — | Replaces the default close icon on error. |
|
|
180
276
|
|
|
@@ -182,7 +278,7 @@ State derivation: `index < activeStep` → `completed`, `index === activeStep`
|
|
|
182
278
|
|
|
183
279
|
The line between steps. No props beyond standard HTML attributes — orientation comes from the parent `Stepper`.
|
|
184
280
|
|
|
185
|
-
### StepLabel
|
|
281
|
+
### StepLabel
|
|
186
282
|
|
|
187
283
|
Forward `HTMLAttributes<HTMLDivElement>`. Their colors follow the parent `Step` state automatically.
|
|
188
284
|
|
|
@@ -192,7 +288,7 @@ Forward `HTMLAttributes<HTMLDivElement>`. Their colors follow the parent `Step`
|
|
|
192
288
|
- Active: blue informational background + focus ring.
|
|
193
289
|
- Completed: green success background and ring; check icon.
|
|
194
290
|
- Error: red negative background and ring; close icon.
|
|
195
|
-
- Connectors: `
|
|
291
|
+
- Connectors: `3px` rounded bar, `border-presentation-stepper-default` by default and focus-blue when `completed` is set. Vertically it centres itself under the indicator, tracking the stepper's size.
|
|
196
292
|
|
|
197
293
|
## TypeScript Types
|
|
198
294
|
|
|
@@ -204,18 +300,17 @@ type StepperVariants = VariantProps<typeof stepperStyles>
|
|
|
204
300
|
// { orientation?: 'horizontal' | 'vertical' }
|
|
205
301
|
|
|
206
302
|
type IndicatorVariants = VariantProps<typeof stepIndicatorStyles>
|
|
207
|
-
// {
|
|
303
|
+
// { type?: 'default' | 'success' | 'negative'; selected?: boolean; size?: 'S' | 'M' | 'L' }
|
|
208
304
|
```
|
|
209
305
|
|
|
210
306
|
## Accessibility
|
|
211
307
|
|
|
212
308
|
- Wrap the stepper in a `<nav aria-label="Progress">` when it represents real navigation.
|
|
213
309
|
- Use `aria-current="step"` on the active step's container when steps are interactive.
|
|
214
|
-
- Don't rely on
|
|
310
|
+
- Don't rely on colour alone for the negative type — pair it with an off-screen message.
|
|
215
311
|
|
|
216
312
|
## Best Practices
|
|
217
313
|
|
|
218
|
-
1.
|
|
314
|
+
1. Add `StepConnector` between steps when you want the run of progress drawn; leave it out for a bare row of pills.
|
|
219
315
|
2. Keep `Step` count to 3–5 horizontal, 3–7 vertical. Beyond that, switch to a checklist or summary.
|
|
220
|
-
3. Drive
|
|
221
|
-
4. Provide a `StepDescription` only on vertical steppers — descriptions wrap horizontal layouts awkwardly.
|
|
316
|
+
3. Drive selection from `activeStep` in the parent — only fall back to `selected` for non-linear flows.
|
package/docs/components/table.md
CHANGED
|
@@ -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
|
|
|
@@ -273,6 +273,8 @@ The TORCH mode plugin provides the actual color values and theme-specific styles
|
|
|
273
273
|
- 500+ CSS custom properties
|
|
274
274
|
- Gradient and alpha channel support
|
|
275
275
|
- Comprehensive color palette
|
|
276
|
+
- The shared **radius**, **container** and **breakpoint** scales (exported as
|
|
277
|
+
`borderRadius`, `containers` and `screens`)
|
|
276
278
|
|
|
277
279
|
### Installation
|
|
278
280
|
|
|
@@ -280,6 +282,46 @@ The TORCH mode plugin provides the actual color values and theme-specific styles
|
|
|
280
282
|
npm install glare-torch-mode
|
|
281
283
|
```
|
|
282
284
|
|
|
285
|
+
### The radius scale
|
|
286
|
+
|
|
287
|
+
`borderRadius` produces the `rounded-radius-*` classes the components are built on — Button, Badge,
|
|
288
|
+
the shared `Input` field root, ActionButton, Select and TextArea all use them. The keys mirror the
|
|
289
|
+
Figma `radius/*` collection:
|
|
290
|
+
|
|
291
|
+
| class | value | | class | value |
|
|
292
|
+
|---|---|---|---|---|
|
|
293
|
+
| `rounded-radius-none` | 0px | | `rounded-radius-2xl` | 16px |
|
|
294
|
+
| `rounded-radius-xs` | 2px | | `rounded-radius-3xl` | 24px |
|
|
295
|
+
| `rounded-radius-sm` | 4px | | `rounded-radius-4xl` | 32px |
|
|
296
|
+
| `rounded-radius-md` | 6px | | `rounded-radius-5xl` | 40px |
|
|
297
|
+
| `rounded-radius-lg` | 8px | | `rounded-radius-6xl` | 48px |
|
|
298
|
+
| `rounded-radius-xl` | 12px | | `rounded-radius-round` | 9999px |
|
|
299
|
+
|
|
300
|
+
Deliberately **not** reusing Tailwind's own `sm`/`md`/`lg` keys: that would override the built-in
|
|
301
|
+
scale, where Glare's `sm` is 4px and Tailwind's is 2px, silently restyling every existing
|
|
302
|
+
`rounded-sm`.
|
|
303
|
+
|
|
304
|
+
Note that `tailwind-merge` does not dedupe these classes — they are custom scale keys, not values it
|
|
305
|
+
recognises. Never put a `rounded-radius-*` on a `cva` base *and* on one of its variants: both survive
|
|
306
|
+
and CSS source order decides the winner. Put it only on the variants.
|
|
307
|
+
|
|
308
|
+
### Tailwind v4
|
|
309
|
+
|
|
310
|
+
The plugin is a plain `addBase` function, so under v4 `@plugin` registers the colour variables but
|
|
311
|
+
**not** the scales — those reach Tailwind through `theme.extend` in a JS config, which v4 does not
|
|
312
|
+
have. Import the theme file as well (requires **1.4.0 or newer**):
|
|
313
|
+
|
|
314
|
+
```css
|
|
315
|
+
@import "tailwindcss";
|
|
316
|
+
@import "glare-torch-mode/theme.css"; /* must precede the @plugin rules */
|
|
317
|
+
@plugin "glare-torch-mode";
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Without it `rounded-radius-*` is never generated and `sm:` / `@md:` fall back to Tailwind's values.
|
|
321
|
+
Two v4-only caveats: the container scale is shared with `max-w-*`, so `--container-md` also sets
|
|
322
|
+
`max-w-md` to 650px; and the plugin's `--radius-*` variables land in v4's own border-radius
|
|
323
|
+
namespace — matching values, but `px` where Tailwind uses `rem`.
|
|
324
|
+
|
|
283
325
|
### Setup (Required with mapping-color-system)
|
|
284
326
|
|
|
285
327
|
```ts
|
|
@@ -104,6 +104,13 @@ Add the following to your `global.css` file:
|
|
|
104
104
|
(e.g. Badge renders with no background). Keep it directly under
|
|
105
105
|
@import "tailwindcss". */
|
|
106
106
|
@import "mapping-color-system-v4/tailwindVars.css";
|
|
107
|
+
/* Required, and needs glare-torch-mode >= 1.4.0. The plugin only registers the colour
|
|
108
|
+
variables; the radius scale, container sizes and breakpoints reach Tailwind through
|
|
109
|
+
`theme.extend` in a JS config, which v4 does not have. Without this the
|
|
110
|
+
`rounded-radius-*` classes are never generated (square corners on Button, Badge,
|
|
111
|
+
Input, ActionButton, Select, TextArea) and `sm:` / `@md:` fall back to Tailwind's
|
|
112
|
+
own values. Same @import-ordering rule as above applies. */
|
|
113
|
+
@import "glare-torch-mode/theme.css";
|
|
107
114
|
@plugin "glare-torch-mode";
|
|
108
115
|
@plugin "tailwind-scrollbar-hide";
|
|
109
116
|
@plugin "tailwindcss-animate";
|
|
@@ -111,6 +118,14 @@ Add the following to your `global.css` file:
|
|
|
111
118
|
@plugin "mapping-color-system-v4";
|
|
112
119
|
```
|
|
113
120
|
|
|
121
|
+
Two version-4-only caveats:
|
|
122
|
+
|
|
123
|
+
- Tailwind 4 shares the container scale with `max-w-*`, so `--container-md` also sets `max-w-md`
|
|
124
|
+
to 650px.
|
|
125
|
+
- The plugin sets `--radius-*` on `:root`, which is Tailwind 4's own border-radius namespace. The
|
|
126
|
+
values match its defaults (2/4/6/8/12/16/24/32px) but are declared in `px` where Tailwind uses
|
|
127
|
+
`rem`, so they diverge if you change the root font size.
|
|
128
|
+
|
|
114
129
|
> ⚠️ **Common failure:** if your Badge (or any component using
|
|
115
130
|
> `bg-background-presentation-*` colors) renders with no background, the
|
|
116
131
|
> `tailwindVars.css` `@import` is almost certainly positioned **after** the
|
|
@@ -130,6 +145,8 @@ Then configure your `tailwind.config.js`:
|
|
|
130
145
|
|
|
131
146
|
```js
|
|
132
147
|
const { plugin, mappingVars } = require('mapping-color-system')
|
|
148
|
+
// Design tokens plus the shared radius / container / screen scales.
|
|
149
|
+
const torchMode = require('glare-torch-mode')
|
|
133
150
|
|
|
134
151
|
module.exports = {
|
|
135
152
|
content: [
|
|
@@ -139,26 +156,22 @@ module.exports = {
|
|
|
139
156
|
theme: {
|
|
140
157
|
extend: {
|
|
141
158
|
colors: mappingVars,
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
sm: "600px",
|
|
145
|
-
md: "768px",
|
|
146
|
-
lg: "1024px",
|
|
147
|
-
xl: "1280px",
|
|
148
|
-
"2xl": "1536px",
|
|
149
|
-
},
|
|
159
|
+
borderRadius: torchMode.borderRadius,
|
|
160
|
+
containers: torchMode.containers,
|
|
150
161
|
},
|
|
151
162
|
},
|
|
163
|
+
// Top level, not inside extend — this replaces Tailwind's breakpoints.
|
|
164
|
+
screens: torchMode.screens,
|
|
152
165
|
plugins: [
|
|
153
166
|
plugin,
|
|
154
167
|
require('@tailwindcss/container-queries'),
|
|
155
168
|
require('tailwindcss-animate'),
|
|
156
169
|
require('tailwind-scrollbar-hide'),
|
|
157
170
|
require('glare-typography'),
|
|
158
|
-
|
|
171
|
+
torchMode,
|
|
159
172
|
function ({ addVariant }) {
|
|
160
|
-
addVariant("rtl", '&[dir="rtl"]');
|
|
161
|
-
addVariant("ltr", '&[dir="ltr"]');
|
|
173
|
+
addVariant("rtl", ['&[dir="rtl"]', '[dir="rtl"] &']);
|
|
174
|
+
addVariant("ltr", ['&[dir="ltr"]', '[dir="ltr"] &']);
|
|
162
175
|
},
|
|
163
176
|
],
|
|
164
177
|
};
|
|
@@ -168,6 +181,14 @@ Important:
|
|
|
168
181
|
- Specify the component path in the `content` array matching your `glare.json` path
|
|
169
182
|
- Add all plugins to the `plugins` array
|
|
170
183
|
- Add `mappingVars` to the `extend.colors` object
|
|
184
|
+
- Take `borderRadius`, `containers` and `screens` from `glare-torch-mode` rather than hardcoding
|
|
185
|
+
them. `borderRadius` is what produces the `rounded-radius-*` classes the components are built on;
|
|
186
|
+
without it Button, Badge, Input, ActionButton, Select and TextArea render with square corners.
|
|
187
|
+
- Put `screens` at the **top level**, not inside `extend`, so Glare's breakpoints replace
|
|
188
|
+
Tailwind's rather than being added alongside them (`sm` is 600px, not 640px).
|
|
189
|
+
- Register `rtl` / `ltr` with **both** selectors. `&[dir="rtl"]` alone only matches an element that
|
|
190
|
+
carries the attribute itself, so an `rtl:` class on a component nested inside an RTL wrapper never
|
|
191
|
+
applies.
|
|
171
192
|
|
|
172
193
|
---
|
|
173
194
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "torch-glare",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.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.",
|