@timeax/form-palette 0.1.16 → 0.1.18
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/README.md +306 -241
- package/dist/{core-BFcyKS5S.d.ts → core-1lO-bk72.d.ts} +77 -4
- package/dist/{core-B0VZEMYY.d.mts → core-BgfUlhu0.d.mts} +77 -4
- package/dist/extra.d.mts +2 -2
- package/dist/extra.d.ts +2 -2
- package/dist/extra.js +2597 -616
- package/dist/extra.js.map +1 -1
- package/dist/extra.mjs +2522 -541
- package/dist/extra.mjs.map +1 -1
- package/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +2017 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2018 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +97 -96
package/README.md
CHANGED
|
@@ -1,132 +1,58 @@
|
|
|
1
|
-
# Index
|
|
2
|
-
|
|
3
|
-
- [
|
|
4
|
-
- [
|
|
5
|
-
|
|
6
|
-
- [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
- [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
- [
|
|
32
|
-
- [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- [
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- [radio](#radio) 940-999
|
|
49
|
-
- [Variant props](#variant-props-4) 942-967
|
|
50
|
-
- [Supported option shapes](#supported-option-shapes) 969-972
|
|
51
|
-
- [Sample usage](#sample-usage-1) 974-999
|
|
52
|
-
- [select](#select) 1001-1077
|
|
53
|
-
- [Variant props](#variant-props-5) 1003-1048
|
|
54
|
-
- [Sample usage](#sample-usage-2) 1050-1077
|
|
55
|
-
- [checkbox](#checkbox) 1079-1147
|
|
56
|
-
- [chips](#chips) 1149-1202
|
|
57
|
-
- [color](#color) 1204-1234
|
|
58
|
-
- [date](#date) 1236-1283
|
|
59
|
-
- [Variant props](#variant-props-6) 1238-1256
|
|
60
|
-
- [Sample usage](#sample-usage-3) 1258-1283
|
|
61
|
-
- [keyvalue](#keyvalue) 1285-1335
|
|
62
|
-
- [Variant props](#variant-props-7) 1287-1307
|
|
63
|
-
- [Sample usage](#sample-usage-4) 1309-1335
|
|
64
|
-
- [editor](#editor) 1337-1381
|
|
65
|
-
- [Variant props](#variant-props-8) 1339-1356
|
|
66
|
-
- [Sample usage](#sample-usage-5) 1358-1381
|
|
67
|
-
- [file](#file) 1383-1460
|
|
68
|
-
- [Variant props](#variant-props-9) 1385-1411
|
|
69
|
-
- [Mode and trigger props](#mode-and-trigger-props-1) 1413-1435
|
|
70
|
-
- [Sample usage](#sample-usage-6) 1437-1460
|
|
71
|
-
- [json-editor](#json-editor) 1462-1542
|
|
72
|
-
- [Wrapper / trigger props](#wrapper-trigger-props) 1464-1482
|
|
73
|
-
- [Editor props (passed into the JSON editor)](#editor-props-passed-into-the-json-editor) 1484-1504
|
|
74
|
-
- [Sample usage](#sample-usage-7) 1506-1542
|
|
75
|
-
- [lister](#lister) 1544-1644
|
|
76
|
-
- [Data + mapping props](#data-mapping-props) 1546-1563
|
|
77
|
-
- [Selection + behaviour props](#selection-behaviour-props) 1565-1584
|
|
78
|
-
- [Trigger styling + container props](#trigger-styling-container-props) 1586-1614
|
|
79
|
-
- [Sample usage](#sample-usage-8) 1616-1644
|
|
80
|
-
- [custom](#custom) 1646-1707
|
|
81
|
-
- [Variant props](#variant-props-10) 1648-1663
|
|
82
|
-
- [Sample usage](#sample-usage-9) 1665-1707
|
|
83
|
-
- [Form Palette — `extra` entrypoint (v2)](#form-palette-extra-entrypoint-v2) 1709-1723
|
|
84
|
-
- [1) Lister (runtime)](#1-lister-runtime) 1725-1849
|
|
85
|
-
- [What is Lister?](#what-is-lister) 1727-1738
|
|
86
|
-
- [Building blocks (what you actually mount/call)](#building-blocks-what-you-actually-mountcall) 1740-1771
|
|
87
|
-
- [✅ `ListerProvider`](#listerprovider) 1742-1747
|
|
88
|
-
- [✅ `ListerUI`](#listerui) 1749-1752
|
|
89
|
-
- [✅ `useLister()`](#uselister) 1754-1764
|
|
90
|
-
- [✅ `useData()`](#usedata) 1766-1771
|
|
91
|
-
- [Quick start (recommended)](#quick-start-recommended) 1773-1818
|
|
92
|
-
- [Step 1 — Mount provider + UI once](#step-1-mount-provider-ui-once) 1775-1794
|
|
93
|
-
- [Step 2 — Open a picker imperatively](#step-2-open-a-picker-imperatively) 1796-1818
|
|
94
|
-
- [`ListerProvider` API](#listerprovider-api) 1820-1849
|
|
95
|
-
- [`ListerProviderHost`](#listerproviderhost) 1832-1842
|
|
96
|
-
- [Practical usage](#practical-usage) 1844-1849
|
|
97
|
-
- [2) `useData()` — deep dive (extremely important)](#2-usedata-deep-dive-extremely-important) 1851-2247
|
|
98
|
-
- [What `useData()` returns (mental model)](#what-usedata-returns-mental-model) 1865-1877
|
|
99
|
-
- [`UseDataOptions` (inputs)](#usedataoptions-inputs) 1879-1910
|
|
100
|
-
- [Selection config (`selection`)](#selection-config-selection) 1898-1910
|
|
101
|
-
- [Search modes: remote vs local vs hybrid](#search-modes-remote-vs-local-vs-hybrid) 1912-1935
|
|
102
|
-
- [✅ `remote` (default)](#remote-default) 1914-1919
|
|
103
|
-
- [✅ `local`](#local) 1921-1926
|
|
104
|
-
- [✅ `hybrid`](#hybrid) 1928-1935
|
|
105
|
-
- [Search targeting (`searchTarget`)](#search-targeting-searchtarget) 1937-1947
|
|
106
|
-
- [Core returned API (what you’ll use most)](#core-returned-api-what-youll-use-most) 1949-1984
|
|
107
|
-
- [Data + status](#data-status) 1951-1954
|
|
108
|
-
- [Search](#search) 1956-1960
|
|
109
|
-
- [Filters](#filters) 1962-1966
|
|
110
|
-
- [Fetch](#fetch) 1968-1971
|
|
111
|
-
- [Selection (when enabled)](#selection-when-enabled) 1973-1984
|
|
112
|
-
- [`useData()` — practical use cases (full examples)](#usedata-practical-use-cases-full-examples) 1986-2238
|
|
113
|
-
- [Use case A — Remote search list (simple)](#use-case-a-remote-search-list-simple) 1988-2030
|
|
114
|
-
- [Use case B — Local mode (fetch once, instant client filtering)](#use-case-b-local-mode-fetch-once-instant-client-filtering) 2032-2066
|
|
115
|
-
- [Use case C — Filters with `patchFilters` (remote/hybrid auto-fetch)](#use-case-c-filters-with-patchfilters-remotehybrid-auto-fetch) 2068-2121
|
|
116
|
-
- [Use case D — Constrain to a known allow-list (`searchTarget: mode="only"`)](#use-case-d-constrain-to-a-known-allow-list-searchtarget-modeonly) 2123-2159
|
|
117
|
-
- [Use case E — Custom multi-select UI (selection enabled)](#use-case-e-custom-multi-select-ui-selection-enabled) 2161-2209
|
|
118
|
-
- [Use case F — Advanced request shaping (`buildRequest`)](#use-case-f-advanced-request-shaping-buildrequest) 2211-2238
|
|
119
|
-
- [Practical tips](#practical-tips) 2240-2247
|
|
120
|
-
- [3) JsonEditor (overview)](#3-jsoneditor-overview) 2249-2280
|
|
121
|
-
- [Standalone usage](#standalone-usage) 2259-2280
|
|
1
|
+
# Index
|
|
2
|
+
- [Form Palette](#form-palette)
|
|
3
|
+
- [Quick start](#quick-start)
|
|
4
|
+
- [Form](#form)
|
|
5
|
+
- [InputField](#inputfield)
|
|
6
|
+
- [Adapters](#adapters)
|
|
7
|
+
- [Recommended boot order](#recommended-boot-order)
|
|
8
|
+
- [Variant props + InputField usage](#variant-props-inputfield-usage)
|
|
9
|
+
- [text](#text)
|
|
10
|
+
- [textarea](#textarea)
|
|
11
|
+
- [toggle-group](#toggle-group)
|
|
12
|
+
- [number](#number)
|
|
13
|
+
- [password](#password)
|
|
14
|
+
- [phone](#phone)
|
|
15
|
+
- [Slider (`slider`)](#slider-slider)
|
|
16
|
+
- [Toggle (`toggle`)](#toggle-toggle)
|
|
17
|
+
- [TreeSelect (`treeselect`)](#treeselect-treeselect)
|
|
18
|
+
- [multi-select](#multi-select)
|
|
19
|
+
- [radio](#radio)
|
|
20
|
+
- [select](#select)
|
|
21
|
+
- [checkbox](#checkbox)
|
|
22
|
+
- [chips](#chips)
|
|
23
|
+
- [color](#color)
|
|
24
|
+
- [date](#date)
|
|
25
|
+
- [keyvalue](#keyvalue)
|
|
26
|
+
- [editor](#editor)
|
|
27
|
+
- [file](#file)
|
|
28
|
+
- [icon](#icon)
|
|
29
|
+
- [image-icon](#image-icon)
|
|
30
|
+
- [json-editor](#json-editor)
|
|
31
|
+
- [lister](#lister)
|
|
32
|
+
- [custom](#custom)
|
|
33
|
+
- [Form Palette - `extra` entrypoint (v2)](#form-palette-extra-entrypoint-v2)
|
|
34
|
+
- [1) Lister (runtime)](#1-lister-runtime)
|
|
35
|
+
- [What is Lister?](#what-is-lister)
|
|
36
|
+
- [Building blocks (what you actually mount/call)](#building-blocks-what-you-actually-mountcall)
|
|
37
|
+
- [Quick start (recommended)](#quick-start-recommended)
|
|
38
|
+
- [`ListerProvider` API](#listerprovider-api)
|
|
39
|
+
- [2) `useData()` - deep dive (extremely important)](#2-usedata-deep-dive-extremely-important)
|
|
40
|
+
- [`UseDataOptions` (inputs)](#usedataoptions-inputs)
|
|
41
|
+
- [Search modes: remote vs local vs hybrid](#search-modes-remote-vs-local-vs-hybrid)
|
|
42
|
+
- [Search targeting (`searchTarget`)](#search-targeting-searchtarget)
|
|
43
|
+
- [Core returned API (what you'll use most)](#core-returned-api-what-youll-use-most)
|
|
44
|
+
- [`useData()` - practical use cases (full examples)](#usedata-practical-use-cases-full-examples)
|
|
45
|
+
- [Practical tips](#practical-tips)
|
|
46
|
+
- [3) JsonEditor (overview)](#3-jsoneditor-overview)
|
|
47
|
+
- [Standalone usage](#standalone-usage)
|
|
122
48
|
|
|
123
49
|
# Form Palette
|
|
124
50
|
|
|
125
51
|
A small but powerful React form runtime built around three ideas:
|
|
126
52
|
|
|
127
53
|
1. **A single `<Form />` shell** that wires up state, submission and validation.
|
|
128
|
-
2. **`<InputField />`** as the universal
|
|
129
|
-
3. **Adapters** that decide what
|
|
54
|
+
2. **`<InputField />`** as the universal “field wrapper†that renders a registered **variant** (text, number, select, json-editor, etc.) and handles label / description / errors / layout.
|
|
55
|
+
3. **Adapters** that decide what “submit†means (`local`, `axios`, `inertia`, or your own).
|
|
130
56
|
|
|
131
57
|
---
|
|
132
58
|
|
|
@@ -164,7 +90,7 @@ await registerInertiaAdapter();
|
|
|
164
90
|
|
|
165
91
|
`Form` is the main form component exported from the package entrypoint (it is `CoreShell`, re-exported as `Form`).
|
|
166
92
|
|
|
167
|
-
### Minimal
|
|
93
|
+
### Minimal “local†form
|
|
168
94
|
|
|
169
95
|
Use `adapter="local"` when you want submission to be handled purely in JS.
|
|
170
96
|
|
|
@@ -238,7 +164,7 @@ function Example() {
|
|
|
238
164
|
|
|
239
165
|
## InputField
|
|
240
166
|
|
|
241
|
-
`InputField` is the form runtime
|
|
167
|
+
`InputField` is the form runtime’s “field wrapperâ€. It:
|
|
242
168
|
|
|
243
169
|
* Pulls the chosen `variant` from the variant registry and renders it.
|
|
244
170
|
* Connects to form state when used inside `<Form />` (by `name`).
|
|
@@ -299,9 +225,9 @@ Adapters define how the form submits.
|
|
|
299
225
|
|
|
300
226
|
### Built-in adapter keys
|
|
301
227
|
|
|
302
|
-
* `local`
|
|
303
|
-
* `axios`
|
|
304
|
-
* `inertia`
|
|
228
|
+
* `local` – no network; calls your callbacks.
|
|
229
|
+
* `axios` – HTTP submit via Axios.
|
|
230
|
+
* `inertia` – submit via Inertia.
|
|
305
231
|
|
|
306
232
|
### Registering adapters
|
|
307
233
|
|
|
@@ -332,7 +258,7 @@ Some adapters expose additional props on `<Form />` (e.g. `url`, `method`, `conf
|
|
|
332
258
|
|
|
333
259
|
## Recommended boot order
|
|
334
260
|
|
|
335
|
-
1. Register variants (so InputField can resolve `variant`
|
|
261
|
+
1. Register variants (so InputField can resolve `variant` → component).
|
|
336
262
|
2. Register the adapters you will use.
|
|
337
263
|
3. Render forms.
|
|
338
264
|
|
|
@@ -365,8 +291,10 @@ Below are the **variant-specific props** you can pass to `<InputField />` for:
|
|
|
365
291
|
* `date`
|
|
366
292
|
* `keyvalue`
|
|
367
293
|
* `editor`
|
|
368
|
-
* `json-editor`
|
|
369
294
|
* `file`
|
|
295
|
+
* `icon`
|
|
296
|
+
* `image-icon`
|
|
297
|
+
* `json-editor`
|
|
370
298
|
* `lister`
|
|
371
299
|
* `custom`
|
|
372
300
|
|
|
@@ -380,22 +308,22 @@ Below are the **variant-specific props** you can pass to `<InputField />` for:
|
|
|
380
308
|
|
|
381
309
|
| Prop | Description |
|
|
382
310
|
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
383
|
-
| `trim?: boolean` | **boolean**
|
|
384
|
-
| `minLength?: number` | **number**
|
|
385
|
-
| `maxLength?: number` | **number**
|
|
386
|
-
| `joinControls?: boolean` | **boolean**
|
|
387
|
-
| `extendBoxToControls?: boolean` | **boolean**
|
|
388
|
-
| `inputClassName?: string` | **string**
|
|
389
|
-
| `prefix?: string` | **string**
|
|
390
|
-
| `suffix?: string` | **string**
|
|
391
|
-
| `stripPrefix?: boolean` | **boolean**
|
|
392
|
-
| `stripSuffix?: boolean` | **boolean**
|
|
393
|
-
| `mask?: string` | **string**
|
|
394
|
-
| `maskDefinitions?: Record<string, RegExp>` | **Record**
|
|
395
|
-
| `slotChar?: string` | **string**
|
|
396
|
-
| `autoClear?: boolean` | **boolean**
|
|
397
|
-
| `unmask?: "raw" \| "masked" \| boolean` | **union**
|
|
398
|
-
| `maskInsertMode?: "stream" \| "caret"` | **union**
|
|
311
|
+
| `trim?: boolean` | **boolean** — If `true`, the value is trimmed **before validation** (visual input stays as typed). |
|
|
312
|
+
| `minLength?: number` | **number** — Minimum allowed length (after optional trimming). |
|
|
313
|
+
| `maxLength?: number` | **number** — Maximum allowed length (after optional trimming). |
|
|
314
|
+
| `joinControls?: boolean` | **boolean** — If `true` and there are controls, the input + controls share one box (border/radius/focus). |
|
|
315
|
+
| `extendBoxToControls?: boolean` | **boolean** — When `joinControls` is true, controls are either visually “inside†the same box (`true`) or separate (`false`). |
|
|
316
|
+
| `inputClassName?: string` | **string** — Extra classes for the **inner** `<input>` element (not the wrapper). |
|
|
317
|
+
| `prefix?: string` | **string** — Fixed prefix rendered as part of the visible input string (e.g. `₦`, `ID: `). |
|
|
318
|
+
| `suffix?: string` | **string** — Fixed suffix rendered as part of the visible input string (e.g. `%`, `kg`). |
|
|
319
|
+
| `stripPrefix?: boolean` | **boolean** — If `true` (default), the prefix is stripped from the emitted model value before calling `onValue` internally. |
|
|
320
|
+
| `stripSuffix?: boolean` | **boolean** — If `true` (default), the suffix is stripped from the emitted model value before calling `onValue` internally. |
|
|
321
|
+
| `mask?: string` | **string** — Mask pattern (PrimeReact style), e.g. `"99/99/9999"`, `"(999) 999-9999"`. |
|
|
322
|
+
| `maskDefinitions?: Record<string, RegExp>` | **Record** — Per-symbol slot definitions (kept for future custom engine; unused by current implementation). |
|
|
323
|
+
| `slotChar?: string` | **string** — Placeholder slot character (default `_`). |
|
|
324
|
+
| `autoClear?: boolean` | **boolean** — If `true`, “empty†masked values emit `""` instead of a fully-masked placeholder string. |
|
|
325
|
+
| `unmask?: "raw" \| "masked" \| boolean` | **union** — Controls whether the **model value** is raw vs masked. (`"raw"`/`true` ⇒ emit unmasked; `"masked"`/`false`/`undefined` ⇒ emit masked). |
|
|
326
|
+
| `maskInsertMode?: "stream" \| "caret"` | **union** — Reserved for future caret-mode logic (currently unused; kept for API compatibility). |
|
|
399
327
|
| `...inputProps` | All other standard `React.InputHTMLAttributes<HTMLInputElement>` (except `value`, `defaultValue`, `onChange`, `size`) are forwarded. |
|
|
400
328
|
|
|
401
329
|
### Sample usage (InputField)
|
|
@@ -409,7 +337,7 @@ export function ExampleText() {
|
|
|
409
337
|
variant="text"
|
|
410
338
|
name="phone"
|
|
411
339
|
label="Phone number"
|
|
412
|
-
description="We
|
|
340
|
+
description="We’ll use this for account recovery."
|
|
413
341
|
|
|
414
342
|
// semantic validation flags (core layer)
|
|
415
343
|
trim
|
|
@@ -471,17 +399,17 @@ export function ExampleTextarea() {
|
|
|
471
399
|
| Prop | Description |
|
|
472
400
|
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
473
401
|
| `options: (ToggleOption \| string \| number \| boolean)[]` | Options for the toggle group. You can pass full option objects or primitive shorthand (primitives are normalized to `{ value: String(x), label: String(x) }`). |
|
|
474
|
-
| `multiple?: boolean` | **boolean**
|
|
475
|
-
| `variant?: "default" \| "outline"` | **union**
|
|
476
|
-
| `layout?: "horizontal" \| "vertical" \| "grid"` | **union**
|
|
477
|
-
| `gridCols?: number` | **number**
|
|
478
|
-
| `fillWidth?: boolean` | **boolean**
|
|
479
|
-
| `optionValue?: string` | **string**
|
|
480
|
-
| `optionLabel?: string` | **string**
|
|
481
|
-
| `optionIcon?: string` | **string**
|
|
482
|
-
| `optionDisabled?: string` | **string**
|
|
483
|
-
| `optionTooltip?: string` | **string**
|
|
484
|
-
| `optionMeta?: string` | **string**
|
|
402
|
+
| `multiple?: boolean` | **boolean** — If `true`, enables multi-select (value becomes an array of strings internally). |
|
|
403
|
+
| `variant?: "default" \| "outline"` | **union** — Visual style passed to the underlying ToggleGroup. |
|
|
404
|
+
| `layout?: "horizontal" \| "vertical" \| "grid"` | **union** — Layout mode. |
|
|
405
|
+
| `gridCols?: number` | **number** — Column count when `layout="grid"` (defaults to `2` in the component). |
|
|
406
|
+
| `fillWidth?: boolean` | **boolean** — If `true`, makes the group/items stretch to fill available width (adds `w-full` and related item sizing). |
|
|
407
|
+
| `optionValue?: string` | **string** — When `options` are custom objects, the property name to read `value` from (fallback: `obj.value`). |
|
|
408
|
+
| `optionLabel?: string` | **string** — When `options` are custom objects, the property name to read `label` from (fallback: `obj.label` or `String(value)`). |
|
|
409
|
+
| `optionIcon?: string` | **string** — When `options` are custom objects, the property name to read `icon` from (fallback: `obj.icon`). |
|
|
410
|
+
| `optionDisabled?: string` | **string** — When `options` are custom objects, the property name to read disabled flag from (fallback: `obj.disabled`). |
|
|
411
|
+
| `optionTooltip?: string` | **string** — When `options` are custom objects, the property name to read tooltip content from (fallback: `obj.tooltip`). |
|
|
412
|
+
| `optionMeta?: string` | **string** — When `options` are custom objects, the property name to read meta from (fallback: `obj.meta`). |
|
|
485
413
|
| `renderOption?: (option, isSelected) => React.ReactNode` | Custom renderer per option (receives normalized option + selected state). |
|
|
486
414
|
| `className?: string` | Class for the toggle group container. |
|
|
487
415
|
| `itemClassName?: string` | Base class applied to **all** toggle items. |
|
|
@@ -532,13 +460,13 @@ export function ExampleToggleGroup() {
|
|
|
532
460
|
|
|
533
461
|
| Prop | Description |
|
|
534
462
|
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
535
|
-
| `showButtons` | When `true`, renders built-in step controls (
|
|
463
|
+
| `showButtons` | When `true`, renders built-in step controls (±) alongside the number input. |
|
|
536
464
|
| `buttonLayout` | Layout for the step controls when `showButtons` is enabled. Supported layouts: `"stacked"` (vertical on the right) and `"inline"` (`-` left, `+` right). |
|
|
537
465
|
| `step` | Step amount used by the built-in controls and stepping logic (forwarded to the underlying number input). |
|
|
538
466
|
| `min` | Minimum numeric value constraint (used by the stepping logic and forwarded to the underlying number input). |
|
|
539
467
|
| `max` | Maximum numeric value constraint (used by the stepping logic and forwarded to the underlying number input). |
|
|
540
468
|
|
|
541
|
-
> Also accepts the rest of the underlying `InputNumberProps` (they
|
|
469
|
+
> Also accepts the rest of the underlying `InputNumberProps` (they’re forwarded to the number input).
|
|
542
470
|
|
|
543
471
|
**Sample**
|
|
544
472
|
|
|
@@ -614,7 +542,7 @@ export function ExampleToggleGroup() {
|
|
|
614
542
|
| `dialCodeDelimiter` | Delimiter between dial code and the input number (e.g. `" "`, `"-"`). |
|
|
615
543
|
| `valueMode` | Controls how the field value is emitted (e.g. E.164 vs local formats). |
|
|
616
544
|
| `mask` | Optional input mask (string or resolver function). |
|
|
617
|
-
| `lazy` | IMask
|
|
545
|
+
| `lazy` | IMask “lazy†mode (placeholder chars hidden until typed). |
|
|
618
546
|
| `keepCharPositions` | IMask option to keep character positions stable. |
|
|
619
547
|
| `unmask` | How the underlying mask value is emitted (IMask option). |
|
|
620
548
|
|
|
@@ -672,7 +600,7 @@ Value type: `number | undefined`
|
|
|
672
600
|
| `leadingControlClassName` | Wrapper className for the leading control. |
|
|
673
601
|
| `trailingControlClassName` | Wrapper className for the trailing control. |
|
|
674
602
|
| `joinControls` | Join controls visually to the slider box. |
|
|
675
|
-
| `extendBoxToControls` | Extend slider
|
|
603
|
+
| `extendBoxToControls` | Extend slider “box†background behind controls. |
|
|
676
604
|
| `controlVariant` | Variant for the +/- controls (if shown). |
|
|
677
605
|
| `controlStep` | Step used by +/- controls (falls back to `step`). |
|
|
678
606
|
| `controlDecrementIcon` | Custom icon node for decrement control. |
|
|
@@ -790,7 +718,7 @@ Value type: `TreeKey | TreeKey[] | undefined` (where `TreeKey` is `string | numb
|
|
|
790
718
|
| `joinControls` | Visually join controls to the trigger box (shared border). |
|
|
791
719
|
| `extendBoxToControls` | Extend trigger background behind controls. |
|
|
792
720
|
| `rootClassName` | Wrapper className around controls + trigger. |
|
|
793
|
-
| `triggerInnerClassName` | ClassName for the trigger
|
|
721
|
+
| `triggerInnerClassName` | ClassName for the trigger’s inner content. |
|
|
794
722
|
|
|
795
723
|
### Mode: button (`mode="button"`)
|
|
796
724
|
|
|
@@ -828,7 +756,7 @@ Value type: `TreeKey | TreeKey[] | undefined` (where `TreeKey` is `string | numb
|
|
|
828
756
|
},
|
|
829
757
|
]}
|
|
830
758
|
searchable
|
|
831
|
-
placeholder="Pick one
|
|
759
|
+
placeholder="Pick one…"
|
|
832
760
|
/>
|
|
833
761
|
```
|
|
834
762
|
|
|
@@ -865,9 +793,9 @@ Value type: `TreeKey | TreeKey[] | undefined` (where `TreeKey` is `string | numb
|
|
|
865
793
|
| `searchable` | Enable search field in the list. |
|
|
866
794
|
| `searchPlaceholder` | Placeholder for the search field. |
|
|
867
795
|
| `emptySearchText` | Text when there are no matches for the current search. |
|
|
868
|
-
| `showSelectAll` | Show a
|
|
869
|
-
| `selectAllLabel` | Label for the
|
|
870
|
-
| `selectAllPosition` | Where to render the
|
|
796
|
+
| `showSelectAll` | Show a “Select all†row. |
|
|
797
|
+
| `selectAllLabel` | Label for the “Select all†row. |
|
|
798
|
+
| `selectAllPosition` | Where to render the “Select all†row. |
|
|
871
799
|
| `clearable` | Show a clear action when there is at least one selection. |
|
|
872
800
|
| `placeholder` | Placeholder when nothing is selected. |
|
|
873
801
|
| `renderOption` | Optional global renderer for an option row. (An option may also provide its own per-option `render`.) |
|
|
@@ -945,7 +873,7 @@ export function MultiSelectExample() {
|
|
|
945
873
|
| ---------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
946
874
|
| `items` | Alias of `options` (list of items to render). |
|
|
947
875
|
| `options` | Options to render. Supports `RadioItem` objects or custom items via mappers. |
|
|
948
|
-
| `mappers` | Mapping functions for `TItem
|
|
876
|
+
| `mappers` | Mapping functions for `TItem → value/label/description/disabled/key/render`. Takes precedence over `option*` props. |
|
|
949
877
|
| `optionValue` | Shortcut mapping for **value** (used only if `mappers` is not provided). |
|
|
950
878
|
| `optionLabel` | Shortcut mapping for **label** (used only if `mappers` is not provided). |
|
|
951
879
|
| `renderOption` | Global option renderer (can be overridden per item via `item.render`). |
|
|
@@ -1016,7 +944,7 @@ export function RadioExample() {
|
|
|
1016
944
|
| `searchPlaceholder` | Placeholder for the search field. |
|
|
1017
945
|
| `emptySearchText` | Text shown when there are no matches for the current search. |
|
|
1018
946
|
| `clearable` | Show a clear action (x) when a value is selected. |
|
|
1019
|
-
| `emptyLabel` | Label to show when no value is selected (acts like
|
|
947
|
+
| `emptyLabel` | Label to show when no value is selected (acts like “noneâ€). |
|
|
1020
948
|
| `placeholder` | Placeholder when no value is selected (and `emptyLabel` not shown). |
|
|
1021
949
|
| `renderOption` | Optional global renderer for a list option. (An option may also provide its own per-option `render`.) |
|
|
1022
950
|
| `renderValue` | Custom renderer for the trigger display (selected option). |
|
|
@@ -1086,13 +1014,13 @@ export function SelectExample() {
|
|
|
1086
1014
|
| `options` | Option list for group mode. Accepts primitives or objects (normalized to `{ value, label, description?, disabled?, key? }`). | | |
|
|
1087
1015
|
| `items` | Alias for `options` (alternate naming). | | |
|
|
1088
1016
|
| `mappers` | Override normalization: `{ mapValue?, mapLabel?, mapDescription?, mapDisabled?, mapKey? }`. | | |
|
|
1089
|
-
| `optionValue` | Map item
|
|
1090
|
-
| `optionLabel` | Map item
|
|
1091
|
-
| `optionDescription` | Map item
|
|
1092
|
-
| `optionDisabled` | Map item
|
|
1093
|
-
| `optionKey` | Map item
|
|
1017
|
+
| `optionValue` | Map item → option value (overrides `mappers.mapValue`). | | |
|
|
1018
|
+
| `optionLabel` | Map item → option label (overrides `mappers.mapLabel`). | | |
|
|
1019
|
+
| `optionDescription` | Map item → option description (overrides `mappers.mapDescription`). | | |
|
|
1020
|
+
| `optionDisabled` | Map item → disabled boolean (overrides `mappers.mapDisabled`). | | |
|
|
1021
|
+
| `optionKey` | Map item → stable React key (overrides `mappers.mapKey`). | | |
|
|
1094
1022
|
| `renderOption` | Custom option renderer (gets `{ item, index, state, effectiveTristate, disabled, size, density, checkboxId, click(), checkbox }`). | | |
|
|
1095
|
-
| `tristate` | Enable tri-state cycling for group options (`none
|
|
1023
|
+
| `tristate` | Enable tri-state cycling for group options (`none → true → false → none`). | | |
|
|
1096
1024
|
| `layout` | Group layout: `"list"` or `"grid"`. | | |
|
|
1097
1025
|
| `columns` | Grid columns when `layout="grid"` (default: `2`). | | |
|
|
1098
1026
|
| `itemGapPx` | Gap between options in px (defaults vary by layout). | | |
|
|
@@ -1156,7 +1084,7 @@ export function SelectExample() {
|
|
|
1156
1084
|
| `addOnTab` | Commit chips on **Tab**. Default: `true`. | |
|
|
1157
1085
|
| `addOnBlur` | Commit chips on **blur**. Default: `true`. | |
|
|
1158
1086
|
| `allowDuplicates` | When `false`, duplicate chips are ignored. Default: `false`. | |
|
|
1159
|
-
| `maxChips` | Maximum number of chips allowed (`undefined`
|
|
1087
|
+
| `maxChips` | Maximum number of chips allowed (`undefined` → unlimited). | |
|
|
1160
1088
|
| `backspaceRemovesLast` | Remove last chip on Backspace when input is empty. Default: `true`. | |
|
|
1161
1089
|
| `clearable` | Show a clear-all button. Default: `false`. | |
|
|
1162
1090
|
| `onAddChips` | Callback: `(added, next) => void` after chips are added. | |
|
|
@@ -1184,7 +1112,7 @@ export function SelectExample() {
|
|
|
1184
1112
|
name="tags"
|
|
1185
1113
|
label="Tags"
|
|
1186
1114
|
variant="chips"
|
|
1187
|
-
placeholder="Add tags
|
|
1115
|
+
placeholder="Add tags…"
|
|
1188
1116
|
separators={[",", ";"]}
|
|
1189
1117
|
maxChips={10}
|
|
1190
1118
|
clearable
|
|
@@ -1240,14 +1168,14 @@ import { Palette } from "lucide-react";
|
|
|
1240
1168
|
| Prop | Description | |
|
|
1241
1169
|
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
1242
1170
|
| `mode` | Selection mode: `"single"` or `"range"`. | |
|
|
1243
|
-
| `placeholder` | Placeholder content shown when there
|
|
1171
|
+
| `placeholder` | Placeholder content shown when there’s no selection. | |
|
|
1244
1172
|
| `clearable` | If `true`, shows a clear action when a value is set. | |
|
|
1245
1173
|
| `minDate` | Minimum selectable date (inclusive). | |
|
|
1246
1174
|
| `maxDate` | Maximum selectable date (inclusive). | |
|
|
1247
1175
|
| `disabledDays` | Disabled-day matcher forwarded to the calendar wrapper (`Calendar["disabled"]`). | |
|
|
1248
1176
|
| `formatSingle` | Display pattern for single values. Supports tokens: `yyyy`, `MM`, `dd`, `HH`, `mm`. Defaults depend on `kind`. | |
|
|
1249
1177
|
| `formatRange` | Range display formatter: either a pattern string (same tokens as `formatSingle`) or a custom `(range) => string` formatter. | |
|
|
1250
|
-
| `rangeSeparator` | Separator used between `from` and `to` when `formatRange` is a string pattern. Default: `"
|
|
1178
|
+
| `rangeSeparator` | Separator used between `from` and `to` when `formatRange` is a string pattern. Default: `" – "`. | |
|
|
1251
1179
|
| `stayOpenOnSelect` | If `true`, keeps the popover open after selecting. In range mode, stays open until both ends are chosen. | |
|
|
1252
1180
|
| `open` | Controlled open state for the popover. | |
|
|
1253
1181
|
| `onOpenChange` | Called when the popover open state changes. | |
|
|
@@ -1269,7 +1197,7 @@ export function DateRangeExample() {
|
|
|
1269
1197
|
description="Select a date range."
|
|
1270
1198
|
mode="range"
|
|
1271
1199
|
kind="date"
|
|
1272
|
-
placeholder="YYYY-MM-DD
|
|
1200
|
+
placeholder="YYYY-MM-DD – YYYY-MM-DD"
|
|
1273
1201
|
clearable
|
|
1274
1202
|
minDate={new Date(2025, 0, 1)}
|
|
1275
1203
|
maxDate={new Date(2025, 11, 31)}
|
|
@@ -1290,16 +1218,16 @@ export function DateRangeExample() {
|
|
|
1290
1218
|
| ---------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
1291
1219
|
| `min` | Minimum number of pairs allowed (enforced by the UI controls). |
|
|
1292
1220
|
| `max` | Maximum number of pairs allowed. |
|
|
1293
|
-
| `minVisible` | Minimum number of chips to show before collapsing into a
|
|
1294
|
-
| `maxVisible` | Maximum number of chips to show before collapsing into a
|
|
1295
|
-
| `showAddButton` | Toggle visibility of the
|
|
1221
|
+
| `minVisible` | Minimum number of chips to show before collapsing into a “more†indicator. |
|
|
1222
|
+
| `maxVisible` | Maximum number of chips to show before collapsing into a “more†indicator. |
|
|
1223
|
+
| `showAddButton` | Toggle visibility of the “Add†action. |
|
|
1296
1224
|
| `showMenuButton` | Toggle visibility of the overflow/menu action (if supported by the preset). |
|
|
1297
1225
|
| `placeholder` | Placeholder shown when there are no items. |
|
|
1298
1226
|
| `dialogTitle` | Title for the edit/add dialog UI. |
|
|
1299
|
-
| `keyLabel` | Label used for the
|
|
1300
|
-
| `valueLabel` | Label used for the
|
|
1227
|
+
| `keyLabel` | Label used for the “key†input. |
|
|
1228
|
+
| `valueLabel` | Label used for the “value†input. |
|
|
1301
1229
|
| `submitLabel` | Text for the dialog submit button. |
|
|
1302
|
-
| `moreLabel` | Label renderer for the collapsed
|
|
1230
|
+
| `moreLabel` | Label renderer for the collapsed “more†indicator: `(count) => ReactNode`. |
|
|
1303
1231
|
| `emptyLabel` | Label shown when there are no entries (fallback text). |
|
|
1304
1232
|
| `className` | Wrapper class for the whole variant. |
|
|
1305
1233
|
| `chipsClassName` | Class for the chips container. |
|
|
@@ -1394,13 +1322,13 @@ export function EditorExample() {
|
|
|
1394
1322
|
| `dropIcon` | Optional icon shown in the drop area. |
|
|
1395
1323
|
| `dropTitle` | Title text shown in the drop area. |
|
|
1396
1324
|
| `dropDescription` | Helper text shown in the drop area. |
|
|
1397
|
-
| `custom` | Use a fully custom
|
|
1325
|
+
| `custom` | Use a fully custom “picker†UI instead of the built-in drop/trigger. |
|
|
1398
1326
|
| `asRaw` | Treat values as raw `File` objects (native picker flow). |
|
|
1399
1327
|
| `renderDropArea` | Custom renderer for the drop area section. |
|
|
1400
1328
|
| `renderFileItem` | Custom renderer for each file item row. |
|
|
1401
1329
|
| `showCheckboxes` | Show checkboxes next to file items (when supported by the UI). |
|
|
1402
1330
|
| `onFilesAdded` | Callback fired when files are added. |
|
|
1403
|
-
| `customLoader` | Provide your own file loader (e.g. resolve URLs
|
|
1331
|
+
| `customLoader` | Provide your own file loader (e.g. resolve URLs → metadata). |
|
|
1404
1332
|
| `mergeMode` | Merge strategy when adding files (e.g. append/replace/dedupe). |
|
|
1405
1333
|
| `formatFileName` | Custom formatter for displaying a file name. |
|
|
1406
1334
|
| `formatFileSize` | Custom formatter for displaying a file size. |
|
|
@@ -1425,7 +1353,7 @@ export function EditorExample() {
|
|
|
1425
1353
|
| `trailingControl` | Custom node on the far-right *outside* the trigger. |
|
|
1426
1354
|
| `leadingControlClassName` | ClassName for the leading control wrapper. |
|
|
1427
1355
|
| `trailingControlClassName` | ClassName for the trailing control wrapper. |
|
|
1428
|
-
| `joinControls` | Visually
|
|
1356
|
+
| `joinControls` | Visually “joins†leading/trailing controls with the trigger. |
|
|
1429
1357
|
| `extendBoxToControls` | Extends the input box styling around joined controls. |
|
|
1430
1358
|
| `button` | When `mode="button"`: explicit trigger node. |
|
|
1431
1359
|
| `children` | When `mode="button"` and `button` is not provided: trigger content. |
|
|
@@ -1459,6 +1387,141 @@ export function FileExample() {
|
|
|
1459
1387
|
|
|
1460
1388
|
---
|
|
1461
1389
|
|
|
1390
|
+
## icon
|
|
1391
|
+
|
|
1392
|
+
### Variant props
|
|
1393
|
+
|
|
1394
|
+
| Prop | Description |
|
|
1395
|
+
| ------------------ | --------------------------------------------------------------------------- |
|
|
1396
|
+
| `multiple` | Allow selecting multiple icons (value becomes `string[]`). |
|
|
1397
|
+
| `url` | Iconify API base URL (defaults to registry `iconPicker.url`). |
|
|
1398
|
+
| `groups` | Icon groups to display (defaults to registry `iconPicker.groups`). |
|
|
1399
|
+
| `allowedGroupIds` | Restrict selectable groups by group id. |
|
|
1400
|
+
| `maxRender` | Max icons rendered in the grid (safety cap for large sets). |
|
|
1401
|
+
| `placeholder` | Placeholder text when nothing is selected. |
|
|
1402
|
+
| `className` | Wrapper class for the whole variant. |
|
|
1403
|
+
| `triggerClassName` | ClassName for the trigger (default mode). |
|
|
1404
|
+
| `popoverClassName` | ClassName for the popover content wrapper. |
|
|
1405
|
+
|
|
1406
|
+
### Mode and trigger props
|
|
1407
|
+
|
|
1408
|
+
| Prop | Description |
|
|
1409
|
+
| ----------------------------- | ----------------------------------------------------------------------- |
|
|
1410
|
+
| `mode` | Trigger style: `"default"` (input-like) or `"button"` (custom trigger). |
|
|
1411
|
+
| `leadingIcons` | Icons shown before the selection (default mode). |
|
|
1412
|
+
| `trailingIcons` | Icons shown after the selection. |
|
|
1413
|
+
| `icon` | Single icon shorthand (falls into leading icons). |
|
|
1414
|
+
| `leadingControl` | Custom node on the far-left *outside* the trigger. |
|
|
1415
|
+
| `trailingControl` | Custom node on the far-right *outside* the trigger. |
|
|
1416
|
+
| `leadingControlClassName` | ClassName for the leading control wrapper. |
|
|
1417
|
+
| `trailingControlClassName` | ClassName for the trailing control wrapper. |
|
|
1418
|
+
| `joinControls` | Visually "joins" leading/trailing controls with the trigger. |
|
|
1419
|
+
| `extendBoxToControls` | Extends the input box styling around joined controls. |
|
|
1420
|
+
| `button` | When `mode="button"`: explicit trigger node. |
|
|
1421
|
+
| `children` | When `mode="button"` and `button` is not provided: trigger content. |
|
|
1422
|
+
| `selectedBadge` | Selected-count badge (button mode). |
|
|
1423
|
+
| `selectedBadgeHiddenWhenZero` | Hide badge when selected count is 0. |
|
|
1424
|
+
| `selectedBadgeVariant` | Badge style variant (button mode). |
|
|
1425
|
+
| `selectedBadgeClassName` | ClassName for the selected-count badge. |
|
|
1426
|
+
| `selectedBadgePlacement` | Where to place the badge relative to trigger content. |
|
|
1427
|
+
|
|
1428
|
+
> Note: In `mode="button"`, the icon/control props (`leadingIcons`, `trailingIcons`, `leadingControl`, etc.) are not supported.
|
|
1429
|
+
>
|
|
1430
|
+
> Value is an Iconify name string (e.g. `"mdi:home"`) or `string[]` when `multiple` is true.
|
|
1431
|
+
|
|
1432
|
+
### Sample usage
|
|
1433
|
+
|
|
1434
|
+
```tsx
|
|
1435
|
+
import { InputField } from "@timeax/form-palette";
|
|
1436
|
+
|
|
1437
|
+
export function IconExample() {
|
|
1438
|
+
return (
|
|
1439
|
+
<InputField
|
|
1440
|
+
variant="icon"
|
|
1441
|
+
name="app_icon"
|
|
1442
|
+
label="App icon"
|
|
1443
|
+
placeholder="Search icons..."
|
|
1444
|
+
/>
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
```
|
|
1448
|
+
|
|
1449
|
+
---
|
|
1450
|
+
|
|
1451
|
+
## image-icon
|
|
1452
|
+
|
|
1453
|
+
### Variant props
|
|
1454
|
+
|
|
1455
|
+
| Prop | Description |
|
|
1456
|
+
| --------------------- | ------------------------------------------------------------------------------------------------- |
|
|
1457
|
+
| `multiple` | Allow selecting multiple items (icons and/or images). |
|
|
1458
|
+
| `iconUrl` | Iconify API base URL for the icon picker (defaults to registry `iconPicker.url`). |
|
|
1459
|
+
| `iconGroups` | Icon groups to display (defaults to registry `iconPicker.groups`). |
|
|
1460
|
+
| `allowedIconGroupIds` | Restrict selectable icon groups by id. |
|
|
1461
|
+
| `iconMaxRender` | Max icons rendered in the grid (safety cap for large sets). |
|
|
1462
|
+
| `accept` | Accepted file types (input accept string / list). |
|
|
1463
|
+
| `maxFiles` | Max number of files allowed. |
|
|
1464
|
+
| `maxTotalSize` | Max total size allowed for all files (bytes). |
|
|
1465
|
+
| `customLoader` | Provide your own file loader (e.g. resolve URLs -> metadata). |
|
|
1466
|
+
| `mergeMode` | Merge strategy when adding files (`"append"` or `"replace"`). |
|
|
1467
|
+
| `formatFileName` | Custom formatter for displaying a file name. |
|
|
1468
|
+
| `formatFileSize` | Custom formatter for displaying a file size. |
|
|
1469
|
+
| `formatFileValue` | Convert a `FileItem` into a persisted string value (falls back to `url`, `path`, or native file). |
|
|
1470
|
+
| `placeholder` | Placeholder text when nothing is selected. |
|
|
1471
|
+
| `className` | Wrapper class for the whole variant. |
|
|
1472
|
+
| `triggerClassName` | ClassName for the trigger (default mode). |
|
|
1473
|
+
| `popoverClassName` | ClassName for the popover content wrapper. |
|
|
1474
|
+
| `showCheckboxes` | Show checkboxes next to items in the list (when supported by the UI). |
|
|
1475
|
+
|
|
1476
|
+
### Mode and trigger props
|
|
1477
|
+
|
|
1478
|
+
| Prop | Description |
|
|
1479
|
+
| ----------------------------- | ----------------------------------------------------------------------- |
|
|
1480
|
+
| `mode` | Trigger style: `"default"` (input-like) or `"button"` (custom trigger). |
|
|
1481
|
+
| `leadingIcons` | Icons shown before the summary (default mode). |
|
|
1482
|
+
| `trailingIcons` | Icons shown after the summary / clear action. |
|
|
1483
|
+
| `icon` | Single icon shorthand (falls into leading icons). |
|
|
1484
|
+
| `leadingControl` | Custom node on the far-left *outside* the trigger. |
|
|
1485
|
+
| `trailingControl` | Custom node on the far-right *outside* the trigger. |
|
|
1486
|
+
| `leadingControlClassName` | ClassName for the leading control wrapper. |
|
|
1487
|
+
| `trailingControlClassName` | ClassName for the trailing control wrapper. |
|
|
1488
|
+
| `joinControls` | Visually "joins" leading/trailing controls with the trigger. |
|
|
1489
|
+
| `extendBoxToControls` | Extends the input box styling around joined controls. |
|
|
1490
|
+
| `button` | When `mode="button"`: explicit trigger node. |
|
|
1491
|
+
| `children` | When `mode="button"` and `button` is not provided: trigger content. |
|
|
1492
|
+
| `selectedBadge` | Selected-count badge (button mode). |
|
|
1493
|
+
| `selectedBadgeHiddenWhenZero` | Hide badge when selected count is 0. |
|
|
1494
|
+
| `selectedBadgeVariant` | Badge style variant (button mode). |
|
|
1495
|
+
| `selectedBadgeClassName` | ClassName for the selected-count badge. |
|
|
1496
|
+
| `selectedBadgePlacement` | Where to place the badge relative to trigger content. |
|
|
1497
|
+
|
|
1498
|
+
> Note: In `mode="button"`, the icon/control props (`leadingIcons`, `trailingIcons`, `leadingControl`, etc.) are not supported.
|
|
1499
|
+
>
|
|
1500
|
+
> Value accepts `string` or `File` (or arrays). Strings can be Iconify names (e.g. `"lucide:camera"`) or image/file URLs/paths.
|
|
1501
|
+
|
|
1502
|
+
### Sample usage
|
|
1503
|
+
|
|
1504
|
+
```tsx
|
|
1505
|
+
import { InputField } from "@timeax/form-palette";
|
|
1506
|
+
|
|
1507
|
+
export function ImageIconExample() {
|
|
1508
|
+
return (
|
|
1509
|
+
<InputField
|
|
1510
|
+
variant="image-icon"
|
|
1511
|
+
name="avatar"
|
|
1512
|
+
label="Avatar"
|
|
1513
|
+
placeholder="Pick an image or icon..."
|
|
1514
|
+
accept={["image/*", ".svg"]}
|
|
1515
|
+
iconGroups={[
|
|
1516
|
+
{ id: "brand", label: "Brand", prefixes: ["simple-icons"] },
|
|
1517
|
+
]}
|
|
1518
|
+
/>
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
```
|
|
1522
|
+
|
|
1523
|
+
---
|
|
1524
|
+
|
|
1462
1525
|
## json-editor
|
|
1463
1526
|
|
|
1464
1527
|
### Wrapper / trigger props
|
|
@@ -1486,13 +1549,13 @@ export function FileExample() {
|
|
|
1486
1549
|
| Prop | Description |
|
|
1487
1550
|
| ------------------ | ----------------------------------------------------------------------------------- |
|
|
1488
1551
|
| `title` | Title displayed in the editor header. |
|
|
1489
|
-
| `fieldMap` | Field mapping rules (wildcards supported)
|
|
1552
|
+
| `fieldMap` | Field mapping rules (wildcards supported) → picks a field variant + props per path. |
|
|
1490
1553
|
| `layout` | Layout rules (grid/rows + route/page rules). |
|
|
1491
1554
|
| `defaults` | Default values / behaviours for missing keys and created fields. |
|
|
1492
1555
|
| `filters` | Include/exclude filters for routes/fields. |
|
|
1493
1556
|
| `permissions` | Permissions (add/delete/view/edit raw, etc.). |
|
|
1494
1557
|
| `callbacks` | Hooks for events like add/delete/edit / route changes. |
|
|
1495
|
-
| `route` | Controlled
|
|
1558
|
+
| `route` | Controlled “page route†(e.g. `"config.headers"`). |
|
|
1496
1559
|
| `defaultRoute` | Starting route when uncontrolled. |
|
|
1497
1560
|
| `onRouteChange` | Route change callback. |
|
|
1498
1561
|
| `viewMode` | Controlled view mode (e.g. raw vs structured UI). |
|
|
@@ -1552,13 +1615,13 @@ export function JsonEditorExample() {
|
|
|
1552
1615
|
| `method` | Inline HTTP method: `"GET"` or `"POST"`. |
|
|
1553
1616
|
| `buildRequest` | Custom request builder (params/body/headers). |
|
|
1554
1617
|
| `selector` | How to extract the array from the response (function or selector path). |
|
|
1555
|
-
| `optionValue` | How to map a raw row
|
|
1556
|
-
| `optionLabel` | How to map a raw row
|
|
1557
|
-
| `optionIcon` | How to map a raw row
|
|
1558
|
-
| `optionDescription` | How to map a raw row
|
|
1559
|
-
| `optionDisabled` | How to map a raw row
|
|
1560
|
-
| `optionGroup` | How to map a raw row
|
|
1561
|
-
| `optionMeta` | How to map a raw row
|
|
1618
|
+
| `optionValue` | How to map a raw row → option value (key or function). |
|
|
1619
|
+
| `optionLabel` | How to map a raw row → label. |
|
|
1620
|
+
| `optionIcon` | How to map a raw row → icon. |
|
|
1621
|
+
| `optionDescription` | How to map a raw row → description. |
|
|
1622
|
+
| `optionDisabled` | How to map a raw row → disabled. |
|
|
1623
|
+
| `optionGroup` | How to map a raw row → group label. |
|
|
1624
|
+
| `optionMeta` | How to map a raw row → meta payload. |
|
|
1562
1625
|
| `search` | Search override (inline). |
|
|
1563
1626
|
| `searchTarget` | Search target override (inline). |
|
|
1564
1627
|
|
|
@@ -1570,7 +1633,7 @@ export function JsonEditorExample() {
|
|
|
1570
1633
|
| `confirm` | Optional confirm behaviour (e.g. confirm selection). |
|
|
1571
1634
|
| `permissions` | Permissions object used by the lister UI (actions, views). |
|
|
1572
1635
|
| `placeholder` | Placeholder text when nothing is selected. |
|
|
1573
|
-
| `maxDisplayItems` | Max chips/labels to show before collapsing into
|
|
1636
|
+
| `maxDisplayItems` | Max chips/labels to show before collapsing into “+Nâ€. |
|
|
1574
1637
|
| `renderTrigger` | Custom trigger renderer. |
|
|
1575
1638
|
| `title` | Title displayed when opening the lister UI. |
|
|
1576
1639
|
| `searchMode` | Search mode for the open UI. |
|
|
@@ -1599,7 +1662,7 @@ export function JsonEditorExample() {
|
|
|
1599
1662
|
| `trailingControl` | Custom node on the far-right *outside* the trigger. |
|
|
1600
1663
|
| `leadingControlClassName` | ClassName for the leading control wrapper. |
|
|
1601
1664
|
| `trailingControlClassName` | ClassName for the trailing control wrapper. |
|
|
1602
|
-
| `joinControls` | Visually
|
|
1665
|
+
| `joinControls` | Visually “joins†leading/trailing controls with the trigger. |
|
|
1603
1666
|
| `extendBoxToControls` | Extends the input box styling around joined controls. |
|
|
1604
1667
|
| `maxListHeight` | Max height for the open list/panel (px). |
|
|
1605
1668
|
| `className` | Wrapper class for the whole variant. |
|
|
@@ -1706,12 +1769,12 @@ export function CustomExample() {
|
|
|
1706
1769
|
|
|
1707
1770
|
---
|
|
1708
1771
|
|
|
1709
|
-
# Form Palette
|
|
1772
|
+
# Form Palette — `extra` entrypoint (v2)
|
|
1710
1773
|
|
|
1711
|
-
The `extra` entrypoint exposes two
|
|
1774
|
+
The `extra` entrypoint exposes two “power tools†that sit beside the normal **Form / InputField** flow:
|
|
1712
1775
|
|
|
1713
|
-
1. **Lister runtime** (provider + global UI + hooks)
|
|
1714
|
-
2. **JsonEditor**
|
|
1776
|
+
1. **Lister runtime** (provider + global UI + hooks) — a reusable, app-wide **picker** system for single/multi selection with search/filter + **remote / local / hybrid** data.
|
|
1777
|
+
2. **JsonEditor** — an interactive JSON editor UI (also used by the `json-editor` InputField variant).
|
|
1715
1778
|
|
|
1716
1779
|
> This README is written against the `extra.ts` export surface:
|
|
1717
1780
|
>
|
|
@@ -1728,30 +1791,30 @@ The `extra` entrypoint exposes two “power tools” that sit beside the normal
|
|
|
1728
1791
|
|
|
1729
1792
|
Lister is a small runtime that lets you open a **picker UI** from anywhere in your app:
|
|
1730
1793
|
|
|
1731
|
-
* **Single** selection (
|
|
1794
|
+
* **Single** selection (“choose one userâ€) or **multi** selection (“choose many tagsâ€).
|
|
1732
1795
|
* **Local**, **remote**, or **hybrid** search.
|
|
1733
|
-
* A consistent session model: **open
|
|
1796
|
+
* A consistent session model: **open → search/filter → select → apply/cancel**.
|
|
1734
1797
|
* App-level integration via a provider and a single UI renderer.
|
|
1735
1798
|
|
|
1736
|
-
If you use the `lister` InputField variant, it
|
|
1799
|
+
If you use the `lister` InputField variant, it’s powered by this same runtime.
|
|
1737
1800
|
|
|
1738
1801
|
---
|
|
1739
1802
|
|
|
1740
1803
|
## Building blocks (what you actually mount/call)
|
|
1741
1804
|
|
|
1742
|
-
###
|
|
1805
|
+
### ✅ `ListerProvider`
|
|
1743
1806
|
|
|
1744
1807
|
* Holds the Lister store/context.
|
|
1745
1808
|
* Receives the **host** (permission checks + logging).
|
|
1746
1809
|
* Can register a **presets map** (reusable picker definitions).
|
|
1747
1810
|
* Supports provider-side remote debounce via `remoteDebounceMs` (default **300ms**).
|
|
1748
1811
|
|
|
1749
|
-
###
|
|
1812
|
+
### ✅ `ListerUI`
|
|
1750
1813
|
|
|
1751
1814
|
* Renders any **open sessions** (popovers) from the provider store.
|
|
1752
1815
|
* Mount this **once** under the provider.
|
|
1753
1816
|
|
|
1754
|
-
###
|
|
1817
|
+
### ✅ `useLister()`
|
|
1755
1818
|
|
|
1756
1819
|
* Imperative controller + access to store.
|
|
1757
1820
|
|
|
@@ -1763,7 +1826,7 @@ Provides:
|
|
|
1763
1826
|
* search actions (setQuery/searchLocal/searchRemote)
|
|
1764
1827
|
* filter helpers
|
|
1765
1828
|
|
|
1766
|
-
###
|
|
1829
|
+
### ✅ `useData()`
|
|
1767
1830
|
|
|
1768
1831
|
* Lower-level hook used for **fetching + searching + filters + selection state**.
|
|
1769
1832
|
* Exported so you can build custom list UIs that still behave like Lister.
|
|
@@ -1772,7 +1835,7 @@ Provides:
|
|
|
1772
1835
|
|
|
1773
1836
|
## Quick start (recommended)
|
|
1774
1837
|
|
|
1775
|
-
### Step 1
|
|
1838
|
+
### Step 1 — Mount provider + UI once
|
|
1776
1839
|
|
|
1777
1840
|
```tsx
|
|
1778
1841
|
import * as React from "react";
|
|
@@ -1793,7 +1856,7 @@ export function AppShell({ children }: { children: React.ReactNode }) {
|
|
|
1793
1856
|
}
|
|
1794
1857
|
```
|
|
1795
1858
|
|
|
1796
|
-
### Step 2
|
|
1859
|
+
### Step 2 — Open a picker imperatively
|
|
1797
1860
|
|
|
1798
1861
|
```tsx
|
|
1799
1862
|
import * as React from "react";
|
|
@@ -1848,7 +1911,7 @@ export interface ListerProviderHost {
|
|
|
1848
1911
|
|
|
1849
1912
|
---
|
|
1850
1913
|
|
|
1851
|
-
# 2) `useData()`
|
|
1914
|
+
# 2) `useData()` — deep dive (extremely important)
|
|
1852
1915
|
|
|
1853
1916
|
`useData()` is the engine behind Lister-style **data fetching + searching + filtering + selection**.
|
|
1854
1917
|
|
|
@@ -1856,9 +1919,9 @@ Use it when:
|
|
|
1856
1919
|
|
|
1857
1920
|
* You want a **custom picker UI** (your own layout, rows, pagination).
|
|
1858
1921
|
* You want a **data-backed selection** UX but not the standard Lister popover.
|
|
1859
|
-
* You want Lister
|
|
1922
|
+
* You want Lister’s semantics (remote/local/hybrid search + filters) in other UIs.
|
|
1860
1923
|
|
|
1861
|
-
> It works only under `<ListerProvider />` because it uses the provider
|
|
1924
|
+
> It works only under `<ListerProvider />` because it uses the provider’s fetch engine.
|
|
1862
1925
|
|
|
1863
1926
|
---
|
|
1864
1927
|
|
|
@@ -1911,26 +1974,26 @@ It also returns **selection state** (optional) and **fetch/search/filter helpers
|
|
|
1911
1974
|
|
|
1912
1975
|
## Search modes: remote vs local vs hybrid
|
|
1913
1976
|
|
|
1914
|
-
###
|
|
1977
|
+
### ✅ `remote` (default)
|
|
1915
1978
|
|
|
1916
1979
|
* Query changes trigger a **debounced fetch**.
|
|
1917
1980
|
* The server is responsible for searching.
|
|
1918
1981
|
|
|
1919
1982
|
Best for: **large datasets**, server ranking, true search endpoints.
|
|
1920
1983
|
|
|
1921
|
-
###
|
|
1984
|
+
### ✅ `local`
|
|
1922
1985
|
|
|
1923
1986
|
* Switching to local fetches a **base list once** using an empty query.
|
|
1924
1987
|
* After that, `visible` is filtered client-side.
|
|
1925
1988
|
|
|
1926
1989
|
Best for: **small-medium datasets** you can cache (countries, categories, roles).
|
|
1927
1990
|
|
|
1928
|
-
###
|
|
1991
|
+
### ✅ `hybrid`
|
|
1929
1992
|
|
|
1930
1993
|
* Query changes still fetch remotely.
|
|
1931
1994
|
* But `visible` also applies the local filtering rules.
|
|
1932
1995
|
|
|
1933
|
-
Best for:
|
|
1996
|
+
Best for: “server list + extra client constraints†(e.g. `searchOnly`).
|
|
1934
1997
|
|
|
1935
1998
|
---
|
|
1936
1999
|
|
|
@@ -1938,15 +2001,15 @@ Best for: “server list + extra client constraints” (e.g. `searchOnly`).
|
|
|
1938
2001
|
|
|
1939
2002
|
`useData()` supports Lister-style targeting via `searchTarget`:
|
|
1940
2003
|
|
|
1941
|
-
* `mode: "all"`
|
|
1942
|
-
* `mode: "subject"`
|
|
1943
|
-
* `mode: "only"`
|
|
2004
|
+
* `mode: "all"` → search across everything
|
|
2005
|
+
* `mode: "subject"` → search only against one subject field (e.g. `name`)
|
|
2006
|
+
* `mode: "only"` → constrain results to a known list of IDs
|
|
1944
2007
|
|
|
1945
2008
|
If you pass `search={{ default: "name" }}`, the default target becomes `mode:"subject"` on that key.
|
|
1946
2009
|
|
|
1947
2010
|
---
|
|
1948
2011
|
|
|
1949
|
-
## Core returned API (what you
|
|
2012
|
+
## Core returned API (what you’ll use most)
|
|
1950
2013
|
|
|
1951
2014
|
### Data + status
|
|
1952
2015
|
|
|
@@ -1967,8 +2030,8 @@ If you pass `search={{ default: "name" }}`, the default target becomes `mode:"su
|
|
|
1967
2030
|
|
|
1968
2031
|
### Fetch
|
|
1969
2032
|
|
|
1970
|
-
* `refresh()`
|
|
1971
|
-
* `fetch({ query?, filters?, searchTarget?, search? })`
|
|
2033
|
+
* `refresh()` — refetch using current query/filters/target
|
|
2034
|
+
* `fetch({ query?, filters?, searchTarget?, search? })` — manual override fetch
|
|
1972
2035
|
|
|
1973
2036
|
### Selection (when enabled)
|
|
1974
2037
|
|
|
@@ -1977,15 +2040,15 @@ If you pass `search={{ default: "name" }}`, the default target becomes `mode:"su
|
|
|
1977
2040
|
* `selected` (array of objects resolved from cache)
|
|
1978
2041
|
* `select(id)`, `deselect(id)`, `toggle(id)`, `clearSelection()`
|
|
1979
2042
|
* `isSelected(id)`
|
|
1980
|
-
* `getSelection()`
|
|
2043
|
+
* `getSelection()` — returns the best current selection shape
|
|
1981
2044
|
|
|
1982
2045
|
> Important: selection maintains an internal cache so selected objects can be returned even when the current page/list no longer contains them.
|
|
1983
2046
|
|
|
1984
2047
|
---
|
|
1985
2048
|
|
|
1986
|
-
## `useData()`
|
|
2049
|
+
## `useData()` — practical use cases (full examples)
|
|
1987
2050
|
|
|
1988
|
-
### Use case A
|
|
2051
|
+
### Use case A — Remote search list (simple)
|
|
1989
2052
|
|
|
1990
2053
|
```tsx
|
|
1991
2054
|
import * as React from "react";
|
|
@@ -2006,13 +2069,13 @@ export function RemoteUserSearch() {
|
|
|
2006
2069
|
<input
|
|
2007
2070
|
value={query}
|
|
2008
2071
|
onChange={(e) => setQuery(e.target.value)}
|
|
2009
|
-
placeholder="Search users
|
|
2072
|
+
placeholder="Search users…"
|
|
2010
2073
|
/>
|
|
2011
2074
|
<button onClick={refresh} disabled={loading}>
|
|
2012
2075
|
Refresh
|
|
2013
2076
|
</button>
|
|
2014
2077
|
|
|
2015
|
-
{loading && <p>Loading
|
|
2078
|
+
{loading && <p>Loading…</p>}
|
|
2016
2079
|
{error && <p style={{ color: "crimson" }}>{String(error)}</p>}
|
|
2017
2080
|
|
|
2018
2081
|
<ul>
|
|
@@ -2029,7 +2092,7 @@ export function RemoteUserSearch() {
|
|
|
2029
2092
|
|
|
2030
2093
|
---
|
|
2031
2094
|
|
|
2032
|
-
### Use case B
|
|
2095
|
+
### Use case B — Local mode (fetch once, instant client filtering)
|
|
2033
2096
|
|
|
2034
2097
|
```tsx
|
|
2035
2098
|
import * as React from "react";
|
|
@@ -2051,7 +2114,7 @@ export function CountryPickerLocal() {
|
|
|
2051
2114
|
<input
|
|
2052
2115
|
value={query}
|
|
2053
2116
|
onChange={(e) => setQuery(e.target.value)}
|
|
2054
|
-
placeholder="Search countries
|
|
2117
|
+
placeholder="Search countries…"
|
|
2055
2118
|
/>
|
|
2056
2119
|
<ul>
|
|
2057
2120
|
{visible.map((c) => (
|
|
@@ -2065,7 +2128,7 @@ export function CountryPickerLocal() {
|
|
|
2065
2128
|
|
|
2066
2129
|
---
|
|
2067
2130
|
|
|
2068
|
-
### Use case C
|
|
2131
|
+
### Use case C — Filters with `patchFilters` (remote/hybrid auto-fetch)
|
|
2069
2132
|
|
|
2070
2133
|
```tsx
|
|
2071
2134
|
import * as React from "react";
|
|
@@ -2120,7 +2183,7 @@ export function FilteredUsers() {
|
|
|
2120
2183
|
|
|
2121
2184
|
---
|
|
2122
2185
|
|
|
2123
|
-
### Use case D
|
|
2186
|
+
### Use case D — Constrain to a known allow-list (`searchTarget: mode="only"`)
|
|
2124
2187
|
|
|
2125
2188
|
```tsx
|
|
2126
2189
|
import * as React from "react";
|
|
@@ -2158,7 +2221,7 @@ export function AllowedIdsOnly() {
|
|
|
2158
2221
|
|
|
2159
2222
|
---
|
|
2160
2223
|
|
|
2161
|
-
### Use case E
|
|
2224
|
+
### Use case E — Custom multi-select UI (selection enabled)
|
|
2162
2225
|
|
|
2163
2226
|
```tsx
|
|
2164
2227
|
import * as React from "react";
|
|
@@ -2208,7 +2271,7 @@ selectedIds: {JSON.stringify(selectedIds, null, 2)}
|
|
|
2208
2271
|
|
|
2209
2272
|
---
|
|
2210
2273
|
|
|
2211
|
-
### Use case F
|
|
2274
|
+
### Use case F — Advanced request shaping (`buildRequest`)
|
|
2212
2275
|
|
|
2213
2276
|
```tsx
|
|
2214
2277
|
import { useData } from "@timeax/form-palette/extra";
|
|
@@ -2239,10 +2302,10 @@ export function CustomPayloadExample() {
|
|
|
2239
2302
|
|
|
2240
2303
|
## Practical tips
|
|
2241
2304
|
|
|
2242
|
-
* Want instant search UX and your dataset is small
|
|
2243
|
-
* Want selection to persist while users search remotely
|
|
2244
|
-
* Want selection to strictly match what
|
|
2245
|
-
* Want lazy fetch (open a modal first)
|
|
2305
|
+
* Want instant search UX and your dataset is small → `searchMode: "local"`.
|
|
2306
|
+
* Want selection to persist while users search remotely → `selection.prune = "never"`.
|
|
2307
|
+
* Want selection to strictly match what’s visible in the current list → `selection.prune = "missing"`.
|
|
2308
|
+
* Want lazy fetch (open a modal first) → `enabled: false`, then call `fetch()` when needed.
|
|
2246
2309
|
|
|
2247
2310
|
---
|
|
2248
2311
|
|
|
@@ -2278,3 +2341,5 @@ export function JsonEditorStandalone() {
|
|
|
2278
2341
|
);
|
|
2279
2342
|
}
|
|
2280
2343
|
```
|
|
2344
|
+
|
|
2345
|
+
|