@ixfx/components 0.5.20 → 0.6.0
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/bundle/index.d.ts +535 -263
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +7971 -6596
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +12 -7
- package/dist/ac-text.d.ts.map +1 -1
- package/dist/ac-text.js +3 -4
- package/dist/ac-text.js.map +1 -1
- package/dist/ac-token-DVbmHmky.d.ts +107 -0
- package/dist/ac-token-DVbmHmky.d.ts.map +1 -0
- package/dist/ac-token.d.ts +2 -0
- package/dist/ac-token.js +646 -0
- package/dist/ac-token.js.map +1 -0
- package/dist/{button-pcDaCemT.js → button-Bn0BuLpO.js} +3 -4
- package/dist/{button-pcDaCemT.js.map → button-Bn0BuLpO.js.map} +1 -1
- package/dist/button.d.ts +1 -2
- package/dist/button.d.ts.map +1 -1
- package/dist/button.js +1 -1
- package/dist/checkbox.d.ts +0 -1
- package/dist/checkbox.d.ts.map +1 -1
- package/dist/checkbox.js +1 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/{colour-picker-D43Q96r0.js → colour-picker-0stHB90J.js} +11 -14
- package/dist/{colour-picker-D43Q96r0.js.map → colour-picker-0stHB90J.js.map} +1 -1
- package/dist/colour-picker.d.ts +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +4 -2
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +1152 -1
- package/dist/crumbs.js.map +1 -0
- package/dist/data-controller-DOlmqNKb.js +171 -0
- package/dist/data-controller-DOlmqNKb.js.map +1 -0
- package/dist/data-display.d.ts +1 -2
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +24 -22
- package/dist/data-display.js.map +1 -1
- package/dist/data-grid-BeAkORz2.d.ts +215 -0
- package/dist/data-grid-BeAkORz2.d.ts.map +1 -0
- package/dist/data-grid.d.ts +2 -0
- package/dist/data-grid.js +1225 -0
- package/dist/data-grid.js.map +1 -0
- package/dist/data-provider-BAn_-oR1.d.ts +61 -0
- package/dist/data-provider-BAn_-oR1.d.ts.map +1 -0
- package/dist/{decorate-DdjvVHS-.js → decorate-VRK8rslU.js} +2 -2
- package/dist/{decorate-DdjvVHS-.js.map → decorate-VRK8rslU.js.map} +1 -1
- package/dist/{defaults-BkWCPJFL.js → defaults-BCiDhZbF.js} +20 -3
- package/dist/defaults-BCiDhZbF.js.map +1 -0
- package/dist/drag-ghost-DtSDvjri.js +85 -0
- package/dist/drag-ghost-DtSDvjri.js.map +1 -0
- package/dist/editable-label.d.ts +1 -2
- package/dist/editable-label.d.ts.map +1 -1
- package/dist/editable-label.js +1 -1
- package/dist/editable-label.js.map +1 -1
- package/dist/{incr-search-CeERfijK.js → element-search-Y8SRfPGM.js} +7 -135
- package/dist/element-search-Y8SRfPGM.js.map +1 -0
- package/dist/form-CsXJX15p.js +64 -0
- package/dist/form-CsXJX15p.js.map +1 -0
- package/dist/form.d.ts +15 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +2 -0
- package/dist/grouped-item-lister-CNLMgdIr.d.ts +121 -0
- package/dist/grouped-item-lister-CNLMgdIr.d.ts.map +1 -0
- package/dist/grouped-item-lister.d.ts +2 -0
- package/dist/grouped-item-lister.js +177 -0
- package/dist/grouped-item-lister.js.map +1 -0
- package/dist/{hex-editor-B-UI4OZu.js → hex-editor-Bk6rxhfg.js} +6 -8
- package/dist/{hex-editor-B-UI4OZu.js.map → hex-editor-Bk6rxhfg.js.map} +1 -1
- package/dist/{hex-editor-CMIxtNgT.d.ts → hex-editor-Caq8vNQk.d.ts} +2 -3
- package/dist/hex-editor-Caq8vNQk.d.ts.map +1 -0
- package/dist/hex.d.ts +1 -1
- package/dist/hex.js +1 -1
- package/dist/highlight-B-eQrhhb.js.map +1 -1
- package/dist/{icon-Bd5BiU4b.d.ts → icon-BUwP1CZ1.d.ts} +3 -4
- package/dist/icon-BUwP1CZ1.d.ts.map +1 -0
- package/dist/{icon-CK14NUcE.js → icons-Bm2ByQ3s.js} +10 -5
- package/dist/icons-Bm2ByQ3s.js.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +2 -8
- package/dist/incr-search-vCzuao-2.js +137 -0
- package/dist/incr-search-vCzuao-2.js.map +1 -0
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +2 -1
- package/dist/{index-DrKRD8_a.d.ts → index-BOUaDIW-.d.ts} +4 -4
- package/dist/index-BOUaDIW-.d.ts.map +1 -0
- package/dist/{index-CkMIKEWp.d.ts → index-BUB5SICW.d.ts} +3 -4
- package/dist/index-BUB5SICW.d.ts.map +1 -0
- package/dist/{index-tX6fKF8m.d.ts → index-BeuCXtiO.d.ts} +3 -3
- package/dist/index-BeuCXtiO.d.ts.map +1 -0
- package/dist/{index-BslNaMLo.d.ts → index-Cu5i8zZY.d.ts} +3 -3
- package/dist/index-Cu5i8zZY.d.ts.map +1 -0
- package/dist/{index-D87kRcEs.d.ts → index-RqMh1i-O.d.ts} +2 -1
- package/dist/index-RqMh1i-O.d.ts.map +1 -0
- package/dist/{index-Cdmrn0SZ.d.ts → index-ovq_GTdl.d.ts} +11 -11
- package/dist/index-ovq_GTdl.d.ts.map +1 -0
- package/dist/index.d.ts +93 -606
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1351 -3714
- package/dist/index.js.map +1 -1
- package/dist/{labelled-input-base-ORb1rGq6.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +2 -3
- package/dist/labelled-input-base-Dp_9KP0G.d.ts.map +1 -0
- package/dist/{labelled-input-base-9K_w3oLj.js → labelled-input-base-hoKGwyKT.js} +2 -2
- package/dist/{labelled-input-base-9K_w3oLj.js.map → labelled-input-base-hoKGwyKT.js.map} +1 -1
- package/dist/labelled-radial-input.d.ts +4 -5
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-radial-input.js +2 -3
- package/dist/labelled-radial-input.js.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-range-input.js +2 -2
- package/dist/labelled-range-input.js.map +1 -1
- package/dist/led.d.ts +1 -2
- package/dist/led.d.ts.map +1 -1
- package/dist/led.js +1 -1
- package/dist/led.js.map +1 -1
- package/dist/menu-DIfU70AA.js +1609 -0
- package/dist/menu-DIfU70AA.js.map +1 -0
- package/dist/{menu-item-AtoP6bD4.d.ts → menu-item-BG5w7fi4.d.ts} +4 -4
- package/dist/menu-item-BG5w7fi4.d.ts.map +1 -0
- package/dist/menu.d.ts +2 -2
- package/dist/menu.js +1 -2
- package/dist/miller.d.ts +7 -5
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +23 -25
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.d.ts +1 -2
- package/dist/narrowed-text.d.ts.map +1 -1
- package/dist/narrowed-text.js +14 -13
- package/dist/narrowed-text.js.map +1 -1
- package/dist/notification-pill-DyZydXoZ.d.ts +68 -0
- package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -0
- package/dist/notifier.d.ts +2 -0
- package/dist/notifier.js +146 -0
- package/dist/notifier.js.map +1 -0
- package/dist/panel.d.ts +1 -1
- package/dist/panel.d.ts.map +1 -1
- package/dist/panel.js +1 -2
- package/dist/panel.js.map +1 -1
- package/dist/plots.d.ts +1 -1
- package/dist/plots.js +1 -1
- package/dist/polar-pad.d.ts +1 -2
- package/dist/polar-pad.d.ts.map +1 -1
- package/dist/polar-pad.js +2 -2
- package/dist/polar-pad.js.map +1 -1
- package/dist/{radial-input-Dhu5ZGP5.d.ts → radial-input-DXMN55Nz.d.ts} +2 -3
- package/dist/radial-input-DXMN55Nz.d.ts.map +1 -0
- package/dist/{radial-input-C4f-2Bya.js → radial-input-Dk8Wydp5.js} +26 -16
- package/dist/radial-input-Dk8Wydp5.js.map +1 -0
- package/dist/radial-input.d.ts +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.d.ts +2 -3
- package/dist/range-input.d.ts.map +1 -1
- package/dist/range-input.js +2 -2
- package/dist/range-input.js.map +1 -1
- package/dist/range.d.ts +2 -3
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +2 -2
- package/dist/range.js.map +1 -1
- package/dist/scroll-fade-CAs1EabA.js +70 -0
- package/dist/scroll-fade-CAs1EabA.js.map +1 -0
- package/dist/select-horiz.d.ts +50 -0
- package/dist/select-horiz.d.ts.map +1 -0
- package/dist/select-horiz.js +263 -0
- package/dist/select-horiz.js.map +1 -0
- package/dist/{slider-input-SW7e2Ac2.js → slider-input-CT4gcF-o.js} +30 -27
- package/dist/{slider-input-SW7e2Ac2.js.map → slider-input-CT4gcF-o.js.map} +1 -1
- package/dist/{slider-input-BEaztT-g.d.ts → slider-input-XppH3vcy.d.ts} +2 -3
- package/dist/slider-input-XppH3vcy.d.ts.map +1 -0
- package/dist/slider-input.d.ts +1 -1
- package/dist/slider-input.js +1 -1
- package/dist/snackbar.d.ts +58 -0
- package/dist/snackbar.d.ts.map +1 -0
- package/dist/snackbar.js +265 -0
- package/dist/snackbar.js.map +1 -0
- package/dist/snap-container.d.ts +1 -2
- package/dist/snap-container.d.ts.map +1 -1
- package/dist/snap-container.js +6 -5
- package/dist/snap-container.js.map +1 -1
- package/dist/split-layout.d.ts +1 -2
- package/dist/split-layout.d.ts.map +1 -1
- package/dist/split-layout.js +5 -3
- package/dist/split-layout.js.map +1 -1
- package/dist/swipe.d.ts +1 -2
- package/dist/swipe.d.ts.map +1 -1
- package/dist/swipe.js +4 -3
- package/dist/swipe.js.map +1 -1
- package/dist/{tab-list-B8v9KntS.d.ts → tab-list-Beuh2nom.d.ts} +4 -4
- package/dist/tab-list-Beuh2nom.d.ts.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +533 -1
- package/dist/tabs.js.map +1 -0
- package/dist/{tickled-controller-JDOR9B8V.d.ts → tickled-controller-BtevrRLV.d.ts} +1 -2
- package/dist/tickled-controller-BtevrRLV.d.ts.map +1 -0
- package/dist/{tickled-styles-Bgo_Lpw-.js → tickled-controller-DkAU-0qL.js} +2 -88
- package/dist/tickled-controller-DkAU-0qL.js.map +1 -0
- package/dist/tickled-styles-BrAHEj1q.js +89 -0
- package/dist/tickled-styles-BrAHEj1q.js.map +1 -0
- package/dist/{timeline-CdSI003L.js → timeline-B2fgDL4U.js} +3 -3
- package/dist/{timeline-CdSI003L.js.map → timeline-B2fgDL4U.js.map} +1 -1
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/{tooltip-BMTSUPBU.d.ts → tooltip-BlvBUQxx.d.ts} +2 -3
- package/dist/tooltip-BlvBUQxx.d.ts.map +1 -0
- package/dist/transitory-label.d.ts +30 -0
- package/dist/transitory-label.d.ts.map +1 -0
- package/dist/transitory-label.js +249 -0
- package/dist/transitory-label.js.map +1 -0
- package/dist/{tree-CqPhQRHo.js → tree-BO6BXI2b.js} +9 -10
- package/dist/{tree-CqPhQRHo.js.map → tree-BO6BXI2b.js.map} +1 -1
- package/dist/{tree-component-CDLO1ITF.d.ts → tree-component-BvV4muxx.d.ts} +8 -124
- package/dist/tree-component-BvV4muxx.d.ts.map +1 -0
- package/dist/tree.d.ts +9 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +1 -1
- package/dist/types-Bc23SI94.d.ts +72 -0
- package/dist/types-Bc23SI94.d.ts.map +1 -0
- package/dist/types-DlVNJez_.d.ts +41 -0
- package/dist/types-DlVNJez_.d.ts.map +1 -0
- package/dist/vertical-list.d.ts +122 -0
- package/dist/vertical-list.d.ts.map +1 -0
- package/dist/vertical-list.js +737 -0
- package/dist/vertical-list.js.map +1 -0
- package/dist/{wheel-nudge-Dhzi5nHc.js → wheel-nudge-BlSCe_hD.js} +2 -2
- package/dist/wheel-nudge-BlSCe_hD.js.map +1 -0
- package/dist/{wheel-nudge-C-ra_1os.d.ts → wheel-nudge-DGrNzWuE.d.ts} +3 -4
- package/dist/wheel-nudge-DGrNzWuE.d.ts.map +1 -0
- package/dist/{xy-axis-CtDDQzGZ.d.ts → xy-axis-5KhVTNoX.d.ts} +8 -6
- package/dist/xy-axis-5KhVTNoX.d.ts.map +1 -0
- package/dist/{xy-axis-BpA2eJq6.js → xy-axis-B6yMjckW.js} +8 -112
- package/dist/xy-axis-B6yMjckW.js.map +1 -0
- package/dist/xy-pad.d.ts +1 -2
- package/dist/xy-pad.d.ts.map +1 -1
- package/dist/xy-pad.js +2 -2
- package/dist/xy-pad.js.map +1 -1
- package/docs-user/README.md +3 -2
- package/docs-user/data-grid.md +248 -0
- package/docs-user/index.json +217 -0
- package/docs-user/llms.txt +57 -0
- package/docs-user/rating.md +102 -0
- package/llms.txt +57 -0
- package/package.json +21 -11
- package/dist/crumb-navigation-Pif-kupA.js +0 -1221
- package/dist/crumb-navigation-Pif-kupA.js.map +0 -1
- package/dist/defaults-BkWCPJFL.js.map +0 -1
- package/dist/hex-editor-CMIxtNgT.d.ts.map +0 -1
- package/dist/icon-Bd5BiU4b.d.ts.map +0 -1
- package/dist/icon-CK14NUcE.js.map +0 -1
- package/dist/icons.js.map +0 -1
- package/dist/incr-search-CeERfijK.js.map +0 -1
- package/dist/index-BslNaMLo.d.ts.map +0 -1
- package/dist/index-Cdmrn0SZ.d.ts.map +0 -1
- package/dist/index-CkMIKEWp.d.ts.map +0 -1
- package/dist/index-D87kRcEs.d.ts.map +0 -1
- package/dist/index-DrKRD8_a.d.ts.map +0 -1
- package/dist/index-tX6fKF8m.d.ts.map +0 -1
- package/dist/interaction-_Y2qO3QI.js +0 -1
- package/dist/labelled-input-base-ORb1rGq6.d.ts.map +0 -1
- package/dist/menu-BiFarLUA.js +0 -826
- package/dist/menu-BiFarLUA.js.map +0 -1
- package/dist/menu-item-AtoP6bD4.d.ts.map +0 -1
- package/dist/menu-item-yHSPV8nS.js +0 -783
- package/dist/menu-item-yHSPV8nS.js.map +0 -1
- package/dist/radial-input-C4f-2Bya.js.map +0 -1
- package/dist/radial-input-Dhu5ZGP5.d.ts.map +0 -1
- package/dist/registry-CkW7q09Q.js +0 -21
- package/dist/registry-CkW7q09Q.js.map +0 -1
- package/dist/selecthorizontal.d.ts +0 -16
- package/dist/selecthorizontal.d.ts.map +0 -1
- package/dist/selecthorizontal.js +0 -43
- package/dist/selecthorizontal.js.map +0 -1
- package/dist/slider-input-BEaztT-g.d.ts.map +0 -1
- package/dist/tab-list-B8v9KntS.d.ts.map +0 -1
- package/dist/tab-list-CR0v53KJ.js +0 -615
- package/dist/tab-list-CR0v53KJ.js.map +0 -1
- package/dist/tickled-controller-JDOR9B8V.d.ts.map +0 -1
- package/dist/tickled-styles-Bgo_Lpw-.js.map +0 -1
- package/dist/tooltip-BMTSUPBU.d.ts.map +0 -1
- package/dist/tree-component-CDLO1ITF.d.ts.map +0 -1
- package/dist/types-DSfbtHs3.d.ts +0 -8
- package/dist/types-DSfbtHs3.d.ts.map +0 -1
- package/dist/wheel-nudge-C-ra_1os.d.ts.map +0 -1
- package/dist/wheel-nudge-Dhzi5nHc.js.map +0 -1
- package/dist/xy-axis-BpA2eJq6.js.map +0 -1
- package/dist/xy-axis-CtDDQzGZ.d.ts.map +0 -1
- package/docs-user/selecthorizontal.md +0 -32
- /package/bundle/{chunk-D7D4PA-g.js → rolldown-runtime-D7D4PA-g.js} +0 -0
- /package/dist/{chunk-D7D4PA-g.js → rolldown-runtime-D7D4PA-g.js} +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# `ixfx-data-grid`
|
|
2
|
+
|
|
3
|
+
A virtualised data grid with sortable/resizable/reorderable columns, single/multi selection, grouping, and inline cell editing. Handles 200+ rows with windowed rendering and keyboard navigation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<ixfx-data-grid id="grid" style="height:400px"></ixfx-data-grid>
|
|
11
|
+
|
|
12
|
+
<script type="module">
|
|
13
|
+
import '@ixfx/components/data-grid';
|
|
14
|
+
|
|
15
|
+
const grid = document.querySelector('#grid');
|
|
16
|
+
grid.columns = [
|
|
17
|
+
{ key: 'name', label: 'Name', width: 160 },
|
|
18
|
+
{ key: 'age', label: 'Age', width: 70, align: 'right' },
|
|
19
|
+
{ key: 'score', label: 'Score', width: 90, align: 'right' },
|
|
20
|
+
];
|
|
21
|
+
grid.rows = [
|
|
22
|
+
{ key: 'r0', name: 'Ada', age: 30, score: 9.123 },
|
|
23
|
+
{ key: 'r1', name: 'Bob', age: 25, score: 4 },
|
|
24
|
+
];
|
|
25
|
+
</script>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Import via bundle: `import '@ixfx/components';` or per-component `import '@ixfx/components/data-grid';`.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Columns
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
type DataGridColumn = {
|
|
36
|
+
key: string;
|
|
37
|
+
label: string;
|
|
38
|
+
width?: number; minWidth?: number; maxWidth?: number;
|
|
39
|
+
visible?: boolean;
|
|
40
|
+
sortable?: boolean; sortFn?: (a,b)=>number;
|
|
41
|
+
resizable?: boolean; reorderable?: boolean;
|
|
42
|
+
align?: 'left'|'center'|'right'; // default left, applied as justify-content + tabular-nums for numbers
|
|
43
|
+
renderer?: (row, col, rowIndex) => unknown; // Lit template or string
|
|
44
|
+
selectable?: boolean;
|
|
45
|
+
groupable?: boolean;
|
|
46
|
+
editable?: boolean;
|
|
47
|
+
editor?: 'text'|'number'|'boolean'|'select' | DataGridEditorFactory;
|
|
48
|
+
editorOptions?: readonly (string|{value,label})[];
|
|
49
|
+
formatter?: (value, row, col) => unknown;
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
* `width` defaults to `150`. Drag the handle between headers to resize; double-click handle to auto-size to content. Drag the `⠿` handle to reorder.
|
|
54
|
+
* `align` controls cell content justification. Numeric columns should use `right` (or `center` for Age) – cells use `font-variant-numeric: tabular-nums` so decimal points align when paired with a fixed formatter.
|
|
55
|
+
* `renderer` overrides default `String(value)` display. Use `html` from `lit`.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Rows & keys
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
grid.rows = [{ key: 'r0', ... }, ...];
|
|
63
|
+
grid.getRowKey = (row, i) => row.key ?? row.id ?? String(i);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Reassign `rows` to update. Sorting is derived from `sortState`.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Selection & interaction
|
|
71
|
+
|
|
72
|
+
| Property | Type | Default | Description |
|
|
73
|
+
|---|---|---|---|
|
|
74
|
+
| `selectionMode` / `selection-mode` | `'none'|'single'|'multiple'` | `'single'` | How many rows can be selected |
|
|
75
|
+
| `interactionMode` / `interaction-mode` | `'standard'|'implicit'|'checked'|'sticky'|'vscode'|'manual'` | `'standard'` | Gesture mapping (same as `ixfx-vertical-list`) |
|
|
76
|
+
|
|
77
|
+
See `ixfx-vertical-list` README for mode table. Data-grid adds checkbox column in `checked` mode.
|
|
78
|
+
|
|
79
|
+
Programmatic: selection is `Set<string>` of row keys (`_selectedKeys` private, read via events).
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Sorting
|
|
84
|
+
|
|
85
|
+
Click header to cycle `asc → desc → none`. Or set:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
grid.sortState = { key: 'age', direction: 'asc' };
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Events: `datagrid-sort` `{ sort, previous }`. Custom `sortFn` per column.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Grouping
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
grid.allowGrouping = true;
|
|
99
|
+
grid.groupBy = 'department'; // or (row)=>String(row.dept)
|
|
100
|
+
grid.groupLabel = (key, rows) => `${key} (${rows.length})`;
|
|
101
|
+
grid.groupableColumns = ['department','age']; // optional allowlist
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Collapsible group headers (no background, just divider). Header bar `ixfx-menu-trigger` (gear) shows `Columns` check-items and `Group by` radio group – uses CSS anchor positioning with `position-try-fallbacks` so it never goes off-screen (flips `block`/`inline`, max-height `min(60vh,400px)` scrolls).
|
|
105
|
+
|
|
106
|
+
Cross-group selection:
|
|
107
|
+
|
|
108
|
+
```html
|
|
109
|
+
<ixfx-data-grid cross-group-selection></ixfx-data-grid>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
* `cross-group-selection` (boolean, default `false` – matches `ixfx-grouped-item-lister`). When `false`, selecting in one group clears other groups; `Shift+click` range and `Ctrl+A` are clamped to the anchor's group. When `true`, selection spans groups. Logic lifted to `src/util/grouped-selection.ts`.
|
|
113
|
+
|
|
114
|
+
Events: `datagrid-group-change` `{ groupBy }`.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Editing
|
|
119
|
+
|
|
120
|
+
### Editability modes
|
|
121
|
+
|
|
122
|
+
| `editability` | Behaviour |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `disabled` | No editing |
|
|
125
|
+
| `manual` | Only via `startEdit` / `startRowEdit` |
|
|
126
|
+
| `user` (default) | Slow double-click (two clicks 150–700ms apart on same cell) opens editor; `Enter` on a tickled row opens `lastClickedCell` if editable else first editable |
|
|
127
|
+
| `immediate` | Editable cells render as editors by default |
|
|
128
|
+
|
|
129
|
+
```html
|
|
130
|
+
<ixfx-data-grid editability="user"></ixfx-data-grid>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
grid.editable = (row, col) => col.key==='name' || col.key==='department';
|
|
135
|
+
// or per-column editable:true
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Editors
|
|
139
|
+
|
|
140
|
+
* `editor:'text'` (default) → `<input type="text">`
|
|
141
|
+
* `editor:'select'` + `editorOptions: ['A','B']` → `<select>`
|
|
142
|
+
* `editor:'boolean'` → checkbox
|
|
143
|
+
* `editor: (ctx)=>html`...` ` custom factory with `{ row, column, rowIndex, colIndex, value, commit, cancel }`
|
|
144
|
+
|
|
145
|
+
Editors are seeded with the cell's current value (`curVal`). For `select`, the matching `editorOptions` entry is preselected.
|
|
146
|
+
|
|
147
|
+
### Programmatic
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
grid.startEdit('r4','name'); // single cell
|
|
151
|
+
grid.startRowEdit('r4'); // all editable cells in row
|
|
152
|
+
grid.stopEdit();
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Keyboard while editing
|
|
156
|
+
|
|
157
|
+
* `Tab` / `Shift+Tab` – commit and move to next/prev editable cell in same row, focus follows.
|
|
158
|
+
* `Up` / `Down` – commit and move to same column in adjacent row if editable, also moves tickled cursor.
|
|
159
|
+
* `Enter` – commit.
|
|
160
|
+
* `Escape` – cancel (revert) when grid has focus.
|
|
161
|
+
* Focus leaving the component reverts editors (unless `immediate`), committing only via explicit `Tab`/`Enter`/`Down`.
|
|
162
|
+
|
|
163
|
+
Implementation: `updated` focuses the editor (`data-col` attribute), `_suppressBlurCommit` prevents double-commit on Tab navigation, `_onFocusOut` reverts.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Formatting & alignment
|
|
168
|
+
|
|
169
|
+
Global or per-column formatters transform display value (not stored value):
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
type GlobalFormatter = (value, columnName, row) => unknown;
|
|
173
|
+
grid.globalFormatter = (v, col) => col==='score' ? Number(v).toFixed(2) : v;
|
|
174
|
+
grid.setColumnFormatter('score', 'fixed', { digits: 3 }); // built-ins
|
|
175
|
+
grid.setColumnFormatter('score', v => String(v)); // custom
|
|
176
|
+
grid.setColumnFormatter('score', null); // clear
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Built-ins:
|
|
180
|
+
|
|
181
|
+
| Name | Options | Example |
|
|
182
|
+
|---|---|---|
|
|
183
|
+
| `fixed` | `{digits:2}` | `9.1 → 9.10` |
|
|
184
|
+
| `percentage` | `{digits:0}` | `0.75 → 75%` |
|
|
185
|
+
| `integer` | – | `9.6 → 10` |
|
|
186
|
+
|
|
187
|
+
Column `formatter?: (value,row,col)=>unknown` also supported. Formatted value is shown when no `renderer`; if `renderer` exists it receives raw row.
|
|
188
|
+
|
|
189
|
+
Demo: `Score` is random float `0–100` with 0–3 decimals, `align:'right'`, `font-variant-numeric: tabular-nums`, `fixed` 3 digits for decimal alignment. `Age` is `align:'center'` to demo middle alignment.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Column visibility & menu
|
|
194
|
+
|
|
195
|
+
Gear menu (`ixfx-menu-trigger` placement `bottom-end`, `inset-area: block-end span-inline-end`) lists `Columns` (check-items) and `Group by` (radio). Toggle visibility via `col.visible=false` or menu. Event: `datagrid-column-visibility` `{key, visible}`.
|
|
196
|
+
|
|
197
|
+
Other events: `datagrid-column-reorder` `{from,to,columns}`, `datagrid-column-resize` `{key,width}`, `datagrid-cell-click` `{rowKey,colKey,rowIndex,colIndex}`, `datagrid-cell-edit` `{rowKey,colKey,oldValue,newValue}`.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Keyboard navigation
|
|
202
|
+
|
|
203
|
+
Grid is focusable (`tabindex=0`). When not editing:
|
|
204
|
+
|
|
205
|
+
| Key | Action |
|
|
206
|
+
|---|---|
|
|
207
|
+
| `ArrowDown/Up` | Move tickled cursor, scroll into view; with `Shift` + `vscode`/`standard` extends range |
|
|
208
|
+
| `Home/End` | First/last |
|
|
209
|
+
| `Enter` | If `editability=user` and row has editable cell, open editor (prefers `lastClickedCell`); else select row |
|
|
210
|
+
| `Space` | Toggle selection |
|
|
211
|
+
| `Escape` | Clear selection (or cancel edit) |
|
|
212
|
+
| `Ctrl/Cmd+A` | Select all (clamped to anchor group if `!crossGroupSelection`) |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## CSS variables & parts
|
|
217
|
+
|
|
218
|
+
| Variable | Default | Description |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| `--data-grid-row-height` | `28px` | Row height |
|
|
221
|
+
| `--data-grid-header-height` | `32px` | Header height |
|
|
222
|
+
| `--data-grid-bg` | `var(--surface-3)` | Grid background |
|
|
223
|
+
| `--data-grid-header-bg` | `var(--surface-2)` | Header background |
|
|
224
|
+
| `--data-grid-border` | `var(--border)` | Outer/between border |
|
|
225
|
+
| `--data-grid-header-text` | `var(--surface-3-text)` | Header text |
|
|
226
|
+
|
|
227
|
+
Inherits global theme (`--surface-*`, `--accent`, `--item-*`, `--space-*`, `--radius-*`, `--shadow-m`). Cells use `font-variant-numeric: tabular-nums`. Group rows are transparent with divider.
|
|
228
|
+
|
|
229
|
+
No `::part` exports yet (header/row/cell are shadow-internal).
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Methods
|
|
234
|
+
|
|
235
|
+
| Method | Signature | Description |
|
|
236
|
+
|---|---|---|
|
|
237
|
+
| `setColumnFormatter` | `(key, preset\|fn\|null, opts?)` | Set built-in or custom formatter |
|
|
238
|
+
| `startEdit` | `(rowKey, colKey)` | Open single-cell editor |
|
|
239
|
+
| `startRowEdit` | `(rowKey)` | Open row editors |
|
|
240
|
+
| `stopEdit` | `()` | Cancel editors |
|
|
241
|
+
| `getVisibleRange` | `()=>{startRow,endRow,startCol,endCol}` | Virtual window |
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Demo
|
|
246
|
+
|
|
247
|
+
`demo/data-grid.html` + `demo/data-grid.ts`: 200 rows, `Department` random, `Score` float, `Name`/`Department` editable (`user` mode, slow double-click; `Tab`/`Up`/`Down` navigation; `Enter` from tickled row). Controls: Selection/Interaction/Group by/Editability + `Edit first row` (manual).
|
|
248
|
+
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ixfx/components",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"generated": "2026-08-29T11:13:25.291Z",
|
|
5
|
+
"components": [
|
|
6
|
+
{
|
|
7
|
+
"name": "ac-text",
|
|
8
|
+
"summary": "VS Code command-palette style autocomplete text input. Shows a popup with matching results as the user types.",
|
|
9
|
+
"path": "docs-user/ac-text.md"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "ac-token",
|
|
13
|
+
"summary": "Token/tag input with per-token autocomplete. Looks like a text box — committed tokens appear as inline chips, and a suggestion popup follows the typing cursor. Typical use cases are email To: fields a",
|
|
14
|
+
"path": "docs-user/ac-token.md"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "button",
|
|
18
|
+
"summary": "Three related button components:",
|
|
19
|
+
"path": "docs-user/button.md"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "checkbox",
|
|
23
|
+
"summary": "A custom checkbox with a diagonal line indicator and indeterminate state support. Uses shadow DOM with CSS variables for full appearance customization.",
|
|
24
|
+
"path": "docs-user/checkbox.md"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "colour-picker",
|
|
28
|
+
"summary": "Two components for picking OKLCH colours. Use `ixfx-colour-picker` when you need a full inline picker; use `ixfx-colour-picker-popup` when you need a compact swatch that opens a picker in a popover.",
|
|
29
|
+
"path": "docs-user/colour-picker.md"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "crumbs",
|
|
33
|
+
"summary": "Breadcrumb navigation with lazy-loading child support. Uses the same `TreeNode` / `TreeItem` data model as `ixfx-tree-list`, allowing easy swapping between the two components.",
|
|
34
|
+
"path": "docs-user/crumbs.md"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "data-display",
|
|
38
|
+
"summary": "A debug data display component that renders key-value pairs from a plain object. Supports 7 inline render modes (`led`, `plot`, `plot-xy`, `plot-heat`, `plot-histogram`, `time-elapsed`, `hide`) via `c",
|
|
39
|
+
"path": "docs-user/data-display.md"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "data-grid",
|
|
43
|
+
"summary": "A virtualised data grid with sortable/resizable/reorderable columns, single/multi selection, grouping, and inline cell editing. Handles 200+ rows with windowed rendering and keyboard navigation.",
|
|
44
|
+
"path": "docs-user/data-grid.md"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "editable-label",
|
|
48
|
+
"summary": "Inline editable text components. `ixfx-editable-number` extends `ixfx-editable-label` with drag-to-adjust and fill-bar visualization.",
|
|
49
|
+
"path": "docs-user/editable-label.md"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "form",
|
|
53
|
+
"summary": "Primitives for typical form layout with responsive label positioning and data binding.",
|
|
54
|
+
"path": "docs-user/form.md"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "grouped-item-lister",
|
|
58
|
+
"summary": "A meta-component that renders a typed item list using any sub-component you supply. Items can be displayed in a single sub-component (_ungrouped_ mode) or split into labelled groups, each with its own",
|
|
59
|
+
"path": "docs-user/grouped-item-lister.md"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "icons",
|
|
63
|
+
"summary": "A centralized SVG icon system for `@ixfx/components`. Icons are stored by name, can be overridden globally, and all components that use a given icon re-render automatically when it changes.",
|
|
64
|
+
"path": "docs-user/icons.md"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "incr-search",
|
|
68
|
+
"summary": "Utilities for incremental (type-ahead) search over data collections or DOM-backed lists.",
|
|
69
|
+
"path": "docs-user/incr-search.md"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "labelled-radial-input",
|
|
73
|
+
"summary": "A composite radial input that pairs an editable label (`ixfx-editable-number`) with a rotary dial (`ixfx-radial-input`). The two controls are always in sync — turning the dial updates the number, and ",
|
|
74
|
+
"path": "docs-user/labelled-radial-input.md"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "labelled-range-input",
|
|
78
|
+
"summary": "A composite range input that pairs an editable label (`ixfx-editable-number`) with a slider (`ixfx-range-input`). The two controls are always in sync — dragging the slider updates the number, and edit",
|
|
79
|
+
"path": "docs-user/labelled-range-input.md"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "led",
|
|
83
|
+
"summary": "An LED indicator component with color mixing and optional blinking animation.",
|
|
84
|
+
"path": "docs-user/led.md"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "menu",
|
|
88
|
+
"summary": "A custom menu system built on native HTML popovers with keyboard navigation, tickled focus management, and command routing.",
|
|
89
|
+
"path": "docs-user/menu.md"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "miller",
|
|
93
|
+
"summary": "A Miller column component displays hierarchical data as multiple vertical columns, like macOS Finder or email clients. Each column shows the children of the selected item in the previous column.",
|
|
94
|
+
"path": "docs-user/miller.md"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "narrowed-text",
|
|
98
|
+
"summary": "A filtered text selection component with inline search. Shows slotted items filtered by a query string as the user types.",
|
|
99
|
+
"path": "docs-user/narrowed-text.md"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "notifier",
|
|
103
|
+
"summary": "A \"lookless\" app-wide notification system. `NotificationManager` is a singleton that owns notification state, queueing, and timing — it doesn't know how to draw anything. A `NotificationRenderer` (the",
|
|
104
|
+
"path": "docs-user/notifier.md"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "panel",
|
|
108
|
+
"summary": "An collapsible panel component with support for titles, icons, toolbars, and multiple visual variants.",
|
|
109
|
+
"path": "docs-user/panel.md"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "plots",
|
|
113
|
+
"summary": "SVG-based plotting components for visualising data streams.",
|
|
114
|
+
"path": "docs-user/plots.md"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "polar-pad",
|
|
118
|
+
"summary": "A circular pad for setting polar coordinates (angle + radius). The user clicks or drags within a circle to position a marker. The marker's position encodes an angle (degrees, 0 = right, clockwise) and",
|
|
119
|
+
"path": "docs-user/polar-pad.md"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "radial-input",
|
|
123
|
+
"summary": "A rotary dial input component inspired by music production interfaces (Ableton Live, synthesiser knobs). Renders as a flattened arc SVG and responds to drag and keyboard input.",
|
|
124
|
+
"path": "docs-user/radial-input.md"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "range",
|
|
128
|
+
"summary": "Range: Coloured bar that suggests values",
|
|
129
|
+
"path": "docs-user/range.md"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"name": "range-input",
|
|
133
|
+
"summary": "A label-free, fully styled range slider wrapping `<input type=\"range\">`. Supports horizontal and vertical orientations, CSS variable theming, gradient fills, custom thumb shapes, and an optional value",
|
|
134
|
+
"path": "docs-user/range-input.md"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "rating",
|
|
138
|
+
"summary": "A rating input that renders a row of glyphs (star / heart / square). Supports half-step increments, keyboard control, per-rank theming via CSS variables, and prominence-based hover feedback. Clicking ",
|
|
139
|
+
"path": "docs-user/rating.md"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"name": "select-horiz",
|
|
143
|
+
"summary": "A horizontally scrolling, snap-to-center single-item picker. Children are ordinary elements you provide — the component doesn't render its own item markup, it just lays them out with scroll-snap, keep",
|
|
144
|
+
"path": "docs-user/select-horiz.md"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "slider-input",
|
|
148
|
+
"summary": "A linear SVG-based slider. Supports horizontal and vertical orientations, three value modes (single/dual/triple), three single-mode styles (range/bipolar/unipolar), triangle/needle/dot markers, and `v",
|
|
149
|
+
"path": "docs-user/slider-input.md"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"name": "snackbar",
|
|
153
|
+
"summary": "A small floating toolbar anchored in visual proximity to another element on the page (the \"target\"), built on the native Popover and CSS Anchor Positioning APIs.",
|
|
154
|
+
"path": "docs-user/snackbar.md"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "snap-container",
|
|
158
|
+
"summary": "A container that positions its child element at configurable snap positions along an axis. The child can be dragged, clicked to snap, or controlled via keyboard.",
|
|
159
|
+
"path": "docs-user/snap-container.md"
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"name": "split-layout",
|
|
163
|
+
"summary": "A Lit web component that lays out two elements within a container with a split bar to adjust their proportions.",
|
|
164
|
+
"path": "docs-user/split-layout.md"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"name": "swipe",
|
|
168
|
+
"summary": "A touch-friendly swipe/nudge component. User taps and drags to generate a value in range [-1, 1]. Value is emitted only on pointer release.",
|
|
169
|
+
"path": "docs-user/swipe.md"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"name": "tabs",
|
|
173
|
+
"summary": "A complete tabbed interface system using several coordinated components:",
|
|
174
|
+
"path": "docs-user/tabs.md"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"name": "timeline",
|
|
178
|
+
"summary": "A canvas-based timeline component with tracks, events, zoom/pan, and vertical track resizing. Suitable for visualizing time-series data, event logs, or scheduling.",
|
|
179
|
+
"path": "docs-user/timeline.md"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "transitory-label",
|
|
183
|
+
"summary": "An inline text label that animates between values instead of changing instantly. Displays as `inline-block` and inherits text styling from its parent.",
|
|
184
|
+
"path": "docs-user/transitory-label.md"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"name": "tree",
|
|
188
|
+
"summary": "Three components share a common `TreeComponent` interface: **`ixfx-tree-list`**, **`ixfx-miller-list`**, and **`ixfx-crumb-navigation`**. This document describes the shared API, plus component-specifi",
|
|
189
|
+
"path": "docs-user/tree.md"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"name": "util",
|
|
193
|
+
"summary": "A tooltip component that renders a value with optional icon and formatted number display. Uses native render root (no shadow DOM).",
|
|
194
|
+
"path": "docs-user/util.md"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"name": "vertical-list",
|
|
198
|
+
"summary": "A scrollable vertical list of items with selection, keyboard navigation, and incremental search. Items can be plain `<li>` elements declared in HTML or rich custom elements added programmatically.",
|
|
199
|
+
"path": "docs-user/vertical-list.md"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"name": "xy-pad",
|
|
203
|
+
"summary": "A 2D touch-friendly XY pad for controlling two parameters simultaneously. Each axis supports independent linear/logarithmic scaling.",
|
|
204
|
+
"path": "docs-user/xy-pad.md"
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
"overviews": [
|
|
208
|
+
{
|
|
209
|
+
"name": "user-catalog.md",
|
|
210
|
+
"path": "docs-user/user-catalog.md"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"name": "user-theming.md",
|
|
214
|
+
"path": "docs-user/user-theming.md"
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @ixfx/components
|
|
2
|
+
> Web components for ixfx — Lit-based UI toolkit
|
|
3
|
+
|
|
4
|
+
## Quick start
|
|
5
|
+
```bash
|
|
6
|
+
pnpm add @ixfx/components
|
|
7
|
+
```
|
|
8
|
+
```ts
|
|
9
|
+
import '@ixfx/components/button';
|
|
10
|
+
import '@ixfx/components/data-grid';
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Components
|
|
14
|
+
- [ac-text](docs-user/ac-text.md): VS Code command-palette style autocomplete text input. Shows a popup with matching results as the user types.
|
|
15
|
+
- [ac-token](docs-user/ac-token.md): Token/tag input with per-token autocomplete. Looks like a text box — committed tokens appear as inline chips, and a suggestion popup follows the typing cursor. Typical use cases are email To: fields a
|
|
16
|
+
- [button](docs-user/button.md): Three related button components:
|
|
17
|
+
- [checkbox](docs-user/checkbox.md): A custom checkbox with a diagonal line indicator and indeterminate state support. Uses shadow DOM with CSS variables for full appearance customization.
|
|
18
|
+
- [colour-picker](docs-user/colour-picker.md): Two components for picking OKLCH colours. Use `ixfx-colour-picker` when you need a full inline picker; use `ixfx-colour-picker-popup` when you need a compact swatch that opens a picker in a popover.
|
|
19
|
+
- [crumbs](docs-user/crumbs.md): Breadcrumb navigation with lazy-loading child support. Uses the same `TreeNode` / `TreeItem` data model as `ixfx-tree-list`, allowing easy swapping between the two components.
|
|
20
|
+
- [data-display](docs-user/data-display.md): A debug data display component that renders key-value pairs from a plain object. Supports 7 inline render modes (`led`, `plot`, `plot-xy`, `plot-heat`, `plot-histogram`, `time-elapsed`, `hide`) via `c
|
|
21
|
+
- [data-grid](docs-user/data-grid.md): A virtualised data grid with sortable/resizable/reorderable columns, single/multi selection, grouping, and inline cell editing. Handles 200+ rows with windowed rendering and keyboard navigation.
|
|
22
|
+
- [editable-label](docs-user/editable-label.md): Inline editable text components. `ixfx-editable-number` extends `ixfx-editable-label` with drag-to-adjust and fill-bar visualization.
|
|
23
|
+
- [form](docs-user/form.md): Primitives for typical form layout with responsive label positioning and data binding.
|
|
24
|
+
- [grouped-item-lister](docs-user/grouped-item-lister.md): A meta-component that renders a typed item list using any sub-component you supply. Items can be displayed in a single sub-component (_ungrouped_ mode) or split into labelled groups, each with its own
|
|
25
|
+
- [icons](docs-user/icons.md): A centralized SVG icon system for `@ixfx/components`. Icons are stored by name, can be overridden globally, and all components that use a given icon re-render automatically when it changes.
|
|
26
|
+
- [incr-search](docs-user/incr-search.md): Utilities for incremental (type-ahead) search over data collections or DOM-backed lists.
|
|
27
|
+
- [labelled-radial-input](docs-user/labelled-radial-input.md): A composite radial input that pairs an editable label (`ixfx-editable-number`) with a rotary dial (`ixfx-radial-input`). The two controls are always in sync — turning the dial updates the number, and
|
|
28
|
+
- [labelled-range-input](docs-user/labelled-range-input.md): A composite range input that pairs an editable label (`ixfx-editable-number`) with a slider (`ixfx-range-input`). The two controls are always in sync — dragging the slider updates the number, and edit
|
|
29
|
+
- [led](docs-user/led.md): An LED indicator component with color mixing and optional blinking animation.
|
|
30
|
+
- [menu](docs-user/menu.md): A custom menu system built on native HTML popovers with keyboard navigation, tickled focus management, and command routing.
|
|
31
|
+
- [miller](docs-user/miller.md): A Miller column component displays hierarchical data as multiple vertical columns, like macOS Finder or email clients. Each column shows the children of the selected item in the previous column.
|
|
32
|
+
- [narrowed-text](docs-user/narrowed-text.md): A filtered text selection component with inline search. Shows slotted items filtered by a query string as the user types.
|
|
33
|
+
- [notifier](docs-user/notifier.md): A "lookless" app-wide notification system. `NotificationManager` is a singleton that owns notification state, queueing, and timing — it doesn't know how to draw anything. A `NotificationRenderer` (the
|
|
34
|
+
- [panel](docs-user/panel.md): An collapsible panel component with support for titles, icons, toolbars, and multiple visual variants.
|
|
35
|
+
- [plots](docs-user/plots.md): SVG-based plotting components for visualising data streams.
|
|
36
|
+
- [polar-pad](docs-user/polar-pad.md): A circular pad for setting polar coordinates (angle + radius). The user clicks or drags within a circle to position a marker. The marker's position encodes an angle (degrees, 0 = right, clockwise) and
|
|
37
|
+
- [radial-input](docs-user/radial-input.md): A rotary dial input component inspired by music production interfaces (Ableton Live, synthesiser knobs). Renders as a flattened arc SVG and responds to drag and keyboard input.
|
|
38
|
+
- [range](docs-user/range.md): Range: Coloured bar that suggests values
|
|
39
|
+
- [range-input](docs-user/range-input.md): A label-free, fully styled range slider wrapping `<input type="range">`. Supports horizontal and vertical orientations, CSS variable theming, gradient fills, custom thumb shapes, and an optional value
|
|
40
|
+
- [rating](docs-user/rating.md): A rating input that renders a row of glyphs (star / heart / square). Supports half-step increments, keyboard control, per-rank theming via CSS variables, and prominence-based hover feedback. Clicking
|
|
41
|
+
- [select-horiz](docs-user/select-horiz.md): A horizontally scrolling, snap-to-center single-item picker. Children are ordinary elements you provide — the component doesn't render its own item markup, it just lays them out with scroll-snap, keep
|
|
42
|
+
- [slider-input](docs-user/slider-input.md): A linear SVG-based slider. Supports horizontal and vertical orientations, three value modes (single/dual/triple), three single-mode styles (range/bipolar/unipolar), triangle/needle/dot markers, and `v
|
|
43
|
+
- [snackbar](docs-user/snackbar.md): A small floating toolbar anchored in visual proximity to another element on the page (the "target"), built on the native Popover and CSS Anchor Positioning APIs.
|
|
44
|
+
- [snap-container](docs-user/snap-container.md): A container that positions its child element at configurable snap positions along an axis. The child can be dragged, clicked to snap, or controlled via keyboard.
|
|
45
|
+
- [split-layout](docs-user/split-layout.md): A Lit web component that lays out two elements within a container with a split bar to adjust their proportions.
|
|
46
|
+
- [swipe](docs-user/swipe.md): A touch-friendly swipe/nudge component. User taps and drags to generate a value in range [-1, 1]. Value is emitted only on pointer release.
|
|
47
|
+
- [tabs](docs-user/tabs.md): A complete tabbed interface system using several coordinated components:
|
|
48
|
+
- [timeline](docs-user/timeline.md): A canvas-based timeline component with tracks, events, zoom/pan, and vertical track resizing. Suitable for visualizing time-series data, event logs, or scheduling.
|
|
49
|
+
- [transitory-label](docs-user/transitory-label.md): An inline text label that animates between values instead of changing instantly. Displays as `inline-block` and inherits text styling from its parent.
|
|
50
|
+
- [tree](docs-user/tree.md): Three components share a common `TreeComponent` interface: **`ixfx-tree-list`**, **`ixfx-miller-list`**, and **`ixfx-crumb-navigation`**. This document describes the shared API, plus component-specifi
|
|
51
|
+
- [util](docs-user/util.md): A tooltip component that renders a value with optional icon and formatted number display. Uses native render root (no shadow DOM).
|
|
52
|
+
- [vertical-list](docs-user/vertical-list.md): A scrollable vertical list of items with selection, keyboard navigation, and incremental search. Items can be plain `<li>` elements declared in HTML or rich custom elements added programmatically.
|
|
53
|
+
- [xy-pad](docs-user/xy-pad.md): A 2D touch-friendly XY pad for controlling two parameters simultaneously. Each axis supports independent linear/logarithmic scaling.
|
|
54
|
+
|
|
55
|
+
## Overviews
|
|
56
|
+
- [user-catalog.md](docs-user/user-catalog.md)
|
|
57
|
+
- [user-theming.md](docs-user/user-theming.md)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# `ixfx-rating`
|
|
2
|
+
|
|
3
|
+
A rating input that renders a row of glyphs (star / heart / square). Supports half-step increments, keyboard control, per-rank theming via CSS variables, and prominence-based hover feedback. Clicking the current value clears it to `0` (unrated).
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<ixfx-rating value="3"></ixfx-rating>
|
|
7
|
+
<ixfx-rating allow-half value="2.5"></ixfx-rating>
|
|
8
|
+
<ixfx-rating max="10" value="7"></ixfx-rating>
|
|
9
|
+
<ixfx-rating variant="heart" value="4"></ixfx-rating>
|
|
10
|
+
<ixfx-rating variant="square" value="3"></ixfx-rating>
|
|
11
|
+
<ixfx-rating disabled value="3"></ixfx-rating>
|
|
12
|
+
<ixfx-rating readonly value="3"></ixfx-rating>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Properties / attributes
|
|
16
|
+
|
|
17
|
+
| Attribute / Property | Type | Default | Description |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| `value` | `number` | `0` | Current rating. `0` means unrated. Clamped `0..max` |
|
|
20
|
+
| `max` | `number` | `5` | Number of glyphs rendered |
|
|
21
|
+
| `allow-half` / `allowHalf` | `boolean` | `false` | When set, pointer position within a glyph selects `n` or `n+0.5`; keyboard step becomes `0.5` |
|
|
22
|
+
| `variant` | `"star"` \| `"heart"` \| `"square"` | `"star"` | Glyph shape |
|
|
23
|
+
| `disabled` | `boolean` | `false` | Disables interaction; muted via prominence filter and `pointer-events: none` |
|
|
24
|
+
| `readonly` | `boolean` | `false` | Prevents interaction but retains full visual prominence |
|
|
25
|
+
|
|
26
|
+
### Events
|
|
27
|
+
|
|
28
|
+
Both events bubble and are `composed`.
|
|
29
|
+
|
|
30
|
+
| Event | Detail | Description |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `input` | `{ value: number, oldValue: number }` | Fired on commit |
|
|
33
|
+
| `change` | `{ value: number, oldValue: number }` | Fired on commit (same timing as `input` for this component) |
|
|
34
|
+
|
|
35
|
+
Clicking the glyph that already equals `value` clears to `0`. Both events carry the previous value as `oldValue`.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import type { RatingChangeEvent } from './rating.js';
|
|
39
|
+
el.addEventListener('change', (e: RatingChangeEvent) => {
|
|
40
|
+
console.log(e.detail.value, e.detail.oldValue);
|
|
41
|
+
});
|
|
42
|
+
el.addEventListener('input', (e: RatingChangeEvent) => {
|
|
43
|
+
console.log(e.detail.value, e.detail.oldValue);
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Interaction
|
|
48
|
+
|
|
49
|
+
**Pointer:** hovering previews the value that would be set (filled glyphs use the hover colour, host gains prominence saturation). Click commits; clicking the active value clears to `0`. With `allow-half`, the left/right half of a glyph resolves to `n+0.5` / `n+1`.
|
|
50
|
+
|
|
51
|
+
**Keyboard** (when focused, not `disabled`/`readonly`):
|
|
52
|
+
|
|
53
|
+
| Key | Action |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `ArrowRight` / `ArrowUp` | Increase by `1` (or `0.5` with `allow-half`) |
|
|
56
|
+
| `ArrowLeft` / `ArrowDown` | Decrease by `1` (or `0.5`) |
|
|
57
|
+
| `Home` | Clear to `0` |
|
|
58
|
+
| `End` | Set to `max` |
|
|
59
|
+
| `0`–`9` | Set to that number (clamped to `max`) |
|
|
60
|
+
|
|
61
|
+
Accessibility: `role="slider"` with `aria-valuenow` / `aria-valuemin="0"` / `aria-valuemax` / `aria-disabled` / `aria-readonly`; `tabindex` is `0` when interactive, `-1` when `disabled` or `readonly`.
|
|
62
|
+
|
|
63
|
+
### CSS custom properties
|
|
64
|
+
|
|
65
|
+
| Property | Default | Description |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `--ixfx-rating-size` | `1.5rem` | Glyph width/height |
|
|
68
|
+
| `--ixfx-rating-gap` | `0.2rem` | Gap between glyphs |
|
|
69
|
+
| `--ixfx-rating-color` | `var(--surface-4)` | Idle glyph colour |
|
|
70
|
+
| `--ixfx-rating-color-active` | `var(--accent)` | Filled glyph colour |
|
|
71
|
+
| `--ixfx-rating-color-hover` | `var(--accent)` | Hover-preview glyph colour |
|
|
72
|
+
| `--ixfx-rating-<n>-color` | — | Per-rank idle override (e.g. `--ixfx-rating-3-color`) |
|
|
73
|
+
| `--ixfx-rating-<n>-color-active` | — | Per-rank filled override |
|
|
74
|
+
| `--ixfx-rating-<n>-color-hover` | — | Per-rank hover override |
|
|
75
|
+
|
|
76
|
+
Per-rank variables are set **outside** the shadow DOM (e.g. on the `ixfx-rating` element or a parent) and bridged via inline `var()` fallbacks on each glyph, so they pierce the shadow boundary without extra plumbing.
|
|
77
|
+
|
|
78
|
+
```html
|
|
79
|
+
<style>
|
|
80
|
+
ixfx-rating.saturated {
|
|
81
|
+
--ixfx-rating-1-color-active: oklch(70% 0.05 280);
|
|
82
|
+
--ixfx-rating-5-color-active: oklch(60% 0.25 30);
|
|
83
|
+
}
|
|
84
|
+
</style>
|
|
85
|
+
<ixfx-rating class="saturated" value="4"></ixfx-rating>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Prominence
|
|
89
|
+
|
|
90
|
+
Includes `prominenceStyles` from `src/styles/prominence.ts`: idle state is desaturated/dimmed, `:hover` / `:focus-within` raises opacity and saturation, `:active` removes the filter, `disabled` applies a heavy mute. `readonly` explicitly resets the filter so it remains visually full. Override via `--prominence-*` variables if needed.
|
|
91
|
+
|
|
92
|
+
### TypeScript types
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import type { RatingElement, RatingVariant, RatingChangeDetail, RatingChangeEvent } from 'ixfxfun-components';
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Implementation notes
|
|
99
|
+
|
|
100
|
+
* Half-fill is a stacked pair ofidentical SVGs — a background glyph plus an absolutely-positioned foreground glyph clipped with `clip-path: inset(0 50% 0 0)`.
|
|
101
|
+
* Glyph paths are inline `d` strings (`star` is a 5-point star, `heart` a cardioid-like path, `square` a rect) sharing a single `24×24` viewBox.
|
|
102
|
+
* Preview is local `@state _preview: number | null`, derived into render via `_effective() = _preview ?? value`; `pointerleave` on the host clears it.
|