@ixfx/components 0.13.1 → 0.13.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +100 -14
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +2211 -636
- package/bundle/index.js.map +1 -1
- package/dist/ac-token.js +1 -1
- package/dist/{data-grid-Ck1Qx2H1.d.ts → data-grid-DHWJN66w.d.ts} +7 -5
- package/dist/{data-grid-Ck1Qx2H1.d.ts.map → data-grid-DHWJN66w.d.ts.map} +1 -1
- package/dist/data-grid.d.ts +1 -1
- package/dist/data-grid.js +210 -120
- package/dist/data-grid.js.map +1 -1
- package/dist/detail-list-C96B5Txz.js +2001 -0
- package/dist/detail-list-C96B5Txz.js.map +1 -0
- package/dist/{detail-list-C1xzr1z7.d.ts → detail-list-dX7jLO6b.d.ts} +12 -3
- package/dist/{detail-list-C1xzr1z7.d.ts.map → detail-list-dX7jLO6b.d.ts.map} +1 -1
- package/dist/detail-list.d.ts +2 -2
- package/dist/detail-list.js +1 -1680
- package/dist/{flat-list-DEDG6epz.d.ts → flat-list-Y98IqH00.d.ts} +5 -2
- package/dist/flat-list-Y98IqH00.d.ts.map +1 -0
- package/dist/flat-list.d.ts +1 -1
- package/dist/flat-list.js +33 -1
- package/dist/flat-list.js.map +1 -1
- package/dist/{grid-list-pefLORIr.d.ts → grid-list-CoT9e1jB.d.ts} +9 -2
- package/dist/{grid-list-pefLORIr.d.ts.map → grid-list-CoT9e1jB.d.ts.map} +1 -1
- package/dist/{grid-list-DjIl910A.js → grid-list-DeqAd9-h.js} +189 -40
- package/dist/grid-list-DeqAd9-h.js.map +1 -0
- package/dist/grid-list.d.ts +1 -1
- package/dist/grid-list.js +1 -1
- package/dist/{incr-search-D91M4Ozq.js → incr-search-JIhwB49y.js} +27 -5
- package/dist/incr-search-JIhwB49y.js.map +1 -0
- package/dist/incr-search.d.ts +1 -1
- package/dist/incr-search.js +1 -1
- package/dist/index-CnQPCywE.d.ts +325 -0
- package/dist/index-CnQPCywE.d.ts.map +1 -0
- package/dist/{index-CxZ61DO1.d.ts → index-Dlah7Zfi.d.ts} +8 -1
- package/dist/{index-CxZ61DO1.d.ts.map → index-Dlah7Zfi.d.ts.map} +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -25
- package/dist/index.js.map +1 -1
- package/dist/miller.d.ts +1 -1
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +146 -100
- package/dist/miller.js.map +1 -1
- package/dist/narrowed-text.js +1 -1
- package/dist/split-layout-C5SYbDrq.d.ts.map +1 -1
- package/dist/{split-layout-CXotkdbx.js → split-layout-Deoxy47d.js} +6 -1
- package/dist/{split-layout-CXotkdbx.js.map → split-layout-Deoxy47d.js.map} +1 -1
- package/dist/split-layout.js +1 -1
- package/dist/{tab-list-v8mKX7Fu.d.ts → tab-list-D_dmImJM.d.ts} +2 -3
- package/dist/tab-list-D_dmImJM.d.ts.map +1 -0
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +22 -0
- package/dist/tabs.js.map +1 -1
- package/dist/{tree-DGveys4K.js → tree-DD8OaqsK.js} +1010 -230
- package/dist/tree-DD8OaqsK.js.map +1 -0
- package/dist/tree.d.ts +4 -267
- package/dist/tree.js +1 -1
- package/dist/{vertical-list-CqBc-t8w.d.ts → vertical-list-lj_19DCx.d.ts} +3 -2
- package/dist/{vertical-list-CqBc-t8w.d.ts.map → vertical-list-lj_19DCx.d.ts.map} +1 -1
- package/dist/vertical-list.d.ts +1 -1
- package/dist/vertical-list.js +113 -24
- package/dist/vertical-list.js.map +1 -1
- package/docs-user/data-grid.md +74 -4
- package/docs-user/detail-list.md +65 -0
- package/docs-user/flat-list.md +14 -2
- package/docs-user/grid-list.md +81 -4
- package/docs-user/index.json +2 -2
- package/docs-user/miller.md +59 -3
- package/docs-user/tree.md +63 -2
- package/docs-user/vertical-list.md +9 -1
- package/package.json +6 -1
- package/dist/detail-list.js.map +0 -1
- package/dist/flat-list-DEDG6epz.d.ts.map +0 -1
- package/dist/grid-list-DjIl910A.js.map +0 -1
- package/dist/incr-search-D91M4Ozq.js.map +0 -1
- package/dist/tab-list-v8mKX7Fu.d.ts.map +0 -1
- package/dist/tree-DGveys4K.js.map +0 -1
- package/dist/tree.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-DD8OaqsK.js","names":["clamp","#root","#loadChildren","#cache","#notify","#subscribers","#host","#config","#active","#current","#bind","#boundContainer","#unbind","#onDragEnter","#onDragOver","#onDragLeave","#onDrop","#clearExpand","#stopScroll","#pointerX","#pointerY","#reject","#source","#dragKeys","#dragNodes","#handleExpandHover","#rowAtPointer","#kickScroll","#resolveIntent","#setDropState","#endHover","#expandPendingKey","#expandTimer","#scrollRaf","#scrollTick","#virtualScrollRaf","#syncWindowToScroll","#getFlat","#drop","#nativeDrag","#rowsCache","#stickyRaf","#updateStickyHeaders","#getFocusedIndex","#navigateToIndex","#pageSize","#toggleExpand","#setFocusedIndex","#setExpanded","#toggleSelection","#abortPending","#flat","#stickyDirty","#structureVersion","#flatRoot","#flatFilter","#getFilter","#treeIndexCache","#metrics","#viewportH","#getItemHeight","#container","#layoutParams","#virtualActive","#winStart","#winEnd","#virtualScrollContainer","#onVirtualScroll","#resizeObserver","#filterCache","#getTreeIndex","#ownedRegistry","#effectiveSearchModes","#unregisterSearchCommands","#stickyScrollBound","#stickyScrollContainer","#onStickyScroll","#setStickyKeys","#renderedRowKeys","#rowReader","#renderedRowIndex","#stickyEntries","#renderStickyHeader","#onStickyClick","#activateSticky","#canSelect","#scrollKeyIntoView","#dropState","#nativeDragKeys","#leavingAnimations","#scrollOnlyUpdate","#syncScrollTopFromContainer","#diffVisibleNodes","#measureMetrics","#enteringKeys","#cancelAllLeavingAnimations","#leaving","#renderedKeys","#treeAnimReady","#lastNodeByKey","#cancelLeavingAnimation","#syncVirtualObservers","#repaintSearchHighlights","#syncStickyScroll","#clearSelectionInternal","#modelUnsubscribe","#anchor","#runItemAnimations","#syncSearchCommands","#initDnd","#dragSourceId","#anyRowDraggable","#internalDropHandled","#postDragSuppressTimer","#getVisibleRows","#childrenOfKey","#getIndentPx","#isSelfOrDescendant","#findParentByKey","#resolveDrag","#springLoadExpand","#onContainerScroll","#collectVirtualDropRows","#nodeByKey","#teardownVirtualObservers","#config","#dispatchSelect","#applyCheckedToggle","#applyExclusivity","#findNodePath","#pendingNode","#handleImplicitClick","#handleStandardClick","#handleManualClick","#handleExpandOnly","#clickedOnCaret","#getFlatIndexOf","#allDescendantsSelected","#pendingController","#invokeLoadChildren","#revealIndex","#revealToken","#revealRowElement","#collapseSiblingsAtDepth","#findAncestorKeys","#findParent","#scrollTickledIntoView","#extendRangeSelection","#onKeyDown","#onDblClick","#renderStickyHeaders","#renderNodes","#renderWindow","#currentWindow","customElement","#syncCheckboxStates","#checkboxCache","#renderCheckbox","customElement","#root","#element","#options","#connectSignal","#childrenOf","#nodeToTree","#findTreePath","#toTreeNode","#identityToTreeNode"],"sources":["../src/common/tree-drop-apply.ts","../src/common/tree-data-model.ts","../src/tree/tree-drag-registry.ts","../src/tree/tree-drop-controller.ts","../src/tree/tree-flat.ts","../src/tree/tree-layout.ts","../src/tree/tree-row-geometry.ts","../src/tree/tree-base.ts","../src/tree/tree-list.ts","../src/tree/tree-controller.ts"],"sourcesContent":["import type { TreeDropApplyContext, TreeDropPosition, TreeDropTarget } from './tree-component.js';\nimport type { TreeNode } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Pure helpers (functional; never mutate the input root)\n// ---------------------------------------------------------------------------\n\nfunction findNode(root: TreeNode, key: string): TreeNode | undefined {\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const found = findNode(child, key);\n if (found)\n return found;\n }\n return undefined;\n}\n\nfunction findParent(root: TreeNode, key: string, parent: TreeNode | undefined = undefined): TreeNode | undefined {\n for (const child of root.children ?? []) {\n if (child.item.key === key)\n return parent === undefined ? root : parent;\n const found = findParent(child, key, child);\n if (found)\n return found;\n }\n return undefined;\n}\n\n/** True when `key` is `ancestorKey`, or a descendant of it. */\nfunction isSelfOrDescendant(root: TreeNode, ancestorKey: string, key: string): boolean {\n const ancestor = findNode(root, ancestorKey);\n return ancestor !== undefined && findNode(ancestor, key) !== undefined;\n}\n\n/** Remove every node whose key is in `keys` (with its whole subtree), in one pass. */\nfunction removeKeys(node: TreeNode, keys: ReadonlySet<string>): TreeNode {\n if (!node.children)\n return node;\n return {\n ...node,\n children: node.children\n .filter(c => !keys.has(c.item.key))\n .map(c => removeKeys(c, keys)),\n };\n}\n\nfunction childrenOf(root: TreeNode, parentKey: string | undefined): readonly TreeNode[] {\n if (parentKey === undefined)\n return root.children ?? [];\n return findNode(root, parentKey)?.children ?? [];\n}\n\n/** Return a new root with `parentKey`'s children replaced (root itself when `parentKey` is undefined). */\nfunction withChildren(node: TreeNode, parentKey: string | undefined, children: TreeNode[]): TreeNode {\n if (parentKey === undefined)\n return { ...node, children };\n if (node.item.key === parentKey)\n return { ...node, children };\n if (!node.children)\n return node;\n return { ...node, children: node.children.map(c => withChildren(c, parentKey, children)) };\n}\n\nfunction clamp(n: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, n));\n}\n\n/**\n * Drop keys whose ancestor is also being dragged — only the top-most selected\n * nodes move; their subtrees travel with them. Preserves input order.\n */\nexport function pruneDraggedDescendants(root: TreeNode, keys: readonly string[]): string[] {\n const set = new Set(keys);\n return keys.filter((key) => {\n let parent = findParent(root, key);\n while (parent) {\n if (set.has(parent.item.key))\n return false;\n parent = findParent(root, parent.item.key);\n }\n return true;\n });\n}\n\n// ---------------------------------------------------------------------------\n// applyTreeDrop\n// ---------------------------------------------------------------------------\n\n/**\n * Framework-agnostic drop application. Given the current immutable `root` and a\n * resolved drop context, returns a **new** root with the drop applied, or the\n * unchanged `root` when the drop is invalid (dragged node into its own subtree,\n * missing reference, empty payload). Never throws, never mutates.\n *\n * The insertion point is re-derived from `target.referenceKey` + `target.position`\n * against the post-removal tree, so same-parent reorders are off-by-one-safe and\n * multi-node drops land as siblings in drag order. `target.index` is honoured only\n * for `position: 'inside'` (0 = first child, large = append).\n */\nexport function applyTreeDrop(root: TreeNode, ctx: TreeDropApplyContext): TreeNode {\n const { target, source } = ctx;\n\n let nodes: TreeNode[];\n let removeSet: ReadonlySet<string> = new Set();\n\n if (source === `internal`) {\n const keys = pruneDraggedDescendants(root, [...ctx.draggedKeys]);\n if (keys.length === 0)\n return root;\n\n // Reject dropping a node into itself or its own subtree.\n if (target.parentKey !== undefined) {\n for (const key of keys) {\n if (isSelfOrDescendant(root, key, target.parentKey))\n return root;\n }\n }\n // For before/after, the reference must not be inside a dragged subtree.\n if (target.position !== `inside`) {\n for (const key of keys) {\n if (isSelfOrDescendant(root, key, target.referenceKey))\n return root;\n }\n }\n\n const resolved = keys.map(k => findNode(root, k));\n if (resolved.includes(undefined))\n return root;\n nodes = resolved as TreeNode[];\n removeSet = new Set(keys);\n } else {\n nodes = (ctx.dragged ?? []).map(n => ({ ...n }));\n if (nodes.length === 0)\n return root;\n }\n\n const afterRemoval = removeSet.size > 0 ? removeKeys(root, removeSet) : root;\n\n let parentKey: string | undefined;\n let index: number;\n\n if (target.position === `inside`) {\n if (findNode(afterRemoval, target.referenceKey) === undefined)\n return root;\n parentKey = target.referenceKey;\n const kids = childrenOf(afterRemoval, parentKey);\n index = clamp(target.index, 0, kids.length);\n } else {\n const parent = findParent(afterRemoval, target.referenceKey);\n parentKey = parent?.item.key;\n const kids = childrenOf(afterRemoval, parentKey);\n const refIdx = kids.findIndex(c => c.item.key === target.referenceKey);\n if (refIdx < 0)\n return root;\n index = (target.position as TreeDropPosition) === `before` ? refIdx : refIdx + 1;\n }\n\n const kids = [...childrenOf(afterRemoval, parentKey)];\n const next = [...kids.slice(0, index), ...nodes, ...kids.slice(index)];\n return withChildren(afterRemoval, parentKey, next);\n}\n\n/** Build a synthetic `TreeDropTarget` for programmatic moves (see `TreeDataModel`). */\nexport function dropTargetFor(\n referenceKey: string,\n position: TreeDropPosition,\n index = position === `inside` ? Number.MAX_SAFE_INTEGER : 0,\n): TreeDropTarget {\n return {\n referenceKey,\n position,\n index,\n parentKey: position === `inside` ? referenceKey : undefined,\n depth: 0,\n };\n}\n","import type { TreeDropApplyContext } from './tree-component.js';\nimport type { LoadChildrenCallback, TreeItem, TreeNode } from './types.js';\nimport { collectDataResult } from './data-provider.js';\nimport { applyTreeDrop, dropTargetFor } from './tree-drop-apply.js';\n\n// ---------------------------------------------------------------------------\n// Subscription event types (internal — not part of the public API)\n// ---------------------------------------------------------------------------\n\ntype InvalidateEvent = { type: `invalidate`; key: string };\ntype RootEvent = { type: `root`; root: TreeNode };\ntype ModelEvent = InvalidateEvent | RootEvent;\n\ntype ModelSubscriber = (event: ModelEvent) => void;\n\n// ---------------------------------------------------------------------------\n// Pure tree-mutation helpers (functional, produce new roots)\n// ---------------------------------------------------------------------------\n\n// function cloneNode(node: TreeNode): TreeNode {\n// if (node.children === undefined)\n// return { item: { ...node.item } };\n// return { item: { ...node.item }, children: node.children.map(cloneNode) };\n// }\n\n/** Return a new root with the node at `key` replaced by `replacer(node)`. */\nfunction mapNode(root: TreeNode, key: string, replacer: (n: TreeNode) => TreeNode): TreeNode {\n if (root.item.key === key)\n return replacer(root);\n if (!root.children)\n return root;\n return { item: root.item, children: root.children.map(c => mapNode(c, key, replacer)) };\n}\n\n/** Return a new root with `newChild` appended to the children of the node at `parentKey`. */\nfunction addChildTo(root: TreeNode, parentKey: string, newChild: TreeNode): TreeNode {\n return mapNode(root, parentKey, parent => ({\n item: parent.item,\n children: [...(parent.children ?? []), newChild],\n }));\n}\n\n/** Return a new root with the node at `key` removed (along with all its descendants). */\nfunction removeNodeFrom(root: TreeNode, key: string): TreeNode {\n if (!root.children)\n return root;\n return {\n item: root.item,\n children: root.children\n .filter(c => c.item.key !== key)\n .map(c => removeNodeFrom(c, key)),\n };\n}\n\n/** Return a new root with `newChild` inserted at `index` among the children of `parentKey`. */\nfunction insertChildAt(root: TreeNode, parentKey: string, newChild: TreeNode, index: number): TreeNode {\n return mapNode(root, parentKey, (parent) => {\n const children = parent.children ?? [];\n const clampedIndex = Math.max(0, Math.min(index, children.length));\n return {\n item: parent.item,\n children: [...children.slice(0, clampedIndex), newChild, ...children.slice(clampedIndex)],\n };\n });\n}\n\nfunction getRootChildren(root: TreeNode): TreeNode[] {\n return root.children ?? [];\n}\n\n// ---------------------------------------------------------------------------\n// TreeDataModelOptions\n// ---------------------------------------------------------------------------\n\nexport type TreeDataModelOptions = {\n /** The initial root node. Required. */\n root: TreeNode;\n /**\n * Optional callback for lazily loading children.\n * If omitted, nodes with `children === undefined` are treated as empty branches.\n */\n loadChildren?: LoadChildrenCallback;\n};\n\n// ---------------------------------------------------------------------------\n// TreeDataModel\n// ---------------------------------------------------------------------------\n\n/**\n * Manages tree data for tree-like components.\n *\n * Handles two concerns:\n * 1. **Lazy loading** — caches children fetched via `loadChildren` and can invalidate\n * specific branches so they are re-fetched on next expand.\n * 2. **Structural mutations** — convenience methods to add, remove, update, or move\n * nodes. Each mutation produces a new immutable root and notifies connected components.\n *\n * Assign an instance to a component's `model` property instead of setting `root`/`loadChildren`\n * directly. The same model instance can be shared across multiple components.\n *\n * @example\n * ```typescript\n * const model = new TreeDataModel({\n * root: { item: { key: 'root', label: 'Root' }, children: [] },\n * loadChildren: async (node, depth, signal) => fetchChildren(node.item.key),\n * });\n * myTreeList.model = model;\n * myMillerList.model = model;\n *\n * // Later — invalidate a branch to force a re-fetch on next expand:\n * model.invalidate('some-key');\n * ```\n */\nexport class TreeDataModel {\n #root: TreeNode;\n #loadChildren: LoadChildrenCallback | undefined;\n #cache = new Map<string, TreeNode[]>();\n #subscribers = new Set<ModelSubscriber>();\n\n constructor(options: TreeDataModelOptions) {\n this.#root = options.root;\n this.#loadChildren = options.loadChildren;\n }\n\n // ---------------------------------------------------------------------------\n // Root\n // ---------------------------------------------------------------------------\n\n /** The current immutable root snapshot. */\n get root(): TreeNode {\n return this.#root;\n }\n\n /**\n * Replace the entire root with a new immutable snapshot.\n * All cached children are cleared. Connected components re-render.\n */\n setRoot(root: TreeNode): void {\n this.#root = root;\n this.#cache.clear();\n this.#notify({ type: `root`, root });\n }\n\n // ---------------------------------------------------------------------------\n // Child loading\n // ---------------------------------------------------------------------------\n\n /**\n * Returns children for the given node.\n * If children are cached, they are returned immediately (as a resolved Promise).\n * Otherwise the `loadChildren` callback is invoked and the result is cached.\n * If no `loadChildren` is set and no cache entry exists, returns `[]`.\n *\n * Called by components internally — not typically called by application code.\n */\n async getChildren(node: TreeNode, depth: number, signal: AbortSignal): Promise<TreeNode[]> {\n const key = node.item.key;\n if (this.#cache.has(key)) {\n return this.#cache.get(key)!;\n }\n if (!this.#loadChildren) {\n return [];\n }\n const items = await collectDataResult(this.#loadChildren({ node, depth }, signal), signal);\n const children = [...items] as TreeNode[];\n if (!signal.aborted) {\n this.#cache.set(key, children);\n }\n return children;\n }\n\n // ---------------------------------------------------------------------------\n // Cache invalidation\n // ---------------------------------------------------------------------------\n\n /**\n * Clears the cached children for the node with the given key.\n * Connected components will collapse that node (if currently expanded), so that\n * the next expand triggers a fresh `loadChildren` call.\n */\n invalidate(key: string): void {\n this.#cache.delete(key);\n this.#notify({ type: `invalidate`, key });\n }\n\n // ---------------------------------------------------------------------------\n // Convenience mutators\n // ---------------------------------------------------------------------------\n\n /**\n * Adds `node` as a child of the node identified by `parentKey`.\n * Returns the new root (connected components are notified automatically).\n */\n addNode(parentKey: string, node: TreeNode): TreeNode {\n this.#root = addChildTo(this.#root, parentKey, node);\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n /**\n * Removes the node with the given key and all its descendants.\n * Returns the new root (connected components are notified automatically).\n */\n removeNode(key: string): TreeNode {\n this.#cache.delete(key);\n this.#root = removeNodeFrom(this.#root, key);\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n /**\n * Applies a partial update to the `item` of the node with the given key.\n * Returns the new root (connected components are notified automatically).\n */\n updateItem(key: string, patch: Partial<TreeItem>): TreeNode {\n this.#root = mapNode(this.#root, key, n => ({\n item: { ...n.item, ...patch },\n children: n.children,\n }));\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n /**\n * Moves the node with the given key to become a child of `newParentKey`.\n * When `index` is provided, inserts at that position; otherwise appends.\n * Returns the new root (connected components are notified automatically).\n */\n moveNode(key: string, newParentKey: string, index?: number): TreeNode {\n const next = applyTreeDrop(this.#root, {\n source: `internal`,\n draggedKeys: [key],\n target: dropTargetFor(newParentKey, `inside`, index ?? Number.MAX_SAFE_INTEGER),\n });\n if (next !== this.#root) {\n this.#root = next;\n this.#notify({ type: `root`, root: this.#root });\n }\n return this.#root;\n }\n\n /**\n * Moves the node with the given key to become a sibling of `referenceKey`,\n * positioned `before` or `after` it. A no-op (returns the unchanged root) when\n * `key` is `referenceKey`, an ancestor of it, or either is missing.\n * Returns the new root (connected components are notified automatically).\n */\n moveNodeRelative(key: string, referenceKey: string, position: `before` | `after`): TreeNode {\n const next = applyTreeDrop(this.#root, {\n source: `internal`,\n draggedKeys: [key],\n target: dropTargetFor(referenceKey, position),\n });\n if (next !== this.#root) {\n this.#root = next;\n this.#notify({ type: `root`, root: this.#root });\n }\n return this.#root;\n }\n\n /**\n * Applies a resolved drop (from `ixfx-tree-list`'s `tree-drop` event or a\n * hand-built context) to the current root. No-op when the drop is invalid.\n * Returns the new root (connected components are notified automatically).\n */\n applyDrop(ctx: TreeDropApplyContext): TreeNode {\n const next = applyTreeDrop(this.#root, ctx);\n if (next !== this.#root) {\n this.#root = next;\n this.#notify({ type: `root`, root: this.#root });\n }\n return this.#root;\n }\n\n /**\n * Inserts `node` as a child of `parentKey` (or at the root level when `parentKey` is undefined).\n * When `index` is provided, inserts at that position; otherwise appends.\n * Returns the new root (connected components are notified automatically).\n */\n insertNode(parentKey: string | undefined, node: TreeNode, index?: number): TreeNode {\n if (parentKey === undefined) {\n const children = getRootChildren(this.#root);\n const clampedIndex = Math.max(0, Math.min(index ?? children.length, children.length));\n this.#root = {\n ...this.#root,\n children: [...children.slice(0, clampedIndex), node, ...children.slice(clampedIndex)],\n };\n } else {\n if (index !== undefined) {\n this.#root = insertChildAt(this.#root, parentKey, node, index);\n } else {\n this.#root = addChildTo(this.#root, parentKey, node);\n }\n }\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n // ---------------------------------------------------------------------------\n // Internal subscription (used by components — not part of the public API)\n // ---------------------------------------------------------------------------\n\n /**\n * Subscribe to model events. Returns an unsubscribe function.\n * Components call this when the `model` property is set, and unsubscribe when it is unset.\n *\n * @internal\n */\n _subscribe(callback: ModelSubscriber): () => void {\n this.#subscribers.add(callback);\n return () => this.#subscribers.delete(callback);\n }\n\n #notify(event: ModelEvent): void {\n for (const sub of this.#subscribers) {\n sub(event);\n }\n }\n}\n","import type { TreeNode } from '../common/types.js';\n\nconst TREE_DRAG_MIME = `application/x-ixfx-tree`;\n\ninterface TreeDragEntry {\n readonly sourceId: string;\n readonly nodes: TreeNode[];\n readonly keys: string[];\n}\n\nconst registry = new Map<string, TreeDragEntry>();\nconst weakRefs = new Map<string, WeakRef<HTMLElement>>();\n\n/**\n * The source id of the drag currently in flight, if any. There is only ever one\n * native drag at a time, so a drop target can resolve the dragged nodes during\n * `dragover` — when `DataTransfer.getData()` is unreadable (protected mode) — by\n * looking this up in the registry.\n */\nlet currentSourceId: string | undefined;\n\nlet sourceIdCounter = 0;\n\nexport function treeDragGenerateSourceId(): string {\n return `tree-drag-${++sourceIdCounter}-${Date.now()}`;\n}\n\nexport function treeDragRegister(\n sourceId: string,\n element: HTMLElement,\n nodes: TreeNode[],\n keys: string[],\n): void {\n registry.set(sourceId, { sourceId, nodes, keys });\n weakRefs.set(sourceId, new WeakRef(element));\n currentSourceId = sourceId;\n}\n\nexport function treeDragUnregister(sourceId: string): void {\n registry.delete(sourceId);\n weakRefs.delete(sourceId);\n if (currentSourceId === sourceId)\n currentSourceId = undefined;\n}\n\n/** The in-flight drag's `{ keys, nodes, element }`, or `undefined` when nothing is dragging. */\nexport function treeDragCurrent(): { sourceId: string; keys: string[]; nodes: TreeNode[]; element: HTMLElement | undefined } | undefined {\n if (currentSourceId === undefined)\n return undefined;\n const entry = registry.get(currentSourceId);\n if (!entry)\n return undefined;\n return { sourceId: currentSourceId, keys: entry.keys, nodes: entry.nodes, element: weakRefs.get(currentSourceId)?.deref() };\n}\n\nexport function treeDragGetNodes(sourceId: string): TreeNode[] | undefined {\n return registry.get(sourceId)?.nodes;\n}\n\nexport function treeDragGetKeys(sourceId: string): string[] | undefined {\n return registry.get(sourceId)?.keys;\n}\n\nexport function treeDragGetElement(sourceId: string): HTMLElement | undefined {\n const ref = weakRefs.get(sourceId);\n return ref?.deref();\n}\n\nexport function treeDragParsePayload(dataTransfer: DataTransfer): {\n sourceId: string;\n keys: string[];\n nodes: TreeNode[];\n} | undefined {\n try {\n const raw = dataTransfer.getData(TREE_DRAG_MIME);\n if (!raw)\n return undefined;\n const payload = JSON.parse(raw) as { sourceId: string; keys: string[]; nodes: TreeNode[] };\n return payload;\n } catch {\n return undefined;\n }\n}\n\nexport function treeDragWritePayload(\n dataTransfer: DataTransfer,\n sourceId: string,\n keys: string[],\n nodes: TreeNode[],\n labelText: string,\n): void {\n const payload = JSON.stringify({ sourceId, keys, nodes });\n dataTransfer.setData(TREE_DRAG_MIME, payload);\n dataTransfer.setData(`text/plain`, labelText);\n}\n\nexport { TREE_DRAG_MIME };\n","import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type { TreeNode } from '../common/types.js';\nimport type { TreeDropContext, TreeDropDetail, TreeDropPosition, TreeDropTarget } from './tree-drag-types.js';\n\nconst EDGE_ZONE_PX = 24;\nconst MAX_SCROLL_SPEED = 16;\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\nexport interface TreeDropVisibleRow {\n readonly key: string;\n readonly node: TreeNode;\n readonly depth: number;\n /** Index of this row in the full flat (visible) list — not in the `rows` array. */\n readonly index: number;\n readonly rect: DOMRect;\n}\n\n/** Structural facts about a visible row, independent of geometry. */\nexport interface TreeDropRowInfo {\n readonly node: TreeNode;\n readonly depth: number;\n /** Parent key, or `undefined` for a root-level row. */\n readonly parentKey: string | undefined;\n}\n\n/** What a `dragover` / `drop` DataTransfer resolved to for this tree. */\nexport interface TreeDropResolvedDrag {\n readonly source: `internal` | `external`;\n /** Keys of the dragged nodes (empty for external). */\n readonly keys: readonly string[];\n /** The dragged nodes — live nodes for internal, parsed payload for external. */\n readonly nodes: readonly TreeNode[];\n}\n\nexport type TreeDropControllerConfig = {\n getDndMode: () => `none` | `internal` | `external` | `both`;\n getExpandHoverMs: () => number;\n /**\n * Measured rows in display order, each with a fresh viewport rect. May be\n * limited to the rows intersecting the scroll container — ancestors and\n * siblings are resolved through `getRowInfo` / `getChildren`, not from here.\n * Host may cache.\n */\n getVisibleRows: () => TreeDropVisibleRow[];\n /** Flat-list info for a visible key (no geometry), or `undefined` if not visible. */\n getRowInfo: (key: string) => TreeDropRowInfo | undefined;\n /** Children of `parentKey`, or the root's children when undefined. */\n getChildren: (parentKey: string | undefined) => readonly TreeNode[];\n getIndentPx: () => number;\n getScrollContainer: () => HTMLElement | undefined;\n /** True when `key` is `ancestorKey` or a descendant of it. */\n isSelfOrDescendant: (ancestorKey: string, key: string) => boolean;\n /** True when the node is currently expanded in the UI. */\n isExpanded: (key: string) => boolean;\n /**\n * When `false`, an internal drop that would not change any dragged node's\n * parent (pure sibling reorder, or dropping back into the current parent) is\n * rejected outright — no indicator, no `tree-drop`.\n */\n isReorderAllowed: () => boolean;\n /** Current parent key of `key`, or `undefined` for a root-level node. */\n getParentKey: (key: string) => string | undefined;\n /**\n * Decide whether this DataTransfer is acceptable and resolve the dragged set.\n * `phase` is `hover` during dragenter/dragover (DataTransfer is read-protected —\n * resolve internal drags from the drag registry) and `drop` during drop\n * (getData is readable; external payloads may be parsed here). Return\n * `undefined` to reject (the tree will not become a drop target).\n */\n resolveDrag: (dataTransfer: DataTransfer, phase: `hover` | `drop`) => TreeDropResolvedDrag | undefined;\n vet: (ctx: TreeDropContext) => boolean;\n expandKey: (key: string) => void;\n /** Fired whenever the resolved drop target changes (undefined = none / rejected). */\n onDropStateChange: (state: TreeDropTarget | undefined) => void;\n /** Fired when a drag enters / leaves this tree. */\n onActiveChange: (active: boolean) => void;\n commitDrop: (detail: TreeDropDetail) => boolean;\n onDragEnd: (dropped: boolean) => void;\n};\n\nexport class TreeDropController implements ReactiveController {\n readonly #host: ReactiveControllerHost & HTMLElement;\n readonly #config: TreeDropControllerConfig;\n\n #active = false;\n #current: TreeDropTarget | undefined;\n #source: `internal` | `external` = `internal`;\n #dragKeys: readonly string[] = [];\n #dragNodes: readonly TreeNode[] = [];\n\n #expandTimer: ReturnType<typeof setTimeout> | undefined;\n #expandPendingKey: string | undefined;\n\n #scrollRaf = 0;\n #pointerX = 0;\n #pointerY = 0;\n #boundContainer: HTMLElement | undefined;\n\n constructor(host: ReactiveControllerHost & HTMLElement, config: TreeDropControllerConfig) {\n this.#host = host;\n this.#config = config;\n host.addController(this);\n }\n\n /** A drag is currently over this tree. */\n get isDragging(): boolean {\n return this.#active;\n }\n\n /** A drag is over this tree but the current position is not a valid drop. */\n get isRejected(): boolean {\n return this.#active && this.#current === undefined;\n }\n\n get dropState(): TreeDropTarget | undefined {\n return this.#current;\n }\n\n hostConnected(): void {\n this.#bind();\n }\n\n /** Bind once the shadow `#container` exists (it does not yet at `hostConnected`). */\n hostUpdated(): void {\n this.#bind();\n }\n\n #bind(): void {\n const container = this.#config.getScrollContainer();\n if (!container || container === this.#boundContainer)\n return;\n this.#unbind();\n this.#boundContainer = container;\n container.addEventListener(`dragenter`, this.#onDragEnter);\n container.addEventListener(`dragover`, this.#onDragOver);\n container.addEventListener(`dragleave`, this.#onDragLeave);\n container.addEventListener(`drop`, this.#onDrop);\n }\n\n #unbind(): void {\n const c = this.#boundContainer;\n if (!c)\n return;\n c.removeEventListener(`dragenter`, this.#onDragEnter);\n c.removeEventListener(`dragover`, this.#onDragOver);\n c.removeEventListener(`dragleave`, this.#onDragLeave);\n c.removeEventListener(`drop`, this.#onDrop);\n this.#boundContainer = undefined;\n }\n\n hostDisconnected(): void {\n this.#unbind();\n this.#clearExpand();\n this.#stopScroll();\n this.#active = false;\n this.#current = undefined;\n }\n\n #onDragEnter = (event: DragEvent): void => {\n if (this.#config.getDndMode() === `none` || !event.dataTransfer)\n return;\n if (this.#config.resolveDrag(event.dataTransfer, `hover`) === undefined)\n return;\n // Signal that this element can accept the drag.\n event.preventDefault();\n if (!this.#active) {\n this.#active = true;\n this.#config.onActiveChange(true);\n }\n };\n\n #onDragOver = (event: DragEvent): void => {\n if (this.#config.getDndMode() === `none` || !event.dataTransfer)\n return;\n\n this.#pointerX = event.clientX;\n this.#pointerY = event.clientY;\n\n const drag = this.#config.resolveDrag(event.dataTransfer, `hover`);\n if (!drag) {\n this.#reject(event);\n return;\n }\n\n if (!this.#active) {\n this.#active = true;\n this.#config.onActiveChange(true);\n }\n\n this.#source = drag.source;\n this.#dragKeys = drag.keys;\n this.#dragNodes = drag.nodes;\n\n const rows = this.#config.getVisibleRows();\n\n // Spring-load: keyed off the row physically under the pointer, regardless of\n // where the drop would land after the x-position ancestor walk.\n this.#handleExpandHover(this.#rowAtPointer(rows, event.clientY));\n this.#kickScroll();\n\n const target = this.#resolveIntent(event, rows, drag.source);\n if (!target) {\n this.#reject(event, false);\n return;\n }\n\n const ctx: TreeDropContext = {\n source: drag.source,\n dragged: drag.nodes.length > 0 ? drag.nodes : undefined,\n draggedKeys: drag.keys,\n target,\n dataTransfer: event.dataTransfer,\n };\n\n if (!this.#config.vet(ctx)) {\n this.#reject(event, false);\n return;\n }\n\n event.preventDefault();\n event.dataTransfer.dropEffect = drag.source === `internal` ? `move` : `copy`;\n this.#setDropState(target);\n };\n\n /** Not a valid drop here: keep the drag active for feedback but accept nothing. */\n #reject(event: DragEvent, clearHover = true): void {\n if (event.dataTransfer)\n event.dataTransfer.dropEffect = `none`;\n this.#setDropState(undefined);\n if (clearHover)\n this.#clearExpand();\n }\n\n #onDragLeave = (event: DragEvent): void => {\n const container = this.#config.getScrollContainer();\n const related = event.relatedTarget as Node | null;\n if (container && related && container.contains(related))\n return; // moved between descendants — still inside\n this.#endHover();\n };\n\n #onDrop = (event: DragEvent): void => {\n if (!event.dataTransfer) {\n this.#endHover();\n return;\n }\n event.preventDefault();\n this.#stopScroll();\n this.#clearExpand();\n\n const finish = (dropped: boolean): void => {\n this.#current = undefined;\n this.#active = false;\n this.#config.onDropStateChange(undefined);\n this.#config.onActiveChange(false);\n this.#config.onDragEnd(dropped);\n };\n\n if (this.#config.getDndMode() === `none`) {\n finish(false);\n return;\n }\n\n const drag = this.#config.resolveDrag(event.dataTransfer, `drop`);\n if (!drag) {\n finish(false);\n return;\n }\n this.#dragKeys = drag.keys;\n this.#dragNodes = drag.nodes;\n\n const target = this.#resolveIntent(event, this.#config.getVisibleRows(), drag.source);\n if (!target) {\n finish(false);\n return;\n }\n\n const ctx: TreeDropContext = {\n source: drag.source,\n dragged: drag.nodes.length > 0 ? drag.nodes : undefined,\n draggedKeys: drag.keys,\n target,\n dataTransfer: event.dataTransfer,\n };\n\n if (!this.#config.vet(ctx)) {\n finish(false);\n return;\n }\n\n const detail: TreeDropDetail = {\n ...ctx,\n external: drag.source === `external` ? drag.nodes : undefined,\n };\n finish(this.#config.commitDrop(detail));\n };\n\n #endHover(): void {\n this.#clearExpand();\n this.#stopScroll();\n if (this.#current !== undefined) {\n this.#current = undefined;\n this.#config.onDropStateChange(undefined);\n }\n if (this.#active) {\n this.#active = false;\n this.#config.onActiveChange(false);\n }\n }\n\n // -------------------------------------------------------------------------\n // Intent resolution\n // -------------------------------------------------------------------------\n\n #rowAtPointer(rows: readonly TreeDropVisibleRow[], clientY: number): TreeDropVisibleRow | undefined {\n if (rows.length === 0)\n return undefined;\n if (clientY < rows[0].rect.top)\n return rows[0];\n if (clientY > rows[rows.length - 1].rect.bottom)\n return rows[rows.length - 1];\n return rows.find(r => clientY >= r.rect.top && clientY <= r.rect.bottom) ?? rows[rows.length - 1];\n }\n\n #resolveIntent(\n event: DragEvent,\n rows: readonly TreeDropVisibleRow[],\n source: `internal` | `external`,\n ): TreeDropTarget | undefined {\n if (rows.length === 0)\n return undefined;\n\n const row = this.#rowAtPointer(rows, event.clientY);\n if (!row)\n return undefined;\n\n const f = clamp((event.clientY - row.rect.top) / row.rect.height, 0, 1);\n let position: TreeDropPosition = f < 0.25 ? `before` : f > 0.75 ? `after` : `inside`;\n\n const isLeaf = row.node.item.isLeaf === true;\n if (position === `inside` && isLeaf)\n position = `after`;\n\n // VS Code: dropping just below an expanded branch lands as its first child.\n let insideFromExpandedAfter = false;\n if (position === `after` && !isLeaf && this.#config.isExpanded(row.key)) {\n position = `inside`;\n insideFromExpandedAfter = true;\n }\n\n let parentKey: string | undefined;\n let referenceKey: string;\n let depth: number;\n let index: number;\n\n if (position === `inside`) {\n parentKey = row.key;\n referenceKey = row.key;\n depth = row.depth + 1;\n index = insideFromExpandedAfter ? 0 : (row.node.children?.length ?? 0);\n } else {\n // X-position ancestor walk — lets the user target a shallow parent without\n // scrolling, by dragging left across a deeply-indented row.\n const indent = this.#config.getIndentPx() || 1;\n const treeLeft = rows[0].rect.left;\n const pointerDepth = Math.round((event.clientX - treeLeft) / indent);\n const effDepth = clamp(pointerDepth, 0, row.depth);\n\n // The ancestors may be scrolled out of `rows`, so walk them structurally.\n let anchor: TreeDropRowInfo = { node: row.node, depth: row.depth, parentKey: this.#config.getRowInfo(row.key)?.parentKey };\n referenceKey = row.key;\n for (let up = row.depth - effDepth; up > 0 && anchor.parentKey !== undefined; up--) {\n const parentInfo = this.#config.getRowInfo(anchor.parentKey);\n if (!parentInfo)\n break;\n referenceKey = anchor.parentKey;\n anchor = parentInfo;\n }\n depth = anchor.depth;\n parentKey = anchor.parentKey;\n\n const siblings = this.#config.getChildren(parentKey);\n const refIdx = siblings.findIndex(n => n.item.key === referenceKey);\n index = (refIdx < 0 ? 0 : refIdx) + (position === `after` ? 1 : 0);\n }\n\n if (source === `internal`) {\n for (const key of this.#dragKeys) {\n if (key === parentKey || key === referenceKey)\n return undefined;\n if (parentKey !== undefined && this.#config.isSelfOrDescendant(key, parentKey))\n return undefined;\n if (position !== `inside` && this.#config.isSelfOrDescendant(key, referenceKey))\n return undefined;\n }\n\n // Pure reorder (no dragged node changes parent) — rejected when the host\n // has reordering disabled, e.g. an unordered filesystem model.\n if (this.#dragKeys.length > 0 && !this.#config.isReorderAllowed()) {\n const changesParent = this.#dragKeys.some(k => this.#config.getParentKey(k) !== parentKey);\n if (!changesParent)\n return undefined;\n }\n }\n\n return { parentKey, index, referenceKey, position, depth };\n }\n\n // -------------------------------------------------------------------------\n // Spring-loaded expand\n // -------------------------------------------------------------------------\n\n #handleExpandHover(row: TreeDropVisibleRow | undefined): void {\n if (!row || row.node.item.isLeaf === true || this.#config.isExpanded(row.key)) {\n this.#clearExpand();\n return;\n }\n if (row.key === this.#expandPendingKey)\n return; // timer already armed for this row\n\n this.#clearExpand();\n const key = this.#expandPendingKey = row.key;\n this.#expandTimer = setTimeout(() => {\n this.#expandTimer = undefined;\n if (this.#expandPendingKey === key) {\n this.#expandPendingKey = undefined;\n this.#config.expandKey(key);\n }\n }, Math.max(0, this.#config.getExpandHoverMs()));\n }\n\n #clearExpand(): void {\n if (this.#expandTimer !== undefined) {\n clearTimeout(this.#expandTimer);\n this.#expandTimer = undefined;\n }\n this.#expandPendingKey = undefined;\n }\n\n // -------------------------------------------------------------------------\n // Edge auto-scroll\n // -------------------------------------------------------------------------\n\n #kickScroll(): void {\n if (this.#scrollRaf === 0)\n this.#scrollRaf = requestAnimationFrame(this.#scrollTick);\n }\n\n #scrollTick = (): void => {\n this.#scrollRaf = 0;\n if (!this.#active)\n return;\n const container = this.#config.getScrollContainer();\n if (!container)\n return;\n\n const rect = container.getBoundingClientRect();\n const y = this.#pointerY - rect.top;\n let dy = 0;\n if (y < EDGE_ZONE_PX)\n dy = -Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, y) / EDGE_ZONE_PX));\n else if (y > rect.height - EDGE_ZONE_PX)\n dy = Math.ceil(MAX_SCROLL_SPEED * (1 - Math.max(0, rect.height - y) / EDGE_ZONE_PX));\n\n if (dy !== 0 && this.#pointerX >= rect.left && this.#pointerX <= rect.right) {\n container.scrollTop += dy;\n this.#kickScroll();\n }\n };\n\n #stopScroll(): void {\n if (this.#scrollRaf !== 0) {\n cancelAnimationFrame(this.#scrollRaf);\n this.#scrollRaf = 0;\n }\n }\n\n #setDropState(state: TreeDropTarget | undefined): void {\n const unchanged = state === undefined\n ? this.#current === undefined\n : state.referenceKey === this.#current?.referenceKey\n && state.position === this.#current?.position\n && state.depth === this.#current?.depth\n && state.index === this.#current?.index;\n this.#current = state;\n // Always notify while a drag is active so the host can refresh the\n // rejected / accepted feedback even when the resolved target is unchanged.\n if (!unchanged || this.#active)\n this.#config.onDropStateChange(state);\n }\n}\n","/**\n * Pure tree flattening and indexing utilities.\n *\n * These functions operate on the shared TreeNode type and are independent of\n * any specific component, making them suitable for testing without DOM.\n */\n\nimport type { TreeNode } from '../common/types.js';\n\n/**\n * A single flattened row in display order.\n * Root itself is never included; depth 0 is the root's children.\n */\nexport type FlatRow = Readonly<{\n node: TreeNode;\n depth: number;\n /** Key of the parent node, or undefined for depth 0 (root's children). */\n parentKey: string | undefined;\n /** 1-based position among visible siblings (for ARIA posinset). */\n posInSet: number;\n /** Total count of visible siblings (for ARIA setsize). */\n setSize: number;\n}>;\n\n/**\n * The result of flattening the visible tree structure.\n */\nexport type FlatTree = Readonly<{\n rows: readonly FlatRow[];\n /** Map from node key to its index in `rows`. O(1) lookup. */\n indexByKey: ReadonlyMap<string, number>;\n}>;\n\n/**\n * Options for flattening the visible tree.\n */\nexport type FlattenOptions = Readonly<{\n /**\n * Returns true if the given node should be expanded at the given depth.\n * When false, the node's children are not included in the flat list.\n */\n isExpanded: (node: TreeNode, depth: number) => boolean;\n /**\n * Returns true if the given node should be shown at all.\n * When false, the node and its entire subtree are omitted.\n */\n isShown: (node: TreeNode, depth: number) => boolean;\n}>;\n\n/**\n * An index over the (potentially large) loaded tree structure.\n * Built once per structure version and cached.\n */\nexport type TreeIndex = Readonly<{\n /** Parent key for every loaded node (root has no parent). */\n parentByKey: ReadonlyMap<string, string>;\n /** Depths at which at least one node carries an icon. */\n depthsWithIcons: ReadonlySet<number>;\n}>;\n\n/**\n * Flatten the visible rows under `root` (root itself excluded).\n *\n * Iterative implementation using an explicit stack to avoid recursion depth\n * limits with deep trees. `posInSet` / `setSize` count only shown siblings.\n *\n * @param root - The root node (never included in output; its children are depth 0)\n * @param options - Callbacks determining expansion and visibility\n * @returns FlatTree with rows in display order and a key→index map\n */\nexport function flattenTree(root: TreeNode, options: FlattenOptions): FlatTree {\n const rows: FlatRow[] = [];\n const indexByKey = new Map<string, number>();\n\n type StackEntry = Readonly<{ node: TreeNode; depth: number; parentKey: string | undefined; posInSet: number; setSize: number }>;\n const stack: StackEntry[] = [];\n\n const pushChildren = (children: readonly TreeNode[] | undefined, depth: number, parentKey: string | undefined) => {\n if (!children || children.length === 0)\n return;\n const shown = children.filter(c => options.isShown(c, depth));\n for (let i = shown.length - 1; i >= 0; i--) {\n stack.push({ node: shown[i], depth, parentKey, posInSet: i + 1, setSize: shown.length });\n }\n };\n\n pushChildren(root.children, 0, undefined);\n\n while (stack.length > 0) {\n const { node, depth, parentKey, posInSet, setSize } = stack.pop()!;\n indexByKey.set(node.item.key, rows.length);\n rows.push({ node, depth, parentKey, posInSet, setSize });\n if (node.children && node.children.length > 0 && options.isExpanded(node, depth)) {\n pushChildren(node.children, depth + 1, node.item.key);\n }\n }\n\n return { rows, indexByKey };\n}\n\n/**\n * Build a whole-tree index over the currently loaded nodes.\n * This walks the entire loaded tree once and is cached on structure version.\n *\n * @param root - The root node\n * @returns TreeIndex with parent map and icon depth set\n */\nexport function indexTree(root: TreeNode): TreeIndex {\n const parentByKey = new Map<string, string>();\n const depthsWithIcons = new Set<number>();\n\n // Iterative traversal using explicit stack\n type StackEntry = { node: TreeNode; depth: number; parentKey: string };\n const stack: StackEntry[] = [];\n\n // Start with root's children at depth 0 (since root itself is depth -1 in flatten)\n if (root.children) {\n for (const child of root.children) {\n parentByKey.set(child.item.key, root.item.key);\n stack.push({ node: child, depth: 0, parentKey: root.item.key });\n }\n }\n\n while (stack.length > 0) {\n const { node, depth, parentKey } = stack.pop()!;\n\n // Record parent\n parentByKey.set(node.item.key, parentKey);\n\n // Track icon depth\n if (node.item.icon) {\n depthsWithIcons.add(depth);\n }\n\n // Push children in reverse order\n if (node.children) {\n for (let i = node.children.length - 1; i >= 0; i--) {\n const child = node.children[i];\n stack.push({ node: child, depth: depth + 1, parentKey: node.item.key });\n }\n }\n }\n\n return { parentByKey, depthsWithIcons };\n}\n\n/**\n * Compute which nodes match a filter predicate.\n * Returns the set of keys for nodes that match OR have a matching descendant.\n *\n * One iterative post-order pass; every node is visited (no short-circuiting).\n */\nexport function computeFilterMatches(\n root: TreeNode,\n predicate: (node: TreeNode, depth: number) => boolean,\n): ReadonlySet<string> {\n const matches = new Set<string>();\n if (!root.children)\n return matches;\n\n type Frame = { node: TreeNode; depth: number; next: number; matched: boolean };\n const stack: Frame[] = [];\n const enter = (node: TreeNode, depth: number) => {\n stack.push({ node, depth, next: 0, matched: predicate(node, depth) });\n };\n\n for (const child of root.children) {\n enter(child, 0);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n const children = frame.node.children;\n if (children && frame.next < children.length) {\n enter(children[frame.next++], frame.depth + 1);\n continue;\n }\n stack.pop();\n if (frame.matched) {\n matches.add(frame.node.item.key);\n // Propagate to the parent frame\n if (stack.length > 0)\n stack[stack.length - 1].matched = true;\n }\n }\n }\n\n return matches;\n}\n\n/**\n * Merge ghost rows back near their previous position.\n * Each ghost goes immediately before the first row that followed it last render\n * and still exists; otherwise at the end. Ghosts sharing an anchor keep their\n * previous relative order. O(rows + prevKeys).\n *\n * @param rows - Current flat rows (with node and depth)\n * @param prevKeys - Previous render's row keys in order\n * @param ghosts - Map of ghost keys to their row data\n * @returns Rows with ghosts woven in at their original relative positions\n */\nexport function weaveGhosts<T extends { node: TreeNode }>(\n rows: readonly T[],\n prevKeys: readonly string[],\n ghosts: ReadonlyMap<string, T>,\n): T[] {\n if (ghosts.size === 0)\n return [...rows];\n\n const present = new Set<string>();\n for (const r of rows)\n present.add(r.node.item.key);\n\n const END = Symbol(`end`);\n const before = new Map<string | typeof END, T[]>();\n let nextSurvivor: string | typeof END = END;\n\n for (let i = prevKeys.length - 1; i >= 0; i--) {\n const key = prevKeys[i];\n if (present.has(key)) {\n nextSurvivor = key;\n continue;\n }\n const ghost = ghosts.get(key);\n if (!ghost)\n continue;\n const list = before.get(nextSurvivor);\n if (list)\n list.push(ghost);\n else\n before.set(nextSurvivor, [ghost]);\n }\n\n const result: T[] = [];\n for (const row of rows) {\n const list = before.get(row.node.item.key);\n if (list) {\n for (let i = list.length - 1; i >= 0; i--)\n result.push(list[i]);\n }\n result.push(row);\n }\n const tail = before.get(END);\n if (tail) {\n for (let i = tail.length - 1; i >= 0; i--)\n result.push(tail[i]);\n }\n return result;\n}\n\n/** Checkbox tri-state in `checked` interactionMode: a branch node is `indeterminate` when some but not all of its descendants are selected. */\nexport type TreeCheckboxState = `checked` | `unchecked` | `indeterminate`;\n\n/**\n * Compute checkbox states for all nodes in a single iterative post-order pass.\n * A leaf (or a branch with no children) uses `selected.has(node)`; otherwise a\n * branch is checked if all children are checked, unchecked if all are\n * unchecked, else indeterminate.\n *\n * @param root - The root node\n * @param selected - Set of selected nodes\n * @returns Map from node key to checkbox state\n */\nexport function computeCheckboxStates(\n root: TreeNode,\n selected: ReadonlySet<TreeNode>,\n): ReadonlyMap<string, TreeCheckboxState> {\n const states = new Map<string, TreeCheckboxState>();\n if (!root.children)\n return states;\n\n type Frame = { node: TreeNode; next: number; checked: number; unchecked: number };\n const stack: Frame[] = [];\n\n for (const top of root.children) {\n stack.push({ node: top, next: 0, checked: 0, unchecked: 0 });\n while (stack.length > 0) {\n const frame = stack[stack.length - 1];\n const { node } = frame;\n const children = node.children;\n const isLeafLike = node.item.isLeaf || !children?.length;\n if (!isLeafLike && frame.next < children!.length) {\n stack.push({ node: children![frame.next++], next: 0, checked: 0, unchecked: 0 });\n continue;\n }\n stack.pop();\n let state: TreeCheckboxState;\n if (isLeafLike)\n state = selected.has(node) ? `checked` : `unchecked`;\n else if (frame.checked === children!.length)\n state = `checked`;\n else if (frame.unchecked === children!.length)\n state = `unchecked`;\n else\n state = `indeterminate`;\n states.set(node.item.key, state);\n if (stack.length > 0) {\n const parent = stack[stack.length - 1];\n if (state === `checked`)\n parent.checked++;\n else if (state === `unchecked`)\n parent.unchecked++;\n }\n }\n }\n\n return states;\n}\n\n// --- Immutable key-set helpers ------------------------------------------------\n// Each returns the *same* set when nothing changes, so callers can compare by\n// identity to detect a no-op.\n\nexport function withKey(set: ReadonlySet<string>, key: string): ReadonlySet<string> {\n if (set.has(key))\n return set;\n const next = new Set(set);\n next.add(key);\n return next;\n}\n\nexport function withoutKey(set: ReadonlySet<string>, key: string): ReadonlySet<string> {\n if (!set.has(key))\n return set;\n const next = new Set(set);\n next.delete(key);\n return next;\n}\n\n/** Remove every key for which `pred` returns true. */\nexport function withoutKeys(set: ReadonlySet<string>, pred: (key: string) => boolean): ReadonlySet<string> {\n let next: Set<string> | undefined;\n for (const key of set) {\n if (pred(key)) {\n next ??= new Set(set);\n next.delete(key);\n }\n }\n return next ?? set;\n}\n","/**\n * Pure fixed-stride layout for a windowed (virtualised) tree list.\n *\n * Every row is `rowHeight` tall and preceded by `gap` px of margin, so row `i`\n * occupies the slot `[listOffset + i * stride, listOffset + (i + 1) * stride)`\n * with the visible box at the end of it. Nothing is measured per row: the\n * window, scroll targets and drag geometry are all arithmetic. Mirrors\n * `grid-list-layout.ts`.\n */\nimport type { RowGeometryReader } from './tree-row-geometry.js';\n\nexport type TreeLayoutParams = Readonly<{\n /** Number of visible rows (the flat list length). */\n count: number;\n /** Row box height in px (`--tree-item-height`). */\n rowHeight: number;\n /** Margin above each row in px (`--tree-item-gap`). */\n gap: number;\n /** Content-space y of the first row's slot (list top + its padding). */\n listOffset: number;\n /** Height of the scroll viewport in px. */\n viewportHeight: number;\n}>;\n\nexport type TreeWindow = Readonly<{\n /** First rendered row index (inclusive). */\n start: number;\n /** One past the last rendered row index. */\n end: number;\n}>;\n\n/** Rows rendered beyond each edge of the viewport. */\nexport const TREE_OVERSCAN = 5;\n\nexport function treeStride(params: TreeLayoutParams): number {\n return Math.max(1, params.rowHeight + params.gap);\n}\n\n/** Content-space top of the row box at `index`. */\nexport function treeRowTop(params: TreeLayoutParams, index: number): number {\n return params.listOffset + index * treeStride(params) + params.gap;\n}\n\nexport function treeRowBottom(params: TreeLayoutParams, index: number): number {\n return treeRowTop(params, index) + params.rowHeight;\n}\n\n/** Total height of the rows' slots (what the two spacers add up to, plus the rendered rows). */\nexport function treeRowsHeight(params: TreeLayoutParams): number {\n return params.count * treeStride(params);\n}\n\n/** The window of rows to render for a given scroll offset. Always `0 <= start <= end <= count`. */\nexport function computeTreeWindow(\n params: TreeLayoutParams,\n scrollTop: number,\n overscan = TREE_OVERSCAN,\n): TreeWindow {\n const { count } = params;\n if (count <= 0)\n return { start: 0, end: 0 };\n const stride = treeStride(params);\n const top = Math.max(0, scrollTop - params.listOffset);\n const firstVisible = Math.floor(top / stride);\n const lastVisible = Math.ceil((top + params.viewportHeight) / stride);\n const start = Math.min(count, Math.max(0, firstVisible - overscan));\n const end = Math.min(count, Math.max(start, lastVisible + overscan));\n return { start, end };\n}\n\n/** Index of the row whose slot contains content-space `y`, clamped to `[0, count - 1]`. */\nexport function treeIndexAt(params: TreeLayoutParams, y: number): number {\n if (params.count <= 0)\n return -1;\n const index = Math.floor((y - params.listOffset) / treeStride(params));\n return Math.min(params.count - 1, Math.max(0, index));\n}\n\n/**\n * The scroll offset that brings row `index` fully into view with the least\n * movement, leaving `topInset` px at the top clear (the sticky-header overlay).\n * Returns `scrollTop` unchanged when the row is already visible.\n */\nexport function treeScrollTopToReveal(\n params: TreeLayoutParams,\n index: number,\n scrollTop: number,\n topInset = 0,\n): number {\n if (index < 0 || index >= params.count)\n return scrollTop;\n const top = treeRowTop(params, index);\n const bottom = top + params.rowHeight;\n if (top < scrollTop + topInset) {\n // The first row reveals the list's own top padding too.\n return index === 0 ? 0 : Math.max(0, top - topInset);\n }\n if (bottom > scrollTop + params.viewportHeight)\n return Math.max(0, bottom - params.viewportHeight);\n return scrollTop;\n}\n\n/** Rows that fit one viewport (PageUp / PageDown step), at least 1. */\nexport function treePageSize(params: TreeLayoutParams): number {\n return Math.max(1, Math.floor(params.viewportHeight / treeStride(params)) - 1);\n}\n\n/** Arithmetic `RowGeometryReader` over flat-row indices (the windowed counterpart of reading `offsetTop`). */\nexport function treeRowReader(params: TreeLayoutParams): RowGeometryReader {\n return {\n count: params.count,\n topOf: i => treeRowTop(params, i),\n bottomOf: i => treeRowBottom(params, i),\n };\n}\n","/**\n * Pure row-geometry helpers over a small reader interface.\n *\n * The tree reads row offsets through a `RowGeometryReader`, so the sticky-header\n * and drag-and-drop logic never depends on how rows are laid out. A windowed\n * (virtualised) list can swap in arithmetic (`topOf(i) = listTop + i * stride`)\n * without touching that logic.\n */\n\nexport type RowGeometryReader = Readonly<{\n count: number;\n /** Top of rendered row `i`, in container content coordinates. */\n topOf: (i: number) => number;\n /** Bottom of rendered row `i`, in container content coordinates. */\n bottomOf: (i: number) => number;\n}>;\n\n/**\n * First index whose bottom is greater than `y` (binary search; rows are\n * monotonic). Returns `reader.count` when no row qualifies.\n */\nexport function firstRowBelow(reader: RowGeometryReader, y: number): number {\n let lo = 0;\n let hi = reader.count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (reader.bottomOf(mid) > y)\n hi = mid;\n else\n lo = mid + 1;\n }\n return lo;\n}\n\n/**\n * Inclusive index range of rows that overlap `[top, bottom]`, widened by\n * `margin` rows on each side. Returns `undefined` when there are no rows.\n */\nexport function rowRangeOverlapping(\n reader: RowGeometryReader,\n top: number,\n bottom: number,\n margin = 0,\n): Readonly<{ first: number; last: number }> | undefined {\n if (reader.count === 0)\n return undefined;\n const firstHit = Math.min(firstRowBelow(reader, top), reader.count - 1);\n // First row whose top is at or beyond `bottom`: everything before it may overlap.\n let lo = firstHit;\n let hi = reader.count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (reader.topOf(mid) >= bottom)\n hi = mid;\n else\n lo = mid + 1;\n }\n const lastHit = Math.max(firstHit, lo - 1);\n return {\n first: Math.max(0, firstHit - margin),\n last: Math.min(reader.count - 1, lastHit + margin),\n };\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues, TemplateResult } from 'lit';\nimport type { TreeSearchHost } from '../common/searchable.js';\nimport type {\n TreeActivateDetail,\n TreeActivateEvent,\n TreeCollapseDetail,\n TreeCollapseEvent,\n TreeComponent,\n TreeComponentEventMap,\n TreeDndMode,\n TreeDragContext,\n TreeDragEndEvent,\n TreeDragOverEvent,\n TreeDragStartEvent,\n TreeDropContext,\n TreeDropDetail,\n TreeDropEvent,\n TreeDropTarget,\n TreeExpandDetail,\n TreeExpandEvent,\n TreeItemClickDetail,\n TreeItemClickEvent,\n TreeItemDblClickDetail,\n TreeItemDblClickEvent,\n TreeSelectDetail,\n TreeSelectEvent,\n TreeTickleDetail,\n TreeTickleEvent,\n} from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeInteractionMode,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type { ListDragPreviewRenderer, ListDragPreviewSourceResolver, ListNativeDragStartDetail } from '../interaction/list-drag-types.js';\nimport type { TreeDropResolvedDrag, TreeDropVisibleRow } from './tree-drop-controller.js';\nimport type { FlatRow, FlatTree, TreeIndex } from './tree-flat.js';\nimport type { TreeLayoutParams } from './tree-layout.js';\nimport type { RowGeometryReader } from './tree-row-geometry.js';\nimport type { TreeConfig } from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport { pruneDraggedDescendants } from '../common/tree-drop-apply.js';\nimport {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { animateListItemIn, animateListItemOut } from '../interaction/list-item-animation.js';\nimport { ListNativeDragController } from '../interaction/list-native-drag-controller.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport {\n TREE_DRAG_MIME,\n treeDragCurrent,\n treeDragGenerateSourceId,\n treeDragRegister,\n treeDragUnregister,\n} from './tree-drag-registry.js';\nimport { TreeDropController } from './tree-drop-controller.js';\nimport { computeFilterMatches, flattenTree, indexTree, weaveGhosts, withKey, withoutKey, withoutKeys } from './tree-flat.js';\nimport {\n computeTreeWindow,\n treePageSize,\n treeRowReader,\n treeRowTop,\n treeScrollTopToReveal,\n treeStride,\n} from './tree-layout.js';\nimport { firstRowBelow, rowRangeOverlapping } from './tree-row-geometry.js';\n\n/** Above this many rows entering / leaving at once, skip the animation entirely. */\nconst MAX_ANIMATED_ROWS = 50;\n\nconst EMPTY_FLAT: FlatTree = { rows: [], indexByKey: new Map() };\n\n/**\n * `auto` windows the list once it has more than `virtualizeThreshold` visible\n * rows; `on` / `off` force it.\n */\nexport type TreeVirtualize = `auto` | `on` | `off`;\n\n/** Viewport height assumed until the container has been measured (or when it reads 0). */\nconst FALLBACK_VIEWPORT_HEIGHT = 600;\n\n@customElement(`ixfx-tree-base`)\nexport class TreeBaseElement extends LitElement implements TreeComponent, TreeSearchHost {\n @property({ type: Object })\n root: TreeNode | undefined;\n\n @property({ attribute: false })\n model: TreeDataModel | undefined;\n\n /** Callback to lazily load children for a node. Superseded by `model` when both are set. */\n @property({ attribute: false })\n loadChildren: LoadChildrenCallback | undefined;\n\n @property({ reflect: true, attribute: `exclusivity` })\n exclusivity: TreeExclusivity = `none`;\n\n @property({ reflect: true, attribute: `selection-filter` })\n selectionFilter: TreeSelectionFilter = `all`;\n\n /** Controls how pointer/keyboard gestures map to selection changes. Default: `'standard'`. */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: TreeInteractionMode = `standard`;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n protected _selectedNodes = new Set<TreeNode>();\n\n get selectedNodes(): ReadonlySet<TreeNode> {\n return this._selectedNodes;\n }\n\n @property({ attribute: false })\n filterPredicate: TreeFilterPredicate | undefined;\n\n @property({ type: Boolean, attribute: `disable-keyboard-navigation` })\n disableKeyboardNavigation = false;\n\n @property({ attribute: false })\n registry: CommandRegistry<unknown> | undefined = undefined;\n\n /**\n * Space-separated subset of `navigate select filter` — limits which\n * incremental-search modes are offered. Unset ⇒ all three; empty ⇒ search\n * disabled. See `docs/infra-incremental.md`.\n */\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @property({ reflect: true, attribute: `item-dnd` })\n itemDnd: TreeDndMode = `none`;\n\n @property({ type: String, attribute: `accept-drop-types` })\n acceptDropTypes: string | undefined;\n\n @property({ type: Number, attribute: `dnd-expand-hover-ms` })\n dndExpandHoverMs = 500;\n\n /**\n * Whether a drag that only reorders siblings (no dragged node changes parent)\n * is honoured. Default `true`. Set `reorderable=\"false\"` for models with no\n * meaningful child order (e.g. a filesystem) — pure-reorder drags then get no\n * drop indicator and emit no `tree-drop`. Reparenting is unaffected.\n */\n @property({\n reflect: true,\n attribute: `reorderable`,\n converter: {\n fromAttribute: (value: string | null) => value !== `false`,\n toAttribute: (value: unknown) => (value ? null : `false`),\n },\n })\n reorderable = true;\n\n /**\n * VS Code-style sticky headers: while scrolling vertically, the ancestors of\n * the top-visible row stick to the top of the list. Clicking a stuck header\n * selects that ancestor and scrolls it into view; clicking its caret toggles\n * expansion. On by default — set `sticky-headers=\"false\"` to opt out.\n */\n @property({\n reflect: true,\n attribute: `sticky-headers`,\n converter: {\n fromAttribute: (value: string | null) => value !== `false`,\n toAttribute: (value: unknown) => (value ? null : `false`),\n },\n })\n stickyHeaders = true;\n\n /**\n * Windowed rendering: only the rows near the viewport exist in the DOM, so a\n * node with tens of thousands of children stays fast. `auto` (default)\n * switches on above `virtualizeThreshold` visible rows; `on` / `off` force it.\n * While windowed, rows are a fixed `--tree-item-height` tall and expand /\n * collapse rows do not animate.\n */\n @property({ reflect: true, attribute: `virtualize` })\n virtualize: TreeVirtualize = `auto`;\n\n /** Visible-row count above which `virtualize=\"auto\"` windows the list. */\n @property({ type: Number, attribute: `virtualize-threshold` })\n virtualizeThreshold = 200;\n\n @property({ attribute: false })\n dragPreviewRenderer: ListDragPreviewRenderer<TreeNode> | undefined;\n\n @property({ attribute: false })\n dragPreviewSource: ListDragPreviewSourceResolver<TreeNode> | undefined;\n\n @property({ attribute: false })\n canDrag: ((ctx: TreeDragContext) => boolean) | undefined;\n\n @property({ attribute: false })\n canDrop: ((ctx: TreeDropContext) => boolean) | undefined;\n\n @property({ attribute: false })\n parseExternalDrop: ((dt: DataTransfer) => TreeNode[] | undefined) | undefined;\n\n @property({ attribute: false })\n applyInternalDrop: boolean = true;\n\n /** Immutable: replace via `#setExpanded` so the flat-row cache is invalidated. */\n @state()\n protected _expandedKeys: ReadonlySet<string> = new Set<string>();\n\n #setExpanded(next: ReadonlySet<string>): void {\n if (next === this._expandedKeys)\n return;\n this._expandedKeys = next;\n this.#flat = undefined;\n this.#stickyDirty = true;\n }\n\n // --- Cached derived models ---\n // `#flat` (visible rows) is rebuilt lazily, once per update: it is O(visible)\n // and so also copes with in-place `node.children` mutation. The heavier\n // whole-tree products (`#treeIndex`, `#filterCache`, checkbox states) are\n // keyed on `#structureVersion` and rebuilt only when the structure changes.\n #flat: FlatTree | undefined;\n #flatRoot: TreeNode | undefined;\n #flatFilter: TreeFilterPredicate | undefined;\n #structureVersion = 0;\n #treeIndexCache: { root: TreeNode; version: number; index: TreeIndex } | undefined;\n #filterCache: {\n predicate: TreeFilterPredicate;\n root: TreeNode;\n version: number;\n matches: ReadonlySet<string>;\n autoExpanded: ReadonlySet<string>;\n } | undefined;\n\n /** Bumped whenever `_selectedNodes` content may have changed. */\n protected _selectionVersion = 0;\n\n /**\n * Call after editing `node.children` / `node.item` in place (outside\n * `TreeDataModel`). Drops the cached whole-tree indexes and re-renders.\n */\n invalidateStructure(): void {\n this.#structureVersion++;\n this.#flat = undefined;\n this.requestUpdate();\n }\n\n /** Visible rows in display order (cached for the current update). */\n #getFlat(): FlatTree {\n if (!this.root)\n return EMPTY_FLAT;\n if (this.#flat && this.#flatRoot === this.root && this.#flatFilter === this.filterPredicate)\n return this.#flat;\n const filter = this.#getFilter();\n this.#flat = flattenTree(this.root, {\n isExpanded: (node, depth) => this._isExpanded(node, depth),\n isShown: filter ? node => filter.matches.has(node.item.key) : () => true,\n });\n this.#flatRoot = this.root;\n this.#flatFilter = this.filterPredicate;\n return this.#flat;\n }\n\n /** Whole-loaded-tree index (parents, icon depths); cached on `(root, structureVersion)`. */\n #getTreeIndex(): TreeIndex {\n const root = this.root;\n if (!root)\n return { parentByKey: new Map(), depthsWithIcons: new Set() };\n const cached = this.#treeIndexCache;\n if (cached && cached.root === root && cached.version === this.#structureVersion)\n return cached.index;\n const index = indexTree(root);\n this.#treeIndexCache = { root, version: this.#structureVersion, index };\n return index;\n }\n\n // --- Virtualisation ---\n // With a fixed row stride the window is pure arithmetic (`tree-layout.ts`).\n // Rows outside it do not exist in the DOM; two spacer `<li>`s hold the\n // scroll height. Cursor, selection, search and keyboard navigation already\n // work on keys / flat indices, so only scrolling and geometry need care.\n\n /** Scroll offset used for the last render; kept in sync with the container's. */\n @state()\n private _scrollTop = 0;\n\n /** Row height / gap / list offset as last measured from CSS + layout. */\n #metrics = { rowHeight: 30, gap: 1, listOffset: 0 };\n /** Last non-zero container height (a hidden dock tab reads 0). */\n #viewportH = 0;\n #virtualScrollRaf = 0;\n #virtualScrollContainer: HTMLElement | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #winStart = 0;\n #winEnd = 0;\n /** Set in `willUpdate` when only the scroll offset changed; consumed in `updated`. */\n #scrollOnlyUpdate = false;\n\n /** True when the current visible row count should be windowed. */\n #virtualActive(): boolean {\n if (this.virtualize === `off`)\n return false;\n if (this.virtualize === `on`)\n return true;\n return this.#getFlat().rows.length > this.virtualizeThreshold;\n }\n\n #layoutParams(count: number): TreeLayoutParams {\n return {\n count,\n rowHeight: this.#metrics.rowHeight,\n gap: this.#metrics.gap,\n listOffset: this.#metrics.listOffset,\n viewportHeight: this.#viewportH > 0 ? this.#viewportH : FALLBACK_VIEWPORT_HEIGHT,\n };\n }\n\n /**\n * Re-read the CSS metrics and viewport height. Returns true when anything\n * that changes row positions moved (the caller re-renders).\n */\n #measureMetrics(): boolean {\n // Prefer what a rendered row actually measures: `.item` is content-box with\n // padding and a border, so its box is taller than `--tree-item-height`.\n // The CSS variables are only the fallback before the first render.\n const list = this.renderRoot.querySelector<HTMLElement>(`ul.tree-list`);\n const sample = list?.querySelector<HTMLElement>(`li.item:not(.leaving)`);\n const measuredHeight = sample?.getBoundingClientRect().height ?? 0;\n const rowHeight = measuredHeight > 0 ? measuredHeight : this.#getItemHeight();\n const measuredGap = sample ? Number.parseFloat(getComputedStyle(sample).marginTop) : Number.NaN;\n const parsedGap = Number.isNaN(measuredGap)\n ? Number.parseFloat(getComputedStyle(this).getPropertyValue(`--tree-item-gap`))\n : measuredGap;\n const gap = Number.isNaN(parsedGap) ? 1 : parsedGap;\n let listOffset = this.#metrics.listOffset;\n if (list) {\n const padTop = Number.parseFloat(getComputedStyle(list).paddingTop);\n listOffset = list.offsetTop + (Number.isNaN(padTop) ? 0 : padTop);\n }\n const height = this.#container()?.clientHeight ?? 0;\n const heightChanged = height > 0 && height !== this.#viewportH;\n if (height > 0)\n this.#viewportH = height;\n const prev = this.#metrics;\n const changed = prev.rowHeight !== rowHeight || prev.gap !== gap || prev.listOffset !== listOffset;\n this.#metrics = { rowHeight, gap, listOffset };\n return changed || heightChanged;\n }\n\n /** The window for the current scroll offset. */\n #currentWindow(count: number): { start: number; end: number } {\n return computeTreeWindow(this.#layoutParams(count), this._scrollTop);\n }\n\n /** Pull the container's real scroll offset into state (programmatic and clamped scrolls included). */\n #syncScrollTopFromContainer(): void {\n const top = this.#container()?.scrollTop;\n if (top !== undefined && top !== this._scrollTop)\n this._scrollTop = top;\n }\n\n #onVirtualScroll = (): void => {\n if (this.#virtualScrollRaf !== 0)\n return;\n this.#virtualScrollRaf = requestAnimationFrame(() => {\n this.#virtualScrollRaf = 0;\n this.#syncWindowToScroll();\n });\n };\n\n /** Re-render only when the scroll has moved the window; scrolling inside it is free. */\n #syncWindowToScroll(): void {\n const container = this.#container();\n if (!container || !this.root || !this.#virtualActive())\n return;\n const top = container.scrollTop;\n if (top === this._scrollTop)\n return;\n const next = computeTreeWindow(this.#layoutParams(this.#getFlat().rows.length), top);\n if (next.start !== this.#winStart || next.end !== this.#winEnd)\n this._scrollTop = top;\n }\n\n /** Bind the window's scroll listener and resize observer to the container once it exists. */\n #syncVirtualObservers(): void {\n const container = this.#container();\n if (container === this.#virtualScrollContainer)\n return;\n this.#virtualScrollContainer?.removeEventListener(`scroll`, this.#onVirtualScroll);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#virtualScrollContainer = container;\n if (!container)\n return;\n container.addEventListener(`scroll`, this.#onVirtualScroll, { passive: true });\n if (typeof ResizeObserver !== `undefined`) {\n this.#resizeObserver = new ResizeObserver((entries) => {\n // A zero-size read (e.g. an inactive dock tab) must not collapse the window.\n const height = entries.at(-1)?.contentRect.height ?? 0;\n if (height > 0 && height !== this.#viewportH && this.#virtualActive())\n this.requestUpdate();\n });\n this.#resizeObserver.observe(container);\n }\n }\n\n #teardownVirtualObservers(): void {\n this.#virtualScrollContainer?.removeEventListener(`scroll`, this.#onVirtualScroll);\n this.#virtualScrollContainer = undefined;\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n if (this.#virtualScrollRaf !== 0) {\n cancelAnimationFrame(this.#virtualScrollRaf);\n this.#virtualScrollRaf = 0;\n }\n }\n\n /**\n * Scroll flat row `index` into view (below the sticky overlay). Writes the\n * container's `scrollTop` and `_scrollTop` together, so the very next render\n * already contains the target row — no frame where it is missing.\n */\n #revealIndex(index: number): void {\n const container = this.#container();\n if (!container)\n return;\n const params = this.#layoutParams(this.#getFlat().rows.length);\n const inset = (\n this.renderRoot.querySelector(`.sticky-headers`) as HTMLElement | null\n )?.getBoundingClientRect().height ?? 0;\n const next = treeScrollTopToReveal(params, index, container.scrollTop, inset);\n if (next === container.scrollTop && next === this._scrollTop)\n return;\n container.scrollTop = next;\n this._scrollTop = next;\n }\n\n /** Filter match sets, or `undefined` when no filter is active. */\n #getFilter() {\n const predicate = this.filterPredicate;\n const root = this.root;\n if (!predicate || !root)\n return undefined;\n const cached = this.#filterCache;\n if (cached && cached.predicate === predicate && cached.root === root && cached.version === this.#structureVersion)\n return cached;\n const matches = computeFilterMatches(root, predicate);\n // A node is auto-expanded when one of its children matches (or contains a match).\n const { parentByKey } = this.#getTreeIndex();\n const autoExpanded = new Set<string>();\n for (const key of matches) {\n const parent = parentByKey.get(key);\n if (parent !== undefined)\n autoExpanded.add(parent);\n }\n const next = { predicate, root, version: this.#structureVersion, matches, autoExpanded };\n this.#filterCache = next;\n return next;\n }\n\n /** Structure version for cache keys in subclasses (bumped on root / model change and lazy loads). */\n protected get _structureVersion(): number {\n return this.#structureVersion;\n }\n\n /** Depths at which any loaded node carries an icon (stable across expansion). */\n protected get _depthsWithIcons(): ReadonlySet<number> {\n return this.#getTreeIndex().depthsWithIcons;\n }\n\n protected tickled = new TickledController<string>(this, {\n getItems: () => {\n return this.#getFlat().rows.map(({ node }) => ({ id: node.item.key, enabled: true }));\n },\n // Suppress hover-cursor moves while a drag is in flight over this tree.\n hoverDisabled: () => this.#drop?.isDragging === true || this.#nativeDrag?.isDragging === true,\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n });\n\n @state()\n protected _focusedDepth = 0;\n\n /** Incremental search (navigate / select / filter). See `docs/infra-incremental.md`. */\n readonly search = new ListSearchController<{ node: TreeNode; depth: number }>(this, {\n adapter: createTreeListSearchAdapter(this, {\n labelSelector: `.tree-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n #unregisterSearchCommands: (() => void) | undefined;\n\n #effectiveSearchModes(): ListSearchMode[] {\n const raw = this.searchModes?.trim();\n if (raw === undefined)\n return [...LIST_SEARCH_MODES];\n const requested = new Set(raw.split(/\\s+/));\n return LIST_SEARCH_MODES.filter(m => requested.has(m));\n }\n\n #syncSearchCommands(): void {\n if (!this.#ownedRegistry)\n return;\n this.search.setModes(this.#effectiveSearchModes());\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = registerListSearchCommands(this.#ownedRegistry, this.search);\n }\n\n #pendingNode: TreeNode | undefined;\n #pendingController: AbortController | undefined;\n #modelUnsubscribe: (() => void) | undefined;\n // Range-select anchor: the flat-list index and node from which a Shift-range is measured.\n #anchor: { node: TreeNode; flatIndex: number; selectionSnapshot?: ReadonlySet<TreeNode> } | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n\n #config: TreeConfig = {\n indent: 20,\n };\n\n // --- Insertion / removal animation ---\n // The visible node list is diffed each update: rows that appear (a branch\n // expanded, a node added to the model) collapse in; rows that disappear (a\n // branch collapsed, a node removed) are kept as fading \"ghost\" rows until\n // their collapse-out finishes. All no-ops under `prefers-reduced-motion`.\n #renderedKeys: string[] = [];\n /** Keys in the exact DOM order of the last render (ghost rows woven in). */\n #renderedRowKeys: string[] = [];\n #renderedRowIndex = new Map<string, number>();\n #lastNodeByKey = new Map<string, { node: TreeNode; depth: number }>();\n #enteringKeys = new Set<string>();\n #leaving = new Map<string, { node: TreeNode; depth: number }>();\n #leavingAnimations = new Map<string, Animation>();\n #treeAnimReady = false;\n\n // --- Drag and drop ---\n #dragSourceId = ``;\n #postDragSuppressTimer: ReturnType<typeof setTimeout> | undefined;\n #dropState: TreeDropTarget | undefined;\n #drop!: TreeDropController;\n #nativeDrag!: ListNativeDragController<TreeNode>;\n /** Keys of the nodes currently being dragged out (for `.dragging` styling). */\n #nativeDragKeys: ReadonlySet<string> = new Set();\n /** Set by `commitDrop` for a same-tree internal drop, read by the native `onEnd` to avoid a duplicate `tree-drag-end`. */\n #internalDropHandled = false;\n /** Per-drag cache of measured rows; invalidated on scroll / update. */\n #rowsCache: TreeDropVisibleRow[] | undefined;\n #onContainerScroll = () => {\n this.#rowsCache = undefined;\n };\n\n /** Bind the sticky scroll listener once the container exists; unbind on opt-out. */\n #syncStickyScroll(): void {\n const container = this.#container();\n if (this.stickyHeaders && container) {\n if (!this.#stickyScrollBound || this.#stickyScrollContainer !== container) {\n this.#stickyScrollContainer?.removeEventListener(`scroll`, this.#onStickyScroll);\n container.addEventListener(`scroll`, this.#onStickyScroll, { passive: true });\n this.#stickyScrollContainer = container;\n this.#stickyScrollBound = true;\n }\n } else if (this.#stickyScrollBound) {\n this.#stickyScrollContainer?.removeEventListener(`scroll`, this.#onStickyScroll);\n this.#stickyScrollContainer = undefined;\n this.#stickyScrollBound = false;\n }\n }\n\n #onStickyScroll = (): void => {\n if (this.#stickyRaf !== 0)\n return;\n this.#stickyRaf = requestAnimationFrame(() => {\n this.#stickyRaf = 0;\n this.#updateStickyHeaders();\n });\n };\n\n /**\n * Row geometry over the rendered `<li>` elements (ghost rows included), in\n * container content coordinates. `#container` is `position: relative`, so\n * `offsetTop` is scroll-independent. Reads only — no layout writes.\n */\n #rowReader(rows: HTMLCollection): RowGeometryReader {\n return {\n count: rows.length,\n topOf: i => (rows[i] as HTMLElement).offsetTop,\n bottomOf: i => (rows[i] as HTMLElement).offsetTop + (rows[i] as HTMLElement).offsetHeight,\n };\n }\n\n /**\n * Recompute which ancestors stick to the top: the ancestors of the first\n * row whose bottom clears the container top, minus any ancestor that is\n * itself still visible below the overlay. Synchronous — reads current\n * geometry, renders nothing, expands nothing. O(log N) offset reads + O(depth).\n */\n #updateStickyHeaders(): void {\n this.#stickyDirty = false;\n const empty = new Map<string, { node: TreeNode; depth: number }>();\n const clear = () => this.#setStickyKeys([], empty);\n if (!this.stickyHeaders || !this.root)\n return clear();\n const container = this.#container();\n const list = this.renderRoot.querySelector(`ul.tree-list`);\n if (!container || !list)\n return clear();\n const flat = this.#getFlat();\n const virtual = this.#virtualActive();\n const rows = list.children;\n const keys = this.#renderedRowKeys;\n // The DOM and the last render's key order must agree to map index → key.\n if (flat.rows.length === 0)\n return clear();\n if (!virtual && (rows.length === 0 || rows.length !== keys.length))\n return clear();\n\n // Windowed: row geometry is arithmetic over flat indices and there are no\n // ghost rows. Otherwise read the rendered `<li>` offsets.\n const reader = virtual\n ? treeRowReader(this.#layoutParams(flat.rows.length))\n : this.#rowReader(rows);\n const scrollTop = container.scrollTop;\n // NOTE: the top-visible row is measured against the container top WITHOUT\n // the overlay height. Folding the overlay's own height into this threshold\n // oscillates: showing the overlay pushes the marginal row out (hiding the\n // overlay), which drops the threshold and shows it again — rapid flashing\n // at the boundary, e.g. scrolling past an open node's last child.\n // The overlay-aware threshold below is only used to skip ancestors that\n // are genuinely visible beneath the overlay; that filter is monotonic\n // (a stuck ancestor keeps the overlay tall, a skipped one keeps it short),\n // so it always converges instead of flipping.\n const visibleThreshold = scrollTop + (\n (this.renderRoot.querySelector(`.sticky-headers`) as HTMLElement | null)?.getBoundingClientRect().height ?? 0\n );\n\n let topIdx = firstRowBelow(reader, scrollTop);\n // Ghost rows are animating out and inert — never anchor on them.\n if (!virtual) {\n while (topIdx < rows.length && rows[topIdx].classList.contains(`leaving`))\n topIdx++;\n }\n if (topIdx >= reader.count)\n return clear();\n\n const topFlat = virtual ? topIdx : flat.indexByKey.get(keys[topIdx]);\n if (topFlat === undefined)\n return clear();\n\n // Visible rows' ancestors are always visible rows, so the flat list suffices.\n const chain: FlatRow[] = [];\n let cursor = flat.rows[topFlat].parentKey;\n while (cursor !== undefined) {\n const idx = flat.indexByKey.get(cursor);\n if (idx === undefined)\n break;\n chain.unshift(flat.rows[idx]);\n cursor = flat.rows[idx].parentKey;\n }\n\n const entries = new Map<string, { node: TreeNode; depth: number }>();\n const stuck: string[] = [];\n for (const row of chain) {\n const key = row.node.item.key;\n const domIdx = virtual ? flat.indexByKey.get(key) : this.#renderedRowIndex.get(key);\n // An ancestor with no real row (shouldn't happen) or one still visible\n // below the overlay must not duplicate into the header.\n if (domIdx === undefined || reader.bottomOf(domIdx) > visibleThreshold)\n continue;\n stuck.push(key);\n entries.set(key, { node: row.node, depth: row.depth });\n }\n this.#setStickyKeys(stuck, entries);\n }\n\n #setStickyKeys(keys: string[], entries: Map<string, { node: TreeNode; depth: number }>): void {\n const prev = this._stickyKeys;\n if (prev.length === keys.length && prev.every((key, i) => key === keys[i]))\n return;\n this.#stickyEntries = entries;\n this._stickyKeys = keys;\n }\n\n #renderStickyHeaders(): TemplateResult | typeof nothing {\n if (!this.stickyHeaders || this._stickyKeys.length === 0)\n return nothing;\n // `.sticky-anchor` is transparent to layout normally; while windowed it is a\n // zero-height sticky strip so the overlay takes no space and row offsets\n // (pure arithmetic there) never shift when it appears.\n return html`\n <div class=\"sticky-anchor\">\n <div class=\"sticky-headers\" part=\"sticky-headers\">\n ${this._stickyKeys.map((key) => {\n const entry = this.#stickyEntries.get(key);\n if (!entry)\n return nothing;\n return this.#renderStickyHeader(entry.node, entry.depth);\n })}\n </div>\n </div>\n `;\n }\n\n #renderStickyHeader(node: TreeNode, depth: number): TemplateResult {\n const selected = this._isSelected(node);\n const isBranch = node.item.isLeaf !== true;\n return html`\n <div\n class=\"item ${isBranch ? `branch` : `leaf`} sticky-header${selected ? ` selected` : ``}\"\n part=\"sticky-header\"\n role=\"button\"\n tabindex=\"0\"\n aria-label=\"Go to ${node.item.label}\"\n data-key=${node.item.key}\n style=${`--depth: ${depth}`}\n @click=${(e: MouseEvent) => this.#onStickyClick(e, node)}\n @keydown=${(e: KeyboardEvent) => {\n if (e.key === `Enter` || e.key === ` `) {\n e.preventDefault();\n this.#activateSticky(node);\n }\n }}\n >${this.renderNodeContent(node, depth)}</div>\n `;\n }\n\n #onStickyClick(event: MouseEvent, node: TreeNode): void {\n if (this.#drop?.isDragging || this.#nativeDrag?.isDragging)\n return;\n // Caret clicks toggle expansion (leaves have an empty caret gutter, so\n // only guard branches) — everywhere else selects + reveals.\n if (node.item.isLeaf !== true && event.target instanceof Element && event.target.closest(`.tree-caret`)) {\n const depth = this.#stickyEntries.get(node.item.key)?.depth ?? 0;\n this.#toggleExpand(node, depth);\n this.#stickyDirty = true;\n this.requestUpdate();\n return;\n }\n this.#activateSticky(node);\n }\n\n #activateSticky(node: TreeNode): void {\n if (this.#canSelect(node))\n this.select(node);\n this.#scrollKeyIntoView(node.item.key);\n this.#stickyDirty = true;\n this.requestUpdate();\n }\n\n /**\n * Ancestor keys currently stuck to the top of the list (root-ward order).\n * Recomputed on scroll and structural updates; empty when nothing is stuck.\n */\n @state()\n protected _stickyKeys: string[] = [];\n\n /** Visible `{ node, depth }` entries for `_stickyKeys` — depths drive the indent. */\n #stickyEntries = new Map<string, { node: TreeNode; depth: number }>();\n /** Set when expansion / data / filter changes may have altered the sticky set. Consumed in `updated()`. */\n #stickyDirty = true;\n #stickyRaf = 0;\n #stickyScrollContainer: HTMLElement | undefined;\n #stickyScrollBound = false;\n\n protected get nativeDrag(): ListNativeDragController<TreeNode> {\n return this.#nativeDrag;\n }\n\n protected get dropState(): TreeDropTarget | undefined {\n return this.#dropState;\n }\n\n /** Keys of the nodes currently being dragged out of this tree. */\n protected get nativeDragKeys(): ReadonlySet<string> {\n return this.#nativeDragKeys;\n }\n\n #cancelLeavingAnimation(key: string): void {\n const animation = this.#leavingAnimations.get(key);\n animation?.cancel();\n this.#leavingAnimations.delete(key);\n }\n\n #cancelAllLeavingAnimations(): void {\n for (const animation of this.#leavingAnimations.values()) {\n try {\n animation.cancel();\n } catch {\n // Ignore — cancelling a finished animation can reject its `finished`.\n }\n }\n this.#leavingAnimations.clear();\n }\n\n override willUpdate(changedProps: PropertyValues) {\n super.willUpdate(changedProps);\n // A windowed list scrolling inside its cached rows changes nothing but the\n // window: keep the flat model and skip the (O(rows)) animation diff.\n const scrollOnly = this.#flat !== undefined\n && changedProps.size === 1\n && changedProps.has(`_scrollTop`)\n && this.#virtualActive();\n this.#scrollOnlyUpdate = scrollOnly;\n if (scrollOnly) {\n this.#syncScrollTopFromContainer();\n return;\n }\n // `children` can be mutated in place, so never trust the flat cache across updates.\n this.#flat = undefined;\n if (changedProps.has(`root`) || changedProps.has(`model`))\n this.#structureVersion++;\n this.#diffVisibleNodes(changedProps.has(`filterPredicate`));\n const virtual = this.#virtualActive();\n this.toggleAttribute(`data-virtual`, virtual);\n if (virtual) {\n this.#measureMetrics();\n this.#syncScrollTopFromContainer();\n }\n if (\n changedProps.has(`root`)\n || changedProps.has(`model`)\n || changedProps.has(`filterPredicate`)\n || changedProps.has(`stickyHeaders`)\n ) {\n this.#stickyDirty = true;\n }\n // Runs pre-render so the overlay lands in the same update (no extra pass,\n // no layout shift under running row animations). DOM reads below hit the\n // previous frame's rows, which is exactly what scroll position refers to.\n if (this.#stickyDirty)\n this.#updateStickyHeaders();\n }\n\n /**\n * `filterChanged`: typing in a filter adds / removes whole rows from the DOM.\n * That is not an expand / collapse, so skip the enter / leave animations\n * (and any ghosts) for this update; `#renderedKeys` is still refreshed.\n */\n #diffVisibleNodes(filterChanged: boolean): void {\n const nodes = this.#getFlat().rows;\n if (this.#virtualActive()) {\n // Fixed-stride geometry has no room for ghost rows or height animations.\n this.#enteringKeys.clear();\n this.#cancelAllLeavingAnimations();\n this.#leaving.clear();\n this.#renderedKeys = [];\n return;\n }\n const nowKeys = new Set(nodes.map(n => n.node.item.key));\n\n this.#enteringKeys.clear();\n if (filterChanged) {\n this.#cancelAllLeavingAnimations();\n this.#leaving.clear();\n } else if (this.#treeAnimReady && this.#renderedKeys.length > 0) {\n const prevSet = new Set(this.#renderedKeys);\n for (const { node } of nodes) {\n if (!prevSet.has(node.item.key))\n this.#enteringKeys.add(node.item.key);\n }\n if (this.#enteringKeys.size > MAX_ANIMATED_ROWS)\n this.#enteringKeys.clear();\n\n for (const key of this.#renderedKeys) {\n if (!nowKeys.has(key) && !this.#leaving.has(key)) {\n const last = this.#lastNodeByKey.get(key);\n if (last)\n this.#leaving.set(key, last);\n }\n }\n }\n // A ghost whose key is visible again (re-expanded fast) stops being a\n // ghost. Its outgoing animation must be cancelled: merely deleting the\n // bookkeeping leaves the `fill: forwards` final frame overriding the\n // reused `<li>` (height 0 / opacity 0) indefinitely.\n for (const key of [...this.#leaving.keys()]) {\n if (nowKeys.has(key)) {\n this.#cancelLeavingAnimation(key);\n this.#leaving.delete(key);\n }\n }\n if (this.#leaving.size > MAX_ANIMATED_ROWS) {\n this.#cancelAllLeavingAnimations();\n this.#leaving.clear();\n }\n }\n\n /** True while `node` is a fading ghost row (removed / collapsed, still animating out). */\n protected _isLeaving(node: TreeNode): boolean {\n return this.#leaving.has(node.item.key);\n }\n\n /**\n * Kept for subclass compatibility. Filtered-out rows are no longer rendered\n * at all (they are omitted from the flat list), so this is `false` for every\n * rendered row.\n */\n protected _isFilteredOut(_node: TreeNode, _depth: number): boolean {\n return false;\n }\n\n #runItemAnimations(): void {\n if (this.#enteringKeys.size > 0) {\n for (const el of this.renderRoot.querySelectorAll<HTMLElement>(`.item`)) {\n const key = el.dataset.key;\n if (key === undefined || !this.#enteringKeys.has(key))\n continue;\n // A revived row may still carry its outgoing collapse animation\n // (same `<li>` reused by the keyed repeat). Cancel it so the entrance\n // starts from a clean style cascade.\n if (this.#leavingAnimations.has(key)) {\n this.#cancelLeavingAnimation(key);\n } else {\n for (const animation of el.getAnimations())\n animation.cancel();\n }\n animateListItemIn(el);\n }\n this.#enteringKeys.clear();\n }\n if (this.#leaving.size > 0) {\n for (const el of this.renderRoot.querySelectorAll<HTMLElement>(`.item.leaving`)) {\n const key = el.dataset.key;\n if (key === undefined || this.#leavingAnimations.has(key))\n continue;\n const result = animateListItemOut(el);\n const animation = result.animation;\n if (!animation) {\n // Reduced motion / zero size: no handle to own; drop the ghost.\n void result.then(() => {\n if (!this.#leaving.has(key))\n return;\n this.#leaving.delete(key);\n this.requestUpdate();\n });\n continue;\n }\n // Supersede any stale handle for the same key before owning the new one.\n this.#cancelLeavingAnimation(key);\n this.#leavingAnimations.set(key, animation);\n void result.then(() => {\n // Race-safe: only the current outgoing animation may clean up.\n if (this.#leavingAnimations.get(key) !== animation)\n return;\n this.#leavingAnimations.delete(key);\n this.#leaving.delete(key);\n this.requestUpdate();\n // Remove the retained `fill: forwards` effect after the ghost row\n // has been removed from the next render, so a later reuse of the\n // node (or Lit's DOM pool) never inherits the collapsed frame.\n // Awaiting updateComplete avoids a one-frame flash back to full size.\n void this.updateComplete.then(() => {\n try {\n animation.cancel();\n } catch {\n // Ignore — already cancelled by a revival path.\n }\n });\n });\n }\n }\n const visible = this.#getFlat().rows;\n this.#renderedKeys = visible.map(n => n.node.item.key);\n this.#lastNodeByKey.clear();\n for (const entry of visible)\n this.#lastNodeByKey.set(entry.node.item.key, entry);\n this.#treeAnimReady = true;\n }\n\n override updated(changedProps: PropertyValues) {\n // Row geometry may have shifted (expand/collapse, filter, resize) — drop the\n // per-drag measurement cache so the next `dragover` re-measures.\n this.#rowsCache = undefined;\n this.#syncVirtualObservers();\n if (this.#scrollOnlyUpdate) {\n this.#scrollOnlyUpdate = false;\n this.#repaintSearchHighlights();\n return;\n }\n this.#syncStickyScroll();\n\n if (changedProps.has(`root`) && this.root) {\n this.#abortPending();\n this.#setExpanded(new Set());\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._focusedDepth = 0;\n // A new root invalidates every ghost row; cancel their animations so no\n // retained `fill: forwards` frame survives on a reused `<li>`.\n this.#cancelAllLeavingAnimations();\n this.#leaving.clear();\n this.#enteringKeys.clear();\n }\n\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n const model = this.model;\n if (model) {\n this.root = model.root;\n this.#modelUnsubscribe = model._subscribe((event) => {\n if (event.type === `root`) {\n this.root = event.root;\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n // If the invalidated node is currently expanded, collapse it\n if (this._expandedKeys.has(event.key)) {\n this.#setExpanded(withoutKey(this._expandedKeys, event.key));\n this.requestUpdate();\n }\n }\n });\n }\n }\n\n if (changedProps.has(`interactionMode`)) {\n this.#anchor = undefined;\n this.clearSelection();\n }\n\n // When selectedNode is set externally, sync focus to match\n if (changedProps.has(`selectedNode`) && this.selectedNode) {\n const prev = changedProps.get(`selectedNode`) as TreeNode | undefined;\n if (prev !== this.selectedNode) {\n this.tickled.setTickled(this.selectedNode.item.key);\n }\n }\n\n if (this.#virtualActive()) {\n this.#renderedKeys = [];\n this.#lastNodeByKey.clear();\n // The list's own offset is only known once it has rendered.\n // Deferred: requesting an update from `updated()` itself trips Lit's change-in-update warning.\n if (this.#measureMetrics())\n queueMicrotask(() => this.requestUpdate());\n this.#repaintSearchHighlights();\n } else {\n this.#runItemAnimations();\n }\n }\n\n /** Highlights are painted on rendered labels, so they move with the window. */\n #repaintSearchHighlights(): void {\n if (this.search.isOpen)\n this.search.repaintHighlights();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute(`data-input-mode`, `mouse`);\n const registry = this.#ownedRegistry = createCommandRegistry();\n registry.register({\n id: `select-all`,\n label: `Select All`,\n description: `Select all visible items`,\n execute: () => this.selectAll(),\n });\n registry.register({\n id: `deselect-all`,\n label: `Deselect All`,\n description: `Clear all selection`,\n execute: () => this.deselectAll(),\n });\n this.registry = registry;\n this.#syncSearchCommands();\n this.#initDnd();\n }\n\n #initDnd(): void {\n this.#dragSourceId = treeDragGenerateSourceId();\n\n this.#nativeDrag = new ListNativeDragController<TreeNode>(this, {\n source: `tree-list`,\n isEnabled: () => this.itemDnd !== `none` && this.#anyRowDraggable(),\n resolveEventToKey: (target) => {\n if (!(target instanceof Element))\n return undefined;\n // Scoped to the real list — sticky header duplicates live outside it.\n const key = target.closest(`ul.tree-list li[data-key]`)?.getAttribute(`data-key`);\n return key ?? undefined;\n },\n prepareSelection: (originKey) => {\n const flat = this.#getFlat();\n const allNodes = flat.rows;\n const originIdx = flat.indexByKey.get(originKey);\n const originEntry = originIdx === undefined ? undefined : allNodes[originIdx];\n if (!originEntry)\n return undefined;\n\n const selectedNodes = new Set(this._selectedNodes);\n if (!selectedNodes.has(originEntry.node))\n selectedNodes.clear();\n selectedNodes.add(originEntry.node);\n\n // Only the top-most selected nodes travel — a nested selected descendant\n // rides along inside its ancestor's subtree (decision 6).\n const orderedKeys = allNodes.filter(n => selectedNodes.has(n.node)).map(n => n.node.item.key);\n const topKeys = new Set(\n this.root ? pruneDraggedDescendants(this.root, orderedKeys) : orderedKeys,\n );\n\n const selected = allNodes\n .filter(n => topKeys.has(n.node.item.key))\n .map((n, i) => ({\n key: n.node.item.key,\n index: i,\n item: n.node,\n element: this.shadowRoot?.querySelector(`ul.tree-list li[data-key=\"${CSS.escape(n.node.item.key)}\"]`) ?? undefined,\n }));\n\n const origin = selected.find(e => e.key === originKey)\n // origin pruned away (it sits under another dragged node) — anchor on it anyway\n ?? { key: originKey, index: 0, item: originEntry.node, element: undefined };\n if (!selected.some(e => e.key === origin.key))\n selected.unshift(origin);\n\n return { origin, selected };\n },\n getMetrics: () => ({\n rowHeight: this.#getItemHeight(),\n }),\n getRenderer: () => this.dragPreviewRenderer,\n getDragPreviewSourceResolver: () => this.dragPreviewSource,\n dispatch: (detail) => {\n const keys = detail.selected.map(e => e.key);\n const nodes = detail.selected.map(e => e.item as TreeNode);\n const evt = new CustomEvent<ListNativeDragStartDetail<TreeNode>>(`list-native-drag-start`, {\n detail,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n const notCancelled = this.dispatchEvent(evt);\n if (notCancelled) {\n this.#nativeDragKeys = new Set(keys);\n this.#internalDropHandled = false;\n if (this.itemDnd === `internal` || this.itemDnd === `both`)\n treeDragRegister(this.#dragSourceId, this, nodes, keys);\n this.dispatchEvent(new CustomEvent<TreeDragContext>(`tree-drag-start`, {\n detail: { nodes, keys },\n bubbles: true,\n composed: true,\n }));\n }\n return notCancelled;\n },\n writeDataTransfer: (dataTransfer, detail) => {\n if (this.itemDnd !== `internal` && this.itemDnd !== `both`)\n return;\n const keys = detail.selected.map(e => e.key);\n const nodes = detail.selected.map(e => e.item as TreeNode);\n try {\n dataTransfer.setData(TREE_DRAG_MIME, JSON.stringify({ sourceId: this.#dragSourceId, keys, nodes }));\n dataTransfer.setData(`text/plain`, nodes.map(n => n.item.label).join(`\\n`));\n } catch {\n // happy-dom / restricted DataTransfer — the registry still carries the drag.\n }\n },\n onActiveChange: (active) => {\n this.toggleAttribute(`data-native-dragging`, active);\n if (!active)\n this.#nativeDragKeys = new Set();\n this.requestUpdate();\n },\n onEnd: () => {\n treeDragUnregister(this.#dragSourceId);\n this.#nativeDragKeys = new Set();\n this.#postDragSuppressTimer = setTimeout(() => {\n this.#postDragSuppressTimer = undefined;\n }, 150);\n // The drop controller already fired `tree-drag-end` if the drop landed on\n // this same tree; only fire here for a drag that ended elsewhere.\n if (!this.#internalDropHandled) {\n this.dispatchEvent(new CustomEvent<{ dropped: boolean }>(`tree-drag-end`, {\n detail: { dropped: false },\n bubbles: true,\n composed: true,\n }));\n }\n this.#internalDropHandled = false;\n },\n });\n\n this.#drop = new TreeDropController(this, {\n getDndMode: () => this.itemDnd,\n getExpandHoverMs: () => this.dndExpandHoverMs,\n getVisibleRows: () => this.#getVisibleRows(),\n getRowInfo: (key) => {\n const flat = this.#getFlat();\n const idx = flat.indexByKey.get(key);\n if (idx === undefined)\n return undefined;\n const { node, depth, parentKey } = flat.rows[idx];\n return { node, depth, parentKey };\n },\n getChildren: parentKey => this.#childrenOfKey(parentKey),\n getIndentPx: () => this.#getIndentPx(),\n getScrollContainer: () => this.#container(),\n isSelfOrDescendant: (ancestorKey, key) => this.#isSelfOrDescendant(ancestorKey, key),\n isExpanded: key => this._expandedKeys.has(key),\n isReorderAllowed: () => this.reorderable,\n getParentKey: key => this.#findParentByKey(key)?.item.key,\n resolveDrag: (dataTransfer, phase) => this.#resolveDrag(dataTransfer, phase),\n vet: (ctx) => {\n if (this.canDrop && !this.canDrop(ctx))\n return false;\n const evt = new CustomEvent<TreeDropContext>(`tree-drag-over`, {\n detail: ctx,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n return this.dispatchEvent(evt);\n },\n expandKey: key => this.#springLoadExpand(key),\n onDropStateChange: (state) => {\n this.#dropState = state;\n // Rejected = a drag is over the tree but there's no valid target here.\n this.toggleAttribute(`data-drop-rejected`, this.#drop.isDragging && state === undefined);\n this.requestUpdate();\n },\n onActiveChange: (active) => {\n if (active) {\n this.#rowsCache = undefined;\n this.#container()?.addEventListener(`scroll`, this.#onContainerScroll, { passive: true });\n } else {\n this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);\n this.#rowsCache = undefined;\n this.toggleAttribute(`data-drop-rejected`, false);\n }\n this.requestUpdate();\n },\n commitDrop: (detail) => {\n const accepted = this.dispatchEvent(new CustomEvent<TreeDropDetail>(`tree-drop`, {\n detail,\n bubbles: true,\n composed: true,\n cancelable: true,\n }));\n if (!accepted)\n return false;\n if (this.applyInternalDrop && detail.source === `internal` && this.model) {\n this.model.applyDrop({\n source: `internal`,\n draggedKeys: detail.draggedKeys,\n target: detail.target,\n });\n }\n this.#internalDropHandled = true;\n return true;\n },\n onDragEnd: (dropped) => {\n this.#dropState = undefined;\n this.toggleAttribute(`data-drop-rejected`, false);\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ dropped: boolean }>(`tree-drag-end`, {\n detail: { dropped },\n bubbles: true,\n composed: true,\n }));\n },\n });\n }\n\n #container(): HTMLElement | undefined {\n return (this.shadowRoot?.querySelector(`#container`) as HTMLElement | null) ?? undefined;\n }\n\n #getIndentPx(): number {\n const parsed = Number.parseInt(getComputedStyle(this).getPropertyValue(`--tree-indent`), 10);\n return Number.isNaN(parsed) ? 20 : parsed;\n }\n\n #getItemHeight(): number {\n const parsed = Number.parseInt(getComputedStyle(this).getPropertyValue(`--tree-item-height`), 10);\n return Number.isNaN(parsed) ? 30 : parsed;\n }\n\n /** Children of `parentKey` (the root's children when undefined), straight from the tree. */\n #childrenOfKey(parentKey: string | undefined): readonly TreeNode[] {\n if (parentKey === undefined)\n return this.root?.children ?? [];\n const flat = this.#getFlat();\n const idx = flat.indexByKey.get(parentKey);\n return idx === undefined ? [] : (flat.rows[idx].node.children ?? []);\n }\n\n /**\n * Windowed counterpart of the measured rows: rects come from the layout\n * arithmetic and one rendered row's horizontal extent, so nothing is looked\n * up per row and rows outside the window still resolve.\n */\n #collectVirtualDropRows(container: HTMLElement, list: Element, out: TreeDropVisibleRow[]): void {\n const flat = this.#getFlat();\n const params = this.#layoutParams(flat.rows.length);\n const range = rowRangeOverlapping(\n treeRowReader(params),\n container.scrollTop,\n container.scrollTop + container.clientHeight,\n 1,\n );\n if (!range)\n return;\n const containerRect = container.getBoundingClientRect();\n // Every row spans the same horizontal extent; borrow it from a rendered one.\n const sample = list.querySelector(`li.item`)?.getBoundingClientRect() ?? containerRect;\n for (let i = range.first; i <= range.last; i++) {\n const { node, depth } = flat.rows[i];\n const top = containerRect.top - container.scrollTop + treeRowTop(params, i);\n const rect = {\n x: sample.left,\n y: top,\n left: sample.left,\n right: sample.left + sample.width,\n top,\n bottom: top + params.rowHeight,\n width: sample.width,\n height: params.rowHeight,\n toJSON: () => ({}),\n } as DOMRect;\n out.push({ key: node.item.key, node, depth, index: i, rect });\n }\n }\n\n /**\n * Measured rows for the part of the list that intersects the scroll\n * container (plus one row of margin each side), cached for the duration of a\n * drag and invalidated on scroll / update. Each row carries its flat index;\n * structural lookups (parents, siblings) come from `getRowInfo` / `getChildren`.\n */\n #getVisibleRows(): TreeDropVisibleRow[] {\n if (this.#rowsCache)\n return this.#rowsCache;\n const rows: TreeDropVisibleRow[] = [];\n const container = this.#container();\n const list = this.renderRoot.querySelector(`ul.tree-list`);\n const keys = this.#renderedRowKeys;\n if (container && list && this.#virtualActive()) {\n this.#collectVirtualDropRows(container, list, rows);\n } else if (container && list && list.children.length === keys.length) {\n const flat = this.#getFlat();\n const items = list.children;\n const range = rowRangeOverlapping(\n this.#rowReader(items),\n container.scrollTop,\n container.scrollTop + container.clientHeight,\n 1,\n );\n if (range) {\n for (let i = range.first; i <= range.last; i++) {\n const li = items[i] as HTMLElement;\n if (li.classList.contains(`leaving`))\n continue;\n const flatIdx = flat.indexByKey.get(keys[i]);\n if (flatIdx === undefined)\n continue;\n const { node, depth } = flat.rows[flatIdx];\n rows.push({ key: node.item.key, node, depth, index: flatIdx, rect: li.getBoundingClientRect() });\n }\n }\n }\n this.#rowsCache = rows;\n return rows;\n }\n\n /** Route spring-load through the real expand path so lazy children load and `expand` fires with the right depth. */\n #springLoadExpand(key: string): void {\n if (this._expandedKeys.has(key))\n return;\n const flat = this.#getFlat();\n const idx = flat.indexByKey.get(key);\n const entry = idx === undefined ? undefined : flat.rows[idx];\n if (!entry || entry.node.item.isLeaf === true)\n return;\n this.#toggleExpand(entry.node, entry.depth);\n this.#rowsCache = undefined;\n this.requestUpdate();\n }\n\n /** O(depth): walk up the whole-tree parent map. */\n #isSelfOrDescendant(ancestorKey: string, key: string): boolean {\n if (ancestorKey === key)\n return true;\n const { parentByKey } = this.#getTreeIndex();\n let cursor = parentByKey.get(key);\n while (cursor !== undefined) {\n if (cursor === ancestorKey)\n return true;\n cursor = parentByKey.get(cursor);\n }\n return false;\n }\n\n #findParentByKey(key: string): TreeNode | undefined {\n const parentKey = this.#getTreeIndex().parentByKey.get(key);\n if (parentKey === undefined || parentKey === this.root?.item.key)\n return undefined;\n return this.#nodeByKey(parentKey);\n }\n\n /** Node for a key anywhere in the loaded tree (via the flat list when visible). */\n #nodeByKey(key: string): TreeNode | undefined {\n const flat = this.#getFlat();\n const idx = flat.indexByKey.get(key);\n if (idx !== undefined)\n return flat.rows[idx].node;\n // Not visible (collapsed / filtered): walk down from the root along the parent chain.\n const { parentByKey } = this.#getTreeIndex();\n const path: string[] = [];\n for (let cursor: string | undefined = key; cursor !== undefined && cursor !== this.root?.item.key; cursor = parentByKey.get(cursor))\n path.unshift(cursor);\n let node: TreeNode | undefined = this.root;\n for (const k of path)\n node = node?.children?.find(c => c.item.key === k);\n return node;\n }\n\n /**\n * Decide whether a DataTransfer is acceptable and resolve the dragged set.\n * During `hover` the DataTransfer is read-protected, so an internal drag is\n * recovered from the module-level drag registry (there is only one at a time).\n */\n #resolveDrag(dataTransfer: DataTransfer, phase: `hover` | `drop`): TreeDropResolvedDrag | undefined {\n const mode = this.itemDnd;\n if (mode === `none`)\n return undefined;\n\n const canInternal = mode === `internal` || mode === `both`;\n const canExternal = mode === `external` || mode === `both`;\n\n let types: string[] = [];\n try {\n types = Array.from(dataTransfer.types);\n } catch {\n // some browsers throw reading `types` mid-drag — treat as unknown\n }\n // A drag started from any ixfx tree on this page. The registry is the source\n // of truth for same-document drags — `dataTransfer.types` is unreliable\n // across browsers during `dragover`, so we do not require the MIME to match.\n const current = treeDragCurrent();\n const looksInternal = types.includes(TREE_DRAG_MIME) || (current !== undefined);\n\n if (canInternal && looksInternal) {\n if (current && current.keys.length > 0) {\n const keys = this.root ? pruneDraggedDescendants(this.root, current.keys) : current.keys;\n const nodes = keys\n .map(k => this.#nodeByKey(k))\n .filter((n): n is TreeNode => n !== undefined);\n return { source: `internal`, keys, nodes };\n }\n if (phase === `drop`) {\n try {\n const raw = dataTransfer.getData(TREE_DRAG_MIME);\n if (raw) {\n const payload = JSON.parse(raw) as { keys: string[]; nodes: TreeNode[] };\n return { source: `internal`, keys: payload.keys ?? [], nodes: payload.nodes ?? [] };\n }\n } catch {\n // fall through\n }\n }\n // Internal drag from another document we can't resolve yet — accept the\n // target so the drop event still fires; the drop phase reads getData.\n return { source: `internal`, keys: [], nodes: [] };\n }\n\n if (canExternal && !looksInternal) {\n if (this.acceptDropTypes !== undefined) {\n const accepted = this.acceptDropTypes.trim().split(/\\s+/).filter(Boolean);\n const present = Array.from(dataTransfer.types);\n if (accepted.length > 0 && !accepted.some(t => present.includes(t)))\n return undefined;\n }\n if (phase === `drop`) {\n const nodes = this.parseExternalDrop?.(dataTransfer);\n if (!nodes || nodes.length === 0)\n return undefined;\n return { source: `external`, keys: nodes.map(n => n.item.key), nodes };\n }\n // hover: accept iff a parser is configured (payload can't be read yet)\n return this.parseExternalDrop ? { source: `external`, keys: [], nodes: [] } : undefined;\n }\n\n return undefined;\n }\n\n #anyRowDraggable(): boolean {\n if (this.itemDnd === `none`)\n return false;\n const allNodes = this.#getFlat().rows;\n if (allNodes.length === 0)\n return false;\n if (!this.canDrag)\n return true;\n return allNodes.some(({ node }) => this.canDrag!({ nodes: [node], keys: [node.item.key] }));\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.#cancelAllLeavingAnimations();\n this.#leaving.clear();\n this.#enteringKeys.clear();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = undefined;\n if (this.#postDragSuppressTimer !== undefined) {\n clearTimeout(this.#postDragSuppressTimer);\n this.#postDragSuppressTimer = undefined;\n }\n this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);\n this.#teardownVirtualObservers();\n if (this.#stickyScrollBound) {\n this.#stickyScrollContainer?.removeEventListener(`scroll`, this.#onStickyScroll);\n this.#stickyScrollContainer = undefined;\n this.#stickyScrollBound = false;\n }\n if (this.#stickyRaf !== 0) {\n cancelAnimationFrame(this.#stickyRaf);\n this.#stickyRaf = 0;\n }\n treeDragUnregister(this.#dragSourceId);\n if (this.#ownedRegistry) {\n this.#ownedRegistry.unregister(`select-all`);\n this.#ownedRegistry.unregister(`deselect-all`);\n this.#ownedRegistry = undefined;\n this.registry = undefined;\n }\n }\n\n getConfig(): TreeConfig {\n return { ...this.#config };\n }\n\n setConfig(config: Partial<TreeConfig>) {\n this.#config = { ...this.#config, ...config };\n this.requestUpdate();\n }\n\n // --- Programmatic selection ---\n\n select(node: TreeNode): void {\n if (!this.#canSelect(node))\n return;\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.clear();\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselect(node: TreeNode): void {\n if (!this._selectedNodes.has(node))\n return;\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.delete(node);\n if (this.selectedNode === node) {\n this.selectedNode = [...this._selectedNodes].at(-1);\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n clearSelection(): void {\n if (this._selectedNodes.size === 0)\n return;\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n selectAll(): void {\n const prev = new Set(this._selectedNodes);\n if (this.interactionMode === `checked`) {\n for (const { node } of this.#getFlat().rows) {\n if (!this.#canSelect(node))\n continue;\n this.#applyCheckedToggle(node, true);\n }\n } else {\n for (const { node } of this.#getFlat().rows) {\n if (!this.#canSelect(node))\n continue;\n this._selectedNodes.add(node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n if (this.interactionMode === `checked`) {\n for (const { node } of this.#getFlat().rows) {\n if (!this.#canSelect(node))\n continue;\n this.#applyCheckedToggle(node, false);\n }\n } else {\n this.#clearSelectionInternal();\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n // --- Navigation ---\n\n navigateTo(keys: readonly string[]): boolean {\n if (!this.root?.children)\n return false;\n\n this.#abortPending();\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._focusedDepth = 0;\n\n let currentNode: TreeNode | undefined = this.root;\n\n for (const key of keys) {\n const children: TreeNode[] | undefined = currentNode?.children;\n if (!children)\n return false;\n\n const found: TreeNode | undefined = children.find(n => n.item.key === key);\n if (!found)\n return false;\n\n this.#applyExclusivity(found.item.key);\n this.#setExpanded(withKey(this._expandedKeys, found.item.key));\n\n if (key === keys.at(-1)) {\n this.select(found);\n this.tickled.setTickled(found.item.key);\n }\n\n currentNode = found;\n }\n\n this.#stickyDirty = true;\n this.requestUpdate();\n this.#scrollKeyIntoView(keys.at(-1)!);\n return true;\n }\n\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n if (!this.root?.children)\n return false;\n const keyPath = this.#findNodePath(this.root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /** Expand ancestors + move the cursor to `key`, without touching the selection (search \"navigate\" mode). */\n revealKey(key: string): boolean {\n if (!this.root?.children)\n return false;\n const path = this.#findNodePath(this.root.children, n => n.item.key === key);\n if (!path)\n return false;\n for (let i = 0; i < path.length - 1; i++) {\n this.#applyExclusivity(path[i]);\n this.#setExpanded(withKey(this._expandedKeys, path[i]));\n }\n this.tickled.setTickled(key);\n this.#stickyDirty = true;\n this.requestUpdate();\n void this.updateComplete.then(() => this.#scrollKeyIntoView(key));\n return true;\n }\n\n /** Replace the selection with `nodes` (subject to `selectionFilter`) — search \"select\" mode. */\n selectMany(nodes: Iterable<TreeNode>): void {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = new Set([...nodes].filter(n => this.#canSelect(n)));\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n if (!this.root?.children)\n return [];\n const result: Array<{ node: TreeNode; depth: number }> = [];\n const visit = (node: TreeNode, depth: number) => {\n result.push({ node, depth });\n if (node.children) {\n for (const child of node.children) visit(child, depth + 1);\n }\n };\n for (const child of this.root.children) visit(child, 0);\n return result;\n }\n\n // --- Internal helpers ---\n\n #canSelect(node: TreeNode): boolean {\n if (this.selectionFilter === `none`)\n return false;\n if (this.selectionFilter === `leaf`)\n return node.item.isLeaf === true;\n if (this.selectionFilter === `branch`)\n return node.item.isLeaf === false || (node.children !== undefined && node.children.length > 0);\n return true;\n }\n\n #clearSelectionInternal(): void {\n this._selectionVersion++;\n this._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this._selectionVersion++;\n const detail: TreeSelectDetail = {\n selected: new Set(this._selectedNodes),\n previous,\n };\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n }\n\n #findNodePath(\n nodes: TreeNode[],\n predicate: (node: TreeNode) => boolean,\n prefix: string[] = [],\n ): string[] | undefined {\n for (const node of nodes) {\n const path = [...prefix, node.item.key];\n if (predicate(node))\n return path;\n if (node.children?.length) {\n const result = this.#findNodePath(node.children, predicate, path);\n if (result)\n return result;\n }\n }\n return undefined;\n }\n\n protected renderNodeContent(node: TreeNode, depth: number): TemplateResult | typeof nothing {\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n return html`\n <span class=\"tree-caret\">\n ${isBranch ? html`<ixfx-icon class=\"caret-icon\" name=\"chevron-down\" .rotate=${isExpanded ? nothing : `-90deg`}></ixfx-icon>` : ``}\n </span>\n <span class=\"tree-label\">${node.item.label}</span>\n `;\n }\n\n protected _handleItemClick(node: TreeNode, depth: number, event?: MouseEvent) {\n if (this.#drop?.isDragging || this.#nativeDrag?.isDragging || this.#postDragSuppressTimer !== undefined)\n return;\n\n // Second (or later) click of a double-click. `MouseEvent.detail` is the\n // running click count, so it is 2 on the second click. Swallow it: the\n // container's dblclick handler dispatches `item-dblclick`, and skipping the\n // switch below means a branch is never toggled open/closed by a double-click.\n if (event && event.detail >= 2)\n return;\n\n if (this.#pendingNode && this._expandedKeys.has(this.#pendingNode.item.key)) {\n this.#abortPending();\n }\n\n this.tickled.handlePointerEnter(node.item.key);\n this._focusedDepth = depth;\n\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n\n switch (this.interactionMode) {\n case `implicit`: this.#handleImplicitClick(node, depth, event); break;\n case `standard`: this.#handleStandardClick(node, depth, event); break;\n case `vscode`: this.#handleStandardClick(node, depth, event); break;\n case `manual`: this.#handleManualClick(node, depth, event); break;\n case `checked`: this.#handleExpandOnly(node, depth); break;\n }\n\n this.requestUpdate();\n }\n\n /**\n * True when a click landed on the expand/collapse caret rather than the node\n * label. Caret clicks should only toggle expansion, never select or navigate.\n * The caret and label are siblings in the same shadow root, so `closest` on\n * the event target resolves reliably. See tree-fix.md.\n */\n #clickedOnCaret(node: TreeNode, event?: MouseEvent): boolean {\n // Leaf nodes still render an (empty) caret gutter for alignment; clicking\n // there should behave like a label click, so only guard branch nodes.\n if (node.item.isLeaf === true)\n return false;\n const target = event?.target;\n if (!(target instanceof Element))\n return false;\n return target.closest(`.tree-caret`) !== null;\n }\n\n #handleImplicitClick(node: TreeNode, depth: number, event?: MouseEvent): void {\n if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.clear();\n this._selectedNodes.add(node);\n this.selectedNode = node;\n if (!prev.has(node) || prev.size !== 1)\n this.#dispatchSelect(prev);\n }\n this.#toggleExpand(node, depth);\n }\n\n #handleStandardClick(node: TreeNode, depth: number, event?: MouseEvent): void {\n const isMeta = event ? (event.metaKey || event.ctrlKey) : false;\n const isShift = event ? event.shiftKey : false;\n\n if (isMeta) {\n if (this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n if (this._selectedNodes.has(node)) {\n this._selectedNodes.delete(node);\n if (this.selectedNode === node)\n this.selectedNode = [...this._selectedNodes].at(-1);\n } else {\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n }\n this.#dispatchSelect(prev);\n }\n return; // no expand on Ctrl+click\n }\n\n if (isShift && this.#anchor) {\n const flat = this.#getFlat();\n const visible = flat.rows;\n const anchorIdx = flat.indexByKey.get(this.#anchor.node.item.key) ?? -1;\n const targetIdx = flat.indexByKey.get(node.item.key) ?? -1;\n if (anchorIdx >= 0 && targetIdx >= 0) {\n const prev = new Set(this._selectedNodes);\n const from = Math.min(anchorIdx, targetIdx);\n const to = Math.max(anchorIdx, targetIdx);\n const rangeNodes = visible.slice(from, to + 1)\n .map(n => n.node)\n .filter(n => this.#canSelect(n));\n this._selectedNodes = new Set(rangeNodes);\n this.selectedNode = node;\n this.#dispatchSelect(prev);\n }\n return; // no expand on Shift+click\n }\n\n // Plain click: select + toggle expand. A click on the caret only toggles\n // expansion — it must not change selection or trigger navigation.\n if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.clear();\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n if (!prev.has(node) || prev.size !== 1)\n this.#dispatchSelect(prev);\n }\n this.#toggleExpand(node, depth);\n }\n\n #handleExpandOnly(node: TreeNode, depth: number): void {\n this.#toggleExpand(node, depth);\n }\n\n #handleManualClick(node: TreeNode, depth: number, event?: MouseEvent): void {\n const isMeta = event ? (event.metaKey || event.ctrlKey) : false;\n const isShift = event ? event.shiftKey : false;\n\n if (isMeta) {\n if (this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n if (this._selectedNodes.has(node)) {\n this._selectedNodes.delete(node);\n if (this.selectedNode === node)\n this.selectedNode = [...this._selectedNodes].at(-1);\n } else {\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n }\n this.#dispatchSelect(prev);\n }\n return; // no expand on Meta+click\n }\n\n if (isShift && this.#anchor) {\n const flat = this.#getFlat();\n const visible = flat.rows;\n const anchorIdx = flat.indexByKey.get(this.#anchor.node.item.key) ?? -1;\n const targetIdx = flat.indexByKey.get(node.item.key) ?? -1;\n if (anchorIdx >= 0 && targetIdx >= 0) {\n const prev = new Set(this._selectedNodes);\n const from = Math.min(anchorIdx, targetIdx);\n const to = Math.max(anchorIdx, targetIdx);\n const rangeNodes = visible.slice(from, to + 1)\n .map(n => n.node)\n .filter(n => this.#canSelect(n));\n this._selectedNodes = new Set(rangeNodes);\n this.selectedNode = node;\n this.#dispatchSelect(prev);\n }\n return; // no expand on Shift+click\n }\n\n this.#toggleExpand(node, depth);\n }\n\n #toggleSelection(node: TreeNode, _depth: number): void {\n if (!this.#canSelect(node))\n return;\n const prev = new Set(this._selectedNodes);\n if (this._selectedNodes.has(node)) {\n this._selectedNodes.delete(node);\n if (this.selectedNode === node)\n this.selectedNode = [...this._selectedNodes].at(-1);\n } else {\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n }\n this.#dispatchSelect(prev);\n }\n\n protected _handleCheckboxClick(event: MouseEvent, node: TreeNode, _depth: number): void {\n event.stopPropagation();\n const prev = new Set(this._selectedNodes);\n const allSelected = this.#allDescendantsSelected(node);\n this.#applyCheckedToggle(node, !allSelected);\n if (this.selectedNode === undefined || !this._selectedNodes.has(this.selectedNode)) {\n this.selectedNode = [...this._selectedNodes].at(-1);\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n #toggleExpand(node: TreeNode, depth: number): void {\n const isExpanded = this._expandedKeys.has(node.item.key);\n this.#stickyDirty = true;\n if (isExpanded) {\n this.#setExpanded(withoutKey(this._expandedKeys, node.item.key));\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n } else {\n if (node.children === undefined) {\n if (node.item.isLeaf !== false)\n return;\n const loader = this.model ?? (this.loadChildren ? this : undefined);\n if (loader) {\n this.#pendingNode = node;\n const controller = new AbortController();\n this.#pendingController = controller;\n this.#invokeLoadChildren(node, depth, controller).catch(() => {});\n }\n } else {\n this.#applyExclusivity(node.item.key);\n this.#setExpanded(withKey(this._expandedKeys, node.item.key));\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n }\n }\n }\n\n #allDescendantsSelected(node: TreeNode): boolean {\n if (!this._selectedNodes.has(node))\n return false;\n if (!node.children?.length)\n return true;\n return node.children.every(child => this.#allDescendantsSelected(child));\n }\n\n #applyCheckedToggle(node: TreeNode, selected: boolean): void {\n if (this.#canSelect(node)) {\n if (selected) {\n this._selectedNodes.add(node);\n } else {\n this._selectedNodes.delete(node);\n }\n }\n if (node.children) {\n for (const child of node.children) {\n this.#applyCheckedToggle(child, selected);\n }\n }\n }\n\n #getFlatIndexOf(node: TreeNode): number {\n return this.#getFlat().indexByKey.get(node.item.key) ?? -1;\n }\n\n #extendRangeSelection(nodes: readonly FlatRow[], fromIdx: number, toIdx: number): void {\n // Set anchor at `fromIdx` if not already anchored\n if (!this.#anchor) {\n const anchorNode = nodes[fromIdx]?.node;\n if (anchorNode)\n this.#anchor = { node: anchorNode, flatIndex: fromIdx };\n }\n if (!this.#anchor)\n return;\n\n const anchorIdx = this.#getFlat().indexByKey.get(this.#anchor.node.item.key) ?? -1;\n if (anchorIdx < 0)\n return;\n\n const from = Math.min(anchorIdx, toIdx);\n const to = Math.max(anchorIdx, toIdx);\n\n if (this.interactionMode === `vscode`) {\n // On first Shift+arrow: snapshot current selection\n if (!this.#anchor.selectionSnapshot) {\n this.#anchor = { ...this.#anchor, selectionSnapshot: new Set(this._selectedNodes) };\n }\n const snap = this.#anchor.selectionSnapshot!;\n const rangeNodes = nodes.slice(from, to + 1).map(n => n.node).filter(n => this.#canSelect(n));\n // Toggle: items in snapshot stay toggled based on presence in snapshot\n const next = new Set(snap);\n for (const n of rangeNodes) {\n if (snap.has(n))\n next.delete(n);\n else next.add(n);\n }\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = next;\n this.selectedNode = nodes[toIdx]?.node ?? this.selectedNode;\n this.#dispatchSelect(prev);\n } else {\n // standard: range replaces selection\n const prev = new Set(this._selectedNodes);\n const rangeNodes = nodes.slice(from, to + 1).map(n => n.node).filter(n => this.#canSelect(n));\n this._selectedNodes = new Set(rangeNodes);\n this.selectedNode = nodes[toIdx]?.node ?? this.selectedNode;\n this.#dispatchSelect(prev);\n }\n }\n\n async #invokeLoadChildren(node: TreeNode, depth: number, controller: AbortController): Promise<void> {\n try {\n let children: TreeNode[];\n if (this.model) {\n children = await this.model.getChildren(node, depth, controller.signal);\n } else {\n children = [...await collectDataResult(\n this.loadChildren!({ node, depth }, controller.signal),\n controller.signal,\n )];\n }\n if (controller.signal.aborted)\n return;\n node.children = children;\n this.#structureVersion++;\n this.#applyExclusivity(node.item.key);\n this.#setExpanded(withKey(this._expandedKeys, node.item.key));\n this.#flat = undefined;\n this.#stickyDirty = true;\n this.#pendingNode = undefined;\n this.#pendingController = undefined;\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n this.#structureVersion++;\n this.#flat = undefined;\n this.#pendingNode = undefined;\n this.#pendingController = undefined;\n this.requestUpdate();\n }\n }\n\n protected _isSelected(node: TreeNode): boolean {\n return this._selectedNodes.has(node);\n }\n\n protected _isFocused(node: TreeNode): boolean {\n return this.tickled.isTickled(node.item.key);\n }\n\n protected _isExpanded(node: TreeNode, _depth = 0): boolean {\n if (this._expandedKeys.has(node.item.key))\n return true;\n // While filtering, branches with a match below them open so the matches show.\n return this.#getFilter()?.autoExpanded.has(node.item.key) ?? false;\n }\n\n protected get _pendingNode(): TreeNode | undefined {\n return this.#pendingNode;\n }\n\n #scrollKeyIntoView(key: string) {\n if (this.#virtualActive()) {\n // The target may only exist after this update (a branch just expanded),\n // and the scroll height only grows once its spacers have rendered.\n void this.updateComplete.then(() => {\n const idx = this.#getFlat().indexByKey.get(key);\n if (idx !== undefined)\n this.#revealIndex(idx);\n });\n return;\n }\n const token = ++this.#revealToken;\n requestAnimationFrame(() => {\n this.#revealRowElement(key);\n // Rows that just appeared are still growing from near-zero height (enter\n // animations), so the row can look visible now yet land below the fold once\n // they finish. Measure again against the settled layout — unless a newer\n // reveal has superseded this one.\n const running = this.#container()?.getAnimations?.({ subtree: true }) ?? [];\n if (running.length > 0) {\n void Promise.allSettled(running.map(a => a.finished)).then(() => {\n if (token === this.#revealToken)\n this.#revealRowElement(key);\n });\n }\n });\n }\n\n #revealToken = 0;\n\n /** Scroll the rendered row for `key` into the container, below the sticky overlay. No-op if it isn't rendered or is already visible. */\n #revealRowElement(key: string): void {\n // The scroll lives on #container, not the host (which is overflow\n // hidden) — adjusting `this.scrollTop` would silently do nothing.\n const container = this.#container();\n const el = this.shadowRoot?.querySelector(`ul.tree-list [data-key=\"${CSS.escape(key)}\"]`) as HTMLElement | null;\n if (!el || !container)\n return;\n const elRect = el.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const relativeTop = elRect.top - containerRect.top;\n const relativeBottom = relativeTop + elRect.height;\n // Land below the sticky headers when showing: scrolling the row to the\n // exact top would hide it underneath the overlay it just came from.\n const overlayHeight = (\n this.renderRoot.querySelector(`.sticky-headers`) as HTMLElement | null\n )?.getBoundingClientRect().height ?? 0;\n if (relativeTop < overlayHeight) {\n container.scrollTop += relativeTop - overlayHeight;\n } else if (relativeBottom > container.clientHeight) {\n container.scrollTop += relativeBottom - container.clientHeight;\n }\n }\n\n #abortPending() {\n if (this.#pendingController) {\n this.#pendingController.abort();\n this.#pendingController = undefined;\n this.#pendingNode = undefined;\n }\n }\n\n /** Apply exclusivity rules when a node is about to be expanded. */\n #applyExclusivity(expandKey: string): void {\n if (this.exclusivity === `none`)\n return;\n\n if (this.exclusivity === `depth`) {\n this.#collapseSiblingsAtDepth(expandKey);\n } else if (this.exclusivity === `global`) {\n // Collapse all expanded nodes except direct ancestors of the expanding node\n const ancestorKeys = this.#findAncestorKeys(expandKey);\n this.#setExpanded(withoutKeys(this._expandedKeys, key => !ancestorKeys.has(key) && key !== expandKey));\n }\n }\n\n #collapseSiblingsAtDepth(expandKey: string): void {\n if (!this.root)\n return;\n\n const parent = this.#findParent(this.root, expandKey);\n if (!parent?.children)\n return;\n\n const siblingKeys = new Set(parent.children.map(c => c.item.key));\n this.#setExpanded(withoutKeys(this._expandedKeys, key => key !== expandKey && siblingKeys.has(key)));\n }\n\n #findAncestorKeys(targetKey: string): Set<string> {\n const keys = new Set<string>();\n const walk = (node: TreeNode): boolean => {\n if (node.item.key === targetKey)\n return true;\n if (!node.children)\n return false;\n for (const child of node.children) {\n if (walk(child)) {\n keys.add(node.item.key);\n return true;\n }\n }\n return false;\n };\n if (this.root)\n walk(this.root);\n return keys;\n }\n\n #findParent(node: TreeNode, targetKey: string, parent: TreeNode | undefined = undefined): TreeNode | undefined {\n if (!node.children)\n return undefined;\n\n for (const child of node.children) {\n if (child.item.key === targetKey) {\n return parent ?? node;\n }\n const found = this.#findParent(child, targetKey, child);\n if (found)\n return found;\n }\n return undefined;\n }\n\n #getFocusedIndex(): number {\n const tickledKey = this.tickled.tickledId;\n if (!tickledKey)\n return 0;\n return this.#getFlat().indexByKey.get(tickledKey) ?? 0;\n }\n\n #setFocusedIndex(index: number) {\n const nodes = this.#getFlat().rows;\n if (index < 0 || index >= nodes.length)\n return;\n const { node, depth } = nodes[index];\n this.tickled.setTickled(node.item.key);\n this._focusedDepth = depth;\n // Emit tickle for keyboard cursor movement\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n if (this.#virtualActive()) {\n // Same-frame: the window then already contains the target row.\n this.#revealIndex(index);\n return;\n }\n this.updateComplete.then(() => this.#scrollTickledIntoView());\n }\n\n #scrollTickledIntoView() {\n const tickledKey = this.tickled.tickledId;\n if (tickledKey === undefined)\n return;\n const item = this.shadowRoot?.querySelector(`ul.tree-list [data-key=\"${CSS.escape(tickledKey)}\"]`);\n item?.scrollIntoView({ block: `nearest`, behavior: `smooth` });\n }\n\n /** Rows per PageUp / PageDown: one viewport, from the current CSS metrics. */\n #pageSize(): number {\n this.#measureMetrics();\n return treePageSize(this.#layoutParams(this.#getFlat().rows.length));\n }\n\n /** Move the cursor to `nextIdx`, applying the interaction mode's selection side effects. */\n #navigateToIndex(nodes: readonly FlatRow[], currentIdx: number, nextIdx: number, shiftKey: boolean): void {\n if (this.interactionMode === `implicit`) {\n this.select(nodes[nextIdx].node);\n }\n this.#setFocusedIndex(nextIdx);\n if (shiftKey && (this.interactionMode === `standard` || this.interactionMode === `vscode`)) {\n this.#extendRangeSelection(nodes, currentIdx, nextIdx);\n } else if (this.interactionMode === `vscode`) {\n this.#anchor = undefined; // clear snapshot on plain navigation\n }\n this.requestUpdate();\n }\n\n #onKeyDown = (event: KeyboardEvent) => {\n if (this.search.isOpen)\n return;\n const nodes = this.#getFlat().rows;\n if (nodes.length === 0)\n return;\n\n if ((event.ctrlKey || event.metaKey) && event.key === `a`) {\n event.preventDefault();\n this.selectAll();\n return;\n }\n\n // Switch to keyboard mode for any navigation key\n if ([`ArrowDown`, `ArrowUp`, `ArrowLeft`, `ArrowRight`, `Home`, `End`, `PageUp`, `PageDown`, `Enter`, ` `].includes(event.key)) {\n this.tickled.setInputMode(`keyboard`);\n }\n\n const currentIdx = this.#getFocusedIndex();\n\n switch (event.key) {\n case `ArrowDown`: {\n event.preventDefault();\n this.#navigateToIndex(nodes, currentIdx, Math.min(currentIdx + 1, nodes.length - 1), event.shiftKey);\n break;\n }\n case `ArrowUp`: {\n event.preventDefault();\n this.#navigateToIndex(nodes, currentIdx, Math.max(currentIdx - 1, 0), event.shiftKey);\n break;\n }\n case `Home`: {\n event.preventDefault();\n this.#navigateToIndex(nodes, currentIdx, 0, event.shiftKey);\n break;\n }\n case `End`: {\n event.preventDefault();\n this.#navigateToIndex(nodes, currentIdx, nodes.length - 1, event.shiftKey);\n break;\n }\n case `PageDown`: {\n event.preventDefault();\n const page = this.#pageSize();\n this.#navigateToIndex(nodes, currentIdx, Math.min(currentIdx + page, nodes.length - 1), event.shiftKey);\n break;\n }\n case `PageUp`: {\n event.preventDefault();\n const page = this.#pageSize();\n this.#navigateToIndex(nodes, currentIdx, Math.max(currentIdx - page, 0), event.shiftKey);\n break;\n }\n case `ArrowRight`: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (current && current.node.item.isLeaf !== true) {\n if (!this._expandedKeys.has(current.node.item.key)) {\n this.#toggleExpand(current.node, current.depth);\n } else if (currentIdx + 1 < nodes.length) {\n this.#setFocusedIndex(currentIdx + 1);\n }\n }\n this.requestUpdate();\n break;\n }\n case `ArrowLeft`: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (current && this._expandedKeys.has(current.node.item.key)) {\n this.#setExpanded(withoutKey(this._expandedKeys, current.node.item.key));\n this.dispatchEvent(new CustomEvent(`collapse`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n } else if (current.depth > 0) {\n const parentDepth = current.depth - 1;\n for (let i = currentIdx - 1; i >= 0; i--) {\n if (nodes[i].depth === parentDepth) {\n this.#setFocusedIndex(i);\n break;\n }\n }\n }\n this.requestUpdate();\n break;\n }\n case `Enter`: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (current) {\n if (this.interactionMode !== `manual` && this.interactionMode !== `checked`) {\n this.select(current.node);\n }\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n }\n break;\n }\n case ` `: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (!current)\n break;\n\n if (this.interactionMode === `checked`) {\n this._handleCheckboxClick(new MouseEvent(`click`), current.node, current.depth);\n } else if (this.interactionMode === `standard` || this.interactionMode === `vscode` || this.interactionMode === `manual`) {\n this.#toggleSelection(current.node, current.depth);\n }\n break;\n }\n case `Escape`: {\n event.preventDefault();\n this.#abortPending();\n break;\n }\n }\n };\n\n protected renderLoadingIndicator(): TemplateResult | typeof nothing {\n return html`<span class=\"loading-spinner\"></span>`;\n }\n\n protected override render() {\n const nodes = this.#getFlat().rows;\n\n return html`\n <div\n id=\"container\"\n data-input-mode=${this.tickled.inputMode}\n @keydown=${this.#onKeyDown}\n @dblclick=${this.#onDblClick}\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n tabindex=\"0\"\n >\n ${this.#renderStickyHeaders()}\n ${this.root ? this.#renderNodes(nodes) : nothing}\n </div>\n ${this.search.renderField()}\n `;\n }\n\n #onDblClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n const li = target.closest(`ul.tree-list li`) as HTMLElement | null;\n if (!li)\n return;\n const key = li.dataset.key;\n if (!key)\n return;\n const flat = this.#getFlat();\n const idx = flat.indexByKey.get(key);\n const node = idx === undefined ? undefined : flat.rows[idx];\n if (!node)\n return;\n const detail = { node: node.node, depth: node.depth };\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n // `activate` still fires here for back-compat (Enter key also dispatches it).\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n };\n\n #renderNodes(nodes: readonly FlatRow[]) {\n if (nodes.length === 0 && this.#pendingNode && this.#leaving.size === 0) {\n return html`\n <div class=\"tree-loading\">\n ${this.renderLoadingIndicator()}\n </div>\n `;\n }\n\n if (this.#virtualActive())\n return this.#renderWindow(nodes);\n\n // Keyed by node key so Lit never recycles a <li> across nodes — otherwise a\n // running leave animation (WAAPI, fill:forwards) would land on whatever node\n // reuses that <li> after the list shrinks, squashing it to 0 height.\n const woven = weaveGhosts<{ node: TreeNode; depth: number }>(nodes, this.#renderedRowKeys, this.#leaving);\n this.#renderedRowKeys = woven.map(e => e.node.item.key);\n this.#renderedRowIndex = new Map(this.#renderedRowKeys.map((key, i) => [key, i]));\n return html`\n <ul class=\"tree-list\" role=\"tree\">\n ${repeat(\n woven,\n ({ node }) => node.item.key,\n ({ node, depth }) => this._renderNode(node, depth),\n )}\n </ul>\n `;\n }\n\n /**\n * Windowed render: the rows near the viewport between two spacers that hold\n * the rest of the scroll height. Keyed, so a row that stays in the window\n * keeps its element while others enter and leave at the edges.\n */\n #renderWindow(nodes: readonly FlatRow[]) {\n const params = this.#layoutParams(nodes.length);\n const { start, end } = this.#currentWindow(nodes.length);\n this.#winStart = start;\n this.#winEnd = end;\n this.#renderedRowKeys = [];\n this.#renderedRowIndex = new Map();\n const stride = treeStride(params);\n return html`\n <ul class=\"tree-list virtual\" role=\"tree\" aria-rowcount=${nodes.length}>\n <li class=\"virtual-spacer\" role=\"presentation\" aria-hidden=\"true\" style=${`height: ${start * stride}px`}></li>\n ${repeat(\n nodes.slice(start, end),\n ({ node }) => node.item.key,\n ({ node, depth }) => this._renderNode(node, depth),\n )}\n <li class=\"virtual-spacer\" role=\"presentation\" aria-hidden=\"true\" style=${`height: ${(nodes.length - end) * stride}px`}></li>\n </ul>\n `;\n }\n\n /**\n * `{ posinset, setsize }` for `aria-posinset` / `aria-setsize`. A windowed\n * list has most siblings out of the DOM, so assistive tech cannot count them.\n */\n protected _ariaSetInfo(node: TreeNode): { posInSet: number; setSize: number } | undefined {\n const flat = this.#getFlat();\n const idx = flat.indexByKey.get(node.item.key);\n if (idx === undefined)\n return undefined;\n const { posInSet, setSize } = flat.rows[idx];\n return { posInSet, setSize };\n }\n\n /** Shared drag-and-drop render state for a row, used by every `_renderNode` variant. */\n protected _dndRowState(node: TreeNode): {\n draggable: boolean;\n dragging: boolean;\n dropTarget: boolean;\n dropPosition?: TreeDropTarget[`position`];\n dropDepth?: number;\n } {\n const dndEnabled = this.itemDnd !== `none` && (this.root?.children?.length ?? 0) > 0;\n const draggable = dndEnabled\n && (this.itemDnd === `internal` || this.itemDnd === `both` || this.itemDnd === `external`)\n && (this.canDrag?.({ nodes: [node], keys: [node.item.key] }) ?? true);\n const dragging = this.#nativeDragKeys.has(node.item.key);\n const state = this.#dropState;\n const dropTarget = state !== undefined && state.referenceKey === node.item.key;\n return {\n draggable,\n dragging,\n dropTarget,\n dropPosition: dropTarget ? state!.position : undefined,\n dropDepth: dropTarget ? state!.depth : undefined,\n };\n }\n\n protected _renderNode(node: TreeNode, depth: number): TemplateResult {\n const selected = this._isSelected(node);\n const tickled = this._isFocused(node);\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n const isPending = this.#pendingNode === node;\n const isLeaving = this._isLeaving(node);\n\n const dnd = this._dndRowState(node);\n\n return html`\n <li\n class=\"item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${isLeaving ? `leaving` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}\"\n role=\"treeitem\"\n aria-selected=${selected}\n aria-expanded=${isBranch ? isExpanded : nothing}\n aria-hidden=${isLeaving ? `true` : nothing}\n aria-level=${depth + 1}\n aria-setsize=${this._ariaSetInfo(node)?.setSize ?? nothing}\n aria-posinset=${this._ariaSetInfo(node)?.posInSet ?? nothing}\n data-key=${node.item.key}\n style=${`--depth: ${depth}`}\n draggable=${dnd.draggable ? `true` : nothing}\n part=${dnd.dropTarget ? `drop-target` : nothing}\n @click=${(e: MouseEvent) => this._handleItemClick(node, depth, e)}\n @pointerenter=${() => {\n this.tickled.handlePointerEnter(node.item.key);\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n }}\n >\n ${dnd.dropTarget && (dnd.dropPosition === `before` || dnd.dropPosition === `after`)\n ? html`<div\n class=\"drop-line drop-line-${dnd.dropPosition}\"\n style=\"--drop-depth: ${dnd.dropDepth ?? depth}\"\n part=\"drop-indicator\"\n ></div>`\n : nothing}\n ${this.renderNodeContent(node, depth)}\n ${isPending ? this.renderLoadingIndicator() : nothing}\n </li>\n `;\n }\n\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n listSearchStyles,\n css`\n :host {\n --tree-bg: var(--surface-3);\n --tree-text: var(--surface-3-text);\n --tree-muted-text: var(--surface-muted-text);\n --tree-indent: 1ch;\n --tree-item-height: 30px;\n /* Margin above each row. A windowed list is positioned by (height + gap), so keep it in px. */\n --tree-item-gap: 1px;\n --tree-caret-size: 30px;\n --tree-radius: var(--radius-s);\n --tree-drop-line: var(--accent);\n --tree-drop-nub-size: 5px;\n --tree-drop-into-outline: 2px solid var(--accent);\n --tree-drop-into-bg: color-mix(in srgb, var(--accent) 14%, transparent);\n --tree-sticky-bg: var(--tree-bg);\n --tree-sticky-border: var(--border, transparent);\n --tree-sticky-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);\n\n position: relative;\n display: block;\n overflow: hidden;\n box-sizing: border-box;\n background: var(--tree-bg);\n color: var(--tree-text);\n }\n\n /* min-height (not height) so the tree still grows to its content when the\n host has no explicit height; when it does, this fills it and scrolls.\n The scroll lives here, not on :host, so the search popover (a sibling of\n #container, positioned against :host) stays put while the list scrolls. */\n #container {\n /* offsetParent for rows: row offsets are scroll-independent (sticky / DnD geometry). */\n position: relative;\n outline: none;\n min-height: 100%;\n max-height: 100%;\n overflow: auto;\n }\n\n .tree-list {\n list-style: none;\n margin: 0;\n padding: var(--space-xs);\n }\n\n /* VS Code-style sticky headers: ancestors of the top-visible row, pinned\n to the top of the scroll container. Rows reuse the item class for\n identical metrics; the overlay itself is opaque so rows slide under it. */\n .sticky-headers {\n position: sticky;\n top: 0;\n z-index: 5;\n background: var(--tree-sticky-bg);\n border-bottom: 1px solid var(--tree-sticky-border);\n box-shadow: var(--tree-sticky-shadow);\n }\n\n .sticky-header {\n margin: 0;\n border-radius: 0;\n }\n\n .sticky-header:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: -2px;\n }\n\n .item {\n position: relative; /* anchor for the .drop-line before/after indicator */\n display: flex;\n align-items: center;\n height: var(--tree-item-height);\n padding-left: calc(var(--tree-indent) * var(--depth, 0));\n cursor: pointer;\n user-select: none;\n font-family: var(--font-family);\n font-size: var(--text-m);\n border-radius: var(--tree-radius);\n transition: background var(--transition, 0.15s ease-out);\n margin: var(--tree-item-gap) 0;\n }\n\n /* Windowed list: rows are placed purely by stride arithmetic — a margin above\n each row only (no collapsing), spacers hold the offscreen height. */\n .tree-list.virtual .item {\n margin: var(--tree-item-gap) 0 0;\n }\n\n .virtual-spacer {\n display: block;\n margin: 0;\n padding: 0;\n list-style: none;\n pointer-events: none;\n }\n\n .sticky-anchor {\n display: contents;\n }\n\n :host([data-virtual]) .sticky-anchor {\n position: sticky;\n top: 0;\n z-index: 5;\n display: block;\n height: 0;\n }\n\n :host([data-virtual]) .sticky-headers {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n }\n\n .tree-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Deliberately narrower than the icon: Lucide chevrons fill only ~half\n their viewBox, so letting the glyph overflow a slim box closes the\n visual gap to the label without shifting the indent. */\n width: calc(var(--tree-caret-size) * 0.5);\n height: var(--tree-caret-size);\n flex-shrink: 0;\n margin-right: 1px;\n overflow: visible;\n }\n\n .caret-icon {\n width: var(--tree-caret-size);\n height: var(--tree-caret-size);\n color: var(--tree-muted-text);\n transition: transform var(--transition, 0.15s ease-out);\n }\n\n .item.selected .caret-icon {\n color: var(--accent-text);\n }\n\n .tree-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tree-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-m);\n }\n\n .loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--surface-5);\n border-top-color: var(--accent);\n border-radius: 50%;\n animation: tree-spin 0.7s linear infinite;\n }\n\n @keyframes tree-spin {\n to { transform: rotate(360deg); }\n }\n\n /* Fading-out ghost row (see #runItemAnimations) — inert while it collapses. */\n .item.leaving {\n pointer-events: none;\n overflow: hidden;\n }\n\n /* Drag and drop styles */\n .item.dragging {\n opacity: 0.4;\n }\n\n .item.drop-into {\n outline: var(--tree-drop-into-outline);\n outline-offset: -2px;\n background: var(--tree-drop-into-bg);\n }\n\n .drop-line {\n position: absolute;\n left: calc(var(--tree-indent) * var(--drop-depth, 0) + var(--space-xs));\n right: var(--space-xs);\n height: 2px;\n background: var(--tree-drop-line);\n pointer-events: none;\n z-index: 10;\n }\n\n /* Nub at the left end of the insertion line (VS Code style). */\n .drop-line::before {\n content: \"\";\n position: absolute;\n left: calc(-1 * var(--tree-drop-nub-size) / 2);\n top: calc(50% - var(--tree-drop-nub-size) / 2);\n width: var(--tree-drop-nub-size);\n height: var(--tree-drop-nub-size);\n border-radius: 50%;\n background: var(--tree-drop-line);\n }\n\n .drop-line-before {\n top: -1px;\n }\n\n .drop-line-after {\n bottom: -1px;\n }\n\n :host([data-drop-rejected]) {\n cursor: not-allowed;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-tree-base': TreeBaseElement;\n }\n}\n\nexport interface TreeBaseElementEventMap extends TreeComponentEventMap {\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'list-native-drag-start': CustomEvent<ListNativeDragStartDetail<TreeNode>>;\n 'tree-drag-start': TreeDragStartEvent;\n 'tree-drag-over': TreeDragOverEvent;\n 'tree-drop': TreeDropEvent;\n 'tree-drag-end': TreeDragEndEvent;\n}\n\nexport interface TreeBaseElement {\n addEventListener: (<K extends keyof TreeBaseElementEventMap>(\n type: K,\n listener: (this: TreeBaseElement, event: TreeBaseElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n removeEventListener: (<K extends keyof TreeBaseElementEventMap>(\n type: K,\n listener: (this: TreeBaseElement, event: TreeBaseElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues, TemplateResult } from 'lit';\nimport type { TreeBaseElementEventMap } from './tree-base.js';\nimport type { TreeCheckboxState } from './tree-flat.js';\nimport type { TreeNode } from './types.js';\nimport { css, html, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { TreeBaseElement } from './tree-base.js';\nimport { computeCheckboxStates } from './tree-flat.js';\n\nexport type { TreeCheckboxState };\n\n@customElement(`ixfx-tree-list`)\nexport class TreeListElement extends TreeBaseElement {\n /**\n * Optional renderer for the checkbox shown in `checked` interactionMode.\n * Receives the node's current tri-state (`checked` / `unchecked` / `indeterminate`,\n * the latter when some but not all descendants are selected) and returns a Lit\n * template.\n *\n * When set, the checkbox becomes a `<span role=\"checkbox\">` whose contents are\n * whatever this returns. When unset, a native `<input type=\"checkbox\">` is used.\n *\n * @example\n * list.checkboxRenderer = (state) => state === `unchecked`\n * ? html``\n * : html`<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\"\n * fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n * stroke-linecap=\"round\" stroke-linejoin=\"round\"\n * style=\"opacity:${state === `indeterminate` ? 0.35 : 0.6}\">\n * <polyline points=\"3,8 7,12 13,4\" />\n * </svg>`;\n */\n @property({ attribute: false })\n checkboxRenderer: ((state: TreeCheckboxState) => unknown) | undefined;\n\n /** Checkbox tri-states for the whole loaded tree, rebuilt only when the structure or selection changes. */\n #checkboxCache: {\n root: TreeNode;\n structureVersion: number;\n selectionVersion: number;\n states: ReadonlyMap<string, TreeCheckboxState>;\n } | undefined;\n\n override willUpdate(changedProps: PropertyValues) {\n super.willUpdate(changedProps);\n this.#syncCheckboxStates();\n }\n\n #syncCheckboxStates(): void {\n const root = this.root;\n if (this.interactionMode !== `checked` || !root) {\n this.#checkboxCache = undefined;\n return;\n }\n const c = this.#checkboxCache;\n if (c && c.root === root && c.structureVersion === this._structureVersion && c.selectionVersion === this._selectionVersion)\n return;\n this.#checkboxCache = {\n root,\n structureVersion: this._structureVersion,\n selectionVersion: this._selectionVersion,\n states: computeCheckboxStates(root, this._selectedNodes),\n };\n }\n\n protected override renderNodeContent(node: TreeNode, depth: number): TemplateResult {\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n const icon = node.item.icon;\n const tooltip = node.item.tooltip;\n\n const caretAndLabel = html`\n <span class=\"tree-caret\">\n ${isBranch ? html`<ixfx-icon class=\"caret-icon\" name=\"chevron-down\" .rotate=${isExpanded ? nothing : `-90deg`}></ixfx-icon>` : ``}\n </span>\n ${icon ? html`<ixfx-icon class=\"tree-icon\" name=\"${icon}\"></ixfx-icon>` : nothing}\n <span class=\"tree-label\">\n ${node.item.label}\n ${tooltip ? html`<ixfx-tooltip class=\"tree-tooltip\" anchor=\"--tooltip-tree-${node.item.key}\" .value=${tooltip}></ixfx-tooltip>` : nothing}\n </span>\n `;\n\n if (this.interactionMode === `checked`) {\n const state = this.#checkboxCache?.states.get(node.item.key) ?? `unchecked`;\n return html`${this.#renderCheckbox(node, depth, state)}${caretAndLabel}`;\n }\n\n return caretAndLabel;\n }\n\n #renderCheckbox(node: TreeNode, depth: number, state: TreeCheckboxState): TemplateResult {\n const onClick = (e: MouseEvent) => this._handleCheckboxClick(e, node, depth);\n\n if (this.checkboxRenderer) {\n const ariaChecked = state === `indeterminate` ? `mixed` : state === `checked` ? `true` : `false`;\n return html`\n <span\n class=\"tree-checkbox tree-checkbox-custom\"\n part=\"checkbox\"\n role=\"checkbox\"\n tabindex=\"-1\"\n aria-checked=${ariaChecked}\n aria-label=\"Select ${node.item.label}\"\n @click=${onClick}\n >${this.checkboxRenderer(state)}</span>`;\n }\n\n return html`\n <input\n type=\"checkbox\"\n class=\"tree-checkbox\"\n part=\"checkbox\"\n .checked=${state === `checked`}\n .indeterminate=${state === `indeterminate`}\n aria-label=\"Select ${node.item.label}\"\n @click=${onClick}\n />`;\n }\n\n protected override _renderNode(node: TreeNode, depth: number): TemplateResult {\n const selected = this._isSelected(node);\n const tickled = this._isFocused(node);\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n const isPending = this._pendingNode === node;\n const hasIconAtDepth = this._depthsWithIcons.has(depth);\n const isLeaving = this._isLeaving(node);\n\n const dnd = this._dndRowState(node);\n\n return html`\n <li\n class=\"item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${dnd.dragging ? `dragging` : ``} ${dnd.dropTarget && dnd.dropPosition === `inside` ? `drop-into` : ``}\"\n data-key=${node.item.key}\n role=\"treeitem\"\n aria-selected=${selected}\n aria-expanded=${isBranch ? isExpanded : nothing}\n aria-hidden=${isLeaving ? `true` : nothing}\n aria-level=${depth + 1}\n aria-setsize=${this._ariaSetInfo(node)?.setSize ?? nothing}\n aria-posinset=${this._ariaSetInfo(node)?.posInSet ?? nothing}\n style=${`--depth: ${depth}`}\n draggable=${dnd.draggable ? `true` : nothing}\n part=${dnd.dropTarget ? `drop-target` : nothing}\n @click=${(e: MouseEvent) => this._handleItemClick(node, depth, e)}\n @pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}\n >\n ${dnd.dropTarget && (dnd.dropPosition === `before` || dnd.dropPosition === `after`)\n ? html`<div\n class=\"drop-line drop-line-${dnd.dropPosition}\"\n style=\"--drop-depth: ${dnd.dropDepth ?? depth}\"\n part=\"drop-indicator\"\n ></div>`\n : nothing}\n ${this.renderNodeContent(node, depth)}\n ${isPending ? this.renderLoadingIndicator() : nothing}\n </li>\n `;\n }\n\n static override styles = [\n themeFallbacks,\n ...TreeBaseElement.styles,\n css`\n .tree-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Deliberately narrower than the icon: Lucide chevrons fill only ~half\n their viewBox, so letting the glyph overflow a slim box closes the\n visual gap to the label without shifting the indent. */\n width: calc(var(--tree-caret-size) * 0.5);\n height: var(--tree-caret-size);\n flex-shrink: 0;\n margin-right: 1px;\n overflow: visible;\n }\n\n .caret-icon {\n width: var(--tree-caret-size);\n height: var(--tree-caret-size);\n color: var(--tree-muted-text);\n transition: transform var(--transition, 0.15s ease-out);\n }\n\n .item.selected .caret-icon {\n color: var(--accent-text);\n }\n\n .tree-icon {\n flex-shrink: 0;\n width: var(--icon-size, 1em);\n height: var(--icon-size, 1em);\n margin-right: var(--icon-spacing, 0px);\n }\n\n .item:not(.has-icon-at-depth) .tree-icon {\n display: none;\n }\n\n .item.has-icon-at-depth .tree-label {\n margin-left: var(--icon-size, 1em);\n }\n\n .tree-tooltip {\n position: absolute;\n anchor-name: --tooltip-tree;\n }\n\n .tree-checkbox {\n flex-shrink: 0;\n margin-right: var(--space-xs, 3px);\n cursor: pointer;\n accent-color: var(--accent);\n pointer-events: auto;\n }\n\n .tree-checkbox-custom {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Reserves a click target even when the renderer returns empty content\n (e.g. the \"nothing when unchecked\" subtle style) — without an explicit\n size the empty span collapses to 0×0 and becomes unclickable. */\n width: var(--tree-checkbox-size, 14px);\n height: var(--tree-checkbox-size, 14px);\n }\n\n /* In checked mode the checkbox communicates selection state —\n suppress the row highlight so it doesn't double-signal */\n :host([interaction-mode=\"checked\"]) .item.selected {\n background: transparent;\n color: inherit;\n outline: none;\n }\n\n \n\n .tree-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n position: relative;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-tree-list': TreeListElement;\n }\n}\n\nexport interface TreeListElement {\n addEventListener: (<K extends keyof TreeBaseElementEventMap>(\n type: K,\n listener: (this: TreeListElement, event: TreeBaseElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import type { TraversableTree } from '@ixfx/collections';\nimport type { TreeBaseElement } from './tree-base.js';\nimport type { TreeItem, TreeNode } from './types.js';\n\nexport type TreeControllerOptions<T> = {\n valueToItem: (value: T, node: TraversableTree<T>) => TreeItem;\n};\n\nexport class TreeController<T> {\n #root: TraversableTree<T>;\n #element: TreeBaseElement;\n #options: TreeControllerOptions<T>;\n\n #nodeToTree = new WeakMap<TreeNode, TraversableTree<T>>();\n #identityToTreeNode = new Map<unknown, TraversableTree<T>>();\n\n #connectSignal: AbortController | undefined;\n\n constructor(\n root: TraversableTree<T>,\n element: TreeBaseElement,\n options: TreeControllerOptions<T>,\n ) {\n this.#root = root;\n this.#element = element;\n this.#options = options;\n }\n\n connect() {\n this.disconnect();\n this.#connectSignal = new AbortController();\n const { signal } = this.#connectSignal;\n\n const rootValue = this.#root.getValue();\n const rootItem = this.#options.valueToItem(rootValue, this.#root);\n const rootChildren = this.#childrenOf(this.#root);\n\n this.#element.root = { item: rootItem, children: rootChildren };\n\n this.#element.addEventListener(`expand`, (e: Event) => {\n const { node } = (e as CustomEvent<{ node: TreeNode }>).detail;\n const treeNode = this.#nodeToTree.get(node);\n if (!treeNode)\n return;\n node.children = this.#childrenOf(treeNode);\n this.#element.invalidateStructure();\n }, { signal });\n\n this.#element.addEventListener(`collapse`, (_e: Event) => {\n }, { signal });\n }\n\n disconnect() {\n this.#connectSignal?.abort();\n this.#connectSignal = undefined;\n }\n\n navigateToValue(predicate: (value: T) => boolean): boolean {\n const treePath = this.#findTreePath(this.#root, predicate);\n if (!treePath)\n return false;\n\n let currentColumn = this.#element.root?.children ?? [];\n const keys: string[] = [];\n\n for (let i = 1; i < treePath.length; i++) {\n const treeNode = treePath[i];\n const key = this.#options.valueToItem(treeNode.getValue(), treeNode).key;\n keys.push(key);\n\n if (i < treePath.length - 1) {\n const node = currentColumn.find(n => n.item.key === key);\n if (!node)\n return false;\n\n if (node.children === undefined) {\n const mapped = this.#nodeToTree.get(node);\n if (mapped) {\n node.children = this.#childrenOf(mapped);\n this.#element.invalidateStructure();\n }\n }\n currentColumn = node.children ?? [];\n }\n }\n\n return this.#element.navigateTo(keys);\n }\n\n #childrenOf(treeNode: TraversableTree<T>): TreeNode[] {\n return Array.from(treeNode.children(), child => this.#toTreeNode(child));\n }\n\n #toTreeNode(treeNode: TraversableTree<T>): TreeNode {\n const value = treeNode.getValue();\n const childList = [...treeNode.children()];\n const userItem = this.#options.valueToItem(value, treeNode);\n\n const isLeaf = userItem.isLeaf ?? childList.length === 0;\n\n const treeNodeMap: TreeNode = {\n item: { ...userItem, isLeaf },\n };\n\n this.#nodeToTree.set(treeNodeMap, treeNode);\n this.#identityToTreeNode.set(treeNode.getIdentity(), treeNode);\n return treeNodeMap;\n }\n\n #findTreePath(\n node: TraversableTree<T>,\n predicate: (value: T) => boolean,\n ancestors: Array<TraversableTree<T>> = [],\n ): Array<TraversableTree<T>> | undefined {\n const path = [...ancestors, node];\n if (predicate(node.getValue()))\n return path;\n for (const child of node.children()) {\n const result = this.#findTreePath(child, predicate, path);\n if (result)\n return result;\n }\n return undefined;\n }\n}\n"],"mappings":"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"}
|