@ixfx/components 0.15.3 → 0.15.5
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 +473 -17
- package/bundle/index.js +432 -225
- package/dist/crumbs.d.ts +1 -1
- package/dist/{data-grid-Dx3l3dxw.js → data-grid-C1sZX6n9.js} +37 -9
- package/dist/{data-grid-DmkId8bu.d.ts → data-grid-D7qzmMMp.d.ts} +13 -6
- package/dist/data-grid.d.ts +2 -2
- package/dist/data-grid.js +1 -1
- package/dist/{detail-list-CmQqeXvp.d.ts → detail-list-CKIKlszv.d.ts} +3 -3
- package/dist/detail-list.d.ts +3 -3
- package/dist/{flat-list-BmQBB3ZC.d.ts → flat-list-DXMyDiSH.d.ts} +2 -2
- package/dist/flat-list.d.ts +1 -1
- package/dist/{grid-list-BVsUEvgd.d.ts → grid-list-0e7snW6t.d.ts} +3 -3
- package/dist/grid-list.d.ts +2 -2
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-DuhzWWTr.d.ts → index-DEVyVIn8.d.ts} +28 -8
- package/dist/{index-BvoXLnBf.d.ts → index-KN2MW_xD.d.ts} +1 -1
- package/dist/index.d.ts +176 -15
- package/dist/index.js +274 -64
- package/dist/{list-native-drag-controller-NMspr0E1.d.ts → list-native-drag-controller-O2Nruqpi.d.ts} +1 -1
- package/dist/miller.d.ts +2 -2
- package/dist/sunburst-tree.d.ts +2 -0
- package/dist/sunburst-tree.js +2 -0
- package/dist/sunbursttree-list--Z0uyh8O.d.ts +266 -0
- package/dist/sunbursttree-list-yXwS-uEI.js +1337 -0
- package/dist/{tree-2_TRrLAV.js → tree-D8VxvR9u.js} +44 -5
- package/dist/{tree-component-CDsYTBDi.d.ts → tree-component-C6UHO-w9.d.ts} +12 -3
- package/dist/tree.d.ts +3 -3
- package/dist/tree.js +1 -1
- package/dist/{vertical-list-ztrdFvyT.d.ts → vertical-list-D8MksoTp.d.ts} +2 -2
- package/dist/vertical-list.d.ts +2 -2
- package/docs-user/README.md +1 -0
- package/docs-user/data-grid.md +11 -4
- package/docs-user/dock.md +62 -1
- package/docs-user/index.json +7 -2
- package/docs-user/llms.txt +1 -0
- package/docs-user/sunburst-tree.md +193 -0
- package/docs-user/tree.md +40 -1
- package/llms.txt +1 -0
- package/package.json +5 -1
|
@@ -3,7 +3,7 @@ import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrA
|
|
|
3
3
|
import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
|
|
4
4
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
5
5
|
import { i as ListSearchController, n as listSearchStyles, o as registerListSearchCommands, r as LIST_SEARCH_MODES, t as createTreeListSearchAdapter } from "./incr-search-JIhwB49y.js";
|
|
6
|
-
import { i as animateListItemOut, r as animateListItemIn, t as ListNativeDragController } from "./list-native-drag-controller-CcXoS0YX.js";
|
|
6
|
+
import { i as animateListItemOut, o as prefersReducedMotion, r as animateListItemIn, t as ListNativeDragController } from "./list-native-drag-controller-CcXoS0YX.js";
|
|
7
7
|
import "./interaction-E-uMGHkJ.js";
|
|
8
8
|
import { t as collectDataResult } from "./data-provider-35TyWclX.js";
|
|
9
9
|
import { LitElement, css, html, nothing } from "lit";
|
|
@@ -1211,6 +1211,7 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
1211
1211
|
this.stickyHeaders = true;
|
|
1212
1212
|
this.virtualize = `auto`;
|
|
1213
1213
|
this.virtualizeThreshold = 200;
|
|
1214
|
+
this.animation = `auto`;
|
|
1214
1215
|
this.applyInternalDrop = true;
|
|
1215
1216
|
this._expandedKeys = /* @__PURE__ */ new Set();
|
|
1216
1217
|
this.#structureVersion = 0;
|
|
@@ -1650,6 +1651,12 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
1650
1651
|
#leaving;
|
|
1651
1652
|
#leavingAnimations;
|
|
1652
1653
|
#treeAnimReady;
|
|
1654
|
+
/**
|
|
1655
|
+
* Per-call animation override. When set (by methods like `expandAll` with `animate: false`),
|
|
1656
|
+
* it takes precedence over the `animation` property for one update cycle.
|
|
1657
|
+
* Cleared after each update.
|
|
1658
|
+
*/
|
|
1659
|
+
#animationOverride;
|
|
1653
1660
|
#dragSourceId;
|
|
1654
1661
|
#postDragSuppressTimer;
|
|
1655
1662
|
#dropState;
|
|
@@ -1901,6 +1908,11 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
1901
1908
|
return false;
|
|
1902
1909
|
}
|
|
1903
1910
|
#runItemAnimations() {
|
|
1911
|
+
if (!this.#shouldAnimate()) {
|
|
1912
|
+
this.#enteringKeys.clear();
|
|
1913
|
+
this.#cancelAllLeavingAnimations();
|
|
1914
|
+
this.#leaving.clear();
|
|
1915
|
+
}
|
|
1904
1916
|
if (this.#enteringKeys.size > 0) {
|
|
1905
1917
|
for (const el of this.renderRoot.querySelectorAll(`.item`)) {
|
|
1906
1918
|
const key = el.dataset.key;
|
|
@@ -1944,6 +1956,17 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
1944
1956
|
for (const entry of visible) this.#lastNodeByKey.set(entry.node.item.key, entry);
|
|
1945
1957
|
this.#treeAnimReady = true;
|
|
1946
1958
|
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Determines whether row enter/leave animations should run for this update.
|
|
1961
|
+
* Checks the per-call `#animationOverride` first, then the `animation` property,
|
|
1962
|
+
* and finally `prefersReducedMotion()`.
|
|
1963
|
+
*/
|
|
1964
|
+
#shouldAnimate() {
|
|
1965
|
+
if (this.#animationOverride !== void 0) return this.#animationOverride;
|
|
1966
|
+
if (this.animation === `never`) return false;
|
|
1967
|
+
if (this.animation === `always`) return true;
|
|
1968
|
+
return !prefersReducedMotion();
|
|
1969
|
+
}
|
|
1947
1970
|
updated(changedProps) {
|
|
1948
1971
|
this.#rowsCache = void 0;
|
|
1949
1972
|
this.#syncVirtualObservers();
|
|
@@ -1994,6 +2017,7 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
1994
2017
|
if (this.#measureMetrics()) queueMicrotask(() => this.requestUpdate());
|
|
1995
2018
|
this.#repaintSearchHighlights();
|
|
1996
2019
|
} else this.#runItemAnimations();
|
|
2020
|
+
this.#animationOverride = void 0;
|
|
1997
2021
|
}
|
|
1998
2022
|
/** Highlights are painted on rendered labels, so they move with the window. */
|
|
1999
2023
|
#repaintSearchHighlights() {
|
|
@@ -2496,8 +2520,12 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
2496
2520
|
* have loaded to expand further. Bulk expansion ignores `exclusivity`. Fires
|
|
2497
2521
|
* one `expand` event per branch that actually opens — none for branches that
|
|
2498
2522
|
* were already expanded, including ones opened by filter auto-expansion.
|
|
2523
|
+
*
|
|
2524
|
+
* @param maxDepth - Maximum depth to expand to
|
|
2525
|
+
* @param animate - Whether to animate row enter/leave. When omitted, uses the `animation` property value.
|
|
2499
2526
|
*/
|
|
2500
|
-
expandAll(maxDepth) {
|
|
2527
|
+
expandAll(maxDepth, animate) {
|
|
2528
|
+
this.#animationOverride = animate;
|
|
2501
2529
|
this.#bulkExpand(true, maxDepth);
|
|
2502
2530
|
}
|
|
2503
2531
|
/**
|
|
@@ -2505,8 +2533,12 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
2505
2533
|
* branches at depth >= `maxDepth` are collapsed, leaving the tree open down
|
|
2506
2534
|
* to depth `maxDepth - 1` (`collapseAll(0)` is a full collapse). Fires one
|
|
2507
2535
|
* `collapse` event per branch that actually closes.
|
|
2536
|
+
*
|
|
2537
|
+
* @param maxDepth - Maximum depth to collapse from
|
|
2538
|
+
* @param animate - Whether to animate row enter/leave. When omitted, uses the `animation` property value.
|
|
2508
2539
|
*/
|
|
2509
|
-
collapseAll(maxDepth) {
|
|
2540
|
+
collapseAll(maxDepth, animate) {
|
|
2541
|
+
this.#animationOverride = animate;
|
|
2510
2542
|
this.#bulkExpand(false, maxDepth);
|
|
2511
2543
|
}
|
|
2512
2544
|
/** Shared bulk expand / collapse: one `_expandedKeys` write, per-node events for real changes only. */
|
|
@@ -2556,6 +2588,7 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
2556
2588
|
const prevSilent = this.#selectSilent;
|
|
2557
2589
|
this.#selectOrigin = `programmatic`;
|
|
2558
2590
|
this.#selectSilent = options.silent === true;
|
|
2591
|
+
if (options.animate !== void 0) this.#animationOverride = options.animate;
|
|
2559
2592
|
try {
|
|
2560
2593
|
return this.#navigateTo(keys, options.reveal ?? `edge`);
|
|
2561
2594
|
} finally {
|
|
@@ -2587,15 +2620,17 @@ let TreeBaseElement = class TreeBaseElement extends LitElement {
|
|
|
2587
2620
|
this.#scrollKeyIntoView(keys.at(-1), reveal);
|
|
2588
2621
|
return true;
|
|
2589
2622
|
}
|
|
2590
|
-
navigateToNode(predicate) {
|
|
2623
|
+
navigateToNode(predicate, animate) {
|
|
2591
2624
|
if (!this.root?.children) return false;
|
|
2625
|
+
if (animate !== void 0) this.#animationOverride = animate;
|
|
2592
2626
|
const keyPath = this.#findNodePath(this.root.children, predicate);
|
|
2593
2627
|
if (!keyPath) return false;
|
|
2594
2628
|
return this.navigateTo(keyPath);
|
|
2595
2629
|
}
|
|
2596
2630
|
/** Expand ancestors + move the cursor to `key`, without touching the selection (search "navigate" mode). */
|
|
2597
|
-
revealKey(key) {
|
|
2631
|
+
revealKey(key, animate) {
|
|
2598
2632
|
if (!this.root?.children) return false;
|
|
2633
|
+
if (animate !== void 0) this.#animationOverride = animate;
|
|
2599
2634
|
const path = this.#findNodePath(this.root.children, (n) => n.item.key === key);
|
|
2600
2635
|
if (!path) return false;
|
|
2601
2636
|
for (let i = 0; i < path.length - 1; i++) {
|
|
@@ -3542,6 +3577,10 @@ __decorate([property({
|
|
|
3542
3577
|
type: Number,
|
|
3543
3578
|
attribute: `virtualize-threshold`
|
|
3544
3579
|
})], TreeBaseElement.prototype, "virtualizeThreshold", void 0);
|
|
3580
|
+
__decorate([property({
|
|
3581
|
+
reflect: true,
|
|
3582
|
+
attribute: `animation`
|
|
3583
|
+
})], TreeBaseElement.prototype, "animation", void 0);
|
|
3545
3584
|
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "dragPreviewRenderer", void 0);
|
|
3546
3585
|
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "dragPreviewSource", void 0);
|
|
3547
3586
|
__decorate([property({ attribute: false })], TreeBaseElement.prototype, "canDrag", void 0);
|
|
@@ -220,6 +220,11 @@ type TreeNavigateOptions = {
|
|
|
220
220
|
reveal?: TreeRevealMode;
|
|
221
221
|
/** Suppress the `select` event this navigation would otherwise fire. */
|
|
222
222
|
silent?: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Whether to animate row enter/leave for this operation.
|
|
225
|
+
* When omitted, uses the `animation` property value (`'auto'` by default).
|
|
226
|
+
*/
|
|
227
|
+
animate?: boolean;
|
|
223
228
|
};
|
|
224
229
|
/**
|
|
225
230
|
* Fired when the selection set changes by any means (click, keyboard, programmatic).
|
|
@@ -385,18 +390,22 @@ interface TreeComponent extends EventTarget {
|
|
|
385
390
|
* Expand ancestors and select the node reached by following `keys` from the root's children.
|
|
386
391
|
* Returns `true` if the path was found and applied.
|
|
387
392
|
*/
|
|
388
|
-
navigateTo: (keys: readonly string[]) => boolean;
|
|
393
|
+
navigateTo: (keys: readonly string[], options?: TreeNavigateOptions) => boolean;
|
|
389
394
|
/**
|
|
390
395
|
* Expand ancestors and select the first node for which `predicate` returns `true`.
|
|
391
396
|
* Returns `true` if a matching node was found.
|
|
397
|
+
* @param predicate - Function to find the target node
|
|
398
|
+
* @param animate - Whether to animate row enter/leave. When omitted, uses the `animation` property value.
|
|
392
399
|
*/
|
|
393
|
-
navigateToNode: (predicate: (node: TreeNode) => boolean) => boolean;
|
|
400
|
+
navigateToNode: (predicate: (node: TreeNode) => boolean, animate?: boolean) => boolean;
|
|
394
401
|
/**
|
|
395
402
|
* Expand ancestors of the node with `key` and move the keyboard cursor to it,
|
|
396
403
|
* scrolling it into view — **without** changing the selection. Returns `true`
|
|
397
404
|
* if the node was found. Used by incremental-search "navigate" mode.
|
|
405
|
+
* @param key - Key of the node to reveal
|
|
406
|
+
* @param animate - Whether to animate row enter/leave. When omitted, uses the `animation` property value.
|
|
398
407
|
*/
|
|
399
|
-
revealKey: (key: string) => boolean;
|
|
408
|
+
revealKey: (key: string, animate?: boolean) => boolean;
|
|
400
409
|
/** Replace the selection with `nodes` (subject to `selectionFilter`). Used by incremental-search "select" mode. */
|
|
401
410
|
selectMany: (nodes: Iterable<TreeNode>) => void;
|
|
402
411
|
/**
|
package/dist/tree.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as TreeTickleEvent, D as TreeSelectDetail, M as TreeDataModelOptions, O as TreeSelectEvent, T as TreeRevealMode, _ as TreeDropTarget, b as TreeItemClickDetail, c as TreeDragContext, d as TreeDragStartEvent, g as TreeDropPosition, h as TreeDropEvent, i as TreeCollapseEvent, j as TreeDataModel, k as TreeTickleDetail, l as TreeDragEndEvent, m as TreeDropDetail, n as TreeActivateEvent, o as TreeComponentEventMap, p as TreeDropContext, r as TreeCollapseDetail, s as TreeDndMode, t as TreeActivateDetail, u as TreeDragOverEvent, v as TreeExpandDetail, w as TreeNavigateOptions, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-
|
|
1
|
+
import { A as TreeTickleEvent, D as TreeSelectDetail, M as TreeDataModelOptions, O as TreeSelectEvent, T as TreeRevealMode, _ as TreeDropTarget, b as TreeItemClickDetail, c as TreeDragContext, d as TreeDragStartEvent, g as TreeDropPosition, h as TreeDropEvent, i as TreeCollapseEvent, j as TreeDataModel, k as TreeTickleDetail, l as TreeDragEndEvent, m as TreeDropDetail, n as TreeActivateEvent, o as TreeComponentEventMap, p as TreeDropContext, r as TreeCollapseDetail, s as TreeDndMode, t as TreeActivateDetail, u as TreeDragOverEvent, v as TreeExpandDetail, w as TreeNavigateOptions, x as TreeItemClickEvent, y as TreeExpandEvent } from "./tree-component-C6UHO-w9.js";
|
|
2
2
|
import { a as TreeItem, n as TreeExclusivity, o as TreeNode, r as TreeFilterPredicate, s as TreeSelectionFilter, t as LoadChildrenCallback } from "./types-Jky6oNAp.js";
|
|
3
|
-
import { a as TreeDropVisibleRow, c as TreeListElement, d as
|
|
4
|
-
export { type LoadChildrenCallback, type TreeActivateDetail, type TreeActivateEvent, TreeBaseElement, TreeBaseElementEventMap, type TreeCheckboxState, type TreeCollapseDetail, type TreeCollapseEvent, type TreeComponentEventMap, TreeConfig, TreeController, TreeControllerOptions, TreeDataModel, type TreeDataModelOptions, type TreeDndMode, type TreeDragContext, type TreeDragEndEvent, type TreeDragOverEvent, type TreeDragStartEvent, type TreeDropContext, TreeDropController, TreeDropControllerConfig, type TreeDropDetail, type TreeDropEvent, type TreeDropPosition, TreeDropResolvedDrag, TreeDropRowInfo, type TreeDropTarget, TreeDropVisibleRow, type TreeExclusivity, type TreeExpandDetail, type TreeExpandEvent, type TreeFilterPredicate, type TreeItem, type TreeItemClickDetail, type TreeItemClickEvent, TreeListElement, type TreeNavigateOptions, type TreeNode, type TreeRevealMode, type TreeSelectDetail, type TreeSelectEvent, type TreeSelectionFilter, type TreeTickleDetail, type TreeTickleEvent, TreeVirtualize };
|
|
3
|
+
import { a as TreeDropVisibleRow, c as TreeListElement, d as TreeBaseElement, f as TreeBaseElementEventMap, i as TreeDropRowInfo, l as TreeCheckboxState, m as TreeConfig, n as TreeDropControllerConfig, o as TreeController, p as TreeVirtualize, r as TreeDropResolvedDrag, s as TreeControllerOptions, t as TreeDropController, u as TreeAnimation } from "./index-DEVyVIn8.js";
|
|
4
|
+
export { type LoadChildrenCallback, type TreeActivateDetail, type TreeActivateEvent, TreeAnimation, TreeBaseElement, TreeBaseElementEventMap, type TreeCheckboxState, type TreeCollapseDetail, type TreeCollapseEvent, type TreeComponentEventMap, TreeConfig, TreeController, TreeControllerOptions, TreeDataModel, type TreeDataModelOptions, type TreeDndMode, type TreeDragContext, type TreeDragEndEvent, type TreeDragOverEvent, type TreeDragStartEvent, type TreeDropContext, TreeDropController, TreeDropControllerConfig, type TreeDropDetail, type TreeDropEvent, type TreeDropPosition, TreeDropResolvedDrag, TreeDropRowInfo, type TreeDropTarget, TreeDropVisibleRow, type TreeExclusivity, type TreeExpandDetail, type TreeExpandEvent, type TreeFilterPredicate, type TreeItem, type TreeItemClickDetail, type TreeItemClickEvent, TreeListElement, type TreeNavigateOptions, type TreeNode, type TreeRevealMode, type TreeSelectDetail, type TreeSelectEvent, type TreeSelectionFilter, type TreeTickleDetail, type TreeTickleEvent, TreeVirtualize };
|
package/dist/tree.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as TreeDataModel, i as TreeDropController, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-
|
|
1
|
+
import { a as TreeDataModel, i as TreeDropController, n as TreeListElement, r as TreeBaseElement, t as TreeController } from "./tree-D8VxvR9u.js";
|
|
2
2
|
export { TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeListElement };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as ListNativeDragStartEvent, I as ListDragPreviewRenderer, L as ListDragPreviewSourceResolver } from "./tree-component-
|
|
1
|
+
import { B as ListNativeDragStartEvent, I as ListDragPreviewRenderer, L as ListDragPreviewSourceResolver } from "./tree-component-C6UHO-w9.js";
|
|
2
2
|
import { n as ListViewportChangeEvent } from "./list-viewport-types-BRZsLcvp.js";
|
|
3
|
-
import { S as ListSearchController } from "./index-
|
|
3
|
+
import { S as ListSearchController } from "./index-KN2MW_xD.js";
|
|
4
4
|
import { i as ListInteractionMode, l as ListSelectionMode, r as ListElementEventMap } from "./list-selection-types-PjKdhF-a.js";
|
|
5
5
|
import "./editable-label-rzXkjf1H.js";
|
|
6
6
|
import { LitElement, PropertyValues } from "lit";
|
package/dist/vertical-list.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as ListNativeDragStartEvent, F as ListDragPreviewContext, I as ListDragPreviewRenderer, N as ListDragEntry, P as ListDragPreview, R as ListDragSource, z as ListNativeDragStartDetail } from "./tree-component-
|
|
1
|
+
import { B as ListNativeDragStartEvent, F as ListDragPreviewContext, I as ListDragPreviewRenderer, N as ListDragEntry, P as ListDragPreview, R as ListDragSource, z as ListNativeDragStartDetail } from "./tree-component-C6UHO-w9.js";
|
|
2
2
|
import { n as ListViewportChangeEvent, t as ListViewportChangeDetail } from "./list-viewport-types-BRZsLcvp.js";
|
|
3
3
|
import { a as ListItemClickDetail, c as ListSelectEvent, d as ListTickleEvent, i as ListInteractionMode, l as ListSelectionMode, n as ListActivateEvent, o as ListItemClickEvent, r as ListElementEventMap, s as ListSelectDetail, t as ListActivateDetail, u as ListTickleDetail } from "./list-selection-types-PjKdhF-a.js";
|
|
4
|
-
import { a as ListContextMenuDetail, c as ListDragLeaveEvent, d as ListDropEvent, f as ListEditCancelDetail, h as ListEditCommitEvent, i as VerticalListElementEventMap, l as ListDragOverEvent, m as ListEditCommitDetail, n as CustomCheckboxOptions, o as ListContextMenuEvent, p as ListEditCancelEvent, r as VerticalListElement, s as ListDragLeaveDetail, t as AddItemOptions, u as ListDropDetail } from "./vertical-list-
|
|
4
|
+
import { a as ListContextMenuDetail, c as ListDragLeaveEvent, d as ListDropEvent, f as ListEditCancelDetail, h as ListEditCommitEvent, i as VerticalListElementEventMap, l as ListDragOverEvent, m as ListEditCommitDetail, n as CustomCheckboxOptions, o as ListContextMenuEvent, p as ListEditCancelEvent, r as VerticalListElement, s as ListDragLeaveDetail, t as AddItemOptions, u as ListDropDetail } from "./vertical-list-D8MksoTp.js";
|
|
5
5
|
export { AddItemOptions, CustomCheckboxOptions, type ListActivateDetail, type ListActivateEvent, type ListContextMenuDetail, type ListContextMenuEvent, type ListDragEntry, type ListDragLeaveDetail, type ListDragLeaveEvent, type ListDragOverEvent, type ListDragPreview, type ListDragPreviewContext, type ListDragPreviewRenderer, type ListDragSource, type ListDropDetail, type ListDropEvent, type ListEditCancelDetail, type ListEditCancelEvent, type ListEditCommitDetail, type ListEditCommitEvent, type ListElementEventMap, type ListInteractionMode, type ListItemClickDetail, type ListItemClickEvent, type ListNativeDragStartDetail, type ListNativeDragStartEvent, type ListSelectDetail, type ListSelectEvent, type ListSelectionMode, type ListTickleDetail, type ListTickleEvent, type ListViewportChangeDetail, type ListViewportChangeEvent, VerticalListElement, VerticalListElementEventMap };
|
package/docs-user/README.md
CHANGED
|
@@ -49,6 +49,7 @@ This directory contains documentation for each component and some architectural
|
|
|
49
49
|
- [snackbar](./snackbar.md)
|
|
50
50
|
- [snap-container](./snap-container.md)
|
|
51
51
|
- [split-layout](./split-layout.md)
|
|
52
|
+
- [sunburst-tree](./sunburst-tree.md)
|
|
52
53
|
- [swipe](./swipe.md)
|
|
53
54
|
- [tabs](./tabs.md)
|
|
54
55
|
- [text-shimmer](./text-shimmer.md)
|
package/docs-user/data-grid.md
CHANGED
|
@@ -306,9 +306,12 @@ for plain text columns. It returns `false` and does nothing for:
|
|
|
306
306
|
|
|
307
307
|
- an unknown column key,
|
|
308
308
|
- a column with `resizable: false`,
|
|
309
|
-
- a column with a `renderer`
|
|
310
|
-
markup, etc.) can't be reliably measured from
|
|
311
|
-
|
|
309
|
+
- a column with a `renderer` that gives no hint of its size — its rendered
|
|
310
|
+
output (icons, badges, custom markup, etc.) can't be reliably measured from
|
|
311
|
+
the raw value. Opt in with either:
|
|
312
|
+
- `fixedExtraWidth: n` — pixels added to the measured text width (e.g. a
|
|
313
|
+
thumbnail beside the text), or
|
|
314
|
+
- `measure: (row, col) => px` — your own content-width measure per row.
|
|
312
315
|
|
|
313
316
|
`--data-grid-column-resize-duration` (default `180ms`) controls the
|
|
314
317
|
transition speed.
|
|
@@ -459,6 +462,10 @@ Demo: `Score` is random float `0–100` with 0–3 decimals, `align:'right'`, `f
|
|
|
459
462
|
|
|
460
463
|
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}`.
|
|
461
464
|
|
|
465
|
+
Set `col.group` to a heading (e.g. the facet a column came from) and the menu
|
|
466
|
+
lists columns sharing that group in one submenu; ungrouped columns stay at the
|
|
467
|
+
top level.
|
|
468
|
+
|
|
462
469
|
`column-menu` attribute: `none` (default) hides the gear menu; `auto` opts in to
|
|
463
470
|
rendering it. `col.visible` + `datagrid-column-visibility` give full external
|
|
464
471
|
control, so a host can own the column-visibility UI.
|
|
@@ -542,7 +549,7 @@ still shadow-internal.
|
|
|
542
549
|
| `appendRows` | `(rows)` | Add rows without a full re-sort/rebuild — for streaming |
|
|
543
550
|
| `selectKeys` / `set selectedKeys` | `(keys)` | Replace the selection by row key |
|
|
544
551
|
| `tickleRow` | `(key)` | Move the row cursor and scroll it into view |
|
|
545
|
-
| `autoSizeColumn` | `(key)=>boolean` | Resize a column to fit its contents, animating the width. Returns `false` (no-op) for an unknown column, `resizable: false`, or a column
|
|
552
|
+
| `autoSizeColumn` | `(key)=>boolean` | Resize a column to fit its contents, animating the width. Returns `false` (no-op) for an unknown column, `resizable: false`, or a `renderer` column without `measure`/`fixedExtraWidth` — see [Auto-sizing a column](#auto-sizing-a-column). |
|
|
546
553
|
|
|
547
554
|
| Getter | Type | |
|
|
548
555
|
|---|---|---|
|
package/docs-user/dock.md
CHANGED
|
@@ -127,6 +127,22 @@ split resizes, and host resizes; handles are hidden during dock drags.
|
|
|
127
127
|
stored policy; `clearLeafPlacementPolicy(name)` resets. `getLeafPlacementPolicy(name)`
|
|
128
128
|
returns the resolved `{ allowKinds, denyKinds, allowEdgeSplit }`.
|
|
129
129
|
|
|
130
|
+
- Host `isolated` attribute: panels can be rearranged freely *inside* this
|
|
131
|
+
host but cannot be dragged **out** to another host. It is checked on the
|
|
132
|
+
**source** host only — it does not stop other hosts dropping panels *into*
|
|
133
|
+
an isolated host. To keep unrelated docks from exchanging panels in both
|
|
134
|
+
directions use `family` (below).
|
|
135
|
+
- Host `family` attribute (default `""`): two hosts exchange panels by drag
|
|
136
|
+
only when their families are equal. Give an inner dock its own family and
|
|
137
|
+
it neither receives outer-dock panels nor lets its own leave.
|
|
138
|
+
- Host `accepts-kinds` attribute / `acceptsKinds` property (space-separated
|
|
139
|
+
panel kinds; default unrestricted): panels arriving from **other** hosts, or
|
|
140
|
+
from another window via `queryDropTarget` / `acceptExternalPanel`, must be of
|
|
141
|
+
one of these kinds. Panels already in the host are unaffected. Combine with
|
|
142
|
+
`family` and `isolated` for a closed two-way exchange of one kind.
|
|
143
|
+
- A host whose `accepts` allows no splits (e.g. `accepts="tabs"`) treats the
|
|
144
|
+
whole leaf as the tabs drop zone, instead of leaving the edge bands inert.
|
|
145
|
+
|
|
130
146
|
A zone lights up only if every applicable rule allows it; disallowed zones
|
|
131
147
|
are inert. Content rules govern tabbing *into* a leaf (`tabs` drops,
|
|
132
148
|
`addPanel`, re-homing). Edge splits beside a leaf stay allowed **unless** that
|
|
@@ -138,11 +154,56 @@ propagated to it. Programmatic fallbacks (`addPanel` without a target,
|
|
|
138
154
|
external panels, leaf-close re-homing) use the first stack admitting the
|
|
139
155
|
panel's kind.
|
|
140
156
|
|
|
157
|
+
## Hiding the strip of a lone tab
|
|
158
|
+
|
|
159
|
+
`hide-single-tab-strip` (host attribute, `hideSingleTabStrip` property) drops
|
|
160
|
+
a leaf's tab strip while it holds exactly one panel; the strip appears when a
|
|
161
|
+
second panel arrives and goes again when one leaves. `DockStackNode.hideSingleTabStrip`
|
|
162
|
+
overrides it per stack (serialized with the layout). The leaf's outer box is
|
|
163
|
+
fixed by its split, so only the body shifts by one tab height when the strip
|
|
164
|
+
appears — the strip never reserves height while hidden.
|
|
165
|
+
|
|
166
|
+
While hidden:
|
|
167
|
+
|
|
168
|
+
- **Drops.** During a drag the host overlays a compact stand-in strip (part
|
|
169
|
+
`drop-hint`) on the leaf — only if that leaf would accept the dragged panel —
|
|
170
|
+
with a caret showing the insertion gap. It takes no layout space. Dropping on
|
|
171
|
+
it, or on the leaf centre, adds a tab; the real strip then appears.
|
|
172
|
+
- **Dragging the lone panel.** There is no tab to grab, so call
|
|
173
|
+
`host.beginPanelDrag(panelId, pointerEvent)` from your own handle's
|
|
174
|
+
`pointerdown`. It returns `false` for an unknown panel or non-primary press.
|
|
175
|
+
The drag starts after a few pixels of movement and is identical to a tab
|
|
176
|
+
drag (ghost, drop zones, `dock-panel-drag-*`, cross-host adoption,
|
|
177
|
+
tear-out). Prefer `touch-action: none` and `user-select: none` on the handle.
|
|
178
|
+
- **Toolbars.** Panel toolbars and `toolbar-<name>` slots live in the strip, so
|
|
179
|
+
they are not shown while it is hidden.
|
|
180
|
+
|
|
141
181
|
## Events
|
|
142
182
|
|
|
143
183
|
`ixfx-dock-host`: `dock-change` (`{ layout }` after structural mutations),
|
|
144
184
|
`dock-panel-added`, `dock-panel-removed`, `dock-panel-activated`,
|
|
145
|
-
`dock-panel-drag-start
|
|
185
|
+
`dock-panel-drag-start`, `dock-panel-moved`, `dock-stack-empty`,
|
|
186
|
+
`dock-tab-contextmenu`.
|
|
187
|
+
|
|
188
|
+
- `dock-panel-added` — `{ panelId, sourceHost, targetHost }`. `sourceHost` is
|
|
189
|
+
the host the panel came from (`null` when new or from another window).
|
|
190
|
+
- `dock-panel-removed` — `{ panelId, sourceHost, targetHost }`. `targetHost` is
|
|
191
|
+
the host it moved to, `null` when it is gone (closed, detached, torn out).
|
|
192
|
+
- `dock-panel-moved` — `{ panelId, sourceHost, targetHost }`, fired on the
|
|
193
|
+
target host once a cross-host drop completes. A move therefore fires
|
|
194
|
+
`removed` (source), `added` (target), then `moved` (target), and the source
|
|
195
|
+
now also emits `dock-change`.
|
|
196
|
+
- `dock-stack-empty` — `{ name, hostEmpty }` when a stack loses its last panel
|
|
197
|
+
(`name` is the container name or `null`). `hostEmpty` is true when the host
|
|
198
|
+
holds no panels at all — the cue to close an owning group. Fires before the
|
|
199
|
+
matching `dock-change`; not fired by `loadLayout()`.
|
|
200
|
+
- `dock-tab-contextmenu` — `{ panelId, clientX, clientY }`, cancelable
|
|
201
|
+
(`preventDefault()` suppresses the native menu). Visible tabs only; with a
|
|
202
|
+
hidden strip handle `contextmenu` on your own element.
|
|
203
|
+
|
|
204
|
+
All of these bubble and are composed, so a nested host's events also reach
|
|
205
|
+
outer hosts and their listeners — compare `targetHost` / `sourceHost` to the
|
|
206
|
+
host you care about. A nested host's drags are owned by the nearest host only.
|
|
146
207
|
|
|
147
208
|
Cross-window (see [Cross-window docking](#cross-window-docking-electron-etc)):
|
|
148
209
|
`dock-panel-drag-out` / `dock-panel-drag-in`
|
package/docs-user/index.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixfx/components",
|
|
3
|
-
"version": "0.15.
|
|
4
|
-
"generated": "2026-10-
|
|
3
|
+
"version": "0.15.5",
|
|
4
|
+
"generated": "2026-10-23T07:10:01.881Z",
|
|
5
5
|
"components": [
|
|
6
6
|
{
|
|
7
7
|
"name": "ac-text",
|
|
@@ -228,6 +228,11 @@
|
|
|
228
228
|
"summary": "A Lit web component that lays out any number of panels along one axis with draggable gutters between them.",
|
|
229
229
|
"path": "docs-user/split-layout.md"
|
|
230
230
|
},
|
|
231
|
+
{
|
|
232
|
+
"name": "sunburst-tree",
|
|
233
|
+
"summary": "`<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",
|
|
234
|
+
"path": "docs-user/sunburst-tree.md"
|
|
235
|
+
},
|
|
231
236
|
{
|
|
232
237
|
"name": "swipe",
|
|
233
238
|
"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.",
|
package/docs-user/llms.txt
CHANGED
|
@@ -56,6 +56,7 @@ import '@ixfx/components/data-grid';
|
|
|
56
56
|
- [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
57
|
- [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
58
|
- [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.
|
|
59
|
+
- [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
60
|
- [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
61
|
- [tabs](docs-user/tabs.md): A complete tabbed interface system using several coordinated components:
|
|
61
62
|
- [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.
|
|
@@ -0,0 +1,193 @@
|
|
|
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. [CSS variables and parts](#css-variables-and-parts)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Differences from `ixfx-tree-list`
|
|
25
|
+
|
|
26
|
+
- **Expand/collapse is reinterpreted as zoom.** `expand` fires on zoom-in, `collapse` on zoom-out.
|
|
27
|
+
- **`interactionMode` drops `'checked'`**; **`exclusivity` is accepted but ignored**.
|
|
28
|
+
- **`filterPredicate` dims** non-matching arcs instead of hiding them.
|
|
29
|
+
- **Reassigning `root` keeps zoom and selection** wherever the same key paths still exist (the icicle and treemap reset instead). See [Progressive data](#progressive-data).
|
|
30
|
+
- Drag-and-drop is out of scope.
|
|
31
|
+
|
|
32
|
+
## Data model
|
|
33
|
+
|
|
34
|
+
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).
|
|
35
|
+
|
|
36
|
+
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.
|
|
37
|
+
|
|
38
|
+
## Values and weighting
|
|
39
|
+
|
|
40
|
+
Every node — branches included — has a value. A child's arc is its share of its parent's:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
childAngle = parentAngle × child / max(parent, Σ siblings)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- Children summing to **less** than their parent leave an unfilled gap — "unaccounted for" space (unscanned disk, an unknown remainder).
|
|
47
|
+
- Children summing to **more** are scaled down to fit.
|
|
48
|
+
|
|
49
|
+
Give values as a plain number on `item.weight` (the default accessor reads it), or as a function:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
el.root = {
|
|
53
|
+
item: { key: 'hd', label: 'Disk', weight: 500e9 },
|
|
54
|
+
children: [
|
|
55
|
+
{ item: { key: 'apps', label: 'Applications', weight: 120e9 }, children: [] },
|
|
56
|
+
{ item: { key: 'users', label: 'Users', weight: 300e9 }, children: [] },
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Swap weighting scheme: no DOM is rebuilt, the chart animates to the new layout.
|
|
61
|
+
el.valueAccessor = (item, node) => (item.data as Stats).fileCount;
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`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:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
el.valueAccessor = (item, node) => node.children ? undefined : Math.log2(bytes(item) + 1);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`valueFormatter` (`(value, node) => string`) formats the value in the centre readout:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
el.valueFormatter = v => `${(v / 1e9).toFixed(1)} GB`;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Progressive data
|
|
77
|
+
|
|
78
|
+
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.
|
|
79
|
+
|
|
80
|
+
Either rebuild the tree immutably and reassign it:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
el.root = snapshotOfScanSoFar(); // zoom + selection carry over by key path
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
or mutate in place and nudge the element — or let a `TreeDataModel` notify it:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
folder.children.push(newFile);
|
|
90
|
+
el.requestUpdate();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Colour
|
|
94
|
+
|
|
95
|
+
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`.
|
|
96
|
+
|
|
97
|
+
All of it is computed in CSS from per-arc custom properties, so the palette is themeable:
|
|
98
|
+
|
|
99
|
+
| Per-arc property | Value |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `--arc-hue` | Degrees, added to `--sunbursttree-hue-start` |
|
|
102
|
+
| `--arc-depth` | Ring index from the centre (`0` = first ring) |
|
|
103
|
+
| `--arc-shade` | Sibling-position offset, `-0.5..0.5` |
|
|
104
|
+
| `--arc-centre` | `0..1`, how far the arc has become the centre disc |
|
|
105
|
+
|
|
106
|
+
## Properties
|
|
107
|
+
|
|
108
|
+
| Property (attribute) | Type | Default | Description |
|
|
109
|
+
|---|---|---|---|
|
|
110
|
+
| `root` | `TreeNode \| undefined` | `undefined` | Root node of the tree |
|
|
111
|
+
| `model` | `TreeDataModel \| undefined` | `undefined` | Shared data model; takes precedence over `loadChildren` |
|
|
112
|
+
| `loadChildren` | `LoadChildrenCallback \| undefined` | `undefined` | Callback for lazy child loading |
|
|
113
|
+
| `valueAccessor` | `SunburstValueAccessor` | `item => item.weight` | Node value. See [Values and weighting](#values-and-weighting) |
|
|
114
|
+
| `valueFormatter` | `SunburstValueFormatter` | locale number | Formats the centre readout's value |
|
|
115
|
+
| `interactionMode` (`interaction-mode`) | `'implicit' \| 'standard' \| 'manual'` | `'standard'` | Gesture mapping |
|
|
116
|
+
| `selectionFilter` (`selection-filter`) | `'none' \| 'leaf' \| 'branch' \| 'all'` | `'all'` | Which node kinds can be selected |
|
|
117
|
+
| `maxDepth` (`max-depth`) | `number` | `5` | Rings drawn around the centre |
|
|
118
|
+
| `centerRatio` (`center-ratio`) | `number` | `0.22` | Centre disc radius as a fraction of the overall radius |
|
|
119
|
+
| `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 |
|
|
120
|
+
| `disableLabels` (`disable-labels`) | `boolean` | `false` | Hide in-arc labels (the centre readout remains) |
|
|
121
|
+
| `curvedLabels` (`curved-labels`) | `boolean` | `false` | Curve labels along their ring instead of drawing them straight. See below |
|
|
122
|
+
| `animationDuration` (`animation-duration`) | `number` | `600` | Transition length in ms; `0` snaps. Respects `prefers-reduced-motion` |
|
|
123
|
+
| `filterPredicate` | `TreeFilterPredicate \| undefined` | `undefined` | Non-matching arcs (with no matching descendant) are dimmed |
|
|
124
|
+
| `disableKeyboardNavigation` (`disable-keyboard-navigation`) | `boolean` | `false` | Turn off keyboard handling |
|
|
125
|
+
| `searchModes` (`search-modes`) | `string \| undefined` | `undefined` | Subset of `navigate select filter` — see [`docs/infra-incremental.md`](../../docs/infra-incremental.md) |
|
|
126
|
+
| `exclusivity` | `TreeExclusivity` | `'none'` | Accepted for interface compatibility, ignored |
|
|
127
|
+
| `selectedNode` / `selectedNodes` | | | Same contract as `ixfx-tree-list` |
|
|
128
|
+
| `focusedNode` | `TreeNode \| undefined` (read-only) | `undefined` | Current zoom node; `undefined` when showing the full tree |
|
|
129
|
+
|
|
130
|
+
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.
|
|
131
|
+
|
|
132
|
+
## Zoom, selection, navigation
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
el.zoomTo(node); // node becomes the centre
|
|
136
|
+
el.zoomUp(); // centre's parent becomes the centre
|
|
137
|
+
el.zoomOut(); // back to the full tree
|
|
138
|
+
|
|
139
|
+
el.select(node); el.deselect(node); el.clearSelection(); el.selectAll(); el.deselectAll();
|
|
140
|
+
|
|
141
|
+
// Zooms so the target sits in the first ring (its parent at the centre), then selects it.
|
|
142
|
+
el.navigateTo(['users', 'me', 'photos']);
|
|
143
|
+
el.navigateToNode(n => n.item.key === 'photos');
|
|
144
|
+
|
|
145
|
+
el.getNodes(); // visible arcs (centre excluded), ring-major
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Events
|
|
149
|
+
|
|
150
|
+
All events **bubble** and are **composed**. `depth` counts from the root's children (`0`).
|
|
151
|
+
|
|
152
|
+
| Event | Detail | When |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| `zoom` | `SunburstZoomDetail` — `{ node: TreeNode \| undefined; depth }` | Zoom node changes (`node` undefined = full tree) |
|
|
155
|
+
| `expand` / `collapse` | `{ node; depth }` | Zoomed into a descendant / out of the previous centre |
|
|
156
|
+
| `select` | `TreeSelectDetail` | Selection changes |
|
|
157
|
+
| `tickle` | `TreeTickleDetail` | Pointer or keyboard cursor enters an arc |
|
|
158
|
+
| `activate` | `TreeActivateDetail` | Enter or double-click |
|
|
159
|
+
| `item-click` / `item-dblclick` | `{ node; depth }` | Raw pointer clicks on an arc |
|
|
160
|
+
|
|
161
|
+
## Keyboard / pointer interaction
|
|
162
|
+
|
|
163
|
+
| Input | Action |
|
|
164
|
+
|---|---|
|
|
165
|
+
| Click an arc | Select (per `interactionMode`) and zoom in, if it has children |
|
|
166
|
+
| Ctrl/⌘-click, Shift-click | Toggle / range-select (`standard` mode), without zooming |
|
|
167
|
+
| Click the centre | Zoom up one level |
|
|
168
|
+
| `←` / `→` | Previous / next sibling (wraps) |
|
|
169
|
+
| `↑` / `↓` | Parent (inward) / first child (outward) |
|
|
170
|
+
| `Home` / `End` | First / last visible arc |
|
|
171
|
+
| `Enter` | Select, activate and zoom in |
|
|
172
|
+
| `Escape` / `Backspace` | Zoom up one level |
|
|
173
|
+
|
|
174
|
+
## CSS variables and parts
|
|
175
|
+
|
|
176
|
+
| Variable | Default | Description |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `--sunbursttree-hue-start` | `250` | Hue at 12 o'clock |
|
|
179
|
+
| `--sunbursttree-chroma` | `0.14` | First-ring chroma |
|
|
180
|
+
| `--sunbursttree-chroma-step` | `0.015` | Chroma lost per ring outward |
|
|
181
|
+
| `--sunbursttree-lightness` | `60%` | First-ring lightness |
|
|
182
|
+
| `--sunbursttree-lightness-step` | `5%` | Lightness gained per ring outward |
|
|
183
|
+
| `--sunbursttree-shade-step` | `10%` | Lightness spread across siblings |
|
|
184
|
+
| `--sunbursttree-center-color` | `var(--surface-4)` | Centre disc fill |
|
|
185
|
+
| `--sunbursttree-center-text` | `var(--surface-4-text)` | Centre readout text |
|
|
186
|
+
| `--sunbursttree-gap-color` | `var(--surface-2)` | Stroke between arcs — match it to the background |
|
|
187
|
+
| `--sunbursttree-gap` | `1px` | Width of that stroke |
|
|
188
|
+
| `--sunbursttree-font-size` | `11px` | Label size (px; read for label fitting) |
|
|
189
|
+
| `--sunbursttree-label-lightness` | `22%` | Label lightness (hue follows the arc) |
|
|
190
|
+
|
|
191
|
+
Parts: `arc`, `center`, `label`, `center-readout`.
|
|
192
|
+
|
|
193
|
+
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
|
@@ -37,7 +37,7 @@ type TreeItem = {
|
|
|
37
37
|
icon?: string; // Icon name (passed to <ixfx-icon>)
|
|
38
38
|
tooltip?: string; // Tooltip content
|
|
39
39
|
value?: string; // Optional machine-readable value
|
|
40
|
-
weight?: number; // Relative importance/magnitude;
|
|
40
|
+
weight?: number; // Relative importance/magnitude; used by ixfx-hyperbolictree-list and ixfx-sunbursttree-list
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
type TreeNode = {
|
|
@@ -153,6 +153,7 @@ These properties are present on all three components (`ixfx-tree-list`, `ixfx-mi
|
|
|
153
153
|
| `stickyHeaders` (`sticky-headers`) | `boolean` | `true` | VS Code-style sticky headers; set `sticky-headers="false"` to opt out (`ixfx-tree-list` only) |
|
|
154
154
|
| `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
155
|
| `virtualizeThreshold` (`virtualize-threshold`) | `number` | `200` | Visible-row count above which `virtualize="auto"` windows the list |
|
|
156
|
+
| `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` |
|
|
156
157
|
|
|
157
158
|
### Replacing `root`
|
|
158
159
|
|
|
@@ -280,6 +281,44 @@ On by default: while scrolling vertically, the ancestors of the top-visible row
|
|
|
280
281
|
- An ancestor that is itself still visible is never duplicated in the header.
|
|
281
282
|
- Style via `--tree-sticky-bg`, `--tree-sticky-border`, `--tree-sticky-shadow`, and the `sticky-headers` / `sticky-header` parts.
|
|
282
283
|
|
|
284
|
+
### Animation control
|
|
285
|
+
|
|
286
|
+
Row enter/leave animations are controlled by the `animation` property:
|
|
287
|
+
|
|
288
|
+
| Value | Behaviour |
|
|
289
|
+
|-------|-----------|
|
|
290
|
+
| `'auto'` (default) | Animate normally, respecting `prefers-reduced-motion` and the `MAX_ANIMATED_ROWS` (50) threshold |
|
|
291
|
+
| `'always'` | Always animate, even when many rows change at once |
|
|
292
|
+
| `'never'` | Skip all row enter/leave animations |
|
|
293
|
+
|
|
294
|
+
```html
|
|
295
|
+
<ixfx-tree-list animation="never"></ixfx-tree-list>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Per-call override**: Methods that change the tree structure accept an optional `animate` parameter to override the property for that single call:
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
// Expand with animation (default)
|
|
302
|
+
tree.expandAll();
|
|
303
|
+
|
|
304
|
+
// Expand without animation
|
|
305
|
+
tree.expandAll(undefined, false);
|
|
306
|
+
|
|
307
|
+
// Collapse without animation
|
|
308
|
+
tree.collapseAll(0, false);
|
|
309
|
+
|
|
310
|
+
// Navigate with animation
|
|
311
|
+
tree.navigateTo(['root', 'child']);
|
|
312
|
+
|
|
313
|
+
// Navigate without animation
|
|
314
|
+
tree.navigateTo(['root', 'child'], { animate: false });
|
|
315
|
+
|
|
316
|
+
// Reveal without animation
|
|
317
|
+
tree.revealKey('some-key', false);
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
This is useful when populating a tree initially or when performance matters more than visual polish.
|
|
321
|
+
|
|
283
322
|
### Virtualisation (`ixfx-tree-list`)
|
|
284
323
|
|
|
285
324
|
A node with 10,000 children needs only about 25 `<li>` elements in the DOM. When
|
package/llms.txt
CHANGED
|
@@ -56,6 +56,7 @@ import '@ixfx/components/data-grid';
|
|
|
56
56
|
- [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
57
|
- [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
58
|
- [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.
|
|
59
|
+
- [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
60
|
- [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
61
|
- [tabs](docs-user/tabs.md): A complete tabbed interface system using several coordinated components:
|
|
61
62
|
- [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.
|