torch-glare 2.4.1 → 2.4.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.
- package/apps/lib/components/Button.tsx +1 -1
- package/apps/lib/components/Card.tsx +47 -20
- package/apps/lib/components/ColorPicker.tsx +441 -0
- package/apps/lib/components/ConclusionHeader.tsx +148 -0
- package/apps/lib/components/DatePicker.tsx +2 -0
- package/apps/lib/components/Drawer.tsx +66 -24
- package/apps/lib/components/FormBuilder/context.ts +68 -0
- package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +60 -0
- package/apps/lib/components/FormBuilder/fields/ColorField.tsx +59 -0
- package/apps/lib/components/FormBuilder/fields/CustomField.tsx +11 -0
- package/apps/lib/components/FormBuilder/fields/DateField.tsx +32 -0
- package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +74 -0
- package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +148 -0
- package/apps/lib/components/FormBuilder/fields/FileField.tsx +39 -0
- package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +132 -0
- package/apps/lib/components/FormBuilder/fields/OtpField.tsx +31 -0
- package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +83 -0
- package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +31 -0
- package/apps/lib/components/FormBuilder/fields/SelectField.tsx +91 -0
- package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +157 -0
- package/apps/lib/components/FormBuilder/fields/SliderField.tsx +67 -0
- package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +41 -0
- package/apps/lib/components/FormBuilder/fields/TableField.tsx +308 -0
- package/apps/lib/components/FormBuilder/fields/TextField.tsx +213 -0
- package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +43 -0
- package/apps/lib/components/FormBuilder/fields/countries.ts +303 -0
- package/apps/lib/components/FormBuilder/fields/index.ts +25 -0
- package/apps/lib/components/FormBuilder/form-builder.tsx +279 -0
- package/apps/lib/components/FormBuilder/header.tsx +101 -0
- package/apps/lib/components/FormBuilder/index.ts +33 -0
- package/apps/lib/components/FormBuilder/numberFormat.ts +16 -0
- package/apps/lib/components/FormBuilder/stepper.tsx +290 -0
- package/apps/lib/components/FormBuilder/submit.tsx +38 -0
- package/apps/lib/components/FormBuilder/types.ts +261 -0
- package/apps/lib/components/FormRenderer/FormDrawer.tsx +128 -0
- package/apps/lib/components/FormRenderer/form-renderer.tsx +111 -0
- package/apps/lib/components/FormRenderer/index.ts +4 -0
- package/apps/lib/components/FormRenderer/types.ts +77 -0
- package/apps/lib/components/FormSummary.tsx +282 -0
- package/apps/lib/components/ImageAttachment.tsx +36 -61
- package/apps/lib/components/Label.tsx +49 -42
- package/apps/lib/components/Popover.tsx +6 -2
- package/apps/lib/components/RadioCard.tsx +2 -0
- package/apps/lib/components/SearchableSelect.tsx +16 -5
- package/apps/lib/components/SectionBlock.tsx +16 -8
- package/apps/lib/components/Select.tsx +41 -120
- package/apps/lib/components/TextEditor/RichTextField.tsx +46 -0
- package/apps/lib/components/{TextEditor.tsx → TextEditor/TextEditor.tsx} +63 -9
- package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +429 -0
- package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +70 -0
- package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +50 -0
- package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +48 -0
- package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +98 -0
- package/apps/lib/{types → components/TextEditor}/editorjs.d.ts +19 -0
- package/apps/lib/components/TextEditor/index.ts +7 -0
- package/apps/lib/components/Textarea.tsx +1 -1
- package/apps/lib/layouts/FieldSection.tsx +25 -22
- package/apps/lib/registry.json +51 -58
- package/apps/lib/tsconfig.tsbuildinfo +1 -0
- package/apps/lib/utils/color.ts +175 -0
- package/dist/src/shared/tailwindInit.d.ts.map +1 -1
- package/dist/src/shared/tailwindInit.js +3 -0
- package/dist/src/shared/tailwindInit.js.map +1 -1
- package/docs/components/card.md +4 -2
- package/docs/components/chart-block-tool.md +5 -4
- package/docs/components/color-picker.md +101 -0
- package/docs/components/conclusion-header.md +80 -0
- package/docs/components/drawer.md +153 -102
- package/docs/components/form-builder.md +260 -0
- package/docs/components/form-renderer.md +234 -0
- package/docs/components/form-summary.md +123 -0
- package/docs/components/image-attachment.md +10 -4
- package/docs/components/searchable-select.md +50 -46
- package/docs/components/table-dnd-wrapper.md +5 -3
- package/docs/components/text-editor.md +18 -0
- package/docs/how-to/form-and-list-recipes.md +26 -19
- package/docs/how-to/forms-with-form-builder.md +411 -0
- package/docs/how-to/guides.md +153 -179
- package/docs/reference/tailwind-plugins.md +11 -1
- package/docs/tutorials/building-first-form.md +150 -159
- package/docs/tutorials/getting-started.md +9 -0
- package/package.json +1 -1
- /package/apps/lib/components/{ChartBlockTool.ts → TextEditor/ChartBlockTool.ts} +0 -0
- /package/apps/lib/components/{TableDnDWrapper.ts → TextEditor/TableDnDWrapper.ts} +0 -0
- /package/apps/lib/{utils → components/TextEditor}/markdownParser.ts +0 -0
|
@@ -168,70 +168,73 @@ function ArabicPicker({ options, value, onValueChange }) {
|
|
|
168
168
|
|
|
169
169
|
### SearchableSelect
|
|
170
170
|
|
|
171
|
-
| Prop
|
|
172
|
-
|
|
173
|
-
| `options`
|
|
174
|
-
| `value`
|
|
175
|
-
| `onValueChange`
|
|
176
|
-
| `placeholder`
|
|
177
|
-
| `size`
|
|
178
|
-
| `variant`
|
|
179
|
-
| `icon`
|
|
180
|
-
| `theme`
|
|
181
|
-
| `dir`
|
|
182
|
-
| `className`
|
|
183
|
-
| `filterClientSide` | `boolean`
|
|
184
|
-
| `onSearchChange`
|
|
185
|
-
| `searchDebounceMs` | `number`
|
|
186
|
-
| `hasMore`
|
|
187
|
-
| `loading`
|
|
188
|
-
| `onLoadMore`
|
|
189
|
-
| `maxVisibleItems`
|
|
171
|
+
| Prop | Type | Default | Description |
|
|
172
|
+
| ------------------ | --------------------------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
173
|
+
| `options` | `SearchableSelectOption[]` | Required | The list of selectable options. In server mode (`filterClientSide={false}`) these are rendered as-is. |
|
|
174
|
+
| `value` | `string \| null` | - | Controlled selected value. The matching option's label is shown as solid text in the input. |
|
|
175
|
+
| `onValueChange` | `(value: string, option: SearchableSelectOption) => void` | - | Called when an option is selected. Receives the value and the full option object. |
|
|
176
|
+
| `placeholder` | `string` | `'Search…'` | Placeholder text for the search input. |
|
|
177
|
+
| `size` | `'XS' \| 'S' \| 'M'` | `'M'` | Field size. |
|
|
178
|
+
| `variant` | `'PresentationStyle'` | `'PresentationStyle'` | Visual style variant for the field and dropdown surface. |
|
|
179
|
+
| `icon` | `ReactNode` | - | Optional leading icon rendered inside the field. |
|
|
180
|
+
| `theme` | `'dark' \| 'light' \| 'default'` | - | Theme variant, applied via `data-theme`. |
|
|
181
|
+
| `dir` | `string` | - | Text direction (e.g. `'rtl'`) for the field and dropdown. |
|
|
182
|
+
| `className` | `string` | - | Additional CSS classes for the field group. |
|
|
183
|
+
| `filterClientSide` | `boolean` | `true` | When `true`, filters `options` locally by label. Set `false` for server-side search — `options` are rendered as-is and refetched via `onSearchChange`. |
|
|
184
|
+
| `onSearchChange` | `(query: string) => void` | - | Called (debounced) with the trimmed query as the user types. Refetch your data here for server-side search. |
|
|
185
|
+
| `searchDebounceMs` | `number` | `300` | Debounce delay (ms) before `onSearchChange` fires. |
|
|
186
|
+
| `hasMore` | `boolean` | `false` | Whether more pages are available; gates the infinite-scroll loader. |
|
|
187
|
+
| `loading` | `boolean` | `false` | Whether a fetch is in flight; shows a loading row and blocks `onLoadMore`. |
|
|
188
|
+
| `onLoadMore` | `() => void` | - | Called when the scroll viewport nears the bottom and `hasMore && !loading`. |
|
|
189
|
+
| `maxVisibleItems` | `number` | `5` | Maximum rows visible before the list scrolls internally. |
|
|
190
190
|
|
|
191
191
|
### SearchableSelectOption
|
|
192
192
|
|
|
193
|
-
| Prop
|
|
194
|
-
|
|
195
|
-
| `value`
|
|
196
|
-
| `label`
|
|
197
|
-
| `icon`
|
|
193
|
+
| Prop | Type | Default | Description |
|
|
194
|
+
| ------------ | ----------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
195
|
+
| `value` | `string` | Required | Unique value for the option; matched against the `value` prop. |
|
|
196
|
+
| `label` | `string` | Required | Display text; also the default target for client-side filtering. |
|
|
197
|
+
| `icon` | `ReactNode` | - | Optional leading icon rendered in the row. |
|
|
198
|
+
| `searchText` | `string` | `label` | Text used for client-side filtering. Set it to match on a **subset** of the label — e.g. a country name when the label also shows a dial code, so typing the dial doesn't match. |
|
|
198
199
|
|
|
199
200
|
## TypeScript
|
|
200
201
|
|
|
201
202
|
### Type Definitions
|
|
202
203
|
|
|
203
204
|
```typescript
|
|
204
|
-
import { ReactNode } from
|
|
205
|
+
import { ReactNode } from "react";
|
|
205
206
|
|
|
206
207
|
export interface SearchableSelectOption {
|
|
207
|
-
value: string
|
|
208
|
-
label: string
|
|
209
|
-
icon?: ReactNode
|
|
208
|
+
value: string;
|
|
209
|
+
label: string;
|
|
210
|
+
icon?: ReactNode;
|
|
211
|
+
/** Text used for client-side filtering. Defaults to `label`. */
|
|
212
|
+
searchText?: string;
|
|
210
213
|
}
|
|
211
214
|
|
|
212
215
|
interface SearchableSelectProps {
|
|
213
|
-
options: SearchableSelectOption[]
|
|
214
|
-
value?: string | null
|
|
215
|
-
onValueChange?: (value: string, option: SearchableSelectOption) => void
|
|
216
|
-
placeholder?: string
|
|
217
|
-
size?:
|
|
218
|
-
variant?:
|
|
219
|
-
icon?: ReactNode
|
|
220
|
-
theme?:
|
|
221
|
-
dir?: string
|
|
222
|
-
className?: string
|
|
216
|
+
options: SearchableSelectOption[];
|
|
217
|
+
value?: string | null;
|
|
218
|
+
onValueChange?: (value: string, option: SearchableSelectOption) => void;
|
|
219
|
+
placeholder?: string;
|
|
220
|
+
size?: "XS" | "S" | "M";
|
|
221
|
+
variant?: "PresentationStyle";
|
|
222
|
+
icon?: ReactNode;
|
|
223
|
+
theme?: "dark" | "light" | "default";
|
|
224
|
+
dir?: string;
|
|
225
|
+
className?: string;
|
|
223
226
|
|
|
224
227
|
// Async / backend pagination (all optional; static `options` still work)
|
|
225
|
-
filterClientSide?: boolean
|
|
226
|
-
onSearchChange?: (query: string) => void
|
|
227
|
-
searchDebounceMs?: number
|
|
228
|
-
hasMore?: boolean
|
|
229
|
-
loading?: boolean
|
|
230
|
-
onLoadMore?: () => void
|
|
231
|
-
maxVisibleItems?: number
|
|
228
|
+
filterClientSide?: boolean;
|
|
229
|
+
onSearchChange?: (query: string) => void;
|
|
230
|
+
searchDebounceMs?: number;
|
|
231
|
+
hasMore?: boolean;
|
|
232
|
+
loading?: boolean;
|
|
233
|
+
onLoadMore?: () => void;
|
|
234
|
+
maxVisibleItems?: number;
|
|
232
235
|
}
|
|
233
236
|
|
|
234
|
-
export function SearchableSelect(props: SearchableSelectProps): JSX.Element
|
|
237
|
+
export function SearchableSelect(props: SearchableSelectProps): JSX.Element;
|
|
235
238
|
```
|
|
236
239
|
|
|
237
240
|
## Common Patterns
|
|
@@ -340,6 +343,7 @@ function UserPicker() {
|
|
|
340
343
|
## Best Practices
|
|
341
344
|
|
|
342
345
|
1. **Always control `value`** — pass `value` and `onValueChange` so the input can display the selected label.
|
|
346
|
+
|
|
343
347
|
```typescript
|
|
344
348
|
<SearchableSelect value={value} onValueChange={setValue} options={options} />
|
|
345
349
|
```
|
|
@@ -27,13 +27,15 @@ TORCH Glare is a copy-in library: the CLI copies this module's source into your
|
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
29
|
npx torch-glare@latest init
|
|
30
|
-
npx torch-glare@latest add
|
|
30
|
+
npx torch-glare@latest add TextEditor
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
`createTableDnDClass` ships as part of the `TextEditor` folder, so `add TextEditor` copies it in.
|
|
34
|
+
|
|
33
35
|
## Import
|
|
34
36
|
|
|
35
37
|
```typescript
|
|
36
|
-
import createTableDnDClass from "@/components/
|
|
38
|
+
import { createTableDnDClass } from "@/components/TextEditor";
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
## Quick Examples
|
|
@@ -43,7 +45,7 @@ import createTableDnDClass from "@/components/TableDnDWrapper";
|
|
|
43
45
|
```typescript
|
|
44
46
|
import EditorJS from "@editorjs/editorjs";
|
|
45
47
|
import Table from "@editorjs/table";
|
|
46
|
-
import createTableDnDClass from "@/components/
|
|
48
|
+
import { createTableDnDClass } from "@/components/TextEditor";
|
|
47
49
|
|
|
48
50
|
// Wrap the original table tool to add row/column drag-and-drop.
|
|
49
51
|
const TableWithDnD = createTableDnDClass(Table);
|
|
@@ -260,8 +260,26 @@ function MarkdownEditor() {
|
|
|
260
260
|
| `tools` | `Record<string, any>` | Default 18+ tools | Override the Editor.js tools configuration |
|
|
261
261
|
| `minHeight` | `number` | - | Custom min-height in pixels (overrides size) |
|
|
262
262
|
| `disabled` | `boolean` | `false` | Disables interaction with reduced opacity |
|
|
263
|
+
| `toolbar` | `boolean` | `true` | Show the fixed formatting toolbar. Auto-hidden when `readOnly`/`disabled`. |
|
|
263
264
|
| `className` | `string` | - | Additional CSS classes |
|
|
264
265
|
|
|
266
|
+
### Formatting toolbar
|
|
267
|
+
|
|
268
|
+
A fixed, sticky toolbar sits at the top of the editor (shown by default; pass `toolbar={false}`
|
|
269
|
+
to hide it, and it is automatically hidden in `readOnly`/`disabled` editors). It drives the
|
|
270
|
+
underlying Editor.js instance and offers:
|
|
271
|
+
|
|
272
|
+
- **History** — undo / redo (via `editorjs-undo`; also bound to `Ctrl/⌘+Z` / `Ctrl/⌘+Y`).
|
|
273
|
+
- **Block type** — a dropdown to switch between Normal text and Heading 1–3 (`blocks.convert`).
|
|
274
|
+
- **Alignment** — left / center / right (a block tune persisted on each block).
|
|
275
|
+
- **Text color** — a swatch palette.
|
|
276
|
+
- **Inline** — bold, italic, underline, strikethrough, clear formatting.
|
|
277
|
+
- **Lists** — bullet and ordered.
|
|
278
|
+
- **Insert image** — from a local file (inserted as an `image` block).
|
|
279
|
+
|
|
280
|
+
Strikethrough and color are backed by small custom inline tools whose `sanitize` allowlists let
|
|
281
|
+
that markup survive `save()`; alignment persists as a block tune.
|
|
282
|
+
|
|
265
283
|
### Ref Methods (TextEditorRef)
|
|
266
284
|
|
|
267
285
|
| Method | Signature | Description |
|
|
@@ -10,6 +10,13 @@ Battle-tested layouts and component combinations from production frontend work.
|
|
|
10
10
|
Use these as the starting point for create dialogs, list/filter pages,
|
|
11
11
|
line-item grids, and login flows.
|
|
12
12
|
|
|
13
|
+
> **For actual forms, reach for [`FormBuilder`](../components/form-builder.md) first.** The
|
|
14
|
+
> multi-column form rows below are a layout escape hatch for the rare case that needs bespoke
|
|
15
|
+
> positioning — they are **not** the default way to build a form. A normal create/edit form is
|
|
16
|
+
> `FormBuilder` fields as JSX children with a resolver; see the
|
|
17
|
+
> [Forms with FormBuilder](./forms-with-form-builder.md) guide. Don't hand-wire `FormField` /
|
|
18
|
+
> `InputField` rows or hold field state in `useState` when `FormBuilder` would do it.
|
|
19
|
+
|
|
13
20
|
> All examples use the `presentation` color tokens. Never substitute
|
|
14
21
|
> `*-system-*` tokens or `variant="SystemStyle"` — see the rules banner at
|
|
15
22
|
> the top of every doc response.
|
|
@@ -76,7 +83,9 @@ the same filter bar — a search input + one or more select filters above a
|
|
|
76
83
|
data table.
|
|
77
84
|
|
|
78
85
|
```tsx
|
|
79
|
-
{
|
|
86
|
+
{
|
|
87
|
+
/* Filter bar */
|
|
88
|
+
}
|
|
80
89
|
<div className="flex items-center gap-3">
|
|
81
90
|
<div className="flex-1 max-w-sm">
|
|
82
91
|
<InputField
|
|
@@ -99,9 +108,11 @@ data table.
|
|
|
99
108
|
]}
|
|
100
109
|
placeholder="All Statuses"
|
|
101
110
|
/>
|
|
102
|
-
</div
|
|
111
|
+
</div>;
|
|
103
112
|
|
|
104
|
-
{
|
|
113
|
+
{
|
|
114
|
+
/* Data table */
|
|
115
|
+
}
|
|
105
116
|
<Card className="p-0 overflow-hidden">
|
|
106
117
|
<CardContent className="p-0 overflow-x-auto">
|
|
107
118
|
<Table className="w-full">
|
|
@@ -122,9 +133,7 @@ data table.
|
|
|
122
133
|
>
|
|
123
134
|
<i className="ri-inbox-line text-4xl opacity-60" />
|
|
124
135
|
<p className="typography-body-medium-regular">No vouchers</p>
|
|
125
|
-
<p className="typography-body-small-regular opacity-80">
|
|
126
|
-
Try adjusting your filters
|
|
127
|
-
</p>
|
|
136
|
+
<p className="typography-body-small-regular opacity-80">Try adjusting your filters</p>
|
|
128
137
|
</TableCell>
|
|
129
138
|
</TableRow>
|
|
130
139
|
) : (
|
|
@@ -144,7 +153,7 @@ data table.
|
|
|
144
153
|
</TableBody>
|
|
145
154
|
</Table>
|
|
146
155
|
</CardContent>
|
|
147
|
-
</Card
|
|
156
|
+
</Card>;
|
|
148
157
|
```
|
|
149
158
|
|
|
150
159
|
Key rules:
|
|
@@ -263,15 +272,15 @@ hierarchy. Adding a relevant icon makes dialogs instantly recognizable.
|
|
|
263
272
|
|
|
264
273
|
Pick an icon that matches the entity:
|
|
265
274
|
|
|
266
|
-
| Entity
|
|
267
|
-
|
|
268
|
-
| Account
|
|
269
|
-
| Fiscal period / year | `ri-calendar-line`
|
|
270
|
-
| Voucher / journal
|
|
271
|
-
| Number series
|
|
272
|
-
| Posting rule
|
|
273
|
-
| Exchange rate
|
|
274
|
-
| Bank / cash account
|
|
275
|
+
| Entity | Icon |
|
|
276
|
+
| -------------------- | -------------------- |
|
|
277
|
+
| Account | `ri-bank-line` |
|
|
278
|
+
| Fiscal period / year | `ri-calendar-line` |
|
|
279
|
+
| Voucher / journal | `ri-receipt-line` |
|
|
280
|
+
| Number series | `ri-hashtag` |
|
|
281
|
+
| Posting rule | `ri-settings-3-line` |
|
|
282
|
+
| Exchange rate | `ri-exchange-line` |
|
|
283
|
+
| Bank / cash account | `ri-bank-card-line` |
|
|
275
284
|
|
|
276
285
|
---
|
|
277
286
|
|
|
@@ -297,9 +306,7 @@ export function LoginPage() {
|
|
|
297
306
|
"to-background-presentation-state-information/10",
|
|
298
307
|
].join(" ")}
|
|
299
308
|
>
|
|
300
|
-
<h1 className="typography-headers-large-medium">
|
|
301
|
-
Welcome to Torch Finance
|
|
302
|
-
</h1>
|
|
309
|
+
<h1 className="typography-headers-large-medium">Welcome to Torch Finance</h1>
|
|
303
310
|
<ul className="flex flex-col gap-3">
|
|
304
311
|
{features.map((f) => (
|
|
305
312
|
<li key={f.title} className="flex items-start gap-3">
|