@ixfx/components 0.15.4 → 0.16.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 +1223 -48
- package/bundle/index.js +875 -700
- package/dist/ac-text.d.ts +1 -1
- package/dist/{ac-token-Cq7lsYf-.d.ts → ac-token-qEs3FsQv.d.ts} +1 -1
- package/dist/ac-token.d.ts +1 -1
- package/dist/colour-picker.d.ts +1 -1
- package/dist/crumb-navigation-BbqfmkYs.d.ts +147 -0
- package/dist/crumb-navigation-YnFVFqrx.js +1290 -0
- package/dist/crumbs.d.ts +2 -115
- package/dist/crumbs.js +1 -1179
- package/dist/{data-grid-CbiubdG2.d.ts → data-grid-CIG2DVip.d.ts} +58 -9
- package/dist/{data-grid-Dx3l3dxw.js → data-grid-rMkLX2qo.js} +630 -215
- package/dist/data-grid.d.ts +3 -3
- package/dist/data-grid.js +1 -1
- package/dist/{detail-list-ClkMV0SN.d.ts → detail-list-6iMTNP4N.d.ts} +35 -5
- package/dist/{detail-list-q8bs67BM.js → detail-list-C4pDSoI8.js} +218 -7
- package/dist/detail-list.d.ts +4 -4
- package/dist/detail-list.js +1 -1
- package/dist/{flat-list-0xTZdXzh.d.ts → flat-list-JPgQSmLW.d.ts} +28 -5
- package/dist/flat-list.d.ts +2 -2
- package/dist/flat-list.js +123 -4
- package/dist/{grid-list-y6dWJYu3.js → grid-list-CdEkScn-.js} +276 -75
- package/dist/{grid-list-BnWJUIBC.d.ts → grid-list-D6n7WH8l.d.ts} +128 -22
- package/dist/grid-list.d.ts +3 -3
- package/dist/grid-list.js +1 -1
- package/dist/{grouped-item-lister-Bhyo-dkH.d.ts → grouped-item-lister-DETte0Dh.d.ts} +1 -1
- package/dist/grouped-item-lister.d.ts +1 -1
- package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +1 -1
- package/dist/icons.d.ts +2 -2
- package/dist/incr-search.d.ts +1 -1
- package/dist/index-9ttcdwlL.d.ts +71 -0
- package/dist/{index-BAuqR9El.d.ts → index-Bx0BXPxI.d.ts} +52 -6
- package/dist/index-CYRc6Dah.d.ts +475 -0
- package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +1 -1
- package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +1 -1
- package/dist/{index-Bz3loIAf.d.ts → index-DN2BWctP.d.ts} +1 -1
- package/dist/{index-BPTuCRGb.d.ts → index-Dr80Zdl6.d.ts} +2 -2
- package/dist/{index-cnaRPQPp.d.ts → index-DxyyVqzA.d.ts} +2 -2
- package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +1 -1
- package/dist/index.d.ts +380 -33
- package/dist/index.js +2247 -866
- package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +1 -1
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-slider-input.d.ts +1 -1
- package/dist/list-group-header.d.ts +1 -1
- package/dist/{list-native-drag-controller-O2Nruqpi.d.ts → list-native-drag-controller-D_UrXipS.d.ts} +1 -1
- package/dist/{list-selection-controller-BeE70lbB.js → list-selection-controller-5L0Nj9tR.js} +87 -2
- package/dist/{menu-item-B0zqw2xp.d.ts → menu-item-bF6narIz.d.ts} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/miller-BFRfn0ve.js +2237 -0
- package/dist/miller.d.ts +4 -437
- package/dist/miller.js +1 -1815
- package/dist/panel.d.ts +1 -1
- package/dist/pending-BGidHppL.js +91 -0
- package/dist/scroll-hover-guard-Cjw6179Q.js +35 -0
- package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-CophkNeU.d.ts} +42 -4
- package/dist/{split-layout-Deoxy47d.js → split-layout-DTY4PJRp.js} +251 -19
- package/dist/split-layout.d.ts +1 -1
- package/dist/split-layout.js +1 -1
- package/dist/sunburst-tree.d.ts +2 -0
- package/dist/sunburst-tree.js +2 -0
- package/dist/sunbursttree-list-B_VxOHlo.js +1556 -0
- package/dist/sunbursttree-list-D6j5BxVQ.d.ts +303 -0
- package/dist/{tab-list-wC0xNz1b.d.ts → tab-list-Df371rqw.d.ts} +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +1 -1
- package/dist/titlebar.d.ts +1 -1
- package/dist/tree-CftHwtEb.js +146 -0
- package/dist/{tree-D8VxvR9u.js → tree-Crdpl4nc.js} +275 -47
- package/dist/{tree-component-C6UHO-w9.d.ts → tree-component-DgfkxmVY.d.ts} +19 -8
- package/dist/tree.d.ts +3 -3
- package/dist/tree.js +1 -1
- package/dist/types-LU1u0CB8.d.ts +87 -0
- package/dist/vertical-list-1V1Vg2O5.js +1993 -0
- package/dist/{vertical-list-B8FoU-pU.d.ts → vertical-list-BPDmZx6T.d.ts} +31 -3
- package/dist/vertical-list.d.ts +3 -3
- package/dist/vertical-list.js +1 -1789
- package/dist/view-state-controller-BdyXWUUM.js +305 -0
- package/docs-user/README.md +3 -0
- package/docs-user/crumbs.md +27 -0
- package/docs-user/data-grid.md +77 -5
- package/docs-user/detail-list.md +54 -0
- package/docs-user/dock.md +54 -12
- package/docs-user/flat-list.md +27 -0
- package/docs-user/grid-list.md +64 -11
- package/docs-user/hyperbolic-tree.md +31 -4
- package/docs-user/icicle-tree.md +36 -0
- package/docs-user/index.json +17 -2
- package/docs-user/llms.txt +3 -0
- package/docs-user/miller.md +52 -21
- package/docs-user/multicol-list.md +50 -8
- package/docs-user/split-layout.md +45 -17
- package/docs-user/sunburst-tree.md +223 -0
- package/docs-user/tree.md +46 -7
- package/docs-user/treemap.md +32 -0
- package/docs-user/twosplit-layout.md +22 -0
- package/docs-user/user-catalog.md +1 -1
- package/docs-user/vertical-list.md +55 -7
- package/llms.txt +3 -0
- package/package.json +5 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Sunburst Tree
|
|
2
|
+
|
|
3
|
+
`<ixfx-sunbursttree-list>` — a zoomable sunburst over weighted tree data. The zoom node is the centre disc; each ring outward is one generation, and each arc's angle is its share of its parent's value. Every change — data arriving, a different weighting, a zoom — animates from what's on screen to the new layout.
|
|
4
|
+
|
|
5
|
+
It implements the shared `TreeComponent` interface (see [`src/tree/README.md`](../tree/README.md)), so `TreeDataModel`, `IncrSearchTreeController`, and `TreeComponent`-typed code work unmodified. Geometrically it is a polar [icicle](../icicle-tree/), and shares its API shape.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
1. [Differences from `ixfx-tree-list`](#differences-from-ixfx-tree-list)
|
|
12
|
+
2. [Data model](#data-model)
|
|
13
|
+
3. [Values and weighting](#values-and-weighting)
|
|
14
|
+
4. [Progressive data](#progressive-data)
|
|
15
|
+
5. [Colour](#colour)
|
|
16
|
+
6. [Properties](#properties)
|
|
17
|
+
7. [Zoom, selection, navigation](#zoom-selection-navigation)
|
|
18
|
+
8. [Events](#events)
|
|
19
|
+
9. [Keyboard / pointer interaction](#keyboard--pointer-interaction)
|
|
20
|
+
10. [View state](#view-state)
|
|
21
|
+
11. [CSS variables and parts](#css-variables-and-parts)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Differences from `ixfx-tree-list`
|
|
26
|
+
|
|
27
|
+
- **Expand/collapse is reinterpreted as zoom.** `expand` fires on zoom-in, `collapse` on zoom-out.
|
|
28
|
+
- **`interactionMode` drops `'checked'`**; **`exclusivity` is accepted but ignored**.
|
|
29
|
+
- **`filterPredicate` dims** non-matching arcs instead of hiding them.
|
|
30
|
+
- **Reassigning `root` keeps zoom and selection** wherever the same key paths still exist; state whose path has gone stays pending and comes back with it. See [Progressive data](#progressive-data) and [View state](#view-state).
|
|
31
|
+
- Drag-and-drop is out of scope.
|
|
32
|
+
|
|
33
|
+
## Data model
|
|
34
|
+
|
|
35
|
+
Same `TreeNode` / `TreeItem` shapes as the rest of the tree family, including `root`, `model` and `loadChildren` for lazy loading (children are fetched for every visible arc).
|
|
36
|
+
|
|
37
|
+
Keys only need to be unique **among siblings**: arcs are identified by their key *path* from the root, so file-system data — where `readme.md` recurs in many folders — works. Lookups that only have a bare key (`revealKey`) match the first node, depth-first, carrying it.
|
|
38
|
+
|
|
39
|
+
## Values and weighting
|
|
40
|
+
|
|
41
|
+
Every node — branches included — has a value. A child's arc is its share of its parent's:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
childAngle = parentAngle × child / max(parent, Σ siblings)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Children summing to **less** than their parent leave an unfilled gap — "unaccounted for" space (unscanned disk, an unknown remainder).
|
|
48
|
+
- Children summing to **more** are scaled down to fit.
|
|
49
|
+
|
|
50
|
+
Give values as a plain number on `item.weight` (the default accessor reads it), or as a function:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
el.root = {
|
|
54
|
+
item: { key: 'hd', label: 'Disk', weight: 500e9 },
|
|
55
|
+
children: [
|
|
56
|
+
{ item: { key: 'apps', label: 'Applications', weight: 120e9 }, children: [] },
|
|
57
|
+
{ item: { key: 'users', label: 'Users', weight: 300e9 }, children: [] },
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Swap weighting scheme: no DOM is rebuilt, the chart animates to the new layout.
|
|
62
|
+
el.valueAccessor = (item, node) => (item.data as Stats).fileCount;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`valueAccessor` is `(item, node) => number | undefined`. When it returns `undefined` (or a negative / non-finite number) the node falls back to the **sum of its loaded children**, or `1` for a leaf or not-yet-loaded node. So unweighted data shows descendant counts, and an accessor can value only leaves and let branches sum:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
el.valueAccessor = (item, node) => node.children ? undefined : Math.log2(bytes(item) + 1);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`valueFormatter` (`(value, node) => string`) formats the value in the centre readout:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
el.valueFormatter = v => `${(v / 1e9).toFixed(1)} GB`;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Progressive data
|
|
78
|
+
|
|
79
|
+
Any update re-lays out and animates: new arcs grow from zero width, removed ones shrink away, the rest slide to their new angles. An update arriving mid-animation retargets from wherever things currently are.
|
|
80
|
+
|
|
81
|
+
Either rebuild the tree immutably and reassign it:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
el.root = snapshotOfScanSoFar(); // zoom + selection carry over by key path
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
or mutate in place and nudge the element — or let a `TreeDataModel` notify it:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
folder.children.push(newFile);
|
|
91
|
+
el.requestUpdate();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Colour
|
|
95
|
+
|
|
96
|
+
Hue is set by the ring around the centre: each first-ring arc takes the hue at its angular midpoint (so the ring spans the colour wheel), and every descendant takes a tone of that hue — lighter and less saturated each ring out, with a small per-sibling shift so neighbours stay distinct. Zooming re-anchors hues to the new first ring, cross-fading as it goes. The centre disc mixes towards `--sunbursttree-center-color`.
|
|
97
|
+
|
|
98
|
+
All of it is computed in CSS from per-arc custom properties, so the palette is themeable:
|
|
99
|
+
|
|
100
|
+
| Per-arc property | Value |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `--arc-hue` | Degrees, added to `--sunbursttree-hue-start` |
|
|
103
|
+
| `--arc-depth` | Ring index from the centre (`0` = first ring) |
|
|
104
|
+
| `--arc-shade` | Sibling-position offset, `-0.5..0.5` |
|
|
105
|
+
| `--arc-centre` | `0..1`, how far the arc has become the centre disc |
|
|
106
|
+
|
|
107
|
+
## Properties
|
|
108
|
+
|
|
109
|
+
| Property (attribute) | Type | Default | Description |
|
|
110
|
+
|---|---|---|---|
|
|
111
|
+
| `root` | `TreeNode \| undefined` | `undefined` | Root node of the tree |
|
|
112
|
+
| `model` | `TreeDataModel \| undefined` | `undefined` | Shared data model; takes precedence over `loadChildren` |
|
|
113
|
+
| `loadChildren` | `LoadChildrenCallback \| undefined` | `undefined` | Callback for lazy child loading |
|
|
114
|
+
| `valueAccessor` | `SunburstValueAccessor` | `item => item.weight` | Node value. See [Values and weighting](#values-and-weighting) |
|
|
115
|
+
| `valueFormatter` | `SunburstValueFormatter` | locale number | Formats the centre readout's value |
|
|
116
|
+
| `interactionMode` (`interaction-mode`) | `'implicit' \| 'standard' \| 'manual'` | `'standard'` | Gesture mapping |
|
|
117
|
+
| `selectionFilter` (`selection-filter`) | `'none' \| 'leaf' \| 'branch' \| 'all'` | `'all'` | Which node kinds can be selected |
|
|
118
|
+
| `maxDepth` (`max-depth`) | `number` | `5` | Rings drawn around the centre |
|
|
119
|
+
| `centerRatio` (`center-ratio`) | `number` | `0.22` | Centre disc radius as a fraction of the overall radius |
|
|
120
|
+
| `minArcLength` (`min-arc-length`) | `number` | `1.5` | Arcs whose outer edge is shorter than this (px) aren't drawn — bounds DOM size for big trees |
|
|
121
|
+
| `disableLabels` (`disable-labels`) | `boolean` | `false` | Hide in-arc labels (the centre readout remains) |
|
|
122
|
+
| `curvedLabels` (`curved-labels`) | `boolean` | `false` | Curve labels along their ring instead of drawing them straight. See below |
|
|
123
|
+
| `animationDuration` (`animation-duration`) | `number` | `600` | Transition length in ms; `0` snaps. Respects `prefers-reduced-motion` |
|
|
124
|
+
| `filterPredicate` | `TreeFilterPredicate \| undefined` | `undefined` | Non-matching arcs (with no matching descendant) are dimmed |
|
|
125
|
+
| `disableKeyboardNavigation` (`disable-keyboard-navigation`) | `boolean` | `false` | Turn off keyboard handling |
|
|
126
|
+
| `searchModes` (`search-modes`) | `string \| undefined` | `undefined` | Subset of `navigate select filter` — see [`docs/infra-incremental.md`](../../docs/infra-incremental.md) |
|
|
127
|
+
| `exclusivity` | `TreeExclusivity` | `'none'` | Accepted for interface compatibility, ignored |
|
|
128
|
+
| `selectedNode` / `selectedNodes` | | | Same contract as `ixfx-tree-list` |
|
|
129
|
+
| `focusedNode` | `TreeNode \| undefined` (read-only) | `undefined` | Current zoom node; `undefined` when showing the full tree |
|
|
130
|
+
|
|
131
|
+
In-arc labels run along the ring when the arc is long enough, otherwise radially (truncated to the ring width); both flip to stay upright. With `curved-labels`, ring-following labels bend to the arc (an SVG `<textPath>` along the ring's middle, reversed in the bottom half so it reads upright). Since the whole arc length is usable, long labels are truncated with `…` rather than dropped; arcs too narrow for a few characters still fall back to straight radial text. Arcs too thin for either are unlabelled — hover or keyboard-cursor them and the centre readout shows their label, value and share of the centre.
|
|
132
|
+
|
|
133
|
+
## Zoom, selection, navigation
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
el.zoomTo(node); // node becomes the centre
|
|
137
|
+
el.zoomUp(); // centre's parent becomes the centre
|
|
138
|
+
el.zoomOut(); // back to the full tree
|
|
139
|
+
|
|
140
|
+
el.select(node); el.deselect(node); el.clearSelection(); el.selectAll(); el.deselectAll();
|
|
141
|
+
|
|
142
|
+
// Zooms so the target sits in the first ring (its parent at the centre), then selects it.
|
|
143
|
+
el.navigateTo(['users', 'me', 'photos']);
|
|
144
|
+
el.navigateToNode(n => n.item.key === 'photos');
|
|
145
|
+
|
|
146
|
+
el.getNodes(); // visible arcs (centre excluded), ring-major
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Events
|
|
150
|
+
|
|
151
|
+
All events **bubble** and are **composed**. `depth` counts from the root's children (`0`).
|
|
152
|
+
|
|
153
|
+
| Event | Detail | When |
|
|
154
|
+
|---|---|---|
|
|
155
|
+
| `zoom` | `SunburstZoomDetail` — `{ node: TreeNode \| undefined; depth }` | Zoom node changes (`node` undefined = full tree) |
|
|
156
|
+
| `expand` / `collapse` | `{ node; depth }` | Zoomed into a descendant / out of the previous centre |
|
|
157
|
+
| `select` | `TreeSelectDetail` | Selection changes |
|
|
158
|
+
| `tickle` | `TreeTickleDetail` | Pointer or keyboard cursor enters an arc |
|
|
159
|
+
| `activate` | `TreeActivateDetail` | Enter or double-click |
|
|
160
|
+
| `item-click` / `item-dblclick` | `{ node; depth }` | Raw pointer clicks on an arc |
|
|
161
|
+
|
|
162
|
+
## Keyboard / pointer interaction
|
|
163
|
+
|
|
164
|
+
| Input | Action |
|
|
165
|
+
|---|---|
|
|
166
|
+
| Click an arc | Select (per `interactionMode`) and zoom in, if it has children |
|
|
167
|
+
| Ctrl/⌘-click, Shift-click | Toggle / range-select (`standard` mode), without zooming |
|
|
168
|
+
| Click the centre | Zoom up one level |
|
|
169
|
+
| `←` / `→` | Previous / next sibling (wraps) |
|
|
170
|
+
| `↑` / `↓` | Parent (inward) / first child (outward) |
|
|
171
|
+
| `Home` / `End` | First / last visible arc |
|
|
172
|
+
| `Enter` | Select, activate and zoom in |
|
|
173
|
+
| `Escape` / `Backspace` | Zoom up one level |
|
|
174
|
+
|
|
175
|
+
## View state
|
|
176
|
+
|
|
177
|
+
Implements the shared view-state API (`getViewState()` / `setViewState()` / `clearPendingViewState()` / `view-state-change`) — see [`docs/infra-view-state.md`](../../docs/infra-view-state.md). `kind` is `sunbursttree-list`.
|
|
178
|
+
|
|
179
|
+
| Field | Type | Meaning |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `selected` | `string[]` | Selected `item.key`s |
|
|
182
|
+
| `zoom` | `string[]` | Key path from the root's children to the centre node; `[]` = full tree |
|
|
183
|
+
| `focus` | `string` | Keyboard-cursor `item.key` (recorded only when the cursor was moved by keyboard) |
|
|
184
|
+
|
|
185
|
+
There is no `expanded` (expansion *is* zoom) and no `scroll`.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
const stop = bindViewState(el, {
|
|
189
|
+
load: () => JSON.parse(localStorage.getItem(`disk`) ?? `null`),
|
|
190
|
+
save: s => localStorage.setItem(`disk`, JSON.stringify(s)),
|
|
191
|
+
});
|
|
192
|
+
el.root = await scan(); // zoom + selection apply as their nodes arrive
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- State for nodes not loaded yet stays pending and applies when they appear — whether the tree is reassigned, grown in place, or lazily loaded. A data change that removes the zoom node or a selected node moves it back to pending (silently), so it returns with its path.
|
|
196
|
+
- `zoom` is a path because keys only need to be unique among siblings. While it is pending, the nodes along it are loaded one at a time via `loadChildren` / `model` (set `restoreLoads = false` to only apply it as the host loads them).
|
|
197
|
+
- Live selection follows its key path across data changes. A restored `selected` key matches the first node, depth-first, carrying it — so with repeated keys (`readme.md` in many folders) a restored selection can land on a different node.
|
|
198
|
+
- Restored selection fires `select`; a restored zoom fires `zoom` (and `expand`). Any explicit selection change drops pending selection; any explicit zoom (`zoomTo()`, clicks, `navigateTo()`…) drops a pending zoom.
|
|
199
|
+
|
|
200
|
+
| Property | Type | Default | Description |
|
|
201
|
+
|---|---|---|---|
|
|
202
|
+
| `restoreLoads` | `boolean` | `true` | Load nodes along a pending saved zoom path |
|
|
203
|
+
|
|
204
|
+
## CSS variables and parts
|
|
205
|
+
|
|
206
|
+
| Variable | Default | Description |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| `--sunbursttree-hue-start` | `250` | Hue at 12 o'clock |
|
|
209
|
+
| `--sunbursttree-chroma` | `0.14` | First-ring chroma |
|
|
210
|
+
| `--sunbursttree-chroma-step` | `0.015` | Chroma lost per ring outward |
|
|
211
|
+
| `--sunbursttree-lightness` | `60%` | First-ring lightness |
|
|
212
|
+
| `--sunbursttree-lightness-step` | `5%` | Lightness gained per ring outward |
|
|
213
|
+
| `--sunbursttree-shade-step` | `10%` | Lightness spread across siblings |
|
|
214
|
+
| `--sunbursttree-center-color` | `var(--surface-4)` | Centre disc fill |
|
|
215
|
+
| `--sunbursttree-center-text` | `var(--surface-4-text)` | Centre readout text |
|
|
216
|
+
| `--sunbursttree-gap-color` | `var(--surface-2)` | Stroke between arcs — match it to the background |
|
|
217
|
+
| `--sunbursttree-gap` | `1px` | Width of that stroke |
|
|
218
|
+
| `--sunbursttree-font-size` | `11px` | Label size (px; read for label fitting) |
|
|
219
|
+
| `--sunbursttree-label-lightness` | `22%` | Label lightness (hue follows the arc) |
|
|
220
|
+
|
|
221
|
+
Parts: `arc`, `center`, `label`, `center-readout`.
|
|
222
|
+
|
|
223
|
+
The host defaults to `aspect-ratio: 1` with a `200px` minimum height; give it a width (or both dimensions) to size it.
|
package/docs-user/tree.md
CHANGED
|
@@ -20,6 +20,7 @@ Three components share a common `TreeComponent` interface: **`ixfx-tree-list`**,
|
|
|
20
20
|
7. [ARIA](#aria)
|
|
21
21
|
8. [CSS variables](#css-variables)
|
|
22
22
|
9. [Controller authoring guide](#controller-authoring-guide)
|
|
23
|
+
10. [View state](#view-state-ixfx-tree-list)
|
|
23
24
|
|
|
24
25
|
---
|
|
25
26
|
|
|
@@ -37,7 +38,7 @@ type TreeItem = {
|
|
|
37
38
|
icon?: string; // Icon name (passed to <ixfx-icon>)
|
|
38
39
|
tooltip?: string; // Tooltip content
|
|
39
40
|
value?: string; // Optional machine-readable value
|
|
40
|
-
weight?: number; // Relative importance/magnitude;
|
|
41
|
+
weight?: number; // Relative importance/magnitude; used by ixfx-hyperbolictree-list and ixfx-sunbursttree-list
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
type TreeNode = {
|
|
@@ -148,11 +149,12 @@ These properties are present on all three components (`ixfx-tree-list`, `ixfx-mi
|
|
|
148
149
|
| `interactionMode` | `TreeInteractionMode` | `'standard'` | How gestures map to selection changes (`ixfx-tree-list` / `ixfx-miller-list` only) |
|
|
149
150
|
| `selectionFilter` | `'none' \| 'leaf' \| 'branch'` | `'leaf'` | Which node kinds can be selected (reflected attribute) |
|
|
150
151
|
| `alignCheckboxes` (`align-checkboxes`) | `boolean` | `false` | In `checked` mode, unselectable rows keep the space their checkbox would take so they line up with selectable siblings (`ixfx-tree-list` only). See [Unselectable items](#unselectable-items-selectable-aligncheckboxes) |
|
|
151
|
-
| `filterPredicate` | `TreeFilterPredicate \| undefined` | `undefined` | Filter; only matching nodes and their ancestors are rendered (non-matching rows are not in the DOM
|
|
152
|
+
| `filterPredicate` | `TreeFilterPredicate \| undefined` | `undefined` | Filter; only matching nodes and their ancestors are rendered (non-matching rows are not in the DOM; keyboard navigation, `selectAll`/`deselectAll` and Shift-range skip them) |
|
|
152
153
|
| `exclusivity` | `'none' \| 'depth' \| 'global'` | `'none'` | Expansion exclusivity (reflected attribute) |
|
|
153
154
|
| `stickyHeaders` (`sticky-headers`) | `boolean` | `true` | VS Code-style sticky headers; set `sticky-headers="false"` to opt out (`ixfx-tree-list` only) |
|
|
154
155
|
| `virtualize` | `'auto' \| 'on' \| 'off'` | `'auto'` | Render only the rows near the viewport; `auto` switches on above `virtualizeThreshold` visible rows (`ixfx-tree-list` only). See [Virtualisation](#virtualisation-ixfx-tree-list) |
|
|
155
156
|
| `virtualizeThreshold` (`virtualize-threshold`) | `number` | `200` | Visible-row count above which `virtualize="auto"` windows the list |
|
|
157
|
+
| `scrollHoverTickle` (`scroll-hover-tickle`) | `boolean` | `false` | Let the hover cursor follow rows that scroll beneath a stationary pointer. Off by default: during a scroll gesture row `pointerenter` is ignored (host carries `data-scroll-hover-suppress`), so the hover highlight and `tickle` hold still instead of trailing the content. Hover resumes on the next real pointer movement or when the pointer leaves |
|
|
156
158
|
| `animation` | `'auto' \| 'always' \| 'never'` | `'auto'` | Controls row enter/leave animations. `'auto'` respects `prefers-reduced-motion`; `'always'` always animates; `'never'` skips all animations. Can be overridden per-call on `expandAll`, `collapseAll`, `navigateTo`, `revealKey`, and `navigateToNode` |
|
|
157
159
|
|
|
158
160
|
### Replacing `root`
|
|
@@ -387,14 +389,14 @@ el.selectAll();
|
|
|
387
389
|
el.deselectAll();
|
|
388
390
|
```
|
|
389
391
|
|
|
390
|
-
`selectAll()`
|
|
392
|
+
`selectAll()` selects every selectable node in the tree, including nodes inside collapsed branches (unloaded lazy children are not included). `deselectAll()` deselects the same set. Pass `{ visibleOnly: true }` to act only on the rows that are showing; Ctrl+A and the `select-all` command do this.
|
|
391
393
|
|
|
392
|
-
| Mode | `selectAll()` | `
|
|
394
|
+
| Mode | `selectAll()` | `selectAll({ visibleOnly: true })` |
|
|
393
395
|
|------|---------------|-----------------|
|
|
394
|
-
| `checked` | Checks
|
|
395
|
-
| All other modes | Adds every
|
|
396
|
+
| `checked` | Checks every selectable node | Same: checking a row checks its descendants |
|
|
397
|
+
| All other modes | Adds every selectable node to the selection | Adds the showing selectable rows |
|
|
396
398
|
|
|
397
|
-
While a `filterPredicate` is active, `selectAll()` / `deselectAll()` and Shift-range selection
|
|
399
|
+
While a `filterPredicate` is active, `selectAll()` / `deselectAll()` cover only the matching nodes (and their matching ancestors), and Shift-range selection covers only the rows that are shown (as in `ixfx-vertical-list`). `deselectAll()` leaves selected nodes the filter hides alone.
|
|
398
400
|
|
|
399
401
|
Both methods dispatch a single `select` event with the full old and new selection sets. `selectAll` respects `selectionFilter` — only nodes that pass the filter are selected.
|
|
400
402
|
|
|
@@ -455,6 +457,43 @@ Notes:
|
|
|
455
457
|
|
|
456
458
|
---
|
|
457
459
|
|
|
460
|
+
## View state (`ixfx-tree-list`)
|
|
461
|
+
|
|
462
|
+
Snapshot and restore selection, expansion, keyboard cursor and scroll
|
|
463
|
+
separately from the data — see [`docs/infra-view-state.md`](../../docs/infra-view-state.md)
|
|
464
|
+
for the shared contract. `kind: 'tree-list'`; fields `selected`, `expanded`,
|
|
465
|
+
`focus`, `scroll`, all keyed by `item.key`.
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
import { bindViewState } from '@ixfx/components';
|
|
469
|
+
|
|
470
|
+
bindViewState(tree, {
|
|
471
|
+
load: () => JSON.parse(localStorage.getItem(`tree`) ?? `null`),
|
|
472
|
+
save: s => localStorage.setItem(`tree`, JSON.stringify(s)),
|
|
473
|
+
});
|
|
474
|
+
tree.root = initialRoot; // any time, before or after
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
- **Keys, not nodes.** Replacing `root` keeps selection, expansion and cursor
|
|
478
|
+
for every key the new root still has. State for keys that disappear is kept
|
|
479
|
+
*pending* and comes back if they reappear — expand `C`, swap in a root
|
|
480
|
+
without it, swap back, and `C` is open again.
|
|
481
|
+
- **Built up over time.** `setViewState({ expanded: { A: true, B: true, C: true } })`
|
|
482
|
+
then grow the tree (new `root`, or mutate `children` + `invalidateStructure()`):
|
|
483
|
+
each branch opens as it arrives.
|
|
484
|
+
- **Lazy trees.** With `restoreLoads` (default `true`) saved-open branches that
|
|
485
|
+
aren't loaded are fetched through `loadChildren` / `model`, one at a time, so
|
|
486
|
+
a saved path cascades open. `el.restoreLoads = false` to only open branches
|
|
487
|
+
the host loads itself.
|
|
488
|
+
- **Selection.** A restored key fires the normal `select` event
|
|
489
|
+
(`origin: 'programmatic'`). Any explicit selection change — click, key,
|
|
490
|
+
`select()`, `clearSelection()` — drops a saved selection that hasn't matched yet.
|
|
491
|
+
- **Scroll** is saved as the first visible row's key plus an offset, and is
|
|
492
|
+
applied once that row exists. The user's own scroll cancels it.
|
|
493
|
+
- `focus` is recorded only for a keyboard-moved cursor, not mouse hover.
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
458
497
|
## Events
|
|
459
498
|
|
|
460
499
|
All events **bubble** and are **composed** (cross shadow-DOM boundaries).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Treemap
|
|
2
|
+
|
|
3
|
+
`<ixfx-treemap-list>` — a nested-area (treemap) view over tree data. The zoom root fills the viewport; each node's rectangle is subdivided among its children by `valueAccessor` share. Clicking a branch zooms into it, and ancestors collapse into a breadcrumb strip. It implements the shared `TreeComponent` interface (see [`src/tree/README.md`](../tree/README.md)). See the class docs in `treemap-list.ts` for properties and events.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## View state
|
|
8
|
+
|
|
9
|
+
Implements the shared view-state API (`getViewState()` / `setViewState()` / `clearPendingViewState()` / `view-state-change`) — see [`docs/infra-view-state.md`](../../docs/infra-view-state.md). `kind` is `treemap-list`.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
type TreemapListViewState = ViewStateBase & {
|
|
13
|
+
zoom?: string[]; // key path from the root's children to the zoom root; [] = full tree
|
|
14
|
+
};
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Field | Meaning |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `selected` | Selected item keys. |
|
|
20
|
+
| `focus` | Keyboard cursor key. It is only recorded when the cursor was moved by keyboard or search navigation. |
|
|
21
|
+
| `zoom` | The zoomed-into node, as a key path. The target is matched by key anywhere in the tree. The ancestors in the path only matter when the target isn't loaded yet. |
|
|
22
|
+
|
|
23
|
+
There is no `expanded` (zoom stands in for it) and no `scroll` (the treemap fills its box).
|
|
24
|
+
|
|
25
|
+
- **Data changes keep state.** A new `root`, a model `root` / `invalidate` event or a lazy load re-applies state by key. If the zoom root goes away, the view falls back to the full tree silently and `zoom` stays pending. Selected nodes that go away are deselected silently and their keys stay pending.
|
|
26
|
+
- **Lazy data.** With `restoreLoads` (default `true`), a saved `zoom` whose target isn't loaded yet is reached by loading each ancestor in turn via `loadChildren` / `model`.
|
|
27
|
+
- **Events.** A restored selection fires `select`. A restored zoom fires `zoom` (not `expand`/`collapse`) and doesn't animate.
|
|
28
|
+
- An explicit zoom (click, key, wheel, crumbs, `zoomTo()` / `zoomOut()`) drops a pending `zoom`. Any explicit selection change drops pending `selected`.
|
|
29
|
+
|
|
30
|
+
| Property | Type | Default | Description |
|
|
31
|
+
|---|---|---|---|
|
|
32
|
+
| `restoreLoads` | `boolean` | `true` | Whether restoring a saved `zoom` may load its unloaded ancestors. |
|
|
@@ -46,6 +46,28 @@ theme it with the `--ixfx-handle-*` variables (see
|
|
|
46
46
|
| Event | Detail | Description |
|
|
47
47
|
|-------|--------|-------------|
|
|
48
48
|
| `ixfx-split-collapsed` | `{ panel: 'A' \| 'B', collapsed: boolean }` | Fired when a panel is collapsed or uncollapsed via drag. |
|
|
49
|
+
| `view-state-change` | `{ state: TwoSplitLayoutViewState, reason }` | Debounced, after a drag that changed the sizes and after `setViewState()`. See [View state](#view-state). |
|
|
50
|
+
|
|
51
|
+
### View state
|
|
52
|
+
|
|
53
|
+
`getViewState()` / `setViewState()` snapshot and restore both sides as plain
|
|
54
|
+
JSON (`kind: 'twosplit-layout'`), keyed by slot name. The component never
|
|
55
|
+
persists anything itself — see
|
|
56
|
+
[docs/infra-view-state.md](../../docs/infra-view-state.md) and `bindViewState()`.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
split.getViewState();
|
|
60
|
+
// { v: 1, kind: 'twosplit-layout', layout: { a: { size: '30%' }, b: { size: '70%' } } }
|
|
61
|
+
split.setViewState({ layout: { a: { size: '0px', collapsed: true }, b: { size: '100%' } } });
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
| Field | Type | Meaning |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| `layout` | `{ a?, b?: { size: string; collapsed?: boolean } }` | `size` as in `sizeA` / `sizeB`; `collapsed` absent ⇒ expanded. A side missing from a restored `layout` is left as it is. |
|
|
67
|
+
|
|
68
|
+
Both slots always exist, so nothing is ever pending (`clearPendingViewState()`
|
|
69
|
+
is a no-op). Note the `layout` *field* is unrelated to the `layout`
|
|
70
|
+
(orientation) attribute.
|
|
49
71
|
|
|
50
72
|
---
|
|
51
73
|
|
|
@@ -124,7 +124,7 @@ A meta-component that renders a typed item list using any sub-component you supp
|
|
|
124
124
|
## Layout Components
|
|
125
125
|
|
|
126
126
|
### ixfx-dock-host / ixfx-dock-panel
|
|
127
|
-
A dockable panel system in the style of VS Code. Author a flat pool of `ixfx-dock-panel` elements inside an `ixfx-dock-host`; drag panels by titlebar or tab to tab them together, split panels horizontally/vertically, or drag between hosts. Layouts
|
|
127
|
+
A dockable panel system in the style of VS Code. Author a flat pool of `ixfx-dock-panel` elements inside an `ixfx-dock-host`; drag panels by titlebar or tab to tab them together, split panels horizontally/vertically, or drag between hosts. Layouts save and restore via `getViewState()` / `setViewState()` (see `docs/infra-view-state.md`). Drop restrictions are available per host (`accepts` attribute, `canAccept()` callback) and per panel (`accepts`). Use for IDE-like workspaces, dashboards, or any composable multi-panel UI.
|
|
128
128
|
|
|
129
129
|
### ixfx-split-layout
|
|
130
130
|
A resizable n-way split pane that allows users to adjust the proportion between adjacent sections. Supports `row`/`column` directions, positional `sizes` weights, per-child `size`/`min`/`collapsed` attributes, and nested splits for cross-axis layouts. Use for editor layouts, file explorers with previews, or any interface where users need to control space allocation.
|
|
@@ -20,8 +20,9 @@ A scrollable vertical list of items with selection, keyboard navigation, and inc
|
|
|
20
20
|
12. [Context menu](#context-menu)
|
|
21
21
|
13. [In-place rename](#in-place-rename)
|
|
22
22
|
14. [Virtualisation](#virtualisation)
|
|
23
|
-
15. [
|
|
24
|
-
16. [CSS
|
|
23
|
+
15. [View state](#view-state)
|
|
24
|
+
16. [CSS variables](#css-variables)
|
|
25
|
+
17. [CSS parts](#css-parts)
|
|
25
26
|
|
|
26
27
|
---
|
|
27
28
|
|
|
@@ -387,7 +388,8 @@ list.addItem(myElement);
|
|
|
387
388
|
// In checked mode, add a row that shows no checkbox and can't be checked
|
|
388
389
|
list.addItem('Header', { notChecked: true });
|
|
389
390
|
|
|
390
|
-
// Remove a specific element (returns a Promise that resolves once it's gone)
|
|
391
|
+
// Remove a specific element (returns a Promise that resolves once it's gone).
|
|
392
|
+
// A selected item is deselected silently; its key stays pending (see View state).
|
|
391
393
|
list.removeItem(element);
|
|
392
394
|
list.removeItems(list.selectedItems);
|
|
393
395
|
|
|
@@ -453,12 +455,13 @@ list.addEventListener('list-select', ({ detail }) => {
|
|
|
453
455
|
});
|
|
454
456
|
```
|
|
455
457
|
|
|
456
|
-
|
|
458
|
+
Selection survives a data reload by itself: keys of selected items that
|
|
459
|
+
leave the list (`clearItems`, `removeItem`, a DOM removal, an adapter rebuild)
|
|
460
|
+
go pending and are re-selected when items with the same keys come back.
|
|
457
461
|
|
|
458
462
|
```typescript
|
|
459
|
-
|
|
460
|
-
list.setItems(await fetchRows()); //
|
|
461
|
-
list.selectKeys(keep); // ...but the keys still resolve
|
|
463
|
+
list.clearItems();
|
|
464
|
+
list.setItems(await fetchRows()); // previously-selected keys re-select
|
|
462
465
|
```
|
|
463
466
|
|
|
464
467
|
The `data-key` requirement is documented, not enforced: items without a key
|
|
@@ -768,6 +771,51 @@ dispatch. Mirrors `ixfx-grid-list`'s `grid-list-viewport-change`.
|
|
|
768
771
|
|
|
769
772
|
---
|
|
770
773
|
|
|
774
|
+
## View state
|
|
775
|
+
|
|
776
|
+
The list implements the shared view-state API (see `docs/infra-view-state.md`):
|
|
777
|
+
snapshot *how* it shows its items as plain JSON and restore it later, before or
|
|
778
|
+
after the items exist. Kind: `vertical-list`. All state is keyed by each row's
|
|
779
|
+
`data-key` / `data-value`, so rows without a key don't take part.
|
|
780
|
+
|
|
781
|
+
| Field | Type | Meaning |
|
|
782
|
+
|---|---|---|
|
|
783
|
+
| `selected` | `string[]` | Selected keys. In `checked` mode this is the checked set. |
|
|
784
|
+
| `focus` | `string` | Keyboard cursor key. Only recorded while the cursor was last moved by keyboard. |
|
|
785
|
+
| `scroll` | `{ top, left?, anchor?: { key, offset } }` | First visible row's key plus px offset into it. Works with `virtualize` too. |
|
|
786
|
+
|
|
787
|
+
```typescript
|
|
788
|
+
import { bindViewState } from '@ixfx/components';
|
|
789
|
+
|
|
790
|
+
bindViewState(list, {
|
|
791
|
+
load: () => JSON.parse(localStorage.getItem('files') ?? 'null'),
|
|
792
|
+
save: s => localStorage.setItem('files', JSON.stringify(s)),
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
list.getViewState(); // { v: 1, kind: 'vertical-list', selected, focus, scroll }
|
|
796
|
+
list.setViewState({ selected: ['a'] }); // partial: only fields present apply
|
|
797
|
+
list.clearPendingViewState();
|
|
798
|
+
list.addEventListener('view-state-change', e => e.detail /* { state, reason } */);
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
- **Pending state.** Keys that aren't in the list yet stay pending and apply as
|
|
802
|
+
matching rows arrive through `addItem`, `setItems`, a plain `appendChild`, an
|
|
803
|
+
`items` rebuild, or a virtual registry change. `getViewState()` includes pending
|
|
804
|
+
state by default (`includePending: false` leaves it out).
|
|
805
|
+
- **Selection.** A restored selection fires the normal `list-select`. Any explicit
|
|
806
|
+
selection change (click, key, `select*()`, `clearSelection()`) drops pending
|
|
807
|
+
selection. A selected row that leaves the list is deselected **silently** (no
|
|
808
|
+
`list-select`) and its key goes pending.
|
|
809
|
+
- **Scroll** is applied once the anchor row exists and the list is laid out
|
|
810
|
+
(it is retried on data changes and resizes). The user's own wheel, touch,
|
|
811
|
+
pointer or navigation key cancels a pending scroll.
|
|
812
|
+
- **Focus.** A keyboard cursor whose row leaves the list goes pending and comes
|
|
813
|
+
back when the key reappears. Moving the cursor by keyboard, or `focusKey()`,
|
|
814
|
+
drops a pending one.
|
|
815
|
+
- `view-state-change` is debounced (150 ms), bubbles and is composed.
|
|
816
|
+
|
|
817
|
+
---
|
|
818
|
+
|
|
771
819
|
## CSS variables
|
|
772
820
|
|
|
773
821
|
| Variable | Default | Description |
|
package/llms.txt
CHANGED
|
@@ -30,6 +30,7 @@ import '@ixfx/components/data-grid';
|
|
|
30
30
|
- [grid-list](docs-user/grid-list.md): A virtualised grid of items — thumbnails, cards, or arbitrary slotted markup —
|
|
31
31
|
- [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
|
|
32
32
|
- [hyperbolic-tree](docs-user/hyperbolic-tree.md): `<ixfx-hyperbolictree-list>` — a hyperbolic (Poincaré disk) browser over tree data. The focused node sits at the disk's center; its neighbourhood fans outward, shrinking toward the edge with tree-grap
|
|
33
|
+
- [icicle-tree](docs-user/icicle-tree.md): `<ixfx-icicletree-list>` — an icicle (partition) view over tree data. Each depth is a band; each node a rectangle sized by its `valueAccessor` share of its parent. Clicking a branch zooms so it become
|
|
33
34
|
- [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.
|
|
34
35
|
- [incr-search](docs-user/incr-search.md): Utilities for incremental (type-ahead) search over data collections or DOM-backed lists.
|
|
35
36
|
- [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
|
|
@@ -56,6 +57,7 @@ import '@ixfx/components/data-grid';
|
|
|
56
57
|
- [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.
|
|
57
58
|
- [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.
|
|
58
59
|
- [split-layout](docs-user/split-layout.md): A Lit web component that lays out any number of panels along one axis with draggable gutters between them.
|
|
60
|
+
- [sunburst-tree](docs-user/sunburst-tree.md): `<ixfx-sunbursttree-list>` — a zoomable sunburst over weighted tree data. The zoom node is the centre disc; each ring outward is one generation, and each arc's angle is its share of its parent's value
|
|
59
61
|
- [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.
|
|
60
62
|
- [tabs](docs-user/tabs.md): A complete tabbed interface system using several coordinated components:
|
|
61
63
|
- [text-shimmer](docs-user/text-shimmer.md): A label with a sweeping highlight band across the text. Useful as a lightweight "still working…" or "loading…" indicator.
|
|
@@ -64,6 +66,7 @@ import '@ixfx/components/data-grid';
|
|
|
64
66
|
- [toolbar](docs-user/toolbar.md): Two components for building toolbars:
|
|
65
67
|
- [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.
|
|
66
68
|
- [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
|
|
69
|
+
- [treemap](docs-user/treemap.md): `<ixfx-treemap-list>` — a nested-area (treemap) view over tree data. The zoom root fills the viewport; each node's rectangle is subdivided among its children by `valueAccessor` share. Clicking a branc
|
|
67
70
|
- [twosplit-layout](docs-user/twosplit-layout.md): A Lit web component that lays out two elements within a container with a split bar to adjust their proportions.
|
|
68
71
|
- [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).
|
|
69
72
|
- [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. Lar
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixfx/components",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.16.0",
|
|
5
5
|
"packageManager": "pnpm@10.0.0",
|
|
6
6
|
"description": "Web components for ixfx — Lit-based UI toolkit",
|
|
7
7
|
"author": "Clint Heyer",
|
|
@@ -141,6 +141,10 @@
|
|
|
141
141
|
"types": "./dist/tabs.d.ts",
|
|
142
142
|
"import": "./dist/tabs.js"
|
|
143
143
|
},
|
|
144
|
+
"./sunburst-tree": {
|
|
145
|
+
"types": "./dist/sunburst-tree.d.ts",
|
|
146
|
+
"import": "./dist/sunburst-tree.js"
|
|
147
|
+
},
|
|
144
148
|
"./timeline": {
|
|
145
149
|
"types": "./dist/timeline.d.ts",
|
|
146
150
|
"import": "./dist/timeline.js"
|