@ixfx/components 0.11.4 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +442 -120
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +2230 -538
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.d.ts +1 -1
- package/dist/{ac-token-TCLAZeVg.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
- package/dist/{ac-token-TCLAZeVg.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
- package/dist/ac-token.d.ts +1 -1
- package/dist/{button-CTL45aBl.d.ts → button-BYuf72aR.d.ts} +2 -2
- package/dist/{button-CTL45aBl.d.ts.map → button-BYuf72aR.d.ts.map} +1 -1
- package/dist/button.d.ts +1 -1
- package/dist/colour-picker.d.ts +1 -1
- package/dist/crumbs.d.ts +3 -3
- package/dist/{data-grid-CfiaBqTA.d.ts → data-grid-CPsJBnL4.d.ts} +48 -6
- package/dist/data-grid-CPsJBnL4.d.ts.map +1 -0
- package/dist/data-grid.d.ts +3 -3
- package/dist/data-grid.js +66 -2
- package/dist/data-grid.js.map +1 -1
- package/dist/{detail-list-DxQZkK-C.d.ts → detail-list-CmdCxddo.d.ts} +22 -5
- package/dist/detail-list-CmdCxddo.d.ts.map +1 -0
- package/dist/detail-list.d.ts +3 -3
- package/dist/detail-list.js +67 -4
- package/dist/detail-list.js.map +1 -1
- package/dist/{grid-list-k89JpiNy.js → grid-list-3fGhdaFA.js} +92 -7
- package/dist/grid-list-3fGhdaFA.js.map +1 -0
- package/dist/{grid-list-ChgYpUUq.d.ts → grid-list-D6AfWfwn.d.ts} +27 -4
- package/dist/grid-list-D6AfWfwn.d.ts.map +1 -0
- package/dist/grid-list.d.ts +2 -2
- package/dist/grid-list.js +1 -1
- package/dist/{grouped-item-lister-Bhyo-dkH.d.ts → grouped-item-lister-DETte0Dh.d.ts} +2 -2
- package/dist/{grouped-item-lister-Bhyo-dkH.d.ts.map → grouped-item-lister-DETte0Dh.d.ts.map} +1 -1
- package/dist/grouped-item-lister.d.ts +1 -1
- package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +2 -2
- package/dist/icon-CDGprSdE.d.ts.map +1 -0
- package/dist/icons.d.ts +2 -2
- package/dist/incr-search.d.ts +1 -1
- package/dist/{index-CHbuPyLL.d.ts → index-CMsmZ6Or.d.ts} +4 -4
- package/dist/{index-CHbuPyLL.d.ts.map → index-CMsmZ6Or.d.ts.map} +1 -1
- package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +2 -2
- package/dist/{index-garxxqgV.d.ts.map → index-CYndvTWH.d.ts.map} +1 -1
- package/dist/{index-CDllxjVG.d.ts → index-CnyoNA6m.d.ts} +4 -4
- package/dist/{index-CDllxjVG.d.ts.map → index-CnyoNA6m.d.ts.map} +1 -1
- package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
- package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
- package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +2 -2
- package/dist/{index-CJ5fshD3.d.ts.map → index-UvnoZUAo.d.ts.map} +1 -1
- package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -2
- package/dist/{index-BOUaDIW-.d.ts.map → index-tq6f8007.d.ts.map} +1 -1
- package/dist/index.d.ts +337 -140
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2036 -644
- package/dist/index.js.map +1 -1
- package/dist/item-appearance-BjcMyauw.js +31 -0
- package/dist/item-appearance-BjcMyauw.js.map +1 -0
- package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
- package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
- package/dist/labelled-radial-input.d.ts +2 -2
- package/dist/labelled-radial-input.d.ts.map +1 -1
- package/dist/labelled-range-input.d.ts +1 -1
- package/dist/labelled-slider-input.d.ts +1 -1
- package/dist/{list-native-drag-controller-B9reY4uM.d.ts → list-native-drag-controller-CllsHLxw.d.ts} +2 -2
- package/dist/{list-native-drag-controller-B9reY4uM.d.ts.map → list-native-drag-controller-CllsHLxw.d.ts.map} +1 -1
- package/dist/{menu-item-DlxAb0Xr.d.ts → menu-item-DT7bKAIw.d.ts} +2 -2
- package/dist/{menu-item-DlxAb0Xr.d.ts.map → menu-item-DT7bKAIw.d.ts.map} +1 -1
- package/dist/menu.d.ts +2 -2
- package/dist/miller.d.ts +3 -3
- package/dist/miller.d.ts.map +1 -1
- package/dist/miller.js +18 -2
- package/dist/miller.js.map +1 -1
- package/dist/panel.d.ts +1 -1
- package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-JK3xWVX2.d.ts} +2 -2
- package/dist/{split-layout-C5SYbDrq.d.ts.map → split-layout-JK3xWVX2.d.ts.map} +1 -1
- package/dist/split-layout.d.ts +1 -1
- package/dist/{tab-list-v8mKX7Fu.d.ts → tab-list-pqfKaVAE.d.ts} +2 -2
- package/dist/{tab-list-v8mKX7Fu.d.ts.map → tab-list-pqfKaVAE.d.ts.map} +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +2 -2
- package/dist/{titlebar-B5zSTZnF.d.ts.map → titlebar-Tqu-VvMU.d.ts.map} +1 -1
- package/dist/titlebar.d.ts +1 -1
- package/dist/{tree-component-CMGeqyjZ.d.ts → tree-component-DukLqesg.d.ts} +2 -2
- package/dist/{tree-component-CMGeqyjZ.d.ts.map → tree-component-DukLqesg.d.ts.map} +1 -1
- package/dist/tree.d.ts +4 -4
- package/dist/{types-3Jfcaxvo.d.ts → types-D-kYF16b.d.ts} +21 -1
- package/dist/types-D-kYF16b.d.ts.map +1 -0
- package/dist/{vertical-list-R25WqAVO.d.ts → vertical-list-DTp-UIUE.d.ts} +26 -3
- package/dist/vertical-list-DTp-UIUE.d.ts.map +1 -0
- package/dist/vertical-list.d.ts +2 -2
- package/dist/vertical-list.js +53 -4
- package/dist/vertical-list.js.map +1 -1
- package/docs-user/data-grid.md +51 -1
- package/docs-user/detail-list.md +46 -0
- package/docs-user/grid-list.md +49 -2
- package/docs-user/hyperbolic-tree.md +98 -18
- package/docs-user/index.json +2 -2
- package/docs-user/miller.md +52 -7
- package/docs-user/vertical-list.md +63 -0
- package/package.json +1 -1
- package/dist/data-grid-CfiaBqTA.d.ts.map +0 -1
- package/dist/detail-list-DxQZkK-C.d.ts.map +0 -1
- package/dist/grid-list-ChgYpUUq.d.ts.map +0 -1
- package/dist/grid-list-k89JpiNy.js.map +0 -1
- package/dist/icon-DR_3rSyZ.d.ts.map +0 -1
- package/dist/types-3Jfcaxvo.d.ts.map +0 -1
- package/dist/vertical-list-R25WqAVO.d.ts.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#collapsedDragging","#dragStartY","#dragStartHeight","#onTabPointerMove","#onTabPointerUp","#displayHeight","#onResizeMove","#onResizeEnd","#maxHeight","#setHeight","#syncCommands","#teardownCommands","#ownedRegistry","#commandTarget","#commandName","#commandIds","#morphProgress","#dragOpacity","#onDrawerKeyDown","#onResizeStart","#onResizeKeyDown","customElement","#updateComputedItems","#handleToggleChange","#handleRadioChange","customElement","#handleArrowDown","#handleArrowUp","#handleArrowRight","#handleArrowLeft","#handleEnter","customElement","#separator","#onQuery","#sortCompare","#pathed","#element","#siblingLookup","#segmentIconLookup","#cleanupPending","#closeDropdown","#scrollDropdownActiveIntoView","#selectSibling","#uid","#getSegments","#anchorName","#pendingController","#pendingIndex","#getRootSegments","#clickSuppressUntil","#segmentDragPayloads","#clicksSuppressed","#onSiblingClick","#getCumulativePath","#resolveFullPathSegments","#resolveSegmentIcon","#onSegmentClick","#onSegDragOver","#onSegDragLeave","#onSegDrop","#onLabelClick","#onLabelDragStart","#onLabelDragEnd","#onCaretClick","#onRootSegmentClick","#dispatchChangeEvent","#makeCompletionProvider","#onAcChange","#onAcFocusOut","#onAcKeyDown","#onHostKeyDown","#renderRootSegment","#renderSegment","#onTrailingClick","#onPopoverToggle","#onDropdownKeyDown","#renderDropdownContent","customElement","#resizeObserver","#lastWidth","#updateStacked","#detailTimer","#handlePointerLeave","#handlePointerEnter","#select","customElement","customElement","DRAG_THRESHOLD_PX","customElement","DRAG_THRESHOLD_PX","customElement","#layout","#effectiveRoot","#effectiveCenter","#ownedRegistry","#syncSearchCommands","#modelUnsubscribe","#aborters","#pendingKeys","#animFrame","#effectiveSearchModes","#unregisterSearchCommands","#resetViewState","#ensureVisibleChildren","#clearSelectionInternal","#loadChildren","#canSelect","#dispatchSelect","#animateTo","#prefersReducedMotion","#findKeyPath","#matchesFilter","#focusAndMaybeSelect","#isBackgroundTarget","#panStart","#defaultEdgeRenderer","#nodeRenderRadius","#handleItemClick","#handleItemDblClick","#computeLabelKeys","#handleKeyDown","#handleBackgroundPointerDown","#handleBackgroundPointerMove","#handleBackgroundPointerUp","#renderEdge","#renderNode","customElement","#rects","#effectiveRoot","#ownedRegistry","#syncSearchCommands","#resizeObserver","#modelUnsubscribe","#aborters","#pendingKeys","#effectiveSearchModes","#unregisterSearchCommands","#resetViewState","#anchorIndex","#ensureVisibleChildren","#syncTooltip","#hostExtent","#labelMode","#clearSelectionInternal","#loadChildren","#canSelect","#dispatchSelect","#findKeyPath","#resolveKeyPath","#matchesFilter","#canZoom","#onCrumbSelect","#handleItemClick","#handleItemDblClick","#handleKeyDown","#renderBreadcrumb","#renderRect","customElement","#category","#categoryDefaults","#selectionMode","#dataProvider","#onSelectionChange","#onRequestData","#state","#repush","#syncGrouping","#subComponents","#host","#allSelected","#setAllSelection","#allRow","#handleSelect","#listerEl","#syncAllRow","#lastItems","#pushItems","#restoreAfterSync","#abortPending","#abortController","#applyItems","#selectedValues","#syncingSelection","#createController","#categoryToNode","#openMenuAt","#menuItem","#insertColumn","customElement","DRAG_THRESHOLD_PX","customElement","#scaleTo100","#userMin","#userMax","#scaleFrom100","#userClamp","#updateScale","customElement","customElement","#dragging","#dragStartY","#lastPointerY","#valueAtDragStart","#lastSetValue","#onPointerMove","#onPointerUp","#setValueFromRelative","#stepByRelativeDelta","#quantise","#getRelativeValue","#scheduleChangeEvent","#fireChangeEvent","#changeDebounceTimer","#onPointerDown","#onKeyDown","#renderRectangle","#renderCircle","customElement","customElement","customElement","#list","#panels","#opts","#commands","#signal","#onChange","#onReorder","#onClose","#observer","#rebuild","#tabs","#registerCommand","#unregisterCommand","#registeredCommands","#resolveTab","#selectOffset","#idsFor","#fillContent","#insertElement","#adjacentTab","#removeFromIndex","#reregisterCommand","#tabByItem","#slug","#uniqueId","#labelOf","#isSelected","#list","#unselect","#select","#findTabItem","#labelOf","customElement","customElement","customElement","customElement","normaliseValue","#rects","#effectiveRoot","#rectsForZoom","#cascadeFractions","#ownedRegistry","#syncSearchCommands","#resizeObserver","#modelUnsubscribe","#aborters","#pendingKeys","#effectiveSearchModes","#unregisterSearchCommands","#resetViewState","#anchorIndex","#ensureVisibleChildren","#pendingFlip","#applyFlip","#clearSelectionInternal","#loadChildren","#canSelect","#dispatchSelect","#planFlip","#findKeyPath","#resolveKeyPath","#matchesFilter","#rectCenter","#canZoom","#nearestInDirection","#wheelCooldownUntil","#zoomOutOneStep","#onCrumbSelect","#pixelSize","#categorySlug","#hideLabel","#categoryStyle","#handleItemClick","#handleItemDblClick","#canDescend","#renderNestedTile","#renderTileBox","#renderTile","#handleKeyDown","#handleWheel","#renderBreadcrumb","#renderTopTile","customElement","#elementBounds","#startSizeA","#startSizeB","#onResizeHandleUp","#onResizeHandleMove","#collapsedAPointerAtCollapse","#hysteresisThreshold","#dispatchCollapsedEvent","#applyConstraints","#collapsedBPointerAtCollapse","#cornerStartX","#cornerStartY","#getNestedSplit","#nestedSplitInitialSizeA","#nestedSplitBounds","#nestedHandleBounds","#onCornerResizeUp","#onCornerResizeMove","#parseSizeAsFraction","#pendingNestedUpdate","#applyPendingNestedUpdate","#observer","#setupNestedSplitObserver","#updateCornerPosition","#updateDataCollapsed","#checkForNestedSplit","#nestedSplit","#minSizeToFraction","#maxSizeToFraction","#parseSizeToPx","#getIntersectionPoint","#onCornerResizeDown","#onResizeHandleDown","customElement"],"sources":["../src/bottom-drawer/bottom-drawer.ts","../src/button/radio-group.ts","../src/interaction/tree-keyboard-controller.ts","../src/button/split-button.ts","../src/crumbs/crumb-path-controller.ts","../src/crumbs/crumb-path.ts","../src/data-table/data-table.ts","../src/dock/dock-drag.ts","../src/dock/dock-model.ts","../src/tabs/tab-list-item.ts","../src/dock/dock-panel.ts","../src/dock/dock-host.ts","../src/form/form-group.ts","../src/form/form-part.ts","../src/grouped-item-lister/tree-list-adapter.ts","../src/grouped-item-lister/vertical-list-adapter.ts","../src/hyperbolic-tree/poincare-math.ts","../src/hyperbolic-tree/layout.ts","../src/hyperbolic-tree/hyperbolictree-list.ts","../src/icicle-tree/layout.ts","../src/icicle-tree/icicletree-list.ts","../src/multicol-list/types.ts","../src/multicol-list/column.ts","../src/multicol-list/multicol-list.ts","../src/notifier/pill-renderer.ts","../src/notifier/manager.ts","../src/panel/panel-group.ts","../src/util/drag.ts","../src/util/near.ts","../src/range/range-multi.ts","../src/rating/rating.ts","../src/util/clamp.ts","../src/util/geometry.ts","../src/shapefill-value/shapefill-value.ts","../src/sliding-number/sliding-number.ts","../src/tabs/tab-panel.ts","../src/tabs/tab-controller.ts","../src/tabs/tab-panels.ts","../src/text-shimmer/text-shimmer.ts","../src/toolbar/toolbar-group.ts","../src/toolbar/toolbar.ts","../src/treemap/layout.ts","../src/treemap/treemap-list.ts","../src/twosplit-layout/split-layout.ts","../src/util/checkbox.ts","../src/index.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\n/**\n * `ixfx-bottom-drawer` — an overlay that slides up over the bottom of its\n * container. Place it as a **sibling** of the content it covers, inside a\n * positioned container:\n *\n * ```html\n * <div id=\"container\" style=\"position: relative; overflow: hidden\">\n * Some stuff\n * <ixfx-bottom-drawer label=\"Inspector\" open>Drawer contents</ixfx-bottom-drawer>\n * </div>\n * ```\n *\n * The element stretches to fill the nearest positioned ancestor and clips the\n * drawer as it slides; it is `pointer-events: none` except over the drawer\n * itself, so sibling content underneath stays interactive. The drawer can be\n * resized from its top edge.\n *\n * Slots\n * (default) – drawer body content\n * `toolbar` – header toolbar items, forwarded into the `ixfx-titlebar` toolbar\n *\n * Properties\n * `open` – whether the drawer is visible (default: false)\n * `height` – drawer height in px (default: 320)\n * `min-height` – minimum height before fade-out (default: 160)\n * `dismiss-threshold` – drag below this height closes the drawer (default: 96)\n * `max-height-ratio` – max height as a fraction of host height (default: 0.85)\n * `label` – header title and accessible label (default: `Drawer`)\n * `icon-name` – header icon (default: ``)\n * `closable` – show the header close button (default: true)\n * `collapsible` – show the expand/collapse caret that toggles `open` (default: true)\n * `maintain-handle` – keep a drag handle docked to the bottom when\n * collapsed so users can drag up to reopen. Dragging the drawer down\n * gradually morphs it into the handle (default: false)\n * `name` – command namespace. When set, `expand`/`collapse`/`toggle`\n * commands are registered as `<name>.expand` etc. (default: `` = no commands)\n * `registry` – `@clinth/ui-commands` registry carrying this drawer's\n * commands. Created automatically; assign a shared registry to trigger\n * named drawers globally (default: owned registry)\n *\n * The header is an `ixfx-titlebar`. Theme variables (e.g. `--surface-4`,\n * `--accent`) set on the drawer inherit into the header, and `toolbar`-slotted\n * content stays in the consumer's light DOM so it can be styled directly.\n *\n * Commands (require `name`; see {@link bottomDrawerCommandId})\n * `<name>.expand` – open the drawer (`show()`)\n * `<name>.collapse` – close the drawer (`close()`, fires `drawer-close`)\n * `<name>.toggle` – open if closed, close if open\n *\n * ```typescript\n * drawer.registry?.invoke('inspector.expand');\n * ```\n *\n * Events\n * `drawer-close` – CustomEvent<void>, bubbles + composed\n * `drawer-resize` – CustomEvent { detail: { height: number } }, bubbles + composed\n *\n * CSS variables\n * `--bottom-drawer-background` – drawer fill\n * `--bottom-drawer-border` – drawer border\n * `--bottom-drawer-radius` – top corner radius\n * `--bottom-drawer-blur` – backdrop blur amount\n * `--bottom-drawer-shadow` – drawer drop shadow\n * `--ixfx-handle-*` – resize-grip look (shared handle primitive; see\n * docs/infra-handle.md)\n * `--bottom-drawer-collapsed-width` – width of the floating pill shown\n * when collapsed with `maintain-handle` (default: 96px)\n * `--bottom-drawer-title-background` – header fill (default: transparent,\n * so the header shares the drawer's translucency)\n */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TitlebarCloseEvent, TitlebarToggleEvent } from '../titlebar/titlebar.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../titlebar/titlebar.js';\n\nexport type BottomDrawerResizeDetail = {\n readonly height: number;\n};\n\nexport type BottomDrawerResizeEvent = CustomEvent<BottomDrawerResizeDetail>;\nexport type BottomDrawerCloseEvent = CustomEvent<void>;\n\nexport interface BottomDrawerElementEventMap {\n 'drawer-close': BottomDrawerCloseEvent;\n 'drawer-resize': BottomDrawerResizeEvent;\n}\n\n/** Commands a named drawer registers, namespaced as `<name>.<command>`. */\nexport type BottomDrawerCommand = `expand` | `collapse` | `toggle`;\n\n/** Builds the command id for a named drawer's command, e.g. `inspector.expand`. */\nexport function bottomDrawerCommandId(name: string, command: BottomDrawerCommand): string {\n return `${name.trim()}.${command}`;\n}\n\nfunction clampRange(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n@customElement(`ixfx-bottom-drawer`)\nexport class BottomDrawerElement extends LitElement {\n static override styles = [themeFallbacks, handleStyles, css`\n :host {\n --bottom-drawer-background: color-mix(in srgb, var(--surface-2) 84%, transparent);\n --bottom-drawer-border: 1px solid color-mix(in srgb, var(--surface-2-text) 14%, transparent);\n --bottom-drawer-radius: var(--radius-l);\n --bottom-drawer-blur: 18px;\n --bottom-drawer-shadow: var(--shadow-l);\n --bottom-drawer-collapsed-width: 96px;\n\n display: block;\n position: absolute;\n inset: 0;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n pointer-events: none;\n }\n .drawer {\n --m: 0;\n position: absolute;\n z-index: 2;\n pointer-events: auto;\n right: calc(var(--m) * (50% - var(--bottom-drawer-collapsed-width) / 2));\n bottom: 0;\n left: calc(var(--m) * (50% - var(--bottom-drawer-collapsed-width) / 2));\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n height: var(--bottom-drawer-height);\n max-height: 100%;\n min-height: 0;\n color: var(--surface-2-text);\n background: var(--bottom-drawer-background);\n border: var(--bottom-drawer-border);\n border-bottom: 0;\n border-radius: var(--bottom-drawer-radius) var(--bottom-drawer-radius) 0 0;\n box-shadow: var(--bottom-drawer-shadow);\n backdrop-filter: blur(var(--bottom-drawer-blur)) saturate(1.15);\n -webkit-backdrop-filter: blur(var(--bottom-drawer-blur)) saturate(1.15);\n opacity: 0;\n transform: translateY(100%);\n visibility: hidden;\n transition:\n transform var(--transition),\n opacity var(--transition),\n left var(--transition),\n right var(--transition),\n height var(--transition),\n visibility 0s linear 0.16s;\n will-change: transform, opacity;\n }\n :host([open]) .drawer {\n opacity: var(--bottom-drawer-opacity, 1);\n transform: translateY(0);\n visibility: visible;\n transition:\n transform var(--transition),\n opacity var(--transition),\n left var(--transition),\n right var(--transition),\n height var(--transition);\n }\n :host([resizing]) {\n cursor: ns-resize;\n user-select: none;\n }\n :host([resizing]) .drawer {\n transition: none;\n }\n .resize-edge {\n position: absolute;\n z-index: 1;\n top: -5px;\n right: 0;\n left: 0;\n height: 11px;\n cursor: ns-resize;\n touch-action: none;\n outline: none;\n }\n .resize-edge .ixfx-handle {\n position: absolute;\n top: 7px;\n left: 50%;\n transform: translateX(-50%);\n --ixfx-handle-length: 44px;\n --ixfx-handle-thickness: 3px;\n --ixfx-handle-radius: 999px;\n }\n /* Inner content fades as the drawer morphs into its collapsed tab. */\n ixfx-titlebar,\n .body {\n opacity: calc(1 - var(--m, 0));\n transition: opacity var(--transition);\n }\n :host([resizing]) ixfx-titlebar,\n :host([resizing]) .body {\n transition: none;\n }\n /* Collapsed tab: docked to the bottom edge, narrowed to handle width. */\n :host([maintain-handle]:not([open])) .drawer {\n --m: 1;\n height: 20px;\n opacity: 1;\n transform: translateY(0);\n visibility: visible;\n transition:\n transform var(--transition),\n opacity var(--transition),\n left var(--transition),\n right var(--transition),\n height var(--transition);\n }\n :host([maintain-handle]:not([open])) ixfx-titlebar,\n :host([maintain-handle]:not([open])) .body {\n display: none;\n }\n :host([maintain-handle]:not([open])) .resize-edge {\n top: 0;\n height: 100%;\n }\n :host([maintain-handle]:not([open])) .resize-edge .ixfx-handle {\n top: 50%;\n transform: translate(-50%, -50%);\n }\n ixfx-titlebar {\n flex: none;\n --titlebar-background: var(--bottom-drawer-title-background, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--surface-2-text) 10%, transparent);\n }\n .body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n }\n .body ::slotted(*) {\n box-sizing: border-box;\n }\n @media (prefers-reduced-motion: reduce) {\n .drawer,\n ixfx-titlebar,\n .body {\n transition-duration: 0s;\n }\n }\n `];\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: Number })\n height = 320;\n\n @property({ type: Number, attribute: `min-height` })\n minHeight = 160;\n\n @property({ type: Number, attribute: `dismiss-threshold` })\n dismissThreshold = 96;\n\n @property({ type: Number, attribute: `max-height-ratio` })\n maxHeightRatio = 0.85;\n\n @property({ type: String })\n label = `Drawer`;\n\n @property({ type: String, attribute: `icon-name` })\n iconName = ``;\n\n @property({ type: Boolean })\n closable = true;\n\n @property({ type: Boolean })\n collapsible = true;\n\n @property({ type: Boolean, attribute: `maintain-handle`, reflect: true })\n maintainHandle = false;\n\n @property({ type: String })\n name = ``;\n\n @property({ attribute: false })\n registry: CommandRegistry<unknown> | undefined;\n\n @state() private _dragHeight: number | undefined;\n\n #dragStartY = 0;\n #dragStartHeight = 0;\n #collapsedDragging = false;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #commandTarget: CommandRegistry<unknown> | undefined;\n #commandName = ``;\n #commandIds: string[] = [];\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#syncCommands();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#teardownCommands();\n if (this.#ownedRegistry !== undefined) {\n if (this.registry === this.#ownedRegistry)\n this.registry = undefined;\n this.#ownedRegistry = undefined;\n }\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n if (changed.has(`name`) || changed.has(`registry`))\n this.#syncCommands();\n }\n\n show(): void {\n this.open = true;\n }\n\n close(): void {\n if (!this.open)\n return;\n this.open = false;\n this.dispatchEvent(new CustomEvent<void>(`drawer-close`, { bubbles: true, composed: true }));\n }\n\n toggle(): void {\n if (this.open)\n this.close();\n else\n this.show();\n }\n\n #syncCommands(): void {\n const name = this.name.trim();\n const target = this.registry ?? this.#ownedRegistry;\n if (name !== `` && this.isConnected && target !== undefined\n && this.#commandTarget === target && this.#commandName === name) {\n return;\n }\n this.#teardownCommands();\n if (name === `` || !this.isConnected)\n return;\n const resolved = this.registry ?? (this.#ownedRegistry ??= createCommandRegistry());\n if (this.#ownedRegistry !== undefined && resolved !== this.#ownedRegistry)\n this.#ownedRegistry = undefined;\n if (this.registry === undefined)\n this.registry = resolved;\n const registered: string[] = [];\n const commands: Array<{ command: BottomDrawerCommand; label: string; description: string; execute: () => void }> = [\n { command: `expand`, label: `Expand ${this.label}`, description: `Open the ${this.label} drawer`, execute: () => this.show() },\n { command: `collapse`, label: `Collapse ${this.label}`, description: `Close the ${this.label} drawer`, execute: () => this.close() },\n { command: `toggle`, label: `Toggle ${this.label}`, description: `Open the ${this.label} drawer if closed, close it if open`, execute: () => this.toggle() },\n ];\n for (const { command, label, description, execute } of commands) {\n const id = bottomDrawerCommandId(name, command);\n if (resolved.has(id))\n continue;\n resolved.register({ id, label, description, execute });\n registered.push(id);\n }\n this.#commandTarget = resolved;\n this.#commandName = name;\n this.#commandIds = registered;\n }\n\n #teardownCommands(): void {\n if (this.#commandTarget !== undefined) {\n for (const id of this.#commandIds)\n this.#commandTarget.unregister(id);\n this.#commandTarget = undefined;\n this.#commandName = ``;\n this.#commandIds = [];\n }\n }\n\n private _onTitlebarToggle(event: TitlebarToggleEvent): void {\n event.stopPropagation();\n if (event.detail.collapsed)\n this.close();\n else\n this.open = true;\n }\n\n private _onTitlebarClose(event: TitlebarCloseEvent): void {\n event.stopPropagation();\n this.close();\n }\n\n protected override render(): ReturnType<typeof html> {\n const raw = this.#displayHeight();\n const max = this.#maxHeight();\n const morph = this.#morphProgress(raw);\n const height = this.open ? raw * (1 - morph) + 20 * morph : 20;\n const opacity = this.maintainHandle && this.open ? 1 : this.#dragOpacity(raw);\n return html`\n <section\n class=\"drawer\"\n style=${`--bottom-drawer-height: ${height}px; --bottom-drawer-opacity: ${opacity}; --m: ${morph}`}\n role=\"region\"\n aria-label=${this.label}\n @keydown=${this.#onDrawerKeyDown}\n >\n <div\n class=\"resize-edge\"\n role=\"separator\"\n tabindex=\"0\"\n aria-label=${`${this.open ? `Resize` : `Expand`} ${this.label}`}\n aria-orientation=\"horizontal\"\n aria-valuemin=${this.minHeight}\n aria-valuemax=${max}\n aria-valuenow=${Math.round(raw)}\n @pointerdown=${this.#onResizeStart}\n @keydown=${this.#onResizeKeyDown}\n ><span class=\"ixfx-handle\" data-handle=\"dimpled\" data-shape=\"horizontal\" part=\"handle\"></span></div>\n <ixfx-titlebar\n .title=${this.label}\n .iconName=${this.iconName}\n .closable=${this.maintainHandle ? false : this.closable}\n .collapsible=${this.maintainHandle ? this.collapsible : false}\n .collapsed=${!this.open}\n ?inert=${!this.open}\n @toggle=${this._onTitlebarToggle}\n @close=${this._onTitlebarClose}\n >\n <slot name=\"toolbar\" slot=\"toolbar\"></slot>\n </ixfx-titlebar>\n <div class=\"body\" ?inert=${!this.open}><slot></slot></div>\n </section>\n `;\n }\n\n #maxHeight(): number {\n const availableHeight = this.clientHeight || this.height;\n return Math.max(this.minHeight, availableHeight * clampRange(this.maxHeightRatio, 0, 1));\n }\n\n #displayHeight(): number {\n return clampRange(this._dragHeight ?? this.height, 0, this.#maxHeight());\n }\n\n #dragOpacity(height: number): number {\n if (this._dragHeight === undefined || height >= this.minHeight)\n return 1;\n const fadeRange = this.minHeight - this.dismissThreshold;\n if (fadeRange <= 0)\n return height >= this.dismissThreshold ? 1 : 0;\n return clampRange((height - this.dismissThreshold) / fadeRange, 0, 1);\n }\n\n #morphProgress(raw: number): number {\n if (!this.open)\n return this.maintainHandle ? 1 : 0;\n if (this._dragHeight === undefined || !this.maintainHandle)\n return 0;\n const range = this.minHeight - this.dismissThreshold;\n if (range <= 0)\n return raw < this.dismissThreshold ? 1 : 0;\n return clampRange((this.minHeight - raw) / range, 0, 1);\n }\n\n #setHeight(height: number): void {\n this.height = clampRange(height, this.minHeight, this.#maxHeight());\n this.dispatchEvent(new CustomEvent<BottomDrawerResizeDetail>(`drawer-resize`, {\n detail: { height: this.height },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onResizeStart = (event: PointerEvent): void => {\n if (event.button !== 0)\n return;\n event.preventDefault();\n const edge = event.currentTarget as HTMLElement;\n edge.setPointerCapture(event.pointerId);\n if (!this.open) {\n this.#collapsedDragging = false;\n this.#dragStartY = event.clientY;\n this.#dragStartHeight = this.dismissThreshold;\n edge.addEventListener(`pointermove`, this.#onTabPointerMove);\n edge.addEventListener(`pointerup`, this.#onTabPointerUp, { once: true });\n edge.addEventListener(`pointercancel`, this.#onTabPointerUp, { once: true });\n return;\n }\n this.#dragStartY = event.clientY;\n this.#dragStartHeight = this.#displayHeight();\n this._dragHeight = this.#dragStartHeight;\n this.toggleAttribute(`resizing`, true);\n edge.addEventListener(`pointermove`, this.#onResizeMove);\n edge.addEventListener(`pointerup`, this.#onResizeEnd, { once: true });\n edge.addEventListener(`pointercancel`, this.#onResizeEnd, { once: true });\n };\n\n #onResizeMove = (event: PointerEvent): void => {\n this._dragHeight = clampRange(this.#dragStartHeight + this.#dragStartY - event.clientY, 0, this.#maxHeight());\n };\n\n #onResizeEnd = (event: PointerEvent): void => {\n const edge = event.currentTarget as HTMLElement;\n edge.removeEventListener(`pointermove`, this.#onResizeMove);\n edge.removeEventListener(`pointerup`, this.#onResizeEnd);\n edge.removeEventListener(`pointercancel`, this.#onResizeEnd);\n if (edge.hasPointerCapture(event.pointerId))\n edge.releasePointerCapture(event.pointerId);\n this.toggleAttribute(`resizing`, false);\n const height = this._dragHeight ?? this.height;\n this._dragHeight = undefined;\n if (height < this.dismissThreshold) {\n this.close();\n return;\n }\n this.#setHeight(height);\n };\n\n #onResizeKeyDown = (event: KeyboardEvent): void => {\n if (!this.open) {\n if (event.key === `ArrowUp` || event.key === `Enter` || event.key === ` ` || event.key === `Home` || event.key === `End`) {\n event.preventDefault();\n this.show();\n }\n return;\n }\n const delta = event.shiftKey ? 64 : 16;\n if (event.key === `ArrowUp`) {\n event.preventDefault();\n this.#setHeight(this.height + delta);\n } else if (event.key === `ArrowDown`) {\n event.preventDefault();\n if (this.height - delta < this.dismissThreshold)\n this.close();\n else\n this.#setHeight(this.height - delta);\n } else if (event.key === `Home`) {\n event.preventDefault();\n this.#setHeight(this.minHeight);\n } else if (event.key === `End`) {\n event.preventDefault();\n this.#setHeight(this.#maxHeight());\n }\n };\n\n #onTabPointerMove = (event: PointerEvent): void => {\n const delta = this.#dragStartY - event.clientY;\n if (!this.#collapsedDragging) {\n if (delta < 4)\n return;\n this.#collapsedDragging = true;\n this.show();\n this.toggleAttribute(`resizing`, true);\n }\n this._dragHeight = clampRange(this.#dragStartHeight + this.#dragStartY - event.clientY, 0, this.#maxHeight());\n };\n\n #onTabPointerUp = (event: PointerEvent): void => {\n const target = event.currentTarget as HTMLElement;\n target.removeEventListener(`pointermove`, this.#onTabPointerMove);\n target.removeEventListener(`pointerup`, this.#onTabPointerUp);\n target.removeEventListener(`pointercancel`, this.#onTabPointerUp);\n if (target.hasPointerCapture(event.pointerId))\n target.releasePointerCapture(event.pointerId);\n if (!this.#collapsedDragging) {\n this.show();\n return;\n }\n this.#collapsedDragging = false;\n this.toggleAttribute(`resizing`, false);\n const height = this._dragHeight ?? this.height;\n this._dragHeight = undefined;\n if (height < this.dismissThreshold) {\n this.close();\n return;\n }\n this.#setHeight(height);\n };\n\n #onDrawerKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== `Escape`)\n return;\n event.preventDefault();\n event.stopPropagation();\n this.close();\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-bottom-drawer': BottomDrawerElement;\n }\n}\n\nexport interface BottomDrawerElement {\n addEventListener: (<K extends keyof BottomDrawerElementEventMap>(\n type: K,\n listener: (this: BottomDrawerElement, event: BottomDrawerElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import type { PropertyValues } from 'lit';\nimport { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../icons/icon.js';\n\nexport type RadioGroupMode = `compact` | `max`;\n\nexport type RadioItem = Readonly<{\n value: string;\n label: string;\n disabled?: boolean;\n iconName?: string;\n iconNameOff?: string;\n}>;\n\n@customElement(`ixfx-radio-group`)\nexport class RadioGroup extends LitElement {\n @property({ type: String }) value = ``;\n @property({ type: String }) orientation: `horizontal` | `vertical` = `horizontal`;\n @property({ type: Array }) items: RadioItem[] = [];\n @property({ type: String }) name = ``;\n @property({ type: String }) mode: RadioGroupMode = `compact`;\n @property({ type: Boolean }) checked = false;\n @property({ type: String, attribute: `value-off` }) valueOff = ``;\n @property({ type: String, attribute: `icon-name` }) iconName = ``;\n @property({ type: String, attribute: `icon-name-off` }) iconNameOff = ``;\n @property({ type: Boolean, attribute: `hide-labels` }) hideLabels = false;\n\n @state() private _computedItems: RadioItem[] = [];\n @state() private _icons: Map<string, string> = new Map();\n @query(`slot`) private _slot?: HTMLSlotElement;\n\n private get _isSingleToggle(): boolean {\n return this._computedItems.length === 0 && Boolean(this.textContent?.trim());\n }\n\n private get _singleToggleIconName(): string | null {\n if (!this.iconName && !this.iconNameOff)\n return null;\n return this.checked ? this.iconName : (this.iconNameOff || this.iconName);\n }\n\n protected override firstUpdated(): void {\n this.#updateComputedItems();\n }\n\n protected override updated(changedProperties: PropertyValues): void {\n if (changedProperties.has(`checked`)) {\n const input = this.shadowRoot?.querySelector(`.radio-toggle-input`) as HTMLInputElement | undefined;\n if (input && input.checked !== this.checked) {\n input.checked = this.checked;\n const newValue = this.checked\n ? (this.value || `on`)\n : (this.valueOff || undefined);\n\n this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n detail: { checked: this.checked, value: newValue },\n bubbles: true,\n composed: true,\n }));\n }\n }\n\n if (changedProperties.has(`value`) && !this._isSingleToggle) {\n const inputs = this.shadowRoot?.querySelectorAll(`.radio-input`) as NodeListOf<HTMLInputElement>;\n if (inputs) {\n for (const input of inputs) {\n if (input.checked !== (input.value === this.value)) {\n input.checked = input.value === this.value;\n }\n }\n }\n }\n }\n\n #updateComputedItems(): void {\n const options = this.querySelectorAll(`option`);\n const icons = new Map<string, string>();\n\n if (options.length > 0) {\n this._computedItems = Array.from(options, (el) => {\n const tempDiv = document.createElement(`div`);\n tempDiv.innerHTML = el.innerHTML;\n const iconEl = tempDiv.querySelector(`svg`);\n if (iconEl) {\n icons.set(el.getAttribute(`value`) || ``, iconEl.outerHTML);\n }\n return {\n value: el.getAttribute(`value`) || ``,\n label: el.textContent?.trim() || ``,\n disabled: el.hasAttribute(`disabled`),\n iconName: el.getAttribute(`icon-name`) || undefined,\n iconNameOff: el.getAttribute(`icon-name-off`) || undefined,\n };\n });\n this._icons = icons;\n } else {\n this._computedItems = [...this.items];\n }\n }\n\n // #handleItemClick(item: RadioItem): void {\n // if (item.disabled || item.value === this.value)\n // return;\n\n // this.value = item.value;\n // this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n // detail: { checked: true, value: item.value },\n // bubbles: true,\n // composed: true,\n // }));\n // }\n\n #handleRadioChange(e: Event): void {\n e.stopImmediatePropagation();\n const input = e.target as HTMLInputElement;\n this.value = input.value;\n this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n detail: { checked: true, value: input.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleToggleChange(e: Event): void {\n e.stopImmediatePropagation();\n const input = e.target as HTMLInputElement;\n this.checked = input.checked;\n const newValue = this.checked\n ? (this.value || `on`)\n : (this.valueOff || undefined);\n\n this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n detail: { checked: this.checked, value: newValue },\n bubbles: true,\n composed: true,\n }));\n }\n\n #renderIcon(item: RadioItem): ReturnType<typeof html> | null {\n const isSelected = item.value === this.value;\n const iconName = isSelected ? (item.iconName || null) : (item.iconNameOff || item.iconName || null);\n if (iconName) {\n return html`<ixfx-icon class=\"radio-icon\" name=\"${iconName}\"></ixfx-icon>`;\n }\n const iconHtml = this._icons.get(item.value);\n if (!iconHtml)\n return null;\n return html`<span class=\"radio-icon\">${unsafeHTML(iconHtml)}</span>`;\n }\n\n protected override render(): unknown {\n if (this._isSingleToggle) {\n const iconName = this._singleToggleIconName;\n const showIcon = iconName || this.hideLabels;\n const iconPart = showIcon\n ? html`<ixfx-icon class=\"radio-icon\" name=\"${iconName || `check`}\"></ixfx-icon>`\n : null;\n const labelPart = !this.hideLabels\n ? html`<span class=\"radio-label\" data-text=\"${this.textContent?.trim()}\">${this.textContent?.trim()}</span>`\n : null;\n return html`\n <label class=\"radio-item ${this.checked ? `selected` : ``}\">\n <input\n type=\"checkbox\"\n class=\"radio-toggle-input\"\n ?checked=${this.checked}\n @change=${this.#handleToggleChange}\n />\n ${iconPart}\n ${labelPart}\n </label>\n `;\n }\n\n return html`\n <slot @slotchange=${this.#updateComputedItems} style=\"display: none;\"></slot>\n <div class=\"radio-group ${this.orientation} ${this.mode}\" role=\"radiogroup\" aria-label=${this.name}>\n ${this._computedItems.map((item) => {\n const isSelected = item.value === this.value;\n const iconName = isSelected\n ? (item.iconName || null)\n : (item.iconNameOff || item.iconName || null);\n const showIcon = iconName || this.hideLabels;\n const iconPart = showIcon\n ? html`<ixfx-icon class=\"radio-icon\" name=\"${iconName || `check`}\"></ixfx-icon>`\n : null;\n const labelPart = !this.hideLabels\n ? html`<span class=\"radio-label\" data-text=\"${item.label}\">${item.label}</span>`\n : null;\n return html`\n <label class=\"radio-item ${item.value === this.value ? `selected` : ``}\" ?disabled=${item.disabled}>\n <input\n type=\"radio\"\n class=\"radio-input\"\n name=${this.name}\n value=${item.value}\n ?disabled=${item.disabled}\n ?checked=${item.value === this.value}\n @change=${this.#handleRadioChange}\n />\n ${iconPart}\n ${labelPart}\n </label>\n `;\n })}\n </div>\n `;\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-flex;\n min-width: min-content;\n box-sizing: border-box;\n /* Default to looking like a cohesive control group */\n background: var(--surface-4, transparent);\n background: oklch(from var(--surface-4) l calc(c*0.2) h / 0.4);\n\n border: var(--border, none);\n border-radius: var(--radius-xl, 8px);\n }\n\n * {\n box-sizing: border-box;\n }\n\n .radio-toggle-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n }\n\n .radio-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n }\n\n .radio-group {\n display: flex;\n width: 100%;\n height: 100%;\n gap: var(--item-spacing, 0);\n overflow: hidden;\n border-radius: inherit;\n justify-content: center;\n }\n\n .radio-group.horizontal {\n flex-direction: row;\n }\n\n .radio-group.vertical {\n flex-direction: column;\n }\n\n .radio-group.max.horizontal .radio-item {\n flex: 1;\n justify-content: center;\n }\n\n .radio-group.max.vertical .radio-item {\n flex: 1;\n justify-content: flex-start;\n }\n\n .radio-item {\n display: inline-flex;\n align-items: center;\n justify-content: flex-start;\n gap: var(--icon-label-spacing, 0.5rem);\n padding: var(--space-m, 0.5rem) var(--space-l, 1rem);\n border: none;\n background: transparent;\n color: var(--color-fg-fade, var(--surface-muted-text));\n font-family: inherit;\n font-size: var(--text-m, inherit);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n cursor: pointer;\n transition: all var(--transition, 0.1s) ease;\n user-select: none;\n white-space: nowrap;\n }\n\n .radio-item:hover:not([disabled]) {\n opacity: 0.9;\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent), \n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n .radio-item.selected {\n font-weight: bold;\n color: var(--color-fg-accent, var(--surface-2-text));\n background: var(--surface-5, rgba(255,255,255,0.1));\n }\n\n .radio-item[disabled] {\n cursor: not-allowed;\n }\n\n .radio-item:has(input:focus-visible) {\n outline: 2px solid var(--accent, #666);\n outline-offset: -2px;\n }\n\n .radio-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--icon-size, 1.2rem);\n height: var(--icon-size, 1.2rem);\n flex-shrink: 0;\n }\n\n .radio-icon svg {\n width: 100%;\n height: 100%;\n }\n\n .radio-label {\n position: relative;\n display: inline-flex;\n flex-shrink: 0;\n flex-direction: column;\n align-items: center;\n justify-content: space-between;\n }\n\n .radio-label::after {\n content: attr(data-text);\n content: attr(data-text)/\"\";\n font-weight: bold;\n height: 0;\n visibility: hidden;\n overflow: hidden;\n user-select: none;\n pointer-events: none;\n @media speech {\n display: none;\n }\n }\n\n .radio-group.vertical .radio-item {\n width: 100%;\n }\n\n .radio-group.horizontal .radio-item {\n flex-shrink: 0;\n }\n\n .radio-group.compact .radio-label {\n display: var(--show-labels, inline-flex);\n }\n\n .radio-group.compact.horizontal .radio-item {\n padding: var(--compact-padding, 0.5rem);\n }\n `];\n}\n\nexport type RadioGroupChangeDetail = {\n readonly checked: boolean;\n readonly value: string | undefined;\n};\n\nexport type RadioGroupChangeEvent = CustomEvent<RadioGroupChangeDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-radio-group': RadioGroup;\n }\n}\n","import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type { TickledController, TickledItem } from './tickled-controller.js';\n\nexport type TreeKeyboardNavItemId = string;\n\nexport type TreeKeyboardNavCallbacks = {\n getItems: () => ReadonlyArray<TickledItem<TreeKeyboardNavItemId>>;\n onExpand: (id: TreeKeyboardNavItemId) => void;\n onCollapse: (id: TreeKeyboardNavItemId) => void;\n onActivate: (id: TreeKeyboardNavItemId) => void;\n onSelect?: (id: TreeKeyboardNavItemId) => void;\n onEscape?: () => void;\n isLeaf: (id: TreeKeyboardNavItemId) => boolean;\n isExpanded: (id: TreeKeyboardNavItemId) => boolean;\n getParentId?: (id: TreeKeyboardNavItemId) => TreeKeyboardNavItemId | undefined;\n};\n\nexport type TreeKeyboardNavControllerConfig = {\n callbacks: TreeKeyboardNavCallbacks;\n disableKeyboardNavigation?: () => boolean;\n};\n\nexport class TreeKeyboardNavController implements ReactiveController {\n private host: ReactiveControllerHost;\n private tickled: TickledController<TreeKeyboardNavItemId>;\n private callbacks: TreeKeyboardNavCallbacks;\n private disableKeyboardNavigation: () => boolean;\n\n constructor(host: ReactiveControllerHost, tickled: TickledController<TreeKeyboardNavItemId>, config: TreeKeyboardNavControllerConfig) {\n this.host = host;\n this.tickled = tickled;\n this.callbacks = config.callbacks;\n this.disableKeyboardNavigation = config.disableKeyboardNavigation ?? (() => false);\n host.addController(this);\n }\n\n hostConnected(): void {}\n\n hostDisconnected(): void {}\n\n handleKeyDown = (event: KeyboardEvent): void => {\n if (this.disableKeyboardNavigation()) {\n return;\n }\n\n const { key } = event;\n\n if ([`ArrowDown`, `ArrowUp`, `ArrowLeft`, `ArrowRight`, `Enter`, `Escape`].includes(key)) {\n this.tickled.setInputMode(`keyboard`);\n }\n\n switch (key) {\n case `ArrowDown`:\n event.preventDefault();\n this.#handleArrowDown();\n break;\n case `ArrowUp`:\n event.preventDefault();\n this.#handleArrowUp();\n break;\n case `ArrowRight`:\n event.preventDefault();\n this.#handleArrowRight();\n break;\n case `ArrowLeft`:\n event.preventDefault();\n this.#handleArrowLeft();\n break;\n case `Enter`:\n event.preventDefault();\n this.#handleEnter();\n break;\n case `Escape`:\n event.preventDefault();\n this.callbacks.onEscape?.();\n break;\n }\n };\n\n #handleArrowDown(): void {\n this.tickled.handleKeyboardNavigation(`next`);\n }\n\n #handleArrowUp(): void {\n this.tickled.handleKeyboardNavigation(`previous`);\n }\n\n #handleArrowRight(): void {\n const currentId = this.tickled.tickledId;\n if (!currentId)\n return;\n\n if (this.callbacks.isLeaf(currentId)) {\n return;\n }\n\n if (!this.callbacks.isExpanded(currentId)) {\n this.callbacks.onExpand(currentId);\n this.tickled.setTickled(currentId);\n } else {\n const items = this.callbacks.getItems();\n const currentIdx = items.findIndex(item => item.id === currentId);\n if (currentIdx !== -1 && currentIdx + 1 < items.length) {\n const nextItem = items[currentIdx + 1];\n if (nextItem.enabled !== false) {\n this.tickled.setTickled(nextItem.id);\n }\n }\n }\n }\n\n #handleArrowLeft(): void {\n const currentId = this.tickled.tickledId;\n if (!currentId)\n return;\n\n if (this.callbacks.isLeaf(currentId)) {\n const parentId = this.callbacks.getParentId?.(currentId);\n if (parentId) {\n this.tickled.setTickled(parentId);\n if (this.callbacks.isExpanded(parentId)) {\n this.callbacks.onCollapse(parentId);\n }\n }\n } else if (this.callbacks.isExpanded(currentId)) {\n this.callbacks.onCollapse(currentId);\n } else {\n const parentId = this.callbacks.getParentId?.(currentId);\n if (parentId) {\n this.tickled.setTickled(parentId);\n }\n }\n }\n\n #handleEnter(): void {\n const currentId = this.tickled.tickledId;\n if (!currentId)\n return;\n\n this.callbacks.onActivate(currentId);\n this.callbacks.onSelect?.(currentId);\n }\n}","import type { CommandRegistry, KeyboardManager } from '@clinth/ui-commands';\nimport type { MenuTrigger } from '../menu/menu-trigger.js';\nimport type { ItemsProvider, PopupItem, SwitcherItem } from './types.js';\nimport { css, html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { buttonStyles } from './button-styles.js';\nimport { ButtonElement } from './button.js';\nimport '../menu/menu-trigger.js';\nimport '../menu/menu-container.js';\nimport '../menu/menu-item.js';\nimport '../icons/icon.js';\n\nexport type SplitButtonMode = `default` | `switcher`;\n\n@customElement(`ixfx-split-button`)\nexport class SplitButton extends ButtonElement {\n @property({ attribute: false }) registry?: CommandRegistry<unknown>;\n @property({ attribute: false }) keyboardManager?: KeyboardManager;\n @property({ type: String }) mode: SplitButtonMode = `default`;\n @property({ type: String, attribute: `default-value` }) defaultValue = ``;\n /** When set, called each time the popup is opened; its return value replaces declarative items. */\n @property({ attribute: false }) itemsProvider?: ItemsProvider;\n /** Directly set popup items. Ignored when itemsProvider is also set. */\n @property({ attribute: false }) items?: PopupItem[];\n\n @query(`ixfx-menu-trigger`) private _menuTrigger!: MenuTrigger;\n\n @state() private _selectedCommand = ``;\n @state() private _selectedLabel = ``;\n @state() private _selectedIcon = ``;\n @state() private _switcherItems: SwitcherItem[] = [];\n @state() private _dynamicItems: PopupItem[] = [];\n @state() private _loadingItems = false;\n @state() private _menuHasItems = false;\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._menuTrigger?.removeEventListener(`menu-command`, this._handleSwitcherMenuCommand as EventListener);\n }\n\n override firstUpdated(): void {\n this.updateComplete.then(() => {\n this._menuTrigger?.addEventListener(`menu-command`, this._handleSwitcherMenuCommand as EventListener);\n });\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if ((changedProperties.has(`items`) || changedProperties.has(`mode`)) && this.items && !this.itemsProvider) {\n this._applyItems(this.items);\n }\n }\n\n // ── Programmatic API ───────────────────────────────────────────────────\n\n private _applyItems(items: PopupItem[]): void {\n if (this.mode === `switcher`) {\n this._applySwitcherItems(items.map(i => ({ command: i.command, label: i.label, icon: i.icon ?? `` })));\n } else {\n this._dynamicItems = [...items];\n this._menuHasItems = items.length > 0;\n }\n }\n\n /** In switcher mode, programmatically select the active command. Returns false if not found. */\n selectCommand(command: string): boolean {\n const item = this._switcherItems.find(i => i.command === command);\n if (!item)\n return false;\n this._selectedCommand = item.command;\n this._selectedLabel = item.label;\n this._selectedIcon = item.icon;\n return true;\n }\n\n /** Invokes the primary button action as if clicked by the user. */\n invoke(): boolean {\n if (this.disabled)\n return false;\n const primaryBtn = this.shadowRoot?.querySelector(`.split button.primary`);\n if (!primaryBtn)\n return false;\n if (this.mode === `switcher` && this._selectedCommand) {\n this.dispatchEvent(new CustomEvent(`menu-command`, {\n detail: { command: this._selectedCommand },\n bubbles: true,\n composed: true,\n }));\n return true;\n }\n primaryBtn.dispatchEvent(new MouseEvent(`click`, { bubbles: true }));\n return true;\n }\n\n // ── Caret state ────────────────────────────────────────────────────────\n\n /** True when there is (or will be) popup content. Used to dim the caret visually. */\n private get _caretHasContent(): boolean {\n if (this.itemsProvider)\n return true;\n if (this.items && this.items.length > 0)\n return true;\n if (this.mode === `switcher`)\n return this._switcherItems.length > 1;\n return this._menuHasItems;\n }\n\n // ── Default-mode slot ──────────────────────────────────────────────────\n\n private _onDefaultMenuSlotChange = (e: Event): void => {\n const slot = e.target as HTMLSlotElement;\n this._menuHasItems = slot.assignedElements({ flatten: true }).length > 0;\n };\n\n // ── Switcher helpers ───────────────────────────────────────────────────\n\n private _onSwitcherSlotChange = (e: Event): void => {\n // When itemsProvider is set, declarative items are ignored\n if (this.itemsProvider)\n return;\n const slot = e.target as HTMLSlotElement;\n this._applySwitcherItems(\n slot.assignedElements({ flatten: true })\n .filter(el => el.tagName === `IXFX-MENU-ITEM`)\n .map(el => ({\n command: el.getAttribute(`command`) ?? ``,\n label: el.getAttribute(`label`) ?? el.textContent?.trim() ?? ``,\n icon: el.getAttribute(`icon-name`) ?? ``,\n })),\n );\n };\n\n private _applySwitcherItems(items: SwitcherItem[]): void {\n this._switcherItems = items;\n if (!this._selectedCommand && items.length > 0) {\n const picked = this.defaultValue\n ? (items.find(i => i.command === this.defaultValue) ?? items[0])\n : items[0];\n this._selectedCommand = picked.command;\n this._selectedLabel = picked.label;\n this._selectedIcon = picked.icon;\n }\n }\n\n private _handleSwitcherMenuCommand = (e: CustomEvent): void => {\n if (this.mode !== `switcher`)\n return;\n e.stopPropagation();\n\n const { command } = e.detail;\n const item = this._switcherItems.find(i => i.command === command);\n if (!item)\n return;\n\n this._selectedCommand = item.command;\n this._selectedLabel = item.label;\n this._selectedIcon = item.icon;\n\n // Fire immediately\n this.dispatchEvent(new CustomEvent(`menu-command`, {\n detail: e.detail,\n bubbles: true,\n composed: true,\n }));\n };\n\n private _handleSwitcherPrimaryClick = (): void => {\n if (!this._selectedCommand)\n return;\n this.dispatchEvent(new CustomEvent(`menu-command`, {\n detail: { command: this._selectedCommand },\n bubbles: true,\n composed: true,\n }));\n };\n\n // ── Caret / menu open ──────────────────────────────────────────────────\n\n private _handleCaretClick = async (e: Event): Promise<void> => {\n e.stopPropagation();\n if (this._menuTrigger?.isOpen) {\n this._menuTrigger.closeMenu();\n return;\n }\n\n if (this.itemsProvider) {\n this._loadingItems = true;\n try {\n const result = this.itemsProvider();\n const items = result instanceof Promise ? await result : result;\n\n if (this.mode === `switcher`) {\n this._applySwitcherItems(\n items.map(i => ({ command: i.command, label: i.label, icon: i.icon ?? `` })),\n );\n } else {\n this._dynamicItems = items;\n }\n } finally {\n this._loadingItems = false;\n }\n // Let Lit render the new items before the popup opens\n await this.updateComplete;\n }\n\n this._menuTrigger?.openMenu();\n };\n\n private _handlePrimaryKeyDown = (e: KeyboardEvent): void => {\n if (e.key === `ArrowDown`) {\n e.preventDefault();\n this._menuTrigger?.openMenu();\n }\n };\n\n private _handleCaretKeyDown = (e: KeyboardEvent): void => {\n if (e.key === `ArrowDown`) {\n e.preventDefault();\n this._menuTrigger?.openMenu();\n }\n };\n\n // ── Render ─────────────────────────────────────────────────────────────\n\n protected override render() {\n return this.mode === `switcher`\n ? this._renderSwitcher()\n : this._renderDefault();\n }\n\n private _renderCaret(iconName: string, ariaLabel: string) {\n const empty = !this._caretHasContent;\n return html`\n <button\n slot=\"trigger\"\n class=\"caret\"\n part=\"caret\"\n ?disabled=${this.disabled}\n ?data-empty=${empty}\n aria-haspopup=\"true\"\n aria-label=${ariaLabel}\n @click=${this._handleCaretClick}\n @keydown=${this._handleCaretKeyDown}\n >\n <ixfx-icon name=\"${iconName}\"></ixfx-icon>\n </button>\n `;\n }\n\n private _renderLoadingOrItems(items: PopupItem[]) {\n if (this._loadingItems) {\n return html`<ixfx-menu-item label=\"Loading…\" disabled></ixfx-menu-item>`;\n }\n return items.map(i => html`\n <ixfx-menu-item\n command=${i.command}\n label=${i.label}\n icon-name=${i.icon || nothing}\n ?disabled=${i.disabled ?? false}\n ></ixfx-menu-item>\n `);\n }\n\n private _renderDefault() {\n const label = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\"><slot></slot></span>`;\n\n const menuContent = this.itemsProvider\n ? html`\n <ixfx-menu-container slot=\"menu\">\n ${this._renderLoadingOrItems(this._dynamicItems)}\n </ixfx-menu-container>\n `\n : html`<slot name=\"menu\" slot=\"menu\" @slotchange=${this._onDefaultMenuSlotChange}></slot>`;\n\n return html`\n <div class=\"split\">\n <button\n class=\"primary\"\n part=\"primary\"\n ?disabled=${this.disabled}\n @keydown=${this._handlePrimaryKeyDown}\n >\n ${this._renderIcon()}${label}\n </button>\n <ixfx-menu-trigger .registry=${this.registry} .keyboardManager=${this.keyboardManager}>\n ${this._renderCaret(`chevron-down`, `Open menu`)}\n ${menuContent}\n </ixfx-menu-trigger>\n </div>\n `;\n }\n\n private _renderSwitcher() {\n const primaryIcon = this._selectedIcon\n ? html`<ixfx-icon class=\"button-icon\" name=\"${this._selectedIcon}\"></ixfx-icon>`\n : nothing;\n\n const primaryLabel = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\">${this._selectedLabel}</span>`;\n\n const popupItems = this.itemsProvider\n ? this._renderLoadingOrItems(this._dynamicItems)\n : this._switcherItems\n .filter(i => i.command !== this._selectedCommand)\n .map(i => html`\n <ixfx-menu-item\n command=${i.command}\n label=${i.label}\n icon-name=${i.icon || nothing}\n ></ixfx-menu-item>\n `);\n\n return html`\n <!-- Hidden data-capture slot reads light-DOM items as the data source -->\n <slot name=\"menu\" class=\"switcher-data\" @slotchange=${this._onSwitcherSlotChange}></slot>\n <div class=\"split switcher\">\n <button\n class=\"primary\"\n part=\"primary\"\n ?disabled=${this.disabled}\n @keydown=${this._handlePrimaryKeyDown}\n @click=${this._handleSwitcherPrimaryClick}\n >\n ${primaryIcon}${primaryLabel}\n </button>\n <ixfx-menu-trigger .registry=${this.registry} .keyboardManager=${this.keyboardManager}>\n ${this._renderCaret(`chevron-right`, `Choose action`)}\n <ixfx-menu-container slot=\"menu\">\n ${popupItems}\n </ixfx-menu-container>\n </ixfx-menu-trigger>\n </div>\n `;\n }\n\n // ── Styles ─────────────────────────────────────────────────────────────\n\n static override styles = [\n themeFallbacks,\n prominenceStyles,\n buttonStyles,\n css`\n :host {\n display: inline-flex;\n max-width: 100%;\n min-width: var(--ixfx-split-button-min-width, 0);\n vertical-align: middle;\n }\n\n slot.switcher-data {\n display: none;\n }\n\n .split {\n display: inline-flex;\n width: 100%;\n background: var(--surface-3, #ccc);\n color: var(--surface-3-text, #000);\n border: var(--border, 1px solid #999);\n border-radius: var(--radius-xl, 8px);\n corner-shape: superellipse(1);\n box-shadow:\n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent),\n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);\n overflow: hidden;\n transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);\n }\n\n /* Switcher: accent the caret separator to signal \"this changes the default\" */\n .split.switcher button.caret {\n border-inline-start-color: var(--accent, #666);\n opacity: 0.7;\n }\n\n .split.switcher button.caret:hover:not(:disabled) {\n opacity: 1;\n }\n\n /* Caret is dimmed when there is no popup content */\n button.caret[data-empty] {\n opacity: 0.3;\n pointer-events: none;\n }\n\n .split:has(button:hover:not(:disabled)) {\n border-color: var(--accent, #666);\n box-shadow:\n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent),\n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n .split:has(button:active:not(:disabled)) {\n transform: translateY(1px);\n box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch, var(--surface-1), transparent);\n }\n\n button.primary,\n button.caret {\n border: none;\n border-radius: 0;\n background: none;\n box-shadow: none;\n color: inherit;\n margin: 0;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background var(--transition, 0.2s), opacity var(--transition, 0.2s);\n }\n\n button.primary {\n flex: 1;\n min-width: 0;\n padding: var(--space-m, 8px) var(--space-l, 12px);\n gap: 0.5em;\n overflow: hidden;\n white-space: nowrap;\n }\n\n button.primary .button-label {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n button.caret {\n padding: var(--space-m, 8px) var(--space-s, 6px);\n border-inline-start: var(--border, 1px solid #999);\n flex-shrink: 0;\n }\n\n button.primary:hover:not(:disabled),\n button.caret:hover:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n }\n\n button.primary:active:not(:disabled),\n button.caret:active:not(:disabled) {\n background: var(--surface-2, #aaa);\n transform: none;\n box-shadow: none;\n }\n\n button.primary:disabled,\n button.caret:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n button.primary:focus-visible,\n button.caret:focus-visible {\n outline: 2px solid var(--accent, #666);\n outline-offset: -2px;\n }\n\n :host([subtle]) button.primary,\n :host([subtle]) button.caret,\n :host([subtle]) button.primary:hover:not(:disabled),\n :host([subtle]) button.caret:hover:not(:disabled) {\n background: none;\n }\n\n :host([subtle]) .split {\n background: color-mix(in oklch, var(--surface-3, #ccc) 40%, transparent);\n }\n\n :host([subtle]) .split:has(button:hover:not(:disabled)),\n :host([subtle]) .split:has(button:focus-visible:not(:disabled)) {\n background: color-mix(in oklch, var(--surface-3, #ccc) 70%, transparent);\n }\n\n ixfx-menu-trigger {\n display: inline-flex;\n align-items: stretch;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-split-button': SplitButton;\n }\n}\n","import type { CrumbPathElement, CrumbSegment, SegmentIconLookupFn } from './crumb-path.js';\n\nimport { Trees } from '@ixfx/collections';\n\nexport type SortCompareFn = (a: CrumbSegment, b: CrumbSegment) => number;\n\nexport type CrumbPathControllerOptions = {\n separator?: string;\n paths?: string[];\n onQuery?: (pathSegments: string[]) => Promise<CrumbSegment[]>;\n sortCompare?: SortCompareFn | null;\n};\n\nexport class CrumbPathController {\n #element: CrumbPathElement | null = null;\n #pathed: Trees.Pathed.Pathed<CrumbSegment>;\n #separator: string;\n #onQuery: ((pathSegments: string[]) => Promise<CrumbSegment[]>) | undefined;\n #sortCompare: SortCompareFn | null | undefined;\n\n constructor(options: CrumbPathControllerOptions = {}) {\n this.#separator = options.separator ?? `/`;\n this.#onQuery = options.onQuery;\n this.#sortCompare = options.sortCompare;\n this.#pathed = new Trees.Pathed.Pathed<CrumbSegment>({ separator: this.#separator });\n\n if (options.paths) {\n this.addPaths(options.paths);\n // console.log(this.#pathed.prettyPrint());\n }\n }\n\n get separator(): string {\n return this.#separator;\n }\n\n addPath(path: string): void {\n const segments = path.split(this.#separator).filter(s => s.length > 0);\n for (let i = 0; i < segments.length; i++) {\n const segmentPath = segments.slice(0, i + 1).join(this.#separator);\n const label = segments[i];\n const segment: CrumbSegment = { label };\n this.#pathed.add(segment, segmentPath);\n }\n }\n\n addPaths(paths: string[]): void {\n for (const path of paths) {\n this.addPath(path);\n }\n }\n\n addSegment(segment: CrumbSegment, path: string): void {\n this.#pathed.add(segment, path);\n }\n\n addSegments(entries: Array<{ path: string; segment: CrumbSegment }>): void {\n for (const { path, segment } of entries) {\n this.addSegment(segment, path);\n }\n }\n\n getIcon(cumulativePath: string): string | undefined {\n const value = this.#pathed.getValue(cumulativePath);\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === `object` && value !== null && `value` in value) {\n const nested = (value as { value?: CrumbSegment }).value;\n return nested?.icon;\n }\n return (value as CrumbSegment).icon;\n }\n\n getPath(): string {\n return this.#element?.getPath() ?? ``;\n }\n\n setPath(path: string): void {\n this.#element?.setPath(path);\n }\n\n #segmentIconLookup: SegmentIconLookupFn = (pathSegments: string[]): string | undefined => {\n return this.getIcon(pathSegments.join(this.#separator));\n };\n\n connect(element: CrumbPathElement): void {\n this.#element = element;\n element.separator = this.#separator;\n element.siblingLookup = this.#siblingLookup.bind(this);\n if (!element.segmentIconLookup) {\n element.segmentIconLookup = this.#segmentIconLookup;\n }\n }\n\n disconnect(): void {\n if (this.#element) {\n this.#element.siblingLookup = undefined;\n if (this.#element.segmentIconLookup === this.#segmentIconLookup) {\n this.#element.segmentIconLookup = undefined;\n }\n this.#element = null;\n }\n }\n\n async #siblingLookup(\n pathSegments: string[],\n _index: number,\n signal: AbortSignal,\n ): Promise<CrumbSegment[]> {\n const currentPath = pathSegments.join(this.#separator);\n\n const cachedChildren = this.#pathed.children(currentPath);\n const children = [...cachedChildren];\n\n if (children.length > 0) {\n const mapped = children\n .map(node => node.value)\n .filter((v): v is NonNullable<typeof v> => v !== undefined)\n .map((v) => {\n if (`value` in v) {\n return v.value ?? { label: v.label };\n }\n return { label: v.label };\n });\n return this.#sortCompare ? [...mapped].sort(this.#sortCompare) : mapped;\n }\n\n if (this.#onQuery) {\n const newChildren = await this.#onQuery(pathSegments);\n\n const sorted = this.#sortCompare ? [...newChildren].sort(this.#sortCompare) : newChildren;\n for (const child of sorted) {\n const childPath = currentPath.length > 0\n ? `${currentPath}${this.#separator}${child.label}`\n : child.label;\n this.#pathed.add(child, childPath);\n }\n\n if (signal.aborted) {\n return [];\n }\n\n return sorted;\n }\n\n return [];\n }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport type { AcTextChangeEvent, AcTextItem } from '../ac-text/ac-text.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { popupSurfaceStyles } from '../styles/popup.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../ac-text/ac-text.js';\nimport '../icons/icon.js';\n\nconst INVALID_ANCHOR_CHARS_RE = /[^\\w-]/g;\n\nexport type CrumbSegment = {\n label: string;\n icon?: string;\n isLeaf?: boolean;\n};\n\nexport type CrumbSiblingLookupFn = (\n pathSegments: string[],\n index: number,\n signal: AbortSignal,\n) => Promise<CrumbSegment[]>;\n\nexport type SegmentIconLookupFn = (\n pathSegments: string[],\n index: number,\n) => string | undefined;\n\nexport type CrumbNavNavigateDetail = { index: number; label: string; parentPath: string; fullPath: string };\nexport type CrumbNavNavigateEvent = CustomEvent<CrumbNavNavigateDetail>;\nexport type CrumbNavChangeDetail = { label: string; parentPath: string; fullPath: string };\nexport type CrumbNavChangeEvent = CustomEvent<CrumbNavChangeDetail>;\nexport type CrumbNavExpandDetail = { index: number; segments: string[]; path: string; signal: AbortSignal };\nexport type CrumbNavExpandEvent = CustomEvent<CrumbNavExpandDetail>;\n\n/** A MIME-typed payload written to the drag's `DataTransfer` when a segment drag starts. */\nexport type CrumbSegmentDragData = {\n /** MIME type, e.g. `text/plain` or an application-specific type. */\n type: string;\n /** Payload string for `type`. */\n data: string;\n};\n\n/**\n * Consulted per segment with the full cumulative path (including any\n * `pathRoot` prefix). Returning drag data marks the segment `draggable`;\n * returning `undefined` leaves it alone. Called at render time (to mark the\n * segment) and again during `dragstart` (for fresh payload data).\n */\nexport type CrumbSegmentDragLookupFn = (\n pathSegments: string[],\n index: number,\n) => CrumbSegmentDragData | readonly CrumbSegmentDragData[] | undefined;\n\n/**\n * Interprets a drop landing on a segment. Return `undefined` for drops the\n * app does not handle — no `crumb-drop` event fires for them. Only\n * `dataTransfer.types` is reliably readable during `dragover`; full data is\n * readable at `drop`.\n */\nexport type CrumbExternalDropParser = (dataTransfer: DataTransfer) => unknown;\n\nexport type CrumbDragStartDetail = {\n /** Index of the dragged segment within `pathSegments`. */\n index: number;\n label: string;\n /** Full cumulative path segments, including any `pathRoot` prefix. */\n pathSegments: string[];\n parentPath: string;\n fullPath: string;\n /** Null in stubbed environments; normally present during a real `dragstart`. */\n dataTransfer: DataTransfer | null;\n};\nexport type CrumbDragStartEvent = CustomEvent<CrumbDragStartDetail>;\n\nexport type CrumbDropDetail = {\n /** Index of the drop segment within `pathSegments`. */\n index: number;\n label: string;\n /** Full cumulative path segments, including any `pathRoot` prefix. */\n pathSegments: string[];\n parentPath: string;\n fullPath: string;\n /** Result of `parseExternalDrop` — always defined; unparsed drops emit nothing. */\n data: unknown;\n dataTransfer: DataTransfer;\n};\nexport type CrumbDropEvent = CustomEvent<CrumbDropDetail>;\n\n@customElement(`ixfx-crumb-path`)\nexport class CrumbPathElement extends LitElement {\n @property({ type: String })\n path = ``;\n\n @property({ type: String })\n separator = `/`;\n\n @property({ type: String, attribute: `path-root` })\n pathRoot = ``;\n\n @property({ type: Object })\n siblingLookup: CrumbSiblingLookupFn | undefined;\n\n @property({ type: Object })\n segmentIconLookup: SegmentIconLookupFn | undefined;\n\n /** Marks segments draggable and supplies their drag payloads. */\n @property({ type: Object })\n segmentDragLookup: CrumbSegmentDragLookupFn | undefined;\n\n /** Interprets drops landing on segments; enables drop targeting when set. */\n @property({ type: Object })\n parseExternalDrop: CrumbExternalDropParser | undefined;\n\n @state()\n private _openIdx: number | null = null;\n\n @state()\n private _editing = false;\n\n @state()\n private _cachedSiblings: Map<string, CrumbSegment[]> = new Map();\n\n @state()\n private _leafSegmentIndex: number | null = null;\n\n @state()\n private _confirmedLeafIndices: Set<string> = new Set();\n\n @state()\n private _dropdownActiveIndex = -1;\n\n @state()\n private _editingCancelled = false;\n\n @state()\n private _editStartIndex: number | null = null;\n\n @state()\n private _openCumPath: string | null = null;\n\n /** Cumulative path of the segment currently being dragged out (`.dragging`). */\n @state()\n private _dragCumPath: string | null = null;\n\n /** Cumulative path of the segment currently hovered by an external drag (`.drop-into`). */\n @state()\n private _dropCumPath: string | null = null;\n\n #pendingController: AbortController | undefined;\n #pendingIndex: number | undefined;\n readonly #uid = Math.random().toString(36).slice(2, 8);\n /** Clicks within this window after a drag are ignored (post-drag click-through guard). */\n #clickSuppressUntil = 0;\n\n #anchorName(cumPath: string): string {\n return `--cp-${this.#uid}-${cumPath\n .replaceAll(this.separator, `-`)\n .replaceAll(` `, `-`)\n .replace(INVALID_ANCHOR_CHARS_RE, `-`)}`;\n }\n\n #closeDropdown() {\n if (this._openIdx !== null) {\n this._openIdx = null;\n this._openCumPath = null;\n this._dropdownActiveIndex = -1;\n this.#cleanupPending();\n const popup = this.shadowRoot?.querySelector(`.crumb-dropdown`) as HTMLElement | null;\n try {\n (popup as any)?.hidePopover();\n } catch { /* unsupported */ }\n }\n }\n\n #onPopoverToggle = (e: Event): void => {\n if ((e as ToggleEvent).newState === `closed` && this._openIdx !== null) {\n this._openIdx = null;\n this._dropdownActiveIndex = -1;\n this.#cleanupPending();\n }\n };\n\n protected override updated(changedProperties: PropertyValues): void {\n if (this._editing) {\n const el = this.shadowRoot?.querySelector(`ixfx-ac-text`);\n if (el instanceof LitElement) {\n const editValue = this.path;\n if (this._editStartIndex !== null) {\n const segments = this.#getSegments();\n const segmentLabel = segments[this._editStartIndex];\n const startPos = this.path.indexOf(segmentLabel);\n (el as any).focusWithValue(editValue, startPos);\n } else {\n (el as any).focusWithValue(editValue);\n }\n }\n }\n if (changedProperties.has(`_openIdx`) && this._openIdx !== null) {\n this.updateComplete.then(() => {\n const popup = this.shadowRoot?.querySelector(`.crumb-dropdown`) as HTMLElement | null;\n if (popup) {\n popup.style.setProperty(`position-anchor`, this.#anchorName(this._openCumPath ?? String(this._openIdx)));\n try {\n (popup as any).showPopover();\n } catch { /* unsupported */ }\n popup.focus();\n }\n });\n }\n }\n\n #cleanupPending() {\n if (this.#pendingController) {\n this.#pendingController.abort();\n this.#pendingController = undefined;\n this.#pendingIndex = undefined;\n }\n }\n\n #getSegments(): string[] {\n const fullPath = this.path;\n if (this.pathRoot.length > 0 && fullPath.startsWith(this.pathRoot)) {\n const relativePath = fullPath.slice(this.pathRoot.length);\n return relativePath.split(this.separator).filter(p => p.length > 0);\n }\n return this.path.split(this.separator).filter(p => p.length > 0);\n }\n\n #getRootSegments(): string[] {\n if (this.pathRoot.length === 0)\n return [];\n return this.pathRoot.split(this.separator).filter(p => p.length > 0);\n }\n\n #getCumulativePath(index: number, isRoot: boolean): string {\n const segments = this.#getSegments();\n const rootSegments = this.#getRootSegments();\n\n if (isRoot) {\n return rootSegments.slice(0, index + 1).join(this.separator);\n }\n\n return [...rootSegments, ...segments.slice(0, index + 1)].join(this.separator);\n }\n\n #resolveFullPathSegments(index: number, isRoot: boolean): string[] {\n const rootSegments = this.#getRootSegments();\n if (isRoot)\n return rootSegments.slice(0, index + 1);\n return [...rootSegments, ...this.#getSegments().slice(0, index + 1)];\n }\n\n #segmentDragPayloads(fullPathSegments: string[]): CrumbSegmentDragData[] {\n try {\n const result = this.segmentDragLookup?.(fullPathSegments, fullPathSegments.length - 1);\n if (result === undefined || result === null)\n return [];\n // `Array.isArray` does not narrow away `readonly T[]` in the false branch.\n return Array.isArray(result) ? [...result] : [result as CrumbSegmentDragData];\n } catch {\n return [];\n }\n }\n\n #clicksSuppressed(): boolean {\n return Date.now() < this.#clickSuppressUntil || this._dragCumPath !== null;\n }\n\n #resolveSegmentIcon(fullPathSegments: string[], index: number): string | undefined {\n const direct = this.segmentIconLookup?.(fullPathSegments, index);\n if (typeof direct === `string` && direct.length > 0) {\n return direct;\n }\n const label = fullPathSegments[index];\n if (label === undefined) {\n return undefined;\n }\n const parentKey = fullPathSegments.slice(0, index).join(this.separator);\n const cached = this._cachedSiblings.get(parentKey);\n const match = cached?.find(s => s.label === label);\n return match?.icon;\n }\n\n public setPath(newPath: string): void {\n this.#cleanupPending();\n if (this.pathRoot.length > 0 && !newPath.startsWith(this.pathRoot)) {\n newPath = this.pathRoot;\n }\n this.path = newPath;\n this._cachedSiblings = new Map();\n this._openIdx = null;\n this._leafSegmentIndex = null;\n this._confirmedLeafIndices = new Set();\n }\n\n public getPath(): string {\n return this.path;\n }\n\n #onCaretClick(index: number, event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n if (this._openIdx === index) {\n this.#closeDropdown();\n return;\n }\n\n const target = event.currentTarget as HTMLElement;\n const cumPath = target.dataset.cumulative;\n\n this._openIdx = index;\n this._openCumPath = cumPath ?? null;\n this._dropdownActiveIndex = -1;\n const segments = this.#getSegments();\n const rootSegments = this.#getRootSegments();\n\n const pathSegments = cumPath\n ? cumPath.split(this.separator).filter(p => p.length > 0)\n : (index === -1 ? rootSegments : segments.slice(0, index + 1));\n\n const cacheKey = cumPath ?? String(index);\n if (!this._cachedSiblings.has(cacheKey) && this.siblingLookup) {\n this.#cleanupPending();\n const controller = new AbortController();\n this.#pendingController = controller;\n this.#pendingIndex = index;\n\n this.siblingLookup(pathSegments, index, controller.signal)\n .then((siblings) => {\n if (!controller.signal.aborted) {\n this._cachedSiblings.set(cacheKey, siblings);\n if (siblings.length === 0) {\n this._confirmedLeafIndices.add(cumPath ?? ``);\n }\n this.#pendingController = undefined;\n this.#pendingIndex = undefined;\n this.requestUpdate();\n }\n })\n .catch((err) => {\n if (err.name !== `AbortError`) {\n console.error(`Sibling lookup failed:`, err);\n }\n this.#pendingController = undefined;\n this.#pendingIndex = undefined;\n });\n\n this.dispatchEvent(new CustomEvent<CrumbNavExpandDetail>(`expand`, {\n detail: { index, segments: pathSegments, path: pathSegments.join(this.separator), signal: controller.signal },\n bubbles: true,\n composed: true,\n }));\n }\n\n this.requestUpdate();\n }\n\n #onLabelDragStart(fullPathSegments: string[], cumPath: string, event: DragEvent): void {\n this.#closeDropdown();\n const index = fullPathSegments.length - 1;\n const dt = event.dataTransfer;\n const detail: CrumbDragStartDetail = {\n index,\n label: fullPathSegments[index] ?? ``,\n pathSegments: fullPathSegments,\n parentPath: fullPathSegments.slice(0, -1).join(this.separator),\n fullPath: fullPathSegments.join(this.separator),\n dataTransfer: dt,\n };\n const evt = new CustomEvent<CrumbDragStartDetail>(`crumb-drag-start`, {\n detail,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n const notCancelled = this.dispatchEvent(evt);\n if (!notCancelled) {\n event.preventDefault();\n return;\n }\n this._dragCumPath = cumPath;\n this.toggleAttribute(`data-native-dragging`, true);\n if (!dt)\n return;\n try {\n // Let drop targets show a \"move\" / \"copy\" cursor.\n if (dt.effectAllowed === `none` || dt.effectAllowed === `uninitialized`) {\n dt.effectAllowed = `copyMove`;\n }\n } catch { /* read-only in some contexts — non-fatal. */ }\n try {\n for (const payload of this.#segmentDragPayloads(fullPathSegments)) {\n dt.setData(payload.type, payload.data);\n }\n // The cumulative path is the natural fallback payload for a segment.\n if (!dt.types.includes(`text/plain`)) {\n dt.setData(`text/plain`, detail.fullPath);\n }\n } catch { /* restricted / stubbed DataTransfer — non-fatal. */ }\n }\n\n #onLabelDragEnd(): void {\n this._dragCumPath = null;\n this._dropCumPath = null;\n this.toggleAttribute(`data-native-dragging`, false);\n // Suppress the click that some browsers still fire after a drag ends.\n this.#clickSuppressUntil = Date.now() + 150;\n }\n\n #onSegDragOver(cumPath: string, event: DragEvent): void {\n if (!this.parseExternalDrop)\n return;\n if (!event.dataTransfer)\n return;\n event.preventDefault();\n if (this._dropCumPath !== cumPath) {\n this._dropCumPath = cumPath;\n }\n }\n\n #onSegDragLeave(cumPath: string, _event: DragEvent): void {\n if (!this.parseExternalDrop)\n return;\n if (this._dropCumPath === cumPath) {\n this._dropCumPath = null;\n }\n }\n\n #onSegDrop(fullPathSegments: string[], event: DragEvent): void {\n if (!this.parseExternalDrop)\n return;\n event.preventDefault();\n event.stopPropagation();\n this._dropCumPath = null;\n const dt = event.dataTransfer;\n if (!dt)\n return;\n let data: unknown;\n try {\n data = this.parseExternalDrop(dt);\n } catch (err) {\n console.error(`parseExternalDrop failed:`, err);\n return;\n }\n if (data === undefined)\n return;\n const index = fullPathSegments.length - 1;\n this.dispatchEvent(new CustomEvent<CrumbDropDetail>(`crumb-drop`, {\n detail: {\n index,\n label: fullPathSegments[index] ?? ``,\n pathSegments: fullPathSegments,\n parentPath: fullPathSegments.slice(0, -1).join(this.separator),\n fullPath: fullPathSegments.join(this.separator),\n data,\n dataTransfer: dt,\n },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onLabelClick(index: number, event: MouseEvent) {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n this.#closeDropdown();\n\n const segments = this.#getSegments();\n const truncatedSegments = segments.slice(0, index + 1);\n const hadLeading = this.path.startsWith(this.separator);\n const newPath = truncatedSegments.join(this.separator);\n this.path = hadLeading ? this.separator + newPath : newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = null;\n\n const parentPath = truncatedSegments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavNavigateDetail>(`navigate`, {\n detail: { index, label: truncatedSegments[index], parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #selectSibling(index: number, segment: CrumbSegment): void {\n const cumPath = this._openCumPath;\n this.#closeDropdown();\n const segments = this.#getSegments();\n const rootSegments = this.#getRootSegments();\n let newSegments: string[];\n\n if (cumPath) {\n newSegments = [...cumPath.split(this.separator).filter(p => p.length > 0), segment.label];\n } else if (this.pathRoot.length > 0 && index < rootSegments.length) {\n newSegments = [...rootSegments.slice(0, index + 1), segment.label];\n } else {\n newSegments = [...rootSegments, ...segments.slice(0, index + 1 - rootSegments.length), segment.label];\n }\n\n const hadLeading = this.path.startsWith(this.separator);\n const newPath = newSegments.join(this.separator);\n this.path = hadLeading ? this.separator + newPath : newPath;\n this._cachedSiblings = new Map();\n const leafIndex = segment.isLeaf ? newSegments.length - 1 : null;\n this._leafSegmentIndex = leafIndex;\n if (segment.isLeaf) {\n this._confirmedLeafIndices.add(cumPath ?? ``);\n }\n const parentPath = newSegments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavNavigateDetail>(`navigate`, {\n detail: { index, label: segment.label, parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onSiblingClick(index: number, segment: CrumbSegment, event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n this.#selectSibling(index, segment);\n }\n\n #onDropdownKeyDown = (e: KeyboardEvent): void => {\n if (this._openIdx === null)\n return;\n const siblings = this._cachedSiblings.get(this._openCumPath ?? String(this._openIdx)) ?? [];\n if (!siblings.length) {\n if (e.key === `Escape`) {\n e.preventDefault(); this.#closeDropdown();\n }\n return;\n }\n switch (e.key) {\n case `ArrowDown`:\n e.preventDefault();\n this._dropdownActiveIndex = (this._dropdownActiveIndex + 1) % siblings.length;\n this.#scrollDropdownActiveIntoView();\n break;\n case `ArrowUp`:\n e.preventDefault();\n this._dropdownActiveIndex = this._dropdownActiveIndex <= 0\n ? siblings.length - 1\n : this._dropdownActiveIndex - 1;\n this.#scrollDropdownActiveIntoView();\n break;\n case `Enter`:\n if (this._dropdownActiveIndex >= 0) {\n e.preventDefault();\n this.#selectSibling(this._openIdx, siblings[this._dropdownActiveIndex]);\n }\n break;\n case `Escape`:\n e.preventDefault();\n this.#closeDropdown();\n break;\n }\n };\n\n #scrollDropdownActiveIntoView(): void {\n this.updateComplete.then(() => {\n this.shadowRoot?.querySelector(`.crumb-option.active`)\n ?.scrollIntoView({ block: `nearest` });\n });\n }\n\n #renderDropdownContent(index: number) {\n const siblings = this._cachedSiblings.get(this._openCumPath ?? String(index)) ?? [];\n const isPending = this.#pendingIndex === index;\n\n return html`\n ${isPending ? html`<span class=\"loading-spinner\"></span>` : nothing}\n ${siblings.length === 0 && !isPending\n ? html`<span class=\"crumb-option crumb-option-label\">No items</span>`\n : siblings.map((segment, i) => html`\n <div class=\"crumb-option ${i === this._dropdownActiveIndex ? `active` : ``}\"\n @click=${(e: MouseEvent) => this.#onSiblingClick(index, segment, e)}>\n ${segment.icon\n ? html`<ixfx-icon class=\"crumb-icon\" name=\"${segment.icon}\"></ixfx-icon>`\n : nothing}\n <span class=\"option-label\">${segment.label}</span>\n </div>\n `)}\n `;\n }\n\n #renderSegment(label: string, index: number, isLast: boolean) {\n const isOpen = this._openIdx === index;\n const cumPath = this.#getCumulativePath(index, false);\n const fullPathSegments = this.#resolveFullPathSegments(index, false);\n const icon = this.#resolveSegmentIcon(fullPathSegments, fullPathSegments.length - 1);\n const draggable = this.#segmentDragPayloads(fullPathSegments).length > 0;\n const dragging = this._dragCumPath === cumPath;\n const dropInto = this._dropCumPath === cumPath;\n\n return html`\n <div class=\"seg ${dragging ? `dragging` : ``} ${dropInto ? `drop-into` : ``}\"\n part=${dropInto ? `segment drop-target` : `segment`}\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onSegmentClick(index, e)}\n @dragover=${(e: DragEvent) => this.#onSegDragOver(cumPath, e)}\n @dragleave=${(e: DragEvent) => this.#onSegDragLeave(cumPath, e)}\n @drop=${(e: DragEvent) => this.#onSegDrop(fullPathSegments, e)}>\n <label title=${label}\n part=\"label\"\n ?draggable=${draggable}\n @click=${(e: MouseEvent) => this.#onLabelClick(index, e)}\n @dragstart=${(e: DragEvent) => this.#onLabelDragStart(fullPathSegments, cumPath, e)}\n @dragend=${() => this.#onLabelDragEnd()}>\n ${icon\n ? html`<ixfx-icon class=\"crumb-icon segment-icon\" name=${icon}></ixfx-icon>`\n : nothing}\n ${label}\n </label>\n ${(!isLast || this.siblingLookup) && this._leafSegmentIndex !== index\n ? html`\n <div class=\"caret ${isOpen ? `open` : ``} ${this._confirmedLeafIndices.has(cumPath) ? `disabled` : ``}\"\n part=\"caret\"\n style=\"anchor-name: ${this.#anchorName(cumPath)}\"\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onCaretClick(index, e)}>\n ${this.separator}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n #renderRootSegment(label: string, index: number) {\n const rootSegments = this.#getRootSegments();\n const isLast = index === rootSegments.length - 1;\n const isOpen = this._openIdx === index;\n const cumPath = this.#getCumulativePath(index, true);\n const fullPathSegments = this.#resolveFullPathSegments(index, true);\n const icon = this.#resolveSegmentIcon(fullPathSegments, index);\n const draggable = this.#segmentDragPayloads(fullPathSegments).length > 0;\n const dragging = this._dragCumPath === cumPath;\n const dropInto = this._dropCumPath === cumPath;\n\n return html`\n <div class=\"seg seg-root ${dragging ? `dragging` : ``} ${dropInto ? `drop-into` : ``}\"\n part=${dropInto ? `segment drop-target` : `segment`}\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onRootSegmentClick(index, e)}\n @dragover=${(e: DragEvent) => this.#onSegDragOver(cumPath, e)}\n @dragleave=${(e: DragEvent) => this.#onSegDragLeave(cumPath, e)}\n @drop=${(e: DragEvent) => this.#onSegDrop(fullPathSegments, e)}>\n <label title=${label}\n part=\"label\"\n ?draggable=${draggable}\n @click=${(e: MouseEvent) => this.#onLabelClick(index, e)}\n @dragstart=${(e: DragEvent) => this.#onLabelDragStart(fullPathSegments, cumPath, e)}\n @dragend=${() => this.#onLabelDragEnd()}>${icon\n ? html`<ixfx-icon class=\"crumb-icon segment-icon\" name=${icon}></ixfx-icon>`\n : nothing}${label}</label>\n ${isLast && this.siblingLookup\n ? html`\n <div class=\"caret ${isOpen ? `open` : ``} ${this._confirmedLeafIndices.has(cumPath) ? `disabled` : ``}\"\n part=\"caret\"\n style=\"anchor-name: ${this.#anchorName(cumPath)}\"\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onCaretClick(index, e)}>\n ${this.separator}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n #onRootSegmentClick(index: number, event: MouseEvent): void {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n const rootSegments = this.#getRootSegments();\n const newPath = rootSegments.slice(0, index + 1).join(this.separator);\n this.setPath(newPath);\n }\n\n #onSegmentClick(index: number, event: MouseEvent): void {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n this.#closeDropdown();\n this._editing = true;\n this._editStartIndex = index;\n }\n\n #onTrailingClick() {\n if (this.#clicksSuppressed())\n return;\n this.#closeDropdown();\n this._editing = true;\n this._editStartIndex = null;\n }\n\n #makeCompletionProvider() {\n return async (query: string, signal: AbortSignal): Promise<AcTextItem[]> => {\n if (!this.siblingLookup)\n return [];\n const endsWithSep = query.endsWith(this.separator);\n const parts = query.split(this.separator).filter(p => p.length > 0);\n const parentSegments = endsWithSep ? parts : parts.slice(0, -1);\n const lastSegment = endsWithSep ? `` : (parts.at(-1) ?? ``);\n const hadLeading = query.startsWith(this.separator);\n const children = await this.siblingLookup(\n parentSegments,\n parentSegments.length - 1,\n signal,\n );\n return children\n .filter(c => c.label.toLowerCase().startsWith(lastSegment.toLowerCase()))\n .map((c) => {\n const joined = [...parentSegments, c.label].join(this.separator);\n return { label: hadLeading ? this.separator + joined : joined, icon: c.icon, isLeaf: c.isLeaf };\n });\n };\n }\n\n #onAcChange(e: AcTextChangeEvent) {\n e.stopPropagation();\n const newPath = e.detail.value;\n this.path = newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = newPath.endsWith(this.separator) ? null : newPath.split(this.separator).filter((p: string) => p.length > 0).length - 1;\n this._editing = false;\n this._editingCancelled = false;\n this._editStartIndex = null;\n this.#dispatchChangeEvent(newPath);\n }\n\n #onAcFocusOut() {\n if (this._editing) {\n this._editing = false;\n if (!this._editingCancelled) {\n const el = this.shadowRoot?.querySelector(`ixfx-ac-text`) as any;\n const newPath = el?.value ?? this.path;\n if (newPath !== this.path) {\n this.path = newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = newPath.endsWith(this.separator) ? null : newPath.split(this.separator).filter((p: string) => p.length > 0).length - 1;\n this.#dispatchChangeEvent(newPath);\n }\n }\n this._editingCancelled = false;\n this._editStartIndex = null;\n }\n }\n\n #dispatchChangeEvent(newPath: string): void {\n const segments = newPath.split(this.separator).filter(p => p.length > 0);\n const label = segments.at(-1) ?? ``;\n const parentPath = segments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavChangeDetail>(`change`, {\n detail: { label, parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onAcKeyDown(e: KeyboardEvent) {\n if (e.key === `Escape`) {\n this._editingCancelled = true;\n this._editing = false;\n this._editStartIndex = null;\n }\n }\n\n #onHostKeyDown = (e: KeyboardEvent): void => {\n if (this._editing)\n return;\n const nonEditKeys = [`ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Enter`];\n if (!nonEditKeys.includes(e.key)) {\n this._editing = true;\n }\n };\n\n protected override render() {\n const segments = this.#getSegments();\n\n if (this._editing) {\n const editValue = this.path;\n return html`\n <ixfx-ac-text\n .value=${editValue}\n .tabSuffix=${this.separator}\n .completionProvider=${this.#makeCompletionProvider()}\n @change=${this.#onAcChange}\n @focusout=${this.#onAcFocusOut}\n @keydown=${this.#onAcKeyDown}\n ></ixfx-ac-text>\n `;\n }\n\n const rootSegments = this.#getRootSegments();\n const leadingCaret = this.siblingLookup && rootSegments.length === 0\n ? html`\n <div class=\"caret ${this._openIdx === -1 ? `open` : ``} ${this._confirmedLeafIndices.has(``) ? `disabled` : ``}\"\n style=\"anchor-name: ${this.#anchorName(``)}\"\n data-cumulative=\"\"\n @click=${(e: MouseEvent) => this.#onCaretClick(-1, e)}>\n ${this.separator}\n </div>`\n : nothing;\n\n return html`\n <div class=\"crumbs scroll-fade-x\" tabindex=\"0\" @keydown=${this.#onHostKeyDown}>\n ${rootSegments.length > 0\n ? rootSegments.map((label, i) => this.#renderRootSegment(label, i))\n : nothing}\n ${leadingCaret}\n ${segments.map((label, i) =>\n this.#renderSegment(label, i, i === segments.length - 1),\n )}\n <div class=\"trailing\" @click=${this.#onTrailingClick}></div>\n </div>\n ${this._openIdx !== null\n ? html`\n <div class=\"crumb-dropdown popup-surface\" popover=\"auto\" tabindex=\"-1\"\n @toggle=${this.#onPopoverToggle}\n @keydown=${this.#onDropdownKeyDown}\n @click=${(e: Event) => e.stopPropagation()}>\n ${this.#renderDropdownContent(this._openIdx)}\n </div>\n `\n : nothing}\n `;\n }\n\n static override styles = [prominenceStyles, themeFallbacks, popupSurfaceStyles, scrollFadeStyles(`x`), css`\n :host {\n --text-highlight: var(--accent);\n --separator: var(--surface-muted-text);\n --padding-s: var(--space-xs);\n --padding-m: var(--space-s);\n --hover-bg: var(--surface-5);\n --hover-fg: var(--surface-5-text);\n\n display: flex;\n width: 100%;\n gap: var(--padding-s);\n position: relative;\n }\n\n ixfx-ac-text {\n flex: 1;\n font-size: inherit;\n --ac-input-padding: var(--padding-s) var(--padding-m);\n --ac-input-background: var(--surface-4);\n --ac-input-border-radius: var(--radius-s, 3px);\n --ac-popup-font-size: var(--text-s, 11px);\n }\n\n .crumbs {\n display: flex;\n width: 100%;\n overflow-x:scroll;\n scroll-snap-type:x proximity;\n scrollbar-width: none;\n }\n\n .trailing {\n flex: 1;\n min-width: 1em;\n cursor: text;\n }\n\n .seg {\n scroll-snap-align:start;\n\n position: relative;\n cursor: pointer;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n user-select: none;\n pointer-events: auto;\n }\n\n .seg:hover {\n overflow: unset;\n }\n\n .seg-root {\n opacity: var(--prominence-idle-opacity);\n }\n\n .seg-root:hover {\n opacity: var(--prominence-tickled-opacity);\n }\n\n .seg-root label {\n font-weight: normal;\n }\n\n label {\n display: flex;\n align-items: center;\n gap: var(--padding-s);\n white-space: nowrap;\n text-overflow: ellipsis;\n align-content: center;\n overflow: hidden;\n padding: 0 var(--padding-m);\n transition: all 0.2s ease-in-out;\n border-radius: var(--radius-m);\n }\n\n label:hover,.caret:hover {\n color: var(--item-text-tickled);\n background: var(--item-bg-tickled);\n }\n\n .caret {\n scroll-snap-align:start;\n\n position: relative;\n padding: var(--padding-m);\n transition: all 0.2s ease-in-out;\n\n border-radius: var(--radius-m);\n }\n\n\n .caret.open {\n background: color-mix(in srgb, var(--hover-bg) 40%, transparent);\n }\n\n .caret.disabled {\n opacity: var(--prominence-disabled-opacity);\n cursor: not-allowed;\n }\n\n /* Drag and drop styles */\n label[draggable] {\n cursor: grab;\n }\n\n .seg.dragging {\n opacity: 0.4;\n }\n\n .seg.drop-into {\n outline: var(--crumb-drop-into-outline, 2px solid var(--accent));\n outline-offset: -2px;\n background: var(--crumb-drop-into-bg, color-mix(in srgb, var(--accent) 14%, transparent));\n }\n\n .crumb-icon {\n width: 1em;\n height: 1em;\n flex-shrink: 0;\n }\n\n .crumb-dropdown {\n /* Reset popover UA defaults */\n inset: unset;\n margin: 0;\n\n /* Anchor positioning — position-anchor set dynamically via JS */\n position: fixed;\n position-area: block-end span-inline-end;\n position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;\n margin-block-start: 2px;\n\n min-width: 10ch;\n max-width: min(40ch, 80vw);\n max-height: 280px;\n overflow-y: auto;\n padding: var(--padding-s);\n outline: none;\n }\n\n .crumb-option {\n display: flex;\n align-items: center;\n gap: var(--padding-s);\n padding: var(--padding-s) var(--padding-m);\n cursor: pointer;\n border-radius: var(--radius-s, 4px);\n transition: background 0.15s ease-out;\n overflow: hidden;\n }\n\n .crumb-option:hover,\n .crumb-option.active {\n background: var(--hover-bg);\n color: var(--hover-fg);\n }\n\n .option-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .crumb-option-label {\n font-style: italic;\n opacity: 0.6;\n pointer-events: none;\n user-select: none;\n }\n\n .loading-spinner {\n display: inline-block;\n width: 12px;\n height: 12px;\n border: 2px solid var(--surface-5);\n border-top-color: var(--accent);\n border-radius: 50%;\n animation: crumb-spin 0.7s linear infinite;\n }\n\n @keyframes crumb-spin {\n to { transform: rotate(360deg); }\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-crumb-path': CrumbPathElement;\n }\n}\n\nexport interface CrumbPathElementEventMap {\n \"navigate\": CrumbNavNavigateEvent;\n \"change\": CrumbNavChangeEvent;\n \"expand\": CrumbNavExpandEvent;\n 'crumb-drag-start': CrumbDragStartEvent;\n 'crumb-drop': CrumbDropEvent;\n}\n\nexport interface CrumbPathElement {\n addEventListener: (<K extends keyof CrumbPathElementEventMap>(\n type: K,\n listener: (this: CrumbPathElement, event: CrumbPathElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues, TemplateResult } from 'lit';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { popupSurfaceStyles } from '../styles/popup.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type DataTableRow = {\n label: string;\n value: string | number | boolean | Node | TemplateResult;\n fullWidth?: boolean;\n detail?: string | TemplateResult;\n id?: string;\n};\n\nexport type DataTableRowClickDetail = {\n readonly row: DataTableRow;\n readonly index: number;\n readonly selected: boolean;\n};\n\nexport type DataTableRowClickEvent = CustomEvent<DataTableRowClickDetail>;\n\nexport interface DataTableElementEventMap {\n 'data-table-row-click': DataTableRowClickEvent;\n}\n\n@customElement(`ixfx-data-table`)\nexport class DataTableElement extends LitElement {\n static override styles = [\n tickledStyles,\n tickledItemStyles,\n popupSurfaceStyles,\n css`\n :host {\n display: block;\n container-type: inline-size;\n }\n\n .properties {\n display: grid;\n grid-template-columns: var(--data-table-name-width, max-content)\n var(--data-table-value-width, minmax(0, 1fr));\n /* No column gap: the tickled highlight reads as one solid block.\n Separation comes from cell padding, which the highlight covers. */\n gap: 2px 0;\n }\n\n /* Widening: 2 then 3 property-pairs per row on roomy containers.\n Suppressed when stacked, or when locked to 'columns'. */\n @container (min-width: 650px) {\n :host(:not([layout='columns'])) .properties:not(.stacked) {\n grid-template-columns:\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr))\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr));\n }\n }\n\n @container (min-width: 1000px) {\n :host(:not([layout='columns'])) .properties:not(.stacked) {\n grid-template-columns:\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr))\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr))\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr));\n }\n }\n\n /* Stacked (key above value). Threshold is JS-driven via 'narrowBreakpoint'.\n minmax(0, 1fr) — not 1fr — so a long value's min-content size can't\n blow the column out past the container; the value then ellipsises. */\n .properties.stacked {\n grid-template-columns: minmax(0, 1fr);\n }\n\n /* A pair is its own subgrid so the whole row is one element:\n the tickled highlight can't split, and key/value share a baseline. */\n .pair {\n display: grid;\n grid-column: span 2;\n grid-template-columns: subgrid;\n align-items: var(--data-table-cell-align, baseline);\n cursor: pointer;\n }\n\n .pair[data-full] {\n grid-column: 1 / -1;\n }\n\n .pair[data-full] > .value {\n grid-column: 2 / -1;\n }\n\n .properties.stacked .pair {\n display: block;\n grid-column: 1 / -1;\n /* Let the block shrink below its content so .value-text can clip. */\n min-width: 0;\n }\n\n .properties.stacked .pair:not(:last-child) {\n margin-bottom: var(--space-s);\n }\n\n /* Stacked keys get their own line, so a long label must wrap rather than\n run off the edge (nowrap is only wanted for the max-content column). */\n .properties.stacked .key {\n white-space: normal;\n overflow-wrap: break-word;\n }\n\n .key,\n .value {\n min-width: 0;\n /* Row rhythm comes from this padding (tunable), not line-height. */\n padding: var(--data-table-row-padding, 0.35em) 0;\n }\n\n .key {\n padding-right: var(--space-m);\n opacity: 0.6;\n white-space: nowrap;\n text-align: var(--data-table-name-align, left);\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n /* Uppercase keys have no descenders, so both edges can be trimmed to\n the glyphs for tight baseline / centre alignment. */\n text-box: trim-both cap alphabetic;\n }\n\n .value {\n position: relative;\n padding-right: var(--space-l);\n font: 12px ui-monospace, SFMono-Regular, Menlo, monospace;\n }\n\n /* The value text is clipped here — never on .value itself — so a long\n value stays within its cell even while tickled, and the detail\n popover (a child of .value) can still escape the cell. */\n .value-text {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n /* No text-box trim here: the natural line box gives descenders the room\n overflow:hidden would otherwise clip. Baseline alignment of key and\n value comes from align-items on .pair, which needs no trimming. */\n }\n\n .pair.tickled {\n background: var(--item-bg-tickled, color-mix(in oklch, var(--surface-2), var(--accent) 10%));\n }\n\n /* Lift the row whose detail is open above the rows it slides over. */\n .pair.show-detail {\n position: relative;\n z-index: 1;\n }\n\n .detail {\n position: absolute;\n z-index: 2;\n /* Flush with the bottom of the value (no gap) so the pointer can travel\n from value to panel without crossing a dead zone that would dismiss it.\n Left-aligned with the value; only as wide as its content, capped at\n the table width. */\n top: 100%;\n left: 0;\n right: auto;\n width: max-content;\n max-width: 100cqi;\n padding: var(--space-xs);\n visibility: hidden;\n transform: translateY(-4px);\n pointer-events: none;\n transition: transform var(--transition);\n }\n\n .pair.show-detail .detail {\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n }\n `,\n ];\n\n @property({ type: Array, attribute: false })\n rows: readonly DataTableRow[] = [];\n\n @property({ type: Number, attribute: false })\n selectedIndex: number | undefined;\n\n /**\n * How long (ms) the pointer must rest on a hovered row before its detail\n * panel is revealed. The tickled highlight itself appears immediately on\n * hover; only the detail panel is debounced. Clicking a row reveals its\n * detail straight away, ignoring this delay.\n */\n @property({ type: Number, attribute: `tickle-delay` })\n tickleDelay = 400;\n\n /**\n * Table layout.\n * - `auto` (default): responsive — widens to multiple pair-columns on wide\n * containers, and stacks key above value once narrower than\n * {@link narrowBreakpoint}.\n * - `rows`: always stacked (key above value), regardless of width.\n * - `columns`: always a two-column key/value grid, regardless of width.\n */\n @property({ type: String, reflect: true })\n layout: `auto` | `rows` | `columns` = `auto`;\n\n /**\n * Inline width (px) at or below which the `auto` layout switches to its\n * stacked, key-above-value form. Ignored when {@link layout} is locked.\n */\n @property({ type: Number, attribute: `narrow-breakpoint` })\n narrowBreakpoint = 420;\n\n @state()\n private _tickled = new TickledController<number>(this, {\n getItems: () => this.rows.map((_, i) => ({ id: i, enabled: true })),\n });\n\n /** Index of the row whose detail panel is currently revealed, if any. */\n @state()\n private _detailIndex: number | undefined;\n\n /** Whether the table is currently rendering in its stacked form. */\n @state()\n private _stacked = false;\n\n #detailTimer: ReturnType<typeof setTimeout> | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #lastWidth = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (!entry)\n return;\n this.#lastWidth = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n this.#updateStacked();\n });\n this.#resizeObserver.observe(this);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n clearTimeout(this.#detailTimer);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has(`layout`) || changed.has(`narrowBreakpoint`)) {\n this.#updateStacked();\n }\n }\n\n #updateStacked(): void {\n const stacked = this.layout === `rows`\n ? true\n : this.layout === `columns`\n ? false\n : this.#lastWidth > 0 && this.#lastWidth <= this.narrowBreakpoint;\n if (stacked !== this._stacked)\n this._stacked = stacked;\n }\n\n #handlePointerEnter(i: number): void {\n // Tickle straight away, exactly as a click would.\n this._tickled.handlePointerEnter(i);\n // But hold the detail panel back until the pointer has rested a while.\n clearTimeout(this.#detailTimer);\n if (this._detailIndex !== undefined)\n this._detailIndex = undefined;\n this.#detailTimer = setTimeout(() => {\n if (this._tickled.isTickled(i))\n this._detailIndex = i;\n }, this.tickleDelay);\n }\n\n #handlePointerLeave(e: PointerEvent): void {\n clearTimeout(this.#detailTimer);\n this._detailIndex = undefined;\n this._tickled.handlePointerLeave(e);\n }\n\n #select(i: number): void {\n clearTimeout(this.#detailTimer);\n this.selectedIndex = this.selectedIndex === i ? undefined : i;\n this._tickled.setTickled(i);\n // A click reveals the detail immediately, no debounce.\n this._detailIndex = i;\n this.dispatchEvent(\n new CustomEvent<DataTableRowClickDetail>(`data-table-row-click`, {\n bubbles: true,\n composed: true,\n detail: {\n row: this.rows[i]!,\n index: i,\n selected: this.selectedIndex === i,\n },\n }),\n );\n }\n\n override render(): ReturnType<typeof html> {\n return html`<div\n class=\"properties ${this._stacked ? `stacked` : ``}\"\n @pointerleave=${(e: PointerEvent) => this.#handlePointerLeave(e)}\n >\n ${this.rows.map(\n (r, i) => html`<div\n class=\"pair ${this._tickled.isTickled(i) ? `tickled` : ``} ${\n this._detailIndex === i ? `show-detail` : ``\n }\"\n ?data-full=${r.fullWidth}\n @pointerenter=${() => this.#handlePointerEnter(i)}\n @click=${() => this.#select(i)}\n ><div class=\"key\">${r.label}</div><div class=\"value\"><span class=\"value-text\">${\n typeof r.value === `boolean`\n ? r.value\n ? `Yes`\n : `No`\n : r.value\n }</span>${r.detail === undefined ? nothing : html`<div class=\"detail popup-surface\" part=\"detail\">${r.detail}</div>`}</div></div>`,\n )}</div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-data-table': DataTableElement;\n }\n}\n\nexport interface DataTableElement {\n addEventListener<K extends keyof DataTableElementEventMap>(\n type: K,\n listener: (\n this: DataTableElement,\n event: DataTableElementEventMap[K],\n ) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n","import type { DragGhost } from '../util/drag-ghost.js';\nimport type { DockHostElement } from './dock-host.js';\nimport type { DockDragBoundaryDetail, DockOperation, DockPanelTearOutDetail } from './types.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\n\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly w: number;\n readonly h: number;\n}\n\nexport interface DockDropZone {\n /** Host whose model would receive the drop. */\n readonly host: DockHostElement;\n readonly operation: DockOperation;\n /** Path of the target stack (`[]` = the host root). */\n readonly targetPath: number[];\n readonly side: `before` | `after`;\n /** Insert position for `tabs` drops (panel index in the target stack). */\n readonly gapIndex?: number;\n /** Highlight rect, relative to the host. */\n readonly rect: Rect;\n /** Optional insertion caret for strip gaps, relative to the host. */\n readonly caretRect?: Rect;\n}\n\ninterface DragState {\n panelId: string;\n /** Content kind at drag start — target hosts vet leaf rules without element access. */\n kind?: string;\n sourceHost: DockHostElement;\n pointerId: number;\n ghost: DragGhost | null;\n /** True while the pointer is outside every registered host (tear-out zone). */\n outside: boolean;\n}\n\nlet activeDrag: DragState | null = null;\nconst dragHosts: Set<DockHostElement> = new Set();\n\nexport function registerDockHost(host: DockHostElement): void {\n dragHosts.add(host);\n}\n\nexport function unregisterDockHost(host: DockHostElement): void {\n dragHosts.delete(host);\n if (activeDrag !== null && activeDrag.sourceHost === host) {\n abortDrag();\n }\n}\n\n/**\n * Begin a dock-panel drag. Called by hosts in response to their own\n * `dock-panel-drag-start` events (titlebar or tab-item handles).\n */\nexport function startDrag(\n panelId: string,\n sourceHost: DockHostElement,\n pointerId: number,\n clientX: number,\n clientY: number,\n kind?: string,\n): void {\n if (activeDrag !== null) {\n abortDrag();\n }\n\n const ghost = createGhostForPanel(sourceHost, panelId);\n activeDrag = { panelId, kind, sourceHost, pointerId, ghost, outside: false };\n\n for (const host of dragHosts) {\n host.setDragActive(true);\n }\n\n activeDrag.ghost?.move(clientX, clientY);\n\n window.addEventListener(`pointermove`, onPointerMove);\n window.addEventListener(`pointerup`, onPointerUp);\n window.addEventListener(`pointercancel`, onPointerCancel);\n window.addEventListener(`keydown`, onKeyDown);\n}\n\nfunction createGhostForPanel(host: DockHostElement, panelId: string): DragGhost | null {\n const panel = Array.from(host.children).find(\n (el): el is HTMLElement & { panelId: string; title: string; iconName: string } =>\n el instanceof HTMLElement && (el as { panelId?: string }).panelId === panelId,\n );\n if (!panel)\n return null;\n\n const content = document.createElement(`span`);\n content.style.display = `inline-flex`;\n content.style.alignItems = `center`;\n content.style.gap = `var(--space-xs, 4px)`;\n content.style.minWidth = `0`;\n\n if (panel.iconName) {\n const icon = document.createElement(`ixfx-icon`) as HTMLElement & { name: string };\n icon.name = panel.iconName;\n content.appendChild(icon);\n }\n\n const label = document.createElement(`span`);\n label.textContent = panel.title || panelId;\n label.style.overflow = `hidden`;\n label.style.textOverflow = `ellipsis`;\n label.style.whiteSpace = `nowrap`;\n content.appendChild(label);\n\n try {\n return createDragGhost({ anchor: panel, content });\n } catch {\n return null;\n }\n}\n\nfunction onPointerMove(event: PointerEvent): void {\n const drag = activeDrag;\n if (drag === null || event.pointerId !== drag.pointerId)\n return;\n\n drag.ghost?.move(event.clientX, event.clientY);\n\n const zone = findDropZone(drag, event.clientX, event.clientY);\n for (const host of dragHosts) {\n host.setDropZone(zone !== null && zone.host === host ? zone : null);\n }\n\n // Boundary crossings — the app uses these to start / stop a native window\n // drag when a panel is pulled out past every host.\n const outside = !pointerOverAnyHost(event.clientX, event.clientY);\n if (outside !== drag.outside) {\n drag.outside = outside;\n dispatchBoundary(drag, outside ? `dock-panel-drag-out` : `dock-panel-drag-in`, event);\n }\n}\n\nfunction onPointerUp(event: PointerEvent): void {\n const drag = activeDrag;\n if (drag === null || event.pointerId !== drag.pointerId)\n return;\n\n const zone = findDropZone(drag, event.clientX, event.clientY);\n if (zone !== null) {\n zone.host.handleDrop(drag.panelId, zone, drag.sourceHost);\n } else {\n // Released with no valid zone. If the pointer is outside every host this\n // is a tear-out request: hand the app a snapshot + screen coordinates so\n // it can open a new window and recreate the panel there. The panel is\n // left untouched in the source host — the app calls `detachPanel()` (or\n // `removePanel()`) once it has taken ownership.\n if (!pointerOverAnyHost(event.clientX, event.clientY)) {\n dispatchTearOut(drag, event);\n }\n }\n endDrag();\n}\n\nfunction onPointerCancel(event: PointerEvent): void {\n const drag = activeDrag;\n if (drag === null || event.pointerId !== drag.pointerId)\n return;\n abortDrag();\n endDrag();\n}\n\nfunction onKeyDown(event: KeyboardEvent): void {\n if (activeDrag === null)\n return;\n if (event.key !== `Escape`)\n return;\n abortDrag();\n endDrag();\n}\n\nfunction findDropZone(drag: DragState, clientX: number, clientY: number): DockDropZone | null {\n const sourceIsolated = drag.sourceHost.isolated;\n\n for (const host of dragHosts) {\n if (sourceIsolated && host !== drag.sourceHost)\n continue;\n\n const zone = host.computeDropZone(clientX, clientY, drag.panelId, drag.kind);\n if (zone !== null)\n return zone;\n }\n return null;\n}\n\n/** True when the point lies within the bounding box of any registered host. */\nexport function pointerOverAnyHost(clientX: number, clientY: number): boolean {\n for (const host of dragHosts) {\n const r = host.getBoundingClientRect();\n if (clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom)\n return true;\n }\n return false;\n}\n\nfunction dispatchBoundary(drag: DragState, type: string, event: PointerEvent): void {\n drag.sourceHost.dispatchEvent(new CustomEvent<DockDragBoundaryDetail>(type, {\n detail: {\n panelId: drag.panelId,\n clientX: event.clientX,\n clientY: event.clientY,\n screenX: event.screenX,\n screenY: event.screenY,\n },\n bubbles: true,\n composed: true,\n }));\n}\n\nfunction dispatchTearOut(drag: DragState, event: PointerEvent): void {\n const snapshot = drag.sourceHost.getPanelSnapshot(drag.panelId);\n if (snapshot === null)\n return;\n drag.sourceHost.dispatchEvent(new CustomEvent<DockPanelTearOutDetail>(`dock-panel-tear-out`, {\n detail: {\n panelId: drag.panelId,\n snapshot,\n clientX: event.clientX,\n clientY: event.clientY,\n screenX: event.screenX,\n screenY: event.screenY,\n },\n bubbles: true,\n composed: true,\n }));\n}\n\n/** Drop cancelled — no model mutation. */\nfunction abortDrag(): void {\n // Zone clearing happens in endDrag; nothing else to undo.\n}\n\nfunction endDrag(): void {\n const drag = activeDrag;\n if (drag === null)\n return;\n\n for (const host of dragHosts) {\n host.setDropZone(null);\n host.setDragActive(false);\n }\n\n drag.ghost?.destroy();\n activeDrag = null;\n\n window.removeEventListener(`pointermove`, onPointerMove);\n window.removeEventListener(`pointerup`, onPointerUp);\n window.removeEventListener(`pointercancel`, onPointerCancel);\n window.removeEventListener(`keydown`, onKeyDown);\n}\n\nexport function isDragging(): boolean {\n return activeDrag !== null;\n}\n\nexport function getActiveDragPanelId(): string | null {\n return activeDrag?.panelId ?? null;\n}\n","import type {\n DockAxis,\n DockDirection,\n DockEdge,\n DockLayout,\n DockLeafInfo,\n DockLeafRef,\n DockNeighbours,\n DockNode,\n DockSplitNode,\n DockStackNode,\n} from './types.js';\n\nexport type {\n DockAxis,\n DockDirection,\n DockEdge,\n DockLayout,\n DockLeafInfo,\n DockLeafRef,\n DockNeighbours,\n DockNode,\n DockSplitNode,\n DockStackNode,\n};\n\n/**\n * The dock model is a plain mutable tree owned exclusively by the host\n * element. Mutators below change the tree in place; the host calls\n * `normalize(root)` then `requestUpdate()` after batching mutations.\n */\nexport function isSplit(node: DockNode): node is DockSplitNode {\n return node.kind === `split`;\n}\n\nexport function isStack(node: DockNode): node is DockStackNode {\n return node.kind === `stack`;\n}\n\nexport function createEmptyStack(): DockStackNode {\n return { kind: `stack`, panels: [], active: `` };\n}\n\nexport function createEmptyLayout(): DockLayout {\n return { version: 1, root: createEmptyStack() };\n}\n\nexport function createStack(panels: string[], active?: string, name?: string): DockStackNode {\n const stack: DockStackNode = {\n kind: `stack`,\n panels: [...panels],\n active: active ?? panels[0] ?? ``,\n };\n const trimmed = name?.trim();\n if (trimmed) {\n stack.name = trimmed;\n }\n return stack;\n}\n\nexport function createSplit(direction: DockAxis, children: DockNode[], sizes?: number[]): DockSplitNode {\n const mean = children.length > 0 ? 1 / children.length : 1;\n return {\n kind: `split`,\n direction,\n children: [...children],\n sizes: sizes ? [...sizes] : children.map(() => mean),\n };\n}\n\n// ── Normalize ────────────────────────────────────────────────────────────────\n\n/**\n * Runs after every mutation:\n * - stack `active` fixed to a member of `panels` (or `''` when empty)\n * - empty *unnamed* stacks removed from their parent split (and their\n * `sizes` entry); named empty stacks are kept so the name stays addressable\n * - splits with ≤1 child replaced by that child (spliced into the parent)\n * - a child split whose direction equals its parent's is flattened into it,\n * spreading its sizes across the slot it vacated\n * - `sizes` kept parallel to `children` (padded with the mean weight)\n * - an empty root collapses to a single empty stack\n */\nexport function normalize(root: DockNode): DockNode {\n if (isStack(root)) {\n sanitizeStackName(root);\n if (!root.panels.includes(root.active)) {\n root.active = root.panels[0] ?? ``;\n }\n return root;\n }\n\n // Depth-first: normalize children, then flatten/carry-up at this level.\n for (let i = root.children.length - 1; i >= 0; i--) {\n normalize(root.children[i]);\n\n const child = root.children[i];\n\n // Drop empty stacks, unless named (names stay addressable)\n if (isStack(child) && child.panels.length === 0 && !child.name) {\n root.children.splice(i, 1);\n root.sizes.splice(i, 1);\n continue;\n }\n\n // Carry single-child splits up\n if (isSplit(child) && child.children.length === 1) {\n root.children.splice(i, 1, child.children[0]);\n root.sizes.splice(i, 1, child.sizes[0] ?? root.sizes[i] ?? 1);\n }\n }\n\n // Flatten same-direction child splits into this one\n for (let i = root.children.length - 1; i >= 0; i--) {\n const child = root.children[i];\n if (isSplit(child) && child.direction === root.direction) {\n root.children.splice(i, 1, ...child.children);\n root.sizes.splice(i, 1, ...child.sizes);\n }\n }\n\n // A split with ≤1 child dissolves\n if (root.children.length === 0) {\n return replaceNodeContents(root, createEmptyStack());\n }\n if (root.children.length === 1) {\n return root.children[0];\n }\n\n // Keep sizes parallel to children\n while (root.sizes.length < root.children.length) {\n root.sizes.push(1 / root.children.length);\n }\n if (root.sizes.length > root.children.length) {\n root.sizes.length = root.children.length;\n }\n\n return root;\n}\n\n/**\n * Turn `target` (a stack or split node object) into the shape of `source`'s\n * kind, used when the root itself must dissolve. Mutates `target` in place so\n * the host's root reference stays valid.\n */\nfunction replaceNodeContents(target: DockNode, source: DockNode): DockNode {\n if (isStack(source)) {\n target.kind = `stack`;\n const t = target as DockStackNode;\n t.panels = source.panels;\n t.active = source.active;\n if (source.name !== undefined) {\n t.name = source.name;\n } else {\n delete t.name;\n }\n if (source.hideLabels !== undefined) {\n t.hideLabels = source.hideLabels;\n } else {\n delete t.hideLabels;\n }\n delete t.collapsed;\n delete t.preCollapseSize;\n if (source.collapsed !== undefined)\n t.collapsed = source.collapsed;\n if (source.preCollapseSize !== undefined)\n t.preCollapseSize = source.preCollapseSize;\n } else {\n target.kind = `split`;\n const t = target as DockSplitNode;\n t.direction = source.direction;\n t.children = source.children;\n t.sizes = source.sizes;\n // Drop stale stack-only fields when morphing stack → split\n const stale = t as unknown as Record<string, unknown>;\n delete stale.panels;\n delete stale.active;\n delete stale.name;\n delete stale.collapsed;\n delete stale.preCollapseSize;\n }\n return target;\n}\n\n/** Trim `name`; drop it when empty / non-string so lookups stay predictable. */\nfunction sanitizeStackName(stack: DockStackNode): void {\n if (stack.name === undefined)\n return;\n const trimmed = typeof stack.name === `string` ? stack.name.trim() : ``;\n if (trimmed) {\n stack.name = trimmed;\n } else {\n delete stack.name;\n }\n}\n\n// ── Lookup ───────────────────────────────────────────────────────────────────\n\nexport function findNode(root: DockNode, path: number[]): DockNode | null {\n let current: DockNode = root;\n for (const index of path) {\n if (!isSplit(current))\n return null;\n const next = current.children[index];\n if (!next)\n return null;\n current = next;\n }\n return current;\n}\n\n/** Parent split of the node at `path`; null when path is empty or malformed. */\nexport function findParentOf(root: DockNode, path: number[]): DockSplitNode | null {\n if (path.length === 0)\n return null;\n const parent = findNode(root, path.slice(0, -1));\n return parent !== null && isSplit(parent) ? parent : null;\n}\n\n/** Path of the stack containing `panelId`, or null. */\nexport function findStackOf(root: DockNode, panelId: string): number[] | null {\n return findStackOfInner(root, panelId, []);\n}\n\nfunction findStackOfInner(node: DockNode, panelId: string, path: number[]): number[] | null {\n if (isStack(node)) {\n return node.panels.includes(panelId) ? path : null;\n }\n for (let i = 0; i < node.children.length; i++) {\n const found = findStackOfInner(node.children[i], panelId, [...path, i]);\n if (found !== null)\n return found;\n }\n return null;\n}\n\nexport function collectPanelIds(root: DockNode): string[] {\n if (isStack(root)) {\n return [...root.panels];\n }\n return root.children.flatMap(collectPanelIds);\n}\n\n/**\n * Path of the first stack (tree order) whose `name` matches, or null.\n * Names are expected to be unique per layout; duplicates resolve first-wins.\n */\nexport function findStackPathByName(root: DockNode, name: string): number[] | null {\n const wanted = name.trim();\n if (!wanted)\n return null;\n return findStackPathByNameInner(root, wanted, []);\n}\n\nfunction findStackPathByNameInner(node: DockNode, name: string, path: number[]): number[] | null {\n if (isStack(node)) {\n return node.name === name ? path : null;\n }\n for (let i = 0; i < node.children.length; i++) {\n const found = findStackPathByNameInner(node.children[i], name, [...path, i]);\n if (found !== null)\n return found;\n }\n return null;\n}\n\n/** Names of every named stack leaf, in tree order. */\nexport function collectContainerNames(root: DockNode): string[] {\n const out: string[] = [];\n const visit = (node: DockNode): void => {\n if (isStack(node)) {\n if (node.name)\n out.push(node.name);\n return;\n }\n node.children.forEach(visit);\n };\n visit(root);\n return out;\n}\n\n/**\n * Paths of every stack leaf, in tree order. `[]` is the root itself when it\n * is a stack.\n */\nexport function collectStackPaths(root: DockNode): number[][] {\n const result: number[][] = [];\n collectStackPathsInner(root, [], result);\n return result;\n}\n\nfunction collectStackPathsInner(node: DockNode, path: number[], out: number[][]): void {\n if (isStack(node)) {\n out.push(path);\n return;\n }\n node.children.forEach((child, i) => collectStackPathsInner(child, [...path, i], out));\n}\n\n// ── Mutations (in place; run `normalize` afterwards) ─────────────────────────\n\nexport function addPanelToStack(stack: DockStackNode, panelId: string, index?: number): void {\n const at = index === undefined ? stack.panels.length : Math.max(0, Math.min(index, stack.panels.length));\n stack.panels.splice(at, 0, panelId);\n stack.active = panelId;\n}\n\nexport function removePanelFromStack(stack: DockStackNode, panelId: string): void {\n const index = stack.panels.indexOf(panelId);\n if (index < 0)\n return;\n stack.panels.splice(index, 1);\n if (stack.active === panelId) {\n stack.active = stack.panels[Math.min(index, stack.panels.length - 1)] ?? ``;\n }\n}\n\nexport function setActive(stack: DockStackNode, panelId: string): boolean {\n if (!stack.panels.includes(panelId) || stack.active === panelId)\n return false;\n stack.active = panelId;\n return true;\n}\n\n/**\n * Insert `node` beside the child at `targetPath`, into the parent split when\n * its direction matches `direction`, otherwise wrap the target in a new split.\n * `side` selects before/after; the neighbour's weight is split 50/50.\n * Returns the path of the inserted node, or null.\n */\nexport function insertBeside(\n root: DockNode,\n targetPath: number[],\n direction: DockAxis,\n newNode: DockNode,\n side: `before` | `after`,\n): number[] | null {\n const target = findNode(root, targetPath);\n if (target === null)\n return null;\n\n // Root-level: insert at the edge if the root already matches, else wrap\n if (targetPath.length === 0) {\n if (isSplit(root) && root.direction === direction) {\n const edgeIndex = side === `before` ? 0 : root.children.length;\n const neighbourIndex = side === `before` ? 0 : root.children.length - 1;\n const neighbour = root.sizes[neighbourIndex];\n root.children.splice(edgeIndex, 0, newNode);\n root.sizes.splice(edgeIndex, 0, neighbour !== undefined ? neighbour / 2 : 1);\n if (neighbour !== undefined) {\n root.sizes[side === `before` ? neighbourIndex + 1 : neighbourIndex] = neighbour / 2;\n }\n return [edgeIndex];\n }\n wrapRoot(root, direction, newNode, side);\n return [side === `before` ? 0 : 1];\n }\n\n const parent = findParentOf(root, targetPath);\n if (parent === null)\n return null;\n\n const index = targetPath[targetPath.length - 1];\n\n if (parent.direction === direction) {\n const insertAt = side === `before` ? index : index + 1;\n const w = parent.sizes[index] !== undefined ? parent.sizes[index] / 2 : 1;\n parent.sizes[index] = w;\n parent.children.splice(insertAt, 0, newNode);\n parent.sizes.splice(insertAt, 0, w);\n const childPath = [...targetPath.slice(0, -1), insertAt];\n normalize(root);\n return childPath;\n }\n\n const wrapper = createSplit(direction, side === `before` ? [newNode, target] : [target, newNode]);\n parent.children[index] = wrapper;\n normalize(root);\n const childIndex = side === `before` ? 0 : 1;\n return [...targetPath.slice(0, -1), index, childIndex];\n}\n\n/**\n * Wrap the whole root in a new split of `direction`, replacing it in place so\n * the caller's reference stays valid. Returns true on success.\n */\nexport function wrapRoot(root: DockNode, direction: DockAxis, newNode: DockNode, side: `before` | `after`): boolean {\n // The wrapper's inner child must be a *copy* of the root's current contents,\n // not `root` itself: `replaceNodeContents` morphs `root` in place, so passing\n // the live reference would leave `root.children` holding `root` — a cycle that\n // makes `normalize` recurse until the stack overflows.\n const inner = cloneNodeShallow(root);\n const wrapper = createSplit(direction, side === `before` ? [newNode, inner] : [inner, newNode]);\n replaceNodeContents(root, wrapper);\n normalize(root);\n return true;\n}\n\n/**\n * Detached copy of `node` (own arrays copied) so it can become a child of a\n * wrapper that then replaces `node` in place.\n */\nfunction cloneNodeShallow(node: DockNode): DockNode {\n if (isStack(node)) {\n return { ...node, panels: [...node.panels] };\n }\n return { ...node, children: [...node.children], sizes: [...node.sizes] };\n}\n\n/**\n * Remove the stack at `stackPath` from the tree. Its panels are moved into\n * `fallbackStack` (if given and still attached) so they are not silently\n * lost; otherwise they are dropped from the model (elements return to the\n * pool). Returns the removed stack.\n */\nexport function extractStack(root: DockNode, stackPath: number[], fallbackStack?: DockStackNode): DockStackNode | null {\n const stack = findNode(root, stackPath);\n if (stack === null || !isStack(stack))\n return null;\n\n const isRoot = stackPath.length === 0;\n\n if (fallbackStack && fallbackStack !== stack) {\n for (const id of stack.panels) {\n addPanelToStack(fallbackStack, id);\n }\n // Only keep the panels in one place\n if (!isRoot) {\n stack.panels = [];\n stack.active = ``;\n }\n }\n\n if (isRoot) {\n replaceNodeContents(root, createEmptyStack());\n return stack;\n }\n\n const parent = findParentOf(root, stackPath);\n if (parent === null)\n return null;\n\n const index = stackPath[stackPath.length - 1];\n parent.children.splice(index, 1);\n parent.sizes.splice(index, 1);\n normalize(root);\n return stack;\n}\n\n// ── Spatial (geometry + leaf moves) ──────────────────────────────────────────\n//\n// Leaves are positioned by subdividing a unit square along each split\n// (child share = `sizes[i] / sum(sizes)`). Neighbour queries and moves below\n// are derived from that geometry, so they reflect what the user sees rather\n// than raw tree adjacency.\n\n/** Tolerance for edge-touch comparisons in unit-square geometry. */\nconst GEOM_EPS = 1e-9;\n\nexport interface DockRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface LeafGeom {\n path: number[];\n name: string | null;\n rect: DockRect;\n}\n\nfunction pathsEqual(a: readonly number[], b: readonly number[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n}\n\n/**\n * Resolve a {@link DockLeafRef} to a stack path. Strings match container\n * `name` first-wins; arrays must index an existing stack leaf. Returns null\n * when unresolvable.\n */\nexport function resolveLeafPath(root: DockNode, ref: DockLeafRef): number[] | null {\n if (typeof ref === `string`) {\n return findStackPathByName(root, ref);\n }\n if (!Array.isArray(ref)) {\n return null;\n }\n let current: DockNode = root;\n for (const index of ref) {\n if (!Number.isInteger(index) || (index as number) < 0) {\n return null;\n }\n if (!isSplit(current)) {\n return null;\n }\n const next = current.children[index as number];\n if (!next) {\n return null;\n }\n current = next;\n }\n return isStack(current) ? [...ref] : null;\n}\n\n/** Absolute (unit-square) rect of every stack leaf, in tree order. */\nexport function computeLeafGeoms(root: DockNode): LeafGeom[] {\n const out: LeafGeom[] = [];\n const visit = (node: DockNode, path: number[], rect: DockRect): void => {\n if (isStack(node)) {\n out.push({ path, name: node.name ?? null, rect });\n return;\n }\n const total = node.sizes.reduce((sum, w) => sum + w, 0);\n const safe = total > 0 ? total : node.children.length || 1;\n let offset = 0;\n node.children.forEach((child, i) => {\n const frac = (node.sizes[i] ?? safe / node.children.length) / safe;\n if (node.direction === `row`) {\n const w = rect.w * frac;\n visit(child, [...path, i], { x: rect.x + offset, y: rect.y, w, h: rect.h });\n offset += w;\n } else {\n const h = rect.h * frac;\n visit(child, [...path, i], { x: rect.x, y: rect.y + offset, w: rect.w, h });\n offset += h;\n }\n });\n };\n visit(root, [], { x: 0, y: 0, w: 1, h: 1 });\n return out;\n}\n\nfunction intervalOverlap(a0: number, a1: number, b0: number, b1: number): number {\n return Math.min(a1, b1) - Math.max(a0, b0);\n}\n\n/**\n * Geometric neighbours of a leaf — what the user sees above / below / left /\n * right of it. Each list holds `{ name, path }` (name is null for unnamed\n * leaves), ordered most-overlapping first. Returns null when `ref` is\n * unresolvable.\n */\nexport function getLeafNeighbours(root: DockNode, ref: DockLeafRef): DockNeighbours | null {\n const path = resolveLeafPath(root, ref);\n if (path === null) {\n return null;\n }\n const geoms = computeLeafGeoms(root);\n const self = geoms.find(g => pathsEqual(g.path, path));\n if (!self) {\n return null;\n }\n const s = self.rect;\n type Hit = { info: DockLeafInfo; overlap: number; order: number };\n const above: Hit[] = [];\n const below: Hit[] = [];\n const left: Hit[] = [];\n const right: Hit[] = [];\n geoms.forEach((g, order) => {\n if (g === self) {\n return;\n }\n const r = g.rect;\n const info: DockLeafInfo = { name: g.name, path: [...g.path] };\n if (Math.abs(r.y + r.h - s.y) < GEOM_EPS) {\n const o = intervalOverlap(r.x, r.x + r.w, s.x, s.x + s.w);\n if (o > GEOM_EPS)\n above.push({ info, overlap: o, order });\n }\n if (Math.abs(s.y + s.h - r.y) < GEOM_EPS) {\n const o = intervalOverlap(r.x, r.x + r.w, s.x, s.x + s.w);\n if (o > GEOM_EPS)\n below.push({ info, overlap: o, order });\n }\n if (Math.abs(r.x + r.w - s.x) < GEOM_EPS) {\n const o = intervalOverlap(r.y, r.y + r.h, s.y, s.y + s.h);\n if (o > GEOM_EPS)\n left.push({ info, overlap: o, order });\n }\n if (Math.abs(s.x + s.w - r.x) < GEOM_EPS) {\n const o = intervalOverlap(r.y, r.y + r.h, s.y, s.y + s.h);\n if (o > GEOM_EPS)\n right.push({ info, overlap: o, order });\n }\n });\n const rank = (hits: Hit[]): DockLeafInfo[] =>\n hits.sort((a, b) => b.overlap - a.overlap || a.order - b.order).map(h => h.info);\n return { above: rank(above), below: rank(below), left: rank(left), right: rank(right) };\n}\n\n/**\n * Exchange two leaves' positions in the tree, each carrying its size slot so\n * the remaining structure and proportions are untouched. Returns false when\n * either path is not a stack leaf.\n */\nexport function swapLeaves(root: DockNode, pathA: number[], pathB: number[]): boolean {\n if (pathsEqual(pathA, pathB)) {\n return false;\n }\n const nodeA = findNode(root, pathA);\n const nodeB = findNode(root, pathB);\n if (nodeA === null || nodeB === null || !isStack(nodeA) || !isStack(nodeB)) {\n return false;\n }\n const parentA = findParentOf(root, pathA);\n const parentB = findParentOf(root, pathB);\n if (parentA === null || parentB === null) {\n return false;\n }\n const indexA = pathA[pathA.length - 1];\n const indexB = pathB[pathB.length - 1];\n if (parentA === parentB) {\n const p = parentA;\n [p.children[indexA], p.children[indexB]] = [p.children[indexB], p.children[indexA]];\n [p.sizes[indexA], p.sizes[indexB]] = [p.sizes[indexB] ?? 1, p.sizes[indexA] ?? 1];\n return true;\n }\n const carriedNode = parentA.children[indexA];\n const carriedSize = parentA.sizes[indexA] ?? 1;\n parentA.children[indexA] = parentB.children[indexB];\n parentA.sizes[indexA] = parentB.sizes[indexB] ?? 1;\n parentB.children[indexB] = carriedNode;\n parentB.sizes[indexB] = carriedSize;\n return true;\n}\n\n/**\n * Move a leaf one position in `direction`, swapping with the neighbour it\n * shares the longest edge with. Returns false when `ref` is unresolvable or\n * nothing adjoins in that direction. Run `normalize()` afterwards.\n */\nexport function moveLeafStep(root: DockNode, ref: DockLeafRef, direction: DockDirection): boolean {\n const path = resolveLeafPath(root, ref);\n if (path === null) {\n return false;\n }\n const neighbours = getLeafNeighbours(root, ref);\n if (neighbours === null) {\n return false;\n }\n const list = direction === `up`\n ? neighbours.above\n : direction === `down`\n ? neighbours.below\n : direction === `left`\n ? neighbours.left\n : neighbours.right;\n if (list.length === 0) {\n return false;\n }\n return swapLeaves(root, path, list[0].path);\n}\n\n/**\n * Move a leaf to an edge of the overall layout, keeping the rest of the\n * tree intact as a single subtree and preserving the leaf's absolute size\n * along the target axis. Returns false when `ref` is unresolvable or the\n * layout holds a single leaf. Run `normalize()` afterwards (also safe to\n * call it twice — the host's commit does).\n */\nexport function moveLeafNodeToEdge(root: DockNode, ref: DockLeafRef, edge: DockEdge): boolean {\n const path = resolveLeafPath(root, ref);\n if (path === null || path.length === 0) {\n return false;\n }\n const geoms = computeLeafGeoms(root);\n const self = geoms.find(g => pathsEqual(g.path, path));\n if (!self) {\n return false;\n }\n const horizontal = edge === `left` || edge === `right`;\n const frac = Math.min(Math.max(horizontal ? self.rect.w : self.rect.h, 0.05), 0.95);\n if (!(frac > 0) || frac >= 1) {\n return false;\n }\n\n const parent = findParentOf(root, path);\n if (parent === null) {\n return false;\n }\n const [node] = parent.children.splice(path[path.length - 1], 1);\n parent.sizes.splice(path[path.length - 1], 1);\n if (!node) {\n return false;\n }\n normalize(root);\n\n const atStart = edge === `left` || edge === `top`;\n const direction: DockAxis = horizontal ? `row` : `column`;\n\n if (isStack(root)) {\n // One leaf remains: wrap it so the moved leaf keeps its absolute share.\n const rest = root;\n const remaining: DockStackNode = { kind: `stack`, panels: [...rest.panels], active: rest.active };\n if (rest.name !== undefined)\n remaining.name = rest.name;\n if (rest.collapsed !== undefined)\n remaining.collapsed = rest.collapsed;\n if (rest.preCollapseSize !== undefined)\n remaining.preCollapseSize = rest.preCollapseSize;\n const wrapper: DockSplitNode = {\n kind: `split`,\n direction,\n children: atStart ? [node, remaining] : [remaining, node],\n sizes: atStart ? [frac, 1 - frac] : [1 - frac, frac],\n };\n replaceNodeContents(root, wrapper);\n return true;\n }\n\n if (isSplit(root) && root.direction === direction) {\n const sum = root.sizes.reduce((total, w) => total + w, 0) || root.children.length || 1;\n const size = frac * sum / (1 - frac);\n const at = atStart ? 0 : root.children.length;\n root.children.splice(at, 0, node);\n root.sizes.splice(at, 0, size);\n return true;\n }\n\n if (isSplit(root)) {\n // Other axis: nest the whole layout so its structure is untouched.\n const inner: DockSplitNode = { kind: `split`, direction: root.direction, children: root.children, sizes: root.sizes };\n const wrapper: DockSplitNode = {\n kind: `split`,\n direction,\n children: atStart ? [node, inner] : [inner, node],\n sizes: atStart ? [frac, 1 - frac] : [1 - frac, frac],\n };\n replaceNodeContents(root, wrapper);\n return true;\n }\n\n return false;\n}\n\n// ── Serialization ────────────────────────────────────────────────────────────\n\nexport function serializeLayout(root: DockNode): DockLayout {\n return {\n version: 1,\n root: serializeNode(root),\n };\n}\n\nfunction serializeNode(node: DockNode): DockNode {\n if (isStack(node)) {\n const out: DockStackNode = {\n kind: `stack`,\n panels: [...node.panels],\n active: node.active,\n };\n if (node.name !== undefined)\n out.name = node.name;\n if (node.hideLabels !== undefined)\n out.hideLabels = node.hideLabels;\n if (node.collapsed !== undefined)\n out.collapsed = node.collapsed;\n if (node.preCollapseSize !== undefined)\n out.preCollapseSize = node.preCollapseSize;\n return out;\n }\n return {\n kind: `split`,\n direction: node.direction,\n sizes: [...node.sizes],\n children: node.children.map(serializeNode),\n };\n}\n\n/**\n * Parse layout JSON, validate loosely, and normalize. Returns null when the\n * JSON is malformed or the root is missing/invalid.\n */\nexport function parseLayout(json: string): DockLayout | null {\n try {\n const parsed = JSON.parse(json) as DockLayout | null;\n if (parsed === null || typeof parsed !== `object`)\n return null;\n const root = (parsed as DockLayout).root;\n if (root === null || typeof root !== `object` || !(`kind` in root))\n return null;\n return { version: 1, root: normalize(root) };\n } catch {\n return null;\n }\n}\n","import type { CommandRegistry } from \"@clinth/ui-commands\";\nimport type { PropertyValues } from \"lit\";\nimport { css, html, LitElement, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport \"../icons/icon.js\";\n\n/**\n * CSS vars (can be overridden per-instance):\n * --selected-colour: text colour when selected\n * --selected-border-width: border width\n * --ixfx-tab-padding: vertical padding for the tab content (default: var(--space-m))\n * --ixfx-tab-padding-horizontal: horizontal padding (default: same as --ixfx-tab-padding)\n */\n@customElement(`ixfx-tab-list-item`)\nexport class TabListItemElement extends LitElement {\n @property({ type: Boolean })\n closeable = false;\n\n @property({ type: Boolean, attribute: `hide-labels` })\n hideLabels = false;\n\n /**\n * Label does not stretch to fill the tab (`flex: 0 0 auto` instead of\n * `1 1 auto`), so status content sits next to the label instead of being\n * pushed to the far edge. Set on the item, or on `ixfx-tab-list` which\n * mirrors it onto every item.\n */\n @property({ type: Boolean, attribute: `label-nogrow` })\n labelNogrow = false;\n\n @property({ type: String, attribute: `icon-name` })\n iconName: string | undefined = undefined;\n\n @property({ type: String })\n description: string | undefined = undefined;\n\n @property({ type: String, attribute: `command-active` })\n commandActive: string | undefined = undefined;\n\n @property({ attribute: false })\n registry: CommandRegistry<unknown> | undefined = undefined;\n\n @state() private _compact = false;\n @state() private _hasToolbarContent = false;\n @state() private _hasStatusContent = false;\n private _resizeObserver?: ResizeObserver;\n private _commandCleanup?: () => void;\n private _labelObserver: MutationObserver | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(([entry]) => {\n this._compact = entry.contentRect.width < 64;\n });\n this._resizeObserver.observe(this);\n this._wireSlotListeners();\n // In-place text edits (e.g. Lit re-rendering a title) don't fire\n // slotchange, so watch the light DOM too. Also covers status-slot\n // content added/removed before the slot itself is rendered.\n this._labelObserver = new MutationObserver(() => {\n this._syncLabelSizer();\n this._updateToolbarContent();\n this._updateStatusContent();\n });\n this._labelObserver.observe(this, {\n childList: true,\n characterData: true,\n subtree: true,\n attributes: true,\n attributeFilter: [`slot`],\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n this._resizeObserver = undefined;\n this._commandCleanup?.();\n this._commandCleanup = undefined;\n this._labelObserver?.disconnect();\n this._labelObserver = null;\n this._unwireSlotListeners();\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._syncTooltipAttrs();\n if (changed.has(`registry`) || changed.has(`commandActive`)) {\n this._syncCommandListener();\n }\n }\n\n private _syncTooltipAttrs(): void {\n if (this.description) {\n this.setAttribute(`data-tooltip`, this.description);\n this.setAttribute(`data-tooltip-anchor`, `top`);\n } else {\n this.removeAttribute(`data-tooltip`);\n this.removeAttribute(`data-tooltip-anchor`);\n }\n }\n\n private _syncCommandListener(): void {\n this._commandCleanup?.();\n this._commandCleanup = undefined;\n if (this.registry && this.commandActive) {\n this._commandCleanup = this.registry.addOnInvokeHandler((id) => {\n if (id === this.commandActive)\n this.click();\n });\n }\n }\n\n private _onToolbarSlotChange = () => {\n this._updateToolbarContent();\n };\n\n private _onStatusSlotChange = () => {\n this._updateStatusContent();\n };\n\n private _onLabelSlotChange = () => {\n this._syncLabelSizer();\n };\n\n /**\n * Attach slotchange listeners. The shadow root is empty during the first\n * connectedCallback (the template only exists once rendered), so this is\n * called again from firstUpdated. addEventListener dedupes identical\n * listener registrations, so double-wiring is harmless.\n */\n private _wireSlotListeners(): void {\n const toolbarSlot = this.shadowRoot?.querySelector(`slot[name=\"toolbar\"]`);\n toolbarSlot?.addEventListener(`slotchange`, this._onToolbarSlotChange);\n const statusSlot = this.shadowRoot?.querySelector(`slot[name=\"status\"]`);\n statusSlot?.addEventListener(`slotchange`, this._onStatusSlotChange);\n const labelSlot = this.shadowRoot?.querySelector(`slot:not([name])`);\n labelSlot?.addEventListener(`slotchange`, this._onLabelSlotChange);\n }\n\n private _unwireSlotListeners(): void {\n const toolbarSlot = this.shadowRoot?.querySelector(`slot[name=\"toolbar\"]`);\n toolbarSlot?.removeEventListener(`slotchange`, this._onToolbarSlotChange);\n const statusSlot = this.shadowRoot?.querySelector(`slot[name=\"status\"]`);\n statusSlot?.removeEventListener(`slotchange`, this._onStatusSlotChange);\n const labelSlot = this.shadowRoot?.querySelector(`slot:not([name])`);\n labelSlot?.removeEventListener(`slotchange`, this._onLabelSlotChange);\n }\n\n /**\n * Mirror the default-slot text into `.label[data-label]` for the `::after`\n * width sizer. Slotted toolbar content is excluded.\n */\n private _syncLabelSizer(): void {\n const slot = this.shadowRoot?.querySelector(`slot:not([name])`) as HTMLSlotElement | null;\n const label = this.shadowRoot?.querySelector(`.label`);\n if (slot === null || slot === undefined || label === null || label === undefined) {\n return;\n }\n const text = slot.assignedNodes()\n .filter(node => !(node instanceof HTMLElement && node.hasAttribute(`slot`)))\n .map(node => node.textContent ?? ``)\n .join(``);\n if (text) {\n label.setAttribute(`data-label`, text);\n } else {\n label.removeAttribute(`data-label`);\n }\n }\n\n private _updateToolbarContent() {\n this._hasToolbarContent = Array.from(this.children).some(child => child.getAttribute(`slot`) === `toolbar`);\n }\n\n /**\n * Named slots only render once content has been detected, so reading\n * assignedElements() cannot bootstrap detection. Direct light-DOM children\n * are exactly what a slot assigns, so scan those instead.\n */\n private _updateStatusContent() {\n this._hasStatusContent = Array.from(this.children).some(child => child.getAttribute(`slot`) === `status`);\n }\n\n override firstUpdated() {\n this._wireSlotListeners();\n this._updateToolbarContent();\n this._updateStatusContent();\n this._syncLabelSizer();\n }\n\n override render() {\n const showLabel = !this.hideLabels || !this.iconName;\n const hasActions = this.closeable || this._hasToolbarContent;\n return html`\n <div>\n ${this.iconName ? html`<ixfx-icon name=\"${this.iconName}\"></ixfx-icon>` : nothing}\n ${showLabel ? html`<span class=\"label\"><slot></slot></span>` : nothing}\n ${this._hasStatusContent ? html`<div class=\"status\"><slot name=\"status\"></slot></div>` : nothing}\n ${hasActions\n ? html`\n <div class=\"actions\">\n <div class=\"toolbar\"><slot name=\"toolbar\"></slot></div>\n ${this.closeable\n ? html`\n <button\n class=\"close-btn\"\n type=\"button\"\n aria-label=\"Close tab\"\n @click=${this._onCloseClick}\n >\n <ixfx-icon name=\"close\"></ixfx-icon>\n </button>\n `\n : nothing}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n private _onCloseClick(e: Event) {\n e.stopPropagation();\n this.dispatchEvent(\n new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }),\n );\n this.remove();\n }\n\n static override styles = [\n themeFallbacks,\n prominenceStyles,\n css`\n :host {\n --selected-tab-color: var(--ixfx-selected-tab-color, var(--surface-2-text));\n --selected-tab-icon-color: var(--ixfx-selected-tab-icon-color, var(--accent));\n --selected-tab-border-width: var(--ixfx-selected-tab-border-width, 1px);\n --selected-tab-weight: var(--ixfx-selected-tab-weight, bold);\n --selected-tab-text-decoration: var(--ixfx-selected-tab-text-decoration, none);\n --selected-tab-text-decoration-color: var(--ixfx-selected-tab-text-decoration-color, var(--accent));\n --selected-tab-text-decoration-thickness: var(--ixfx-selected-tab-text-decoration-thickness, 0px);\n --selected-tab-text-decoration-offset: var(--ixfx-selected-tab-text-decoration-offset, 2px);\n --selected-background: var(--ixfx-tab-selected-background, var(--surface-5));\n --tab-padding: var(--ixfx-tab-padding, var(--space-s));\n display: inline-flex;\n min-width: 0;\n user-select: none;\n box-sizing: border-box;\n font-size: var(--text-m);\n color: inherit;\n /* No explicit height: items stretch (align-self: stretch via the\n list's flex container) so every tab in a strip shares one height\n even when toolbars give some items taller content. */\n }\n\n :host > div {\n display: flex;\n align-items: center;\n padding: var(--tab-padding) calc(2 * var(--tab-padding-horizontal, var(--tab-padding)));\n min-width: 0;\n width: 100%;\n font-weight: 500;\n border: var(--selected-tab-border-width) solid transparent;\n gap: var(--space-s);\n transition: background var(--transition, 0.15s);\n }\n\n /* Hover (\"tickle\") background. When --ixfx-tab-hover-background is\n unset each state keeps its resting background, so existing\n consumers see no change. */\n :host(:hover:not([selected])) > div {\n background: var(--ixfx-tab-hover-background, transparent);\n }\n\n :host([selected]:hover) > div {\n background: var(--ixfx-tab-hover-background, var(--selected-background));\n }\n\n :host([selected]) > div {\n color: var(--selected-tab-color);\n border-top-color: var(--indicator-color-top, transparent);\n border-bottom-color: var(--indicator-color-bottom, transparent);\n border-left-color: var(--indicator-color-left, transparent);\n border-right-color: var(--indicator-color-right, transparent);\n background: var(--selected-background);\n font-weight: var(--selected-tab-weight);\n border-radius:var(--radius-m);\n }\n\n :host([selected]) .label {\n text-decoration: var(--selected-tab-text-decoration);\n text-decoration-color: var(--selected-tab-text-decoration-color);\n text-decoration-thickness: var(--selected-tab-text-decoration-thickness);\n text-decoration-offset: var(--selected-tab-text-decoration-offset);\n }\n\n .label {\n overflow: var(--allow-overflow, hidden);\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n flex: 1 1 auto;\n }\n\n /* Width sizer: an invisible copy of the label, always set at the\n selected weight, so activating a tab (bold) never shifts the strip.\n Text is mirrored from the default slot via the data-label attribute\n (see _syncLabelSizer). */\n .label::after {\n content: attr(data-label);\n display: block;\n height: 0;\n overflow: hidden;\n visibility: hidden;\n font-weight: var(--selected-tab-weight);\n }\n\n ixfx-icon {\n flex-shrink: 0;\n }\n\n /* Leading icon (direct child — not close/toolbar icons) picks up the\n accent when selected, so icon-only tabs read as active. */\n :host([selected]) > div > ixfx-icon {\n color: var(--selected-tab-icon-color);\n }\n\n .actions {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n margin-left: auto;\n flex-shrink: 0;\n }\n\n .toolbar {\n /* Always laid out (display: flex) so the tab's width doesn't shift when\n the toolbar appears on selection. visibility: hidden keeps the\n toolbar from receiving pointer events or painting, while preserving\n the space its contents take up. */\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n visibility: hidden;\n }\n\n :host([selected]) .toolbar {\n visibility: visible;\n }\n\n slot[name=\"toolbar\"] {\n display: contents;\n }\n\n /* Persistent status slot (e.g. an ixfx-led). Unlike .toolbar it is\n always visible, selection or not, and keeps its own size however\n much the label truncates. --size inherits through slotted content,\n so bare and button-wrapped LEDs both render smaller; consumers can\n override per element. */\n .status {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n --size: 0.75ex;\n }\n\n slot[name=\"status\"] {\n display: contents;\n }\n\n /* With label-nogrow, the label keeps its intrinsic width so status\n content lands next to the label text instead of the far edge. */\n :host([label-nogrow]) .label {\n flex: 0 0 auto;\n }\n\n /* Slotted buttons inherit these through the shadow boundary; keeps a\n toolbar button from inflating the strip height. */\n .toolbar ::slotted(ixfx-button) {\n --ixfx-button-padding-block: var(--space-xs);\n }\n\n .close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: var(--space-xs);\n cursor: pointer;\n color: inherit;\n border-radius: var(--radius-s);\n opacity: var(--prominence-idle-opacity);\n transition: opacity var(--transition), background var(--transition);\n }\n\n .close-btn:hover {\n background: var(--surface-5);\n opacity: var(--prominence-tickled-opacity);\n }\n\n .close-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n }\n\n :host([selected]) .close-btn,\n :host(:hover) .close-btn {\n opacity: var(--prominence-tickled-opacity);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-tab-list-item\": TabListItemElement;\n }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { TitlebarCloseEvent, TitlebarToggleDetail, TitlebarToggleEvent } from '../titlebar/titlebar.js';\nimport type { DockPanelDragStartDetail, DockPanelDragStartEvent } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../titlebar/titlebar.js';\n\n/** Pointer movement threshold before a titlebar press becomes a dock drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\nexport type { DockPanelDragStartEvent };\n\nexport interface DockPanelElementEventMap {\n 'dock-panel-drag-start': DockPanelDragStartEvent;\n 'toggle': TitlebarToggleEvent;\n 'close': TitlebarCloseEvent;\n}\n\n/**\n * Leaf content + metadata + drag handle. Renders `ixfx-titlebar` chrome when\n * standalone (`presentation=\"solo\"`) and content only when docked\n * (`presentation=\"tabbed\"` — the host's tab strip carries the title chrome).\n * Adds `panel-id` and the titlebar drag handle. Works standalone outside a\n * host (the drag-start event has no listener and is inert).\n */\n@customElement(`ixfx-dock-panel`)\nexport class DockPanelElement extends LitElement {\n /** Stable identity: model key, slot name suffix, serialization id. */\n @property({ type: String, attribute: `panel-id`, reflect: true })\n panelId = ``;\n\n /**\n * Display text (tab label, titlebar). Stored in the `label` attribute —\n * deliberately not `title`, so browsers never tooltip it.\n */\n @property({ type: String, attribute: `label` })\n title = ``;\n\n @property({ type: String, attribute: `icon-name` })\n iconName = ``;\n\n @property({ type: Boolean })\n closable = false;\n\n @property({ type: Boolean })\n collapsible = false;\n\n /**\n * Content kind for the host's leaf placement rules\n * (`setLeafExclusiveContents` / `setLeafDenyContents`). Matched literally;\n * defaults to `'any'`.\n */\n @property({ type: String, reflect: true })\n kind = `any`;\n\n /**\n * Per-panel restriction when this panel is itself a drop target (solo\n * leaf). Space-separated `tabs` / `horizontal` / `vertical` / `all`;\n * `none` rejects everything; default is unrestricted.\n */\n @property({ type: String, attribute: `accepts` })\n accepts = ``;\n\n /**\n * Host-controlled. Docked panels are always `tabbed` (content only — the\n * leaf's tab strip carries the title chrome). `solo` (full titlebar chrome)\n * applies to panels outside a host or not currently docked.\n */\n @property({ type: String, reflect: true })\n presentation: `solo` | `tabbed` = `solo`;\n\n /** Solo-mode collapse state, mirrored from the titlebar. */\n @state()\n private _collapsed = false;\n\n private _dragPointerId: number | null = null;\n private _dragStartX = 0;\n private _dragStartY = 0;\n private _dragStarted = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Legacy alias: adopt a `title` attribute into the property, then drop\n // it — a lingering native `title` attribute would tooltip on hover.\n // (`title` is unobserved, so removal has no side effects.)\n if (this.hasAttribute(`title`)) {\n if (!this.hasAttribute(`label`)) {\n this.title = this.getAttribute(`title`) ?? ``;\n }\n this.removeAttribute(`title`);\n }\n this.addEventListener(`pointerdown`, this._onPointerDown as EventListener);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardownDragListeners();\n this.removeEventListener(`pointerdown`, this._onPointerDown as EventListener);\n }\n\n // ── Titlebar drag handle ─────────────────────────────────────────────────\n\n private _onPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0)\n return;\n if (this.presentation === `tabbed`)\n return; // tab items are the drag handle in tabbed mode (host-driven)\n if (!this._isDragHandle(event))\n return;\n\n this._dragPointerId = event.pointerId;\n this._dragStartX = event.clientX;\n this._dragStartY = event.clientY;\n this._dragStarted = false;\n\n window.addEventListener(`pointermove`, this._onPointerMove);\n window.addEventListener(`pointerup`, this._onPointerUp);\n window.addEventListener(`pointercancel`, this._onPointerUp);\n };\n\n private _onPointerMove = (event: PointerEvent): void => {\n if (this._dragPointerId === null || event.pointerId !== this._dragPointerId)\n return;\n\n if (!this._dragStarted) {\n const distance = Math.hypot(event.clientX - this._dragStartX, event.clientY - this._dragStartY);\n if (distance < DRAG_THRESHOLD_PX)\n return;\n this._dragStarted = true;\n const pointerId = this._dragPointerId;\n this._teardownDragListeners();\n this._dispatchDragStart(pointerId, event.clientX, event.clientY);\n }\n };\n\n private _onPointerUp = (event: PointerEvent): void => {\n if (this._dragPointerId === null || event.pointerId !== this._dragPointerId)\n return;\n this._teardownDragListeners();\n };\n\n private _teardownDragListeners(): void {\n this._dragPointerId = null;\n this._dragStarted = false;\n window.removeEventListener(`pointermove`, this._onPointerMove);\n window.removeEventListener(`pointerup`, this._onPointerUp);\n window.removeEventListener(`pointercancel`, this._onPointerUp);\n }\n\n /** Clicks that begin on the close / caret buttons or the toolbar are not drags. */\n private _isDragHandle(event: PointerEvent): boolean {\n for (const node of event.composedPath()) {\n if (!(node instanceof HTMLElement))\n continue;\n if (node.classList.contains(`close-btn`) || node.classList.contains(`caret-btn`) || node.classList.contains(`toolbar`)) {\n return false;\n }\n }\n return true;\n }\n\n private _dispatchDragStart(pointerId: number, clientX: number, clientY: number): void {\n if (!this.panelId)\n return;\n this.dispatchEvent(new CustomEvent<DockPanelDragStartDetail>(`dock-panel-drag-start`, {\n detail: {\n panelId: this.panelId,\n pointerId,\n clientX,\n clientY,\n },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ── Chrome event forwarding ──────────────────────────────────────────────\n\n private _onTitlebarToggle = (event: TitlebarToggleEvent): void => {\n event.stopPropagation();\n this._collapsed = event.detail.collapsed;\n this.dispatchEvent(new CustomEvent<TitlebarToggleDetail>(`toggle`, {\n detail: event.detail,\n bubbles: true,\n composed: true,\n }));\n };\n\n private _onTitlebarClose = (event: Event): void => {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }));\n // Mirror ixfx-panel's contract: a close removes the element. When docked,\n // the host's slotchange handler routes this through removePanel().\n this.remove();\n };\n\n protected override render() {\n const tabbed = this.presentation === `tabbed`;\n // Collapsed state only applies to solo chrome; docked leaves collapse at\n // the split-layout level, so ignore it there.\n const collapsed = !tabbed && this._collapsed;\n return html`\n ${tabbed\n ? nothing\n : html`\n <ixfx-titlebar\n .title=${this.title}\n .iconName=${this.iconName}\n .closable=${this.closable}\n .collapsible=${this.collapsible}\n .collapsed=${collapsed}\n .toggleInteraction=${this.collapsible ? `implicit` : `disabled`}\n @toggle=${this._onTitlebarToggle}\n @close=${this._onTitlebarClose}\n >\n <slot name=\"toolbar\" slot=\"toolbar\"></slot>\n </ixfx-titlebar>\n `}\n <div class=\"content\" ?collapsed=${collapsed}>\n <slot></slot>\n </div>\n `;\n }\n\n static override styles = [\n themeFallbacks,\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n\n ixfx-titlebar {\n flex-shrink: 0;\n }\n\n .content {\n flex: 1;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n }\n\n .content[collapsed] {\n display: none;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-dock-panel': DockPanelElement;\n }\n}\n\nexport interface DockPanelElement {\n addEventListener: (<K extends keyof DockPanelElementEventMap>(\n type: K,\n listener: (this: DockPanelElement, event: DockPanelElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { SplitLayoutElement } from '../split-layout/split-layout.js';\nimport type { TabListChangeEvent } from '../tabs/tab-list.js';\nimport type { DockDropZone, Rect } from './dock-drag.js';\nimport type { DockPanelElement } from './dock-panel.js';\nimport type {\n DockAddPanelTarget,\n DockChangeEvent,\n DockDirection,\n DockDragBoundaryEvent,\n DockDropTarget,\n DockEdge,\n DockLayout,\n DockLeafContentRules,\n DockLeafPlacementPolicy,\n DockLeafPlacementPolicyResolved,\n DockLeafRef,\n DockNeighbours,\n DockNode,\n DockOperation,\n DockPanelActivatedEvent,\n DockPanelAddedEvent,\n DockPanelDragStartEvent,\n DockPanelInit,\n DockPanelRemovedEvent,\n DockPanelSnapshot,\n DockPanelTearOutEvent,\n DockStackNode,\n} from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { registerDockHost, startDrag, unregisterDockHost } from './dock-drag.js';\nimport {\n addPanelToStack,\n collectContainerNames,\n collectPanelIds,\n collectStackPaths,\n createStack,\n extractStack,\n findNode,\n findStackOf,\n findStackPathByName,\n getLeafNeighbours,\n insertBeside,\n isSplit,\n isStack,\n moveLeafNodeToEdge,\n moveLeafStep,\n normalize,\n parseLayout,\n removePanelFromStack,\n serializeLayout,\n setActive,\n wrapRoot,\n} from './dock-model.js';\nimport '../split-layout/split-layout.js';\nimport '../tabs/tab-list.js';\nimport '../tabs/tab-list-item.js';\nimport './dock-panel.js';\n\nexport type {\n DockAddPanelTarget,\n DockChangeEvent,\n DockDirection,\n DockDragBoundaryEvent,\n DockEdge,\n DockLeafContentRules,\n DockLeafPlacementPolicy,\n DockLeafPlacementPolicyResolved,\n DockLeafRef,\n DockNeighbours,\n DockPanelActivatedEvent,\n DockPanelAddedEvent,\n DockPanelDragStartEvent,\n DockPanelRemovedEvent,\n DockPanelTearOutEvent,\n};\n\nexport interface DockHostElementEventMap {\n 'dock-change': DockChangeEvent;\n 'dock-panel-added': DockPanelAddedEvent;\n 'dock-panel-removed': DockPanelRemovedEvent;\n 'dock-panel-activated': DockPanelActivatedEvent;\n 'dock-panel-drag-start': DockPanelDragStartEvent;\n /** Panel released outside every host — request to move it to a new window. */\n 'dock-panel-tear-out': DockPanelTearOutEvent;\n /** Drag pointer left every host's bounds during a drag. */\n 'dock-panel-drag-out': DockDragBoundaryEvent;\n /** Drag pointer re-entered a host's bounds after being outside. */\n 'dock-panel-drag-in': DockDragBoundaryEvent;\n}\n\n/** Fraction of the leaf rect (from each edge) that forms the split bands. */\nconst BAND = 0.25;\n\n/** Pointer movement threshold before a press becomes a dock drag (matches tab-list). */\nconst DRAG_THRESHOLD_PX = 5;\n\n/** Tolerance (px) when matching a child gutter endpoint to a parent gutter line. */\nconst JUNCTION_TOL_PX = 6;\n\n/** Junction points closer than this merge into one handle (a 4-way cross yields one per side). */\nconst JUNCTION_MERGE_PX = 8;\n\ninterface DockJunctionTarget {\n split: SplitLayoutElement;\n gutterIndex: number;\n}\n\n/** A point where a parent split's gutter line crosses a nested split's gutter. */\ninterface DockJunction {\n /** Host-relative coordinates. */\n x: number;\n y: number;\n targets: DockJunctionTarget[];\n}\n\n@customElement(`ixfx-dock-host`)\nexport class DockHostElement extends LitElement {\n /** Initial layout as `DockLayout` JSON. Absent ⇒ all pooled panels go into one root stack. */\n @property({ type: String, attribute: `layout` })\n layout: string | null = null;\n\n /**\n * Space-separated drop operations this host allows: `tabs`, `horizontal`,\n * `vertical`, and convenience `all`. `\"\"` / `none` ⇒ nothing may be dropped.\n */\n @property({ type: String, attribute: `accepts` })\n accepts = `tabs horizontal vertical`;\n\n /**\n * When true, panels can be freely reorganised within this host, but\n * cannot be dragged out to another host.\n */\n @property({ type: Boolean, attribute: `isolated` })\n isolated = false;\n\n /** Finest-grained veto, consulted per candidate zone. */\n @property({ attribute: false })\n canAccept: ((panelId: string, op: DockOperation) => boolean) | undefined;\n\n @state()\n private _model: DockNode = createStack([]);\n\n @state()\n private _pool: DockPanelElement[] = [];\n\n @state()\n private _dropZone: DockDropZone | null = null;\n\n @state()\n private _dragActive = false;\n\n @state()\n private _junctions: DockJunction[] = [];\n\n /** panelId → toolbar nodes currently moved out into a tab item. */\n private _toolbarsOut: Map<string, HTMLElement[]> = new Map();\n\n /**\n * Placement policy per named leaf: `{ allow, deny }` kind sets plus an\n * `allowEdgeSplit` gate (default `true`). Host-level only — never serialized\n * into the layout, but kept across `loadLayout()` calls. Existing panels are\n * grandfathered; rules govern future placements (drags, `addPanel`,\n * re-homing). See {@link setLeafPlacementPolicy}.\n */\n private _leafContentRules: Map<string, { allow: Set<string> | null; deny: Set<string>; allowEdgeSplit: boolean }> = new Map();\n\n private _tabDragPending: { panelId: string; pointerId: number; startX: number; startY: number } | null = null;\n\n private _junctionsKey = ``;\n private _junctionsRaf: number | null = null;\n private _hostResizeObserver: ResizeObserver | null = null;\n\n /**\n * Bumped on every `loadLayout()`. Stamped onto each rendered\n * `ixfx-split-layout` as `data-dock-gen`, so `_foldLiveWeights` can tell a\n * split that still carries the *previous* generation's live weights (its\n * async re-render hasn't landed yet) from one that's caught up — and skip\n * folding the stale one back over the just-loaded model.\n */\n private _loadGeneration = 0;\n\n /** `toolbar-<name>` slot names currently provided as light-DOM children. */\n private _toolbarSlots: Set<string> = new Set();\n private _toolbarObserver: MutationObserver | null = null;\n\n /** Observers for panel element attribute changes, keyed by panelId. */\n private _panelObservers: Map<string, MutationObserver> = new Map();\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._buildInitialModel();\n registerDockHost(this);\n this.addEventListener(`dock-panel-drag-start`, this._onDragStart as EventListener);\n this._hostResizeObserver = new ResizeObserver(() => this._scheduleJunctions());\n this._hostResizeObserver.observe(this);\n this._scanToolbarSlots();\n this._toolbarObserver = new MutationObserver(() => this._scanToolbarSlots());\n this._toolbarObserver.observe(this, { childList: true, subtree: true, attributes: true, attributeFilter: [`slot`] });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n unregisterDockHost(this);\n this.removeEventListener(`dock-panel-drag-start`, this._onDragStart as EventListener);\n this._toolbarObserver?.disconnect();\n this._toolbarObserver = null;\n this._hostResizeObserver?.disconnect();\n this._hostResizeObserver = null;\n for (const observer of this._panelObservers.values()) {\n observer.disconnect();\n }\n this._panelObservers.clear();\n if (this._junctionsRaf !== null) {\n cancelAnimationFrame(this._junctionsRaf);\n this._junctionsRaf = null;\n }\n this._junctions = [];\n this._junctionsKey = ``;\n this._returnAllToolbars();\n }\n\n private _onDragStart = (event: DockPanelDragStartEvent): void => {\n const { panelId, pointerId, clientX, clientY } = event.detail;\n startDrag(panelId, this, pointerId, clientX, clientY, this._findPanelEl(panelId)?.kind);\n };\n\n override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate(changed);\n if (changed.has(`layout`) && this.layout !== null) {\n const parsed = parseLayout(this.layout);\n if (parsed) {\n this._model = parsed.root;\n this._mergePoolIntoModel();\n }\n }\n }\n\n override updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n this._syncSlots();\n this._syncToolbars();\n this._scheduleJunctions();\n }\n\n // ── Model setup ──────────────────────────────────────────────────────────\n\n private _buildInitialModel(): void {\n if (this.layout !== null) {\n const parsed = parseLayout(this.layout);\n if (parsed) {\n this._model = parsed.root;\n this._mergePoolIntoModel();\n return;\n }\n }\n this._model = createStack([]);\n this._mergePoolIntoModel();\n }\n\n /** Ensure every pooled panel element appears in the model (appended to the first stack). */\n private _mergePoolIntoModel(): void {\n const known = new Set(collectPanelIds(this._model));\n let changed = false;\n for (const el of this._scanPanels()) {\n if (!known.has(el.panelId)) {\n this._appendPanelToFirstStack(el.panelId);\n known.add(el.panelId);\n changed = true;\n }\n }\n if (changed) {\n normalize(this._model);\n }\n }\n\n private _scanPanels(): DockPanelElement[] {\n return Array.from(this.children).filter((el): el is DockPanelElement =>\n el instanceof HTMLElement && el.tagName === `IXFX-DOCK-PANEL` && Boolean((el as DockPanelElement).panelId),\n );\n }\n\n /** Refresh the set of provided `toolbar-<name>` slots; re-render on change. */\n private _scanToolbarSlots(): void {\n const found = new Set<string>();\n for (const child of this.children) {\n if (!(child instanceof HTMLElement))\n continue;\n const slot = child.getAttribute(`slot`) ?? ``;\n if (slot.startsWith(`toolbar-`) && slot.length > `toolbar-`.length) {\n found.add(slot);\n }\n }\n if (found.size !== this._toolbarSlots.size || [...found].some(s => !this._toolbarSlots.has(s))) {\n this._toolbarSlots = found;\n this.requestUpdate();\n }\n }\n\n private _findPanelEl(panelId: string): DockPanelElement | undefined {\n return this._pool.find(p => p.panelId === panelId)\n ?? this._scanPanels().find(p => p.panelId === panelId);\n }\n\n private _firstStack(): DockStackNode {\n const paths = collectStackPaths(this._model);\n const node = paths.length > 0 ? findNode(this._model, paths[0]) : null;\n if (node !== null && isStack(node))\n return node;\n const fresh = createStack([]);\n wrapRoot(this._model, `row`, fresh, `after`);\n normalize(this._model);\n return fresh;\n }\n\n private _appendPanelToFirstStack(panelId: string): void {\n const kind = this._panelKind(panelId);\n if (this._model.kind === `stack` && this._stackAllowsKind(this._model, kind)) {\n addPanelToStack(this._model, panelId);\n return;\n }\n addPanelToStack(this._firstStackAllowing(kind), panelId);\n }\n\n /** Normalized content kind of a panel (`'any'` when unknown/unset). */\n private _panelKind(panelId: string): string {\n return normalizeKind(this._findPanelEl(panelId)?.kind);\n }\n\n /** Whether `kind` may live in `stack` under the current leaf rules. */\n private _stackAllowsKind(stack: DockStackNode, kind: string): boolean {\n if (stack.name === undefined) {\n return true;\n }\n const rules = this._leafContentRules.get(stack.name);\n if (rules === undefined) {\n return true;\n }\n if (rules.deny.has(kind)) {\n return false;\n }\n return rules.allow === null || rules.allow.has(kind);\n }\n\n /**\n * Whether an edge drop may split a new sibling leaf beside `stack`. Unnamed\n * leaves and leaves with no policy always allow it; a named leaf whose\n * policy sets `allowEdgeSplit: false` does not (strict named-area\n * containment).\n */\n private _leafAllowsEdgeSplit(stack: DockStackNode): boolean {\n if (stack.name === undefined) {\n return true;\n }\n return this._leafContentRules.get(stack.name)?.allowEdgeSplit ?? true;\n }\n\n /** First stack (tree order) whose rules admit `kind`, else the first stack. */\n private _firstStackAllowing(kind: string): DockStackNode {\n for (const path of collectStackPaths(this._model)) {\n const node = findNode(this._model, path);\n if (node !== null && isStack(node) && this._stackAllowsKind(node, kind)) {\n return node;\n }\n }\n console.warn(`[ixfx-dock-host] no leaf admits kind \"${kind}\", using first stack`);\n return this._firstStack();\n }\n\n private _onPoolSlotChange = (): void => {\n this._syncPool();\n };\n\n private _observePanel(el: DockPanelElement): void {\n if (this._panelObservers.has(el.panelId))\n return;\n const observer = new MutationObserver(() => this.requestUpdate());\n observer.observe(el, {\n attributes: true,\n attributeFilter: [`label`, `icon-name`, `closable`, `collapsible`, `kind`, `accepts`],\n });\n this._panelObservers.set(el.panelId, observer);\n }\n\n private _unobservePanel(el: DockPanelElement): void {\n const observer = this._panelObservers.get(el.panelId);\n if (observer) {\n observer.disconnect();\n this._panelObservers.delete(el.panelId);\n }\n }\n\n private _syncPool(): void {\n // Scan the light DOM for all panel elements — panels placed in the model\n // carry named slots and are therefore NOT assigned to the pool slot.\n const current = this._scanPanels();\n const currentIds = new Set(current.map(p => p.panelId));\n let structuralChange = false;\n\n // Removed from DOM → drop from model\n for (const el of [...this._pool]) {\n if (!currentIds.has(el.panelId)) {\n this._unobservePanel(el);\n this._toolbarsOut.delete(el.panelId);\n this._removeFromModel(el.panelId);\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-removed`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n structuralChange = true;\n }\n }\n\n // New in DOM → add to model\n for (const el of current) {\n this._observePanel(el);\n if (!collectPanelIds(this._model).includes(el.panelId)) {\n this._appendPanelToFirstStack(el.panelId);\n normalize(this._model);\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n structuralChange = true;\n }\n }\n\n this._pool = current;\n this.requestUpdate();\n if (structuralChange) {\n this._emitChange();\n }\n }\n\n // ── Public API ───────────────────────────────────────────────────────────\n\n /** Serialize the current layout, folding live split weights from the DOM. */\n saveLayout(): DockLayout {\n this._foldLiveWeights();\n return serializeLayout(this._model);\n }\n\n loadLayout(layout: DockLayout): void {\n this._returnAllToolbars();\n this._loadGeneration++;\n this._model = normalize(cloneNode(layout.root));\n this._mergePoolIntoModel();\n this.requestUpdate();\n this._emitChange();\n }\n\n /**\n * Dock a panel. Returns false (without touching the DOM) when the\n * explicitly targeted container denies the panel's `kind`.\n */\n addPanel(panel: DockPanelElement | DockPanelInit, target?: DockAddPanelTarget): boolean {\n const kind = panel instanceof HTMLElement ? normalizeKind(panel.kind) : normalizeKind(panel.kind);\n const op = target?.op ?? `tabs`;\n\n // Resolve an explicit target first so kind denials can refuse cleanly.\n let stackPath: number[] | null = null;\n let splitTarget: number[] | null = null;\n if (target?.container !== undefined) {\n const namedPath = findStackPathByName(this._model, target.container);\n if (namedPath === null) {\n console.warn(`[ixfx-dock-host] addPanel: unknown container \"${target.container}\", appending to first admitting stack`);\n } else if (op === `tabs` && !this._stackAllowsKindAt(namedPath, kind)) {\n console.warn(`[ixfx-dock-host] addPanel: container \"${target.container}\" does not admit kind \"${kind}\"`);\n return false;\n } else if (op !== `tabs` && !this._stackAllowsEdgeSplitAt(namedPath)) {\n console.warn(`[ixfx-dock-host] addPanel: container \"${target.container}\" forbids edge splits (allowEdgeSplit: false)`);\n return false;\n } else {\n stackPath = namedPath;\n }\n } else if (target?.stack) {\n const found = findStackOf(this._model, target.stack);\n if (found === null) {\n console.warn(`[ixfx-dock-host] addPanel: unknown stack panel \"${target.stack}\", appending to first admitting stack`);\n } else if (op === `tabs` && !this._stackAllowsKindAt(found, kind)) {\n console.warn(`[ixfx-dock-host] addPanel: target stack does not admit kind \"${kind}\"`);\n return false;\n } else if (op !== `tabs` && !this._stackAllowsEdgeSplitAt(found)) {\n console.warn(`[ixfx-dock-host] addPanel: target stack forbids edge splits (allowEdgeSplit: false)`);\n return false;\n } else {\n stackPath = found;\n }\n }\n if (stackPath !== null && op !== `tabs`) {\n splitTarget = stackPath;\n stackPath = null;\n }\n\n let el: DockPanelElement;\n if (panel instanceof HTMLElement) {\n el = panel as DockPanelElement;\n } else {\n el = document.createElement(`ixfx-dock-panel`) as DockPanelElement;\n el.panelId = panel.panelId;\n if (panel.title !== undefined)\n el.title = panel.title;\n if (panel.iconName !== undefined)\n el.iconName = panel.iconName;\n if (panel.closable !== undefined)\n el.closable = panel.closable;\n if (panel.collapsible !== undefined)\n el.collapsible = panel.collapsible;\n if (panel.kind !== undefined)\n el.kind = panel.kind;\n }\n\n if (el.parentElement !== this) {\n this.appendChild(el);\n }\n if (!this._pool.some(p => p.panelId === el.panelId)) {\n this._pool = [...this._pool, el];\n }\n\n this._returnAllToolbars();\n\n // Moves are idempotent: drop an existing entry before re-inserting.\n if (collectPanelIds(this._model).includes(el.panelId)) {\n this._removeFromModel(el.panelId);\n }\n\n if (splitTarget !== null) {\n insertBeside(this._model, splitTarget, opToDirection(op), createStack([el.panelId]), `after`);\n } else if (stackPath !== null) {\n const stack = findNode(this._model, stackPath);\n if (stack !== null && isStack(stack)) {\n addPanelToStack(stack, el.panelId, target?.index);\n }\n } else {\n this._appendPanelToFirstStack(el.panelId);\n }\n\n normalize(this._model);\n this.requestUpdate();\n\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n this._emitChange();\n return true;\n }\n\n /** Whether the stack at `stackPath` admits `kind` under the leaf rules. */\n private _stackAllowsKindAt(stackPath: number[], kind: string): boolean {\n const stack = findNode(this._model, stackPath);\n return stack !== null && isStack(stack) && this._stackAllowsKind(stack, kind);\n }\n\n /** Whether the stack at `stackPath` permits an edge split beside it. */\n private _stackAllowsEdgeSplitAt(stackPath: number[]): boolean {\n const stack = findNode(this._model, stackPath);\n return stack === null || !isStack(stack) || this._leafAllowsEdgeSplit(stack);\n }\n\n removePanel(panelId: string): boolean {\n if (!collectPanelIds(this._model).includes(panelId))\n return false;\n\n this._returnAllToolbars();\n this._removeFromModel(panelId);\n this._pool = this._pool.filter(p => p.panelId !== panelId);\n this._toolbarsOut.delete(panelId);\n\n const el = this._scanPanels().find(p => p.panelId === panelId);\n el?.remove();\n\n normalize(this._model);\n this.requestUpdate();\n\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-removed`, {\n detail: { panelId },\n bubbles: true,\n composed: true,\n }));\n this._emitChange();\n return true;\n }\n\n activatePanel(panelId: string): boolean {\n const stackPath = findStackOf(this._model, panelId);\n if (stackPath === null)\n return false;\n const stack = findNode(this._model, stackPath);\n if (stack === null || !isStack(stack))\n return false;\n if (!setActive(stack, panelId))\n return false;\n\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-activated`, {\n detail: { panelId },\n bubbles: true,\n composed: true,\n }));\n return true;\n }\n\n getPanelIds(): string[] {\n return collectPanelIds(this._model);\n }\n\n /** Names of every named stack leaf, in tree order. */\n getContainerNames(): string[] {\n return collectContainerNames(this._model);\n }\n\n /**\n * Snapshot of a named container (`{ name, panels, active }`), or null when\n * no stack carries that name. First match wins when duplicated.\n */\n getContainer(name: string): { name: string; panels: string[]; active: string } | null {\n const path = findStackPathByName(this._model, name);\n if (path === null)\n return null;\n const node = findNode(this._model, path);\n if (node === null || !isStack(node) || node.name === undefined)\n return null;\n return { name: node.name, panels: [...node.panels], active: node.active };\n }\n\n /** Panel-ids in a named container, in tab order (`[]` when unknown/empty). */\n getContainerPanels(name: string): string[] {\n return this.getContainer(name)?.panels ?? [];\n }\n\n /** Panel elements in a named container, in tab order — for iterating children. */\n getContainerElements(name: string): DockPanelElement[] {\n return this.getContainerPanels(name)\n .map(id => this._findPanelEl(id))\n .filter((el): el is DockPanelElement => el !== undefined);\n }\n\n // ── Leaf placement policy (kind rules + edge-split gate) ─────────────────\n\n private _defaultLeafRule(): { allow: Set<string> | null; deny: Set<string>; allowEdgeSplit: boolean } {\n return { allow: null, deny: new Set<string>(), allowEdgeSplit: true };\n }\n\n /** A rule entry that constrains nothing — safe to drop from the map. */\n private _isEmptyLeafRule(entry: { allow: Set<string> | null; deny: Set<string>; allowEdgeSplit: boolean }): boolean {\n return entry.allow === null && entry.deny.size === 0 && entry.allowEdgeSplit;\n }\n\n private _warnUnknownContainer(method: string, key: string): void {\n if (findStackPathByName(this._model, key) === null) {\n console.warn(`[ixfx-dock-host] ${method}: no container named \"${key}\" yet; rule stored`);\n }\n }\n\n /**\n * Restrict a named container to only the given panel kinds — e.g.\n * `setLeafExclusiveContents('editor', ['document'])`. `tabs` drops,\n * `addPanel`, and re-homing into the leaf then refuse other kinds. Whether\n * edge splits beside the leaf are offered is governed separately by\n * {@link setLeafPlacementPolicy}'s `allowEdgeSplit` (default `true`).\n * Pass `[]` to seal the leaf (nothing admitted). Warns when no stack\n * currently carries `name`, but the rule is still stored and applies once\n * one appears. Rules are host policy: kept across `loadLayout()`, never\n * serialized.\n */\n setLeafExclusiveContents(name: string, kinds: readonly string[]): void {\n const key = name.trim();\n if (!key) {\n console.warn(`[ixfx-dock-host] setLeafExclusiveContents: empty container name`);\n return;\n }\n const entry = this._leafContentRules.get(key) ?? this._defaultLeafRule();\n entry.allow = new Set(kinds.map(k => k.trim()).filter(k => k.length > 0));\n this._leafContentRules.set(key, entry);\n this._warnUnknownContainer(`setLeafExclusiveContents`, key);\n }\n\n /**\n * Forbid the given panel kinds in a named container — e.g.\n * `setLeafDenyContents('footer', ['files', 'document'])`. Everything else\n * stays admitted. Pass `[]` to lift the denial. See\n * {@link setLeafExclusiveContents} for scope/ordering notes.\n */\n setLeafDenyContents(name: string, kinds: readonly string[]): void {\n const key = name.trim();\n if (!key) {\n console.warn(`[ixfx-dock-host] setLeafDenyContents: empty container name`);\n return;\n }\n const entry = this._leafContentRules.get(key) ?? this._defaultLeafRule();\n entry.deny = new Set(kinds.map(k => k.trim()).filter(k => k.length > 0));\n if (this._isEmptyLeafRule(entry)) {\n this._leafContentRules.delete(key);\n } else {\n this._leafContentRules.set(key, entry);\n }\n this._warnUnknownContainer(`setLeafDenyContents`, key);\n }\n\n /**\n * Set (merge) the full placement policy for a named leaf: kind allow/deny\n * lists plus the `allowEdgeSplit` gate. Omitted fields are left unchanged\n * — pass `clearLeafPlacementPolicy(name)` to reset. `allowKinds` /\n * `denyKinds` are equivalent to {@link setLeafExclusiveContents} /\n * {@link setLeafDenyContents} and share the same storage.\n *\n * `allowEdgeSplit: false` enforces strict named-area containment: the edge\n * drop zones beside the leaf go inert for every placement route (pointer\n * preview and drop, `queryDropTarget` / `previewExternalDrop`,\n * `addPanel` with a split `op`), so a panel cannot escape the area by\n * splitting next to it. A permitted split still creates an *unnamed,\n * unconstrained* leaf — the policy is not propagated to it.\n *\n * Warns when no stack currently carries `name`; the policy is stored and\n * applies once one appears. Host policy: kept across `loadLayout()`, never\n * serialized.\n */\n setLeafPlacementPolicy(name: string, policy: DockLeafPlacementPolicy): void {\n const key = name.trim();\n if (!key) {\n console.warn(`[ixfx-dock-host] setLeafPlacementPolicy: empty container name`);\n return;\n }\n const entry = this._leafContentRules.get(key) ?? this._defaultLeafRule();\n if (policy.allowKinds !== undefined) {\n entry.allow = new Set(policy.allowKinds.map(k => k.trim()).filter(k => k.length > 0));\n }\n if (policy.denyKinds !== undefined) {\n entry.deny = new Set(policy.denyKinds.map(k => k.trim()).filter(k => k.length > 0));\n }\n if (policy.allowEdgeSplit !== undefined) {\n entry.allowEdgeSplit = policy.allowEdgeSplit;\n }\n if (this._isEmptyLeafRule(entry)) {\n this._leafContentRules.delete(key);\n } else {\n this._leafContentRules.set(key, entry);\n }\n this._warnUnknownContainer(`setLeafPlacementPolicy`, key);\n }\n\n /** Remove every content rule and reset the edge-split gate for a named container. */\n clearLeafContentRestrictions(name: string): void {\n this._leafContentRules.delete(name.trim());\n }\n\n /** Alias of {@link clearLeafContentRestrictions} — clears kind rules and the edge-split gate. */\n clearLeafPlacementPolicy(name: string): void {\n this._leafContentRules.delete(name.trim());\n }\n\n /** Copy of a container's kind rules, or null when unrestricted. */\n getLeafContentRestrictions(name: string): DockLeafContentRules | null {\n const rules = this._leafContentRules.get(name.trim());\n if (rules === undefined) {\n return null;\n }\n return { allow: rules.allow === null ? null : [...rules.allow], deny: [...rules.deny] };\n }\n\n /** Resolved placement policy for a container, or null when it has none. */\n getLeafPlacementPolicy(name: string): DockLeafPlacementPolicyResolved | null {\n const rules = this._leafContentRules.get(name.trim());\n if (rules === undefined) {\n return null;\n }\n return {\n allowKinds: rules.allow === null ? null : [...rules.allow],\n denyKinds: [...rules.deny],\n allowEdgeSplit: rules.allowEdgeSplit,\n };\n }\n\n // ── Spatial (leaf geometry + moves) ──────────────────────────────────────\n\n /**\n * Geometric neighbours of a leaf (`name` or numeric `path`) — what sits\n * above / below / left / right of it on screen. Each entry is\n * `{ name, path }` (`name` is null for unnamed leaves), ordered\n * most-overlapping first. Returns null when the leaf is unknown.\n */\n getNeighbours(leaf: DockLeafRef): DockNeighbours | null {\n return getLeafNeighbours(this._model, leaf);\n }\n\n /**\n * Move a leaf one position in `direction`, swapping with the neighbour it\n * shares the longest edge with (both keep the remaining structure intact).\n * Returns false when the leaf is unknown or nothing adjoins that way.\n */\n moveLeaf(leaf: DockLeafRef, direction: DockDirection): boolean {\n if (!moveLeafStep(this._model, leaf, direction)) {\n return false;\n }\n this._commit();\n return true;\n }\n\n /**\n * Move a leaf to an edge of the overall layout (e.g. toggle a sidebar from\n * `left` to `right`). The rest of the layout stays intact as a single\n * subtree and the leaf keeps its absolute size along the target axis.\n * Returns false when the leaf is unknown or the layout holds one leaf.\n */\n moveLeafToEdge(leaf: DockLeafRef, edge: DockEdge): boolean {\n if (!moveLeafNodeToEdge(this._model, leaf, edge)) {\n return false;\n }\n this._commit();\n return true;\n }\n\n // ── Cross-window (tear-out / tear-in) ───────────────────────────────────\n //\n // The shared drag coordinator is per-document, so it never spans separate\n // windows / `BrowserWindow`s / `WebContentsView`s. These methods give an\n // outer coordinator (e.g. an Electron main process talking over IPC) the\n // hooks to move a panel between windows: capture a serializable snapshot on\n // one side, hit-test and recreate it on the other. See the README.\n\n /**\n * Capture a structured-clone-safe {@link DockPanelSnapshot} of a panel\n * (identity, chrome attributes, and a best-effort `innerHTML`). Returns\n * null when no such panel element is known to this host.\n */\n getPanelSnapshot(panelId: string): DockPanelSnapshot | null {\n const el = this._findPanelEl(panelId);\n if (el === undefined)\n return null;\n return {\n panelId: el.panelId,\n title: el.title,\n iconName: el.iconName,\n closable: el.closable,\n collapsible: el.collapsible,\n kind: normalizeKind(el.kind),\n accepts: el.accepts,\n contentHTML: el.innerHTML,\n };\n }\n\n /**\n * {@link getPanelSnapshot} + {@link removePanel} in one step: take the\n * snapshot, then drop the panel (and its element) from this host. Call this\n * from a `dock-panel-tear-out` handler once the receiving window has\n * recreated the panel.\n */\n detachPanel(panelId: string): DockPanelSnapshot | null {\n const snapshot = this.getPanelSnapshot(panelId);\n if (snapshot === null)\n return null;\n this.removePanel(panelId);\n return snapshot;\n }\n\n /**\n * Hit-test viewport coordinates against this host and return a plain,\n * serializable {@link DockDropTarget} (no element references) — or null when\n * the point is outside the host or the resulting zone is disallowed by\n * `accepts` / `canAccept`. Pure query: no model mutation, no overlay.\n *\n * `panelId` is passed to `canAccept`; use any stable id for an external\n * panel (defaults to `\"__external__\"`). `kind` covers leaf content rules\n * for panels unknown to this host (defaults to `'any'`).\n */\n queryDropTarget(clientX: number, clientY: number, panelId = `__external__`, kind?: string): DockDropTarget | null {\n const zone = this.computeDropZone(clientX, clientY, panelId, kind);\n return zone === null ? null : zoneToTarget(zone);\n }\n\n /**\n * Like {@link queryDropTarget}, but also shows the drop overlay so an\n * external (cross-window) drag gets the same visual feedback as an in-page\n * one. Call on every pointer update from the outer coordinator, then\n * {@link endExternalDrop} when the drag leaves or ends.\n */\n previewExternalDrop(clientX: number, clientY: number, panelId = `__external__`, kind?: string): DockDropTarget | null {\n this.setDragActive(true);\n const zone = this.computeDropZone(clientX, clientY, panelId, kind);\n this.setDropZone(zone);\n return zone === null ? null : zoneToTarget(zone);\n }\n\n /** Clear any overlay left by {@link previewExternalDrop}. */\n endExternalDrop(): void {\n this.setDropZone(null);\n this.setDragActive(false);\n }\n\n /**\n * Recreate a panel from a {@link DockPanelSnapshot} (or a bare\n * {@link DockPanelInit}) and dock it. With `at` viewport coordinates the\n * panel lands where a drop there would put it (respecting `accepts` /\n * `canAccept` and leaf content rules); without them, or when the point\n * misses the host, it goes into the first stack admitting its kind.\n * Returns the created element, or null when a panel\n * with that id is already docked here.\n */\n acceptExternalPanel(\n snapshot: DockPanelSnapshot | DockPanelInit,\n at?: { clientX: number; clientY: number },\n ): DockPanelElement | null {\n if (collectPanelIds(this._model).includes(snapshot.panelId))\n return null;\n\n const el = document.createElement(`ixfx-dock-panel`) as DockPanelElement;\n el.panelId = snapshot.panelId;\n if (snapshot.title !== undefined)\n el.title = snapshot.title;\n if (snapshot.iconName !== undefined)\n el.iconName = snapshot.iconName;\n if (snapshot.closable !== undefined)\n el.closable = snapshot.closable;\n if (snapshot.collapsible !== undefined)\n el.collapsible = snapshot.collapsible;\n if (`kind` in snapshot && snapshot.kind !== undefined)\n el.kind = snapshot.kind;\n if (`accepts` in snapshot && snapshot.accepts)\n el.setAttribute(`accepts`, snapshot.accepts);\n if (`contentHTML` in snapshot && snapshot.contentHTML)\n el.innerHTML = snapshot.contentHTML;\n\n this._returnAllToolbars();\n this.appendChild(el);\n this._pool = [...this._pool, el];\n this._appendPanelToFirstStack(el.panelId);\n normalize(this._model);\n\n this.endExternalDrop();\n const zone = at ? this.computeDropZone(at.clientX, at.clientY, el.panelId) : null;\n if (zone !== null) {\n this._applyZone(el.panelId, zone);\n }\n\n normalize(this._model);\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n this._emitChange();\n return el;\n }\n\n // ── Drop targeting (called by the drag coordinator) ──────────────────────\n\n /**\n * Hit-test a pointer position against this host's leaves and edges. Returns\n * a zone with rects relative to the host, or null when the pointer is\n * outside the host or the candidate zone is disallowed.\n */\n computeDropZone(clientX: number, clientY: number, panelId: string, kind?: string): DockDropZone | null {\n const hostRect = this.getBoundingClientRect();\n if (clientX < hostRect.left || clientX > hostRect.right\n || clientY < hostRect.top || clientY > hostRect.bottom) {\n return null;\n }\n // Explicit kind wins (cross-host / external drags); otherwise read the\n // panel element, defaulting to `'any'` for unknown panels.\n const resolvedKind = kind?.trim() ? kind.trim() : this._panelKind(panelId);\n const rel = (r: DOMRect): Rect => ({\n x: r.left - hostRect.left,\n y: r.top - hostRect.top,\n w: r.width,\n h: r.height,\n });\n\n // Leaf under the pointer?\n for (const path of collectStackPaths(this._model)) {\n const leaf = this.shadowRoot?.querySelector(`[data-dock-path=\"${path.join(`-`)}\"]`) as HTMLElement | null;\n if (!leaf)\n continue;\n const leafRect = leaf.getBoundingClientRect();\n if (clientX < leafRect.left || clientX > leafRect.right\n || clientY < leafRect.top || clientY > leafRect.bottom) {\n continue;\n }\n\n const stack = findNode(this._model, path);\n if (stack === null || !isStack(stack))\n continue;\n\n // Tab strip has priority over the leaf body\n const strip = leaf.querySelector(`ixfx-tab-list`);\n if (strip !== null) {\n const stripRect = strip.getBoundingClientRect();\n if (clientX >= stripRect.left && clientX <= stripRect.right\n && clientY >= stripRect.top && clientY <= stripRect.bottom) {\n const gapIndex = computeStripGapIndex(strip, clientX, clientY);\n const zone: DockDropZone = {\n host: this,\n operation: `tabs`,\n targetPath: path,\n side: `after`,\n gapIndex,\n rect: rel(leafRect),\n caretRect: this._stripCaretRect(strip, gapIndex, hostRect),\n };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n }\n\n const relX = (clientX - leafRect.left) / Math.max(leafRect.width, 1);\n const relY = (clientY - leafRect.top) / Math.max(leafRect.height, 1);\n\n if (relX >= BAND && relX <= 1 - BAND && relY >= BAND && relY <= 1 - BAND) {\n const zone: DockDropZone = {\n host: this,\n operation: `tabs`,\n targetPath: path,\n side: `after`,\n gapIndex: stack.panels.length,\n rect: rel(leafRect),\n };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n\n const r: Rect = rel(leafRect);\n let operation: DockOperation;\n let side: `before` | `after`;\n let zoneRect: Rect;\n if (relX < BAND) {\n operation = `split-vertical`;\n side = `before`;\n zoneRect = { ...r, w: r.w / 2 };\n } else if (relX > 1 - BAND) {\n operation = `split-vertical`;\n side = `after`;\n zoneRect = { x: r.x + r.w / 2, y: r.y, w: r.w / 2, h: r.h };\n } else if (relY < BAND) {\n operation = `split-horizontal`;\n side = `before`;\n zoneRect = { ...r, h: r.h / 2 };\n } else {\n operation = `split-horizontal`;\n side = `after`;\n zoneRect = { x: r.x, y: r.y + r.h / 2, w: r.w, h: r.h / 2 };\n }\n const zone: DockDropZone = { host: this, operation, targetPath: path, side, rect: zoneRect };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n\n // Outside every leaf: split the root against the nearest host edge\n const fromLeft = clientX - hostRect.left;\n const fromRight = hostRect.right - clientX;\n const fromTop = clientY - hostRect.top;\n const fromBottom = hostRect.bottom - clientY;\n const min = Math.min(fromLeft, fromRight, fromTop, fromBottom);\n const full: Rect = { x: 0, y: 0, w: hostRect.width, h: hostRect.height };\n\n let operation: DockOperation;\n let side: `before` | `after`;\n let zoneRect: Rect;\n if (min === fromLeft) {\n operation = `split-vertical`;\n side = `before`;\n zoneRect = { ...full, w: full.w / 2 };\n } else if (min === fromRight) {\n operation = `split-vertical`;\n side = `after`;\n zoneRect = { x: full.x + full.w / 2, y: full.y, w: full.w / 2, h: full.h };\n } else if (min === fromTop) {\n operation = `split-horizontal`;\n side = `before`;\n zoneRect = { ...full, h: full.h / 2 };\n } else {\n operation = `split-horizontal`;\n side = `after`;\n zoneRect = { x: full.x, y: full.y + full.h / 2, w: full.w, h: full.h / 2 };\n }\n const zone: DockDropZone = { host: this, operation, targetPath: [], side, rect: zoneRect };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n\n private _zoneAllowed(panelId: string, zone: DockDropZone, kind?: string): boolean {\n if (!tokenAllows(this.accepts, operationToToken(zone.operation)))\n return false;\n\n // Per-panel restriction applies only when the drop target is a solo leaf\n const stack = findNode(this._model, zone.targetPath);\n if (stack !== null && isStack(stack) && stack.panels.length === 1) {\n const target = this._findPanelEl(stack.panels[0]);\n if (target && !panelAllows(target.accepts, operationToToken(zone.operation))) {\n return false;\n }\n }\n\n // Leaf content rules govern tabbing *into* a leaf.\n if (zone.operation === `tabs` && stack !== null && isStack(stack)) {\n if (!this._stackAllowsKind(stack, kind?.trim() ? kind.trim() : this._panelKind(panelId))) {\n return false;\n }\n }\n\n // Named-area containment: an edge split creates a new sibling leaf, so it\n // stays allowed *unless* the named leaf's policy sets `allowEdgeSplit:\n // false` — then the edge zones beside it go inert.\n if (zone.operation !== `tabs` && stack !== null && isStack(stack) && !this._leafAllowsEdgeSplit(stack)) {\n return false;\n }\n\n if (this.canAccept && !this.canAccept(panelId, zone.operation)) {\n return false;\n }\n return true;\n }\n\n /**\n * Apply a drop. `sourceHost` differs from `this` when the drag crossed\n * hosts; the panel element is adopted into this host first.\n */\n handleDrop(panelId: string, zone: DockDropZone, sourceHost?: DockHostElement): void {\n if (sourceHost !== undefined && sourceHost !== this) {\n sourceHost.releasePanel(panelId, this);\n }\n\n if (!collectPanelIds(this._model).includes(panelId)) {\n const el = this._findPanelEl(panelId);\n if (!el)\n return;\n this._appendPanelToFirstStack(panelId);\n normalize(this._model);\n }\n\n // In-page moves may carry a vacated leaf's name to the merge target (so\n // merging tabs back together doesn't strand an empty named placeholder).\n // Cross-host drops skip this: their source here is just the temporary\n // adoption stack, not the leaf the panel came from.\n this._applyZone(panelId, zone, sourceHost === undefined || sourceHost === this);\n this._commit();\n }\n\n /**\n * Move `panelId` (already present somewhere in the model) to the position\n * described by `zone`. Shared by in-page drops and external panel adoption.\n */\n private _applyZone(panelId: string, zone: DockDropZone, transferName = false): void {\n const sourcePath = findStackOf(this._model, panelId);\n let vacated: DockStackNode | null = null;\n if (sourcePath !== null) {\n const source = findNode(this._model, sourcePath);\n if (source !== null && isStack(source)) {\n removePanelFromStack(source, panelId);\n if (source.panels.length === 0) {\n vacated = source;\n }\n }\n }\n\n if (zone.operation === `tabs`) {\n const target = findNode(this._model, zone.targetPath);\n if (target !== null && isStack(target)) {\n addPanelToStack(target, panelId, zone.gapIndex);\n // A tabs drop that empties a named stack into an unnamed one hands\n // the name over, so the merged leaf keeps the container identity\n // (and its content rules) instead of leaving a placeholder behind.\n if (transferName && vacated !== null && vacated !== target\n && vacated.name !== undefined && target.name === undefined) {\n target.name = vacated.name;\n delete vacated.name;\n }\n }\n } else {\n insertBeside(this._model, zone.targetPath, opToDirection(zone.operation), createStack([panelId]), zone.side);\n }\n }\n\n /**\n * Move a panel element out of this host into `target`, dropping it from\n * this host's model. Used for cross-host drags.\n */\n releasePanel(panelId: string, target: DockHostElement): void {\n this._returnAllToolbars();\n const el = this._pool.find(p => p.panelId === panelId);\n const stackPath = findStackOf(this._model, panelId);\n if (stackPath !== null) {\n const stack = findNode(this._model, stackPath);\n if (stack !== null && isStack(stack)) {\n removePanelFromStack(stack, panelId);\n }\n }\n normalize(this._model);\n this._pool = this._pool.filter(p => p !== el);\n if (el !== undefined) {\n target.adoptPanelElement(el);\n }\n this.requestUpdate();\n }\n\n /** Adopt a panel element from another host (the one sanctioned reparent). */\n adoptPanelElement(el: DockPanelElement): void {\n this.appendChild(el);\n if (!this._pool.some(p => p.panelId === el.panelId)) {\n this._pool = [...this._pool, el];\n }\n this._appendPanelToFirstStack(el.panelId);\n normalize(this._model);\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ── Drag overlay (driven by the coordinator) ─────────────────────────────\n\n setDragActive(active: boolean): void {\n if (this._dragActive !== active) {\n this._dragActive = active;\n this.requestUpdate();\n }\n }\n\n setDropZone(zone: DockDropZone | null): void {\n if (this._dropZone !== zone) {\n this._dropZone = zone;\n this.requestUpdate();\n }\n }\n\n // ── Junction resize handles ──────────────────────────────────────────────\n\n private _scheduleJunctions(): void {\n if (this._junctionsRaf !== null)\n return;\n this._junctionsRaf = requestAnimationFrame(() => {\n this._junctionsRaf = null;\n this._computeJunctions();\n });\n }\n\n /**\n * Find points where a parent split's gutter line meets a nested split's\n * gutter (T and + crossings). Each junction handle starts both gutter drags\n * at once, like a corner resize in VS Code.\n */\n private _computeJunctions(): void {\n const shadow = this.shadowRoot;\n if (shadow === null)\n return;\n const hostRect = this.getBoundingClientRect();\n const found: DockJunction[] = [];\n\n for (const child of shadow.querySelectorAll<SplitLayoutElement>(`ixfx-split-layout`)) {\n // Nested splits are light children of their parent split\n const parent = child.parentElement?.closest<SplitLayoutElement>(`ixfx-split-layout`) ?? null;\n if (parent === null)\n continue;\n if (typeof child.getGutterRects !== `function` || typeof parent.getGutterRects !== `function`)\n continue;\n const childRect = child.getBoundingClientRect();\n\n for (const [pi, pg] of parent.getGutterRects().entries()) {\n for (const [ci, cg] of child.getGutterRects().entries()) {\n const pgVertical = pg.width <= pg.height;\n const cgVertical = cg.width <= cg.height;\n if (pgVertical === cgVertical)\n continue;\n let x: number;\n let y: number;\n if (pgVertical) {\n // Vertical parent line × horizontal child line: they meet where\n // the child's gutter endpoint abuts the parent's gutter.\n x = pg.left + pg.width / 2;\n y = cg.top + cg.height / 2;\n if (Math.abs(x - childRect.left) > JUNCTION_TOL_PX && Math.abs(x - childRect.right) > JUNCTION_TOL_PX)\n continue;\n if (y < pg.top || y > pg.bottom)\n continue;\n } else {\n y = pg.top + pg.height / 2;\n x = cg.left + cg.width / 2;\n if (Math.abs(y - childRect.top) > JUNCTION_TOL_PX && Math.abs(y - childRect.bottom) > JUNCTION_TOL_PX)\n continue;\n if (x < pg.left || x > pg.right)\n continue;\n }\n found.push({\n x: x - hostRect.left,\n y: y - hostRect.top,\n targets: [\n { split: parent, gutterIndex: pi },\n { split: child, gutterIndex: ci },\n ],\n });\n }\n }\n }\n\n // Merge coincident points so a 4-way cross is a single handle\n const merged: DockJunction[] = [];\n for (const j of found) {\n const near = merged.find(m => Math.abs(m.x - j.x) <= JUNCTION_MERGE_PX && Math.abs(m.y - j.y) <= JUNCTION_MERGE_PX);\n if (near === undefined) {\n merged.push(j);\n continue;\n }\n for (const t of j.targets) {\n if (!near.targets.some(o => o.split === t.split && o.gutterIndex === t.gutterIndex))\n near.targets.push(t);\n }\n }\n\n const key = merged\n .map(j => `${Math.round(j.x)},${Math.round(j.y)}:${j.targets.map(t => `${t.split.getAttribute(`data-dock-path`) ?? ``}#${t.gutterIndex}`).join(`|`)}`)\n .join(`;`);\n if (key === this._junctionsKey)\n return;\n this._junctionsKey = key;\n this._junctions = merged;\n }\n\n private _onJunctionPointerDown = (event: PointerEvent, junction: DockJunction): void => {\n if (event.button !== 0)\n return;\n event.preventDefault();\n event.stopPropagation();\n\n let started = false;\n for (const target of junction.targets) {\n if (!target.split.isConnected)\n continue;\n if (target.split.beginGutterDrag(target.gutterIndex, event.pointerId, event.clientX, event.clientY))\n started = true;\n }\n if (!started)\n return;\n\n // Swallow the trailing click so it cannot focus/select anything beneath.\n this._suppressNextClick();\n\n // Keep the handle following the intersection while both drags run.\n const follow = (): void => this._scheduleJunctions();\n const stop = (): void => {\n window.removeEventListener(`pointermove`, follow);\n window.removeEventListener(`pointerup`, stop);\n window.removeEventListener(`pointercancel`, stop);\n };\n window.addEventListener(`pointermove`, follow);\n window.addEventListener(`pointerup`, stop);\n window.addEventListener(`pointercancel`, stop);\n };\n\n // ── Split-element event consumption ──────────────────────────────────────\n\n /** Fold live weights from each rendered `ixfx-split-layout` into the model. */\n private _foldLiveWeights(): void {\n const splits = this.shadowRoot?.querySelectorAll<SplitLayoutElement>(`ixfx-split-layout[data-dock-path]`);\n if (splits === undefined)\n return;\n for (const el of splits) {\n // A split still stamped with a previous `loadLayout()` generation\n // hasn't re-rendered against the current model yet — its live weights\n // are leftovers from before the load, so folding them now would\n // silently revert the just-loaded sizes.\n if (el.getAttribute(`data-dock-gen`) !== String(this._loadGeneration))\n continue;\n\n const pathStr = el.getAttribute(`data-dock-path`);\n if (pathStr === null)\n continue;\n const node = findNode(this._model, parsePath(pathStr));\n if (node === null || !isSplit(node))\n continue;\n const live = Object.values(el.getSizes());\n if (live.length === node.children.length && !weightsEqual(live, node.sizes)) {\n node.sizes = live;\n // The fold is silent (no dock re-render, so an in-progress drag isn't\n // fought) — but that leaves each child's own `size` attribute lagging\n // the model. Write the folded weights straight onto them so a later\n // split-level rebuild (e.g. collapse/expand reading DOM attributes)\n // sees current sizes instead of stale ones.\n Array.from(el.children).forEach((child, i) => {\n if (child instanceof HTMLElement && node.sizes[i] !== undefined) {\n child.setAttribute(`size`, String(node.sizes[i]));\n }\n });\n }\n }\n }\n\n private _onSplitWeightsChanged = (): void => {\n // Live gutter weights; fold silently (no re-render, so drags aren't fought).\n this._foldLiveWeights();\n this._scheduleJunctions();\n };\n\n private _onSplitCollapsed = (event: Event, collapsed: boolean): void => {\n const detail = (event as CustomEvent<{ id?: string }>).detail;\n if (!detail?.id)\n return;\n const pathStr = this.shadowRoot?.getElementById(detail.id)?.getAttribute(`data-dock-path`);\n if (pathStr === null || pathStr === undefined)\n return;\n const node = findNode(this._model, parsePath(pathStr));\n if (node === null || !isStack(node))\n return;\n // Model mirrors the element; no re-render needed (attrs already match).\n if (collapsed) {\n node.collapsed = true;\n } else {\n delete node.collapsed;\n }\n };\n\n private _onSplitClose = (event: Event): void => {\n // Route leaf closes through the model so panel elements survive: each\n // panel re-homes into the first other stack admitting its kind (or the\n // pool when none does).\n event.preventDefault();\n const detail = (event as CustomEvent<{ id?: string }>).detail;\n if (!detail?.id)\n return;\n const pathStr = this.shadowRoot?.getElementById(detail.id)?.getAttribute(`data-dock-path`);\n if (pathStr === null || pathStr === undefined)\n return;\n const path = parsePath(pathStr);\n const closing = findNode(this._model, path);\n if (closing === null || !isStack(closing))\n return;\n const moving = [...closing.panels];\n this._returnAllToolbars();\n extractStack(this._model, path);\n for (const panelId of moving) {\n addPanelToStack(this._firstStackAllowing(this._panelKind(panelId)), panelId);\n }\n this._commit();\n };\n\n // ── Tab-strip events ─────────────────────────────────────────────────────\n\n private _onTabChange = (event: Event, path: number[]): void => {\n const panelId = (event as TabListChangeEvent).detail.selected;\n const stack = findNode(this._model, path);\n if (stack === null || !isStack(stack))\n return;\n if (!setActive(stack, panelId))\n return;\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-activated`, {\n detail: { panelId },\n bubbles: true,\n composed: true,\n }));\n };\n\n private _onStripPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0)\n return;\n\n // Presses that begin on strip chrome (toolbar buttons, close buttons) are\n // not drag handles.\n const path = event.composedPath();\n for (const node of path) {\n if (!(node instanceof HTMLElement))\n continue;\n if (node.classList.contains(`list-toolbar`) || node.classList.contains(`close-btn`)) {\n return;\n }\n }\n\n const item = path.find((node): node is HTMLElement =>\n node instanceof HTMLElement && node.tagName === `IXFX-TAB-LIST-ITEM`) ?? null;\n if (item === null || !item.id)\n return;\n\n this._tabDragPending = {\n panelId: item.id,\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n };\n\n window.addEventListener(`pointermove`, this._onTabDragMove);\n window.addEventListener(`pointerup`, this._onTabDragUp);\n window.addEventListener(`pointercancel`, this._onTabDragUp);\n };\n\n private _onTabDragMove = (event: PointerEvent): void => {\n const pending = this._tabDragPending;\n if (pending === null || event.pointerId !== pending.pointerId)\n return;\n\n const distance = Math.hypot(event.clientX - pending.startX, event.clientY - pending.startY);\n if (distance < DRAG_THRESHOLD_PX)\n return;\n\n this._tabDragPending = null;\n this._teardownTabDragListeners();\n this._suppressNextClick();\n\n this.dispatchEvent(new CustomEvent<{ panelId: string; pointerId: number; clientX: number; clientY: number }>(`dock-panel-drag-start`, {\n detail: {\n panelId: pending.panelId,\n pointerId: pending.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n },\n bubbles: true,\n composed: true,\n }));\n };\n\n private _onTabDragUp = (event: PointerEvent): void => {\n if (this._tabDragPending === null || event.pointerId !== this._tabDragPending.pointerId)\n return;\n this._tabDragPending = null;\n this._teardownTabDragListeners();\n };\n\n private _teardownTabDragListeners(): void {\n window.removeEventListener(`pointermove`, this._onTabDragMove);\n window.removeEventListener(`pointerup`, this._onTabDragUp);\n window.removeEventListener(`pointercancel`, this._onTabDragUp);\n }\n\n /** After a dock drag from a tab/titlebar, swallow the trailing click so it cannot re-select or toggle. */\n private _suppressNextClick(): void {\n const swallow = (e: MouseEvent): void => {\n e.preventDefault();\n e.stopPropagation();\n window.removeEventListener(`click`, swallow, true);\n };\n window.addEventListener(`click`, swallow, true);\n }\n\n // ── Internal plumbing ────────────────────────────────────────────────────\n\n private _removeFromModel(panelId: string): void {\n const stackPath = findStackOf(this._model, panelId);\n if (stackPath === null)\n return;\n const stack = findNode(this._model, stackPath);\n if (stack !== null && isStack(stack)) {\n removePanelFromStack(stack, panelId);\n }\n normalize(this._model);\n }\n\n /** Normalize, re-render, and announce the structural change. */\n private _commit(): void {\n normalize(this._model);\n this.requestUpdate();\n this._emitChange();\n }\n\n private _syncSlots(): void {\n const inModel = new Set<string>();\n const visit = (node: DockNode): void => {\n if (isStack(node)) {\n for (const id of node.panels) {\n inModel.add(id);\n const el = this._findPanelEl(id);\n if (el === undefined)\n continue;\n el.setAttribute(`slot`, `dock-panel-${id}`);\n // Docked panels always render content-only; the leaf strip carries\n // the title chrome for every stack, single-panel or not.\n el.presentation = `tabbed`;\n }\n } else {\n node.children.forEach(visit);\n }\n };\n visit(this._model);\n\n for (const el of this._pool) {\n if (!inModel.has(el.panelId)) {\n el.setAttribute(`slot`, ``);\n el.presentation = `solo`;\n }\n }\n }\n\n /**\n * Per-panel toolbar routing: docked panels render content-only, so the\n * active panel's toolbar nodes live in its generated tab item (shown\n * right-aligned while active). Node moves preserve element state. Panels\n * outside the model keep their toolbar in their own (solo) chrome.\n */\n private _syncToolbars(): void {\n const wanted = new Map<string, HTMLElement[]>();\n const visit = (node: DockNode): void => {\n if (isStack(node)) {\n if (node.panels.length > 0 && node.active) {\n const el = this._findPanelEl(node.active);\n if (el !== undefined) {\n wanted.set(node.active, toolbarNodesOf(el));\n }\n }\n } else {\n node.children.forEach(visit);\n }\n };\n visit(this._model);\n\n for (const [panelId, nodes] of this._toolbarsOut) {\n if (!wanted.has(panelId)) {\n this._returnToolbar(panelId, nodes);\n }\n }\n\n for (const [panelId, nodes] of wanted) {\n if (this._toolbarsOut.has(panelId) || nodes.length === 0)\n continue;\n const item = this.shadowRoot?.getElementById(panelId);\n if (item === null || item === undefined)\n continue;\n for (const node of nodes) {\n item.appendChild(node);\n }\n this._toolbarsOut.set(panelId, nodes);\n }\n }\n\n private _returnToolbar(panelId: string, nodes: HTMLElement[]): void {\n const el = this._findPanelEl(panelId);\n if (el !== undefined) {\n for (const node of nodes) {\n if (node.isConnected) {\n el.appendChild(node);\n }\n }\n }\n this._toolbarsOut.delete(panelId);\n }\n\n private _returnAllToolbars(): void {\n for (const [panelId, nodes] of [...this._toolbarsOut]) {\n this._returnToolbar(panelId, nodes);\n }\n }\n\n private _emitChange(): void {\n this.dispatchEvent(new CustomEvent<{ layout: DockLayout }>(`dock-change`, {\n detail: { layout: this.saveLayout() },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ── Render ───────────────────────────────────────────────────────────────\n\n protected override render() {\n return html`\n <div class=\"root\">\n ${this._renderNode(this._model, [])}\n </div>\n <div class=\"overlay\" ?hidden=${!this._dragActive}>\n ${this._dropZone === null\n ? nothing\n : html`\n <div class=\"zone-rect\" style=${rectStyle(this._dropZone.rect)}></div>\n ${this._dropZone.caretRect === undefined\n ? nothing\n : html`<div class=\"zone-caret\" style=${rectStyle(this._dropZone.caretRect)}></div>`}\n `}\n </div>\n <div class=\"junctions\" ?hidden=${this._dragActive}>\n ${this._junctions.map(junction => html`\n <div\n class=\"junction-handle\"\n style=${`left:${junction.x}px; top:${junction.y}px;`}\n role=\"separator\"\n aria-label=\"Resize adjacent panels\"\n @pointerdown=${(e: PointerEvent) => this._onJunctionPointerDown(e, junction)}\n ><span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"spot\" part=\"junction-handle\"></span></div>\n `)}\n </div>\n <slot @slotchange=${this._onPoolSlotChange}></slot>\n `;\n }\n\n private _renderNode(node: DockNode, path: number[], size?: number): unknown {\n if (isStack(node)) {\n return this._renderLeaf(node, path, size);\n }\n return this._renderSplit(node, path, size);\n }\n\n private _renderSplit(node: DockNode & { kind: `split` }, path: number[], size?: number): unknown {\n const pathStr = path.join(`-`);\n return html`\n <ixfx-split-layout\n class=\"split\"\n direction=${node.direction}\n size=${size === undefined ? nothing : String(size)}\n style=${`--split-gutter-size: var(--dock-split-bar-size, 2px); --split-collapsed-size: var(--dock-collapsed-size, 40px)`}\n data-dock-path=${pathStr}\n data-dock-gen=${this._loadGeneration}\n @ixfx-split-resize=${this._onSplitWeightsChanged}\n @ixfx-split-change=${this._onSplitWeightsChanged}\n @ixfx-split-collapse=${(e: Event) => this._onSplitCollapsed(e, true)}\n @ixfx-split-expand=${(e: Event) => this._onSplitCollapsed(e, false)}\n @ixfx-split-close=${this._onSplitClose}\n >\n ${node.children.map((child, i) => this._renderNode(child, [...path, i], node.sizes[i]))}\n </ixfx-split-layout>\n `;\n }\n\n private _renderLeaf(stack: DockStackNode, path: number[], size?: number): unknown {\n const pathStr = path.join(`-`);\n const collapsible = stack.panels.length === 1\n ? (this._findPanelEl(stack.panels[0])?.collapsible ?? false)\n : false;\n\n const leafAttrs = (content: unknown): unknown => html`\n <div\n id=${`dock-leaf-${pathStr}`}\n class=\"leaf\"\n data-dock-path=${pathStr}\n data-dock-name=${stack.name ?? nothing}\n size=${size === undefined ? nothing : String(size)}\n min=${collapsible ? `1px` : nothing}\n when-small=${collapsible ? `collapse` : nothing}\n ?collapsed=${stack.collapsed === true}\n >${content}</div>\n `;\n\n if (stack.panels.length === 0) {\n return leafAttrs(html`\n <div class=\"empty\" part=\"empty\">\n <slot name=\"empty\"><span>Drop panels here</span></slot>\n </div>\n `);\n }\n\n // Every leaf renders the same strip + body chrome, so titlebars are\n // consistent whether a stack holds one panel or many. Named leaves\n // forward light-DOM `toolbar-<name>` content into the strip's toolbar.\n const toolbarSlot = stack.name !== undefined && this._toolbarSlots.has(`toolbar-${stack.name}`)\n ? html`<slot name=\"toolbar-${stack.name}\" slot=\"toolbar\"></slot>`\n : nothing;\n return leafAttrs(html`\n <ixfx-tab-list\n class=\"strip\"\n orientation=\"horizontal\"\n scrollable\n shrink\n ?hide-labels=${stack.hideLabels === true}\n @change=${(e: Event) => this._onTabChange(e, path)}\n @pointerdown=${this._onStripPointerDown}\n >\n ${repeat(stack.panels, id => id, id => this._renderTabItem(stack, id))}\n ${toolbarSlot}\n </ixfx-tab-list>\n <div class=\"leaf-body\">\n <slot name=\"dock-panel-${stack.active}\"></slot>\n </div>\n `);\n }\n\n private _renderTabItem(stack: DockStackNode, panelId: string): unknown {\n const el = this._findPanelEl(panelId);\n return html`\n <ixfx-tab-list-item\n id=${panelId}\n ?selected=${panelId === stack.active}\n .iconName=${el?.iconName ?? ``}\n .closeable=${el?.closable ?? false}\n @close=${() => this.removePanel(panelId)}\n >${el?.title ?? panelId}</ixfx-tab-list-item>\n `;\n }\n\n private _stripCaretRect(strip: Element, gapIndex: number | undefined, hostRect: DOMRect): Rect | undefined {\n const items = Array.from(strip.querySelectorAll(`ixfx-tab-list-item`)) as HTMLElement[];\n if (items.length === 0)\n return undefined;\n const index = Math.max(0, Math.min(gapIndex ?? items.length, items.length));\n const edge = index < items.length\n ? items[index].getBoundingClientRect().left\n : items[items.length - 1].getBoundingClientRect().right;\n const stripRect = strip.getBoundingClientRect();\n return {\n x: edge - hostRect.left - 1,\n y: stripRect.top - hostRect.top,\n w: 2,\n h: stripRect.height,\n };\n }\n\n static override styles = [\n themeFallbacks,\n handleStyles,\n css`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n --dock-drop-zone-color: var(--accent);\n --dock-drop-zone-opacity: 0.25;\n --dock-collapsed-size: 40px;\n --dock-split-bar-size: 2px;\n position: relative;\n }\n\n .root {\n width: 100%;\n height: 100%;\n }\n\n ixfx-split-layout.split {\n width: 100%;\n height: 100%;\n }\n\n .leaf {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n box-sizing: border-box;\n overflow: hidden;\n border: 1px solid var(--surface-4);\n border-radius: var(--radius-m);\n }\n\n .leaf[collapsed] {\n pointer-events: none;\n }\n\n .leaf[collapsed] .leaf-body,\n .leaf[collapsed] .empty {\n visibility: hidden;\n }\n\n .strip {\n flex-shrink: 0;\n border: 0;\n /* The leaf background shows through selected tabs; a text underline\n (not the border indicator) carries the selection. */\n --ixfx-tab-selected-background: transparent;\n --ixfx-selected-tab-border-width: 0;\n --ixfx-selected-tab-text-decoration: underline;\n --ixfx-selected-tab-text-decoration-thickness: 2px;\n --ixfx-selected-tab-text-decoration-offset: 4px;\n --ixfx-tab-hover-background: var(--surface-4);\n }\n\n /* Uniform tab height: a panel toolbar button would otherwise inflate\n its tab item, giving strips of different stacks different heights. */\n .strip ixfx-tab-list-item {\n height: var(--dock-tab-height, 30px);\n }\n\n /* Breathing room between strip toolbars and the leaf edge. */\n .strip::part(list-toolbar) {\n padding-right: var(--space-xs);\n }\n\n .leaf-body {\n flex: 1;\n min-height: 0;\n min-width: 0;\n box-sizing: border-box;\n padding: var(--dock-leaf-body-padding, var(--space-s));\n }\n\n .empty {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--surface-3-text);\n opacity: 0.6;\n font-size: var(--text-m);\n border: 1px dashed var(--border-subtle);\n border-radius: var(--radius-m);\n margin: var(--space-s);\n }\n\n .overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 100;\n }\n\n .zone-rect {\n position: absolute;\n background: var(--dock-drop-zone-color);\n opacity: var(--dock-drop-zone-opacity);\n border-radius: var(--radius-s);\n }\n\n .zone-caret {\n position: absolute;\n background: var(--dock-drop-zone-color);\n border-radius: 1px;\n }\n\n .junctions {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 99;\n }\n\n .junctions[hidden] {\n display: none;\n }\n\n .junction-handle {\n position: absolute;\n width: 14px;\n height: 14px;\n transform: translate(-50%, -50%);\n border-radius: 50%;\n cursor: nwse-resize;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .junction-handle .ixfx-handle {\n --ixfx-handle-spot-size: 12px;\n --ixfx-handle-dot-size: 3px;\n --ixfx-handle-opacity: 0;\n --ixfx-handle-opacity-active: 0.9;\n }\n\n slot:not([name]) {\n display: none;\n }\n `,\n ];\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** `split-horizontal` = horizontal divider = panels stacked vertically. */\nfunction opToDirection(op: DockOperation): `row` | `column` {\n return op === `split-horizontal` ? `column` : `row`;\n}\n\nfunction operationToToken(op: DockOperation): string {\n if (op === `tabs`)\n return `tabs`;\n return op === `split-horizontal` ? `horizontal` : `vertical`;\n}\n\n/** Host-level `accepts`: empty or `none` rejects everything. */\nfunction tokenAllows(tokens: string, token: string): boolean {\n const list = tokens.trim().split(/\\s+/).filter(t => t.length > 0);\n if (list.length === 0 || (list.length === 1 && list[0] === `none`))\n return false;\n return list.includes(`all`) || list.includes(token);\n}\n\n/** Panel-level `accepts`: empty means unrestricted (host rules still apply). */\nfunction panelAllows(tokens: string, token: string): boolean {\n const list = tokens.trim().split(/\\s+/).filter(t => t.length > 0);\n if (list.length === 0)\n return true;\n if (list.length === 1 && list[0] === `none`)\n return false;\n return list.includes(`all`) || list.includes(token);\n}\n\nfunction weightsEqual(a: number[], b: number[]): boolean {\n if (a.length !== b.length)\n return false;\n return a.every((v, i) => Math.abs(v - b[i]) < 0.0001);\n}\n\nfunction rectStyle(r: Rect): string {\n return `left:${r.x}px; top:${r.y}px; width:${r.w}px; height:${r.h}px;`;\n}\n\n/** Strip a live `DockDropZone` down to its serializable {@link DockDropTarget}. */\nfunction zoneToTarget(zone: DockDropZone): DockDropTarget {\n return {\n operation: zone.operation,\n targetPath: [...zone.targetPath],\n side: zone.side,\n ...(zone.gapIndex === undefined ? {} : { gapIndex: zone.gapIndex }),\n };\n}\n\nfunction cloneNode(node: DockNode): DockNode {\n return JSON.parse(JSON.stringify(node)) as DockNode;\n}\n\n/** Panel content kind, normalized (`'any'` when unset/blank). */\nfunction normalizeKind(kind: string | undefined): string {\n const trimmed = kind?.trim() ?? ``;\n return trimmed || `any`;\n}\n\nfunction parsePath(pathStr: string): number[] {\n return pathStr.length === 0 ? [] : pathStr.split(`-`).filter(s => s.length > 0).map(Number);\n}\n\n/** Toolbar-slot light children of a dock panel. */\nfunction toolbarNodesOf(el: DockPanelElement): HTMLElement[] {\n return Array.from(el.children).filter((c): c is HTMLElement =>\n c instanceof HTMLElement && c.getAttribute(`slot`) === `toolbar`);\n}\n\n/** Nearest strip gap to the pointer (reuses the tab-list midpoint rule). */\nfunction computeStripGapIndex(strip: Element, clientX: number, _clientY: number): number {\n const items = Array.from(strip.querySelectorAll(`ixfx-tab-list-item`)) as HTMLElement[];\n if (items.length === 0)\n return 0;\n for (let i = 0; i < items.length; i++) {\n const r = items[i].getBoundingClientRect();\n const mid = (r.left + r.right) / 2;\n if (clientX < mid)\n return i;\n }\n return items.length;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-dock-host': DockHostElement;\n }\n}\n\nexport interface DockHostElement {\n addEventListener: (<K extends keyof DockHostElementEventMap>(\n type: K,\n listener: (this: DockHostElement, event: DockHostElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { safeCustomElement } from '../util/custom-elements.js';\nimport \"./form.css\";\n\n@safeCustomElement(`ixfx-form-group`)\nexport class FormGroupElement extends LitElement {\n @property({ type: String })\n label = ``;\n\n private _fieldset?: HTMLFieldSetElement;\n private _observer?: MutationObserver;\n\n protected override createRenderRoot() {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._observer = new MutationObserver(() => this._moveChildren());\n }\n\n override firstUpdated(): void {\n this._fieldset = this.querySelector(`fieldset`) ?? undefined;\n if (this._fieldset) {\n this._observer?.observe(this, { childList: true });\n this._moveChildren();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._observer?.disconnect();\n }\n\n private _moveChildren(): void {\n if (!this._fieldset) {\n return;\n }\n\n const toMove = Array.from(this.children).filter(el => el.tagName !== `FIELDSET`);\n toMove.forEach((el) => {\n this._fieldset!.appendChild(el);\n });\n }\n\n protected override render() {\n return html`<fieldset><legend>${this.label}</legend></fieldset>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-form-group': FormGroupElement;\n }\n}","import { html, LitElement } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { safeCustomElement } from \"../util/custom-elements.js\";\nimport \"./form.css\";\n\nlet idCounter = 0;\n\n@safeCustomElement(`ixfx-form-part`)\nexport class FormPartElement extends LitElement {\n @property({ type: String })\n label = ``;\n\n private _id?: string;\n\n protected override createRenderRoot() {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._ensureId();\n }\n\n private _ensureId(): void {\n const control = this.querySelector(`input, select, textarea, [name]`) as HTMLElement | null;\n if (!control) {\n return;\n }\n\n if (!control.id) {\n this._id = `ixfx-form-part-${++idCounter}`;\n control.id = this._id;\n } else {\n this._id = control.id;\n }\n }\n\n protected override render() {\n if (!this._id) {\n this._ensureId();\n }\n\n return html`<label for=${this._id ?? ``}>${this.label}</label>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-form-part\": FormPartElement;\n }\n}","import type { CommandId } from '@clinth/ui-commands';\nimport type { TreeExclusivity, TreeInteractionMode, TreeItem, TreeNode, TreeSelectionFilter } from '../common/types.js';\nimport type { TreeBaseElement } from '../tree/tree-base.js';\nimport type { ListSelectionMode } from '../vertical-list/types.js';\nimport type {\n IGroupedSubComponent,\n SubComponentActivateDetail,\n SubComponentItemClickDetail,\n SubComponentSelectDetail,\n SubComponentTickleDetail,\n} from './types.js';\nimport '../tree/tree-list.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type TreeListAdapterOptions<T> = {\n /**\n * Returns the direct children of an item to build the tree hierarchy.\n * Omit for flat item lists — all items become leaf nodes at the root level.\n */\n getChildren?: (item: T) => readonly T[];\n\n /** Forwarded to the inner ixfx-tree-list. Default: `'standard'`. */\n interactionMode?: TreeInteractionMode;\n\n /**\n * Controls which node types are selectable.\n * Forwarded to the inner ixfx-tree-list. Default: `'all'`.\n */\n selectionFilter?: TreeSelectionFilter;\n\n /**\n * Controls how expanding one node affects its siblings.\n * Forwarded to the inner ixfx-tree-list. Default: `'none'`.\n */\n exclusivity?: TreeExclusivity;\n\n /**\n * Called when a command is dispatched via `ixfx-grouped-item-lister.dispatch()`.\n * Receives the inner `TreeBaseElement` (undefined until the first `setItems()` call)\n * so the handler can sort, filter, or otherwise manipulate the tree directly.\n */\n onDispatch?: (\n commandId: CommandId,\n args: Record<string, unknown> | undefined,\n tree: TreeBaseElement | undefined,\n ) => void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an `HTMLElement` that implements `IGroupedSubComponent<T>` by wrapping\n * an `ixfx-tree-list` internally.\n *\n * `toTreeItem` converts each item `T` to display metadata (`key`, `label`, etc).\n * The adapter stores the original `T` in `TreeItem.data` and uses it to map\n * tree-node selections back to typed values.\n *\n * Unlike `createVerticalListAdapter`, items can be hierarchical: provide\n * `options.getChildren` to return each item's children and the adapter will\n * recursively build the `TreeNode` tree. Omit it for a flat list of leaf nodes.\n *\n * The four interface events (`select`, `activate`, `item-click`, `tickle`) are\n * intercepted at the tree level, re-typed from `TreeNode` → `T`, and re-dispatched\n * on the adapter element so `ixfx-grouped-item-lister` can identify the source.\n *\n * @example Flat item list:\n * ```ts\n * lister.factory = () =>\n * createTreeListAdapter<FileItem>(item => ({ key: item.id, label: item.name, isLeaf: true }));\n * ```\n *\n * @example Hierarchical items:\n * ```ts\n * lister.factory = () =>\n * createTreeListAdapter<Category>(\n * cat => ({ key: cat.id, label: cat.name }),\n * { getChildren: cat => cat.subCategories },\n * );\n * ```\n */\nexport function createTreeListAdapter<T>(\n toTreeItem: (item: T) => Omit<TreeItem, `data`>,\n options?: TreeListAdapterOptions<T>,\n): HTMLElement & IGroupedSubComponent<T> {\n const container = document.createElement(`div`);\n container.style.cssText = `display:contents;`;\n\n let treeEl: TreeBaseElement | undefined;\n\n // ---- Tree building ----\n\n function buildNode(item: T): TreeNode {\n const treeItem: TreeItem = { ...toTreeItem(item), data: item };\n const children = options?.getChildren?.(item);\n return {\n item: treeItem,\n // If getChildren is provided, recurse. For known leaves (isLeaf:true or\n // no getChildren), use [] to signal \"confirmed leaf\" to the tree.\n children: children ? children.map(buildNode) : (treeItem.isLeaf ? [] : undefined),\n };\n }\n\n function getOrCreateTree(): TreeBaseElement {\n if (treeEl)\n return treeEl;\n\n treeEl = document.createElement(`ixfx-tree-list`) as TreeBaseElement;\n treeEl.interactionMode = options?.interactionMode ?? `standard`;\n treeEl.selectionFilter = options?.selectionFilter ?? `all`;\n treeEl.exclusivity = options?.exclusivity ?? `none`;\n treeEl.style.cssText = `display:block;width:100%;`;\n\n container.appendChild(treeEl);\n attachBridgeListeners();\n\n return treeEl;\n }\n\n // ---- Node → T mapping (via TreeItem.data) ----\n\n function mapNodes(nodes: ReadonlySet<TreeNode>): ReadonlySet<T> {\n const result = new Set<T>();\n for (const node of nodes) {\n if (node.item.data !== undefined)\n result.add(node.item.data as T);\n }\n return result;\n }\n\n // ---- Event bridge ----\n //\n // The tree fires the same event names as IGroupedSubComponent ('select',\n // 'activate', etc.). We must intercept them at the tree level and re-dispatch\n // on the container so grouped-item-lister can identify the correct source\n // element (the container, not the inner tree).\n\n function attachBridgeListeners(): void {\n treeEl!.addEventListener(`select`, (e) => {\n e.stopPropagation();\n const detail: SubComponentSelectDetail<T> = {\n selected: mapNodes(e.detail.selected),\n previous: mapNodes(e.detail.previous),\n };\n container.dispatchEvent(\n new CustomEvent(`select`, { detail, bubbles: true, composed: true }),\n );\n });\n\n treeEl!.addEventListener(`activate`, (e) => {\n e.stopPropagation();\n const item = (e.detail.node as TreeNode).item.data as T | undefined;\n if (item === undefined)\n return;\n const detail: SubComponentActivateDetail<T> = { item };\n container.dispatchEvent(\n new CustomEvent(`activate`, { detail, bubbles: true, composed: true }),\n );\n });\n\n treeEl!.addEventListener(`item-click`, (e) => {\n e.stopPropagation();\n const item = (e.detail.node as TreeNode).item.data as T | undefined;\n if (item === undefined)\n return;\n const detail: SubComponentItemClickDetail<T> = { item };\n container.dispatchEvent(\n new CustomEvent(`item-click`, { detail, bubbles: true, composed: true }),\n );\n });\n\n treeEl!.addEventListener(`tickle`, (e) => {\n e.stopPropagation();\n const item = (e.detail.node as TreeNode).item.data as T | undefined;\n if (item === undefined)\n return;\n const detail: SubComponentTickleDetail<T> = { item };\n container.dispatchEvent(\n new CustomEvent(`tickle`, { detail, bubbles: true, composed: true }),\n );\n });\n }\n\n // ---- IGroupedSubComponent implementation ----\n\n let selectionMode: ListSelectionMode = `single`;\n\n const adapter = Object.assign(container, {\n setItems(items: readonly T[]): void {\n const tree = getOrCreateTree();\n tree.root = {\n item: { key: `__adapter_root__`, label: ``, isLeaf: false },\n children: items.map(buildNode),\n };\n },\n\n clearSelection(): void {\n treeEl?.clearSelection();\n },\n\n dispatch(commandId: CommandId, args?: Record<string, unknown>): void {\n options?.onDispatch?.(commandId, args, treeEl);\n },\n });\n\n Object.defineProperties(adapter, {\n selectedItems: {\n get(): ReadonlySet<T> {\n return treeEl ? mapNodes(treeEl.selectedNodes) : new Set<T>();\n },\n enumerable: true,\n configurable: true,\n },\n selectionMode: {\n get(): ListSelectionMode {\n return selectionMode;\n },\n set(v: ListSelectionMode) {\n selectionMode = v;\n if (!treeEl)\n return;\n if (v === `none`) {\n treeEl.selectionFilter = `none`;\n } else if (v === `single`) {\n treeEl.selectionFilter = options?.selectionFilter ?? `all`;\n treeEl.interactionMode = `implicit`;\n } else {\n treeEl.selectionFilter = options?.selectionFilter ?? `all`;\n treeEl.interactionMode = options?.interactionMode ?? `standard`;\n }\n },\n enumerable: true,\n configurable: true,\n },\n });\n\n return adapter as unknown as HTMLElement & IGroupedSubComponent<T>;\n}\n","import type { CommandId } from '@clinth/ui-commands';\nimport type { ListInteractionMode, ListSelectionMode } from '../vertical-list/types.js';\nimport type { VerticalListElement } from '../vertical-list/vertical-list.js';\nimport type { IGroupedSubComponent, SubComponentSelectDetail } from './types.js';\nimport '../vertical-list/vertical-list.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type VerticalListAdapterOptions = {\n /** Initial selection mode forwarded to the inner ixfx-vertical-list. Default: `'single'`. */\n selectionMode?: ListSelectionMode;\n\n /** Interaction mode forwarded to the inner ixfx-vertical-list. Default: `'standard'`. */\n interactionMode?: ListInteractionMode;\n\n /**\n * Called when a command is dispatched via `ixfx-grouped-item-lister.dispatch()`.\n *\n * Receives the current inner `VerticalListElement` (undefined until the first\n * `setItems()` call) so the handler can sort, filter, or otherwise mutate the\n * list directly.\n *\n * @example Sort items alphabetically by text content:\n * ```ts\n * onDispatch: (id, _args, list) => {\n * if (id !== 'sort-alpha' || !list) return;\n * const rows = [...list.querySelectorAll<HTMLElement>('li')];\n * rows.sort((a, b) => (a.textContent ?? '').localeCompare(b.textContent ?? ''));\n * for (const row of rows) list.appendChild(row);\n * }\n * ```\n */\n onDispatch?: (\n commandId: CommandId,\n args: Record<string, unknown> | undefined,\n list: VerticalListElement | undefined,\n ) => void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an `HTMLElement` that implements `IGroupedSubComponent<T>` by wrapping\n * an `ixfx-vertical-list` internally.\n *\n * Items are typed as `T`. The `renderItem` function converts each item to a DOM\n * element (typically an `<li>`) that `ixfx-vertical-list` renders and handles\n * pointer/keyboard interaction for.\n *\n * The returned element bridges the `list-*` event names fired by\n * `ixfx-vertical-list` to the `select / activate / item-click / tickle` names\n * required by `IGroupedSubComponent`, and maps element-based selection sets back\n * to typed `T` values.\n *\n * @example Basic usage with ixfx-grouped-item-lister:\n * ```ts\n * lister.factory = () =>\n * createVerticalListAdapter<MyItem>(item => {\n * const li = document.createElement('li');\n * li.textContent = item.label;\n * return li;\n * });\n * ```\n */\nexport function createVerticalListAdapter<T>(\n renderItem: (item: T) => Element,\n options?: VerticalListAdapterOptions,\n): HTMLElement & IGroupedSubComponent<T> {\n // Plain div — not a custom element, so appendChild is safe at any time.\n // display:contents makes it invisible in layout; the inner list is treated\n // as if it were a direct child of whatever the adapter is placed inside.\n const container = document.createElement(`div`);\n container.style.cssText = `display:contents;`;\n\n let listEl: VerticalListElement | undefined;\n let selectionMode: ListSelectionMode = options?.selectionMode ?? `single`;\n let elToItem = new WeakMap<Element, T>();\n\n // ---- Internal helpers ----\n\n function getOrCreateList(): VerticalListElement {\n if (listEl)\n return listEl;\n\n listEl = document.createElement(`ixfx-vertical-list`) as VerticalListElement;\n // Override :host { height:100% } so the list sizes to its content\n // when placed inside a panel with no explicit height.\n listEl.style.cssText = `height:auto;width:100%;`;\n listEl.selectionMode = selectionMode;\n if (options?.interactionMode)\n listEl.interactionMode = options.interactionMode;\n\n container.appendChild(listEl);\n attachBridgeListeners();\n\n return listEl;\n }\n\n function attachBridgeListeners(): void {\n listEl!.addEventListener(`list-select`, (e) => {\n const detail: SubComponentSelectDetail<T> = {\n selected: mapEls(e.detail.selected),\n previous: mapEls(e.detail.previous),\n };\n container.dispatchEvent(\n new CustomEvent(`select`, { detail, bubbles: true, composed: true }),\n );\n });\n\n listEl!.addEventListener(`list-activate`, (e) => {\n const item = elToItem.get(e.detail.item);\n if (item !== undefined) {\n container.dispatchEvent(\n new CustomEvent(`activate`, { detail: { item }, bubbles: true, composed: true }),\n );\n }\n });\n\n listEl!.addEventListener(`list-item-click`, (e) => {\n const item = elToItem.get(e.detail.item);\n if (item !== undefined) {\n container.dispatchEvent(\n new CustomEvent(`item-click`, { detail: { item }, bubbles: true, composed: true }),\n );\n }\n });\n\n listEl!.addEventListener(`list-tickle`, (e) => {\n const item = elToItem.get(e.detail.item);\n if (item !== undefined) {\n container.dispatchEvent(\n new CustomEvent(`tickle`, { detail: { item }, bubbles: true, composed: true }),\n );\n }\n });\n }\n\n function applyItems(items: readonly T[]): void {\n const list = getOrCreateList();\n list.clearItems();\n elToItem = new WeakMap();\n for (const item of items) {\n const el = renderItem(item);\n elToItem.set(el, item);\n list.addItem(el);\n }\n }\n\n function mapEls(els: ReadonlySet<Element>): ReadonlySet<T> {\n const result = new Set<T>();\n for (const el of els) {\n const item = elToItem.get(el);\n if (item !== undefined)\n result.add(item);\n }\n return result;\n }\n\n // ---- IGroupedSubComponent methods ----\n\n const adapter = Object.assign(container, {\n setItems(items: readonly T[]): void {\n applyItems(items);\n },\n\n clearSelection(): void {\n listEl?.clearSelection();\n },\n\n dispatch(commandId: CommandId, args?: Record<string, unknown>): void {\n options?.onDispatch?.(commandId, args, listEl);\n },\n });\n\n // Getters/setters require defineProperties — Object.assign would invoke them\n Object.defineProperties(adapter, {\n selectedItems: {\n get(): ReadonlySet<T> {\n return listEl ? mapEls(listEl.selectedItems) : new Set<T>();\n },\n enumerable: true,\n configurable: true,\n },\n selectionMode: {\n get(): ListSelectionMode {\n return listEl?.selectionMode ?? selectionMode;\n },\n set(v: ListSelectionMode) {\n selectionMode = v;\n if (listEl)\n listEl.selectionMode = v;\n },\n enumerable: true,\n configurable: true,\n },\n });\n\n return adapter as unknown as HTMLElement & IGroupedSubComponent<T>;\n}\n","/**\n * Pure hyperbolic geometry primitives for the Poincaré disk model.\n * No Lit, no DOM — unit-testable in isolation.\n *\n * Points are represented as `{ x, y }`, read as the complex number `x + yi`.\n * All translation functions are hyperbolic isometries: they preserve\n * pairwise Poincaré distances between points.\n */\n\nimport type { Point } from './types.js';\n\nconst EPSILON = 1e-9;\n\nfunction complexMul(a: Point, b: Point): Point {\n return { x: a.x * b.x - a.y * b.y, y: a.x * b.y + a.y * b.x };\n}\n\nfunction complexConjugate(a: Point): Point {\n return { x: a.x, y: -a.y };\n}\n\nfunction complexAdd(a: Point, b: Point): Point {\n return { x: a.x + b.x, y: a.y + b.y };\n}\n\nfunction complexSub(a: Point, b: Point): Point {\n return { x: a.x - b.x, y: a.y - b.y };\n}\n\nfunction complexScale(a: Point, s: number): Point {\n return { x: a.x * s, y: a.y * s };\n}\n\nfunction complexDiv(a: Point, b: Point): Point {\n const denominator = b.x * b.x + b.y * b.y;\n if (denominator < EPSILON)\n return { x: 0, y: 0 };\n return complexScale(complexMul(a, complexConjugate(b)), 1 / denominator);\n}\n\n/** Euclidean norm (`|z|`) of a point. */\nexport function norm(a: Point): number {\n return Math.hypot(a.x, a.y);\n}\n\n/** Clamp a point to stay strictly inside the unit disk (the Poincaré model's boundary is never reached). */\nexport function clampToDisk(p: Point, maxNorm = 0.999999): Point {\n const n = norm(p);\n if (n <= maxNorm)\n return p;\n return complexScale(p, maxNorm / n);\n}\n\n/**\n * Möbius transform that translates `a` to the origin: `(z - a) / (1 - conj(a) * z)`.\n * A hyperbolic isometry — preserves all pairwise Poincaré distances.\n */\nexport function mobiusToOrigin(z: Point, a: Point): Point {\n const numerator = complexSub(z, a);\n const denominator = complexSub({ x: 1, y: 0 }, complexMul(complexConjugate(a), z));\n return clampToDisk(complexDiv(numerator, denominator));\n}\n\n/**\n * Inverse of {@link mobiusToOrigin}: translates the origin back to `a`, i.e.\n * `(z + a) / (1 + conj(a) * z)`.\n */\nexport function mobiusFromOrigin(z: Point, a: Point): Point {\n const numerator = complexAdd(z, a);\n const denominator = complexAdd({ x: 1, y: 0 }, complexMul(complexConjugate(a), z));\n return clampToDisk(complexDiv(numerator, denominator));\n}\n\n/**\n * Möbius addition (gyrogroup composition) of two disk-translations: the\n * canonical-space point reached by translating the origin to `a`, then\n * translating that local frame's origin by `b`.\n */\nexport function mobiusAdd(a: Point, b: Point): Point {\n return mobiusFromOrigin(b, a);\n}\n\n/** Euclidean Poincaré-disk radius corresponding to hyperbolic distance `d` from the origin. */\nexport function euclideanRadiusForHyperbolicDistance(d: number): number {\n return Math.tanh(d / 2);\n}\n\n/** Hyperbolic distance from the origin corresponding to Euclidean disk radius `r`. */\nexport function hyperbolicDistanceForEuclideanRadius(r: number): number {\n return 2 * Math.atanh(Math.min(Math.max(r, 0), 0.999999));\n}\n\n/** Hyperbolic (Poincaré) distance between two points in the unit disk. */\nexport function poincareDistance(p: Point, q: Point): number {\n const translated = mobiusToOrigin(q, p);\n return hyperbolicDistanceForEuclideanRadius(norm(translated));\n}\n\n/**\n * Point at parameter `t` (0–1) along the hyperbolic geodesic from `a` to `b`.\n * `t=0` yields `a`, `t=1` yields `b`; intermediate values move at constant\n * hyperbolic speed along the geodesic (not the Euclidean straight line).\n */\nexport function geodesicInterpolate(a: Point, b: Point, t: number): Point {\n if (t <= 0)\n return a;\n if (t >= 1)\n return b;\n const bLocal = mobiusToOrigin(b, a);\n const localNorm = norm(bLocal);\n if (localNorm < EPSILON)\n return a;\n const direction = complexScale(bLocal, 1 / localNorm);\n const hyperbolicDistance = hyperbolicDistanceForEuclideanRadius(localNorm);\n const stepRadius = euclideanRadiusForHyperbolicDistance(hyperbolicDistance * t);\n const local = complexScale(direction, stepRadius);\n return mobiusFromOrigin(local, a);\n}\n","/**\n * Pure hyperbolic-tree layout: `TreeNode` + focus + radius window → positioned\n * nodes/edges on the Poincaré disk. No Lit, no DOM — unit-testable in isolation.\n */\n\nimport type { TreeNode } from '../common/types.js';\nimport type { ComputeHyperbolicLayoutOptions, HyperbolicLayoutEdge, HyperbolicLayoutNode, Point } from './types.js';\nimport { euclideanRadiusForHyperbolicDistance, mobiusFromOrigin, mobiusToOrigin } from './poincare-math.js';\n\ntype CanonicalEntry = {\n readonly node: TreeNode;\n readonly depth: number;\n readonly parentKey: string | undefined;\n readonly position: Point;\n /** Angular width (radians) this node's own parent allocated to it — root is `2π`. */\n readonly angularShare: number;\n};\n\n/** Depth-first search for the node with `key`. Returns `undefined` when absent. */\nexport function findHyperbolicNode(root: TreeNode | undefined, key: string): TreeNode | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const hit = findHyperbolicNode(child, key);\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/**\n * Chain of nodes from `root` down to (and including) the node with `key`.\n * Returns `undefined` when the key is absent. The first entry is always `root`.\n */\nexport function findHyperbolicPath(root: TreeNode | undefined, key: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return [root];\n for (const child of root.children ?? []) {\n const hit = findHyperbolicPath(child, key);\n if (hit)\n return [root, ...hit];\n }\n return undefined;\n}\n\n/**\n * Number of nodes in `node`'s subtree, counting `node` itself, up to\n * `remainingDepth` further levels (matching the canonical-position recursion's\n * own `maxDepth` cutoff, so weighting stays consistent with what's actually\n * laid out).\n */\nfunction subtreeSize(node: TreeNode, remainingDepth: number): number {\n if (remainingDepth <= 0)\n return 1;\n const children = node.children ?? [];\n if (children.length === 0)\n return 1;\n let total = 1;\n for (const child of children)\n total += subtreeSize(child, remainingDepth - 1);\n return total;\n}\n\n/**\n * Angle (as seen from `localOrigin`, i.e. after translating `localOrigin` to\n * the disk's center) of the disk-boundary point that currently sits at angle\n * `theta` from the true origin. Möbius translation is conformal but not\n * angle-preserving in the naive sense — a wedge boundary doesn't just shift\n * by a constant offset when reparented to a new local frame, its exact\n * transformed angle depends on how far off-center `localOrigin` is. Used to\n * carry a node's *own* angular wedge (inherited from its parent) into the\n * local frame of each of its children, rather than approximating it as\n * \"the opposite direction ± half the width\" — the same technique used by\n * reference hyperbolic-tree-browser implementations (e.g. d3-hypertree's\n * `wedgeTranslate`) to keep the recursive layout accurate at any depth/width.\n */\nfunction boundaryAngleInLocalFrame(theta: number, localOrigin: Point): number {\n const boundaryPoint: Point = { x: Math.cos(theta), y: Math.sin(theta) };\n const transformed = mobiusToOrigin(boundaryPoint, localOrigin);\n return Math.atan2(transformed.y, transformed.x);\n}\n\n/** Deterministic pseudo-random value in `[-1, 1]` derived from `key`, stable across renders. */\nfunction stableUnitJitter(key: string): number {\n let hash = 0;\n for (let i = 0; i < key.length; i++)\n hash = (Math.imul(hash, 31) + key.charCodeAt(i)) | 0;\n return ((hash >>> 0) % 1000) / 1000 * 2 - 1;\n}\n\n/**\n * A single unbranching child (no siblings to fan against) would otherwise sit\n * at the exact bisector of its inherited wedge — i.e. dead-center, continuing\n * in a perfectly straight line from its own parent's edge. For a chain of\n * such nodes (a deeply-nested path with no branching), that reads as one\n * unbroken line cutting across the disk rather than a legible sequence of\n * edges. Nudging by a small, key-derived (so stable across re-renders) angle\n * breaks that up — the same purpose served by the small per-node offsets in\n * reference hyperbolic-tree-browser implementations (e.g. d3-hypertree's\n * `layoutBergé`, which staggers leaf nodes rather than stacking them exactly\n * radially).\n */\nconst CHAIN_JITTER_RADIANS = 0.22;\n\n/**\n * Canonical (true-root-anchored) hyperbolic position of every currently-loaded\n * node, keyed by node key. Positions never depend on the current focus —\n * refocusing is purely a Möbius re-projection of these fixed coordinates, so\n * the tree never needs to be re-laid-out when the focus changes.\n *\n * Each node holds an angular wedge — inherited from its parent, expressed in\n * its *own* local frame (root starts with the full `[-π, π]`) — across which\n * its children are placed at hyperbolic distance `curvature` (default `1`).\n * That wedge is partitioned among the children, weighted by each child's own\n * subtree size rather than split evenly, and each child's own share is\n * carried into its local frame via {@link boundaryAngleInLocalFrame} before\n * recursing. This is a strict partition (slices never overlap and always sum\n * to the parent's own wedge), which is what guarantees sibling subtrees never\n * spatially cross regardless of how deep or bushy they are.\n *\n * `curvature` scales how far apart (in hyperbolic distance) each generation\n * sits. Raising it pushes each generation further out, so the Poincaré\n * metric's own `tanh` compression crowds distant generations toward the\n * boundary faster — a stronger fisheye, which is why it reads as \"zooming\n * in\" on the focus. Lowering it spreads generations out more evenly,\n * flattening the view toward a Euclidean-feeling layout.\n */\nexport function computeCanonicalPositions(\n root: TreeNode | undefined,\n maxDepth = 24,\n curvature = 1,\n): Map<string, CanonicalEntry> {\n const map = new Map<string, CanonicalEntry>();\n if (!root)\n return map;\n const origin: Point = { x: 0, y: 0 };\n map.set(root.item.key, { node: root, depth: 0, parentKey: undefined, position: origin, angularShare: 2 * Math.PI });\n\n const place = (\n node: TreeNode,\n position: Point,\n wedgeStart: number,\n wedgeEnd: number,\n depth: number,\n ): void => {\n if (depth >= maxDepth)\n return;\n const children = node.children ?? [];\n const n = children.length;\n if (n === 0)\n return;\n const r0 = euclideanRadiusForHyperbolicDistance(curvature);\n const angularWidth = wedgeEnd - wedgeStart;\n const weights = children.map(child => subtreeSize(child, maxDepth - depth - 1));\n const totalWeight = weights.reduce((a, b) => a + b, 0);\n let cursor = wedgeStart;\n children.forEach((child, index) => {\n const share = n === 1 ? angularWidth : (angularWidth * weights[index]) / totalWeight;\n const childStart = cursor;\n const childEnd = cursor + share;\n cursor = childEnd;\n const bisector = (childStart + childEnd) / 2;\n // Only a lone, unbranching child needs the jitter — anything with\n // siblings is already visually separated by the fan itself.\n const jitter = n === 1\n ? stableUnitJitter(child.item.key) * Math.min(CHAIN_JITTER_RADIANS, share * 0.4)\n : 0;\n const theta = bisector + jitter;\n const local: Point = { x: r0 * Math.cos(theta), y: r0 * Math.sin(theta) };\n const canonicalPosition = mobiusFromOrigin(local, position);\n map.set(child.item.key, {\n node: child,\n depth: depth + 1,\n parentKey: node.item.key,\n position: canonicalPosition,\n angularShare: share,\n });\n const localStart = boundaryAngleInLocalFrame(childStart, local);\n let localWidth = boundaryAngleInLocalFrame(childEnd, local) - localStart;\n if (localWidth <= 0)\n localWidth += 2 * Math.PI;\n place(child, canonicalPosition, localStart, localStart + localWidth, depth + 1);\n });\n };\n\n place(root, origin, -Math.PI, Math.PI, 0);\n return map;\n}\n\n/** Nodes within `maxRadius` tree-graph steps of `focusedKey`, mapped to their step distance. */\nfunction ringDistances(\n canonical: ReadonlyMap<string, CanonicalEntry>,\n focusedKey: string,\n maxRadius: number,\n): Map<string, number> {\n const ring = new Map<string, number>();\n if (!canonical.has(focusedKey))\n return ring;\n ring.set(focusedKey, 0);\n let frontier = [focusedKey];\n for (let distance = 1; distance <= maxRadius && frontier.length > 0; distance++) {\n const next: string[] = [];\n for (const key of frontier) {\n const entry = canonical.get(key);\n if (!entry)\n continue;\n const neighbours: string[] = [];\n if (entry.parentKey !== undefined)\n neighbours.push(entry.parentKey);\n for (const child of entry.node.children ?? [])\n neighbours.push(child.item.key);\n for (const neighbour of neighbours) {\n if (!ring.has(neighbour) && canonical.has(neighbour)) {\n ring.set(neighbour, distance);\n next.push(neighbour);\n }\n }\n }\n frontier = next;\n }\n return ring;\n}\n\n/**\n * Compute the visible nodes/edges of a hyperbolic tree view: every\n * currently-loaded node within `maxRadius` tree-graph steps of the focused\n * node, projected onto the Poincaré disk with the focus at its center.\n *\n * @param root True tree root. `undefined` yields an empty layout.\n * @param options `focusedKey` (default the true root; unknown keys fall back\n * to the true root), `maxRadius` (default unlimited), `maxDepth` (safety\n * cap on canonical-position recursion depth, default 24), `centerOverride`\n * (project around this canonical-space point instead of the focus node's\n * own position — used to animate smoothly between foci).\n */\nexport function computeHyperbolicLayout(\n root: TreeNode | undefined,\n options: ComputeHyperbolicLayoutOptions = {},\n): { nodes: HyperbolicLayoutNode[]; edges: HyperbolicLayoutEdge[] } {\n if (!root)\n return { nodes: [], edges: [] };\n const { maxRadius = Number.POSITIVE_INFINITY, maxDepth = 24, curvature = 1 } = options;\n const canonical = computeCanonicalPositions(root, maxDepth, curvature);\n const focusedKey = options.focusedKey !== undefined && canonical.has(options.focusedKey)\n ? options.focusedKey\n : root.item.key;\n const focusEntry = canonical.get(focusedKey);\n if (!focusEntry)\n return { nodes: [], edges: [] };\n const projectionCenter = options.centerOverride ?? focusEntry.position;\n\n const ring = ringDistances(canonical, focusedKey, maxRadius);\n const rawWeights = [...ring.keys()]\n .map(key => canonical.get(key)!.node.item.weight)\n .filter((w): w is number => typeof w === `number`);\n const minWeight = rawWeights.length > 0 ? Math.min(...rawWeights) : undefined;\n const maxWeight = rawWeights.length > 0 ? Math.max(...rawWeights) : undefined;\n const normalizeWeight = (weight: number | undefined): number => {\n if (weight === undefined || minWeight === undefined || maxWeight === undefined || maxWeight === minWeight)\n return 0.5;\n return (weight - minWeight) / (maxWeight - minWeight);\n };\n\n const nodes: HyperbolicLayoutNode[] = [...ring.entries()]\n .map(([key, distance]) => {\n const entry = canonical.get(key)!;\n const weight = entry.node.item.weight;\n return {\n node: entry.node,\n key,\n depth: entry.depth,\n ring: distance,\n parentKey: entry.parentKey,\n position: mobiusToOrigin(entry.position, projectionCenter),\n angularShare: entry.angularShare,\n weight,\n weightNormalized: normalizeWeight(weight),\n };\n })\n .sort((a, b) => a.ring - b.ring);\n\n const byKey = new Map(nodes.map(n => [n.key, n]));\n const edges: HyperbolicLayoutEdge[] = [];\n for (const n of nodes) {\n if (n.parentKey === undefined)\n continue;\n const parent = byKey.get(n.parentKey);\n if (!parent)\n continue;\n edges.push({\n fromKey: parent.key,\n toKey: n.key,\n from: parent.position,\n to: n.position,\n weightNormalized: (parent.weightNormalized + n.weightNormalized) / 2,\n });\n }\n\n return { nodes, edges };\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TreeActivateDetail, TreeActivateEvent, TreeCollapseDetail, TreeCollapseEvent, TreeComponent, TreeComponentEventMap, TreeExpandDetail, TreeExpandEvent, TreeItemClickDetail, TreeItemClickEvent, TreeItemDblClickDetail, TreeItemDblClickEvent, TreeSearchHost, TreeSelectDetail, TreeSelectEvent, TreeTickleDetail, TreeTickleEvent } from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type {\n HyperbolicEdgeRenderer,\n HyperbolicFocusDetail,\n HyperbolicFocusEvent,\n HyperbolicInteractionMode,\n HyperbolicLayoutEdge,\n HyperbolicLayoutNode,\n Point,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing, svg } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { computeCanonicalPositions, computeHyperbolicLayout, findHyperbolicNode, findHyperbolicPath } from './layout.js';\nimport { clampToDisk, geodesicInterpolate } from './poincare-math.js';\n\nexport interface HyperbolicTreeListElementEventMap extends TreeComponentEventMap {\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'focus': HyperbolicFocusEvent;\n}\n\n/**\n * The Poincaré disk's math operates in a `-1..1` unit radius, but rendering\n * an SVG `viewBox` at that literal scale (then letting CSS stretch it to a\n * few hundred device pixels) is an extreme, unusual upscale factor that has\n * been observed to trigger a Chromium GPU-rasterization glitch — a `fill:\n * none` shape painting as solid-filled, matching its computed style exactly\n * but not what's on screen. Rendering in a \"normal\"-magnitude SVG coordinate\n * system (viewBox radius {@link RENDER_SCALE} instead of `1`) avoids it.\n */\nconst RENDER_SCALE = 500;\n\n/**\n * Sanitizes a node key into a token safe to use inside a `part` attribute /\n * `::part()` selector — arbitrary key characters (spaces, quotes, etc.)\n * would otherwise produce a token CSS can't select without bespoke escaping.\n */\nfunction partToken(key: string): string {\n return key.replace(/[^\\w-]/g, `-`);\n}\n\n/** Angular distance (radians, 0–π) of a layout node from screen-\"up\" (−π/2). */\nfunction angleDistanceFromUp(n: HyperbolicLayoutNode): number {\n const angle = Math.atan2(n.position.y, n.position.x);\n let diff = Math.abs(angle - (-Math.PI / 2));\n if (diff > Math.PI)\n diff = 2 * Math.PI - diff;\n return diff;\n}\n\n/**\n * `ixfx-hyperbolictree-list` — a hyperbolic (Poincaré disk) browser over tree\n * data. The focused node sits at the disk's center; its neighbourhood rings\n * outward, shrinking toward the edge with tree-graph distance. Implements the\n * shared `TreeComponent` interface so existing infrastructure (`TreeDataModel`,\n * `IncrSearchTreeController`, `TreeComponent`-typed code) works unmodified.\n *\n * Differences from `ixfx-tree-list` (deliberate):\n * - **Expand/collapse is reinterpreted as focus change.** Every loaded node is\n * always laid out; clicking a node re-centers the disk on it (an animated\n * Möbius transform of the same fixed layout, not a re-layout). `expand`/\n * `collapse` fire when the new focus is a descendant/ancestor of the\n * previous one, for interop with existing listeners.\n * - **`interactionMode` drops `checked`** — no checkbox affordance at\n * disk-edge node scale.\n * - **`exclusivity` is accepted but ignored** — nothing is independently open.\n * - **`filterPredicate` dims** non-matching nodes instead of hiding them.\n * - Dragging empty disk space pans the view without changing focus or\n * selection — a gesture with no indented-tree analog.\n * - Drag-and-drop and `checkboxRenderer` are out of scope.\n *\n * **Zoom vs. curvature.** `zoom` (default `1`) magnifies the rendered disk\n * around the focus — a post-layout SVG scale, not a re-layout. `curvature`\n * (default `1`) instead changes the layout itself: the hyperbolic distance\n * placed between generations, i.e. how strongly the disk's own compression\n * curves the space. Raising `curvature` crowds distant generations toward\n * the boundary faster (a stronger fisheye) which — unlike `zoom` — also\n * reshapes the relative sizes/spacing of what's near vs. far from the focus,\n * so it reads as \"zooming in\" on the focus even at `zoom: 1`. Both are also\n * independent of `maxRadius`, which changes how many tree-graph rings get\n * laid out at all.\n *\n * **Weighting.** Set `TreeItem.weight` on any node to influence its visuals.\n * Weight is normalized to `0..1` across the currently-visible node set and\n * exposed as the `--node-weight` CSS custom property on each node's `<g\n * part=\"node\">` (raw value also available as `--node-weight-raw`), and as\n * `--edge-weight` (average of the two endpoints) on each edge's `<path\n * part=\"edge\">`. By default this scales node radius (via `minWeightScale`/\n * `maxWeightScale`), tints node fill toward `--accent`, and thickens edge\n * strokes — override any of that with CSS targeting `::part(dot)`/\n * `::part(edge)`, or the vars themselves.\n *\n * A specific node or edge can be targeted from outside the shadow root by\n * key — each node also exports `node-<key>` and each edge `edge-to-<key>`/\n * `edge-from-<key>` (non-identifier key characters replaced with `-`), e.g.\n * `::part(edge-to-library) { stroke-dasharray: 4 2; }`. (A plain attribute\n * selector like `[data-to=\"...\"]` can't reach across the shadow boundary —\n * those `data-from`/`data-to` attributes are there for JS introspection via\n * `shadowRoot.querySelector`, not CSS from the light DOM.) For anything CSS\n * can't express, use `edgeRenderer` for full custom edges.\n */\n@customElement(`ixfx-hyperbolictree-list`)\nexport class HyperbolicTreeListElement extends LitElement implements TreeComponent, TreeSearchHost {\n /** Delegates focus to the shadow-DOM `[role=\"tree\"]` SVG (nodes themselves are `tabindex=\"-1\"`). */\n static override shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\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 /**\n * Accepted for `TreeComponent` compatibility but ignored — every loaded\n * node is always laid out, so exclusivity is not meaningful here.\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 /**\n * Gesture mapping. `checked` is unsupported (see class docs).\n * @default 'standard'\n */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: HyperbolicInteractionMode = `standard`;\n\n /** Tree-graph steps from the focus to lay out and render. */\n @property({ type: Number, attribute: `max-radius` })\n maxRadius = 4;\n\n /** Base node dot radius, as a fraction of the disk radius (the disk has radius 1). */\n @property({ type: Number, attribute: `node-radius` })\n nodeRadius = 0.05;\n\n /** Nodes whose scaled radius falls below this (same fraction-of-disk-radius units) render without a label. */\n @property({ type: Number, attribute: `min-node-radius` })\n minNodeRadius = 0.015;\n\n /** Radius multiplier applied to a node with `weight` at the low end of the currently-visible range. */\n @property({ type: Number, attribute: `min-weight-scale` })\n minWeightScale = 0.6;\n\n /** Radius multiplier applied to a node with `weight` at the high end of the currently-visible range. */\n @property({ type: Number, attribute: `max-weight-scale` })\n maxWeightScale = 1.6;\n\n /**\n * Visual magnification of the rendered disk, centered on the focus — a\n * plain SVG scale applied after layout, distinct from {@link maxRadius}\n * (which changes *how many rings* are laid out, and so how much the\n * Poincaré projection itself compresses distant nodes). `1` is unscaled;\n * `>1` zooms in, `<1` zooms out. Panning (dragging empty disk space) still\n * operates in the same pre-zoom disk coordinates, so it keeps feeling\n * consistent at any zoom level.\n */\n @property({ type: Number })\n zoom = 1;\n\n /**\n * Hyperbolic distance placed between each generation — how much the space\n * itself is curved, as distinct from {@link zoom} (a flat post-layout\n * magnification). `1` is the standard Poincaré-disk layout. Raising it\n * pushes each generation further out, so the disk's own `tanh` compression\n * crowds distant generations toward the boundary faster: a stronger\n * fisheye, which reads as \"zooming in\" on the focus even though `zoom`\n * hasn't changed. Lowering it spreads generations out more evenly,\n * flattening the view toward a Euclidean-feeling layout.\n */\n @property({ type: Number })\n curvature = 1;\n\n /** Duration (ms) of the animated re-center on focus change. `0` snaps instantly. */\n @property({ type: Number, attribute: `focus-animation-duration` })\n focusAnimationDuration = 400;\n\n /** Optional custom renderer for edges, in place of the default geodesic-arc path. */\n @property({ attribute: false })\n edgeRenderer: HyperbolicEdgeRenderer | undefined;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n private _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 /** The node currently centered on the disk. Pure view-state — `root` is never mutated by focus changes. */\n get focusedNode(): TreeNode | undefined {\n if (this._focusKey === undefined)\n return this.#effectiveRoot;\n return findHyperbolicNode(this.#effectiveRoot, this._focusKey) ?? this.#effectiveRoot;\n }\n\n @state()\n private _focusKey: string | undefined = undefined;\n\n /** Interpolated canonical-space view center while a focus-change animation is in flight; `undefined` when settled. */\n @state()\n private _animCenter: Point | undefined = undefined;\n\n /** Extra pan offset applied on top of the focus center, from dragging empty disk space. */\n @state()\n private _panOffset: Point = { x: 0, y: 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: `.hyperbolictree-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n private tickled = new TickledController<string>(this, {\n getItems: () => this.#layout().nodes.map(n => ({ id: n.key, enabled: true })),\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n onTickle: (id) => {\n if (id === undefined)\n return;\n const n = this.#layout().nodes.find(n => n.key === id);\n if (!n)\n return;\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n },\n });\n\n #modelUnsubscribe: (() => void) | undefined;\n #pendingKeys = new Set<string>();\n #aborters = new Map<string, AbortController>();\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n #animFrame: number | undefined;\n #panStart: { pointerId: number; startClient: Point; baseOffset: Point } | undefined;\n\n // --- Derived data -----------------------------------------------------\n\n get #effectiveRoot(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n #layout(): { nodes: HyperbolicLayoutNode[]; edges: HyperbolicLayoutEdge[] } {\n return computeHyperbolicLayout(this.#effectiveRoot, {\n focusedKey: this._focusKey,\n maxRadius: this.maxRadius,\n curvature: this.curvature,\n centerOverride: this._panOffset.x === 0 && this._panOffset.y === 0 && this._animCenter === undefined\n ? undefined\n : this.#effectiveCenter(),\n });\n }\n\n #effectiveCenter(): Point | undefined {\n const canonical = computeCanonicalPositions(this.#effectiveRoot, 24, this.curvature);\n const focusKey = this._focusKey ?? this.#effectiveRoot?.item.key;\n const base = this._animCenter ?? (focusKey === undefined ? undefined : canonical.get(focusKey)?.position);\n if (base === undefined)\n return undefined;\n if (this._panOffset.x === 0 && this._panOffset.y === 0)\n return base;\n return clampToDisk({ x: base.x + this._panOffset.x, y: base.y + this._panOffset.y }, 0.95);\n }\n\n // --- Lifecycle ----------------------------------------------------------\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 }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n for (const aborter of this.#aborters.values())\n aborter.abort();\n this.#aborters.clear();\n this.#pendingKeys.clear();\n if (this.#animFrame !== undefined) {\n cancelAnimationFrame(this.#animFrame);\n this.#animFrame = undefined;\n }\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 #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 protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`root`) && this.root) {\n this.#resetViewState();\n }\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n if (this.model) {\n this.#modelUnsubscribe = this.model._subscribe((event) => {\n if (event.type === `root`) {\n this.#resetViewState();\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n this.requestUpdate();\n }\n });\n this.#resetViewState();\n }\n }\n if (changedProps.has(`interactionMode`)) {\n this.clearSelection();\n }\n if (changedProps.has(`searchModes`))\n this.#syncSearchCommands();\n // A new root invalidates the focus target — fall back to the true root.\n if (this._focusKey !== undefined && !findHyperbolicNode(this.#effectiveRoot, this._focusKey)) {\n this._focusKey = undefined;\n this._animCenter = undefined;\n }\n this.#ensureVisibleChildren();\n }\n\n #resetViewState(): void {\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._focusKey = undefined;\n this._animCenter = undefined;\n this._panOffset = { x: 0, y: 0 };\n if (this.#animFrame !== undefined) {\n cancelAnimationFrame(this.#animFrame);\n this.#animFrame = undefined;\n }\n }\n\n // --- Lazy children --------------------------------------------------------\n\n #ensureVisibleChildren(): void {\n if (!this.model && !this.loadChildren)\n return;\n for (const n of this.#layout().nodes) {\n const { node } = n;\n if (node.children !== undefined || this.#pendingKeys.has(node.item.key))\n continue;\n void this.#loadChildren(node, n.depth);\n }\n }\n\n async #loadChildren(node: TreeNode, depth: number): Promise<void> {\n const key = node.item.key;\n this.#pendingKeys.add(key);\n const controller = new AbortController();\n this.#aborters.set(key, controller);\n this.requestUpdate();\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 } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n } finally {\n this.#pendingKeys.delete(key);\n this.#aborters.delete(key);\n if (!controller.signal.aborted)\n this.requestUpdate();\n }\n }\n\n // --- Selection ------------------------------------------------------------\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._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail: { selected: new Set(this._selectedNodes), previous },\n bubbles: true,\n composed: true,\n }));\n }\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 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 for (const n of this.#layout().nodes) {\n if (!this.#canSelect(n.node))\n continue;\n this._selectedNodes.add(n.node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\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 // --- Focus ------------------------------------------------------------\n\n /**\n * Re-center the disk on `node` (an animated Möbius transform of the fixed\n * layout — `root` is never mutated). Fires `focus`, plus the semantic\n * `expand`/`collapse` event when the new focus is a descendant/ancestor of\n * the previous one, for interop with generic `TreeComponent` listeners.\n */\n focusOn(node: TreeNode): void {\n const targetKey = node.item.key;\n const currentFocusKey = this._focusKey ?? this.#effectiveRoot?.item.key;\n if (currentFocusKey === targetKey)\n return;\n const previousNode = currentFocusKey === undefined\n ? undefined\n : findHyperbolicNode(this.#effectiveRoot, currentFocusKey);\n const canonical = computeCanonicalPositions(this.#effectiveRoot, 24, this.curvature);\n const fromPosition = (currentFocusKey === undefined ? undefined : canonical.get(currentFocusKey)?.position) ?? { x: 0, y: 0 };\n const toPosition = canonical.get(targetKey)?.position ?? { x: 0, y: 0 };\n this._focusKey = targetKey;\n this._panOffset = { x: 0, y: 0 };\n this.#animateTo(fromPosition, toPosition);\n this.dispatchEvent(new CustomEvent<HyperbolicFocusDetail>(`focus`, {\n detail: { node, previous: previousNode },\n bubbles: true,\n composed: true,\n }));\n if (previousNode) {\n if (findHyperbolicNode(previousNode, targetKey)) {\n const depth = (findHyperbolicPath(this.#effectiveRoot, targetKey)?.length ?? 1) - 1;\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n } else if (findHyperbolicNode(node, previousNode.item.key)) {\n const depth = (findHyperbolicPath(this.#effectiveRoot, previousNode.item.key)?.length ?? 1) - 1;\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node: previousNode, depth },\n bubbles: true,\n composed: true,\n }));\n }\n }\n this.requestUpdate();\n }\n\n #prefersReducedMotion(): boolean {\n return typeof matchMedia === `function` && matchMedia(`(prefers-reduced-motion: reduce)`).matches;\n }\n\n #animateTo(from: Point, to: Point): void {\n if (this.#animFrame !== undefined) {\n cancelAnimationFrame(this.#animFrame);\n this.#animFrame = undefined;\n }\n if (this.focusAnimationDuration <= 0 || this.#prefersReducedMotion() || typeof requestAnimationFrame !== `function`) {\n this._animCenter = undefined;\n return;\n }\n const start = performance.now();\n const duration = this.focusAnimationDuration;\n const step = (now: number): void => {\n const t = Math.min(1, (now - start) / duration);\n this._animCenter = t >= 1 ? undefined : geodesicInterpolate(from, to, t);\n this.requestUpdate();\n this.#animFrame = t < 1 ? requestAnimationFrame(step) : undefined;\n };\n this.#animFrame = requestAnimationFrame(step);\n }\n\n #focusAndMaybeSelect(node: TreeNode): void {\n this.focusOn(node);\n this.tickled.setTickled(node.item.key);\n if (this.interactionMode === `implicit`)\n this.select(node);\n }\n\n // --- Navigation -----------------------------------------------------------\n\n /** Focus + select the node at `keys` (path from the root's children). Returns `true` if found. */\n navigateTo(keys: readonly string[]): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n let current: TreeNode = root;\n for (const key of keys) {\n const found = current.children?.find(n => n.item.key === key);\n if (!found)\n return false;\n current = found;\n }\n this.focusOn(current);\n this.select(current);\n this.tickled.setTickled(current.item.key);\n this.requestUpdate();\n return true;\n }\n\n /** Focus + select the first node for which `predicate` returns `true`. Returns `true` if found. */\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const keyPath = this.#findKeyPath(root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /**\n * Bring the node with `key` into the visible window and move the keyboard\n * cursor to it, without changing the selection. Used by incremental-search\n * \"navigate\" mode.\n */\n revealKey(key: string): boolean {\n const node = findHyperbolicNode(this.#effectiveRoot, key);\n if (!node)\n return false;\n if (!this.#layout().nodes.some(n => n.key === key))\n this.focusOn(node);\n this.tickled.setTickled(key);\n this.requestUpdate();\n return true;\n }\n\n #findKeyPath(\n nodes: readonly 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 hit = this.#findKeyPath(node.children, predicate, path);\n if (hit)\n return hit;\n }\n }\n return undefined;\n }\n\n /**\n * All nodes currently laid out on the disk (within `maxRadius` of the\n * focus), in render (ring-major) order. Unlike `ixfx-icicletree-list`, the\n * focused node itself is included — it is literally rendered, at the\n * center.\n */\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n return this.#layout().nodes.map(n => ({ node: n.node, depth: n.depth }));\n }\n\n // --- Pointer / keyboard ---------------------------------------------------\n\n #matchesFilter(node: TreeNode, depth: number): boolean {\n if (!this.filterPredicate)\n return true;\n if (this.filterPredicate(node, depth))\n return true;\n return node.children?.some(child => this.#matchesFilter(child, depth + 1)) ?? false;\n }\n\n #handleItemClick(n: HyperbolicLayoutNode, event: MouseEvent): void {\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.interactionMode === `standard` && (event.ctrlKey || event.metaKey)) {\n if (this._selectedNodes.has(n.node)) {\n this.deselect(n.node);\n } else if (this.#canSelect(n.node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.add(n.node);\n this.selectedNode = n.node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n } else if (this.interactionMode !== `manual`) {\n this.select(n.node);\n }\n this.tickled.setTickled(n.key);\n this.focusOn(n.node);\n }\n\n #handleItemDblClick(n: HyperbolicLayoutNode): void {\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n if (this.disableKeyboardNavigation)\n return;\n const root = this.#effectiveRoot;\n const { nodes } = this.#layout();\n if (!root || nodes.length === 0)\n return;\n const focusKey = this._focusKey ?? root.item.key;\n const focusNode = findHyperbolicNode(root, focusKey);\n if (!focusNode)\n return;\n\n switch (event.key) {\n case `ArrowUp`: {\n event.preventDefault();\n const children = nodes.filter(n => n.parentKey === focusNode.item.key);\n if (children.length === 0)\n return;\n const best = children.reduce((a, b) => angleDistanceFromUp(a) < angleDistanceFromUp(b) ? a : b);\n this.#focusAndMaybeSelect(best.node);\n return;\n }\n case `ArrowDown`: {\n event.preventDefault();\n const path = findHyperbolicPath(root, focusNode.item.key);\n const parent = path && path.length >= 2 ? path[path.length - 2] : undefined;\n if (parent)\n this.#focusAndMaybeSelect(parent);\n return;\n }\n case `ArrowLeft`:\n case `ArrowRight`: {\n event.preventDefault();\n const path = findHyperbolicPath(root, focusNode.item.key);\n const parent = path && path.length >= 2 ? path[path.length - 2] : undefined;\n const siblings = parent?.children ?? (focusNode === root ? [focusNode] : []);\n const index = siblings.findIndex(n => n.item.key === focusNode.item.key);\n if (index === -1 || siblings.length <= 1)\n return;\n const dir = event.key === `ArrowRight` ? 1 : -1;\n const next = siblings[(index + dir + siblings.length) % siblings.length];\n this.#focusAndMaybeSelect(next);\n return;\n }\n case `Enter`: {\n event.preventDefault();\n if (this.interactionMode !== `manual`)\n this.select(focusNode);\n const depth = (findHyperbolicPath(root, focusNode.item.key)?.length ?? 1) - 1;\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: focusNode, depth },\n bubbles: true,\n composed: true,\n }));\n return;\n }\n case `Escape`: {\n if (this._focusKey !== undefined && this._focusKey !== root.item.key) {\n event.preventDefault();\n this.focusOn(root);\n }\n }\n }\n }\n\n #isBackgroundTarget(event: PointerEvent): boolean {\n const target = event.target as Element | null;\n return target === event.currentTarget || target?.classList.contains(`disk-boundary`) === true;\n }\n\n #handleBackgroundPointerDown(event: PointerEvent): void {\n if (!this.#isBackgroundTarget(event))\n return;\n (event.currentTarget as Element).setPointerCapture(event.pointerId);\n this.#panStart = {\n pointerId: event.pointerId,\n startClient: { x: event.clientX, y: event.clientY },\n baseOffset: this._panOffset,\n };\n }\n\n #handleBackgroundPointerMove(event: PointerEvent): void {\n if (!this.#panStart || event.pointerId !== this.#panStart.pointerId)\n return;\n const rect = (event.currentTarget as SVGSVGElement).getBoundingClientRect();\n const extent = Math.min(rect.width, rect.height) || 1;\n const scale = 2.1 / extent;\n const dx = (event.clientX - this.#panStart.startClient.x) * scale;\n const dy = (event.clientY - this.#panStart.startClient.y) * scale;\n this._panOffset = clampToDisk({\n x: this.#panStart.baseOffset.x - dx,\n y: this.#panStart.baseOffset.y - dy,\n }, 0.9);\n this.requestUpdate();\n }\n\n #handleBackgroundPointerUp(event: PointerEvent): void {\n if (this.#panStart?.pointerId === event.pointerId)\n this.#panStart = undefined;\n }\n\n // --- Render ---------------------------------------------------------------\n\n #defaultEdgeRenderer(edge: HyperbolicLayoutEdge): unknown {\n const steps = 8;\n let d = ``;\n for (let i = 0; i <= steps; i++) {\n const p = geodesicInterpolate(edge.from, edge.to, i / steps);\n d += `${i === 0 ? `M` : `L`}${(p.x * RENDER_SCALE).toFixed(2)},${(p.y * RENDER_SCALE).toFixed(2)} `;\n }\n return svg`<path\n class=\"edge\"\n d=${d}\n part=\"edge edge-to-${partToken(edge.toKey)} edge-from-${partToken(edge.fromKey)}\"\n data-from=${edge.fromKey}\n data-to=${edge.toKey}\n style=\"--edge-weight: ${edge.weightNormalized}\"\n />`;\n }\n\n #renderEdge(edge: HyperbolicLayoutEdge, byKey: Map<string, HyperbolicLayoutNode>): unknown {\n if (this.edgeRenderer) {\n const fromNode = byKey.get(edge.fromKey)?.node;\n const toNode = byKey.get(edge.toKey)?.node;\n if (fromNode && toNode) {\n // Custom renderers author against the layout's native -1..1 disk\n // coordinates; this scales that up to match RENDER_SCALE so they\n // don't need to know about it.\n return svg`<g transform=\"scale(${RENDER_SCALE})\">${this.edgeRenderer({ edge, fromNode, toNode })}</g>`;\n }\n }\n return this.#defaultEdgeRenderer(edge);\n }\n\n /**\n * A node's rendered dot radius: shrinks with distance from focus (existing\n * behaviour), but also caps itself to the angular room {@link\n * HyperbolicLayoutNode.angularShare} actually gives it at its radius —\n * without this, a cluster of siblings squeezed into a narrow wedge (a\n * bushy ancestor elsewhere in the tree, or many siblings at this level)\n * all render at the same distance-only size and physically overlap into\n * an unreadable blob, however small {@link minNodeRadius} suppresses their\n * labels. `angularShare * distance` approximates the Euclidean arc length\n * available to the node; capping the diameter to a fraction of that keeps\n * a visible gap between crowded neighbours.\n */\n #nodeRenderRadius(n: HyperbolicLayoutNode): number {\n const distance = Math.hypot(n.position.x, n.position.y);\n const scale = Math.max(0.2, 1 - distance);\n const weightScale = this.minWeightScale + (this.maxWeightScale - this.minWeightScale) * n.weightNormalized;\n const radius = this.nodeRadius * scale * weightScale;\n if (distance < 1e-6)\n return radius;\n const arcLength = n.angularShare * distance;\n return Math.min(radius, Math.max(arcLength * 0.35, 0.003));\n }\n\n /**\n * Which nodes get a rendered label, greedily thinned to avoid overlap: a\n * per-node radius threshold alone ({@link minNodeRadius}) still lets many\n * same-sized nodes crowded into a small angular wedge all show labels that\n * visually collide. Nodes are considered in priority order (closer ring\n * first, then larger on-screen radius) and a label is kept only if its\n * position isn't too close to an already-kept one.\n */\n #computeLabelKeys(nodes: readonly HyperbolicLayoutNode[]): Set<string> {\n const minSpacing = 0.07;\n const eligible = nodes.filter(n => this.#nodeRenderRadius(n) >= this.minNodeRadius);\n const prioritised = [...eligible].sort((a, b) => {\n if (a.ring !== b.ring)\n return a.ring - b.ring;\n return Math.hypot(a.position.x, a.position.y) - Math.hypot(b.position.x, b.position.y);\n });\n const kept: HyperbolicLayoutNode[] = [];\n const keys = new Set<string>();\n for (const n of prioritised) {\n const tooClose = kept.some(k => Math.hypot(k.position.x - n.position.x, k.position.y - n.position.y) < minSpacing);\n if (!tooClose) {\n kept.push(n);\n keys.add(n.key);\n }\n }\n return keys;\n }\n\n #renderNode(n: HyperbolicLayoutNode, siblingGroups: Map<string | undefined, HyperbolicLayoutNode[]>, labelKeys: ReadonlySet<string>): unknown {\n const { node, key, position } = n;\n const selected = this._selectedNodes.has(node);\n const tickled = this.tickled.isTickled(key);\n const filtered = !this.#matchesFilter(node, n.depth);\n const pending = this.#pendingKeys.has(key);\n const isFocused = n.ring === 0;\n const radius = this.#nodeRenderRadius(n);\n const showLabel = labelKeys.has(key);\n const siblings = siblingGroups.get(n.parentKey) ?? [n];\n const index = siblings.findIndex(s => s.key === key);\n const scaledRadius = radius * RENDER_SCALE;\n const weightStyle = `--node-weight: ${n.weightNormalized};${n.weight === undefined ? `` : ` --node-weight-raw: ${n.weight};`}`;\n return svg`\n <g\n class=\"node ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${filtered ? `filtered` : ``} ${pending ? `loading` : ``} ${isFocused ? `focused` : ``}\"\n data-key=${key}\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-level=${n.depth + 1}\n aria-selected=${selected}\n aria-setsize=${siblings.length}\n aria-posinset=${index + 1}\n aria-label=${node.item.label}\n part=\"node node-${partToken(key)}\"\n style=${weightStyle}\n transform=\"translate(${position.x * RENDER_SCALE} ${position.y * RENDER_SCALE})\"\n @pointerdown=${(e: PointerEvent) => e.stopPropagation()}\n @click=${(e: MouseEvent) => {\n e.stopPropagation(); this.#handleItemClick(n, e);\n }}\n @dblclick=${(e: MouseEvent) => {\n e.stopPropagation(); this.#handleItemDblClick(n);\n }}\n @pointerenter=${() => this.tickled.handlePointerEnter(key)}\n >\n <circle class=\"node-hit\" r=${Math.max(scaledRadius, 0.035 * RENDER_SCALE)} part=\"hit\" />\n <circle class=\"node-dot\" r=${scaledRadius} part=\"dot\" />\n ${showLabel\n ? svg`<text class=\"hyperbolictree-label\" part=\"label\" x=${scaledRadius + 0.01 * RENDER_SCALE} y=\"0\" dominant-baseline=\"middle\">${node.item.label}</text>`\n : nothing}\n </g>\n `;\n }\n\n protected override render() {\n const { nodes, edges } = this.#layout();\n const byKey = new Map(nodes.map(n => [n.key, n]));\n const siblingGroups = new Map<string | undefined, HyperbolicLayoutNode[]>();\n for (const n of nodes) {\n const group = siblingGroups.get(n.parentKey) ?? [];\n group.push(n);\n siblingGroups.set(n.parentKey, group);\n }\n const labelKeys = this.#computeLabelKeys(nodes);\n return html`\n <svg\n class=\"hyperbolictree\"\n viewBox=\"${-1.05 * RENDER_SCALE} ${-1.05 * RENDER_SCALE} ${2.1 * RENDER_SCALE} ${2.1 * RENDER_SCALE}\"\n preserveAspectRatio=\"xMidYMid meet\"\n role=\"tree\"\n tabindex=\"0\"\n data-input-mode=${this.tickled.inputMode}\n @keydown=${(e: KeyboardEvent) => this.#handleKeyDown(e)}\n @pointerdown=${(e: PointerEvent) => this.#handleBackgroundPointerDown(e)}\n @pointermove=${(e: PointerEvent) => this.#handleBackgroundPointerMove(e)}\n @pointerup=${(e: PointerEvent) => this.#handleBackgroundPointerUp(e)}\n @pointerleave=${() => this.tickled.clearTickled()}\n >\n <g class=\"zoom\" transform=\"scale(${this.zoom})\">\n <circle class=\"disk-boundary\" part=\"boundary\" cx=\"0\" cy=\"0\" r=${RENDER_SCALE} />\n <g class=\"edges\" part=\"edges\">\n ${repeat(edges, e => `${e.fromKey}->${e.toKey}`, e => this.#renderEdge(e, byKey))}\n </g>\n <g class=\"nodes\" part=\"nodes\">\n ${repeat(nodes, n => n.key, n => this.#renderNode(n, siblingGroups, labelKeys))}\n </g>\n </g>\n </svg>\n ${this.search.renderField()}\n `;\n }\n\n static override styles = [\n themeFallbacks,\n listSearchStyles,\n css`\n :host {\n --hyperbolictree-node-color: var(--surface-4);\n --hyperbolictree-node-text: var(--surface-3-text);\n --hyperbolictree-edge-color: var(--surface-6);\n --hyperbolictree-boundary-color: var(--border-subtle);\n --hyperbolictree-font-size: 25px;\n\n display: block;\n overflow: hidden;\n outline: none;\n overscroll-behavior: contain;\n }\n\n /*\n * delegatesFocus means the host itself reports as focused whenever\n * the shadow DOM's focused descendant (the svg) is — without this,\n * the host also picks up the browser's own default focus ring/fill\n * sized to the whole box.\n */\n :host(:focus),\n :host(:focus-visible) {\n outline: none;\n }\n\n .hyperbolictree {\n display: block;\n width: 100%;\n height: 100%;\n outline: none;\n touch-action: none;\n overscroll-behavior: contain;\n }\n\n .disk-boundary {\n fill: none;\n stroke: var(--hyperbolictree-boundary-color);\n stroke-width: 1;\n }\n\n .edge {\n fill: none;\n stroke: var(--hyperbolictree-edge-color);\n /* --edge-weight (0..1, average of the endpoint nodes' --node-weight) thickens heavier edges. */\n stroke-width: calc(1px + var(--edge-weight, 0.5) * 3px);\n }\n\n .node {\n cursor: pointer;\n }\n\n .node-hit {\n fill: transparent;\n pointer-events: all;\n }\n\n .node-dot {\n /* --node-weight (0..1, normalized across the visible node set) tints toward --accent for heavier nodes. */\n fill: color-mix(in oklab, var(--hyperbolictree-node-color), var(--accent) calc(var(--node-weight, 0.5) * 50%));\n stroke: var(--surface-2);\n stroke-width: 1;\n pointer-events: none;\n }\n\n .node.tickled .node-dot {\n fill: var(--item-bg-tickled);\n }\n\n .node.selected .node-dot {\n fill: var(--item-bg-selected);\n }\n\n .node.selected.tickled .node-dot {\n fill: var(--item-bg-selected-tickled);\n }\n\n .node.focused .node-dot {\n stroke: var(--accent);\n stroke-width: 3;\n }\n\n .node.filtered {\n opacity: 0.3;\n }\n\n .node.loading .node-dot {\n opacity: 0.6;\n }\n\n .hyperbolictree-label {\n font-size: var(--hyperbolictree-font-size);\n fill: var(--hyperbolictree-node-text);\n cursor: pointer;\n user-select: none;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-hyperbolictree-list': HyperbolicTreeListElement;\n }\n}\n\nexport interface HyperbolicTreeListElement {\n addEventListener: (<K extends keyof HyperbolicTreeListElementEventMap>(\n type: K,\n listener: (this: HyperbolicTreeListElement, event: HyperbolicTreeListElementEventMap[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 HyperbolicTreeListElementEventMap>(\n type: K,\n listener: (this: HyperbolicTreeListElement, event: HyperbolicTreeListElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","/**\n * Pure icicle layout: `TreeNode` + value accessor + depth window → positioned rects.\n * No Lit, no DOM — unit-testable in isolation.\n */\n\nimport type {\n ComputeIcicleLayoutOptions,\n IcicleRect,\n IcicleValueAccessor,\n TreeNode,\n} from './types.js';\n\n/** Coerce a raw accessor result to a non-negative finite weight. */\nexport function normaliseValue(raw: unknown): number {\n return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? raw : 0;\n}\n\n/** Depth-first search for the node with `key`. Returns `undefined` when absent. */\nexport function findIcicleNode(root: TreeNode | undefined, key: string): TreeNode | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const hit = findIcicleNode(child, key);\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/**\n * Chain of nodes from `root` down to (and including) the node with `key`.\n * Returns `undefined` when the key is absent. The first entry is always `root`.\n */\nexport function findIciclePath(root: TreeNode | undefined, key: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return [root];\n for (const child of root.children ?? []) {\n const hit = findIciclePath(child, key);\n if (hit)\n return [root, ...hit];\n }\n return undefined;\n}\n\n/**\n * Compute the visible rectangles for an icicle view.\n *\n * Bands start at the zoom node's **children** (the zoom node itself is shown in\n * the breadcrumb strip, never as a rect — matching `TreeComponent.getNodes()`,\n * where the root is never listed). Each band spans 0–1; a rect's `x`/`width`\n * are fractions of its band, proportional to `valueAccessor` shares among\n * siblings. Siblings whose weights all normalise to `0` split the band equally.\n *\n * @param root True tree root. `undefined` (or a root without children) yields `[]`.\n * @param options `valueAccessor` (default equal weights), `maxDepth` (band count,\n * default unlimited), `zoomKey` (visual root, default true root; unknown keys\n * fall back to the true root).\n */\nexport function computeIcicleLayout(\n root: TreeNode | undefined,\n options: ComputeIcicleLayoutOptions = {},\n): IcicleRect[] {\n if (!root?.children?.length)\n return [];\n const { maxDepth = Number.POSITIVE_INFINITY, valueAccessor = () => 1, zoomKey, hideLeaves = false } = options;\n if (maxDepth <= 0)\n return [];\n\n const zoomNode = zoomKey === undefined ? root : (findIcicleNode(root, zoomKey) ?? root);\n const zoomPath = findIciclePath(root, zoomNode.item.key);\n // Absolute depth of the zoom node: root is -1 so its children are depth 0.\n const zoomDepth = zoomPath ? zoomPath.length - 2 : -1;\n const siblings = zoomNode.children ?? [];\n if (siblings.length === 0)\n return [];\n\n // A \"loaded, childless\" node is a leaf; `children === undefined` means not\n // yet loaded (might still turn out to have children), so it's never hidden.\n const isLeaf = (node: TreeNode): boolean =>\n node.item.isLeaf === true || (node.children !== undefined && node.children.length === 0);\n\n const rects: IcicleRect[] = [];\n const layoutLevel = (\n nodes: readonly TreeNode[],\n depth: number,\n relativeDepth: number,\n offset: number,\n span: number,\n parentKey: string | undefined,\n ): void => {\n const visible = hideLeaves ? nodes.filter(n => !isLeaf(n)) : nodes;\n if (visible.length === 0 || relativeDepth >= maxDepth)\n return;\n const weights = visible.map(n => normaliseValue((valueAccessor as IcicleValueAccessor)(n.item)));\n const total = weights.reduce((a, b) => a + b, 0);\n const setSize = visible.length;\n let cursor = offset;\n visible.forEach((node, index) => {\n const share = total > 0 ? weights[index] / total : 1 / setSize;\n const width = span * share;\n const children = node.children ?? [];\n rects.push({\n node,\n depth,\n relativeDepth,\n x: cursor,\n width,\n parentKey,\n index,\n setSize,\n hasChildren: children.length > 0 || (node.children === undefined && node.item.isLeaf !== true),\n });\n if (children.length > 0) {\n layoutLevel(children, depth + 1, relativeDepth + 1, cursor, width, node.item.key);\n }\n cursor += width;\n });\n };\n\n layoutLevel(siblings, zoomDepth + 1, 0, 0, 1, zoomNode.item.key);\n return rects;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TreeActivateDetail, TreeActivateEvent, TreeCollapseDetail, TreeCollapseEvent, TreeComponent, TreeComponentEventMap, TreeExpandDetail, TreeExpandEvent, TreeItemClickDetail, TreeItemClickEvent, TreeItemDblClickDetail, TreeItemDblClickEvent, TreeSearchHost, TreeSelectDetail, TreeSelectEvent, TreeTickleDetail, TreeTickleEvent } from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type {\n IcicleInteractionMode,\n IcicleOrientation,\n IcicleRect,\n IcicleValueAccessor,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { computeIcicleLayout, findIcicleNode, findIciclePath } from './layout.js';\nimport '../crumbs/crumb-navigation.js';\n\n/** Fired when the zoom root changes. `node` is `undefined` on zoom-out to the full tree. */\nexport type IcicleZoomDetail = {\n readonly node: TreeNode | undefined;\n /** Absolute depth of the zoom node (root's children are depth 0); `-1` when fully zoomed out. */\n readonly depth: number;\n};\n\nexport type IcicleZoomEvent = CustomEvent<IcicleZoomDetail>;\n\nexport interface IcicleTreeListElementEventMap extends TreeComponentEventMap {\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'zoom': IcicleZoomEvent;\n}\n\n/**\n * `ixfx-icicletree-list` — an icicle (partition) view over tree data.\n *\n * Each depth is a horizontal band (or vertical band when\n * `orientation=\"vertical\"`); each node is a rectangle whose width is\n * proportional to its `valueAccessor` share of its parent, stacked within the\n * band. Implements the shared `TreeComponent` interface so existing\n * infrastructure (`TreeDataModel`, `IncrSearchTreeController`,\n * `TreeComponent`-typed code) works unmodified.\n *\n * Differences from `ixfx-tree-list` (deliberate):\n * - **Expand/collapse is reinterpreted as zoom.** Clicking a branch zooms so it\n * becomes the visual root; ancestors collapse into the breadcrumb strip.\n * `expand`/`collapse` events fire on zoom-in/zoom-out with the same detail\n * shape so existing listeners keep working conceptually.\n * - **`interactionMode` drops `checked`** — a checkbox per rectangle does not\n * hold up at small rect sizes.\n * - **`exclusivity` is accepted but ignored** — nothing is independently \"open\".\n * - **`filterPredicate` dims** non-matching rects instead of hiding rows.\n * - Drag-and-drop is out of scope.\n */\n@customElement(`ixfx-icicletree-list`)\nexport class IcicleTreeListElement extends LitElement implements TreeComponent, TreeSearchHost {\n /**\n * Delegates focus to the shadow-DOM `[role=\"tree\"]` div (the actual\n * `tabindex=\"0\"` element — rects themselves are `tabindex=\"-1\"`). Without\n * this, the host custom element has no `tabIndex` of its own: `el.focus()`\n * is a no-op, clicking a rect doesn't focus the tree (so arrow keys don't\n * work until the user separately Tabs in), and the host never reports as\n * `document.activeElement`.\n */\n static override shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\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 /**\n * Accepted for `TreeComponent` compatibility but ignored — an icicle has no\n * independently open branches, so exclusivity is not meaningful.\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 /**\n * Gesture mapping. `checked` is unsupported (see class docs).\n * @default 'standard'\n */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: IcicleInteractionMode = `standard`;\n\n /**\n * Band stacking direction.\n * - `'horizontal'` — bands stack top-down, rects flow left-to-right.\n * - `'vertical'` — bands stack left-to-right, rects flow top-down.\n */\n @property({ type: String, reflect: true })\n orientation: IcicleOrientation = `horizontal`;\n\n /** How many depth bands render at once from the current zoom root. */\n @property({ type: Number, attribute: `max-depth` })\n maxDepth = 4;\n\n /**\n * Rects narrower than this (px, horizontal orientation only) rotate their\n * label 90° (`writing-mode: vertical-rl`) to fit more characters in the\n * available band height instead of the shrinking width. Below\n * {@link minVerticalLabelWidth} even the rotated label is hidden.\n */\n @property({ type: Number, attribute: `min-label-width` })\n minLabelWidth = 40;\n\n /**\n * Rects narrower than this (px) hide their label outright — even the\n * rotated form from {@link minLabelWidth} doesn't fit. Ignored in\n * `orientation=\"vertical\"`, where labels never rotate.\n */\n @property({ type: Number, attribute: `min-vertical-label-width` })\n minVerticalLabelWidth = 16;\n\n /**\n * Omit leaf nodes entirely — no rect, no layout space — at every depth,\n * not just the deepest visible band. Non-leaf siblings renormalise to fill\n * the freed space. A node is a leaf when `item.isLeaf === true`, or its\n * `children` array has already loaded and is empty — a node whose\n * `children` is still `undefined` (not yet loaded) is never hidden.\n */\n @property({ type: Boolean, attribute: `hide-leaves`, reflect: true })\n hideLeaves = false;\n\n /** Weight per node. Default `() => 1` — equal-width siblings. */\n @property({ attribute: false })\n valueAccessor: IcicleValueAccessor = () => 1;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n private _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 /** Current zoom root. `undefined` when showing the full tree. Pure view-state — `root` is never mutated. */\n get focusedNode(): TreeNode | undefined {\n if (this._zoomKey === undefined)\n return undefined;\n return findIcicleNode(this.#effectiveRoot, this._zoomKey);\n }\n\n @state()\n private _zoomKey: string | undefined = undefined;\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: `.icicle-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n private tickled = new TickledController<string>(this, {\n getItems: () => this.#rects().map(r => ({ id: r.node.item.key, enabled: true })),\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n onTickle: (id) => {\n if (id === undefined)\n return;\n const rect = this.#rects().find(r => r.node.item.key === id);\n if (!rect)\n return;\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n },\n });\n\n #modelUnsubscribe: (() => void) | undefined;\n #pendingKeys = new Set<string>();\n #aborters = new Map<string, AbortController>();\n #anchorIndex: number | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n #resizeObserver: ResizeObserver | undefined;\n\n /**\n * Shared instant tooltip for rects whose label is rotated or hidden for\n * lack of space — positioned purely via CSS anchor positioning\n * (`anchor-name` on the tickled rect, `position-anchor` here), shown/hidden\n * via the Popover API. Deliberately not the native `title` attribute: that\n * has a UA-controlled show delay, this shows the instant the rect is\n * tickled (hover or keyboard).\n */\n @query(`#icicle-tooltip`)\n private _tooltipEl: HTMLElement | undefined;\n\n // --- Derived data ---------------------------------------------------------\n\n get #effectiveRoot(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n #rects(): IcicleRect[] {\n return computeIcicleLayout(this.#effectiveRoot, {\n valueAccessor: this.valueAccessor,\n maxDepth: this.maxDepth,\n zoomKey: this._zoomKey,\n hideLeaves: this.hideLeaves,\n });\n }\n\n // --- Lifecycle ------------------------------------------------------------\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 if (typeof ResizeObserver !== `undefined`) {\n this.#resizeObserver = new ResizeObserver(() => this.requestUpdate());\n this.#resizeObserver.observe(this);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n for (const aborter of this.#aborters.values())\n aborter.abort();\n this.#aborters.clear();\n this.#pendingKeys.clear();\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\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 #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 protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`root`) && this.root) {\n this.#resetViewState();\n }\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n if (this.model) {\n this.#modelUnsubscribe = this.model._subscribe((event) => {\n if (event.type === `root`) {\n this.#resetViewState();\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n this.requestUpdate();\n }\n });\n this.#resetViewState();\n }\n }\n if (changedProps.has(`interactionMode`)) {\n this.#anchorIndex = undefined;\n this.clearSelection();\n }\n if (changedProps.has(`searchModes`))\n this.#syncSearchCommands();\n // A new root invalidates the zoom target — fall back to the full tree.\n if (this._zoomKey !== undefined && !findIcicleNode(this.#effectiveRoot, this._zoomKey)) {\n this._zoomKey = undefined;\n }\n this.#ensureVisibleChildren();\n this.#syncTooltip();\n }\n\n /** The host's own (viewport) extent — width in horizontal orientation, height in vertical. */\n #hostExtent(): number {\n return (this.orientation === `vertical` ? this.clientHeight : this.clientWidth) || 0;\n }\n\n /**\n * Whether `rect`'s label should be rotated or hidden for lack of space, per\n * {@link minLabelWidth} / {@link minVerticalLabelWidth}. `orientation=\"vertical\"`\n * rects never rotate — hides outright at `minLabelWidth` instead, same as before.\n */\n #labelMode(rect: IcicleRect): { hidden: boolean; rotated: boolean } {\n const hostExtent = this.#hostExtent();\n if (hostExtent === 0)\n return { hidden: false, rotated: false };\n const vertical = this.orientation === `vertical`;\n const pixelWidth = rect.width * hostExtent;\n if (vertical)\n return { hidden: pixelWidth < this.minLabelWidth, rotated: false };\n if (pixelWidth < this.minVerticalLabelWidth)\n return { hidden: true, rotated: false };\n return { hidden: false, rotated: pixelWidth < this.minLabelWidth };\n }\n\n /** Anchor the shared tooltip popover to the tickled rect, if its label needs one. */\n #syncTooltip(): void {\n const popover = this._tooltipEl;\n if (!popover?.popover)\n return;\n const key = this.tickled.tickledId;\n const rect = key === undefined ? undefined : this.#rects().find(r => r.node.item.key === key);\n const mode = rect ? this.#labelMode(rect) : undefined;\n const isOpen = popover.matches(`:popover-open`);\n if (rect && mode && (mode.hidden || mode.rotated)) {\n popover.textContent = rect.node.item.label;\n if (!isOpen) {\n try {\n popover.showPopover();\n } catch {\n // Popover API unsupported — ignore.\n }\n }\n } else if (isOpen) {\n try {\n popover.hidePopover();\n } catch {\n // Popover API unsupported — ignore.\n }\n }\n }\n\n #resetViewState(): void {\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._zoomKey = undefined;\n this.#anchorIndex = undefined;\n }\n\n // --- Lazy children --------------------------------------------------------\n\n #ensureVisibleChildren(): void {\n if (!this.model && !this.loadChildren)\n return;\n for (const rect of this.#rects()) {\n const { node } = rect;\n if (node.children !== undefined || this.#pendingKeys.has(node.item.key))\n continue;\n // #rects() only ever yields rects within the visible window (relativeDepth\n // < maxDepth), so every rect reaching here is a currently-rendered node\n // whose children aren't loaded yet — fetch them so zooming in works.\n void this.#loadChildren(node, rect.depth);\n }\n }\n\n async #loadChildren(node: TreeNode, depth: number): Promise<void> {\n const key = node.item.key;\n this.#pendingKeys.add(key);\n const controller = new AbortController();\n this.#aborters.set(key, controller);\n this.requestUpdate();\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 } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n } finally {\n this.#pendingKeys.delete(key);\n this.#aborters.delete(key);\n if (!controller.signal.aborted)\n this.requestUpdate();\n }\n }\n\n // --- Selection ------------------------------------------------------------\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._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail: { selected: new Set(this._selectedNodes), previous },\n bubbles: true,\n composed: true,\n }));\n }\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 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 for (const rect of this.#rects()) {\n if (!this.#canSelect(rect.node))\n continue;\n this._selectedNodes.add(rect.node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\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 // --- Zoom -----------------------------------------------------------------\n\n /**\n * Drill down so `node` becomes the visual root (ancestors move to the\n * breadcrumb strip). Pure view-state — `root` is never mutated.\n * Fires `zoom` and the semantic `expand` event.\n */\n zoomTo(node: TreeNode): void {\n if (this._zoomKey === node.item.key)\n return;\n this._zoomKey = node.item.key;\n this.tickled.clearTickled();\n const depth = findIciclePath(this.#effectiveRoot, node.item.key)?.length;\n const absoluteDepth = depth === undefined ? -1 : depth - 2;\n this.dispatchEvent(new CustomEvent<IcicleZoomDetail>(`zoom`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n }\n\n /**\n * Zoom back out to the full tree. Fires `zoom` (with `node: undefined`) and\n * the semantic `collapse` event for the previous zoom root.\n */\n zoomOut(): void {\n if (this._zoomKey === undefined)\n return;\n const previous = this.focusedNode;\n const path = this._zoomKey === undefined\n ? undefined\n : findIciclePath(this.#effectiveRoot, this._zoomKey);\n const absoluteDepth = path === undefined ? -1 : path.length - 2;\n this._zoomKey = undefined;\n this.tickled.clearTickled();\n this.dispatchEvent(new CustomEvent<IcicleZoomDetail>(`zoom`, {\n detail: { node: undefined, depth: -1 },\n bubbles: true,\n composed: true,\n }));\n if (previous) {\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node: previous, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n }\n this.requestUpdate();\n }\n\n #canZoom(node: TreeNode): boolean {\n if (node.item.isLeaf === true)\n return false;\n if (node.children !== undefined)\n return node.children.length > 0;\n // Not yet loaded — zoomable when a loader could provide children.\n return this.model !== undefined || this.loadChildren !== undefined;\n }\n\n // --- Navigation -----------------------------------------------------------\n\n /**\n * Zoom so the node at `keys` (path from the root's children) is visible,\n * then select it. Returns `true` if the path was found.\n */\n navigateTo(keys: readonly string[]): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n let current: TreeNode = root;\n const path: TreeNode[] = [];\n for (const key of keys) {\n const found = current.children?.find(n => n.item.key === key);\n if (!found)\n return false;\n path.push(found);\n current = found;\n }\n const target = path.at(-1)!;\n // Keep the target inside the depth window: zoom to the ancestor `maxDepth`\n // bands above it, or the full tree when it already fits.\n if (path.length > this.maxDepth) {\n this.zoomTo(path[path.length - this.maxDepth - 1]);\n } else if (this._zoomKey !== undefined) {\n this.zoomOut();\n }\n this.select(target);\n this.tickled.setTickled(target.item.key);\n this.requestUpdate();\n return true;\n }\n\n /**\n * Zoom + select the first node for which `predicate` returns `true`.\n * Returns `true` if a matching node was found.\n */\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const keyPath = this.#findKeyPath(root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /**\n * Zoom so the node with `key` is visible and move the keyboard cursor to it,\n * without changing the selection. Used by incremental-search \"navigate\" mode.\n */\n revealKey(key: string): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const path = this.#findKeyPath(root.children, n => n.item.key === key);\n if (!path)\n return false;\n if (path.length > this.maxDepth) {\n const ancestor = this.#resolveKeyPath(path.slice(0, path.length - this.maxDepth));\n if (ancestor)\n this.zoomTo(ancestor);\n }\n this.tickled.setTickled(key);\n this.requestUpdate();\n return true;\n }\n\n #resolveKeyPath(keys: readonly string[]): TreeNode | undefined {\n let current = this.#effectiveRoot;\n for (const key of keys) {\n const found = key === current?.item.key ? current : current?.children?.find(n => n.item.key === key);\n if (!found)\n return undefined;\n current = found;\n }\n return current;\n }\n\n #findKeyPath(\n nodes: readonly 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 hit = this.#findKeyPath(node.children, predicate, path);\n if (hit)\n return hit;\n }\n }\n return undefined;\n }\n\n /**\n * All nodes currently visible as rectangles, in render (band-major) order,\n * with absolute depth (root's children are depth 0).\n */\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n return this.#rects().map(r => ({ node: r.node, depth: r.depth }));\n }\n\n // --- Pointer / keyboard ---------------------------------------------------\n\n #matchesFilter(node: TreeNode, depth: number): boolean {\n if (!this.filterPredicate)\n return true;\n if (this.filterPredicate(node, depth))\n return true;\n return node.children?.some(child => this.#matchesFilter(child, depth + 1)) ?? false;\n }\n\n #handleItemClick(rect: IcicleRect, index: number, event: MouseEvent): void {\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.interactionMode === `standard` && (event.ctrlKey || event.metaKey)) {\n if (this._selectedNodes.has(rect.node)) {\n this.deselect(rect.node);\n } else if (this.#canSelect(rect.node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.add(rect.node);\n this.selectedNode = rect.node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n this.#anchorIndex = index;\n } else if (this.interactionMode === `standard` && event.shiftKey && this.#anchorIndex !== undefined) {\n const rects = this.#rects();\n const from = Math.min(this.#anchorIndex, index);\n const to = Math.max(this.#anchorIndex, index);\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = new Set(\n rects.slice(from, to + 1).map(r => r.node).filter(n => this.#canSelect(n)),\n );\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n } else if (this.interactionMode !== `manual`) {\n this.select(rect.node);\n this.#anchorIndex = index;\n }\n this.tickled.setTickled(rect.node.item.key);\n if (this.#canZoom(rect.node))\n this.zoomTo(rect.node);\n }\n\n #handleItemDblClick(rect: IcicleRect): void {\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n if (this.disableKeyboardNavigation)\n return;\n const rects = this.#rects();\n if (rects.length === 0)\n return;\n const tickledKey = this.tickled.tickledId;\n const currentIndex = tickledKey === undefined\n ? -1\n : rects.findIndex(r => r.node.item.key === tickledKey);\n const current = currentIndex >= 0 ? rects[currentIndex] : undefined;\n\n const moveTo = (rect: IcicleRect | undefined) => {\n if (!rect)\n return;\n event.preventDefault();\n this.tickled.setTickled(rect.node.item.key);\n // implicit: single selection follows the keyboard cursor (mirrors tree-base's implicit mode).\n if (this.interactionMode === `implicit`)\n this.select(rect.node);\n };\n\n switch (event.key) {\n case `ArrowLeft`:\n case `ArrowRight`: {\n event.preventDefault();\n const dir = event.key === `ArrowRight` ? 1 : -1;\n if (!current) {\n moveTo(rects[0]);\n return;\n }\n // Siblings share a band (relativeDepth) and parent.\n const siblings = rects.filter(r =>\n r.relativeDepth === current.relativeDepth && r.parentKey === current.parentKey);\n const at = siblings.findIndex(r => r.node.item.key === current.node.item.key);\n moveTo(siblings[at + dir] ?? (dir > 0 ? siblings[0] : siblings.at(-1)));\n return;\n }\n case `ArrowUp`: {\n // Parent band.\n if (!current) {\n moveTo(rects[0]);\n return;\n }\n const parent = current.parentKey === undefined\n ? undefined\n : rects.find(r => r.node.item.key === current.parentKey);\n moveTo(parent ?? rects[0]);\n return;\n }\n case `ArrowDown`: {\n // First-child band.\n if (!current) {\n moveTo(rects[0]);\n return;\n }\n moveTo(rects.find(r => r.parentKey === current.node.item.key));\n return;\n }\n case `Home`:\n moveTo(rects[0]);\n return;\n case `End`:\n moveTo(rects.at(-1));\n return;\n case `Enter`: {\n if (!current)\n return;\n event.preventDefault();\n if (this.interactionMode !== `manual`)\n this.select(current.node);\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n // Mirrors #handleItemClick: Enter on a node should zoom in exactly\n // like clicking it, not just select + activate.\n if (this.#canZoom(current.node))\n this.zoomTo(current.node);\n return;\n }\n case `Escape`:\n if (this._zoomKey !== undefined) {\n event.preventDefault();\n this.zoomOut();\n }\n }\n }\n\n // --- Render ---------------------------------------------------------------\n\n #renderBreadcrumb(): unknown {\n const zoomNode = this.focusedNode;\n if (zoomNode === undefined)\n return nothing;\n return html`\n <nav class=\"breadcrumb\" part=\"breadcrumb\" aria-label=\"Icicle zoom path\">\n <ixfx-crumb-navigation\n with-up\n .root=${this.#effectiveRoot}\n .selectedNode=${zoomNode}\n @select=${this.#onCrumbSelect}\n @item-click=${(e: Event) => e.stopPropagation()}\n @tickle=${(e: Event) => e.stopPropagation()}\n @expand=${(e: Event) => e.stopPropagation()}\n ></ixfx-crumb-navigation>\n </nav>\n `;\n }\n\n /**\n * Translate crumb-trail selection (crumb clicks + the up-button) into zoom\n * state. The event is stopped: crumb clicks must not bubble as our `select`\n * (the selection set is unchanged by them).\n */\n #onCrumbSelect(event: Event): void {\n event.stopPropagation();\n const selected = (event as CustomEvent<TreeSelectDetail>).detail.selected;\n const node = [...selected].at(0);\n if (!node)\n return;\n if (node.item.key === this.#effectiveRoot?.item.key) {\n this.zoomOut();\n } else {\n this.zoomTo(node);\n }\n }\n\n #renderRect(rect: IcicleRect): unknown {\n const { node } = rect;\n const selected = this._selectedNodes.has(node);\n const tickled = this.tickled.isTickled(node.item.key);\n const filtered = !this.#matchesFilter(node, rect.depth);\n const pending = this.#pendingKeys.has(node.item.key);\n const sizePct = `${(rect.width * 100).toFixed(4)}%`;\n const xPct = `${(rect.x * 100).toFixed(4)}%`;\n const vertical = this.orientation === `vertical`;\n const { hidden: hideLabel, rotated } = this.#labelMode(rect);\n const needsTooltip = tickled && (hideLabel || rotated);\n // Positioned absolutely (not flexed) so every rect's `left`/`top` is a\n // fraction of the same band width/height its parent's rect used — a flex\n // row's per-item `gap` compounds across sibling counts and drifts child\n // bands out of alignment with their parent's boundaries.\n let sizeStyle = vertical\n ? `top:${xPct};height:calc(${sizePct} - var(--icicletree-rect-gap))`\n : `left:${xPct};width:calc(${sizePct} - var(--icicletree-rect-gap))`;\n // Only the tickled rect ever claims this anchor name — the shared tooltip\n // (`position-anchor: --icicle-rect-anchor`) follows it via pure CSS.\n if (needsTooltip)\n sizeStyle += `;anchor-name:--icicle-rect-anchor`;\n return html`\n <div\n class=\"item rect ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${filtered ? `filtered` : ``} ${pending ? `loading` : ``} ${rect.width <= 0 ? `empty` : ``} ${rotated ? `rotated` : ``}\"\n data-key=${node.item.key}\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-level=${rect.depth + 1}\n aria-selected=${selected}\n aria-setsize=${rect.setSize}\n aria-posinset=${rect.index + 1}\n aria-label=${node.item.label}\n part=\"rect\"\n style=${sizeStyle}\n @click=${(e: MouseEvent) => this.#handleItemClick(rect, this.#rects().findIndex(r => r.node.item.key === node.item.key), e)}\n @dblclick=${() => this.#handleItemDblClick(rect)}\n @pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}\n >\n <span class=\"icicle-label ${hideLabel ? `hide-label` : ``} ${rotated ? `label-vertical` : ``}\" part=\"label\">${node.item.label}</span>\n </div>\n `;\n }\n\n protected override render() {\n const rects = this.#rects();\n const bands = new Map<number, IcicleRect[]>();\n for (const rect of rects) {\n const band = bands.get(rect.relativeDepth) ?? [];\n band.push(rect);\n bands.set(rect.relativeDepth, band);\n }\n const vertical = this.orientation === `vertical`;\n return html`\n <div\n class=\"icicle ${vertical ? `vertical` : `horizontal`}\"\n role=\"tree\"\n tabindex=\"0\"\n data-input-mode=${this.tickled.inputMode}\n @keydown=${(e: KeyboardEvent) => this.#handleKeyDown(e)}\n @pointerleave=${() => this.tickled.clearTickled()}\n >\n ${this.#renderBreadcrumb()}\n ${rects.length === 0\n ? html`<div class=\"empty-state\">No data</div>`\n : [...bands.entries()].map(([depth, band]) => html`\n <div\n class=\"band\"\n role=\"presentation\"\n data-depth=${depth}\n >\n ${repeat(band, r => r.node.item.key, r => this.#renderRect(r))}\n </div>\n `)}\n </div>\n <div id=\"icicle-tooltip\" popover=\"manual\" part=\"tooltip\" class=\"icicle-tooltip\"></div>\n ${this.search.renderField()}\n `;\n }\n\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n listSearchStyles,\n css`\n :host {\n --icicletree-band-height: 44px;\n --icicletree-band-gap: 2px;\n --icicletree-rect-gap: 2px;\n --icicletree-rect-bg: var(--surface-4);\n --icicletree-rect-text: var(--surface-4-text);\n --icicletree-font-size: var(--text-s);\n\n display: block;\n overflow: auto;\n }\n\n .icicle {\n display: flex;\n gap: var(--icicletree-band-gap);\n outline: none;\n }\n\n .icicle.horizontal {\n flex-direction: column;\n }\n\n .icicle.vertical {\n flex-direction: row;\n min-height: 200px;\n }\n\n .breadcrumb {\n display: flex;\n align-items: center;\n padding: var(--space-xs) var(--space-s);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n font-size: var(--text-s);\n flex-shrink: 0;\n }\n\n .breadcrumb ixfx-crumb-navigation {\n flex: 1;\n min-width: 0;\n }\n\n .band {\n position: relative;\n }\n\n .icicle.horizontal .band {\n height: var(--icicletree-band-height);\n }\n\n .icicle.vertical .band {\n flex: 1 1 0;\n min-width: 0;\n height: 100%;\n }\n\n .rect {\n box-sizing: border-box;\n position: absolute;\n overflow: hidden;\n display: flex;\n align-items: center;\n padding: 0 var(--space-s);\n background: var(--icicletree-rect-bg);\n color: var(--icicletree-rect-text);\n font-size: var(--icicletree-font-size);\n cursor: pointer;\n transition:\n width var(--transition),\n height var(--transition),\n left var(--transition),\n top var(--transition),\n opacity var(--transition),\n background-color var(--transition);\n }\n\n .icicle.horizontal .rect {\n top: 0;\n height: 100%;\n }\n\n /*\n * A rotated label needs its full allotted width to be usable — the\n * default left/right padding (--space-s, ~4px a side) can consume\n * most or all of a rect sized down to minVerticalLabelWidth, leaving\n * the rotated text clipped to invisible. #labelMode's width estimate\n * assumes the whole rect width is usable, so drop the padding here to\n * match that assumption instead of also budgeting for it in the\n * threshold (which would make already-narrow rects need even more).\n */\n .icicle.horizontal .rect.rotated {\n padding: 0;\n }\n\n .icicle.vertical .rect {\n left: 0;\n width: 100%;\n padding: var(--space-s) 0;\n justify-content: center;\n writing-mode: horizontal-tb;\n }\n\n .rect.filtered {\n opacity: 0.3;\n filter: saturate(0.4);\n }\n\n .rect.empty {\n padding: 0;\n border: none;\n }\n\n .rect.loading {\n cursor: progress;\n opacity: 0.6;\n }\n\n .icicle-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n min-width: 0;\n }\n\n .icicle-label.hide-label {\n visibility: hidden;\n }\n\n .icicle-label.label-vertical {\n writing-mode: vertical-rl;\n text-orientation: sideways;\n flex: none;\n width: 100%;\n height: 100%;\n padding: var(--space-2xs, 2px) 0;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n /*\n * Instant tooltip for rects whose label is rotated or hidden — anchored\n * via CSS anchor positioning (anchor-name set on the tickled rect in\n * #renderRect) rather than a JS-computed position, and shown/hidden via\n * the Popover API rather than the browser's own (slow, un-stylable)\n * title tooltip.\n */\n .icicle-tooltip {\n position: fixed;\n position-anchor: --icicle-rect-anchor;\n position-area: bottom center;\n position-try-fallbacks: top center;\n margin: var(--space-xs, 4px) 0 0;\n padding: var(--space-2xs, 2px) var(--space-xs, 6px);\n background: var(--surface-5);\n color: var(--surface-5-text);\n border: var(--border-subtle);\n border-radius: var(--radius-s, 4px);\n font-size: var(--text-s);\n white-space: nowrap;\n pointer-events: none;\n inset: auto;\n }\n\n .icicle-tooltip:popover-open {\n display: block;\n }\n\n .empty-state {\n padding: var(--space-l);\n color: var(--surface-muted-text);\n font-size: var(--text-s);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-icicletree-list': IcicleTreeListElement;\n }\n}\n\nexport interface IcicleTreeListElement {\n addEventListener: (<K extends keyof IcicleTreeListElementEventMap>(\n type: K,\n listener: (this: IcicleTreeListElement, event: IcicleTreeListElementEventMap[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 IcicleTreeListElementEventMap>(\n type: K,\n listener: (this: IcicleTreeListElement, event: IcicleTreeListElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","export type SortDirection = `asc` | `desc`;\n\nexport type MulticolItem = {\n readonly key: string;\n readonly label: string;\n readonly count?: number;\n readonly data?: unknown;\n};\n\nexport type MulticolCategoryDefaults = {\n grouped?: boolean;\n groupBy?: (item: MulticolItem) => string;\n allLabel?: string;\n sort?: SortDirection;\n};\n\nexport type MulticolCategory = {\n readonly key: string;\n readonly label: string;\n readonly children?: readonly MulticolCategory[];\n readonly defaults?: MulticolCategoryDefaults;\n};\n\nexport type MulticolColumnState = {\n readonly id: string;\n readonly categoryKey: string;\n readonly sort: SortDirection;\n readonly grouped: boolean;\n readonly width?: number;\n};\n\nexport type MulticolColumnsChangeReason\n = `add` | `remove` | `reorder` | `category` | `sort` | `grouping` | `resize`;\n\nexport type MulticolQuery = {\n readonly columnId: string;\n readonly categoryKey: string;\n readonly otherSelections: ReadonlyMap<string, readonly string[]>;\n};\n\nexport type MulticolColumnSelection = {\n readonly columnId: string;\n readonly categoryKey: string;\n readonly values: readonly string[];\n};\n\nexport type MulticolSelectDetail = {\n readonly columnId: string;\n readonly columns: readonly MulticolColumnSelection[];\n};\n\nexport const ALL_KEY = `__all__`;\n","import type { IDataProvider } from '../common/data-provider.js';\nimport type { GroupedItemListerElement } from '../grouped-item-lister/grouped-item-lister.js';\nimport type { IGroupedSubComponent } from '../grouped-item-lister/types.js';\nimport type { ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type { VerticalListElement } from '../vertical-list/vertical-list.js';\nimport type { MulticolCategory, MulticolCategoryDefaults, MulticolColumnState, MulticolItem, MulticolQuery, SortDirection } from './types.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport { createVerticalListAdapter } from '../grouped-item-lister/vertical-list-adapter.js';\nimport { ALL_KEY } from './types.js';\nimport '../grouped-item-lister/grouped-item-lister.js';\n\nexport interface MulticolColumnControllerOptions {\n id: string;\n category: MulticolCategory;\n categoryDefaults: MulticolCategoryDefaults | undefined;\n selectionMode: ListSelectionMode;\n dataProvider: IDataProvider<MulticolQuery, MulticolItem> | undefined;\n onSelectionChange: (columnId: string, values: readonly string[]) => void;\n onRequestData: (columnId: string, query: MulticolQuery, signal: AbortSignal) => void;\n}\n\n/** Sorts by label, honouring direction. 'All' lives outside the list, so it is not special-cased. */\nexport function sortItems(items: readonly MulticolItem[], direction: SortDirection): MulticolItem[] {\n const dir = direction === `desc` ? -1 : 1;\n return [...items].sort((a, b) => dir * a.label.localeCompare(b.label, undefined, { sensitivity: `base`, numeric: true }));\n}\n\n/**\n * Nearest-gap math for header drag-reorder (per data-grid's `_beginHeaderDrag`).\n *\n * `offsets` is a prefix-sum of column widths (length = count + 1). `x` is the\n * pointer position in content space (already adjusted for scroll). Returns the\n * final insertion index once the source column is removed (`insert`), plus the\n * un-normalised gap offset for the drop caret (`caretOffset`).\n */\nexport function computeDropGap(offsets: readonly number[], x: number, count: number, from: number): { insert: number; caretOffset: number } {\n if (count === 0)\n return { insert: 0, caretOffset: 0 };\n\n let bestDist = Number.MAX_SAFE_INTEGER;\n let caretGap = from;\n\n for (let i = 0; i < count; i++) {\n if (i === from)\n continue;\n\n const left = offsets[i];\n const right = offsets[i + 1] ?? offsets[offsets.length - 1];\n const mid = (left + right) / 2;\n\n const gapPos = x < mid ? left : right;\n const dist = Math.abs(x - gapPos);\n\n if (dist < bestDist) {\n bestDist = dist;\n caretGap = x < mid ? i : i + 1;\n }\n }\n\n const insert = caretGap > from ? caretGap - 1 : caretGap;\n return {\n insert: Math.max(0, Math.min(count - 1, insert)),\n caretOffset: offsets[caretGap] ?? offsets[offsets.length - 1],\n };\n}\n\nexport class MulticolColumnController {\n readonly id: string;\n\n #category: MulticolCategory;\n #categoryDefaults: MulticolCategoryDefaults | undefined;\n #selectionMode: ListSelectionMode;\n #dataProvider: IDataProvider<MulticolQuery, MulticolItem> | undefined;\n #onSelectionChange: (columnId: string, values: readonly string[]) => void;\n #onRequestData: (columnId: string, query: MulticolQuery, signal: AbortSignal) => void;\n\n #abortController: AbortController | undefined = undefined;\n #host: HTMLElement | undefined;\n #allRow: HTMLDivElement | undefined;\n #listerEl: GroupedItemListerElement<MulticolItem> | undefined;\n #selectedValues: readonly string[] = [];\n #allSelected = true;\n #lastItems: readonly MulticolItem[] = [];\n #syncingSelection = false;\n #state: MulticolColumnState;\n\n constructor(options: MulticolColumnControllerOptions) {\n this.id = options.id;\n this.#category = options.category;\n this.#categoryDefaults = options.categoryDefaults;\n this.#selectionMode = options.selectionMode;\n this.#dataProvider = options.dataProvider;\n this.#onSelectionChange = options.onSelectionChange;\n this.#onRequestData = options.onRequestData;\n this.#state = {\n id: options.id,\n categoryKey: options.category.key,\n sort: options.categoryDefaults?.sort ?? `asc`,\n grouped: options.categoryDefaults?.grouped ?? false,\n width: 220,\n };\n }\n\n get state(): MulticolColumnState {\n return this.getState();\n }\n\n /** Always derived from the live category so a swap is visible everywhere. */\n get categoryKey(): string {\n return this.#category.key;\n }\n\n getState(): MulticolColumnState {\n return { ...this.#state };\n }\n\n updateState(partial: Partial<MulticolColumnState>): void {\n // Drop non-finite widths (e.g. NaN from a bad measurement/restore) —\n // otherwise they poison offset prefix-sums and wedge the update guard\n // (`NaN === NaN` is false, so offsets would never settle).\n let sanitised = partial;\n if (partial.width !== undefined && !Number.isFinite(partial.width)) {\n const { width: _dropped, ...rest } = partial;\n sanitised = rest;\n }\n const sortChanged = sanitised.sort !== undefined && sanitised.sort !== this.#state.sort;\n const groupedChanged = sanitised.grouped !== undefined && sanitised.grouped !== this.#state.grouped;\n this.#state = { ...this.#state, ...sanitised };\n if (sortChanged)\n this.#repush();\n if (groupedChanged)\n this.#syncGrouping();\n }\n\n setWidth(width: number): void {\n // Ignore non-finite measurements (NaN/Infinity from detached or hidden\n // subtrees where style reads come back empty) — storing NaN would poison\n // offset prefix-sums and wedge the host's update guard into a loop.\n if (!Number.isFinite(width))\n return;\n this.#state = { ...this.#state, width: Math.max(80, Math.min(480, Math.round(width))) };\n }\n\n setSort(sort: SortDirection): void {\n if (sort === this.#state.sort)\n return;\n this.#state = { ...this.#state, sort };\n this.#repush();\n }\n\n setGrouped(grouped: boolean): void {\n if (grouped === this.#state.grouped)\n return;\n this.#state = { ...this.#state, grouped };\n this.#syncGrouping();\n }\n\n setSelectionMode(mode: ListSelectionMode): void {\n if (mode === this.#selectionMode)\n return;\n this.#selectionMode = mode;\n for (const sub of this.#subComponents()) {\n sub.selectionMode = mode;\n }\n }\n\n setCategory(category: MulticolCategory): void {\n this.#category = category;\n this.#categoryDefaults = category.defaults;\n this.#state = {\n ...this.#state,\n categoryKey: category.key,\n sort: category.defaults?.sort ?? `asc`,\n grouped: category.defaults?.grouped ?? false,\n };\n this.clearSelection();\n this.#syncGrouping();\n }\n\n get listerHost(): HTMLElement | undefined {\n return this.#host;\n }\n\n get isMounted(): boolean {\n return this.#host !== undefined;\n }\n\n setDataProvider(provider: IDataProvider<MulticolQuery, MulticolItem> | undefined): void {\n this.#dataProvider = provider;\n }\n\n mount(host: HTMLElement): void {\n if (this.#host)\n return;\n this.#host = host;\n\n const allRow = document.createElement(`div`);\n allRow.className = `all-row`;\n allRow.dataset.key = ALL_KEY;\n allRow.setAttribute(`role`, `button`);\n allRow.setAttribute(`tabindex`, `0`);\n const allLabel = document.createElement(`span`);\n allLabel.className = `all-label`;\n allRow.appendChild(allLabel);\n const applyAll = (): void => {\n if (this.#allSelected)\n return;\n this.#setAllSelection();\n };\n allRow.addEventListener(`click`, applyAll);\n allRow.addEventListener(`keydown`, (e: KeyboardEvent) => {\n if (e.key === `Enter` || e.key === ` `) {\n e.preventDefault();\n applyAll();\n }\n });\n this.#allRow = allRow;\n\n const lister = document.createElement(`ixfx-grouped-item-lister`) as GroupedItemListerElement<MulticolItem>;\n lister.crossGroupSelection = true;\n lister.factory = () => createVerticalListAdapter<MulticolItem>(renderItem, {\n selectionMode: this.#selectionMode,\n interactionMode: `standard`,\n });\n lister.addEventListener(`select`, this.#handleSelect as EventListener);\n this.#listerEl = lister;\n\n this.#syncGrouping();\n this.#syncAllRow();\n host.append(allRow, lister);\n\n if (this.#lastItems.length > 0) {\n this.#pushItems();\n this.#restoreAfterSync();\n }\n }\n\n unmount(): void {\n this.#abortPending();\n this.#allRow?.remove();\n this.#listerEl?.remove();\n this.#allRow = undefined;\n this.#listerEl = undefined;\n this.#host = undefined;\n }\n\n // ---- Data ----\n\n requestData(query: MulticolQuery): void {\n if (!this.#dataProvider)\n return;\n\n this.#abortPending();\n\n const controller = new AbortController();\n this.#abortController = controller;\n const { signal } = controller;\n\n this.#onRequestData(this.id, query, signal);\n\n Promise.resolve().then(async () => {\n const result = this.#dataProvider!(query, signal);\n const items = await collectDataResult(result, signal);\n if (signal.aborted)\n return;\n this.#applyItems(items);\n }).catch(() => {\n // Aborted or provider error — leave current items as-is\n });\n }\n\n #applyItems(items: readonly MulticolItem[]): void {\n this.#lastItems = items;\n\n // Drop selections that no longer exist in the data\n const valid = this.#selectedValues.filter(v => items.some(i => i.key === v));\n const changed = valid.length !== this.#selectedValues.length;\n this.#selectedValues = valid;\n if (valid.length === 0)\n this.#allSelected = true;\n\n if (!this.#listerEl) {\n if (changed)\n this.#onSelectionChange(this.id, valid);\n return;\n }\n\n this.#pushItems();\n this.#restoreAfterSync();\n\n if (changed)\n this.#onSelectionChange(this.id, valid);\n }\n\n #pushItems(): void {\n if (!this.#listerEl)\n return;\n const sorted = sortItems(this.#lastItems, this.#state.sort);\n this.#listerEl.provider = () => sorted;\n }\n\n #repush(): void {\n if (!this.#listerEl || this.#lastItems.length === 0)\n return;\n this.#pushItems();\n this.#restoreAfterSync();\n }\n\n /** Grouping config from category defaults; grouping without groupBy is a no-op. */\n #syncGrouping(): void {\n if (!this.#listerEl)\n return;\n const groupBy = this.#categoryDefaults?.groupBy;\n this.#listerEl.groupBy = groupBy;\n this.#listerEl.grouped = this.#state.grouped && groupBy !== undefined;\n if (this.#lastItems.length > 0) {\n this.#restoreAfterSync();\n }\n }\n\n // ---- Selection ----\n\n #subComponents(): Iterable<HTMLElement & IGroupedSubComponent<MulticolItem>> {\n if (!this.#listerEl)\n return [];\n return this.#listerEl.querySelectorAll(`:scope > .ungrouped-host > *, :scope > ixfx-panel > *`);\n }\n\n #handleSelect = (): void => {\n if (this.#syncingSelection)\n return;\n\n const values = [...this.#listerEl?.selectedItems ?? []].map(i => i.key).filter(k => k !== ALL_KEY);\n\n const sameSize = values.length === this.#selectedValues.length;\n const sameValues = sameSize && values.every(v => this.#selectedValues.includes(v));\n if (sameValues) {\n this.#syncAllRow();\n return;\n }\n\n // Selecting a value implicitly deselects All; emptying the selection re-selects All\n this.#selectedValues = values;\n this.#allSelected = values.length === 0;\n this.#syncAllRow();\n this.#onSelectionChange(this.id, values);\n };\n\n #setAllSelection(): void {\n const previous = this.#selectedValues;\n this.#syncingSelection = true;\n try {\n this.#selectedValues = [];\n this.#allSelected = true;\n for (const sub of this.#subComponents()) {\n sub.clearSelection();\n }\n } finally {\n this.#syncingSelection = false;\n }\n this.#syncAllRow();\n\n // Going back to All is a selection change like any other — hosts and the\n // cascade must hear about it\n if (previous.length > 0) {\n this.#onSelectionChange(this.id, []);\n }\n }\n\n clearSelection(): void {\n this.#setAllSelection();\n }\n\n get selectedValues(): readonly string[] {\n return this.#selectedValues;\n }\n\n #restoreAfterSync(): void {\n if (!this.#listerEl)\n return;\n void this.#listerEl.updateComplete.then(() => {\n if (!this.#listerEl || !this.#host)\n return;\n this.#syncingSelection = true;\n try {\n const wanted = this.#selectedValues;\n for (const list of this.#listerEl.querySelectorAll<VerticalListElement>(`ixfx-vertical-list`)) {\n list.selectKeys(wanted);\n }\n const selected = [...this.#listerEl.selectedItems].map(i => i.key).filter(k => k !== ALL_KEY);\n this.#selectedValues = selected;\n this.#allSelected = selected.length === 0;\n } finally {\n this.#syncingSelection = false;\n }\n this.#syncAllRow();\n });\n }\n\n #syncAllRow(): void {\n if (!this.#allRow)\n return;\n const label = this.#categoryDefaults?.allLabel ?? `All`;\n const labelEl = this.#allRow.querySelector(`.all-label`);\n if (labelEl)\n labelEl.textContent = label;\n this.#allRow.toggleAttribute(`data-selected`, this.#allSelected);\n }\n\n // ---- Internal ----\n\n #abortPending(): void {\n if (this.#abortController) {\n this.#abortController.abort();\n this.#abortController = undefined;\n }\n }\n}\n\nfunction renderItem(item: MulticolItem): Element {\n const li = document.createElement(`li`);\n li.dataset.key = item.key;\n\n const labelSpan = document.createElement(`span`);\n labelSpan.className = `item-label`;\n labelSpan.textContent = item.label;\n li.appendChild(labelSpan);\n\n if (item.count !== undefined) {\n const countSpan = document.createElement(`span`);\n countSpan.className = `count`;\n countSpan.textContent = String(item.count);\n li.appendChild(countSpan);\n }\n\n return li;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { IDataProvider } from '../common/data-provider.js';\nimport type { TreeNode } from '../common/types.js';\nimport type { ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type { MenuTrigger } from '../menu/menu-trigger.js';\nimport type { DragGhost } from '../util/drag-ghost.js';\nimport type { MulticolCategory, MulticolColumnsChangeReason, MulticolColumnState, MulticolItem, MulticolQuery, MulticolSelectDetail } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { registerIcon } from '../icons/registry.js';\nimport { menuFromTreeToElements } from '../menu/menu-from-tree.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\nimport { computeDropGap, MulticolColumnController } from './column.js';\nimport '../icons/icon.js';\nimport '../menu/menu-trigger.js';\nimport '../menu/menu-container.js';\nimport '../menu/menu-item.js';\nimport '../menu/menu-sub-trigger.js';\nimport '../menu/menu-separator.js';\n\nexport type {\n MulticolCategory,\n MulticolColumnsChangeReason,\n MulticolColumnState,\n MulticolItem,\n MulticolQuery,\n MulticolSelectDetail,\n SortDirection,\n} from './types.js';\n\nexport type MulticolSelectEvent = CustomEvent<MulticolSelectDetail>;\nexport type MulticolColumnsChangeDetail = {\n readonly columns: readonly MulticolColumnState[];\n readonly reason: MulticolColumnsChangeReason;\n};\nexport type MulticolColumnsChangeEvent = CustomEvent<MulticolColumnsChangeDetail>;\n\nexport interface MulticolListElementEventMap {\n 'multicol-select': MulticolSelectEvent;\n 'multicol-columns-change': MulticolColumnsChangeEvent;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-multicol-list': MulticolListElement;\n }\n}\n\nexport interface MulticolListElement {\n addEventListener<K extends keyof MulticolListElementEventMap>(\n type: K,\n listener: (this: MulticolListElement, event: MulticolListElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n\n// Lucide 'menu' — registered on load so the burger button always renders\nregisterIcon(`menu`, `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 12h16\"/><path d=\"M4 18h16\"/><path d=\"M4 6h16\"/></svg>`);\n\nconst DEFAULT_COLUMN_WIDTH = 220;\nconst MIN_COLUMN_WIDTH = 80;\nconst MAX_COLUMN_WIDTH = 480;\nconst DRAG_THRESHOLD = 5;\n\n@customElement(`ixfx-multicol-list`)\nexport class MulticolListElement extends LitElement {\n static override styles = [\n themeFallbacks,\n handleStyles,\n css`\n :host {\n --multicol-list-bg: var(--surface-3);\n --multicol-list-header-bg: var(--surface-2);\n --multicol-list-header-text: var(--surface-3-text);\n --multicol-list-border: var(--border);\n --multicol-list-min-column-width: ${MIN_COLUMN_WIDTH}px;\n --multicol-list-max-column-width: ${MAX_COLUMN_WIDTH}px;\n --multicol-list-header-font-size: unset;\n\n display: block;\n overflow: hidden;\n background: var(--multicol-list-bg);\n color: var(--surface-3-text);\n font-family: var(--font-family);\n }\n #container {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n overflow: hidden;\n position: relative;\n height: 100%;\n }\n .column {\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n border-right: var(--multicol-list-border);\n min-width: var(--multicol-list-min-column-width);\n max-width: var(--multicol-list-max-column-width);\n background: var(--surface-3);\n }\n .column-header {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n height: 32px;\n background: var(--multicol-list-header-bg);\n color: var(--multicol-list-header-text);\n border-bottom: var(--border);\n position: relative;\n user-select: none;\n min-width: var(--multicol-list-min-column-width);\n box-sizing: border-box;\n }\n .column-header[data-dragging] {\n opacity: 0.4;\n }\n .reorder-handle {\n cursor: grab;\n opacity: 0;\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n padding-left: var(--space-xs);\n touch-action: none;\n transition: opacity var(--transition, 0.15s ease-out);\n }\n .column-header:hover .reorder-handle, .column-header:focus-within .reorder-handle, .column-header[data-dragging] .reorder-handle { opacity: var(--ixfx-handle-opacity, 0.5); }\n .reorder-handle:active {\n cursor: grabbing;\n }\n .reorder-handle .ixfx-handle {\n --ixfx-handle-length: 14px;\n --ixfx-handle-thickness: var(--multicol-list-reorder-handle-width, 10px);\n --ixfx-handle-dot-size: 3px;\n }\n .column-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 var(--space-s);\n font-size: var(--multicol-list-header-font-size);\n font-weight: 600;\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n text-align: left;\n min-width: 0;\n }\n .column-label:hover {\n text-decoration: underline;\n }\n .burger-btn {\n flex-shrink: 0;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--surface-3-text);\n opacity: 0;\n transition: opacity var(--transition);\n border-radius: var(--radius-s);\n }\n .column:hover .burger-btn,\n .column-header:focus-within .burger-btn {\n opacity: 1;\n }\n .burger-btn:hover {\n background: var(--surface-4);\n }\n .resize-handle {\n position: absolute;\n right: -4px;\n top: 0;\n bottom: 0;\n width: 8px;\n cursor: col-resize;\n z-index: 1;\n display: flex;\n align-items: stretch;\n justify-content: center;\n touch-action: none;\n }\n .resize-handle::before {\n content: '';\n width: 2px;\n margin: 2px 0;\n border-radius: 1px;\n background: transparent;\n transition: background-color var(--transition);\n }\n .resize-handle:hover::before,\n .resize-handle[data-active]::before {\n background: var(--accent);\n }\n .lister-host {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n .all-row {\n display: flex;\n align-items: center;\n padding: var(--space-xs) var(--space-s);\n cursor: pointer;\n user-select: none;\n min-height: 28px;\n box-sizing: border-box;\n outline: 1px solid transparent;\n background: var(--surface-3);\n }\n .all-row:hover,\n .all-row[data-selected] {\n background: var(--surface-5);\n }\n .all-row[data-selected] {\n outline-color: var(--accent);\n font-weight: 600;\n }\n ixfx-grouped-item-lister {\n display: block;\n }\n .drop-caret {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--accent);\n border-radius: 1px;\n pointer-events: none;\n z-index: 10;\n }\n .item-label {\n flex: 1;\n }\n .count {\n opacity: 0.6;\n margin-left: var(--space-s);\n font-size: var(--text-s);\n }\n `,\n ];\n\n @property({ attribute: false }) categories: readonly MulticolCategory[] = [];\n @property({ attribute: false }) dataProvider?: IDataProvider<MulticolQuery, MulticolItem>;\n @property({ type: String, attribute: `selection-mode` }) selectionMode: ListSelectionMode = `multiple`;\n @property({ type: Number }) minColumns = 1;\n @property({ type: Number }) maxColumns = 5;\n\n @state() private _columns: MulticolColumnController[] = [];\n @state() private _colOffsets: number[] = [0];\n @state() private _resizingColumnId: string | undefined = undefined;\n @state() private _draggingColumnId: string | undefined = undefined;\n @state() private _dropCaretX: number | undefined = undefined;\n\n @query(`#container`) private _containerEl: HTMLElement | undefined;\n\n private _idCounter = 0;\n private _autoSeeded = false;\n private _drag = {\n pointerId: -1,\n from: -1,\n startX: 0,\n startY: 0,\n active: false,\n ghost: null as DragGhost | null,\n insert: -1,\n };\n\n get columns(): readonly MulticolColumnState[] {\n return this._columns.map(c => c.getState());\n }\n\n setColumns(states: readonly MulticolColumnState[]): void {\n const existingMap = new Map(this._columns.map(c => [c.id, c]));\n const newColumns: MulticolColumnController[] = [];\n\n for (const colState of states) {\n const existing = existingMap.get(colState.id);\n if (existing) {\n // A restored state may point the column at a different category — apply\n // it through setCategory so defaults and label stay in sync\n if (existing.categoryKey !== colState.categoryKey) {\n const newCategory = this.categories.find(c => c.key === colState.categoryKey);\n if (newCategory)\n existing.setCategory(newCategory);\n }\n existing.updateState(colState);\n newColumns.push(existing);\n existingMap.delete(colState.id);\n continue;\n }\n\n // Restore a column that has no live controller (e.g. after a page reload)\n const category = this.categories.find(c => c.key === colState.categoryKey);\n if (!category)\n continue;\n const controller = this.#createController(colState.id, category);\n controller.updateState(colState);\n newColumns.push(controller);\n }\n\n for (const col of existingMap.values()) {\n col.unmount();\n }\n\n this._columns = newColumns;\n this._updateColOffsets();\n this._emitColumnsChange(`add`);\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n addColumn(categoryKey: string, position?: number): void {\n if (this.maxColumns > 0 && this._columns.length >= this.maxColumns)\n return;\n\n const category = this.categories.find(c => c.key === categoryKey);\n if (!category)\n return;\n\n const id = `col-${++this._idCounter}`;\n const controller = this.#createController(id, category);\n\n if (position !== undefined && position >= 0 && position < this._columns.length) {\n this._columns.splice(position, 0, controller);\n } else {\n this._columns.push(controller);\n }\n\n this._updateColOffsets();\n this._emitColumnsChange(`add`);\n\n // New column starts at All, but the host decorates counts from\n // otherSelections — re-query everything so counts stay consistent\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n removeColumn(columnId: string): void {\n if (this._columns.length <= this.minColumns)\n return;\n\n const idx = this._columns.findIndex(c => c.id === columnId);\n if (idx < 0)\n return;\n\n const col = this._columns[idx];\n col.unmount();\n this._columns.splice(idx, 1);\n this._updateColOffsets();\n this._emitColumnsChange(`remove`);\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n getSelection(): ReadonlyArray<{ columnId: string; categoryKey: string; values: readonly string[] }> {\n return this._columns.map(c => ({\n columnId: c.id,\n categoryKey: c.categoryKey,\n values: c.selectedValues,\n }));\n }\n\n clearSelection(): void {\n // Each column that actually changes fires `multicol-select` and cascades\n // a re-query through the standard selection-change path\n for (const col of this._columns) {\n col.clearSelection();\n }\n this.requestUpdate();\n }\n\n protected override render() {\n return html`\n <div id=\"container\">\n ${repeat(this._columns, col => col.id, (col, idx) => this._renderColumn(col, idx))}\n ${this._dropCaretX !== undefined\n ? html`<div class=\"drop-caret\" style=\"left: ${this._dropCaretX}px\"></div>`\n : nothing}\n </div>\n `;\n }\n\n protected override updated(changedProperties: Map<string, unknown>): void {\n // Auto-seed: the component is meant to always show at least one column.\n // Skipped when the host has restored (or otherwise installed) a layout.\n if (!this._autoSeeded && this._columns.length === 0 && this.categories.length > 0) {\n this._autoSeeded = true;\n this.addColumn(this.categories[0].key);\n }\n\n if (changedProperties.has(`selectionMode`)) {\n for (const col of this._columns) {\n col.setSelectionMode(this.selectionMode);\n }\n }\n if (changedProperties.has(`dataProvider`)) {\n for (const col of this._columns) {\n col.setDataProvider(this.dataProvider);\n }\n }\n\n for (const col of this._columns) {\n if (!col.isMounted) {\n const hostEl = this.shadowRoot?.querySelector(`[data-col-id=\"${col.id}\"] .lister-host`);\n if (hostEl) {\n col.mount(hostEl as HTMLElement);\n }\n }\n }\n\n if (changedProperties.has(`categories`)) {\n this._syncColumnsWithCategories();\n }\n if (changedProperties.has(`categories`) || changedProperties.has(`dataProvider`)) {\n this._requeryAllColumns();\n }\n\n this._updateColOffsets();\n }\n\n private _renderColumn(col: MulticolColumnController, idx: number): unknown {\n const state = col.getState();\n const rawWidth = state.width ?? DEFAULT_COLUMN_WIDTH;\n const width = Number.isFinite(rawWidth) ? rawWidth : DEFAULT_COLUMN_WIDTH;\n\n return html`\n <div\n class=\"column\"\n data-col-id=\"${col.id}\"\n style=\"width: ${width}px\"\n >\n <div\n class=\"column-header\"\n ?data-dragging=${this._draggingColumnId === col.id}\n data-col-idx=${idx}\n >\n <span\n class=\"reorder-handle\"\n data-tooltip=\"Drag to reorder\"\n @pointerdown=${(e: PointerEvent) => this._onHeaderPointerDown(e, col, idx)}\n ><span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"vertical\" part=\"reorder-handle\"></span></span>\n <button\n class=\"column-label\"\n data-tooltip=\"Change category\"\n @click=${(e: Event) => {\n e.stopPropagation(); this._openCategoryPicker(col, e.currentTarget as HTMLElement);\n }}\n >${this._getCategoryLabel(col.categoryKey)}</button>\n <button\n class=\"burger-btn\"\n data-tooltip=\"Column options\"\n @click=${(e: Event) => {\n e.stopPropagation(); this._openBurgerMenu(col, e.currentTarget as HTMLElement);\n }}\n >\n <ixfx-icon name=\"menu\" size=\"14\"></ixfx-icon>\n </button>\n <span\n class=\"resize-handle\"\n ?data-active=${this._resizingColumnId === col.id}\n @pointerdown=${(e: PointerEvent) => this._onResizePointerDown(e, col)}\n @click=${(e: Event) => e.stopPropagation()}\n ></span>\n </div>\n <div class=\"lister-host\"></div>\n </div>\n `;\n }\n\n private _getCategoryLabel(key: string): string {\n const cat = this.categories.find(c => c.key === key);\n return cat?.label ?? key;\n }\n\n #createController(id: string, category: MulticolCategory): MulticolColumnController {\n return new MulticolColumnController({\n id,\n category,\n categoryDefaults: category.defaults,\n selectionMode: this.selectionMode,\n dataProvider: this.dataProvider,\n onSelectionChange: this._onColumnSelectionChange.bind(this),\n onRequestData: this._onColumnRequestData.bind(this),\n });\n }\n\n // ---------------------------------------------------------------------\n // Header drag-reorder (pattern per data-grid `_beginHeaderDrag`)\n // ---------------------------------------------------------------------\n\n private _onHeaderPointerDown(e: PointerEvent, col: MulticolColumnController, idx: number): void {\n e.stopPropagation();\n\n this._drag = {\n pointerId: e.pointerId,\n from: idx,\n startX: e.clientX,\n startY: e.clientY,\n active: false,\n ghost: null,\n insert: idx,\n };\n\n const onMove = (ev: PointerEvent): void => {\n if (ev.pointerId !== this._drag.pointerId)\n return;\n\n const dx = ev.clientX - this._drag.startX;\n const dy = ev.clientY - this._drag.startY;\n\n if (!this._drag.active) {\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD)\n return;\n\n this._drag.active = true;\n this._draggingColumnId = col.id;\n\n const headerEl = this.shadowRoot?.querySelector(`[data-col-id=\"${col.id}\"] .column-header`) as HTMLElement | null;\n const content = document.createElement(`span`);\n content.textContent = this._getCategoryLabel(col.categoryKey);\n\n try {\n if (headerEl) {\n this._drag.ghost = createDragGhost({ anchor: headerEl, content });\n this._drag.ghost.move(ev.clientX, ev.clientY);\n }\n } catch { /* ignore */ }\n\n // Capture retargets the eventual click away from the header buttons,\n // so a real drag never opens a menu\n try {\n this._containerEl?.setPointerCapture(ev.pointerId);\n } catch { /* ignore */ }\n }\n\n this._drag.ghost?.move(ev.clientX, ev.clientY);\n\n const containerEl = this._containerEl;\n if (!containerEl)\n return;\n const rect = containerEl.getBoundingClientRect();\n const x = ev.clientX - rect.left + containerEl.scrollLeft;\n const gap = computeDropGap(this._colOffsets, x, this._columns.length, this._drag.from);\n this._drag.insert = gap.insert;\n this._dropCaretX = gap.caretOffset;\n this.requestUpdate();\n };\n\n const finish = (ev: PointerEvent): void => {\n if (ev.pointerId !== this._drag.pointerId)\n return;\n\n const wasActive = this._drag.active;\n const from = this._drag.from;\n const insert = this._drag.insert;\n\n this._drag.ghost?.destroy();\n this._drag.ghost = null;\n this._draggingColumnId = undefined;\n this._dropCaretX = undefined;\n\n try {\n this._containerEl?.releasePointerCapture(ev.pointerId);\n } catch { /* ignore */ }\n\n window.removeEventListener(`pointermove`, onMove);\n window.removeEventListener(`pointerup`, finish);\n window.removeEventListener(`pointercancel`, finish);\n\n if (wasActive && insert !== from) {\n const [moved] = this._columns.splice(from, 1);\n this._columns.splice(insert, 0, moved);\n this._updateColOffsets();\n this._emitColumnsChange(`reorder`);\n this.requestUpdate();\n }\n };\n\n window.addEventListener(`pointermove`, onMove);\n window.addEventListener(`pointerup`, finish);\n window.addEventListener(`pointercancel`, finish);\n }\n\n // ---------------------------------------------------------------------\n // Resize (pattern per data-grid `_onResizePointerDown`)\n // ---------------------------------------------------------------------\n\n private _onResizePointerDown(e: PointerEvent, col: MulticolColumnController): void {\n e.preventDefault();\n e.stopPropagation();\n\n const startX = e.clientX;\n const rawStartW = col.getState().width ?? DEFAULT_COLUMN_WIDTH;\n const startW = Number.isFinite(rawStartW) ? rawStartW : DEFAULT_COLUMN_WIDTH;\n this._resizingColumnId = col.id;\n\n const applyWidth = (clientX: number): number => {\n const w = Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, startW + clientX - startX));\n col.setWidth(w);\n return w;\n };\n\n const onMove = (ev: PointerEvent): void => {\n if (ev.pointerId !== e.pointerId)\n return;\n applyWidth(ev.clientX);\n this._updateColOffsets();\n this.requestUpdate();\n };\n\n const finish = (ev: PointerEvent): void => {\n window.removeEventListener(`pointermove`, onMove);\n window.removeEventListener(`pointerup`, finish);\n window.removeEventListener(`pointercancel`, finish);\n\n // A cancelled pointer restores the starting width\n applyWidth(ev.type === `pointercancel` ? startX : ev.clientX);\n this._resizingColumnId = undefined;\n this._updateColOffsets();\n this._emitColumnsChange(`resize`);\n this.requestUpdate();\n };\n\n window.addEventListener(`pointermove`, onMove);\n window.addEventListener(`pointerup`, finish);\n window.addEventListener(`pointercancel`, finish);\n }\n\n // ---------------------------------------------------------------------\n // Menus\n // ---------------------------------------------------------------------\n\n /** Floats a dropdown menu trigger over `anchorEl` and opens it immediately. */\n #openMenuAt(anchorEl: HTMLElement, placement: `bottom-start` | `bottom-end`, buildMenu: (container: HTMLElement) => void): void {\n const rect = anchorEl.getBoundingClientRect();\n const trigger = document.createElement(`ixfx-menu-trigger`) as MenuTrigger;\n trigger.mode = `dropdown`;\n trigger.tabStop = false;\n trigger.placement = placement;\n trigger.style.position = `fixed`;\n trigger.style.left = `${rect.left}px`;\n trigger.style.top = `${rect.bottom}px`;\n\n const container = document.createElement(`ixfx-menu-container`);\n container.setAttribute(`slot`, `menu`);\n buildMenu(container);\n trigger.appendChild(container);\n\n trigger.addEventListener(`menu-trigger-close`, () => trigger.remove(), { once: true });\n document.body.appendChild(trigger);\n // `openMenu()` reads `.popup` via a @query, which only resolves once Lit has\n // completed the trigger's first render — calling it synchronously right\n // after appendChild silently no-ops because the popup element doesn't exist yet.\n void trigger.updateComplete.then(() => trigger.openMenu());\n }\n\n #categoryToNode(cat: MulticolCategory): TreeNode {\n return {\n item: { key: cat.key, label: cat.label },\n children: cat.children && cat.children.length > 0 ? cat.children.map(c => this.#categoryToNode(c)) : undefined,\n };\n }\n\n private _openCategoryPicker(col: MulticolColumnController, anchorEl: HTMLElement): void {\n this.#openMenuAt(anchorEl, `bottom-start`, (container) => {\n const items = menuFromTreeToElements(this.categories.map(c => this.#categoryToNode(c)), {\n onCommand: (detail) => {\n if (detail.command === undefined)\n return;\n this._changeColumnCategory(col, detail.command);\n },\n });\n for (const el of items) {\n container.appendChild(el);\n }\n for (const item of container.querySelectorAll(`ixfx-menu-item`)) {\n if (item.getAttribute(`command`) === col.categoryKey) {\n item.setAttribute(`disabled`, ``);\n }\n }\n });\n }\n\n #menuItem(label: string, command: string, onCommand?: () => void, iconName?: string): HTMLElement {\n const el = document.createElement(`ixfx-menu-item`);\n el.setAttribute(`command`, command);\n el.setAttribute(`label`, label);\n if (iconName)\n el.setAttribute(`icon-name`, iconName);\n if (onCommand) {\n el.addEventListener(`command`, () => onCommand());\n }\n return el;\n }\n\n private _openBurgerMenu(col: MulticolColumnController, anchorEl: HTMLElement): void {\n this.#openMenuAt(anchorEl, `bottom-end`, (container) => {\n const removeItem = this.#menuItem(`Remove this column`, `remove`, () => this.removeColumn(col.id));\n removeItem.toggleAttribute(`disabled`, this._columns.length <= this.minColumns);\n container.appendChild(removeItem);\n\n const separator = document.createElement(`ixfx-menu-separator`);\n container.appendChild(separator);\n\n const atMax = this.maxColumns > 0 && this._columns.length >= this.maxColumns;\n const usedCats = new Set(this._columns.map(c => c.categoryKey));\n const unused = this.categories.filter(c => !usedCats.has(c.key));\n const canAdd = !atMax && unused.length > 0;\n\n const addSub = document.createElement(`ixfx-menu-sub-trigger`);\n addSub.setAttribute(`label`, `Add column`);\n const addContainer = document.createElement(`ixfx-menu-container`);\n addContainer.setAttribute(`slot`, `submenu`);\n\n const idx = this._columns.findIndex(c => c.id === col.id);\n for (const [label, offset] of [[`Left`, -1], [`Right`, 1]] as const) {\n const item = this.#menuItem(label, `add-${label.toLowerCase()}`, () => {\n this.#insertColumn(unused[0].key, Math.max(0, idx + Math.max(0, offset)));\n });\n item.toggleAttribute(`disabled`, !canAdd);\n addContainer.appendChild(item);\n }\n addSub.appendChild(addContainer);\n container.appendChild(addSub);\n\n const sortSub = document.createElement(`ixfx-menu-sub-trigger`);\n sortSub.setAttribute(`label`, `Sort`);\n const sortContainer = document.createElement(`ixfx-menu-container`);\n sortContainer.setAttribute(`slot`, `submenu`);\n sortContainer.appendChild(this.#menuItem(`Ascending`, `sort-asc`, () => {\n col.setSort(`asc`);\n this._emitColumnsChange(`sort`);\n this.requestUpdate();\n }, col.getState().sort === `asc` ? `check` : undefined));\n sortContainer.appendChild(this.#menuItem(`Descending`, `sort-desc`, () => {\n col.setSort(`desc`);\n this._emitColumnsChange(`sort`);\n this.requestUpdate();\n }, col.getState().sort === `desc` ? `check` : undefined));\n sortSub.appendChild(sortContainer);\n container.appendChild(sortSub);\n\n const grouped = col.getState().grouped;\n container.appendChild(this.#menuItem(grouped ? `Ungroup` : `Group`, `toggle-group`, () => {\n col.setGrouped(!grouped);\n this._emitColumnsChange(`grouping`);\n this.requestUpdate();\n }, grouped ? `check` : undefined));\n });\n }\n\n #insertColumn(categoryKey: string, position: number): void {\n this.addColumn(categoryKey, position);\n }\n\n private _changeColumnCategory(col: MulticolColumnController, categoryKey: string): void {\n const category = this.categories.find(c => c.key === categoryKey);\n if (!category)\n return;\n\n col.setCategory(category);\n this._emitColumnsChange(`category`);\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n // ---------------------------------------------------------------------\n // Selection + data coordination\n // ---------------------------------------------------------------------\n\n private _onColumnSelectionChange(columnId: string, _values: readonly string[]): void {\n const col = this._columns.find(c => c.id === columnId);\n if (!col)\n return;\n\n // Narrow every other column; the changed column keeps its list\n for (const otherCol of this._columns) {\n if (otherCol.id !== columnId) {\n otherCol.requestData(this._buildQuery(otherCol));\n }\n }\n\n const detail: MulticolSelectDetail = {\n columnId,\n columns: this.getSelection(),\n };\n\n this.dispatchEvent(new CustomEvent<MulticolSelectDetail>(`multicol-select`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n\n this.requestUpdate();\n }\n\n private _onColumnRequestData(_columnId: string, _query: MulticolQuery, _signal: AbortSignal): void {\n // Hook for subclasses; the controller drives the provider directly\n }\n\n private _buildQuery(col: MulticolColumnController): MulticolQuery {\n const otherSelections = new Map<string, readonly string[]>();\n\n for (const c of this._columns) {\n if (c.id !== col.id) {\n otherSelections.set(c.id, c.selectedValues);\n }\n }\n\n return {\n columnId: col.id,\n categoryKey: col.categoryKey,\n otherSelections,\n };\n }\n\n private _requeryAllColumns(): void {\n for (const col of this._columns) {\n col.requestData(this._buildQuery(col));\n }\n }\n\n private _syncColumnsWithCategories(): void {\n let changed = false;\n for (const col of this._columns) {\n if (this.categories.some(c => c.key === col.categoryKey))\n continue;\n if (this.categories.length === 0)\n continue;\n col.setCategory(this.categories[0]);\n changed = true;\n }\n if (changed) {\n this._emitColumnsChange(`category`);\n }\n }\n\n private _updateColOffsets(): void {\n const offsets: number[] = [0];\n let sum = 0;\n\n for (const col of this._columns) {\n const rawWidth = col.getState().width ?? DEFAULT_COLUMN_WIDTH;\n // A non-finite width (NaN from a bad measurement/restore) would poison\n // the whole prefix-sum and — since `NaN === NaN` is false — wedge the\n // change guard below into scheduling an update forever.\n const safeWidth = Number.isFinite(rawWidth) ? rawWidth : DEFAULT_COLUMN_WIDTH;\n sum += safeWidth;\n offsets.push(sum);\n }\n\n // Only write back when something changed — unconditional assignment from\n // updated() would schedule an endless chain of updates. The comparison is\n // NaN-safe so a poisoned value can settle instead of looping.\n const unchanged = offsets.length === this._colOffsets.length\n && offsets.every((v, i) => v === this._colOffsets[i] || (Number.isNaN(v) && Number.isNaN(this._colOffsets[i])));\n if (!unchanged)\n this._colOffsets = offsets;\n }\n\n private _emitColumnsChange(reason: MulticolColumnsChangeReason): void {\n this.dispatchEvent(new CustomEvent<MulticolColumnsChangeDetail>(`multicol-columns-change`, {\n detail: {\n columns: this.columns,\n reason,\n },\n bubbles: true,\n composed: true,\n }));\n }\n\n public async autoSizeColumns(options?: { minWidth?: number; maxWidth?: number }): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(() => {\n const minWidth = options?.minWidth ?? MIN_COLUMN_WIDTH;\n const maxWidth = options?.maxWidth ?? MAX_COLUMN_WIDTH;\n\n const measure = (text: string): number => {\n const span = document.createElement(`span`);\n span.style.position = `absolute`;\n span.style.visibility = `hidden`;\n span.style.whiteSpace = `nowrap`;\n span.style.font = getComputedStyle(this).font;\n span.textContent = text;\n document.body.appendChild(span);\n const w = span.getBoundingClientRect().width;\n document.body.removeChild(span);\n // Detached/hidden subtrees (and happy-dom) can yield NaN or 0 —\n // treat non-finite reads as zero so they never poison the width.\n return Number.isFinite(w) ? w : 0;\n };\n\n for (const col of this._columns) {\n const colEl = this.shadowRoot?.querySelector(`[data-col-id=\"${col.id}\"]`);\n if (!colEl)\n continue;\n\n const headerEl = colEl.querySelector(`.column-header`);\n const listerHost = colEl.querySelector(`.lister-host`);\n\n let contentWidth = 0;\n\n if (listerHost) {\n const allLabel = listerHost.querySelector(`.all-label`);\n if (allLabel) {\n contentWidth = Math.max(contentWidth, measure(allLabel.textContent ?? ``));\n }\n\n const groupedLister = listerHost.querySelector(`ixfx-grouped-item-lister`);\n if (groupedLister) {\n const verticalLists = groupedLister.querySelectorAll(`ixfx-vertical-list`);\n for (const vl of verticalLists) {\n const itemEls = vl.querySelectorAll(`li`);\n for (const li of itemEls) {\n const labelEl = li.querySelector(`.item-label`);\n const countEl = li.querySelector(`.count`);\n const labelText = labelEl?.textContent ?? ``;\n const countText = countEl?.textContent ?? ``;\n const combinedText = labelText + countText;\n contentWidth = Math.max(contentWidth, measure(combinedText));\n }\n }\n }\n }\n\n let headerWidth = 0;\n if (headerEl) {\n const labelBtn = headerEl.querySelector(`.column-label`);\n if (labelBtn) {\n const labelTextWidth = measure(labelBtn.textContent ?? ``);\n const btnStyle = getComputedStyle(labelBtn);\n // Empty style reads (detached/hidden subtrees, happy-dom) parse\n // to NaN — coerce to 0 so the sum stays finite.\n const labelBtnPaddingH = (Number.parseFloat(btnStyle.paddingLeft) || 0) + (Number.parseFloat(btnStyle.paddingRight) || 0);\n const burgerBtn = headerEl.querySelector(`.burger-btn`);\n const burgerWidth = burgerBtn ? (Number.parseFloat(getComputedStyle(burgerBtn).width) || 0) : 0;\n const headerStyle = getComputedStyle(headerEl);\n const gap = Number.parseFloat(headerStyle.gap) || 0;\n headerWidth = labelTextWidth + labelBtnPaddingH + burgerWidth + gap;\n }\n }\n\n const padding = 24;\n const extraSpace = 16;\n const neededWidth = Math.max(headerWidth, contentWidth + padding + extraSpace);\n const clampedWidth = Math.max(minWidth, Math.min(maxWidth, Math.ceil(neededWidth)));\n\n // If every measurement came back empty the math above is NaN —\n // skip the column (keep its current width) instead of storing NaN,\n // which would poison offsets and wedge the update loop.\n if (!Number.isFinite(clampedWidth))\n continue;\n col.setWidth(clampedWidth);\n }\n\n this._updateColOffsets();\n this._emitColumnsChange(`resize`);\n this.requestUpdate();\n resolve();\n }, 0);\n });\n }\n}\n","import type { Notification, NotificationRenderer, NotificationRendererHooks } from './types.js';\nimport './notification-pill.js';\n\nexport type PillPosition = `top-left` | `top-middle` | `top-right` | `bottom-left` | `bottom-middle` | `bottom-right`;\nexport type PillQueueDisplay = `list` | `stack`;\n\nexport interface PillSafeArea {\n readonly top?: number;\n readonly right?: number;\n readonly bottom?: number;\n readonly left?: number;\n}\n\nexport interface PillRendererOptions {\n position?: PillPosition;\n /** `list`: one row per message, oldest nearest the anchor edge. `stack`: only the front message is fully shown, the rest peek out behind it. Default `list`. */\n queueDisplay?: PillQueueDisplay;\n /** Extra margin (px) added to the default spacing on each side, letting pills avoid eg. a fixed header/footer/notch. */\n safeArea?: PillSafeArea;\n}\n\ntype PillEntry = {\n element: HTMLElement;\n notification: Notification;\n};\n\ntype Edges = { vertical: `top` | `bottom`; horizontal: `left` | `middle` | `right` };\n\nconst ROW_SPACING = 8;\nconst DEFAULT_ROW_HEIGHT = 40;\nconst STACK_OFFSET_STEP = 4;\nconst STACK_OPACITY_BASE = 0.7;\nconst STACK_OPACITY_DECAY = 0.15;\nconst STACK_OPACITY_MIN = 0.2;\n\nfunction edgesOf(position: PillPosition): Edges {\n const vertical = position.startsWith(`top`) ? `top` : `bottom`;\n const horizontal = position.endsWith(`-left`) ? `left` : position.endsWith(`-right`) ? `right` : `middle`;\n return { vertical, horizontal };\n}\n\nfunction anchorStyles(position: PillPosition, safeArea: PillSafeArea): string {\n const { vertical, horizontal } = edgesOf(position);\n const vMargin = `calc(var(--space-l, 12px) + ${(vertical === `top` ? safeArea.top : safeArea.bottom) ?? 0}px)`;\n let css = `position: fixed; `;\n css += vertical === `top` ? `top: ${vMargin}; bottom: auto; ` : `bottom: ${vMargin}; top: auto; `;\n\n if (horizontal === `left`) {\n const hMargin = `calc(var(--space-l, 12px) + ${safeArea.left ?? 0}px)`;\n css += `left: ${hMargin}; right: auto;`;\n } else if (horizontal === `right`) {\n const hMargin = `calc(var(--space-l, 12px) + ${safeArea.right ?? 0}px)`;\n css += `right: ${hMargin}; left: auto;`;\n } else {\n css += `left: 50%; right: auto;`;\n }\n return css;\n}\n\n/** Entry-animation starting transform: pills slide in from the edge they're anchored to. */\nfunction entryTransform(edges: Edges): string {\n const dy = edges.vertical === `top` ? -20 : 20;\n if (edges.horizontal === `middle`) {\n return `translateX(-50%) translate(0, ${dy}px)`;\n }\n const dx = edges.horizontal === `left` ? -20 : 20;\n return `translate(${dx}px, ${dy}px)`;\n}\n\nfunction restingTransform(edges: Edges, dx: number, dy: number): string {\n if (edges.horizontal === `middle`) {\n return `translateX(-50%) translate(${dx}px, ${dy}px)`;\n }\n return `translate(${dx}px, ${dy}px)`;\n}\n\nexport function createPillRenderer(options: PillRendererOptions = {}): NotificationRenderer {\n const position: PillPosition = options.position ?? `top-right`;\n const queueDisplay: PillQueueDisplay = options.queueDisplay ?? `list`;\n const safeArea: PillSafeArea = options.safeArea ?? {};\n const edges = edgesOf(position);\n\n let container: HTMLDivElement | null = null;\n let hooks: NotificationRendererHooks | null = null;\n const pills: Map<string, PillEntry> = new Map();\n let rowHeight = DEFAULT_ROW_HEIGHT;\n let measured = false;\n\n function ensureContainer(): HTMLDivElement {\n if (container)\n return container;\n\n container = document.createElement(`div`);\n container.className = `ixfx-notification-container`;\n container.setAttribute(`role`, `region`);\n container.setAttribute(`aria-label`, `Notifications`);\n document.body.appendChild(container);\n return container;\n }\n\n function updateAttributes(el: HTMLElement, notification: Notification): void {\n el.setAttribute(`notification-type`, notification.type);\n el.setAttribute(`message`, notification.message);\n if (notification.icon) {\n el.setAttribute(`icon`, notification.icon);\n } else {\n el.removeAttribute(`icon`);\n }\n }\n\n function createPillElement(notification: Notification): HTMLElement {\n const el = document.createElement(`ixfx-notification-pill`) as HTMLElement;\n el.setAttribute(`notification-id`, notification.id);\n el.style.cssText = anchorStyles(position, safeArea);\n updateAttributes(el, notification);\n\n el.style.opacity = `0`;\n el.style.transform = entryTransform(edges);\n\n el.addEventListener(`pill-tap`, (e: Event) => {\n const customEvent = e as CustomEvent<{ id: string }>;\n hooks?.onTap(customEvent.detail.id);\n });\n\n return el;\n }\n\n function measureRowHeight(el: HTMLElement): void {\n if (measured)\n return;\n requestAnimationFrame(() => {\n const height = el.getBoundingClientRect().height;\n if (height > 0) {\n rowHeight = height;\n measured = true;\n }\n });\n }\n\n /** Positions every currently-visible pill for its rank in `order` (index 0 = front/oldest). */\n function applyLayout(order: readonly Notification[]): void {\n const total = order.length;\n order.forEach((notification, index) => {\n const entry = pills.get(notification.id);\n if (!entry)\n return;\n\n const el = entry.element;\n let dx = 0;\n let dy = 0;\n let opacity = 1;\n let pointerEvents = `auto`;\n let filter = `none`;\n\n if (queueDisplay === `list`) {\n const step = index * (rowHeight + ROW_SPACING);\n dy = edges.vertical === `top` ? step : -step;\n } else {\n const step = index * STACK_OFFSET_STEP;\n dy = edges.vertical === `top` ? step : -step;\n dx = edges.horizontal === `left` ? step : edges.horizontal === `right` ? -step : 0;\n if (index > 0) {\n const hintIndex = index - 1;\n opacity = Math.max(STACK_OPACITY_MIN, STACK_OPACITY_BASE - hintIndex * STACK_OPACITY_DECAY);\n pointerEvents = `none`;\n filter = `saturate(0.6)`;\n }\n }\n\n el.style.transition = `opacity 0.2s ease-out, transform 0.2s ease-out`;\n el.style.opacity = `${opacity}`;\n el.style.zIndex = `${total - index}`;\n el.style.pointerEvents = pointerEvents;\n el.style.filter = filter;\n el.style.transform = restingTransform(edges, dx, dy);\n });\n }\n\n function dismiss(id: string): void {\n const entry = pills.get(id);\n if (!entry)\n return;\n\n const el = entry.element as HTMLElement;\n el.setAttribute(`dismissing`, `true`);\n\n const cleanup = () => {\n el.removeEventListener(`transitionend`, cleanup);\n el.remove();\n pills.delete(id);\n\n if (container && pills.size === 0) {\n container.remove();\n container = null;\n measured = false;\n rowHeight = DEFAULT_ROW_HEIGHT;\n }\n };\n\n el.addEventListener(`transitionend`, cleanup);\n setTimeout(cleanup, 300);\n }\n\n function setNotifications(notifications: Notification[], _queueSize: number): void {\n const cont = ensureContainer();\n const idsToKeep = new Set(notifications.map(n => n.id));\n\n for (const notification of notifications) {\n const existing = pills.get(notification.id);\n if (existing) {\n existing.notification = notification;\n updateAttributes(existing.element, notification);\n continue;\n }\n\n const el = createPillElement(notification);\n pills.set(notification.id, { element: el, notification });\n cont.appendChild(el);\n measureRowHeight(el);\n }\n\n for (const [id] of pills) {\n if (!idsToKeep.has(id)) {\n dismiss(id);\n }\n }\n\n requestAnimationFrame(() => applyLayout(notifications));\n }\n\n return {\n attach(newHooks: NotificationRendererHooks): void {\n hooks = newHooks;\n },\n\n detach(): void {\n for (const [id] of pills) {\n dismiss(id);\n }\n if (container) {\n container.remove();\n container = null;\n }\n },\n\n setNotifications,\n };\n}\n","import type {\n Notification,\n NotificationContent,\n NotificationRenderer,\n NotifierOptions,\n} from './types.js';\nimport { createPillRenderer } from './pill-renderer.js';\n\ntype Managed = { -readonly [K in keyof Notification]: Notification[K] } & { timer: number | null; wasQueued: boolean };\n\nconst options: {\n renderer: NotificationRenderer;\n timeout: number;\n timeoutError: number;\n queue: boolean;\n queueSize: number;\n tapBehaviour: `none` | `dismiss`;\n tapHandlerDefault: NotifierOptions[`tapHandlerDefault`];\n} = {\n renderer: undefined as unknown as NotificationRenderer,\n timeout: 4000,\n timeoutError: 8000,\n queue: true,\n queueSize: 3,\n tapBehaviour: `dismiss`,\n tapHandlerDefault: undefined,\n};\n\n/** Rank-ordered, index 0 = oldest/first (next to be evicted or timed out). Length never exceeds queueSize (or 1 when queuing is disabled). */\nconst visible: Managed[] = [];\nlet renderer: NotificationRenderer | null = null;\nlet defaultRenderer: NotificationRenderer | null = null;\n\nfunction getDefaultRenderer(): NotificationRenderer {\n defaultRenderer ??= createPillRenderer({ position: `top-right` });\n return defaultRenderer;\n}\n\nfunction getRenderer(): NotificationRenderer {\n return renderer ?? getDefaultRenderer();\n}\n\nfunction syncRenderer(): void {\n getRenderer().setNotifications([...visible], options.queueSize);\n}\n\nfunction clearTimer(managed: Managed): void {\n if (managed.timer !== null) {\n clearTimeout(managed.timer);\n managed.timer = null;\n }\n}\n\n/**\n * A message shown alone takes the full timeout. A message that joined a\n * non-empty queue at arrival time is permanently \"wasQueued\" and gets\n * 1/queueSize of the timeout once it reaches the front. The timer for a\n * given message is only ever started once - when it first becomes front.\n */\nfunction startTimer(managed: Managed): void {\n const base = managed.type === `error` ? options.timeoutError : options.timeout;\n const duration = managed.wasQueued ? base / options.queueSize : base;\n managed.timer = window.setTimeout(dismiss, duration, managed.id);\n}\n\nfunction ensureFrontTimer(): void {\n const front = visible[0];\n if (front && front.timer === null) {\n startTimer(front);\n }\n}\n\nexport const NotificationManager = {\n configure(opts: NotifierOptions): void {\n if (opts.renderer !== undefined) {\n const old = renderer;\n old?.detach?.();\n renderer = opts.renderer;\n renderer.attach({\n onTap(id: string) {\n const notification = visible.find(n => n.id === id);\n if (!notification)\n return;\n if (notification.onTap) {\n notification.onTap(id);\n } else {\n options.tapHandlerDefault?.(notification);\n }\n if (options.tapBehaviour === `dismiss`) {\n dismiss(id);\n }\n },\n });\n syncRenderer();\n }\n if (opts.timeout !== undefined)\n options.timeout = opts.timeout;\n if (opts.timeoutError !== undefined)\n options.timeoutError = opts.timeoutError;\n if (opts.queue !== undefined)\n options.queue = opts.queue;\n if (opts.queueSize !== undefined) {\n options.queueSize = Math.max(1, opts.queueSize);\n while (visible.length > options.queueSize) {\n clearTimer(visible.shift()!);\n }\n ensureFrontTimer();\n syncRenderer();\n }\n if (opts.tapBehaviour !== undefined)\n options.tapBehaviour = opts.tapBehaviour;\n if (opts.tapHandlerDefault !== undefined)\n options.tapHandlerDefault = opts.tapHandlerDefault;\n },\n\n notify(content: NotificationContent): string {\n const id = crypto.randomUUID();\n const now = Date.now();\n const icon = content.icon ?? (content.type === `error` ? `error` : undefined);\n const managed: Managed = {\n ...content,\n icon,\n id,\n createdAt: now,\n updatedAt: now,\n timer: null,\n wasQueued: false,\n };\n\n if (options.queue) {\n if (visible.length >= options.queueSize) {\n clearTimer(visible.shift()!);\n }\n managed.wasQueued = visible.length > 0;\n visible.push(managed);\n } else {\n while (visible.length > 0) {\n clearTimer(visible.pop()!);\n }\n visible.push(managed);\n }\n\n ensureFrontTimer();\n syncRenderer();\n return id;\n },\n\n update(id: string, content: Partial<NotificationContent>): void {\n const managed = visible.find(n => n.id === id);\n if (!managed)\n return;\n\n Object.assign(managed, content);\n managed.updatedAt = Date.now();\n\n if (visible[0] === managed) {\n clearTimer(managed);\n startTimer(managed);\n }\n syncRenderer();\n },\n\n dismiss(id: string): void {\n dismiss(id);\n },\n\n dismissAll(): void {\n for (const m of visible)\n clearTimer(m);\n visible.length = 0;\n syncRenderer();\n },\n};\n\nfunction dismiss(id: string): void {\n const idx = visible.findIndex(m => m.id === id);\n if (idx === -1)\n return;\n\n clearTimer(visible.splice(idx, 1)[0]);\n ensureFrontTimer();\n syncRenderer();\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { DragGhost } from '../util/drag-ghost.js';\nimport type { PanelElement, PanelOrientation, PanelToggleInteraction, PanelVariant } from './panel.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\n\nexport type PanelGroupOrientation = `horizontal` | `vertical`;\n\nexport interface PanelGroupReorderDetail {\n readonly fromIndex: number;\n readonly toIndex: number;\n readonly panel: PanelElement;\n}\n\nexport type PanelGroupReorderEvent = CustomEvent<PanelGroupReorderDetail>;\n\nexport interface PanelGroupElementEventMap {\n reorder: PanelGroupReorderEvent;\n}\n\n/** Pointer movement threshold (px) before a press becomes a drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\n/**\n * Pure helper: nearest gap index for a pointer position along one axis.\n * `edges` are the [start, end] of each sibling (excluding the drag source),\n * in DOM order. Returns 0..edges.length.\n */\nexport function panelGapIndex(edges: ReadonlyArray<readonly [number, number]>, pos: number): number {\n let bestGap = 0;\n let bestDist = Number.POSITIVE_INFINITY;\n for (let i = 0; i < edges.length; i++) {\n const [start, end] = edges[i];\n const mid = (start + end) / 2;\n if (pos < mid) {\n const d = Math.abs(pos - start);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i;\n }\n } else {\n const d = Math.abs(pos - end);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i + 1;\n }\n }\n }\n return bestGap;\n}\n\nlet panelGhostStylesInjected = false;\n\n/**\n * Global ghost styling so the drag preview matches `ixfx-titlebar` chrome\n * (font, colours, padding). Injected once; the ghost lives outside shadow DOM\n * (body/theme container) so component styles cannot reach it.\n */\nfunction injectPanelGhostStyles(): void {\n if (panelGhostStylesInjected) {\n return;\n }\n panelGhostStylesInjected = true;\n const style = document.createElement(`style`);\n style.textContent = `\n .ixfx-drag-ghost.ixfx-panel-group-ghost {\n padding: var(--space-s, 8px) var(--space-m, 16px);\n background: var(--surface-4);\n color: var(--surface-3-text);\n border: none;\n border-radius: var(--radius-s, 4px);\n font-family: var(--font-family);\n font-size: var(--text-m);\n font-weight: var(--font-weight-bold, 600);\n min-height: 2em;\n user-select: none;\n -webkit-user-select: none;\n }\n .ixfx-drag-ghost.ixfx-panel-group-ghost ixfx-icon {\n width: 1.25em;\n height: 1.25em;\n flex-shrink: 0;\n }\n `;\n document.head.appendChild(style);\n}\n\n@customElement(`ixfx-panel-group`)\nexport class PanelGroupElement extends LitElement {\n @property({ type: String, reflect: true }) orientation: PanelGroupOrientation = `horizontal`;\n @property({ type: String }) variant: PanelVariant = `titlebar`;\n @property({ type: String, attribute: `toggle-interaction` }) toggleInteraction: PanelToggleInteraction = `implicit`;\n @property({ type: Boolean }) collapsible = true;\n @property({ type: Boolean, attribute: `accordion`, reflect: true }) accordion = false;\n @property({ type: Boolean, attribute: `allow-reorder`, reflect: true }) allowReorder = false;\n /** Explicit gap between panels. When unset, `--group-gap` (falling back to `--space-l`) controls the gap. */\n @property() gap?: string;\n\n @queryAssignedElements({ slot: `` }) private _panels!: PanelElement[];\n\n private _dragState: {\n pointerId: number;\n source: PanelElement;\n fromIndex: number;\n startX: number;\n startY: number;\n active: boolean;\n ghost: DragGhost | null;\n gapIndex: number | undefined;\n } | null = null;\n\n private _suppressNextClick = false;\n\n private _onPanelToggle(e: Event) {\n const panel = e.target as PanelElement;\n if (panel.collapsed) {\n return;\n }\n\n if (!this.accordion) {\n return;\n }\n\n for (const p of this._panels) {\n if (p !== panel) {\n p.collapsed = true;\n }\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Capture phase so we can swallow the trailing click after a real reorder\n // before it reaches the titlebar toggle handler inside ixfx-panel.\n this.addEventListener(`click`, this._onClickCapture, true);\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener(`click`, this._onClickCapture, true);\n if (this._dragState) {\n this._abortDrag();\n this._endDrag(this._dragState.pointerId);\n }\n super.disconnectedCallback();\n }\n\n protected override firstUpdated(): void {\n if (this.gap !== undefined) {\n this.style.setProperty(`--group-gap`, this.gap);\n }\n this.updateComplete.then(() => {\n this._propagateAll();\n });\n }\n\n protected override updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has(`gap`)) {\n if (this.gap !== undefined) {\n this.style.setProperty(`--group-gap`, this.gap);\n } else {\n this.style.removeProperty(`--group-gap`);\n }\n }\n if (changed.has(`variant`) || changed.has(`toggleInteraction`) || changed.has(`orientation`) || changed.has(`collapsible`)) {\n this.updateComplete.then(() => {\n this._propagateAll();\n });\n }\n }\n\n private _propagateAll(): void {\n const invertedOrientation: PanelOrientation\n = this.orientation === `horizontal` ? `vertical` : `horizontal`;\n\n for (const panel of this._panels) {\n panel.setAttribute(`variant`, this.variant);\n panel.setAttribute(`toggle-interaction`, this.toggleInteraction);\n panel.setAttribute(`orientation`, invertedOrientation);\n if (this.collapsible) {\n panel.setAttribute(`collapsible`, ``);\n } else {\n panel.removeAttribute(`collapsible`);\n }\n }\n }\n\n private _onSlotChange(): void {\n this.updateComplete.then(() => {\n this._propagateAll();\n });\n }\n\n private _onClickCapture = (event: Event): void => {\n if (!this._suppressNextClick) {\n return;\n }\n this._suppressNextClick = false;\n event.preventDefault();\n event.stopPropagation();\n };\n\n private _onKeyDown = (event: KeyboardEvent): void => {\n const state = this._dragState;\n if (event.key !== `Escape` || !state?.active) {\n return;\n }\n event.preventDefault();\n const pointerId = state.pointerId;\n this._abortDrag();\n this._endDrag(pointerId);\n };\n\n /**\n * Walk composedPath for the nearest ixfx-panel, requiring the press to have\n * gone through an ixfx-titlebar (titlebar-anywhere drag). Bails when the\n * path crosses interactive chrome (buttons/links/inputs/toolbar/caret/close)\n * so those controls always win over dragging.\n */\n private _findDragTarget(event: PointerEvent): PanelElement | null {\n if (!this.allowReorder) {\n return null;\n }\n const path = event.composedPath();\n let panel: PanelElement | null = null;\n let viaTitlebar = false;\n for (const node of path) {\n if (!(node instanceof HTMLElement)) {\n continue;\n }\n const tag = node.tagName;\n if (tag === `BUTTON` || tag === `A` || tag === `INPUT` || tag === `SELECT` || tag === `TEXTAREA`) {\n return null;\n }\n if (node.classList.contains(`toolbar`) || node.classList.contains(`close-btn`) || node.classList.contains(`caret-btn`)) {\n return null;\n }\n if (node.hasAttribute?.(`slot`) && node.getAttribute(`slot`) === `toolbar`) {\n return null;\n }\n if (tag === `IXFX-TITLEBAR`) {\n viaTitlebar = true;\n }\n if (!panel && tag === `IXFX-PANEL`) {\n panel = node as PanelElement;\n }\n }\n if (!panel || !viaTitlebar) {\n return null;\n }\n return panel;\n }\n\n private _onPointerDown = (event: PointerEvent): void => {\n if (!this.allowReorder || event.button !== 0) {\n return;\n }\n const target = this._findDragTarget(event);\n if (!target?.parentNode) {\n return;\n }\n const fromIndex = Array.prototype.indexOf.call(target.parentNode.children, target);\n if (fromIndex < 0) {\n return;\n }\n // Don't capture yet — capturing on pointerdown would redirect the trailing\n // click to the capture target and break the normal titlebar toggle press.\n // Capture only once the drag activates.\n this._dragState = {\n pointerId: event.pointerId,\n source: target,\n fromIndex,\n startX: event.clientX,\n startY: event.clientY,\n active: false,\n ghost: null,\n gapIndex: undefined,\n };\n window.addEventListener(`pointermove`, this._onPointerMove);\n window.addEventListener(`pointerup`, this._onPointerUp);\n window.addEventListener(`pointercancel`, this._onPointerCancel);\n };\n\n private _onPointerMove = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId) {\n return;\n }\n const distance = Math.hypot(event.clientX - state.startX, event.clientY - state.startY);\n if (!state.active) {\n if (distance < DRAG_THRESHOLD_PX) {\n return;\n }\n this._beginDrag(event);\n }\n state.ghost?.move(event.clientX, event.clientY);\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n if (gap !== state.gapIndex) {\n state.gapIndex = gap;\n this.requestUpdate();\n }\n };\n\n private _onPointerUp = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId) {\n return;\n }\n if (state.active) {\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n this._commitDrag(state.source, state.fromIndex, gap);\n }\n this._endDrag(event.pointerId);\n };\n\n private _onPointerCancel = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId) {\n return;\n }\n this._abortDrag();\n this._endDrag(event.pointerId);\n };\n\n private _beginDrag(event: PointerEvent): void {\n const state = this._dragState;\n if (!state || state.active) {\n return;\n }\n try {\n this.setPointerCapture(event.pointerId);\n } catch {\n // Fall through — window listeners still catch move/up.\n }\n state.active = true;\n // `dragging` kills text selection for the gesture (see styles).\n this.setAttribute(`dragging`, ``);\n state.source.setAttribute(`drag-source`, ``);\n state.ghost = this._createGhost(state.source);\n state.ghost?.move(event.clientX, event.clientY);\n }\n\n private _abortDrag(): void {\n const state = this._dragState;\n if (!state) {\n return;\n }\n state.source.removeAttribute(`drag-source`);\n if (state.gapIndex !== undefined) {\n state.gapIndex = undefined;\n this.requestUpdate();\n }\n }\n\n private _endDrag(pointerId: number): void {\n const state = this._dragState;\n if (!state) {\n return;\n }\n state.ghost?.destroy();\n state.ghost = null;\n this.removeAttribute(`dragging`);\n this._dragState = null;\n window.removeEventListener(`pointermove`, this._onPointerMove);\n window.removeEventListener(`pointerup`, this._onPointerUp);\n window.removeEventListener(`pointercancel`, this._onPointerCancel);\n try {\n this.releasePointerCapture(pointerId);\n } catch { /* already released */ }\n this.requestUpdate();\n }\n\n private _commitDrag(source: PanelElement, fromIndex: number, gapIndex: number | undefined): void {\n source.removeAttribute(`drag-source`);\n // Gap is an index into the without-source panel list; resolve the reference\n // node from that list, then measure the public indices against the real\n // light-DOM children (which may include non-panel elements).\n const siblings = (this._panels ?? []).filter(el => el !== source);\n const target = gapIndex === undefined\n ? siblings.length\n : Math.max(0, Math.min(gapIndex, siblings.length));\n const parent = source.parentNode;\n if (!parent) {\n return;\n }\n const ref = siblings[target] ?? null;\n parent.insertBefore(source, ref);\n const toIndex = Array.prototype.indexOf.call(parent.children, source);\n if (toIndex === fromIndex) {\n return;\n }\n // A real reorder happened — swallow the trailing click so the titlebar\n // implicit toggle doesn't also collapse/expand the dragged panel.\n this._suppressNextClick = true;\n this.dispatchEvent(new CustomEvent<PanelGroupReorderDetail>(`reorder`, {\n bubbles: true,\n composed: true,\n detail: { fromIndex, toIndex, panel: source },\n }));\n }\n\n private _createGhost(source: PanelElement): DragGhost | null {\n // Mirror ixfx-titlebar's title-text-wrapper: icon + title with 1ch indent.\n const content = document.createElement(`span`);\n content.style.display = `inline-flex`;\n content.style.alignItems = `center`;\n content.style.padding = `0 var(--space-s, 8px)`;\n content.style.minWidth = `0`;\n if (source.iconName) {\n const icon = document.createElement(`ixfx-icon`) as HTMLElement & { name: string };\n icon.name = source.iconName;\n content.appendChild(icon);\n }\n const label = document.createElement(`span`);\n label.textContent = (source.title || (source.textContent ?? ``).trim()).slice(0, 60);\n label.style.paddingLeft = `1ch`;\n label.style.overflow = `hidden`;\n label.style.textOverflow = `ellipsis`;\n label.style.whiteSpace = `nowrap`;\n content.appendChild(label);\n try {\n injectPanelGhostStyles();\n return createDragGhost({ anchor: source, content, className: `ixfx-panel-group-ghost` });\n } catch {\n return null;\n }\n }\n\n /**\n * Nearest panel gap to the pointer, ignoring the drag source.\n * The perpendicular axis is ignored — the pointer always resolves to a gap.\n */\n private _computeGapIndex(clientX: number, clientY: number): number | undefined {\n const state = this._dragState;\n if (!state) {\n return undefined;\n }\n const siblings = (this._panels ?? []).filter(el => el !== state.source);\n if (siblings.length === 0) {\n return 0;\n }\n const useX = this.orientation === `horizontal`;\n const pos = useX ? clientX : clientY;\n const edges = siblings.map((el) => {\n const rect = el.getBoundingClientRect();\n return [useX ? rect.left : rect.top, useX ? rect.right : rect.bottom] as const;\n });\n return panelGapIndex(edges, pos);\n }\n\n private _computeCaretStyle(): string | undefined {\n const state = this._dragState;\n if (!state?.active || state.gapIndex === undefined) {\n return undefined;\n }\n const siblings = (this._panels ?? []).filter(el => el !== state.source);\n if (siblings.length === 0) {\n return undefined;\n }\n const hostRect = this.getBoundingClientRect();\n if (!hostRect) {\n return undefined;\n }\n const gap = Math.max(0, Math.min(state.gapIndex, siblings.length));\n const rect = gap < siblings.length\n ? siblings[gap].getBoundingClientRect()\n : siblings[siblings.length - 1].getBoundingClientRect();\n if (this.orientation === `horizontal`) {\n const x = (gap < siblings.length ? rect.left : rect.right) - hostRect.left;\n return `transform: translate(${x - 1}px, 0); width: 2px; height: ${hostRect.height}px;`;\n }\n const y = (gap < siblings.length ? rect.top : rect.bottom) - hostRect.top;\n return `transform: translate(0, ${y - 1}px); width: ${hostRect.width}px; height: 2px;`;\n }\n\n protected override render() {\n const caretStyle = this._computeCaretStyle();\n return html`\n <slot\n @toggle=${this._onPanelToggle}\n @slotchange=${this._onSlotChange}\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n ></slot>\n ${caretStyle ? html`<div class=\"drop-caret\" style=${caretStyle}></div>` : nothing}\n `;\n }\n\n static override styles = css`\n :host {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--group-gap, var(--space-l));\n }\n\n :host([orientation=\"horizontal\"]) {\n flex-direction: row;\n align-items: flex-start;\n flex-wrap: wrap;\n }\n\n :host([orientation=\"vertical\"]) {\n flex-direction: column;\n }\n\n ::slotted(ixfx-panel) {\n flex-shrink: 1;\n }\n\n :host([orientation=\"horizontal\"]) ::slotted(ixfx-panel) {\n flex-basis: content;\n min-width: 0;\n }\n\n :host([allow-reorder]) ::slotted(ixfx-panel) {\n cursor: grab;\n }\n\n :host([allow-reorder]) ::slotted(ixfx-panel[drag-source]) {\n cursor: grabbing;\n opacity: 0.4;\n }\n\n /* While dragging, suppress text selection inside the panels. */\n :host([dragging]),\n :host([dragging]) ::slotted(*) {\n user-select: none;\n -webkit-user-select: none;\n }\n\n :host([dragging]) ::slotted(ixfx-panel) {\n cursor: grabbing;\n }\n\n .drop-caret {\n position: absolute;\n top: 0;\n left: 0;\n background: var(--accent);\n border-radius: 1px;\n pointer-events: none;\n z-index: 1;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-panel-group': PanelGroupElement;\n }\n}\n\nexport interface PanelGroupElement {\n addEventListener: (<K extends keyof PanelGroupElementEventMap>(\n type: K,\n listener: (this: PanelGroupElement, event: PanelGroupElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","export type DragLogicCoordinates = {\n client: { x: number; y: number };\n offset: { x: number; y: number };\n};\nexport type DragLogicHandler = {\n progress: (current: DragLogicCoordinates, start: DragLogicCoordinates) => void;\n complete: (final: DragLogicCoordinates, start: DragLogicCoordinates) => void;\n};\n\nfunction getCoordinates(event: PointerEvent): DragLogicCoordinates {\n return {\n client: { x: event.clientX, y: event.clientY },\n offset: { x: event.offsetX, y: event.offsetY },\n };\n}\n\nexport function dragLogicStart(downEvent: PointerEvent, handler: DragLogicHandler) {\n const start = getCoordinates(downEvent);\n const onMove = (event: PointerEvent) => {\n handler.progress(\n getCoordinates(event),\n start,\n );\n };\n\n const onUp = (event: PointerEvent) => {\n document.removeEventListener(`pointermove`, onMove);\n document.removeEventListener(`pointerup`, onUp);\n handler.complete(\n getCoordinates(event),\n start,\n );\n };\n\n document.addEventListener(`pointermove`, onMove);\n document.addEventListener(`pointerup`, onUp);\n}\n","export function near(target: number, range: number) {\n const min = target - range;\n const max = target + range;\n return (v: number) => (v >= min && v <= max);\n}\n","import type { NumberScaler } from \"@ixfx/numbers\";\nimport type { PropertyValues } from \"lit\";\nimport type { TooltipOrientations } from \"../util/tooltip.js\";\nimport { clamper, scaler } from \"@ixfx/numbers\";\nimport { css, html, LitElement, nothing } from \"lit\";\nimport { eventOptions, property } from \"lit/decorators.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { tooltipValueStyles } from \"../styles/tooltip.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport { dragLogicStart } from \"../util/drag.js\";\n// import type { ClampFn } from \"../util/clamp.js\";\nimport { near } from \"../util/near.js\";\n\nexport type Endpoints = `a` | `b`;\n\nexport type CrossoverBehaviour = `stop` | `allow`;\n\nexport type ResizeMode = `dual` | `none` | `bipolar` | `bipolar-flex`;\n\nexport type RangeMultiInputDetail = {\n readonly a: number;\n readonly b: number;\n readonly changed: `a` | `b` | `both`;\n};\n\nexport type RangeMultiInputEvent = CustomEvent<RangeMultiInputDetail>;\n\n/**\n *\n * Attributes\n * crossover: How thumbs can cross over. Default: 'allow' ('allow'/'stop')\n * a/b: Initial A/B values on 0...100 scale\n * step: Increments of input on 0...100 scale. Use 'any' for maximum precision. Default: 1 (number|'any')\n * tooltip: Whether tooltip is shown. Default: true (boolean)\n * tooltip-orientation: Orientation of tooltip if used. Default: 'top' ('top'|'right')\n *\n * CSS variables\n * --range-background: AccentColor\n * --range-height: 1.5em;\n * --range-thickness: 1em;\n * --thumb-background: ButtonFace;\n * --thumb-radius: 50%;\n * --thumb-width: 1em;\n * --thumb-height: 1em;\n */\n@customElement(`ixfx-range-multi`)\nexport class RangeMultiElement extends LitElement {\n @property({ type: Boolean })\n tooltip = true;\n\n @property({ type: String, attribute: `tooltip-orientation` })\n tooltipOrientation: TooltipOrientations = `top`;\n\n @property({ type: String })\n crossover: CrossoverBehaviour = `allow`;\n\n @property({ type: String, attribute: `resize-mode` })\n resizeMode: ResizeMode = `dual`;\n\n @property({ type: String, reflect: true })\n orientation: `horizontal` | `vertical` = `horizontal`;\n\n @property()\n step: number | `any` = 1;\n\n @property({ type: Number })\n a = 0;\n\n @property({ type: Number })\n b = 50;\n\n #userMax = 100;\n #userMin = 0;\n\n #scaleTo100: NumberScaler = (v: number) => v;\n #scaleFrom100: NumberScaler = (v: number) => v;\n #userClamp: NumberScaler = (v: number) => v;\n\n #updateScale() {\n this.#scaleTo100 = scaler(this.#userMin, this.#userMax, 0, 100);\n this.#scaleFrom100 = scaler(0, 100, this.#userMin, this.#userMax);\n this.#userClamp = clamper(this.#userMin, this.#userMax);\n this.a = this.#userClamp(this.a);\n this.b = this.#userClamp(this.b);\n }\n\n @property({ type: Number })\n set max(v: number) {\n this.#userMax = v;\n this.#updateScale();\n }\n\n get max() {\n return this.#userMax;\n }\n\n @property({ type: Number })\n set min(v: number) {\n this.#userMin = v;\n this.#updateScale();\n }\n\n get min() {\n return this.#userMin;\n }\n\n valuesAtPointerDown: undefined | { a: number; b: number };\n draggingThumb: `a` | `b` | `none` = `none`;\n\n @eventOptions({ capture: true })\n _onInput(event: Event) {\n event.stopPropagation();\n const t = event.target as HTMLInputElement;\n const v = this.#scaleFrom100(t.valueAsNumber);\n const which = t.id as Endpoints;\n let a = this.a;\n let b = this.b;\n\n if (this.resizeMode === `none`) {\n const rawDelta = v - (which === `a` ? this.a : this.b);\n let panDelta = rawDelta;\n const newA = this.a + panDelta;\n const newB = this.b + panDelta;\n if (newA < this.min) {\n panDelta = this.min - this.a;\n }\n if (newB > this.max) {\n panDelta = this.max - this.b;\n }\n\n if (panDelta === 0) {\n t.valueAsNumber = this.#scaleTo100(which === `a` ? this.a : this.b);\n return;\n }\n\n a = this.a + panDelta;\n b = this.b + panDelta;\n } else if (this.resizeMode === `bipolar`) {\n let newA: number;\n let newB: number;\n if (which === `a`) {\n const delta = v - this.a;\n newA = v;\n newB = this.b - delta;\n } else {\n const delta = v - this.b;\n newA = this.a - delta;\n newB = v;\n }\n\n if (newA < this.min || newB > this.max || newA > this.max || newB < this.min) {\n t.valueAsNumber = this.#scaleTo100(which === `a` ? this.a : this.b);\n return;\n }\n\n a = newA;\n b = newB;\n } else if (this.resizeMode === `bipolar-flex`) {\n let newA: number;\n let newB: number;\n if (which === `a`) {\n newA = v;\n if (this.b <= this.min) {\n newB = this.min;\n } else if (this.b >= this.max) {\n newB = this.max;\n } else {\n const delta = v - this.a;\n newB = this.b - delta;\n }\n } else {\n newB = v;\n if (this.a <= this.min) {\n newA = this.min;\n } else if (this.a >= this.max) {\n newA = this.max;\n } else {\n const delta = v - this.b;\n newA = this.a - delta;\n }\n }\n\n if (newA < this.min)\n newA = this.min;\n if (newA > this.max)\n newA = this.max;\n if (newB < this.min)\n newB = this.min;\n if (newB > this.max)\n newB = this.max;\n\n if (newA > newB) {\n t.valueAsNumber = this.#scaleTo100(which === `a` ? this.a : this.b);\n return;\n }\n\n a = newA;\n b = newB;\n } else {\n if (which === `a`) {\n if (v > this.b && this.crossover === `stop`) {\n t.valueAsNumber = this.#scaleTo100(this.a);\n } else {\n a = v;\n }\n } else if (which === `b`) {\n if (v < a && this.crossover === `stop`) {\n t.valueAsNumber = this.#scaleTo100(this.b);\n } else {\n b = v;\n }\n } else {\n throw new Error(`Expected 'a' or 'b', got: '${t.id}'`);\n }\n }\n\n this.setPoles(a, b);\n }\n\n setPoles(a: number, b: number) {\n const aDiff = a !== this.a;\n const bDiff = b !== this.b;\n // a = clamp(a, this.min, this.max);\n // b = clamp(b, this.min, this.max);\n this.a = this.#userClamp(a);\n this.b = this.#userClamp(b);\n this.dispatchEvent(new CustomEvent<RangeMultiInputDetail>(`input`, {\n detail: { a: this.a, b: this.b, changed: aDiff && bDiff ? `both` : aDiff ? `a` : `b` },\n }));\n }\n\n @eventOptions({ capture: true })\n _onPointerDown(event: PointerEvent) {\n const startA = this.a;\n const startB = this.b;\n this.valuesAtPointerDown = { a: startA, b: startB };\n const rect = (event.target as HTMLInputElement).getBoundingClientRect();\n const isVertical = this.orientation === `vertical`;\n const dim = isVertical ? rect.height : rect.width;\n const valuePerPix = dim / (this.max - this.min);\n const pos = isVertical ? event.offsetY : event.offsetX;\n\n const valueFromPos = (p: number): number => {\n return isVertical ? this.max - p * valuePerPix : p * valuePerPix;\n };\n const posFromValue = (v: number): number => {\n return isVertical ? dim - (v * valuePerPix) : v * valuePerPix;\n };\n\n const aPosPx = posFromValue(startA);\n const bPosPx = posFromValue(startB);\n\n const outsideClick = isVertical\n ? (this.b < this.a ? pos > bPosPx : pos < bPosPx)\n || (this.b < this.a ? pos < aPosPx : pos > aPosPx)\n : (this.b < this.a && pos < bPosPx) || (this.b > this.a && pos > bPosPx)\n || (this.a < this.b && pos < aPosPx) || (this.a > this.b && pos > aPosPx);\n\n if (outsideClick) {\n if (this.resizeMode === `none` || this.resizeMode === `bipolar` || this.resizeMode === `bipolar-flex`) {\n const newB = valueFromPos(pos);\n let panDelta = newB - this.b;\n if (this.a + panDelta < this.min) {\n panDelta = this.min - this.a;\n }\n if (this.b + panDelta > this.max) {\n panDelta = this.max - this.b;\n }\n const finalA = this.a + panDelta;\n const finalB = this.b + panDelta;\n if (finalA >= this.min && finalB <= this.max) {\n this.setPoles(finalA, finalB);\n }\n } else {\n this.b = valueFromPos(pos);\n }\n return;\n }\n\n const aPosPxNear = near(aPosPx, 10);\n const bPosPxNear = near(bPosPx, 10);\n\n const handleDrag = (draggingWhich: `a` | `b` | `none`) => {\n const setPoles = this.setPoles.bind(this);\n const resizeMode = this.resizeMode;\n const min = this.min;\n const max = this.max;\n const startPos = isVertical ? event.offsetY : event.offsetX;\n let polesChanged = false;\n dragLogicStart(event, {\n progress(current, _start) {\n const currentPos = isVertical ? current.offset.y : current.offset.x;\n const delta = isVertical ? startPos - currentPos : currentPos - startPos;\n const amt = delta / valuePerPix;\n polesChanged = true;\n\n if (draggingWhich === `a`) {\n if (resizeMode === `bipolar`) {\n const calcA = startA + amt;\n const calcB = startB - amt;\n if (calcA < min || calcB > max || calcA > max || calcB < min) {\n return;\n }\n setPoles(calcA, calcB);\n } else if (resizeMode === `bipolar-flex`) {\n let calcA = startA + amt;\n let calcB = startB;\n\n if (startB <= min) {\n calcB = min;\n } else if (startB >= max) {\n calcB = max;\n } else {\n calcA = startA + amt;\n calcB = startB - amt;\n }\n\n if (calcA < min)\n calcA = min;\n if (calcA > max)\n calcA = max;\n if (calcB < min)\n calcB = min;\n if (calcB > max)\n calcB = max;\n\n if (calcA > calcB) {\n return;\n }\n setPoles(calcA, calcB);\n } else {\n let constrainedAmt = amt;\n if (startA + amt < min) {\n constrainedAmt = min - startA;\n }\n if (startB + constrainedAmt > max) {\n constrainedAmt = max - startB;\n }\n const finalA = startA + constrainedAmt;\n const finalB = startB + constrainedAmt;\n if (finalA >= min && finalB <= max) {\n setPoles(finalA, finalB);\n }\n }\n } else if (draggingWhich === `b`) {\n if (resizeMode === `bipolar`) {\n const calcA = startA - amt;\n const calcB = startB + amt;\n if (calcA < min || calcB > max || calcA > max || calcB < min) {\n return;\n }\n setPoles(calcA, calcB);\n } else if (resizeMode === `bipolar-flex`) {\n let calcA = startA;\n let calcB = startB + amt;\n\n if (startA <= min) {\n calcA = min;\n } else if (startA >= max) {\n calcA = max;\n } else {\n calcA = startA - amt;\n calcB = startB + amt;\n }\n\n if (calcA < min)\n calcA = min;\n if (calcA > max)\n calcA = max;\n if (calcB < min)\n calcB = min;\n if (calcB > max)\n calcB = max;\n\n if (calcA > calcB) {\n return;\n }\n setPoles(calcA, calcB);\n } else {\n let constrainedAmt = amt;\n if (startA + amt < min) {\n constrainedAmt = min - startA;\n }\n if (startB + constrainedAmt > max) {\n constrainedAmt = max - startB;\n }\n const finalA = startA + constrainedAmt;\n const finalB = startB + constrainedAmt;\n if (finalA >= min && finalB <= max) {\n setPoles(finalA, finalB);\n }\n }\n } else {\n if (resizeMode === `bipolar`) {\n const calcA = startA + amt;\n const calcB = startB + amt;\n if (calcA < min || calcB > max) {\n return;\n }\n setPoles(calcA, calcB);\n } else if (resizeMode === `bipolar-flex`) {\n let calcA = startA + amt;\n let calcB = startB + amt;\n if (calcA < min) {\n calcA = min;\n calcB = min + (startB - startA);\n } else if (calcB > max) {\n calcB = max;\n calcA = max - (startB - startA);\n }\n if (calcA < min || calcB > max || calcA > calcB) {\n return;\n }\n setPoles(calcA, calcB);\n } else {\n let constrainedAmt = amt;\n if (startA + amt < min) {\n constrainedAmt = min - startA;\n }\n if (startB + constrainedAmt > max) {\n constrainedAmt = max - startB;\n }\n const finalA = startA + constrainedAmt;\n const finalB = startB + constrainedAmt;\n if (finalA >= min && finalB <= max) {\n setPoles(finalA, finalB);\n }\n }\n }\n },\n complete(_final, _start) {\n if (!polesChanged) {\n const currentPos = isVertical ? event.offsetY : event.offsetX;\n const closestA = Math.abs(currentPos - aPosPx) < Math.abs(currentPos - bPosPx);\n if (closestA) {\n setPoles(valueFromPos(currentPos), startB);\n } else {\n setPoles(startA, valueFromPos(currentPos));\n }\n }\n },\n });\n };\n\n if (aPosPxNear(pos)) {\n this.draggingThumb = `a`;\n if (this.resizeMode === `dual`) {\n return false;\n }\n event.preventDefault();\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n handleDrag(`a`);\n return;\n } else if (bPosPxNear(pos)) {\n this.draggingThumb = `b`;\n if (this.resizeMode === `dual`) {\n return false;\n }\n event.preventDefault();\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n handleDrag(`b`);\n return;\n } else {\n this.draggingThumb = `none`;\n }\n\n event.preventDefault();\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n handleDrag(`none`);\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n this.#updateScale();\n }\n\n protected render(): unknown {\n const ttA = this.tooltip ? html`<ixfx-tooltip style=\"--tooltip-background: var(--surface-5); --tooltip-color: var(--surface-5-text)\" anchor=\"--a-tooltip\" .orientation=${this.tooltipOrientation} .value=${this.a}></ixfx-tooltip>` : nothing;\n const ttB = this.tooltip ? html`<ixfx-tooltip style=\"--tooltip-background: var(--surface-5); --tooltip-color: var(--surface-5-text)\" anchor=\"--b-tooltip\" .orientation=${this.tooltipOrientation} .value=${this.b}></ixfx-tooltip>` : nothing;\n\n const scaledA = this.#scaleTo100(this.a);\n const scaledB = this.#scaleTo100(this.b);\n const verticalStyle = this.orientation === `vertical`\n ? `writing-mode: vertical-lr; direction: rtl;`\n : nothing;\n // console.log(`a->b ${ this.a }->${ this.b } scaled: ${ scaledA }->${ scaledB }`)\n return html`\n <div @pointerdown=${this._onPointerDown} @input=${this._onInput} style=\"--a: ${scaledA}; --b: ${scaledB}\">\n <input class=\"thumb-round\" .value=${scaledA} id=\"a\" step=${this.step} type=\"range\" style=\"${verticalStyle}\" anchor=\"--a-tooltip\" />\n ${ttA}\n\n <input class=\"thumb-round\" .value=${scaledB} id=\"b\" step=${this.step} type=\"range\" style=\"${verticalStyle}\" anchor=\"--b-tooltip\" />\n ${ttB}\n </div>`;\n }\n\n static styles = [\n themeFallbacks,\n tooltipValueStyles,\n prominenceStyles,\n css`\n :host {\n display: grid;\n --value-label-color: unset;\n \n --range-background: AccentColor;\n --range-height: 1.5em;\n --range-thickness: 1em;\n --thumb-background: ButtonFace;\n --thumb-radius: 50%;\n --thumb-width: 1em;\n --thumb-height: 1em;\n --js:1;\n }\n\n :host([orientation=\"vertical\"]) {\n display: block;\n width: 1.5em;\n height: 200px;\n }\n\n * {\n margin: 0;\n padding: 0;\n font: inherit;\n }\n\n div {\n --j: var(--js, 0);\n display:inline grid;\n align-content: end;\n grid-gap: 0.25em;\n place-self: center;\n min-width: 8em;\n width: calc(100% - 1.5em);\n height: 1.5rem;\n }\n\n :host([orientation=\"vertical\"]) div {\n width: 1.5rem;\n height: calc(100% - 1.5em);\n min-width: unset;\n min-height: 8em;\n }\n\n div::before, div::after {\n margin: 0.5rem 0.6875rem;\n border-radius: 0.25rem;\n box-shadow: none;\n background: var(--surface-4);\n content: \"\";\n }\n :host([orientation=\"vertical\"]) div::before,\n :host([orientation=\"vertical\"]) div::after {\n margin: 0.5rem 0;\n }\n div::after {\n --or: calc((100 - Max(var(--a), var(--b)))*1%);\n --ol: calc(Min(var(--a), var(--b))*1%);\n box-shadow: none;\n background: var(--accent);\n clip-path: inset(0 var(--or) 0 var(--ol));\n }\n :host([orientation=\"vertical\"]) div::after {\n clip-path: inset(var(--or) 0 var(--ol) 0);\n }\n div input, div::before, div::after {\n grid-area: calc(1 + var(--j))/1;\n }\n div output, div::after {\n display:'none';\n }\n\n [type=range] {\n width: 100%;\n height: var(--range-height);\n background: transparent;\n pointer-events: none;\n }\n\n :host([orientation=\"vertical\"]) [type=range] {\n writing-mode: vertical-lr;\n direction: rtl;\n width: var(--range-height);\n height: 100%;\n }\n\n [type=range], [type=range]::-webkit-slider-runnable-track, [type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n }\n [type=range], [type=range] + ixfx-tooltip {\n --sel: 0;\n z-index: calc(1 + var(--sel));\n }\n [type=range]::-webkit-slider-runnable-track {\n background: transparent;\n }\n [type=range]::-moz-range-track {\n background: transparent;\n }\n\n input.thumb-round::-webkit-slider-thumb {\n width: var(--thumb-width);\n height: var(--thumb-height);\n border-radius: var(--thumb-radius);\n }\n\n [type=range]::-webkit-slider-thumb {\n box-sizing: border-box;\n border: solid calc(0.5rem + -1px) transparent;\n\n /* box-shadow: var(--shadow-m); */\n background: var(--thumb-background);\n pointer-events: auto;\n cursor: ew-resize;\n }\n\n :host([orientation=\"vertical\"]) [type=range]::-webkit-slider-thumb {\n width: var(--thumb-height);\n height: var(--thumb-width);\n cursor: ns-resize;\n }\n\n [type=range]::-moz-range-thumb {\n box-sizing: border-box;\n border: solid calc(0.5rem + -1px) transparent;\n width: 1.375rem;\n height: 1.375rem;\n border-radius: 50%;\n box-shadow: var(--shadow-m);\n background: var(--thumb-background);\n pointer-events: auto;\n cursor: ew-resize;\n }\n\n :host([orientation=\"vertical\"]) [type=range]::-moz-range-thumb {\n cursor: ns-resize;\n }\n\n [type=range]:focus {\n outline: none;\n }\n [type=range]:focus, [type=range]:focus + ixfx-tooltip, [type=range]:hover, [type=range]:hover + ixfx-tooltip {\n --sel: 1 ;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-range-multi\": RangeMultiElement;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type RatingVariant = `star` | `square` | `heart`;\nexport type RatingChangeDetail = Readonly<{ value: number; oldValue: number }>;\nexport type RatingChangeEvent = CustomEvent<RatingChangeDetail>;\nexport type RatingInputEvent = CustomEvent<RatingChangeDetail>;\nexport interface RatingElementEventMap {\n change: RatingChangeEvent;\n input: RatingInputEvent;\n}\n\n@customElement(`ixfx-rating`)\nexport class RatingElement extends LitElement {\n static override styles = [prominenceStyles, css`\n :host {\n --ixfx-rating-size: 1.5rem;\n --ixfx-rating-gap: 0.2rem;\n --ixfx-rating-color: var(--surface-4);\n --ixfx-rating-color-active: var(--accent);\n --ixfx-rating-color-hover: var(--accent);\n display: inline-flex;\n gap: var(--ixfx-rating-gap);\n align-items: center;\n user-select: none;\n --transition: 0.15s ease;\n }\n :host([readonly]) { pointer-events: none; filter: none; }\n :host(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }\n .glyph {\n width: var(--ixfx-rating-size);\n height: var(--ixfx-rating-size);\n position: relative;\n cursor: pointer;\n flex-shrink: 0;\n color: var(--ixfx-rating-glyph-color, var(--ixfx-rating-color));\n transition: color var(--transition), transform var(--transition);\n }\n .glyph.filled { color: var(--ixfx-rating-glyph-color-active, var(--ixfx-rating-color-active)); }\n .glyph.preview { color: var(--ixfx-rating-glyph-color-hover, var(--ixfx-rating-color-hover)); }\n .glyph.half .fill { clip-path: inset(0 50% 0 0); }\n .glyph svg { width: 100%; height: 100%; display: block; }\n .glyph .fill { position: absolute; inset: 0; color: var(--ixfx-rating-glyph-color-active, var(--ixfx-rating-color-active)); }\n .glyph.preview .fill { color: var(--ixfx-rating-glyph-color-hover, var(--ixfx-rating-color-hover)); }\n .glyph .bg { color: var(--ixfx-rating-glyph-color, var(--ixfx-rating-color)); }\n /* per-rank vars: consumer sets --ixfx-rating-1-color etc outside shadow, we map via inline style fallback */\n `];\n\n @property({ type: Number }) value = 0;\n @property({ type: Number }) max = 5;\n @property({ type: Boolean, attribute: `allow-half` }) allowHalf = false;\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: Boolean, reflect: true }) readonly = false;\n @property({ type: String }) variant: RatingVariant = `star`;\n\n @state() private _preview: number | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n this.setAttribute(`role`, `slider`);\n this.tabIndex = this.disabled || this.readonly ? -1 : 0;\n }\n\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has(`disabled`) || changed.has(`readonly`)) {\n this.tabIndex = this.disabled || this.readonly ? -1 : 0;\n this.setAttribute(`aria-disabled`, String(this.disabled));\n }\n this.setAttribute(`aria-valuenow`, String(this.value));\n this.setAttribute(`aria-valuemin`, `0`);\n this.setAttribute(`aria-valuemax`, String(this.max));\n this.setAttribute(`aria-readonly`, String(this.readonly));\n }\n\n private _path(v: RatingVariant) {\n if (v === `heart`)\n return `M12 21s-6.5-4.2-8.5-8.2A4.5 4.5 0 0 1 12 5a4.5 4.5 0 0 1 8.5 7.8C18.5 16.8 12 21 12 21z`;\n if (v === `square`)\n return `M3 3h18v18H3z`;\n return `M12 2l2.4 7.4H22l-6.2 4.5 2.4 7.4L12 17 5.8 21.3l2.4-7.4L2 9.4h7.6z`;\n }\n\n private _effective() {\n return this._preview ?? this.value;\n }\n\n private _commit(newVal: number) {\n if (this.disabled || this.readonly)\n return;\n const oldValue = this.value;\n if (newVal === oldValue)\n newVal = 0;\n if (newVal === oldValue)\n return;\n this.value = newVal;\n this.dispatchEvent(new CustomEvent<RatingChangeDetail>(`input`, { detail: { value: newVal, oldValue }, bubbles: true, composed: true }));\n this.dispatchEvent(new CustomEvent<RatingChangeDetail>(`change`, { detail: { value: newVal, oldValue }, bubbles: true, composed: true }));\n }\n\n private _calc(e: PointerEvent, index: number) {\n if (!this.allowHalf)\n return index + 1;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n return e.clientX - rect.left < rect.width / 2 ? index + 0.5 : index + 1;\n }\n\n protected override render() {\n const eff = this._effective();\n const hovering = this._preview !== null;\n return html`${Array.from({ length: this.max }, (_, i) => {\n const rank = i + 1;\n const filled = eff >= rank;\n const half = !filled && eff >= rank - 0.5;\n const cls = `glyph ${filled ? `filled` : ``} ${half ? `half` : ``} ${hovering && (filled || half) ? `preview` : ``}`;\n // per-rank CSS var mapping via inline style so outer --ixfx-rating-N-color cascades\n const style = `--ixfx-rating-glyph-color:var(--ixfx-rating-${rank}-color, var(--ixfx-rating-color));--ixfx-rating-glyph-color-active:var(--ixfx-rating-${rank}-color-active, var(--ixfx-rating-color-active));--ixfx-rating-glyph-color-hover:var(--ixfx-rating-${rank}-color-hover, var(--ixfx-rating-color-hover));${half || filled ? `` : ``}`;\n const d = this._path(this.variant);\n return html`<span class=${cls} style=${style}\n @pointermove=${(e: PointerEvent) => {\n if (this.disabled || this.readonly)\n return; this._preview = this._calc(e, i);\n }}\n @pointerleave=${() => this._preview = null}\n @click=${(e: PointerEvent) => this._commit(this._calc(e, i))}>\n <svg viewBox=\"0 0 24 24\" class=\"bg\" fill=\"currentColor\"><path d=${d}></path></svg>\n ${(filled || half) ? html`<svg viewBox=\"0 0 24 24\" class=\"fill\" fill=\"currentColor\"><path d=${d}></path></svg>` : ``}\n </span>`;\n })}`;\n }\n\n override firstUpdated() {\n this.addEventListener(`pointerleave`, () => this._preview = null);\n this.addEventListener(`keydown`, (e: KeyboardEvent) => {\n if (this.disabled || this.readonly)\n return;\n const step = this.allowHalf ? 0.5 : 1;\n if (e.key === `ArrowRight` || e.key === `ArrowUp`) {\n e.preventDefault(); this._commit(Math.min(this.max, this.value + step));\n } else if (e.key === `ArrowLeft` || e.key === `ArrowDown`) {\n e.preventDefault(); this._commit(Math.max(0, this.value - step));\n } else if (e.key === `Home`) {\n e.preventDefault(); this._commit(0);\n } else if (e.key === `End`) {\n e.preventDefault(); this._commit(this.max);\n } else if (/^\\d$/.test(e.key)) {\n e.preventDefault(); const n = parseInt(e.key, 10); this._commit(Math.min(n, this.max));\n }\n });\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap { 'ixfx-rating': RatingElement }\n}\nexport interface IxfxRatingElement {\n addEventListener: (<K extends keyof RatingElementEventMap>(type: K, listener: (this: RatingElement, ev: RatingElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions) => void) & ((type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void);\n removeEventListener: (<K extends keyof RatingElementEventMap>(type: K, listener: (this: RatingElement, ev: RatingElementEventMap[K]) => void, options?: boolean | EventListenerOptions) => void) & ((type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions) => void);\n}\n","export function clampValue(v: number, min: number, max: number): number {\n return Math.min(Math.max(v, min), max);\n}\n\nexport type ClampTypes = `none` | `bipolar` | `scalar`;\nexport type ClampFn = (value: number) => number;\nexport function clamp(clamp: ClampTypes = `none`): ClampFn {\n switch (clamp) {\n case `bipolar`:\n return (v: number) => {\n if (v > 1)\n return 1;\n if (v < -1)\n return -1;\n return v;\n };\n case `scalar`:\n return (v: number) => {\n if (v > 1)\n return 1;\n if (v < 0)\n return 0;\n return v;\n };\n default:\n return (v: number) => v;\n }\n}","export interface Point { x: number; y: number }\nexport function polarToCartesian(angle: number, radius: number, center: Point = { x: 50, y: 50 }): Point {\n return { x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius };\n}\nexport { clampValue as clamp } from './clamp.js';\nexport function scale(v: number, fromMin: number, fromMax: number, toMin: number, toMax: number): number {\n if (fromMax === fromMin)\n return toMin;\n return toMin + ((v - fromMin) / (fromMax - fromMin)) * (toMax - toMin);\n}\nexport function describeArc(startAngle: number, endAngle: number, radius: number, center: Point = { x: 50, y: 50 }): string {\n const PI2 = Math.PI * 2;\n let arcLen = endAngle - startAngle;\n if (arcLen < 0)\n arcLen += PI2;\n if (arcLen >= PI2 - 0.001) {\n const adj = startAngle + PI2 - 0.001;\n const s = polarToCartesian(startAngle, radius, center);\n const e = polarToCartesian(adj, radius, center);\n return `M ${s.x},${s.y} A ${radius},${radius} 0 1 1 ${e.x},${e.y}`;\n }\n const s = polarToCartesian(startAngle, radius, center);\n const e = polarToCartesian(endAngle, radius, center);\n return `M ${s.x},${s.y} A ${radius},${radius} 0 ${arcLen > Math.PI ? 1 : 0} 1 ${e.x},${e.y}`;\n}\n","/**\n * Shapefill value component\n * A click-and-drag value input, similar in interaction to `ixfx-radial-input`,\n * but depicted as a shape outline (`rectangle` or `circle`) with a concentric\n * inner shape whose size represents the current value: a value of 50% draws\n * an inner shape scaled to half the outline's size.\n */\n\nimport type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type {\n ShapefillDisplay,\n ShapefillFillMode,\n ShapefillValueChangeDetail,\n ShapefillValueInputDetail,\n} from './types.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { clampValue } from '../util/clamp.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { scale } from '../util/geometry.js';\n\n@customElement(`ixfx-shapefill-value`)\nexport class ShapefillValueElement extends WheelNudgeMixin(LitElement) {\n // Display shape\n @property({ type: String })\n display: ShapefillDisplay = `circle`;\n\n // How the inner shape grows as value increases\n @property({ type: String, attribute: `fill-mode` })\n fillMode: ShapefillFillMode = `centre`;\n\n // Value properties (matches ixfx-radial-input API)\n @property({ type: Number })\n value = 0;\n\n @property({ type: Number })\n min = 0;\n\n @property({ type: Number })\n max = 100;\n\n @property({ type: Number })\n step: number | undefined = undefined;\n\n @property({ type: Number })\n stops?: number;\n\n // Interaction\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // Internal state\n #dragging = false;\n #dragStartY = 0;\n #valueAtDragStart = 0;\n /** Client Y of the last processed pointer event, for external-write re-baselining. */\n #lastPointerY = 0;\n /** Value at the drag's last write — detects external `value` writes mid-drag. */\n #lastSetValue: number | undefined;\n #changeDebounceTimer: number | undefined;\n\n // Internal helpers\n #getRelativeValue(): number {\n return scale(this.value, this.min, this.max, 0, 1);\n }\n\n #quantise(value: number): number {\n if (this.stops && this.stops > 1) {\n const range = this.max - this.min;\n const step = range / this.stops;\n return Math.round((value - this.min) / step) * step + this.min;\n }\n return value;\n }\n\n #setValueFromRelative(relativeValue: number, isUserInteraction = false): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clampedValue = this.#quantise(clampValue(newValue, this.min, this.max));\n\n if (clampedValue === this.value)\n return;\n\n const previousValue = this.value;\n this.value = clampedValue;\n this.#lastSetValue = clampedValue;\n\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(this.#getRelativeValue() * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n if (isUserInteraction) {\n this.dispatchEvent(\n new CustomEvent<ShapefillValueInputDetail>(`input`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n this.#scheduleChangeEvent(previousValue);\n } else {\n this.#fireChangeEvent(previousValue);\n }\n }\n\n #scheduleChangeEvent(previousValue: number): void {\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n\n this.#changeDebounceTimer = window.setTimeout(() => {\n this.#fireChangeEvent(previousValue);\n this.#changeDebounceTimer = undefined;\n }, 150);\n }\n\n #fireChangeEvent(previousValue: number): void {\n this.dispatchEvent(\n new CustomEvent<ShapefillValueChangeDetail>(`change`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n previousValue,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Pointer interaction handlers\n #onPointerDown = (event: PointerEvent): void => {\n if (this.disabled)\n return;\n\n event.preventDefault();\n const svgEl = this.renderRoot.querySelector(`svg`);\n svgEl?.focus();\n this.#dragging = true;\n this.#dragStartY = event.clientY;\n this.#lastPointerY = event.clientY;\n this.#valueAtDragStart = this.value;\n this.#lastSetValue = this.value;\n this.toggleAttribute(`dragging`, true);\n\n if (svgEl) {\n svgEl.setPointerCapture(event.pointerId);\n }\n\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n #onPointerMove = (event: PointerEvent): void => {\n if (!this.#dragging)\n return;\n\n event.preventDefault();\n\n // The value moved outside the drag since our last write (two-way binding,\n // a normalising `input`/`change` handler, wheel nudge, ...). Re-baseline\n // from the previous pointer position so this event's delta still applies\n // on top of the external value, instead of stomping it back toward the\n // drag-start trajectory.\n if (this.value !== this.#lastSetValue) {\n this.#valueAtDragStart = this.value;\n this.#dragStartY = this.#lastPointerY;\n this.#lastSetValue = this.value;\n }\n\n // Calculate sensitivity: full range = 2x the component height\n const sensitivity = this.clientHeight * 2;\n const shiftDivisor = event.shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveSensitivity = sensitivity * shiftDivisor;\n\n // Calculate delta (negative because up = increase)\n const deltaY = this.#dragStartY - event.clientY;\n const deltaValue = (deltaY / effectiveSensitivity) * (this.max - this.min);\n const newValue = this.#valueAtDragStart + deltaValue;\n\n const relativeValue = scale(newValue, this.min, this.max, 0, 1);\n this.#setValueFromRelative(clampValue(relativeValue, 0, 1), true);\n this.#lastPointerY = event.clientY;\n };\n\n #onPointerUp = (): void => {\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n\n const svgEl = this.renderRoot.querySelector(`svg`);\n if (svgEl && `hasPointerCapture` in svgEl && typeof svgEl.hasPointerCapture === `function`) {\n if (svgEl.hasPointerCapture(1)) {\n svgEl.releasePointerCapture(1);\n }\n }\n\n window.removeEventListener(`pointermove`, this.#onPointerMove);\n window.removeEventListener(`pointerup`, this.#onPointerUp);\n window.removeEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n // Keyboard interaction handler\n #onKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled)\n return;\n\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n\n let handled = false;\n\n switch (event.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n this.#stepByRelativeDelta(effectiveStep / range, true);\n handled = true;\n break;\n\n case `ArrowDown`:\n case `ArrowLeft`:\n this.#stepByRelativeDelta(-effectiveStep / range, true);\n handled = true;\n break;\n\n case `Home`:\n this.#setValueFromRelative(0, true);\n handled = true;\n break;\n\n case `End`:\n this.#setValueFromRelative(1, true);\n handled = true;\n break;\n }\n\n if (handled) {\n event.preventDefault();\n }\n };\n\n /**\n * Apply a relative-delta nudge to the current value, clamped to [min, max] and\n * quantised. Shared between keyboard arrow keys and the wheel handler.\n */\n #stepByRelativeDelta(relativeDelta: number, isUserInteraction: boolean): void {\n this.#setValueFromRelative(\n clampValue(this.#getRelativeValue() + relativeDelta, 0, 1),\n isUserInteraction,\n );\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Wheel up increases,\n // wheel down decreases (standard convention, unlike the inverted rotary-dial feel\n // of ixfx-radial-input, since there's no rotational metaphor here).\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this.#stepByRelativeDelta(direction * effectiveStep / range, true);\n }\n\n // Rendering helpers\n #renderCircle() {\n const relativeValue = this.#getRelativeValue();\n const outerRadius = 45;\n const innerRadius = outerRadius * relativeValue;\n const outerCx = 50;\n const outerCy = 50;\n\n // 'left'/'right': the value circle's x-origin travels from the outline's\n // left/right perimeter (value 0) to the outline's centre (value 100%),\n // while its radius grows the same way as 'centre' — the net effect is a\n // circle that inflates outward from that edge.\n let cx = outerCx;\n if (this.fillMode === `left`)\n cx = outerCx - outerRadius + outerRadius * relativeValue;\n else if (this.fillMode === `right`)\n cx = outerCx + outerRadius - outerRadius * relativeValue;\n\n return svg`\n <circle class=\"fill\" cx=\"${cx}\" cy=\"${outerCy}\" r=\"${innerRadius}\" />\n <circle class=\"outline\" cx=\"${outerCx}\" cy=\"${outerCy}\" r=\"${outerRadius}\" fill=\"none\" />\n `;\n }\n\n #renderRectangle() {\n const relativeValue = this.#getRelativeValue();\n const outerSize = 90; // 5..95\n const outerOffset = (100 - outerSize) / 2;\n\n if (this.fillMode === `left` || this.fillMode === `right`) {\n // Classic slider-bar fill: grows from the outline's left/right edge, full height.\n const innerWidth = outerSize * relativeValue;\n const x = this.fillMode === `left` ? outerOffset : outerOffset + outerSize - innerWidth;\n return svg`\n <rect class=\"fill\" x=\"${x}\" y=\"${outerOffset}\" width=\"${innerWidth}\" height=\"${outerSize}\" />\n <rect class=\"outline\" x=\"${outerOffset}\" y=\"${outerOffset}\" width=\"${outerSize}\" height=\"${outerSize}\" fill=\"none\" />\n `;\n }\n\n const innerSize = outerSize * relativeValue;\n const innerOffset = (100 - innerSize) / 2;\n\n return svg`\n <rect class=\"fill\" x=\"${innerOffset}\" y=\"${innerOffset}\" width=\"${innerSize}\" height=\"${innerSize}\" />\n <rect class=\"outline\" x=\"${outerOffset}\" y=\"${outerOffset}\" width=\"${outerSize}\" height=\"${outerSize}\" fill=\"none\" />\n `;\n }\n\n override render(): unknown {\n // Circle keeps a fixed aspect ratio (`meet`) so it always renders as a\n // true circle, letterboxing within a non-square host. Rectangle instead\n // stretches to fill the host (`none`), so a landscape/portrait host\n // produces a matching landscape/portrait rectangle rather than a\n // letterboxed square.\n const preserveAspectRatio = this.display === `rectangle` ? `none` : `xMidYMid meet`;\n\n return html`\n <svg\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"${preserveAspectRatio}\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n @pointerdown=\"${this.#onPointerDown}\"\n @keydown=\"${this.#onKeyDown}\"\n style=\"cursor: ${this.#dragging ? `ns-resize` : `grab`}\"\n >\n ${this.display === `rectangle` ? this.#renderRectangle() : this.#renderCircle()}\n </svg>\n `;\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n this.style.setProperty(`--shapefill-value-relative`, this.#getRelativeValue().toString());\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n this.#onPointerUp();\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-block;\n width: 2em;\n height: 2em;\n touch-action: none;\n user-select: none;\n\n /* Dynamic value - set by JS */\n --shapefill-value-relative: 0;\n\n /* Public styling variables — consumer customisable */\n --shapefill-value-outline-color: var(--surface-4);\n --shapefill-value-outline-width: 2;\n --shapefill-value-fill-color: var(--accent);\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n svg {\n width: 100%;\n height: 100%;\n outline: none;\n display: block;\n }\n\n svg:active {\n cursor: grabbing;\n }\n\n svg:focus-visible {\n outline: var(--shapefill-value-focus-outline, 2px solid var(--accent));\n outline-offset: var(--shapefill-value-focus-outline-offset, 2px);\n }\n\n .outline {\n stroke: var(--shapefill-value-outline-color, var(--surface-4));\n stroke-width: var(--shapefill-value-outline-width, 2);\n vector-effect: non-scaling-stroke;\n }\n\n .fill {\n fill: var(--shapefill-value-fill-color, var(--accent));\n transition: var(--shapefill-value-fill-transition, none);\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-shapefill-value': ShapefillValueElement;\n }\n}\n","import type { PropertyValues } from 'lit';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n/**\n * Digit-roll direction.\n * - `auto` — inferred from whether the value went up or down (default)\n * - `up` / `down` — force the reels to always spin one way\n * - `none` — take the shortest path\n */\nexport type SlidingNumberTrend = `auto` | `up` | `down` | `none` | `increasing` | `decreasing`;\n\ntype CellKind = `digit` | `symbol`;\ntype CellSection = `lead` | `integer` | `fraction` | `trail` | `decimal`;\ntype CellPhase = `enter` | `active` | `leave`;\n\ninterface ViewCell {\n key: string;\n kind: CellKind;\n section: CellSection;\n char: string;\n pos: number;\n phase: CellPhase;\n}\n\n// Three stacked copies of 0–9 so a reel can roll a full wrap in either\n// direction from its canonical rest offset (the middle copy, 10 + digit).\nconst REEL_DIGITS: readonly number[] = Array.from({ length: 30 }, (_, index) => index % 10);\n\nconst SECTION_RANK: Record<CellSection, number> = {\n lead: 0,\n integer: 1,\n decimal: 2,\n fraction: 3,\n trail: 4,\n};\n\nfunction mod(n: number, m: number): number {\n return ((n % m) + m) % m;\n}\n\n/** Parse a CSS time token (`0.7s`, `700ms`, `0`) to milliseconds. */\nfunction millis(value: string): number {\n const s = value.trim();\n if (s === ``)\n return 0;\n if (s.endsWith(`ms`))\n return Number.parseFloat(s) || 0;\n if (s.endsWith(`s`))\n return (Number.parseFloat(s) || 0) * 1000;\n return Number.parseFloat(s) || 0;\n}\n\n/**\n * `ixfx-sliding-number` — an animated number readout. When `value` changes each\n * digit rolls vertically to its new figure (odometer / slot-machine style),\n * digits that appear or disappear slide + fade, and the whole thing stays lined\n * up on the decimal point.\n *\n * Inspired by [NumberFlow](https://number-flow.barvian.me/): configurable\n * timings, a `trend` to bias roll direction, decimal alignment, and `::part()`\n * hooks for styling.\n *\n * ```html\n * <ixfx-sliding-number value=\"1234.5\"></ixfx-sliding-number>\n * <ixfx-sliding-number value=\"19.99\" prefix=\"$\" format='{\"minimumFractionDigits\":2}'></ixfx-sliding-number>\n * ```\n *\n * ### CSS variables\n * | Variable | Default | Purpose |\n * |---|---|---|\n * | `--sliding-number-spin-duration` | `0.7s` | Time for a digit reel to roll |\n * | `--sliding-number-spin-easing` | `cubic-bezier(.16,1,.3,1)` | Easing for the roll |\n * | `--sliding-number-transform-duration` | `0.5s` | Time for digits to slide in/out as the number grows/shrinks |\n * | `--sliding-number-transform-easing` | `cubic-bezier(.16,1,.3,1)` | Easing for that slide |\n * | `--sliding-number-opacity-duration` | `0.35s` | Fade time for entering/leaving digits |\n * | `--sliding-number-digit-width` | `1ch` | Column width of a single digit |\n *\n * ### Parts\n * `prefix`, `suffix`, `number`, `integer`, `fraction`, `digit`, `symbol`.\n */\n@customElement(`ixfx-sliding-number`)\nexport class SlidingNumberElement extends LitElement {\n /** The number to display. */\n @property({ type: Number }) value = 0;\n\n /** BCP-47 locale(s) passed to `Intl.NumberFormat`. */\n @property({ type: String }) locales: string | undefined;\n\n /**\n * `Intl.NumberFormat` options. As an attribute, pass JSON:\n * `format='{\"style\":\"currency\",\"currency\":\"USD\"}'`.\n */\n @property({ type: Object }) format: Intl.NumberFormatOptions | undefined;\n\n /** Static text shown before the number. */\n @property({ type: String }) prefix = ``;\n\n /** Static text shown after the number. */\n @property({ type: String }) suffix = ``;\n\n /** Which way the digit reels roll. */\n @property({ type: String }) trend: SlidingNumberTrend = `auto`;\n\n /** Add the `no-animate` attribute to render every change instantly. */\n @property({ type: Boolean, attribute: `no-animate` }) noAnimate = false;\n\n /** Honour `prefers-reduced-motion: reduce` (default `true`; set the property to `false` to override). */\n @property({ type: Boolean, attribute: false }) respectMotionPreference = true;\n\n @state() private _cells: ViewCell[] = [];\n\n private _formatted = ``;\n private _ready = false;\n private _prevValue: number | undefined;\n private _pendingSpins: Array<{ key: string; from: number; to: number }> = [];\n private _pendingDir: `up` | `down` | `none` = `none`;\n private _reelAnims = new Map<string, Animation>();\n private _reapTimer = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute(`role`))\n this.setAttribute(`role`, `img`);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n for (const anim of this._reelAnims.values()) anim.cancel();\n this._reelAnims.clear();\n if (this._reapTimer)\n clearTimeout(this._reapTimer);\n }\n\n private _motionOK(): boolean {\n if (this.noAnimate)\n return false;\n if (\n this.respectMotionPreference\n && typeof window !== `undefined`\n && window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches\n ) {\n return false;\n }\n return true;\n }\n\n private _timing(kind: `spin` | `transform`): { duration: number; easing: string } {\n const cs = getComputedStyle(this);\n const duration = this._motionOK()\n ? millis(cs.getPropertyValue(`--sliding-number-${kind}-duration`))\n : 0;\n const easing = cs.getPropertyValue(`--sliding-number-${kind}-easing`).trim() || `ease`;\n return { duration, easing };\n }\n\n private _numberFormat(): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(this.locales || undefined, this.format || undefined);\n } catch {\n return new Intl.NumberFormat(this.locales || undefined);\n }\n }\n\n private _resolveDir(first: boolean): `up` | `down` | `none` {\n switch (this.trend) {\n case `up`:\n case `increasing`:\n return `up`;\n case `down`:\n case `decreasing`:\n return `down`;\n case `none`:\n return `none`;\n default: {\n if (first || this._prevValue === undefined || this.value === this._prevValue)\n return `none`;\n return this.value > this._prevValue ? `up` : `down`;\n }\n }\n }\n\n /** Split the formatted value into positioned cells. */\n private _buildCells(parts: Intl.NumberFormatPart[]): ViewCell[] {\n const intRaw: Array<{ digit: boolean; char: string }> = [];\n const fractionChars: string[] = [];\n const lead: string[] = [];\n const trail: string[] = [];\n let decimalChar = ``;\n let sawInteger = false;\n let sawDecimal = false;\n\n for (const part of parts) {\n switch (part.type) {\n case `integer`:\n sawInteger = true;\n for (const c of part.value) intRaw.push({ digit: true, char: c });\n break;\n case `group`:\n intRaw.push({ digit: false, char: part.value });\n break;\n case `decimal`:\n sawDecimal = true;\n decimalChar = part.value;\n break;\n case `fraction`:\n for (const c of part.value) fractionChars.push(c);\n break;\n default:\n (sawInteger || sawDecimal ? trail : lead).push(part.value);\n }\n }\n\n const cells: ViewCell[] = [];\n const totalIntDigits = intRaw.filter(x => x.digit).length;\n\n lead.forEach((char, index) => {\n cells.push({ key: `lead:${index}`, kind: `symbol`, section: `lead`, char, pos: index - 100, phase: `active` });\n });\n\n let seen = 0;\n for (const item of intRaw) {\n if (item.digit) {\n const place = totalIntDigits - 1 - seen;\n seen++;\n cells.push({ key: `int:${place}`, kind: `digit`, section: `integer`, char: item.char, pos: -place, phase: `active` });\n } else {\n // Separator sits just to the right of the digit at `place` (lower-place side).\n const place = totalIntDigits - seen;\n cells.push({ key: `grp:${place}`, kind: `symbol`, section: `integer`, char: item.char, pos: -place + 0.5, phase: `active` });\n }\n }\n\n if (sawDecimal) {\n cells.push({ key: `decimal`, kind: `symbol`, section: `decimal`, char: decimalChar, pos: 0, phase: `active` });\n }\n\n fractionChars.forEach((char, index) => {\n cells.push({ key: `frac:${index}`, kind: `digit`, section: `fraction`, char, pos: index + 1, phase: `active` });\n });\n\n trail.forEach((char, index) => {\n cells.push({ key: `trail:${index}`, kind: `symbol`, section: `trail`, char, pos: index + 100, phase: `active` });\n });\n\n return cells;\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n const relevant = [`value`, `format`, `locales`, `prefix`, `suffix`, `noAnimate`].some(p => changed.has(p));\n if (!relevant && this._ready)\n return;\n\n const nf = this._numberFormat();\n this._formatted = `${this.prefix}${nf.format(this.value)}${this.suffix}`;\n this.setAttribute(`aria-label`, this._formatted);\n this.toggleAttribute(`data-static`, !this._motionOK());\n\n const first = !this._ready;\n const motionOK = this._motionOK() && !first;\n const next = this._buildCells(nf.formatToParts(this.value));\n const nextKeys = new Set(next.map(c => c.key));\n const prev = this._cells.filter(c => c.phase !== `leave`);\n const prevByKey = new Map(prev.map(c => [c.key, c]));\n\n const dir = this._resolveDir(first);\n const spins: Array<{ key: string; from: number; to: number }> = [];\n const merged: ViewCell[] = [];\n\n for (const cell of next) {\n const before = prevByKey.get(cell.key);\n if (before) {\n if (motionOK && cell.kind === `digit` && before.char !== cell.char) {\n spins.push({ key: cell.key, from: Number(before.char), to: Number(cell.char) });\n }\n merged.push({ ...cell, phase: `active` });\n } else {\n merged.push({ ...cell, phase: motionOK ? `enter` : `active` });\n }\n }\n\n if (motionOK) {\n for (const cell of prev) {\n if (!nextKeys.has(cell.key))\n merged.push({ ...cell, phase: `leave` });\n }\n }\n\n merged.sort((a, b) => SECTION_RANK[a.section] - SECTION_RANK[b.section] || a.pos - b.pos);\n\n this._cells = merged;\n this._pendingSpins = spins;\n this._pendingDir = dir;\n }\n\n protected override updated(): void {\n for (const spin of this._pendingSpins) this._spin(spin.key, spin.from, spin.to, this._pendingDir);\n this._pendingSpins = [];\n\n if (this._cells.some(c => c.phase === `enter`)) {\n requestAnimationFrame(() => requestAnimationFrame(() => {\n let changed = false;\n for (const cell of this._cells) {\n if (cell.phase === `enter`) {\n cell.phase = `active`;\n changed = true;\n }\n }\n if (changed) {\n this._cells = [...this._cells];\n this.requestUpdate();\n }\n }));\n }\n\n if (this._cells.some(c => c.phase === `leave`)) {\n if (this._reapTimer)\n clearTimeout(this._reapTimer);\n this._reapTimer = window.setTimeout(() => {\n this._reapTimer = 0;\n const kept = this._cells.filter(c => c.phase !== `leave`);\n if (kept.length !== this._cells.length) {\n this._cells = kept;\n this.requestUpdate();\n }\n }, this._timing(`transform`).duration + 120);\n }\n\n this._prevValue = this.value;\n this._ready = true;\n }\n\n private _spin(key: string, fromDigit: number, toDigit: number, dir: `up` | `down` | `none`): void {\n const reel = this.renderRoot.querySelector<HTMLElement>(`[data-key=\"${key}\"] .reel`);\n if (!reel)\n return;\n\n const fromOffset = 10 + fromDigit;\n let toOffset: number;\n if (dir === `up`) {\n toOffset = fromOffset + mod(toDigit - fromDigit, 10);\n } else if (dir === `down`) {\n toOffset = fromOffset - mod(fromDigit - toDigit, 10);\n } else {\n toOffset = [toDigit, 10 + toDigit, 20 + toDigit].reduce((best, candidate) =>\n Math.abs(candidate - fromOffset) < Math.abs(best - fromOffset) ? candidate : best);\n }\n\n const { duration, easing } = this._timing(`spin`);\n this._reelAnims.get(key)?.cancel();\n\n if (duration === 0) {\n reel.style.setProperty(`--o`, String(10 + toDigit));\n return;\n }\n\n const anim = reel.animate(\n [\n { transform: `translateY(calc(-1em * ${fromOffset}))` },\n { transform: `translateY(calc(-1em * ${toOffset}))` },\n ],\n { duration, easing, fill: `both` },\n );\n this._reelAnims.set(key, anim);\n anim.finished\n .then(() => {\n reel.style.setProperty(`--o`, String(10 + toDigit));\n anim.cancel();\n this._reelAnims.delete(key);\n })\n .catch(() => { /* superseded */ });\n }\n\n private _renderCell(cell: ViewCell) {\n if (cell.kind === `digit`) {\n return html`\n <span class=\"cell digit\" part=\"digit\" data-key=${cell.key} data-phase=${cell.phase}>\n <span class=\"reel\" style=${`--o:${10 + Number(cell.char)}`}>\n ${REEL_DIGITS.map(d => html`<span>${d}</span>`)}\n </span>\n </span>\n `;\n }\n return html`\n <span class=\"cell symbol\" part=\"symbol\" data-key=${cell.key} data-phase=${cell.phase}>${cell.char}</span>\n `;\n }\n\n protected override render() {\n const section = (name: CellSection) => this._cells.filter(c => c.section === name);\n const integer = [...section(`integer`)].reverse();\n\n return html`\n ${this.prefix ? html`<span class=\"affix\" part=\"prefix\">${this.prefix}</span>` : nothing}\n <span class=\"number\" part=\"number\" aria-hidden=\"true\">\n <span class=\"run lead\">${section(`lead`).map(c => this._renderCell(c))}</span>\n <span class=\"run integer\" part=\"integer\">\n ${repeat(integer, c => c.key, c => this._renderCell(c))}\n </span>\n ${section(`decimal`).map(c => this._renderCell(c))}\n <span class=\"run fraction\" part=\"fraction\">\n ${repeat(section(`fraction`), c => c.key, c => this._renderCell(c))}\n </span>\n <span class=\"run trail\">${section(`trail`).map(c => this._renderCell(c))}</span>\n </span>\n ${this.suffix ? html`<span class=\"affix\" part=\"suffix\">${this.suffix}</span>` : nothing}\n `;\n }\n\n static override styles = css`\n :host {\n --sliding-number-spin-duration: 0.7s;\n --sliding-number-spin-easing: cubic-bezier(0.16, 1, 0.3, 1);\n --sliding-number-transform-duration: 0.5s;\n --sliding-number-transform-easing: cubic-bezier(0.16, 1, 0.3, 1);\n --sliding-number-opacity-duration: 0.35s;\n --sliding-number-digit-width: 1ch;\n\n display: inline-flex;\n align-items: flex-end;\n line-height: 1;\n font-variant-numeric: tabular-nums;\n }\n\n .number,\n .run {\n display: inline-flex;\n /* Every cell is exactly 1em tall, so aligning bottom edges keeps\n every glyph on the same line without relying on synthesised\n flex baselines (which break under overflow: hidden). */\n align-items: flex-end;\n white-space: nowrap;\n }\n\n .affix {\n line-height: 1;\n }\n\n /* Integer digits stack right-to-left so the units column (next to the\n decimal point) stays put while higher places grow outward. */\n .run.integer {\n flex-direction: row-reverse;\n }\n\n .cell {\n display: block;\n height: 1em;\n line-height: 1;\n text-align: center;\n overflow: hidden;\n transition:\n width var(--sliding-number-transform-duration) var(--sliding-number-transform-easing),\n max-width var(--sliding-number-transform-duration) var(--sliding-number-transform-easing),\n opacity var(--sliding-number-opacity-duration) var(--sliding-number-transform-easing);\n }\n\n .cell.digit {\n position: relative;\n width: var(--sliding-number-digit-width);\n }\n\n .cell.symbol {\n max-width: 4ch;\n }\n\n .cell[data-phase='enter'],\n .cell[data-phase='leave'] {\n opacity: 0;\n }\n\n .cell.digit[data-phase='enter'],\n .cell.digit[data-phase='leave'] {\n width: 0;\n }\n\n .cell.symbol[data-phase='enter'],\n .cell.symbol[data-phase='leave'] {\n max-width: 0;\n }\n\n .reel {\n position: absolute;\n inset: 0 0 auto 0;\n display: flex;\n flex-direction: column;\n will-change: transform;\n transform: translateY(calc(-1em * var(--o, 10)));\n }\n\n .reel > span {\n display: block;\n height: 1em;\n line-height: 1;\n text-align: center;\n }\n\n :host([data-static]) .cell {\n transition: none;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-sliding-number': SlidingNumberElement;\n }\n}\n","import { css, html, LitElement } from \"lit\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n@customElement(`ixfx-tab-panel`)\nexport class TabPanelElement extends LitElement {\n render() {\n return html`<slot></slot>`;\n }\n\n static styles = [themeFallbacks, css`\n :host {\n display:none;\n height:100%;\n width:100%;\n }\n\n :host([selected]) {\n background: var(--surface-3);\n display:block;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-tab-panel\": TabPanelElement;\n }\n}\n","import type { CommandRegistry } from '@clinth/ui-commands';\nimport type { TabListItemElement } from './tab-list-item.js';\nimport type { TabListChangeDetail, TabListElement } from './tab-list.js';\nimport type { TabPanelElement } from './tab-panel.js';\nimport type { TabPanelsElement } from './tab-panels.js';\nimport './tab-list-item.js';\nimport './tab-panel.js';\n\n/** A single tab managed by a {@link TabController}. */\nexport type Tab = {\n /** id of the `ixfx-tab-list-item` */\n readonly id: string;\n /** id of the `ixfx-tab-panel` (the item's `for` value) */\n readonly forId: string;\n readonly item: TabListItemElement;\n readonly panel: TabPanelElement;\n label: string;\n iconName?: string;\n};\n\nexport type TabAddOptions = {\n label: string;\n /** id for the tab item; derived from the label if omitted */\n id?: string;\n /** id for the panel (and the item's `for`); derived from the label if omitted */\n forId?: string;\n iconName?: string;\n description?: string;\n closeable?: boolean;\n /** Elements to slot into the tab's `slot=\"toolbar\"` */\n toolbar?: HTMLElement[];\n /** Panel content: a node, text, or a callback given the fresh panel element */\n content?: Node | string | ((panel: TabPanelElement) => void);\n /** Select the new tab immediately (default `true`) */\n select?: boolean;\n /** Insertion index among existing tabs (default: append) */\n index?: number;\n};\n\nexport type TabControllerOptions = {\n /**\n * When provided, a command is registered per tab (id = tab id). Invoking\n * `commands.invoke(id)` selects the tab.\n */\n commands?: CommandRegistry;\n /** Fired after a tab becomes selected (via click or programmatic select) */\n onSelect?: (tab: Tab, previous: Tab | undefined) => void;\n onAdd?: (tab: Tab) => void;\n onRemove?: (tab: Tab) => void;\n onReorder?: (tabs: Tab[]) => void;\n};\n\n/**\n * Connects an `ixfx-tab-list` to an `ixfx-tab-panels` container, handling the\n * wiring between them (header clicks show the matching panel, closing a tab\n * removes its panel, etc.) and offering an API to select, add, remove, rename\n * and reorder tabs.\n *\n * @example\n * ```ts\n * const ctrl = new TabController(\n * document.querySelector('ixfx-tab-list'),\n * document.querySelector('ixfx-tab-panels'),\n * );\n * ctrl.connect();\n *\n * ctrl.addTab({ label: 'Console', content: 'Console panel' });\n * ctrl.selectTab('Console');\n * ```\n */\nexport class TabController {\n readonly #list: TabListElement;\n readonly #panels: TabPanelsElement;\n readonly #opts: TabControllerOptions;\n\n #tabs: Tab[] = [];\n #signal: AbortController | undefined;\n #observer: MutationObserver | undefined;\n #commands: CommandRegistry | undefined;\n #registeredCommands = new Set<string>();\n\n constructor(\n list: TabListElement,\n panels: TabPanelsElement,\n options: TabControllerOptions = {},\n ) {\n this.#list = list;\n this.#panels = panels;\n this.#opts = options;\n this.#commands = options.commands;\n }\n\n connect(): void {\n this.disconnect();\n this.#signal = new AbortController();\n const { signal } = this.#signal;\n\n this.#list.addEventListener(`change`, this.#onChange, { signal });\n this.#list.addEventListener(`reorder`, this.#onReorder, { signal });\n this.#list.addEventListener(`close`, this.#onClose, { signal });\n\n this.#observer = new MutationObserver(() => this.#rebuild());\n this.#observer.observe(this.#list, { childList: true });\n this.#observer.observe(this.#panels, { childList: true });\n\n this.#rebuild();\n\n // Establish the list↔panels association and mirror the initially-selected\n // header into the panels (its internal Promise-based initial sync).\n this.#panels.syncWithList(this.#list);\n\n for (const tab of this.#tabs) {\n this.#registerCommand(tab);\n }\n }\n\n disconnect(): void {\n this.#signal?.abort();\n this.#signal = undefined;\n this.#observer?.disconnect();\n this.#observer = undefined;\n\n for (const tab of this.#tabs) {\n this.#unregisterCommand(tab);\n }\n this.#registeredCommands.clear();\n this.#tabs = [];\n }\n\n // ── Selection ────────────────────────────────────────────────────────\n\n /**\n * Select a tab as if it was clicked — activates the header (deactivating the\n * others) and shows its panel.\n *\n * `sel` may be a tab id, the panel id its `for` points at, its label text\n * (case-insensitive), or the tab item element itself.\n *\n * Returns true if a tab was found.\n */\n selectTab(sel: string | TabListItemElement): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n const previous = this.getSelected();\n if (previous?.id === tab.id) {\n // Header already active — still ensure the content panel is shown.\n this.#panels.selectPanel(tab.forId);\n return true;\n }\n\n this.#list.selectElement(tab.item);\n this.#panels.selectPanel(tab.forId);\n this.#opts.onSelect?.(tab, previous);\n return true;\n }\n\n selectNext(): boolean {\n return this.#selectOffset(1);\n }\n\n selectPrevious(): boolean {\n return this.#selectOffset(-1);\n }\n\n getSelected(): Tab | undefined {\n return this.#tabs.find(t => t.item.hasAttribute(`selected`));\n }\n\n getTabs(): Tab[] {\n return [...this.#tabs];\n }\n\n getTab(id: string): Tab | undefined {\n return this.#tabs.find(t => t.id === id);\n }\n\n // ── Mutation ─────────────────────────────────────────────────────────\n\n addTab(opts: TabAddOptions): Tab {\n const { id, forId } = this.#idsFor(opts);\n\n const item = document.createElement(`ixfx-tab-list-item`) as TabListItemElement;\n item.id = id;\n item.setAttribute(`for`, forId);\n item.closeable = opts.closeable ?? true;\n item.append(opts.label);\n if (opts.iconName) {\n item.iconName = opts.iconName;\n }\n if (opts.description) {\n item.description = opts.description;\n }\n for (const el of opts.toolbar ?? []) {\n el.slot = `toolbar`;\n item.append(el);\n }\n\n const panel = document.createElement(`ixfx-tab-panel`) as TabPanelElement;\n panel.id = forId;\n if (opts.content !== undefined) {\n this.#fillContent(panel, opts.content);\n }\n\n const index = Math.max(0, Math.min(opts.index ?? this.#tabs.length, this.#tabs.length));\n this.#insertElement(this.#list, item, index);\n this.#insertElement(this.#panels, panel, index);\n\n const tab: Tab = {\n id,\n forId,\n item,\n panel,\n label: opts.label,\n iconName: opts.iconName,\n };\n this.#tabs.splice(index, 0, tab);\n\n this.#registerCommand(tab);\n this.#opts.onAdd?.(tab);\n\n if (opts.select ?? true) {\n this.selectTab(id);\n }\n return tab;\n }\n\n removeTab(sel: string | TabListItemElement): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n const index = this.#tabs.indexOf(tab);\n const wasSelected = tab.item.hasAttribute(`selected`);\n const adjacent = wasSelected ? this.#adjacentTab(index) : undefined;\n\n tab.item.remove();\n tab.panel.remove();\n this.#removeFromIndex(tab);\n this.#unregisterCommand(tab);\n this.#opts.onRemove?.(tab);\n\n if (adjacent) {\n this.selectTab(adjacent.id);\n }\n return true;\n }\n\n renameTab(sel: string | TabListItemElement, label: string): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n for (const child of [...tab.item.childNodes]) {\n const isToolbar = child.nodeType === Node.ELEMENT_NODE\n && (child as HTMLElement).slot === `toolbar`;\n if (isToolbar)\n continue;\n tab.item.removeChild(child);\n }\n tab.item.prepend(label);\n tab.label = label;\n\n this.#reregisterCommand(tab);\n return true;\n }\n\n setTabIcon(sel: string | TabListItemElement, iconName?: string): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n if (iconName) {\n tab.item.iconName = iconName;\n tab.iconName = iconName;\n } else {\n tab.item.iconName = undefined;\n tab.item.removeAttribute(`icon-name`);\n tab.iconName = undefined;\n }\n return true;\n }\n\n // ── Event handlers ───────────────────────────────────────────────────\n\n #onChange = (event: Event): void => {\n const detail = (event as CustomEvent<TabListChangeDetail>).detail;\n this.#panels.selectPanel(detail.for);\n\n const tab = this.#tabs.find(t => t.forId === detail.for);\n if (!tab)\n return;\n const previous = detail.previous\n ? this.#tabs.find(t => t.id === detail.previous)\n : undefined;\n this.#opts.onSelect?.(tab, previous);\n };\n\n #onReorder = (): void => {\n this.#rebuild();\n this.#opts.onReorder?.(this.#tabs);\n };\n\n #onClose = (event: Event): void => {\n const target = event.target as HTMLElement | null;\n const item = target?.closest(`ixfx-tab-list-item`) as TabListItemElement | null;\n const tab = item ? this.#tabByItem(item) : undefined;\n if (!tab)\n return;\n\n const index = this.#tabs.indexOf(tab);\n const wasSelected = tab.item.hasAttribute(`selected`);\n const adjacent = wasSelected ? this.#adjacentTab(index) : undefined;\n\n // The item removed itself (tab-list-item close handler); remove the panel\n // and drop the tab from the index.\n tab.panel.remove();\n this.#removeFromIndex(tab);\n this.#unregisterCommand(tab);\n this.#opts.onRemove?.(tab);\n\n if (adjacent) {\n this.selectTab(adjacent.id);\n }\n };\n\n // ── Internal helpers ─────────────────────────────────────────────────\n\n #selectOffset(offset: number): boolean {\n const tabs = this.#tabs;\n if (tabs.length === 0)\n return false;\n const current = this.getSelected();\n const index = current ? tabs.indexOf(current) : offset === 1 ? -1 : 0;\n const next = (index + offset + tabs.length) % tabs.length;\n return this.selectTab(tabs[next].id);\n }\n\n #resolveTab(sel: string | TabListItemElement): Tab | undefined {\n if (typeof sel !== `string`) {\n return this.#tabs.find(t => t.item === sel);\n }\n const label = sel.trim().toLowerCase();\n return this.#tabs.find(t => t.id === sel)\n ?? this.#tabs.find(t => t.forId === sel)\n ?? this.#tabs.find(t => t.label.toLowerCase() === label);\n }\n\n #tabByItem(item: TabListItemElement): Tab | undefined {\n return this.#tabs.find(t => t.item === item);\n }\n\n #adjacentTab(index: number): Tab | undefined {\n const tabs = this.#tabs;\n if (tabs.length <= 1)\n return undefined;\n return tabs[index + 1] ?? tabs[index - 1];\n }\n\n #removeFromIndex(tab: Tab): void {\n const index = this.#tabs.indexOf(tab);\n if (index >= 0) {\n this.#tabs.splice(index, 1);\n }\n }\n\n #idsFor(opts: TabAddOptions): { id: string; forId: string } {\n const base = this.#slug(opts.label) || `tab`;\n return {\n id: opts.id ?? this.#uniqueId(`tab-${base}`),\n forId: opts.forId ?? this.#uniqueId(`panel-${base}`),\n };\n }\n\n #slug(value: string): string {\n return value.toLowerCase()\n .replace(/[^a-z0-9]+/g, `-`)\n .replace(/^-+|-+$/g, ``);\n }\n\n #uniqueId(base: string): string {\n let candidate = base;\n let n = 2;\n while (document.getElementById(candidate)) {\n candidate = `${base}-${n++}`;\n }\n return candidate;\n }\n\n #fillContent(panel: TabPanelElement, content: Node | string | ((panel: TabPanelElement) => void)): void {\n if (typeof content === `function`) {\n content(panel);\n return;\n }\n if (typeof content === `string`) {\n panel.append(document.createTextNode(content));\n return;\n }\n panel.append(content);\n }\n\n #insertElement(container: HTMLElement, el: HTMLElement, index: number): void {\n const children = Array.from(container.children);\n container.insertBefore(el, children[index] ?? null);\n }\n\n #rebuild(): void {\n const panels = new Map<string, TabPanelElement>();\n for (const el of this.#panels.querySelectorAll(`ixfx-tab-panel`)) {\n panels.set(el.id, el as TabPanelElement);\n }\n\n const tabs: Tab[] = [];\n for (const item of this.#list.querySelectorAll(`ixfx-tab-list-item`) as NodeListOf<TabListItemElement>) {\n const forId = item.getAttribute(`for`) ?? ``;\n const panel = panels.get(forId);\n if (!panel)\n continue;\n tabs.push({\n id: item.id || forId,\n forId,\n item,\n panel,\n label: this.#labelOf(item),\n iconName: item.iconName,\n });\n }\n this.#tabs = tabs;\n }\n\n /** The tab's visible label text, excluding any `slot=\"toolbar\"` content. */\n #labelOf(item: TabListItemElement): string {\n const clone = item.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(`[slot=\"toolbar\"]`).forEach(el => el.remove());\n return (clone.textContent ?? ``).trim();\n }\n\n #registerCommand(tab: Tab): void {\n if (!this.#commands)\n return;\n if (tab.item.commandActive)\n return;\n if (this.#commands.has(tab.id))\n return;\n this.#commands.register({\n id: tab.id,\n label: tab.label,\n description: tab.item.description ?? tab.label,\n icon: tab.iconName,\n execute: () => {\n this.selectTab(tab.id);\n },\n });\n this.#registeredCommands.add(tab.id);\n }\n\n #unregisterCommand(tab: Tab): void {\n if (!this.#commands)\n return;\n if (this.#registeredCommands.has(tab.id)) {\n this.#commands.unregister(tab.id);\n this.#registeredCommands.delete(tab.id);\n }\n }\n\n #reregisterCommand(tab: Tab): void {\n if (!this.#commands || !this.#registeredCommands.has(tab.id))\n return;\n const existing = this.#commands.get(tab.id);\n if (!existing)\n return;\n this.#commands.unregister(tab.id);\n this.#commands.register({ ...existing, label: tab.label });\n }\n}\n","import type { TabListItemElement } from \"./tab-list-item.js\";\nimport type { TabListElement } from \"./tab-list.js\";\nimport type { TabPanelElement } from \"./tab-panel.js\";\nimport { css, html, LitElement } from \"lit\";\nimport { queryAssignedElements } from \"lit/decorators.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n@customElement(`ixfx-tab-panels`)\nexport class TabPanelsElement extends LitElement {\n @queryAssignedElements()\n _listItems!: TabPanelElement[];\n\n /**\n * The `ixfx-tab-list` this panels element is associated with, established by\n * `syncWithList()`. Used by `selectTab()` to activate the matching header.\n */\n #list: TabListElement | undefined;\n\n /**\n * Triggered when a panel is being de-selected\n */\n onUnselectedPanel?: (id: string, el: TabPanelElement) => void;\n /**\n * Triggered before panel is selected\n */\n onSelectingPanel?: (id: string, el: TabPanelElement) => void;\n /**\n * Triggered after panel is selected\n */\n onSelectedPanel?: (id: string, el: TabPanelElement) => void;\n render() {\n return html`<slot></slot>`;\n }\n\n getSelectedElement() {\n for (const el of this._listItems) {\n if (this.#isSelected(el))\n return el;\n }\n }\n\n #isSelected(el: TabPanelElement) {\n // const v = el.getAttribute(`selected`);\n // console.log(`id: ${ el.id } v: ${ v }`);\n return el.hasAttribute(`selected`);\n }\n\n #unselect(el: TabPanelElement) {\n el.removeAttribute(`selected`);\n if (this.onUnselectedPanel) {\n this.onUnselectedPanel(el.id, el);\n }\n }\n\n #select(el: TabPanelElement) {\n if (this.onSelectingPanel) {\n this.onSelectingPanel(el.id, el);\n }\n el.setAttribute(`selected`, ``);\n if (this.onSelectedPanel) {\n this.onSelectedPanel(el.id, el);\n }\n }\n\n syncWithList(el: TabListElement) {\n this.#list = el;\n const doSync = () => {\n const t = el.getSelectedElement();\n if (!t)\n return;\n const forEl = t.getAttribute(`for`);\n if (forEl)\n this.selectPanel(forEl);\n };\n // Wait for both the list and ourselves to be fully rendered\n // so that getSelectedElement() and _listItems both work.\n Promise.all([el.updateComplete, this.updateComplete]).then(doSync);\n }\n\n selectPanel(id: string) {\n const current = this.getSelectedElement();\n if (current) {\n if (current.id === id)\n return;\n this.#unselect(current);\n }\n\n let found = false;\n for (const el of this._listItems) {\n if (el.id === id) {\n this.#select(el);\n found = true;\n }\n }\n return found;\n }\n\n /**\n * Select a tab as if the user clicked it — activates the matching header in\n * the associated `ixfx-tab-list` (deactivating the others) and shows its\n * panel.\n *\n * `nameOrTitle` may be the label text of a tab (e.g. `'Home'`, matched\n * case-insensitively) or the panel id its `for` attribute points at\n * (e.g. `'panel-home'`). If no tab matches, `nameOrTitle` is tried directly\n * as a panel id.\n *\n * The tab list must first be associated via `syncWithList()` for the header\n * to be activated; panel selection works regardless.\n *\n * Returns true if a panel was found and selected.\n */\n selectTab(nameOrTitle: string): boolean {\n const item = this.#findTabItem(nameOrTitle);\n if (item) {\n this.#list?.selectElement(item);\n return this.selectPanel(item.getAttribute(`for`) ?? ``) === true;\n }\n // Fall back to treating the value as a panel id directly.\n return this.selectPanel(nameOrTitle) === true;\n }\n\n #findTabItem(nameOrTitle: string): TabListItemElement | undefined {\n const list = this.#list;\n if (!list)\n return undefined;\n const items = Array.from(list.querySelectorAll(`ixfx-tab-list-item`)) as TabListItemElement[];\n\n // Prefer an exact match against the `for` attribute (panel id).\n for (const item of items) {\n if (item.getAttribute(`for`) === nameOrTitle)\n return item;\n }\n\n // Otherwise match on the tab's label text, case-insensitively.\n const label = nameOrTitle.trim().toLowerCase();\n for (const item of items) {\n if (this.#labelOf(item).toLowerCase() === label)\n return item;\n }\n return undefined;\n }\n\n /** The tab's visible label text, excluding any `slot=\"toolbar\"` content. */\n #labelOf(item: TabListItemElement): string {\n const clone = item.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(`[slot=\"toolbar\"]`).forEach(el => el.remove());\n return (clone.textContent ?? ``).trim();\n }\n\n static styles = css`\n :host {\n display: block;\n }\n \n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-tab-panels\": TabPanelsElement;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n/**\n * `ixfx-text-shimmer` — a label whose text is dimmed at rest, with a band of\n * brighter colour that sweeps horizontally across it on a loop. Useful as a\n * lightweight \"still working…\" indicator (as seen in Claude Code / Codex).\n *\n * Content comes from the `text` property, or failing that the default slot:\n * ```html\n * <ixfx-text-shimmer text=\"Thinking…\"></ixfx-text-shimmer>\n * <ixfx-text-shimmer>Reticulating splines…</ixfx-text-shimmer>\n * ```\n *\n * CSS variables (set on the element or an ancestor):\n * | Variable | Default | Purpose |\n * |---|---|---|\n * | `--text-shimmer-color` | `var(--surface-3-text)` | Resting / base text colour |\n * | `--text-shimmer-gradient-color` | `var(--surface-2-text)` | Colour of the moving highlight |\n * | `--text-shimmer-duration` | `2s` | Time for one sweep |\n * | `--text-shimmer-spread` | `15%` | Half-width of the highlight band along the sweep track (larger = wider, softer) |\n *\n * Add the `paused` attribute to stop the sweep and show flat base colour.\n * Respects `prefers-reduced-motion`.\n */\n@customElement(`ixfx-text-shimmer`)\nexport class TextShimmerElement extends LitElement {\n /** Text to display. When empty, the default slot is used instead. */\n @property({ type: String }) text = ``;\n\n /** When set, the sweep stops and the text shows flat base colour. */\n @property({ type: Boolean, reflect: true }) paused = false;\n\n protected override render() {\n return html`<span class=\"shimmer\" part=\"text\"\n >${this.text === `` ? html`<slot></slot>` : this.text}</span\n >`;\n }\n\n static override styles = css`\n :host {\n --text-shimmer-color: var(--surface-3-text, #888);\n --text-shimmer-gradient-color: var(--surface-2-text, #fff);\n --text-shimmer-duration: 2s;\n --text-shimmer-spread: 15%;\n\n display: inline-block;\n color: var(--text-shimmer-color);\n }\n\n .shimmer {\n background-image: linear-gradient(\n 90deg,\n var(--text-shimmer-color) 0%,\n var(--text-shimmer-color) calc(50% - var(--text-shimmer-spread)),\n var(--text-shimmer-gradient-color) 50%,\n var(--text-shimmer-color) calc(50% + var(--text-shimmer-spread)),\n var(--text-shimmer-color) 100%\n );\n background-size: 250% 100%;\n background-repeat: no-repeat;\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n -webkit-text-fill-color: transparent;\n animation: ixfx-text-shimmer-sweep var(--text-shimmer-duration) linear infinite;\n }\n\n /* Sweep the highlight band from the right edge to the left edge. */\n @keyframes ixfx-text-shimmer-sweep {\n from {\n background-position: 100% center;\n }\n to {\n background-position: 0% center;\n }\n }\n\n :host([paused]) .shimmer {\n animation: none;\n background-image: none;\n color: var(--text-shimmer-color);\n -webkit-text-fill-color: var(--text-shimmer-color);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .shimmer {\n animation: none;\n background-image: none;\n color: var(--text-shimmer-color);\n -webkit-text-fill-color: var(--text-shimmer-color);\n }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-text-shimmer': TextShimmerElement;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n@customElement(`ixfx-toolbar-group`)\nexport class ToolbarGroupElement extends LitElement {\n @property({ type: String }) label = ``;\n @property({ type: Boolean, reflect: true }) grow = false;\n /**\n * Set by the parent `ixfx-toolbar` when `allow-reorder` is present.\n * Shows the vertical grab handle; drag starts from the handle only.\n */\n @property({ type: Boolean, reflect: true }) reorderable = false;\n\n static override styles = [themeFallbacks, handleStyles, css`\n :host {\n display: flex;\n flex-direction: column;\n align-items: var(--toolbar-group-align-items, center);\n justify-content: var(--toolbar-group-justify-content, flex-start);\n gap: var(--toolbar-gap, var(--space-s));\n padding: var(--toolbar-group-padding, var(--space-xs));\n border: 1px solid var(--border-subtle, var(--border));\n border-radius: var(--radius-s);\n background: var(--surface-3);\n min-width: 0;\n }\n :host([reorderable]) {\n flex-direction: row;\n align-items: center;\n }\n :host(:not([label])) {\n border: none;\n background: transparent;\n padding: 0;\n }\n .grab-handle {\n display: none;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n padding-inline: var(--space-2xs, 2px);\n cursor: grab;\n touch-action: none;\n flex: 0 0 auto;\n }\n :host([reorderable]) .grab-handle { display: inline-flex; }\n :host([reorderable]) .grab-handle .ixfx-handle {\n --ixfx-handle-length: 18px;\n }\n :host([drag-source]) .grab-handle { cursor: grabbing; }\n :host([drag-source]) .grab-handle .ixfx-handle {\n color: var(--accent);\n opacity: 1;\n }\n .body {\n display: flex;\n flex-direction: column;\n align-items: var(--toolbar-group-align-items, center);\n justify-content: var(--toolbar-group-justify-content, flex-start);\n gap: var(--toolbar-gap, var(--space-s));\n min-width: 0;\n flex: 1 1 auto;\n }\n .label-row {\n display: none;\n font-size: var(--text-s, 12px);\n color: var(--surface-muted-text);\n padding-inline: var(--space-xs);\n white-space: nowrap;\n border-bottom: 1px solid var(--border-subtle);\n margin-bottom: var(--space-xs);\n }\n :host([label][show-label]) .label-row { display: block; }\n :host(:not([label])) .label-row { display: none; }\n :host([grow]) { flex: 1 1 auto; min-width: 0; }\n :host([hidden]) { display: none !important; }\n .components { display: flex; }\n ::slotted(*) { flex: 0 0 auto; }\n ::slotted([grow]) { flex: 1 1 auto; }\n `];\n\n protected override render() {\n return html`\n <div class=\"grab-handle\" part=\"grab-handle\" title=\"Drag to reorder\" aria-hidden=\"true\">\n <span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"vertical\"></span>\n </div>\n <div class=\"body\">\n <div class=\"label-row\">${this.label}</div>\n <div class=\"components\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap { 'ixfx-toolbar-group': ToolbarGroupElement }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { DragGhost } from '../util/drag-ghost.js';\nimport type { ToolbarGroupElement } from './toolbar-group.js';\nimport type { ToolbarAlign, ToolbarLayout, ToolbarOrientation, ToolbarVerticalWriting } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { popupSurfaceStyles } from '../styles/popup.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\n\nexport interface ToolbarGroupReorderDetail {\n readonly fromIndex: number;\n readonly toIndex: number;\n readonly group: ToolbarGroupElement;\n}\n\nexport type ToolbarGroupReorderEvent = CustomEvent<ToolbarGroupReorderDetail>;\n\nexport interface ToolbarElementEventMap {\n reorder: ToolbarGroupReorderEvent;\n}\n\n/**\n * JSON-safe snapshot of toolbar group order, suitable for `localStorage`\n * or any other user-preference store. See `getLayoutSnapshot` /\n * `applyLayoutSnapshot`.\n */\nexport interface ToolbarLayoutSnapshot {\n readonly version: 1;\n readonly order: readonly string[];\n}\n\n/** Pointer movement threshold (px) before a press becomes a drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\n/**\n * Pure helper: nearest gap index for a pointer position along one axis.\n * `edges` are the [start, end] of each sibling (excluding the drag source),\n * in visual order. Returns 0..edges.length.\n */\nexport function toolbarGapIndex(edges: ReadonlyArray<readonly [number, number]>, pos: number): number {\n let bestGap = 0;\n let bestDist = Number.POSITIVE_INFINITY;\n for (let i = 0; i < edges.length; i++) {\n const [start, end] = edges[i];\n const mid = (start + end) / 2;\n if (pos < mid) {\n const d = Math.abs(pos - start);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i;\n }\n } else {\n const d = Math.abs(pos - end);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i + 1;\n }\n }\n }\n return bestGap;\n}\n\nlet toolbarGhostStylesInjected = false;\n\n/**\n * Global ghost styling so the drag preview matches toolbar-group chrome.\n * Injected once; the ghost lives outside shadow DOM so component styles\n * cannot reach it.\n */\nfunction injectToolbarGhostStyles(): void {\n if (toolbarGhostStylesInjected) {\n return;\n }\n toolbarGhostStylesInjected = true;\n const style = document.createElement(`style`);\n style.textContent = `\n .ixfx-drag-ghost.ixfx-toolbar-group-ghost {\n padding: var(--space-s, 8px) var(--space-m, 16px);\n background: var(--surface-4);\n color: var(--surface-3-text);\n border: none;\n border-radius: var(--radius-s, 4px);\n font-family: var(--font-family);\n font-size: var(--text-m);\n font-weight: var(--font-weight-bold, 600);\n user-select: none;\n -webkit-user-select: none;\n }\n `;\n document.head.appendChild(style);\n}\n\n@customElement(`ixfx-toolbar`)\nexport class ToolbarElement extends LitElement {\n @property({ type: String, reflect: true }) orientation: ToolbarOrientation = `horizontal`;\n @property({ type: String, reflect: true }) layout: ToolbarLayout = `one-line`;\n @property({ type: String, attribute: `vertical-writing`, reflect: true }) verticalWriting: ToolbarVerticalWriting = `auto`;\n @property({ type: String, attribute: `toolbar-align`, reflect: true }) toolbarAlign: ToolbarAlign = `near`;\n @property({ type: Boolean, attribute: `show-group-labels`, reflect: true }) showGroupLabels = false;\n @property({ type: Boolean, attribute: `invisible-groups`, reflect: true }) invisibleGroups = false;\n @property({ type: Boolean, attribute: `allow-reorder`, reflect: true }) allowReorder = false;\n\n @state() private _overflowCount = 0;\n @state() private _popoverOpen = false;\n private _ro: ResizeObserver | null = null;\n private static _cnt = 0;\n private _anchor = `--toolbar-${ToolbarElement._cnt++}`;\n /** Natural size of items, captured while they are measurable in the main slot. */\n private _sizes = new WeakMap<HTMLElement, number>();\n private _measureQueued = false;\n\n private _dragState: {\n pointerId: number;\n source: ToolbarGroupElement;\n startX: number;\n startY: number;\n active: boolean;\n ghost: DragGhost | null;\n gapIndex: number | undefined;\n } | null = null;\n\n private _suppressNextClick = false;\n\n @query(`.inner`) private _inner!: HTMLElement;\n @query(`.overflow-popover`) private _popover!: HTMLElement;\n @query(`slot`) private _slot!: HTMLSlotElement;\n\n static override styles = [themeFallbacks, popupSurfaceStyles, css`\n :host {\n --toolbar-gap: var(--space-s);\n --toolbar-group-gap: var(--space-m);\n --toolbar-overflow: auto;\n display: block;\n position: relative;\n container-type: inline-size;\n }\n :host([orientation=\"vertical-left\"]),\n :host([orientation=\"vertical-right\"]) {\n container-type: normal;\n width: max-content;\n }\n :host([orientation=\"vertical-left\"]),\n :host([orientation=\"vertical-right\"]) { height: 100%; }\n :host([orientation=\"vertical-left\"]) .inner,\n :host([orientation=\"vertical-right\"]) .inner { height: 100%; box-sizing: border-box; width: max-content; }\n .inner {\n display: flex;\n gap: var(--toolbar-gap);\n background: var(--toolbar-bg, var(--surface-2));\n padding: var(--toolbar-padding, var(--space-s));\n border: var(--toolbar-border, var(--border-subtle));\n border-radius: var(--radius-s);\n align-items: center;\n }\n :host([orientation=\"horizontal\"]) .inner { flex-direction: row; justify-content: flex-start; }\n :host([orientation=\"vertical-left\"]) .inner { flex-direction: column-reverse; align-items: stretch; }\n :host([orientation=\"vertical-right\"]) .inner { flex-direction: column; align-items: stretch; }\n :host([layout=\"wrap\"]) .inner { flex-wrap: wrap; }\n :host([layout=\"one-line\"]) .inner { flex-wrap: nowrap; overflow: hidden; }\n :host([toolbar-align=\"far\"][orientation=\"horizontal\"]) .inner { justify-content: flex-end; }\n :host([orientation=\"vertical-left\"][vertical-writing=\"auto\"]) ::slotted(*) { writing-mode: sideways-lr; }\n :host([orientation=\"vertical-right\"][vertical-writing=\"auto\"]) ::slotted(*) { writing-mode: vertical-lr; }\n :host([vertical-writing=\"up\"]) ::slotted(*) { writing-mode: vertical-rl; text-orientation: upright; }\n :host([vertical-writing=\"down\"]) ::slotted(*) { writing-mode: vertical-lr; }\n :host([vertical-writing=\"none\"]) ::slotted(*) { writing-mode: horizontal-tb; }\n ::slotted(*) { flex: 0 0 auto; }\n ::slotted([grow]), ::slotted(ixfx-toolbar-group[grow]) { flex: 1 1 auto; }\n ::slotted([hidden]) { display: none !important; }\n :host([invisible-groups]) ::slotted(ixfx-toolbar-group) { --toolbar-group-border: none; }\n .overflow-btn {\n anchor-name: var(--anchor-name);\n flex-shrink: 0;\n }\n .overflow-btn[hidden] { display: none; }\n .overflow-popover {\n position: fixed;\n inset: auto;\n margin: 0;\n position-anchor: var(--anchor-name);\n position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;\n position-visibility: anchors-visible;\n max-height: min(60vh, 400px);\n max-width: min(90vw, 320px);\n overflow: auto;\n overscroll-behavior: contain;\n z-index: 100;\n padding: var(--space-s);\n flex-direction: column;\n gap: var(--space-s);\n }\n :host([orientation=\"horizontal\"]) .overflow-popover {\n position-area: bottom span-left;\n margin-top: var(--toolbar-overflow-gap, 8px);\n }\n :host([orientation=\"vertical-left\"]) .overflow-popover {\n position-area: right span-bottom;\n margin-left: var(--toolbar-overflow-gap, 8px);\n }\n :host([orientation=\"vertical-right\"]) .overflow-popover {\n position-area: left span-bottom;\n margin-right: var(--toolbar-overflow-gap, 8px);\n }\n .overflow-popover:popover-open { display: flex; }\n .overflow-popover ::slotted(*) { writing-mode: horizontal-tb; text-orientation: mixed; }\n\n :host([allow-reorder]) ::slotted(ixfx-toolbar-group[drag-source]) {\n opacity: 0.4;\n }\n\n /* While dragging, suppress text selection inside the toolbar. */\n :host([dragging]),\n :host([dragging]) ::slotted(*) {\n user-select: none;\n -webkit-user-select: none;\n }\n\n .drop-caret {\n position: absolute;\n top: 0;\n left: 0;\n background: var(--accent);\n border-radius: 1px;\n pointer-events: none;\n z-index: 1;\n }\n `];\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.style.setProperty(`--anchor-name`, this._anchor);\n // Capture phase so we can swallow the trailing click after a real reorder\n // before it reaches buttons inside the dragged group.\n this.addEventListener(`click`, this._onClickCapture, true);\n }\n\n protected override firstUpdated(): void {\n this._slot.addEventListener(`slotchange`, () => {\n this._updateGroups();\n this._scheduleMeasure();\n });\n this._ro = new ResizeObserver(() => this._scheduleMeasure());\n this._ro.observe(this._inner);\n this._popover.addEventListener(`toggle`, () => {\n this._popoverOpen = this._popover.matches(`:popover-open`);\n });\n this._scheduleMeasure();\n this._updateGroups();\n }\n\n protected override updated(changed: Map<string, unknown>): void {\n if (changed.has(`showGroupLabels`) || changed.has(`allowReorder`))\n this._updateGroups();\n }\n\n /** Groups in the main slot (not overflow) that can participate in reorder. */\n private _mainGroups(): ToolbarGroupElement[] {\n return (Array.from(this.children) as HTMLElement[]).filter(\n el => el.tagName === `IXFX-TOOLBAR-GROUP` && el.getAttribute(`slot`) !== `overflow`,\n ) as ToolbarGroupElement[];\n }\n\n // ── Public API: group order + layout snapshots ─────────────────────────\n\n /**\n * Stable key identifying a group across save/restore: its `id`, falling\n * back to `label`. Groups with neither get an empty key, which still\n * round-trips as long as the set of groups is unchanged. Give groups a\n * unique `id` for reliable preference persistence.\n */\n private _groupKey(group: ToolbarGroupElement): string {\n return group.id || group.label || ``;\n }\n\n /** Keys of the main-slot groups in current DOM order. */\n getGroupOrder(): string[] {\n return this._mainGroups().map(group => this._groupKey(group));\n }\n\n /**\n * Reorder main-slot groups to match `order` (keys as returned by\n * `getGroupOrder`). Unknown keys are ignored; groups not mentioned keep\n * their relative order at the end. Each moved group fires a `reorder`\n * event, exactly as if dragged.\n */\n setGroupOrder(order: readonly string[]): void {\n const groups = this._mainGroups();\n if (groups.length === 0)\n return;\n const used = new Set<ToolbarGroupElement>();\n const desired: ToolbarGroupElement[] = [];\n for (const key of order) {\n const match = groups.find(candidate => !used.has(candidate) && candidate.id === key && key !== ``)\n ?? groups.find(candidate => !used.has(candidate) && this._groupKey(candidate) === key);\n if (match) {\n used.add(match);\n desired.push(match);\n }\n }\n const sequence = [...desired, ...groups.filter(group => !used.has(group))];\n // Pairwise bubble passes until every adjacent pair is in DOM order.\n // Guarded — each pass with a move strictly reduces disorder, and a\n // quiet pass means convergence.\n let guard = sequence.length * sequence.length + 1;\n let moved = true;\n while (moved && guard-- > 0) {\n moved = false;\n for (let i = 0; i + 1 < sequence.length; i++) {\n const before = sequence[i];\n const after = sequence[i + 1];\n if (before.compareDocumentPosition(after) & Node.DOCUMENT_POSITION_FOLLOWING)\n continue;\n if (this._insertAndEmit(before, after))\n moved = true;\n }\n }\n }\n\n /**\n * Capture the current group order as a JSON-safe snapshot for preference\n * stores: `localStorage.setItem(key, JSON.stringify(toolbar.getLayoutSnapshot()))`.\n */\n getLayoutSnapshot(): ToolbarLayoutSnapshot {\n return { version: 1, order: this.getGroupOrder() };\n }\n\n /**\n * Restore a snapshot from `getLayoutSnapshot` (e.g. parsed from\n * `localStorage`). Unknown keys are ignored. Returns `false` when the\n * value is not a valid snapshot, leaving the toolbar untouched.\n */\n applyLayoutSnapshot(snapshot: unknown): boolean {\n if (typeof snapshot !== `object` || snapshot === null)\n return false;\n const { version, order } = snapshot as { version?: unknown; order?: unknown };\n if (version !== 1 || !Array.isArray(order) || !order.every((key: unknown) => typeof key === `string`))\n return false;\n this.setGroupOrder(order as string[]);\n return true;\n }\n\n /**\n * Move `source` before `ref` (or append when `ref` is null), firing a\n * `reorder` event when the position actually changed. Returns whether a\n * move happened. Indices are measured against all light-DOM children,\n * matching the `reorder` detail of drag-reorder.\n */\n private _insertAndEmit(source: ToolbarGroupElement, ref: Node | null): boolean {\n const parent = source.parentNode;\n if (!parent)\n return false;\n const fromIndex = Array.prototype.indexOf.call(parent.children, source);\n parent.insertBefore(source, ref);\n const toIndex = Array.prototype.indexOf.call(parent.children, source);\n if (toIndex === fromIndex)\n return false;\n this.dispatchEvent(new CustomEvent<ToolbarGroupReorderDetail>(`reorder`, {\n bubbles: true,\n composed: true,\n detail: { fromIndex, toIndex, group: source },\n }));\n // Order changed: group markers and overflow sizes depend on DOM order.\n this._updateGroups();\n this._scheduleMeasure();\n return true;\n }\n\n private _updateGroups(): void {\n for (const child of Array.from(this.children) as HTMLElement[]) {\n if (child.tagName !== `IXFX-TOOLBAR-GROUP`)\n continue;\n if (this.showGroupLabels) {\n child.setAttribute(`show-label`, ``);\n } else {\n child.removeAttribute(`show-label`);\n }\n if (this.allowReorder && child.getAttribute(`slot`) !== `overflow`) {\n child.setAttribute(`reorderable`, ``);\n } else {\n child.removeAttribute(`reorderable`);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`click`, this._onClickCapture, true);\n this._ro?.disconnect();\n if (this._dragState) {\n this._abortDrag();\n this._endDrag(this._dragState.pointerId);\n }\n }\n\n private _onClickCapture = (event: Event): void => {\n if (!this._suppressNextClick)\n return;\n this._suppressNextClick = false;\n event.preventDefault();\n event.stopPropagation();\n };\n\n private _onKeyDown = (event: KeyboardEvent): void => {\n const state = this._dragState;\n if (event.key !== `Escape` || !state?.active)\n return;\n event.preventDefault();\n const pointerId = state.pointerId;\n this._abortDrag();\n this._endDrag(pointerId);\n };\n\n /**\n * Walk composedPath for the nearest ixfx-toolbar-group, requiring the press\n * to have gone through its `.grab-handle`. Drag is handle-only so every\n * control inside the group (buttons, selects, inputs) keeps working.\n */\n private _findDragTarget(event: PointerEvent): ToolbarGroupElement | null {\n if (!this.allowReorder)\n return null;\n const path = event.composedPath();\n let group: ToolbarGroupElement | null = null;\n let viaHandle = false;\n for (const node of path) {\n if (!(node instanceof HTMLElement))\n continue;\n if (node.classList.contains(`grab-handle`))\n viaHandle = true;\n if (!group && node.tagName === `IXFX-TOOLBAR-GROUP`)\n group = node as ToolbarGroupElement;\n }\n if (!group || !viaHandle)\n return null;\n if (group.getAttribute(`slot`) === `overflow`)\n return null;\n return group;\n }\n\n private _onPointerDown = (event: PointerEvent): void => {\n if (!this.allowReorder || event.button !== 0)\n return;\n const target = this._findDragTarget(event);\n if (!target?.parentNode)\n return;\n if (Array.prototype.indexOf.call(target.parentNode.children, target) < 0)\n return;\n // Don't capture yet — capturing on pointerdown would redirect the trailing\n // click to the capture target and break the normal button press.\n // Capture only once the drag activates.\n this._dragState = {\n pointerId: event.pointerId,\n source: target,\n startX: event.clientX,\n startY: event.clientY,\n active: false,\n ghost: null,\n gapIndex: undefined,\n };\n window.addEventListener(`pointermove`, this._onPointerMove);\n window.addEventListener(`pointerup`, this._onPointerUp);\n window.addEventListener(`pointercancel`, this._onPointerCancel);\n };\n\n private _onPointerMove = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId)\n return;\n const distance = Math.hypot(event.clientX - state.startX, event.clientY - state.startY);\n if (!state.active) {\n if (distance < DRAG_THRESHOLD_PX)\n return;\n this._beginDrag(event);\n }\n state.ghost?.move(event.clientX, event.clientY);\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n if (gap !== state.gapIndex) {\n state.gapIndex = gap;\n this.requestUpdate();\n }\n };\n\n private _onPointerUp = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId)\n return;\n if (state.active) {\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n this._commitDrag(state.source, gap);\n }\n this._endDrag(event.pointerId);\n };\n\n private _onPointerCancel = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId)\n return;\n this._abortDrag();\n this._endDrag(event.pointerId);\n };\n\n private _beginDrag(event: PointerEvent): void {\n const state = this._dragState;\n if (!state || state.active)\n return;\n try {\n this.setPointerCapture(event.pointerId);\n } catch {\n // Fall through — window listeners still catch move/up.\n }\n state.active = true;\n // `dragging` kills text selection for the gesture (see styles).\n this.setAttribute(`dragging`, ``);\n state.source.setAttribute(`drag-source`, ``);\n state.ghost = this._createGhost(state.source);\n state.ghost?.move(event.clientX, event.clientY);\n }\n\n private _abortDrag(): void {\n const state = this._dragState;\n if (!state)\n return;\n state.source.removeAttribute(`drag-source`);\n if (state.gapIndex !== undefined) {\n state.gapIndex = undefined;\n this.requestUpdate();\n }\n }\n\n private _endDrag(pointerId: number): void {\n const state = this._dragState;\n if (!state)\n return;\n state.ghost?.destroy();\n state.ghost = null;\n this.removeAttribute(`dragging`);\n this._dragState = null;\n window.removeEventListener(`pointermove`, this._onPointerMove);\n window.removeEventListener(`pointerup`, this._onPointerUp);\n window.removeEventListener(`pointercancel`, this._onPointerCancel);\n try {\n this.releasePointerCapture(pointerId);\n } catch { /* already released */ }\n this.requestUpdate();\n }\n\n private _commitDrag(source: ToolbarGroupElement, gapIndex: number | undefined): void {\n source.removeAttribute(`drag-source`);\n // Gap is an index into the visual order of the without-source groups.\n // `vertical-left` lays out as column-reverse, so visual order is the\n // reverse of DOM order — map the visual gap back to a DOM reference.\n const domSiblings = this._mainGroups().filter(el => el !== source);\n const n = domSiblings.length;\n const visualGap = gapIndex === undefined\n ? n\n : Math.max(0, Math.min(gapIndex, n));\n // DOM insertion index that yields visual position `visualGap`.\n const domIndex = this.orientation === `vertical-left` ? n - visualGap : visualGap;\n const parent = source.parentNode;\n if (!parent)\n return;\n const ref = domSiblings[domIndex] ?? null;\n if (this._insertAndEmit(source, ref)) {\n // A real reorder happened — swallow the trailing click so a button inside\n // the dragged group doesn't also activate.\n this._suppressNextClick = true;\n }\n }\n\n private _createGhost(source: ToolbarGroupElement): DragGhost | null {\n const label = document.createElement(`span`);\n const text = (`label` in source && typeof source.label === `string` && source.label)\n || (source.textContent ?? ``).trim();\n label.textContent = text.slice(0, 60);\n label.style.overflow = `hidden`;\n label.style.textOverflow = `ellipsis`;\n label.style.whiteSpace = `nowrap`;\n try {\n injectToolbarGhostStyles();\n return createDragGhost({ anchor: source, content: label, className: `ixfx-toolbar-group-ghost` });\n } catch {\n return null;\n }\n }\n\n /**\n * Nearest group gap to the pointer, ignoring the drag source.\n * The perpendicular axis is ignored — the pointer always resolves to a gap.\n * Gaps are in visual order (reversed for `vertical-left`/column-reverse).\n */\n private _computeGapIndex(clientX: number, clientY: number): number | undefined {\n const state = this._dragState;\n if (!state)\n return undefined;\n const domSiblings = this._mainGroups().filter(el => el !== state.source);\n if (domSiblings.length === 0)\n return 0;\n const visual = this.orientation === `vertical-left` ? [...domSiblings].reverse() : domSiblings;\n const useX = this.orientation === `horizontal`;\n const pos = useX ? clientX : clientY;\n const edges = visual.map((el) => {\n const rect = el.getBoundingClientRect();\n return [useX ? rect.left : rect.top, useX ? rect.right : rect.bottom] as const;\n });\n return toolbarGapIndex(edges, pos);\n }\n\n private _computeCaretStyle(): string | undefined {\n const state = this._dragState;\n if (!state?.active || state.gapIndex === undefined)\n return undefined;\n const domSiblings = this._mainGroups().filter(el => el !== state.source);\n if (domSiblings.length === 0)\n return undefined;\n const hostRect = this.getBoundingClientRect();\n if (!hostRect)\n return undefined;\n const visual = this.orientation === `vertical-left` ? [...domSiblings].reverse() : domSiblings;\n const gap = Math.max(0, Math.min(state.gapIndex, visual.length));\n const rect = gap < visual.length\n ? visual[gap].getBoundingClientRect()\n : visual[visual.length - 1].getBoundingClientRect();\n if (this.orientation === `horizontal`) {\n const x = (gap < visual.length ? rect.left : rect.right) - hostRect.left;\n return `transform: translate(${x - 1}px, 0); width: 2px; height: ${hostRect.height}px;`;\n }\n const y = (gap < visual.length ? rect.top : rect.bottom) - hostRect.top;\n return `transform: translate(0, ${y - 1}px); width: ${hostRect.width}px; height: 2px;`;\n }\n\n /** Coalesce measure passes into one per frame; prevents slotchange feedback loops. */\n private _scheduleMeasure(): void {\n if (this._measureQueued)\n return;\n this._measureQueued = true;\n requestAnimationFrame(() => {\n this._measureQueued = false;\n this._measure();\n });\n }\n\n private _measure(): void {\n const children = Array.from(this.children) as HTMLElement[];\n const isGrow = (el: HTMLElement) => el.hasAttribute(`grow`) || el.matches(`[grow]`);\n const overflowable = children.filter(el => !isGrow(el));\n const isHoriz = this.orientation === `horizontal`;\n const overflowMode = getComputedStyle(this).getPropertyValue(`--toolbar-overflow`).trim() as string;\n\n if (this.layout !== `one-line` || overflowMode === `disabled`) {\n let mutated = false;\n for (const el of children) {\n if (el.getAttribute(`slot`) === `overflow`) {\n el.removeAttribute(`slot`); mutated = true;\n }\n if (el.hasAttribute(`hidden`)) {\n el.removeAttribute(`hidden`); mutated = true;\n }\n }\n if (this._overflowCount !== 0) {\n this._overflowCount = 0; mutated = true;\n }\n if (mutated)\n this.requestUpdate();\n return;\n }\n\n if (!this._inner)\n return;\n const cs = getComputedStyle(this._inner);\n const gap = (isHoriz ? Number.parseFloat(cs.columnGap) : Number.parseFloat(cs.rowGap)) || 0;\n const available = isHoriz ? this._inner.clientWidth : this._inner.clientHeight;\n const btnSize = 36;\n\n const inMain = overflowable.filter(el => el.getAttribute(`slot`) !== `overflow`);\n const inOverflow = overflowable.filter(el => el.getAttribute(`slot`) === `overflow`);\n\n // Cache natural sizes while items are measurable in the main slot\n let cum = 0;\n inMain.forEach((el, i) => {\n const s = isHoriz ? el.offsetWidth : el.offsetHeight;\n if (s > 0)\n this._sizes.set(el, s);\n cum += (i ? gap : 0) + (this._sizes.get(el) ?? s);\n });\n\n let mutated = false;\n\n // 'collapsed' mode: all overflowable items start in overflow\n if (overflowMode === `collapsed`) {\n if (inMain.length > 0) {\n for (const el of inMain) {\n el.setAttribute(`slot`, `overflow`);\n }\n inOverflow.push(...inMain);\n inMain.length = 0;\n mutated = true;\n }\n const newCount = inOverflow.length;\n if (newCount !== this._overflowCount) {\n this._overflowCount = newCount; mutated = true;\n }\n if (mutated)\n this.requestUpdate();\n return;\n }\n\n // 'auto' mode: normal overflow handling\n const btnAllowance = inOverflow.length > 0 ? gap + btnSize : 0;\n\n // Move items to overflow, last-first, until the main run fits\n while (inMain.length > 0 && cum + btnAllowance > available) {\n const last = inMain[inMain.length - 1];\n const s = this._sizes.get(last) ?? 0;\n last.setAttribute(`slot`, `overflow`);\n inMain.pop();\n inOverflow.unshift(last);\n cum -= (inMain.length ? gap : 0) + s;\n mutated = true;\n }\n\n // Move items back, first-from-overflow, only while their cached natural size fits.\n // Cached sizes are always > 0, so this cannot oscillate with the 0px measurements\n // that items report inside the closed popover.\n while (inOverflow.length > 0) {\n const first = inOverflow[0];\n const s = this._sizes.get(first);\n if (s === undefined)\n break; // never measured in main slot; stay conservative\n const addGap = inMain.length ? gap : 0;\n const nextBtnAllowance = inOverflow.length > 1 ? gap + btnSize : 0;\n if (cum + addGap + s + nextBtnAllowance > available)\n break;\n first.removeAttribute(`slot`);\n inOverflow.shift();\n inMain.push(first);\n cum += addGap + s;\n mutated = true;\n }\n\n const newCount = inOverflow.length;\n if (newCount !== this._overflowCount) {\n this._overflowCount = newCount; mutated = true;\n }\n if (mutated)\n this.requestUpdate();\n }\n\n private _toggleOverflow(): void {\n try {\n (this._popover as any).togglePopover();\n } catch {\n (this._popover as any).showPopover();\n }\n }\n\n protected override render() {\n const overflowMode = getComputedStyle(this).getPropertyValue(`--toolbar-overflow`).trim();\n const hasOverflow = this._overflowCount > 0 || overflowMode === `collapsed`;\n const caretStyle = this._computeCaretStyle();\n return html`\n <div class=\"inner\" role=\"toolbar\" aria-orientation=${this.orientation}>\n <slot @pointerdown=${this._onPointerDown} @keydown=${this._onKeyDown}></slot>\n <ixfx-button class=\"overflow-btn\" ?hidden=${!hasOverflow} @click=${this._toggleOverflow} aria-label=\"More\" aria-haspopup=\"true\" aria-expanded=${this._popoverOpen}>⋯</ixfx-button>\n </div>\n <div class=\"overflow-popover popup-surface\" popover=\"auto\" @click=${(e: Event) => e.stopPropagation()}>\n <slot name=\"overflow\"></slot>\n </div>\n ${caretStyle ? html`<div class=\"drop-caret\" style=${caretStyle}></div>` : nothing}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap { 'ixfx-toolbar': ToolbarElement }\n}\n\nexport interface ToolbarElement {\n addEventListener: (<K extends keyof ToolbarElementEventMap>(\n type: K,\n listener: (this: ToolbarElement, event: ToolbarElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","/**\n * Pure treemap layout: `TreeNode` + value accessor + tiling method + depth\n * window → positioned nested rects. No Lit, no DOM — unit-testable in isolation.\n */\n\nimport type {\n ComputeTreemapLayoutOptions,\n TreemapRect,\n TreemapTilingMethod,\n TreemapValueAccessor,\n TreeNode,\n} from './types.js';\n\n/** Coerce a raw accessor result to a non-negative finite weight. */\nexport function normaliseValue(raw: unknown): number {\n return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? raw : 0;\n}\n\n/** Depth-first search for the node with `key`. Returns `undefined` when absent. */\nexport function findTreemapNode(root: TreeNode | undefined, key: string): TreeNode | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const hit = findTreemapNode(child, key);\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/**\n * Chain of nodes from `root` down to (and including) the node with `key`.\n * Returns `undefined` when the key is absent. The first entry is always `root`.\n */\nexport function findTreemapPath(root: TreeNode | undefined, key: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return [root];\n for (const child of root.children ?? []) {\n const hit = findTreemapPath(child, key);\n if (hit)\n return [root, ...hit];\n }\n return undefined;\n}\n\ntype Box = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\n/**\n * Worst aspect ratio of the row items if laid out together along a strip of\n * length `side` (the short side of the remaining container). Lower is better;\n * `1` is a perfect square. Follows Bruls et al.\n */\nfunction worstAspect(areas: readonly number[], total: number, side: number): number {\n if (areas.length === 0 || total <= 0 || side <= 0)\n return Number.POSITIVE_INFINITY;\n let worst = 0;\n for (const area of areas) {\n if (area <= 0)\n return Number.POSITIVE_INFINITY;\n const ratio = (side * side * area) / (total * total);\n worst = Math.max(worst, ratio, 1 / ratio);\n }\n return worst;\n}\n\n/**\n * Squarified tiling of `items` (with pre-normalised positive areas summing to\n * `box.width * box.height`) into `box`. Returns absolute boxes in item order.\n * Sibling order is preserved — no descending sort — so output is deterministic.\n */\nfunction squarifyInto(\n items: ReadonlyArray<{ area: number }>,\n box: Box,\n): Box[] {\n const out: Box[] = Array.from({ length: items.length });\n let cx = box.x;\n let cy = box.y;\n let cw = box.width;\n let ch = box.height;\n let start = 0;\n\n while (start < items.length) {\n const side = Math.min(cw, ch);\n // Grow the row while the worst aspect ratio keeps improving.\n let end = start + 1;\n let rowAreas = items.slice(start, end).map(i => i.area);\n let rowTotal = rowAreas.reduce((a, b) => a + b, 0);\n let worst = worstAspect(rowAreas, rowTotal, side);\n while (end < items.length) {\n const nextAreas = items.slice(start, end + 1).map(i => i.area);\n const nextTotal = nextAreas.reduce((a, b) => a + b, 0);\n const nextWorst = worstAspect(nextAreas, nextTotal, side);\n if (nextWorst <= worst) {\n end++;\n rowAreas = nextAreas;\n rowTotal = nextTotal;\n worst = nextWorst;\n } else {\n break;\n }\n }\n // Lay the row out as a strip spanning the short side.\n if (cw <= ch) {\n // Narrow container: strip spans the full width, items side-by-side.\n const stripH = rowTotal / cw;\n let ix = cx;\n for (let i = start; i < end; i++) {\n const w = rowAreas[i - start] / stripH;\n out[i] = { x: ix, y: cy, width: w, height: stripH };\n ix += w;\n }\n cy += stripH;\n ch -= stripH;\n } else {\n // Wide container: strip spans the full height, items stacked vertically.\n const stripW = rowTotal / ch;\n let iy = cy;\n for (let i = start; i < end; i++) {\n const h = rowAreas[i - start] / stripW;\n out[i] = { x: cx, y: iy, width: stripW, height: h };\n iy += h;\n }\n cx += stripW;\n cw -= stripW;\n }\n start = end;\n }\n return out;\n}\n\n/** Clamp a raw cascade offset fraction to a sane range. */\nfunction normaliseOffset(raw: unknown): number {\n return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? Math.min(raw, 1) : 0;\n}\n\n/**\n * Subdivide `box` among `weights` (same length as the child list) using\n * `method` at `relativeDepth`. Returns one absolute box per weight, in order.\n * Zero-share children get degenerate (zero-area) boxes at the box origin.\n * Degenerate (zero/negative-extent) containers also yield zero-area boxes\n * rather than `NaN` — this matters for cascaded layouts where deep insets\n * can consume the whole box.\n */\nfunction subdivide(\n box: Box,\n weights: readonly number[],\n method: TreemapTilingMethod,\n relativeDepth: number,\n): Box[] {\n if (box.width <= 0 || box.height <= 0) {\n return weights.map(() => ({ x: box.x, y: box.y, width: 0, height: 0 }));\n }\n const total = weights.reduce((a, b) => a + b, 0);\n const shares = total > 0\n ? weights.map(w => w / total)\n : weights.map(() => 1 / weights.length);\n\n const dice = method === `dice` || (method === `slice-dice` && relativeDepth % 2 === 0);\n const slice = method === `slice` || (method === `slice-dice` && relativeDepth % 2 === 1);\n\n if (method === `squarify`) {\n const positive = shares.map((share, i) => ({ share, i })).filter(s => s.share > 0);\n const boxes: Box[] = weights.map(() => ({ x: box.x, y: box.y, width: 0, height: 0 }));\n if (positive.length > 0) {\n const containerArea = box.width * box.height;\n const laid = squarifyInto(\n positive.map(p => ({ area: p.share * containerArea })),\n box,\n );\n positive.forEach((p, k) => {\n boxes[p.i] = laid[k];\n });\n }\n return boxes;\n }\n\n const boxes: Box[] = [];\n if (dice) {\n // Side-by-side vertical slices.\n let cursor = box.x;\n shares.forEach((share) => {\n const w = box.width * share;\n boxes.push({ x: cursor, y: box.y, width: w, height: box.height });\n cursor += w;\n });\n } else if (slice) {\n // Stacked horizontal slices.\n let cursor = box.y;\n shares.forEach((share) => {\n const h = box.height * share;\n boxes.push({ x: box.x, y: cursor, width: box.width, height: h });\n cursor += h;\n });\n }\n return boxes;\n}\n\n/**\n * Compute the visible rectangles for a treemap view.\n *\n * The zoom node fills the whole viewport (`0,0,1,1`); its children subdivide\n * that rectangle by `valueAccessor` share, recursively, up to `maxDepth`\n * nested levels. The zoom node itself is never emitted as a rect (it is shown\n * in the breadcrumb strip instead — matching `TreeComponent.getNodes()`,\n * where the root is never listed). Siblings whose weights all normalise to\n * `0` split their parent's rectangle equally.\n *\n * @param root True tree root. `undefined` (or a root without children) yields `[]`.\n * @param options `valueAccessor` (default equal weights), `maxDepth` (nesting\n * levels, default unlimited), `zoomKey` (visual root, default true root;\n * unknown keys fall back to the true root), `tilingMethod` (default\n * `'squarify'`), `presentation` (default `'nested'`) plus `cascadeOffsetX/Y`\n * (per-level shift as a viewport fraction, cascaded only).\n */\nexport function computeTreemapLayout(\n root: TreeNode | undefined,\n options: ComputeTreemapLayoutOptions = {},\n): TreemapRect[] {\n if (!root?.children?.length)\n return [];\n const {\n maxDepth = Number.POSITIVE_INFINITY,\n valueAccessor = () => 1,\n zoomKey,\n tilingMethod = `squarify`,\n hideLeaves = false,\n presentation = `nested`,\n cascadeOffsetX: rawOx,\n cascadeOffsetY: rawOy,\n } = options;\n if (maxDepth <= 0)\n return [];\n // Nested (or zero offsets) ⇒ classic fill-the-parent behaviour.\n const cascaded = presentation === `cascaded`;\n const ox = cascaded ? normaliseOffset(rawOx) : 0;\n const oy = cascaded ? normaliseOffset(rawOy) : 0;\n\n const visibleChildren = (node: TreeNode): TreeNode[] => {\n const children = node.children ?? [];\n return hideLeaves ? children.filter(n => n.item.isLeaf !== true) : children;\n };\n\n const zoomNode = zoomKey === undefined ? root : (findTreemapNode(root, zoomKey) ?? root);\n const zoomPath = findTreemapPath(root, zoomNode.item.key);\n // Absolute depth of the zoom node: root is -1 so its children are depth 0.\n const zoomDepth = zoomPath ? zoomPath.length - 2 : -1;\n const siblings = visibleChildren(zoomNode);\n if (siblings.length === 0)\n return [];\n\n const rects: TreemapRect[] = [];\n const layoutLevel = (\n nodes: readonly TreeNode[],\n box: Box,\n depth: number,\n relativeDepth: number,\n parentKey: string | undefined,\n ): void => {\n if (nodes.length === 0 || relativeDepth >= maxDepth)\n return;\n const weights = nodes.map(n => normaliseValue((valueAccessor as TreemapValueAccessor)(n.item)));\n const boxes = subdivide(box, weights, tilingMethod, relativeDepth);\n const setSize = nodes.length;\n nodes.forEach((node, index) => {\n const childBox = boxes[index];\n const children = visibleChildren(node);\n rects.push({\n node,\n depth,\n relativeDepth,\n x: childBox.x,\n y: childBox.y,\n width: childBox.width,\n height: childBox.height,\n parentKey,\n index,\n setSize,\n hasChildren: children.length > 0 || (node.children === undefined && node.item.isLeaf !== true),\n });\n if (children.length > 0) {\n // Cascaded presentation (Lü & Fogarty 2008, Fig. 6): the children's\n // content box is shifted down+right inside the parent tile, so the\n // parent's top/left strips stay visible as a stack-of-cards depth\n // effect. Right/bottom edges stay flush with the parent. A consumed\n // box collapses to zero area (never negative) — `subdivide` then\n // emits zero-area descendants rather than `NaN`.\n const contentBox = ox <= 0 && oy <= 0\n ? childBox\n : {\n x: childBox.x + ox,\n y: childBox.y + oy,\n width: Math.max(0, childBox.width - ox),\n height: Math.max(0, childBox.height - oy),\n };\n layoutLevel(children, contentBox, depth + 1, relativeDepth + 1, node.item.key);\n }\n });\n };\n\n layoutLevel(siblings, { x: 0, y: 0, width: 1, height: 1 }, zoomDepth + 1, 0, zoomNode.item.key);\n return rects;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TreeActivateDetail, TreeActivateEvent, TreeCollapseDetail, TreeCollapseEvent, TreeComponent, TreeComponentEventMap, TreeExpandDetail, TreeExpandEvent, TreeItemClickDetail, TreeItemClickEvent, TreeItemDblClickDetail, TreeItemDblClickEvent, TreeSearchHost, TreeSelectDetail, TreeSelectEvent, TreeTickleDetail, TreeTickleEvent } from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type {\n TreemapCategoryAccessor,\n TreemapInteractionMode,\n TreemapPresentation,\n TreemapRect,\n TreemapTilingMethod,\n TreemapValueAccessor,\n} 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 {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { computeTreemapLayout, findTreemapNode, findTreemapPath } from './layout.js';\nimport '../crumbs/crumb-navigation.js';\n\n/** Fired when the zoom root changes. `node` is `undefined` on zoom-out to the full tree. */\nexport type TreemapZoomDetail = {\n readonly node: TreeNode | undefined;\n /** Absolute depth of the zoom node (root's children are depth 0); `-1` when fully zoomed out. */\n readonly depth: number;\n};\n\nexport type TreemapZoomEvent = CustomEvent<TreemapZoomDetail>;\n\n/**\n * A planned FLIP animation for a zoom transition — computed just before the\n * zoom state changes, then applied once the new layout has rendered.\n * - `'in'` (zooming into a tile): `rect` is that tile's position in the *old*\n * viewport's coordinate space (0–1) — the new content starts scaled/placed\n * to match it, then animates to fill the viewport (a \"grow\" effect).\n * - `'out'` (zooming to an ancestor, or fully out): `rect` is where the node\n * being zoomed *from* lands in the *new* layout — the new content starts\n * blown up so that rect fills the viewport (matching what was on screen a\n * moment ago), then animates down to its true size (a \"shrink\" effect).\n */\ntype FlipPlan = {\n readonly direction: `in` | `out`;\n readonly rect: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };\n};\n\nexport interface TreemapListElementEventMap extends TreeComponentEventMap {\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'zoom': TreemapZoomEvent;\n}\n\n/**\n * `ixfx-treemap-list` — a nested-area (treemap) view over tree data.\n *\n * The zoom root fills the whole viewport; at each level a node's rectangle is\n * subdivided among its children by `valueAccessor` share (see `tilingMethod`),\n * recursively, up to `maxDepth` nested levels. Implements the shared\n * `TreeComponent` interface so existing infrastructure (`TreeDataModel`,\n * `IncrSearchTreeController`, `TreeComponent`-typed code) works unmodified.\n *\n * Differences from `ixfx-tree-list` (deliberate):\n * - **Expand/collapse is reinterpreted as zoom.** Clicking a branch zooms so it\n * becomes the visual root; ancestors collapse into the breadcrumb strip.\n * `expand`/`collapse` events fire on zoom-in/zoom-out with the same detail\n * shape so existing listeners keep working conceptually.\n * - **`interactionMode` drops `checked`** — a checkbox per rectangle does not\n * hold up at small tile sizes.\n * - **`exclusivity` is accepted but ignored** — nothing is independently \"open\".\n * - **`filterPredicate` dims** non-matching tiles instead of hiding rows.\n * - Drag-and-drop is out of scope.\n */\n@customElement(`ixfx-treemap-list`)\nexport class TreemapListElement 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 /**\n * Accepted for `TreeComponent` compatibility but ignored — a treemap has no\n * independently open branches, so exclusivity is not meaningful.\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 /**\n * Gesture mapping. `checked` is unsupported (see class docs).\n * @default 'standard'\n */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: TreemapInteractionMode = `standard`;\n\n /**\n * Algorithm used to subdivide a node's rectangle among its children.\n * @default 'squarify'\n */\n @property({ type: String, attribute: `tiling-method` })\n tilingMethod: TreemapTilingMethod = `squarify`;\n\n /**\n * How containment is shown. Orthogonal to `tilingMethod` (Lü & Fogarty 2008:\n * any subdivision can be shown either way).\n * - `'nested'` — children fill the parent (classic nesting).\n * - `'cascaded'` — children shift down+right by `cascadeOffset` per level,\n * leaving the parent's top/left strips visible (stack-of-cards depth).\n * @default 'nested'\n */\n @property({ type: String, attribute: `presentation` })\n presentation: TreemapPresentation = `nested`;\n\n /**\n * Per-level cascade shift (px) down+right applied when\n * `presentation === 'cascaded'`. Converted to viewport fractions using the\n * host size before layout. Ignored when nested.\n * @default 6\n */\n @property({ type: Number, attribute: `cascade-offset` })\n cascadeOffset = 6;\n\n /** How many nested levels render at once from the current zoom root. */\n @property({ type: Number, attribute: `max-depth` })\n maxDepth = 4;\n\n /**\n * When `true`, leaf nodes (`item.isLeaf === true`) are excluded entirely —\n * neither rendered nor counted towards their siblings' area shares. Use\n * this to show branch structure only (e.g. folders, not files).\n */\n @property({ type: Boolean, attribute: `hide-leaves` })\n hideLeaves = false;\n\n /**\n * Tiles whose pixel area falls below this (px²) hide their label.\n * Area is estimated from the tile's area share times the host size.\n */\n @property({ type: Number, attribute: `min-label-area` })\n minLabelArea = 1600;\n\n /**\n * Minimum on-screen width (px) a tile needs before its label is shown or\n * its own children are subdivided. A tall, narrow sliver can clear\n * `minLabelArea`/`minChildArea` on area alone while still being too narrow\n * to show even a truncated character — this catches that case so it\n * renders as a plain, unlabelled block instead of a clipped-to-nothing title.\n */\n @property({ type: Number, attribute: `min-tile-width` })\n minTileWidth = 24;\n\n /**\n * Inner padding (px) between a branch tile's border and its children, so\n * nested levels are visually distinguishable.\n */\n @property({ type: Number })\n padding = 4;\n\n /**\n * Minimum on-screen area (px²) a tile must have before its own children are\n * subdivided and rendered. Below this, a tile renders as a flat block with\n * no nested detail — recursion stops by pixel size rather than by a fixed\n * node depth, so a branch with many descendants doesn't collapse into an\n * illegible cluster of near-zero-size rectangles.\n */\n @property({ type: Number, attribute: `min-child-area` })\n minChildArea = 400;\n\n /** Weight per node. Default `() => 1` — equal-area siblings. */\n @property({ attribute: false })\n valueAccessor: TreemapValueAccessor = () => 1;\n\n /**\n * Category per node, or `undefined` for none. When set, a tile's\n * background/text colour come from `--treemap-category-<slug>-bg` /\n * `--treemap-category-<slug>-text` (the category name slugified —\n * non `[a-zA-Z0-9_-]` characters become `-`), falling back to the normal\n * `--treemap-tile-bg`/`--treemap-tile-text` when that pair isn't defined.\n * Default `undefined` — no categorisation.\n */\n @property({ attribute: false })\n categoryAccessor: TreemapCategoryAccessor | undefined;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n private _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 /** Current zoom root. `undefined` when showing the full tree. Pure view-state — `root` is never mutated. */\n get focusedNode(): TreeNode | undefined {\n if (this._zoomKey === undefined)\n return undefined;\n return findTreemapNode(this.#effectiveRoot, this._zoomKey);\n }\n\n @state()\n private _zoomKey: string | undefined = undefined;\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: `.treemap-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n private tickled = new TickledController<string>(this, {\n getItems: () => this.#rects().map(r => ({ id: r.node.item.key, enabled: true })),\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n onTickle: (id) => {\n if (id === undefined)\n return;\n const rect = this.#rects().find(r => r.node.item.key === id);\n if (!rect)\n return;\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n },\n });\n\n #modelUnsubscribe: (() => void) | undefined;\n #pendingKeys = new Set<string>();\n #aborters = new Map<string, AbortController>();\n #anchorIndex: number | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #pendingFlip: FlipPlan | undefined;\n /** `performance.now()` timestamp before which further Cmd+wheel zoom steps are ignored. */\n #wheelCooldownUntil = 0;\n\n // --- Derived data ---------------------------------------------------------\n\n get #effectiveRoot(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n #rects(): TreemapRect[] {\n return this.#rectsForZoom(this._zoomKey);\n }\n\n #rectsForZoom(zoomKey: string | undefined): TreemapRect[] {\n return computeTreemapLayout(this.#effectiveRoot, {\n valueAccessor: this.valueAccessor,\n maxDepth: this.maxDepth,\n zoomKey,\n tilingMethod: this.tilingMethod,\n hideLeaves: this.hideLeaves,\n presentation: this.presentation,\n ...this.#cascadeFractions(),\n });\n }\n\n /**\n * Pixel `cascadeOffset` as viewport fractions for the current host size.\n * Returns `{}` when nested, unmeasured, or non-positive — layout then falls\n * back to classic nesting for that pass (the `ResizeObserver` re-renders\n * once measured).\n */\n #cascadeFractions(): { cascadeOffsetX?: number; cascadeOffsetY?: number } {\n if (this.presentation !== `cascaded`)\n return {};\n if (!Number.isFinite(this.cascadeOffset) || this.cascadeOffset <= 0)\n return {};\n const w = this.clientWidth || 0;\n const h = this.clientHeight || 0;\n if (w <= 0 || h <= 0)\n return {};\n return { cascadeOffsetX: this.cascadeOffset / w, cascadeOffsetY: this.cascadeOffset / h };\n }\n\n // --- Lifecycle ------------------------------------------------------------\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 if (typeof ResizeObserver !== `undefined`) {\n this.#resizeObserver = new ResizeObserver(() => this.requestUpdate());\n this.#resizeObserver.observe(this);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n for (const aborter of this.#aborters.values())\n aborter.abort();\n this.#aborters.clear();\n this.#pendingKeys.clear();\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\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 #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 protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`root`) && this.root) {\n this.#resetViewState();\n }\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n if (this.model) {\n this.#modelUnsubscribe = this.model._subscribe((event) => {\n if (event.type === `root`) {\n this.#resetViewState();\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n this.requestUpdate();\n }\n });\n this.#resetViewState();\n }\n }\n if (changedProps.has(`interactionMode`)) {\n this.#anchorIndex = undefined;\n this.clearSelection();\n }\n if (changedProps.has(`searchModes`))\n this.#syncSearchCommands();\n // A new root invalidates the zoom target — fall back to the full tree.\n if (this._zoomKey !== undefined && !findTreemapNode(this.#effectiveRoot, this._zoomKey)) {\n this._zoomKey = undefined;\n }\n this.#ensureVisibleChildren();\n if (this.#pendingFlip) {\n const flip = this.#pendingFlip;\n this.#pendingFlip = undefined;\n this.#applyFlip(flip);\n }\n }\n\n #resetViewState(): void {\n this.#pendingFlip = undefined;\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._zoomKey = undefined;\n this.#anchorIndex = undefined;\n }\n\n // --- Lazy children --------------------------------------------------------\n\n #ensureVisibleChildren(): void {\n if (!this.model && !this.loadChildren)\n return;\n for (const rect of this.#rects()) {\n const { node } = rect;\n if (node.children !== undefined || this.#pendingKeys.has(node.item.key))\n continue;\n // #rects() only ever yields rects within the visible window\n // (relativeDepth < maxDepth), so every rect reaching here is a\n // currently-rendered node whose children aren't loaded yet — fetch them\n // so zooming in works.\n void this.#loadChildren(node, rect.depth);\n }\n }\n\n async #loadChildren(node: TreeNode, depth: number): Promise<void> {\n const key = node.item.key;\n this.#pendingKeys.add(key);\n const controller = new AbortController();\n this.#aborters.set(key, controller);\n this.requestUpdate();\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 } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n } finally {\n this.#pendingKeys.delete(key);\n this.#aborters.delete(key);\n if (!controller.signal.aborted)\n this.requestUpdate();\n }\n }\n\n // --- Selection ------------------------------------------------------------\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._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail: { selected: new Set(this._selectedNodes), previous },\n bubbles: true,\n composed: true,\n }));\n }\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 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 for (const rect of this.#rects()) {\n if (!this.#canSelect(rect.node))\n continue;\n this._selectedNodes.add(rect.node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\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 // --- Zoom -----------------------------------------------------------------\n\n /**\n * Drill down so `node` becomes the visual root (ancestors move to the\n * breadcrumb strip). Pure view-state — `root` is never mutated.\n * Fires `zoom` and the semantic `expand` event.\n */\n zoomTo(node: TreeNode): void {\n if (this._zoomKey === node.item.key)\n return;\n this.#pendingFlip = this.#planFlip(node.item.key);\n this._zoomKey = node.item.key;\n this.tickled.clearTickled();\n const depth = findTreemapPath(this.#effectiveRoot, node.item.key)?.length;\n const absoluteDepth = depth === undefined ? -1 : depth - 2;\n this.dispatchEvent(new CustomEvent<TreemapZoomDetail>(`zoom`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n }\n\n /**\n * Zoom back out to the full tree. Fires `zoom` (with `node: undefined`) and\n * the semantic `collapse` event for the previous zoom root.\n */\n zoomOut(): void {\n if (this._zoomKey === undefined)\n return;\n this.#pendingFlip = this.#planFlip(undefined);\n const previous = this.focusedNode;\n const path = this._zoomKey === undefined\n ? undefined\n : findTreemapPath(this.#effectiveRoot, this._zoomKey);\n const absoluteDepth = path === undefined ? -1 : path.length - 2;\n this._zoomKey = undefined;\n this.tickled.clearTickled();\n this.dispatchEvent(new CustomEvent<TreemapZoomDetail>(`zoom`, {\n detail: { node: undefined, depth: -1 },\n bubbles: true,\n composed: true,\n }));\n if (previous) {\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node: previous, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n }\n this.requestUpdate();\n }\n\n /**\n * Work out (before `_zoomKey` changes) whether the upcoming zoom should\n * animate, and how — see `FlipPlan`. Returns `undefined` to skip the\n * animation: reduced-motion is requested, or the node needed to anchor it\n * isn't in either the old or new layout's visible window.\n */\n #planFlip(targetKey: string | undefined): FlipPlan | undefined {\n if (typeof matchMedia === `function` && matchMedia(`(prefers-reduced-motion: reduce)`).matches)\n return undefined;\n if (targetKey !== undefined) {\n // Target already visible under the current zoom root ⇒ zooming in:\n // grow from its current on-screen rect to fill the viewport.\n const visible = this.#rects().find(r => r.node.item.key === targetKey);\n if (visible) {\n return { direction: `in`, rect: { x: visible.x, y: visible.y, width: visible.width, height: visible.height } };\n }\n }\n // Otherwise zooming out (to an ancestor, or fully out): find where the\n // node we're zooming *from* lands in the new layout, and shrink into it.\n const fromKey = this._zoomKey;\n if (fromKey === undefined)\n return undefined;\n const landing = this.#rectsForZoom(targetKey).find(r => r.node.item.key === fromKey);\n if (!landing)\n return undefined;\n return { direction: `out`, rect: { x: landing.x, y: landing.y, width: landing.width, height: landing.height } };\n }\n\n /** Apply a planned FLIP animation once the new layout has rendered — see `FlipPlan`. */\n #applyFlip(flip: FlipPlan): void {\n const inner = this.renderRoot.querySelector(`.viewport-inner`);\n const viewport = this.renderRoot.querySelector(`.viewport`);\n if (!(inner instanceof HTMLElement) || !(viewport instanceof HTMLElement))\n return;\n const vw = viewport.clientWidth;\n const vh = viewport.clientHeight;\n if (vw <= 0 || vh <= 0)\n return;\n const { rect, direction } = flip;\n const startTransform = direction === `in`\n ? `translate(${rect.x * vw}px, ${rect.y * vh}px) scale(${Math.max(rect.width, 0.0001)}, ${Math.max(rect.height, 0.0001)})`\n : (() => {\n const sx = rect.width > 0 ? 1 / rect.width : 1;\n const sy = rect.height > 0 ? 1 / rect.height : 1;\n return `translate(${-rect.x * sx * vw}px, ${-rect.y * sy * vh}px) scale(${sx}, ${sy})`;\n })();\n inner.classList.remove(`flipping`);\n inner.style.transform = startTransform;\n // Force the starting transform to commit before animating away from it.\n void inner.offsetWidth;\n requestAnimationFrame(() => {\n inner.classList.add(`flipping`);\n inner.style.transform = `none`;\n });\n inner.addEventListener(`transitionend`, () => inner.classList.remove(`flipping`), { once: true });\n }\n\n #canZoom(node: TreeNode): boolean {\n if (node.item.isLeaf === true)\n return false;\n if (node.children !== undefined) {\n return this.hideLeaves\n ? node.children.some(n => n.item.isLeaf !== true)\n : node.children.length > 0;\n }\n // Not yet loaded — zoomable when a loader could provide children.\n return this.model !== undefined || this.loadChildren !== undefined;\n }\n\n // --- Navigation -----------------------------------------------------------\n\n /**\n * Zoom so the node at `keys` (path from the root's children) is visible,\n * then select it. Returns `true` if the path was found.\n */\n navigateTo(keys: readonly string[]): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n let current: TreeNode = root;\n const path: TreeNode[] = [];\n for (const key of keys) {\n const found = current.children?.find(n => n.item.key === key);\n if (!found)\n return false;\n path.push(found);\n current = found;\n }\n const target = path.at(-1)!;\n // Keep the target inside the depth window: zoom to the ancestor `maxDepth`\n // levels above it, or the full tree when it already fits.\n if (path.length > this.maxDepth) {\n this.zoomTo(path[path.length - this.maxDepth - 1]);\n } else if (this._zoomKey !== undefined) {\n this.zoomOut();\n }\n this.select(target);\n this.tickled.setTickled(target.item.key);\n this.requestUpdate();\n return true;\n }\n\n /**\n * Zoom + select the first node for which `predicate` returns `true`.\n * Returns `true` if a matching node was found.\n */\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const keyPath = this.#findKeyPath(root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /**\n * Zoom so the node with `key` is visible and move the keyboard cursor to it,\n * without changing the selection. Used by incremental-search \"navigate\" mode.\n */\n revealKey(key: string): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const path = this.#findKeyPath(root.children, n => n.item.key === key);\n if (!path)\n return false;\n if (path.length > this.maxDepth) {\n const ancestor = this.#resolveKeyPath(path.slice(0, path.length - this.maxDepth));\n if (ancestor)\n this.zoomTo(ancestor);\n }\n this.tickled.setTickled(key);\n this.requestUpdate();\n return true;\n }\n\n #resolveKeyPath(keys: readonly string[]): TreeNode | undefined {\n let current = this.#effectiveRoot;\n for (const key of keys) {\n const found = key === current?.item.key ? current : current?.children?.find(n => n.item.key === key);\n if (!found)\n return undefined;\n current = found;\n }\n return current;\n }\n\n #findKeyPath(\n nodes: readonly 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 hit = this.#findKeyPath(node.children, predicate, path);\n if (hit)\n return hit;\n }\n }\n return undefined;\n }\n\n /**\n * All nodes currently visible as tiles, in render (pre-order) order,\n * with absolute depth (root's children are depth 0).\n */\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n return this.#rects().map(r => ({ node: r.node, depth: r.depth }));\n }\n\n // --- Pointer / keyboard ---------------------------------------------------\n\n #matchesFilter(node: TreeNode, depth: number): boolean {\n if (!this.filterPredicate)\n return true;\n if (this.filterPredicate(node, depth))\n return true;\n return node.children?.some(child => this.#matchesFilter(child, depth + 1)) ?? false;\n }\n\n #rectCenter(rect: TreemapRect): { x: number; y: number } {\n return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };\n }\n\n /**\n * Geometrically nearest sibling tile in `direction` from `current`\n * (nearest-neighbour by rect center). Falls back to the parent tile\n * (Up/Left) or first-child tile (Down/Right) when no sibling lies in that\n * direction, so every visible tile stays keyboard-reachable.\n */\n #nearestInDirection(\n current: TreemapRect,\n direction: `left` | `right` | `up` | `down`,\n ): TreemapRect | undefined {\n const rects = this.#rects();\n const center = this.#rectCenter(current);\n const siblings = rects.filter(r =>\n r !== current && r.relativeDepth === current.relativeDepth && r.parentKey === current.parentKey);\n let best: TreemapRect | undefined;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const candidate of siblings) {\n const c = this.#rectCenter(candidate);\n const dx = c.x - center.x;\n const dy = c.y - center.y;\n const inDirection = direction === `left`\n ? dx < 0\n : direction === `right`\n ? dx > 0\n : direction === `up` ? dy < 0 : dy > 0;\n if (!inDirection)\n continue;\n const distance = Math.hypot(dx, dy);\n if (distance < bestDistance) {\n bestDistance = distance;\n best = candidate;\n }\n }\n if (best)\n return best;\n if (direction === `up` || direction === `left`) {\n return current.parentKey === undefined\n ? undefined\n : rects.find(r => r.node.item.key === current.parentKey);\n }\n return rects.find(r => r.parentKey === current.node.item.key);\n }\n\n #handleItemClick(rect: TreemapRect, index: number, event: MouseEvent): void {\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.interactionMode === `standard` && (event.ctrlKey || event.metaKey)) {\n if (this._selectedNodes.has(rect.node)) {\n this.deselect(rect.node);\n } else if (this.#canSelect(rect.node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.add(rect.node);\n this.selectedNode = rect.node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n this.#anchorIndex = index;\n } else if (this.interactionMode === `standard` && event.shiftKey && this.#anchorIndex !== undefined) {\n const rects = this.#rects();\n const from = Math.min(this.#anchorIndex, index);\n const to = Math.max(this.#anchorIndex, index);\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = new Set(\n rects.slice(from, to + 1).map(r => r.node).filter(n => this.#canSelect(n)),\n );\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n } else if (this.interactionMode !== `manual`) {\n this.select(rect.node);\n this.#anchorIndex = index;\n }\n this.tickled.setTickled(rect.node.item.key);\n if (this.#canZoom(rect.node))\n this.zoomTo(rect.node);\n }\n\n #handleItemDblClick(rect: TreemapRect): void {\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n if (this.disableKeyboardNavigation)\n return;\n const rects = this.#rects();\n if (rects.length === 0)\n return;\n const tickledKey = this.tickled.tickledId;\n const currentIndex = tickledKey === undefined\n ? -1\n : rects.findIndex(r => r.node.item.key === tickledKey);\n const current = currentIndex >= 0 ? rects[currentIndex] : undefined;\n\n const moveTo = (rect: TreemapRect | undefined) => {\n if (!rect)\n return;\n event.preventDefault();\n this.tickled.setTickled(rect.node.item.key);\n // implicit: single selection follows the keyboard cursor (mirrors tree-base's implicit mode).\n if (this.interactionMode === `implicit`)\n this.select(rect.node);\n };\n\n switch (event.key) {\n case `ArrowLeft`:\n moveTo(current ? this.#nearestInDirection(current, `left`) : rects[0]);\n return;\n case `ArrowRight`:\n moveTo(current ? this.#nearestInDirection(current, `right`) : rects[0]);\n return;\n case `ArrowUp`:\n moveTo(current ? this.#nearestInDirection(current, `up`) : rects[0]);\n return;\n case `ArrowDown`:\n moveTo(current ? this.#nearestInDirection(current, `down`) : rects[0]);\n return;\n case `Home`:\n moveTo(rects[0]);\n return;\n case `End`:\n moveTo(rects.at(-1));\n return;\n case `Enter`: {\n if (!current)\n return;\n event.preventDefault();\n if (this.interactionMode !== `manual`)\n this.select(current.node);\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.#canZoom(current.node))\n this.zoomTo(current.node);\n return;\n }\n case `Backspace`:\n case `Escape`:\n if (this._zoomKey !== undefined) {\n event.preventDefault();\n this.zoomOut();\n }\n }\n }\n\n /**\n * Cmd+wheel zooms: scrolling backward (deltaY < 0, towards the user) zooms\n * into the tile under the pointer — the same as clicking it; scrolling\n * forward (deltaY > 0, away from the user) zooms out one level at a time\n * (see `#zoomOutOneStep`), not straight to the root. Plain wheel (no Cmd)\n * is left alone for normal page scroll. A short cooldown after each step\n * keeps a single trackpad gesture (which fires many small wheel events)\n * from firing a cascade of zoom steps.\n */\n #handleWheel(event: WheelEvent): void {\n if (!event.metaKey || event.deltaY === 0)\n return;\n event.preventDefault();\n if (performance.now() < this.#wheelCooldownUntil)\n return;\n if (event.deltaY > 0) {\n if (this._zoomKey === undefined)\n return;\n this.#wheelCooldownUntil = performance.now() + 260;\n this.#zoomOutOneStep();\n return;\n }\n const tileEl = (event.target as Element | null)?.closest(`.tile`);\n const key = tileEl?.getAttribute(`data-key`) ?? undefined;\n if (key === undefined)\n return;\n const rect = this.#rects().find(r => r.node.item.key === key);\n if (!rect || !this.#canZoom(rect.node))\n return;\n this.#wheelCooldownUntil = performance.now() + 260;\n this.zoomTo(rect.node);\n }\n\n /** Zoom to the current zoom node's parent, or fully out when it's a direct child of the root. */\n #zoomOutOneStep(): void {\n const path = this._zoomKey === undefined ? undefined : findTreemapPath(this.#effectiveRoot, this._zoomKey);\n // path is [root, ..., zoomNode]; length <= 2 means zoomNode is a direct child of root.\n const parent = path && path.length > 2 ? path[path.length - 2] : undefined;\n if (parent) {\n this.zoomTo(parent);\n } else {\n this.zoomOut();\n }\n }\n\n // --- Render ---------------------------------------------------------------\n\n #renderBreadcrumb(): unknown {\n const zoomNode = this.focusedNode;\n if (zoomNode === undefined)\n return nothing;\n return html`\n <nav class=\"breadcrumb\" part=\"breadcrumb\" aria-label=\"Treemap zoom path\">\n <ixfx-crumb-navigation\n with-up\n .root=${this.#effectiveRoot}\n .selectedNode=${zoomNode}\n @select=${this.#onCrumbSelect}\n @item-click=${(e: Event) => e.stopPropagation()}\n @tickle=${(e: Event) => e.stopPropagation()}\n @expand=${(e: Event) => e.stopPropagation()}\n ></ixfx-crumb-navigation>\n </nav>\n `;\n }\n\n /**\n * Translate crumb-trail selection (crumb clicks + the up-button) into zoom\n * state. The event is stopped: crumb clicks must not bubble as our `select`\n * (the selection set is unchanged by them).\n */\n #onCrumbSelect(event: Event): void {\n event.stopPropagation();\n const selected = (event as CustomEvent<TreeSelectDetail>).detail.selected;\n const node = [...selected].at(0);\n if (!node)\n return;\n if (node.item.key === this.#effectiveRoot?.item.key) {\n this.zoomOut();\n } else {\n this.zoomTo(node);\n }\n }\n\n /** On-screen size (px) of `rect`, or `undefined` before the host has been measured. */\n #pixelSize(rect: TreemapRect): { width: number; height: number } | undefined {\n const hostWidth = this.clientWidth || 0;\n const hostHeight = this.clientHeight || 0;\n if (hostWidth <= 0 || hostHeight <= 0)\n return undefined;\n return { width: rect.width * hostWidth, height: rect.height * hostHeight };\n }\n\n /** Hide when too small by area, or too narrow to fit any readable text even truncated. */\n #hideLabel(rect: TreemapRect): boolean {\n const size = this.#pixelSize(rect);\n if (size === undefined)\n return false;\n return size.width * size.height < this.minLabelArea || size.width < this.minTileWidth;\n }\n\n /** Whether `rect` is large enough on-screen for its own children to be subdivided and drawn. */\n #canDescend(rect: TreemapRect): boolean {\n const size = this.#pixelSize(rect);\n // Unmeasured (first paint, before layout) ⇒ assume yes so nesting still shows up.\n if (size === undefined)\n return true;\n // Cascaded tiles reserve `cascadeOffset` px down+right for the depth\n // effect — children only get what's left, so judge by that.\n const offset = this.presentation === `cascaded` && Number.isFinite(this.cascadeOffset) && this.cascadeOffset > 0\n ? this.cascadeOffset\n : 0;\n const w = size.width - offset;\n const h = size.height - offset;\n if (w <= 0 || h <= 0)\n return false;\n return w * h >= this.minChildArea && w >= this.minTileWidth;\n }\n\n /** Slugify a category name into a CSS custom-property-safe token. */\n #categorySlug(category: string): string {\n return category.replace(/[^\\w-]/g, `-`);\n }\n\n /**\n * Inline colour overrides for `node`'s category, or `undefined` for none.\n * Set as real `background-color`/`color` (not custom properties) so they\n * simply win over `.tile`'s CSS-variable-driven defaults by specificity —\n * no risk of an unresolvable `var()` chain leaving the property invalid.\n */\n #categoryStyle(node: TreeNode): string | undefined {\n const category = this.categoryAccessor?.(node.item);\n if (!category)\n return undefined;\n const slug = this.#categorySlug(category);\n return `background-color:var(--treemap-category-${slug}-bg, var(--treemap-tile-bg));`\n + `color:var(--treemap-category-${slug}-text, var(--treemap-tile-text));`;\n }\n\n #renderTileBox(rect: TreemapRect, positionStyle: string, hasVisibleChildren: boolean, childrenContent: unknown): unknown {\n const { node } = rect;\n const selected = this._selectedNodes.has(node);\n const tickled = this.tickled.isTickled(node.item.key);\n const filtered = !this.#matchesFilter(node, rect.depth);\n const pending = this.#pendingKeys.has(node.item.key);\n const hideLabel = this.#hideLabel(rect);\n const showHeader = hasVisibleChildren && !hideLabel;\n const category = this.categoryAccessor?.(node.item);\n const categoryStyle = this.#categoryStyle(node);\n return html`\n <div\n class=\"item tile ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${filtered ? `filtered` : ``} ${pending ? `loading` : ``} ${rect.width <= 0 || rect.height <= 0 ? `empty` : ``}\"\n data-key=${node.item.key}\n data-depth=${rect.relativeDepth}\n data-category=${category ?? nothing}\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-level=${rect.depth + 1}\n aria-selected=${selected}\n aria-setsize=${rect.setSize}\n aria-posinset=${rect.index + 1}\n aria-label=${node.item.label}\n title=${node.item.label}\n part=\"tile\"\n style=${categoryStyle ? `${positionStyle};${categoryStyle}` : positionStyle}\n @click=${(e: MouseEvent) => {\n e.stopPropagation();\n this.#handleItemClick(rect, this.#rects().findIndex(r => r.node.item.key === node.item.key), e);\n }}\n @dblclick=${(e: MouseEvent) => {\n e.stopPropagation();\n this.#handleItemDblClick(rect);\n }}\n @pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}\n >\n ${showHeader\n ? html`<div class=\"tile-header\" part=\"tile-header\"><span class=\"treemap-label\" part=\"label\">${node.item.label}</span></div>`\n : html`<span class=\"treemap-label ${hideLabel ? `hide-label` : ``}\" part=\"label\">${node.item.label}</span>`}\n ${childrenContent}\n </div>\n `;\n }\n\n /**\n * Render `rect` plus (if it's large enough to descend into — see\n * `#canDescend`) a `.tile-children` holding its own children, each\n * positioned relative to `rect` itself and recursing the same way.\n *\n * Each level gets its own real `.tile-header` + `.tile-children` box, so a\n * header reserves its own space via normal box-model layout (flex column:\n * header, then the remaining space for children) at *every* level — not\n * just the top one. That matters because layout rects are purely\n * geometric (no allowance for header height), so a folder whose one child\n * fills ~100% of its area gets a child rect nearly identical to its own;\n * positioning that child against its direct parent (not some flattened\n * shared ancestor) is what keeps the parent's header from being painted\n * over by an opaque, near-identically-sized child box.\n */\n #renderTile(rect: TreemapRect, positionStyle: string, byParent: Map<string, TreemapRect[]>): unknown {\n const hasVisibleChildren = rect.hasChildren && this.#canDescend(rect);\n const children = hasVisibleChildren ? (byParent.get(rect.node.item.key) ?? []) : [];\n const childrenContent = children.length > 0\n ? html`\n <div class=\"tile-children\" role=\"group\">\n ${repeat(children, r => r.node.item.key, r => this.#renderNestedTile(r, rect, byParent))}\n </div>\n `\n : nothing;\n return this.#renderTileBox(rect, positionStyle, children.length > 0, childrenContent);\n }\n\n /** A child tile, positioned as a percentage of `parent`'s own box. */\n #renderNestedTile(rect: TreemapRect, parent: TreemapRect, byParent: Map<string, TreemapRect[]>): unknown {\n const relX = parent.width > 0 ? (rect.x - parent.x) / parent.width : 0;\n const relY = parent.height > 0 ? (rect.y - parent.y) / parent.height : 0;\n const relW = parent.width > 0 ? rect.width / parent.width : 0;\n const relH = parent.height > 0 ? rect.height / parent.height : 0;\n const style = `left:${(relX * 100).toFixed(4)}%;top:${(relY * 100).toFixed(4)}%;width:${(relW * 100).toFixed(4)}%;height:${(relH * 100).toFixed(4)}%`;\n return this.#renderTile(rect, style, byParent);\n }\n\n #renderTopTile(rect: TreemapRect, byParent: Map<string, TreemapRect[]>): unknown {\n const style = `left:${(rect.x * 100).toFixed(4)}%;top:${(rect.y * 100).toFixed(4)}%;width:${(rect.width * 100).toFixed(4)}%;height:${(rect.height * 100).toFixed(4)}%`;\n return this.#renderTile(rect, style, byParent);\n }\n\n protected override render() {\n const rects = this.#rects();\n const byParent = new Map<string, TreemapRect[]>();\n for (const rect of rects) {\n if (rect.parentKey === undefined)\n continue;\n const list = byParent.get(rect.parentKey) ?? [];\n list.push(rect);\n byParent.set(rect.parentKey, list);\n }\n // Top-level tiles: children of the (unrendered) zoom node.\n const zoomKey = this._zoomKey ?? this.#effectiveRoot?.item.key;\n const topLevel = zoomKey === undefined\n ? rects.filter(r => r.relativeDepth === 0)\n : (byParent.get(zoomKey) ?? rects.filter(r => r.relativeDepth === 0));\n return html`\n <div\n class=\"treemap\"\n role=\"tree\"\n tabindex=\"0\"\n data-presentation=${this.presentation}\n data-input-mode=${this.tickled.inputMode}\n style=${`--treemap-padding:${this.padding}px`}\n @keydown=${(e: KeyboardEvent) => this.#handleKeyDown(e)}\n @pointerleave=${() => this.tickled.clearTickled()}\n @wheel=${(e: WheelEvent) => this.#handleWheel(e)}\n >\n ${this.#renderBreadcrumb()}\n ${rects.length === 0\n ? html`<div class=\"empty-state\">No data</div>`\n : html`\n <div class=\"viewport\" part=\"viewport\">\n <div class=\"viewport-inner\">\n ${repeat(topLevel, r => r.node.item.key, r =>\n this.#renderTopTile(r, byParent))}\n </div>\n </div>\n `}\n </div>\n ${this.search.renderField()}\n `;\n }\n\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n listSearchStyles,\n css`\n :host {\n --treemap-height: 280px;\n --treemap-gap: 2px;\n --treemap-padding: 4px;\n --treemap-tile-bg: var(--surface-4);\n --treemap-tile-text: var(--surface-4-text);\n --treemap-tile-border: var(--border-subtle);\n --treemap-header-bg: rgb(0 0 0 / 0.12);\n --treemap-font-size: var(--text-s);\n --treemap-zoom-duration: 220ms;\n\n display: block;\n overflow: hidden;\n }\n\n /* Per-category tile colours (set categoryAccessor to opt in): define\n --treemap-category-SLUG-bg / -text at whatever scope suits (:host\n here, or globally) for each category your accessor can return —\n e.g. --treemap-category-urgent-bg: oklch(55% 0.18 25). A category\n with no matching pair falls back to --treemap-tile-bg/-text. */\n\n .treemap {\n display: flex;\n flex-direction: column;\n gap: var(--space-xs);\n outline: none;\n height: 100%;\n }\n\n .breadcrumb {\n display: flex;\n align-items: center;\n padding: var(--space-xs) var(--space-s);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n font-size: var(--text-s);\n flex-shrink: 0;\n }\n\n .breadcrumb ixfx-crumb-navigation {\n flex: 1;\n min-width: 0;\n }\n\n .viewport {\n position: relative;\n width: 100%;\n /* flex-basis of --treemap-height (its size when nothing forces a\n different one — the common case of an auto-height host) but\n allowed to grow/shrink like any flex item, so it shares the\n .treemap column's height with the breadcrumb instead of a plain\n fixed height always claiming that full amount regardless of what\n else needs space — which is what let the breadcrumb push the\n host past its own height and scroll once a zoom made it appear. */\n flex: 1 1 var(--treemap-height);\n min-height: 0;\n overflow: hidden;\n border-radius: var(--radius-m);\n }\n\n /* Transform target for the zoom-in/zoom-out FLIP animation (see\n #planFlip/#applyFlip) — kept separate from .viewport so the\n transform never fights that element's own sizing/overflow. */\n .viewport-inner {\n position: absolute;\n inset: 0;\n transform-origin: 0 0;\n }\n\n .viewport-inner.flipping {\n transition: transform var(--treemap-zoom-duration, 220ms) ease-out;\n }\n\n .tile {\n position: absolute;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n /* Override the shared .item class's align-items:center (built for\n icon+label rows) — tiles need their flex children to stretch to\n full width, or .tile-children collapses to its (empty) content\n width and every nested tile collapses with it. */\n align-items: stretch;\n white-space: normal;\n background: var(--treemap-tile-bg);\n color: var(--treemap-tile-text);\n border: var(--treemap-tile-border);\n font-size: var(--treemap-font-size);\n cursor: pointer;\n transition:\n opacity var(--transition),\n background-color var(--transition);\n }\n\n .tile-children {\n position: relative;\n flex: 1;\n min-height: 0;\n margin: var(--treemap-padding);\n margin-top: 0;\n }\n\n /* Cascaded presentation (Lü & Fogarty 2008): the geometric inset is\n already in the layout rects — this adds the stack-of-cards depth\n cue on top. Parent tiles read as cards sitting behind their\n children. */\n .treemap[data-presentation=\"cascaded\"] .tile {\n box-shadow: 2px 2px 0 rgb(0 0 0 / 0.25);\n }\n\n .tile-header {\n flex-shrink: 0;\n padding: 1px var(--space-xs);\n background: var(--treemap-header-bg);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: var(--font-weight-bold);\n }\n\n .tile > .treemap-label {\n padding: var(--space-xs);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tile-header .treemap-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .treemap-label.hide-label {\n visibility: hidden;\n }\n\n .tile.filtered {\n opacity: 0.3;\n filter: saturate(0.4);\n }\n\n .tile.empty {\n padding: 0;\n border: none;\n }\n\n .tile.loading {\n cursor: progress;\n opacity: 0.6;\n }\n\n .empty-state {\n padding: var(--space-l);\n color: var(--surface-muted-text);\n font-size: var(--text-s);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-treemap-list': TreemapListElement;\n }\n}\n\nexport interface TreemapListElement {\n addEventListener: (<K extends keyof TreemapListElementEventMap>(\n type: K,\n listener: (this: TreemapListElement, event: TreemapListElementEventMap[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 TreemapListElementEventMap>(\n type: K,\n listener: (this: TreemapListElement, event: TreemapListElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","import { clamp } from \"@ixfx/numbers\";\nimport { css, html, LitElement } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { handleStyles } from \"../styles/handle.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n// TODO: Fire event when panels have been resized\n/**\n * Lays out two elements within a container, with a bar to resize them\n * proportionally.\n *\n * Events\n * ixfx-split-collapsed: Dispatched when a panel is collapsed/uncollapsed via drag.\n * detail: { panel: 'A' | 'B', collapsed: boolean }\n *\n * Attributes\n * layout: `vertical`|`horizontal`\n * sizeA/B: CSS size of section A or B. Can use relative or absolute values\n * fixedA/B: If _true_ size will be calculated in pixels. By default (_false_) it uses % of whole\n * collapsible: If _true_, panels can be collapsed by dragging to edge (default: false)\n * minSizeA/B: Minimum size for panel A or B (e.g., \"100px\" or \"20%\"). Default: none\n * maxSizeA/B: Maximum size for panel A or B (e.g., \"200px\" or \"80%\"). Default: none\n *\n * CSS variables\n * --handle-size: 2px; // Width/height of split bar\n * --handle-colour: var(--surface-5); // Colour of split bar\n * --handle-hover-colour: var(--surface-6); // Split bar on hover\n * --handle-active-colour: var(--accent); // Split bar while dragging\n * --ixfx-handle-* // Grip look — shared handle primitive\n * // (see docs/infra-handle.md)\n */\n@customElement(`ixfx-twosplit-layout`)\nexport class TwoSplitLayoutElement extends LitElement {\n @property({ type: String })\n layout: `vertical` | `horizontal` = `vertical`;\n\n @property({ type: String })\n sizeA = ``;\n\n @property({ type: String })\n sizeB = ``;\n\n @property({ type: Boolean })\n fixedA = false;\n\n @property({ type: Boolean })\n fixedB = false;\n\n @property({ type: Boolean })\n collapsible = false;\n\n @property({ type: Boolean, reflect: true })\n collapsedA = false;\n\n @property({ type: Boolean, reflect: true })\n collapsedB = false;\n\n @property({ type: String })\n minSizeA = ``;\n\n @property({ type: String })\n maxSizeA = ``;\n\n @property({ type: String })\n minSizeB = ``;\n\n @property({ type: String })\n maxSizeB = ``;\n\n @state()\n private _hasCorner = false;\n\n private get showGrabHandle(): boolean {\n const size = getComputedStyle(this).getPropertyValue(`--handle-size`).trim();\n const num = Number.parseFloat(size);\n return !Number.isNaN(num) && num > 3;\n }\n\n #elementBounds: DOMRect | undefined;\n #startSizeA = ``;\n #startSizeB = ``;\n #cornerStartX = 0;\n #cornerStartY = 0;\n #nestedSplitInitialSizeA = ``;\n\n #cornerZone: HTMLElement | undefined;\n #nestedSplit: TwoSplitLayoutElement | undefined;\n #nestedSplitBounds: DOMRect | undefined;\n #nestedHandleBounds: DOMRect | undefined;\n #observer: MutationObserver | undefined;\n #pendingNestedUpdate: { sizeA: number; sizeB: number } | null = null;\n #collapsedAPointerAtCollapse: number | undefined;\n #collapsedBPointerAtCollapse: number | undefined;\n #hysteresisThreshold = 0.1;\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.#observer?.disconnect();\n }\n\n firstUpdated() {\n this.#setupNestedSplitObserver();\n }\n\n updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has(`sizeA`) || changedProperties.has(`sizeB`)\n || changedProperties.has(`collapsedA`) || changedProperties.has(`collapsedB`)) {\n this.#updateCornerPosition();\n }\n if (changedProperties.has(`sizeA`) || changedProperties.has(`sizeB`)) {\n this.#updateDataCollapsed();\n }\n }\n\n #updateDataCollapsed() {\n if (this.collapsedA) {\n this.setAttribute(`data-collapsed-a`, ``);\n } else {\n this.removeAttribute(`data-collapsed-a`);\n }\n if (this.collapsedB) {\n this.setAttribute(`data-collapsed-b`, ``);\n } else {\n this.removeAttribute(`data-collapsed-b`);\n }\n }\n\n #dispatchCollapsedEvent(panel: `A` | `B`, collapsed: boolean) {\n this.dispatchEvent(new CustomEvent(`ixfx-split-collapsed`, {\n detail: { panel, collapsed },\n bubbles: true,\n composed: true,\n }));\n }\n\n #setupNestedSplitObserver() {\n const slotA = this.shadowRoot?.querySelector(`slot[name=\"a\"]`) as HTMLSlotElement | undefined;\n if (!slotA)\n return;\n\n this.#observer = new MutationObserver(() => {\n this.#checkForNestedSplit();\n });\n\n this.#observer.observe(slotA, { characterData: true, childList: true, subtree: true });\n this.#checkForNestedSplit();\n }\n\n #checkForNestedSplit() {\n const slotA = this.shadowRoot?.querySelector(`slot[name=\"a\"]`) as HTMLSlotElement | undefined;\n if (!slotA)\n return;\n\n const assignedElements = slotA.assignedElements();\n\n const findNestedSplit = (elements: Element[]): TwoSplitLayoutElement | undefined => {\n for (const el of elements) {\n if (el.tagName === `IXFX-SPLIT-LAYOUT`) {\n return el as TwoSplitLayoutElement;\n }\n const nested = findNestedSplit(Array.from(el.children));\n if (nested)\n return nested;\n }\n return undefined;\n };\n\n const nestedSplit = findNestedSplit(assignedElements);\n\n if (nestedSplit) {\n this.#nestedSplit = nestedSplit;\n this._hasCorner = true;\n requestAnimationFrame(() => this.#updateCornerPosition());\n } else {\n this.#nestedSplit = undefined;\n this._hasCorner = false;\n }\n }\n\n #getNestedSplit(): TwoSplitLayoutElement | undefined {\n if (this.#nestedSplit)\n return this.#nestedSplit;\n\n const slotA = this.shadowRoot?.querySelector(`slot[name=\"a\"]`) as HTMLSlotElement | undefined;\n if (!slotA)\n return undefined;\n const assignedElements = slotA.assignedElements();\n return assignedElements.find(\n el => el.tagName === `IXFX-SPLIT-LAYOUT`,\n ) as TwoSplitLayoutElement | undefined;\n }\n\n #parseSizeAsFraction(size: string, total: number): number {\n if (size.endsWith(`px`)) {\n return Number.parseFloat(size.replace(`px`, ``)) / total;\n } else if (size.endsWith(`%`)) {\n return Number.parseFloat(size.replace(`%`, ``)) / 100;\n }\n return 0.5;\n }\n\n #parseSizeToPx(size: string, total: number): number | null {\n if (size.endsWith(`px`)) {\n return Number.parseFloat(size.replace(`px`, ``));\n } else if (size.endsWith(`%`)) {\n return (Number.parseFloat(size.replace(`%`, ``)) / 100) * total;\n }\n return null;\n }\n\n #applyConstraints(sizeA: string, sizeB: string, total: number): { sizeA: string; sizeB: string } {\n let fractionA = this.#parseSizeAsFraction(sizeA, total);\n let fractionB = this.#parseSizeAsFraction(sizeB, total);\n\n const minA = this.#minSizeToFraction(this.minSizeA, total);\n const minB = this.#minSizeToFraction(this.minSizeB, total);\n const maxA = this.#maxSizeToFraction(this.maxSizeA, total);\n const maxB = this.#maxSizeToFraction(this.maxSizeB, total);\n\n if (minA !== null || minB !== null) {\n const minSum = (minA ?? 0) + (minB ?? 0);\n if (minSum > 1) {\n const scale = 1 / minSum;\n if (minA !== null)\n minA !== null ? fractionA = minA * scale : fractionA = 0;\n if (minB !== null)\n minB !== null ? fractionB = minB * scale : fractionB = 0;\n }\n\n if (fractionA < (minA ?? 0))\n fractionA = minA ?? 0;\n if (fractionB < (minB ?? 0))\n fractionB = minB ?? 0;\n }\n\n if (maxA !== null) {\n if (fractionA > maxA)\n fractionA = maxA;\n }\n if (maxB !== null) {\n if (fractionB > maxB)\n fractionB = maxB;\n }\n\n fractionB = 1 - fractionA;\n\n const isPercentA = !this.sizeA.endsWith(`px`);\n const _isPercentB = !this.sizeB.endsWith(`px`);\n\n if (isPercentA) {\n return { sizeA: `${fractionA * 100}%`, sizeB: `${fractionB * 100}%` };\n } else {\n return { sizeA: `${fractionA * total}px`, sizeB: `${fractionB * total}px` };\n }\n }\n\n #minSizeToFraction(minSize: string, total: number): number | null {\n if (minSize.length === 0)\n return null;\n const px = this.#parseSizeToPx(minSize, total);\n if (px !== null)\n return px / total;\n if (minSize.endsWith(`%`))\n return Number.parseFloat(minSize.replace(`%`, ``)) / 100;\n return null;\n }\n\n #maxSizeToFraction(maxSize: string, total: number): number | null {\n if (maxSize.length === 0)\n return null;\n const px = this.#parseSizeToPx(maxSize, total);\n if (px !== null)\n return px / total;\n if (maxSize.endsWith(`%`))\n return Number.parseFloat(maxSize.replace(`%`, ``)) / 100;\n return null;\n }\n\n #getIntersectionPoint(): { x: number; y: number } | null {\n const outerBounds = this.getBoundingClientRect();\n const zoneEl = this.getZone();\n if (!zoneEl)\n return null;\n\n const nestedSplit = this.#getNestedSplit();\n if (!nestedSplit)\n return null;\n\n const _zoneBounds = zoneEl.getBoundingClientRect();\n\n const outerFraction = this.#parseSizeAsFraction(this.sizeA || `50%`, outerBounds.width);\n\n let x: number, y: number;\n\n if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {\n x = outerFraction * outerBounds.width;\n const nestedFraction = this.#parseSizeAsFraction(nestedSplit.sizeA || `50%`, outerBounds.height);\n y = nestedFraction * outerBounds.height;\n } else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {\n const nestedFraction = this.#parseSizeAsFraction(nestedSplit.sizeA || `50%`, outerBounds.width);\n x = nestedFraction * outerBounds.width;\n y = outerFraction * outerBounds.height;\n } else {\n return null;\n }\n\n return { x, y };\n }\n\n #updateCornerPosition() {\n if (!this._hasCorner)\n return;\n\n const cornerZone = this.shadowRoot?.querySelector(`.corner-zone`) as HTMLElement | undefined;\n if (!cornerZone)\n return;\n\n const zoneEl = this.getZone();\n if (!zoneEl)\n return;\n\n const intersection = this.#getIntersectionPoint();\n if (!intersection) {\n cornerZone.style.display = `none`;\n return;\n }\n\n const cornerX = intersection.x - 6;\n const cornerY = intersection.y - 6;\n\n cornerZone.style.left = `${cornerX}px`;\n cornerZone.style.top = `${cornerY}px`;\n cornerZone.style.display = `block`;\n\n const nestedSplit = this.#getNestedSplit();\n if (nestedSplit) {\n if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {\n cornerZone.style.cursor = `nwse-resize`;\n } else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {\n cornerZone.style.cursor = `nesw-resize`;\n }\n }\n }\n\n getZone(): HTMLElement | undefined {\n if (!this.shadowRoot)\n return;\n const el = this.shadowRoot.querySelector(`#zone`);\n if (!el)\n return undefined;\n return el as HTMLElement;\n }\n\n #onResizeHandleDown = (event: PointerEvent) => {\n event.preventDefault();\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.add(`user-resizing`);\n }\n this.#elementBounds = this.getBoundingClientRect();\n this.#startSizeA = this.sizeA;\n this.#startSizeB = this.sizeB;\n window.addEventListener(`pointerup`, this.#onResizeHandleUp);\n window.addEventListener(`pointermove`, this.#onResizeHandleMove);\n };\n\n #onResizeHandleUp = (event: PointerEvent) => {\n event.preventDefault();\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.remove(`user-resizing`);\n }\n window.removeEventListener(`pointerup`, this.#onResizeHandleUp);\n window.removeEventListener(`pointermove`, this.#onResizeHandleMove);\n };\n\n #onResizeHandleMove = (event: PointerEvent) => {\n const bounds = this.#elementBounds;\n if (!bounds)\n return;\n\n const threshold = 5;\n\n if (this.layout === `horizontal`) {\n const y = event.y - bounds.y;\n const relativeY = clamp(y / bounds.height);\n\n if (this.collapsible && this.collapsedA) {\n if (relativeY > (this.#collapsedAPointerAtCollapse ?? 0.05) + this.#hysteresisThreshold) {\n this.collapsedA = false;\n this.#dispatchCollapsedEvent(`A`, false);\n this.#collapsedAPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeY * 100}%`,\n `${(1 - relativeY) * 100}%`,\n bounds.height,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedA && relativeY < threshold / bounds.height) {\n this.collapsedA = true;\n this.#dispatchCollapsedEvent(`A`, true);\n this.sizeA = `0px`;\n this.sizeB = `100%`;\n this.#collapsedAPointerAtCollapse = relativeY;\n } else if (!this.collapsedA) {\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeY * 100}%`,\n `${(1 - relativeY) * 100}%`,\n bounds.height,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n\n if (this.collapsible && this.collapsedB) {\n if (relativeY < (this.#collapsedBPointerAtCollapse ?? 0.95) - this.#hysteresisThreshold) {\n this.collapsedB = false;\n this.#dispatchCollapsedEvent(`B`, false);\n this.#collapsedBPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeY * 100}%`,\n `${(1 - relativeY) * 100}%`,\n bounds.height,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedB && relativeY > (1 - threshold / bounds.height)) {\n this.collapsedB = true;\n this.#dispatchCollapsedEvent(`B`, true);\n this.sizeA = `100%`;\n this.sizeB = `0px`;\n this.#collapsedBPointerAtCollapse = relativeY;\n }\n } else {\n const x = event.x - bounds.x;\n const relativeX = clamp(x / bounds.width);\n\n if (this.collapsible && this.collapsedA) {\n if (relativeX > (this.#collapsedAPointerAtCollapse ?? 0.05) + this.#hysteresisThreshold) {\n this.collapsedA = false;\n this.#dispatchCollapsedEvent(`A`, false);\n this.#collapsedAPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeX * 100}%`,\n `${(1 - relativeX) * 100}%`,\n bounds.width,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedA && relativeX < threshold / bounds.width) {\n this.collapsedA = true;\n this.#dispatchCollapsedEvent(`A`, true);\n this.sizeA = `0px`;\n this.sizeB = `100%`;\n this.#collapsedAPointerAtCollapse = relativeX;\n } else if (!this.collapsedA) {\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeX * 100}%`,\n `${(1 - relativeX) * 100}%`,\n bounds.width,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n\n if (this.collapsible && this.collapsedB) {\n if (relativeX < (this.#collapsedBPointerAtCollapse ?? 0.95) - this.#hysteresisThreshold) {\n this.collapsedB = false;\n this.#dispatchCollapsedEvent(`B`, false);\n this.#collapsedBPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeX * 100}%`,\n `${(1 - relativeX) * 100}%`,\n bounds.width,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedB && relativeX > (1 - threshold / bounds.width)) {\n this.collapsedB = true;\n this.#dispatchCollapsedEvent(`B`, true);\n this.sizeA = `100%`;\n this.sizeB = `0px`;\n this.#collapsedBPointerAtCollapse = relativeX;\n }\n }\n event.preventDefault();\n };\n\n #onCornerResizeDown = (event: PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.add(`user-resizing`);\n }\n\n this.#elementBounds = this.getBoundingClientRect();\n this.#cornerStartX = event.clientX;\n this.#cornerStartY = event.clientY;\n this.#startSizeA = this.sizeA;\n this.#startSizeB = this.sizeB;\n\n const nestedSplit = this.#getNestedSplit();\n if (nestedSplit) {\n this.#nestedSplitInitialSizeA = nestedSplit.sizeA;\n const nestedBounds = nestedSplit.getBoundingClientRect();\n const nestedHandle = nestedSplit.shadowRoot?.querySelector(`.split-bar`) as HTMLElement;\n if (nestedHandle) {\n this.#nestedSplitBounds = nestedBounds;\n this.#nestedHandleBounds = nestedHandle.getBoundingClientRect();\n }\n const nestedZoneEl = nestedSplit.getZone();\n if (nestedZoneEl) {\n nestedZoneEl.classList.add(`user-resizing`);\n }\n }\n\n window.addEventListener(`pointerup`, this.#onCornerResizeUp);\n window.addEventListener(`pointermove`, this.#onCornerResizeMove);\n };\n\n #onCornerResizeUp = (event: PointerEvent) => {\n event.preventDefault();\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.remove(`user-resizing`);\n }\n const nestedSplit = this.#getNestedSplit();\n if (nestedSplit) {\n const nestedZoneEl = nestedSplit.getZone();\n if (nestedZoneEl) {\n nestedZoneEl.classList.remove(`user-resizing`);\n }\n }\n window.removeEventListener(`pointerup`, this.#onCornerResizeUp);\n window.removeEventListener(`pointermove`, this.#onCornerResizeMove);\n };\n\n #applyPendingNestedUpdate() {\n if (!this.#pendingNestedUpdate)\n return;\n const { sizeA, sizeB } = this.#pendingNestedUpdate;\n const nested = this.#getNestedSplit();\n if (nested) {\n nested.sizeA = `${sizeA * 100}%`;\n nested.sizeB = `${sizeB * 100}%`;\n }\n this.#pendingNestedUpdate = null;\n }\n\n #onCornerResizeMove = (event: PointerEvent) => {\n const outerBounds = this.#elementBounds;\n const zoneEl = this.getZone();\n const nestedSplit = this.#getNestedSplit();\n if (!outerBounds || !zoneEl || !nestedSplit)\n return;\n\n const zoneBounds = zoneEl.getBoundingClientRect();\n const cursorZoneLocalX = event.clientX - zoneBounds.left;\n const cursorZoneLocalY = event.clientY - zoneBounds.top;\n\n if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {\n let newOuterFraction = cursorZoneLocalX / outerBounds.width;\n const newNestedFraction = cursorZoneLocalY / outerBounds.height;\n\n const { sizeA: constrainedA, sizeB: constrainedB } = this.#applyConstraints(\n `${newOuterFraction * 100}%`,\n `${(1 - newOuterFraction) * 100}%`,\n outerBounds.width,\n );\n newOuterFraction = this.#parseSizeAsFraction(constrainedA, outerBounds.width);\n\n this.sizeA = constrainedA;\n this.sizeB = constrainedB;\n\n this.#pendingNestedUpdate = {\n sizeA: newNestedFraction,\n sizeB: 1 - newNestedFraction,\n };\n requestAnimationFrame(() => this.#applyPendingNestedUpdate());\n\n const cornerZone = this.shadowRoot?.querySelector(`.corner-zone`) as HTMLElement | undefined;\n if (cornerZone) {\n cornerZone.style.left = `${cursorZoneLocalX - 6}px`;\n cornerZone.style.top = `${cursorZoneLocalY - 6}px`;\n }\n } else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {\n const newNestedFraction = cursorZoneLocalX / outerBounds.width;\n let newOuterFraction = cursorZoneLocalY / outerBounds.height;\n\n const { sizeA: constrainedA, sizeB: constrainedB } = this.#applyConstraints(\n `${newOuterFraction * 100}%`,\n `${(1 - newOuterFraction) * 100}%`,\n outerBounds.height,\n );\n newOuterFraction = this.#parseSizeAsFraction(constrainedA, outerBounds.height);\n\n this.sizeA = constrainedA;\n this.sizeB = constrainedB;\n\n this.#pendingNestedUpdate = {\n sizeA: newNestedFraction,\n sizeB: 1 - newNestedFraction,\n };\n requestAnimationFrame(() => this.#applyPendingNestedUpdate());\n\n const cornerZone = this.shadowRoot?.querySelector(`.corner-zone`) as HTMLElement | undefined;\n if (cornerZone) {\n cornerZone.style.left = `${cursorZoneLocalX - 6}px`;\n cornerZone.style.top = `${cursorZoneLocalY - 6}px`;\n }\n }\n\n event.preventDefault();\n };\n\n render() {\n const sizePrefix = this.layout === `vertical` ? `width` : `height`;\n let sizeA = this.sizeA;\n let sizeB = this.sizeB;\n\n if (this.collapsedA) {\n sizeA = `0px`;\n } else if (sizeA.length === 0 && sizeB.length === 0) {\n sizeB = sizeA = `50%`;\n } else if (sizeA.length === 0) {\n sizeA = `auto`;\n } else if (sizeB.length === 0) {\n sizeB = `auto`;\n }\n\n if (this.collapsedB) {\n sizeB = `0px`;\n }\n\n sizeA = `${sizePrefix}:${sizeA}`;\n sizeB = `${sizePrefix}:${sizeB}`;\n\n return html`\n <div id=\"zone\">\n <slot style=${sizeA} name=\"a\"></slot>\n ${this._hasCorner ? html`<div class=\"corner-zone\" @pointerdown=${this.#onCornerResizeDown}></div>` : ``}\n <div @pointerdown=${this.#onResizeHandleDown} class=\"split-bar\">\n ${this.showGrabHandle\n ? html`<span\n class=\"ixfx-handle\"\n part=\"grip\"\n data-handle=\"dimpled\"\n data-shape=${this.layout === `horizontal` ? `horizontal` : `vertical`}\n ></span>`\n : ``}\n </div>\n <slot style=${sizeB} name=\"b\"></slot>\n </div>`;\n }\n\n static styles = [themeFallbacks, handleStyles, css`\n :host {\n --handle-size: 2px;\n --handle-colour: transparent;\n --handle-hover-colour: var(--surface-6);\n --handle-active-colour: var(--accent);\n /* Grip — shared handle primitive (docs/infra-handle.md). */\n --ixfx-handle-length: 16px;\n --ixfx-handle-thickness: 8px;\n\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n }\n * {\n box-sizing: border-box;\n }\n #zone {\n display: flex;\n height: 100%;\n position: relative;\n }\n slot {\n display: block;\n overflow: hidden;\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n }\n :slotted(*) {\n width: 100%;\n height: 100%;\n }\n\n .split-bar {\n position: relative;\n background-color: var(--handle-colour);\n transition: background-color 0.3s ease 0s;\n width: var(--handle-size);\n height: 100%;\n cursor: ew-resize;\n flex-shrink: 0;\n border-radius: var(--radius-m);\n\n }\n\n @keyframes handle-hover {\n from { background-color: var(--handle-colour); }\n to { background-color: var(--handle-hover-colour); }\n }\n\n .split-bar .ixfx-handle {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n }\n\n #zone.user-resizing .ixfx-handle {\n display: none;\n }\n #zone.user-resizing {\n slot {\n opacity: 0.5;\n }\n .split-bar {\n background-color: var(--handle-active-colour);\n transition: none;\n animation: none !important;\n }\n }\n\n #zone:not(.user-resizing) .split-bar:hover {\n animation: handle-hover 0.001s ease-out 0.7s both;\n }\n\n .corner-zone {\n position: absolute;\n width: 12px;\n height: 12px;\n z-index: 10;\n border-radius: 50%;\n background: transparent;\n }\n .corner-zone:hover {\n background: transparent;\n }\n\n :host([layout='horizontal']) {\n #zone {\n flex-direction: column;\n }\n .split-bar {\n position: relative;\n background-color: var(--handle-colour);\n transition: background-color 0.3s ease 0s;\n height: var(--handle-size);\n width: 100%;\n cursor: ns-resize;\n }\n #zone.user-resizing .split-bar {\n background-color: var(--handle-active-colour);\n transition: none;\n animation: none !important;\n }\n }\n\n :host([data-collapsed-a]) slot[name=\"a\"],\n :host([data-collapsed-b]) slot[name=\"b\"] {\n display: none;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-twosplit-layout\": TwoSplitLayoutElement;\n }\n}\n","interface CheckboxLike extends HTMLElement {\n checked: boolean;\n indeterminate?: boolean;\n}\n\nfunction isCheckboxLike(el: unknown): el is CheckboxLike {\n if (!(el instanceof HTMLElement))\n return false;\n return `checked` in el;\n}\n\nfunction resolveElement(elOrQuery: string | HTMLElement): HTMLElement {\n if (typeof elOrQuery === `string`) {\n const found = document.querySelector(elOrQuery);\n if (!(found instanceof HTMLElement))\n throw new Error(`Element not found or not HTMLElement: ${elOrQuery}`);\n return found;\n }\n return elOrQuery;\n}\n\nexport function monitorIndeterminate(\n targetElOrQuery: string | HTMLElement,\n watchedElsOrQueries: Array<string | HTMLElement>,\n): () => void {\n const target = resolveElement(targetElOrQuery);\n if (!isCheckboxLike(target)) {\n throw new Error(`Target element is not a checkbox-like element`);\n }\n\n const watched: CheckboxLike[] = [];\n for (const elOrQuery of watchedElsOrQueries) {\n const el = resolveElement(elOrQuery);\n if (isCheckboxLike(el)) {\n watched.push(el);\n }\n }\n\n const updateTarget = () => {\n if (watched.length === 0) {\n target.checked = false;\n target.indeterminate = false;\n return;\n }\n\n let checkedCount = 0;\n let uncheckedCount = 0;\n\n for (const el of watched) {\n if (el.checked) {\n checkedCount++;\n } else {\n uncheckedCount++;\n }\n }\n\n if (checkedCount > 0 && uncheckedCount > 0) {\n target.checked = false;\n target.indeterminate = true;\n } else if (checkedCount === watched.length) {\n target.checked = true;\n target.indeterminate = false;\n } else {\n target.checked = false;\n target.indeterminate = false;\n }\n };\n\n const handleChange = () => {\n updateTarget();\n };\n\n for (const el of watched) {\n el.addEventListener(`change`, handleChange);\n }\n\n updateTarget();\n\n return () => {\n for (const el of watched) {\n el.removeEventListener(`change`, handleChange);\n }\n };\n}\n","import \"./style.css\";\n\nexport * from './ac-text/ac-text.js';\nexport * from './ac-token/ac-token.js';\nexport * from './bottom-drawer/bottom-drawer.js';\nexport * from './button/button.js';\nexport * from './button/radio-group.js';\nexport * from './button/split-button.js';\nexport * from './button/types.js';\nexport * from './checkbox/checkbox.js';\nexport * from './colour-picker/index.js';\nexport * from './common/data-controller.js';\nexport * from './common/data-provider.js';\nexport * from './common/searchable.js';\nexport * from './common/tree-component.js';\nexport * from './common/tree-data-model.js';\nexport * from './common/tree-drop-apply.js';\nexport * from './common/types.js';\nexport * from './crumbs/crumb-navigation.js';\nexport * from './crumbs/crumb-path-controller.js';\nexport * from './crumbs/crumb-path.js';\n\nexport * from './data-display/data-display.js';\nexport * from './data-grid/data-grid.js';\nexport * from './data-table/data-table.js';\nexport * from './detail-list/detail-list.js';\nexport {\n getActiveDragPanelId,\n isDragging,\n pointerOverAnyHost,\n} from './dock/dock-drag.js';\nexport type { DockDropZone } from './dock/dock-drag.js';\nexport * from './dock/dock-host.js';\nexport * from './dock/dock-model.js';\nexport * from './dock/dock-panel.js';\nexport * from './dock/types.js';\nexport * from './editable-label/editable-label.js';\nexport * from './editable-label/editable-number.js';\nexport * from './form/form-group.js';\nexport * from './form/form-part.js';\nexport * from './form/form.js';\nexport * from './grid-list/grid-list.js';\nexport * from './grouped-item-lister/grouped-item-lister.js';\nexport * from './grouped-item-lister/tree-list-adapter.js';\nexport * from './grouped-item-lister/vertical-list-adapter.js';\nexport * from './hex/hex-editor.js';\nexport * from './hyperbolic-tree/hyperbolictree-list.js';\nexport * from './hyperbolic-tree/layout.js';\nexport * from './hyperbolic-tree/poincare-math.js';\nexport type {\n ComputeHyperbolicLayoutOptions,\n HyperbolicEdgeRenderContext,\n HyperbolicEdgeRenderer,\n HyperbolicFocusDetail,\n HyperbolicFocusEvent,\n HyperbolicInteractionMode,\n HyperbolicLayoutEdge,\n HyperbolicLayoutNode,\n Point as HyperbolicPoint,\n} from './hyperbolic-tree/types.js';\nexport * from './icicle-tree/icicletree-list.js';\nexport * from './icicle-tree/layout.js';\nexport * from './icicle-tree/types.js';\nexport * from './icons/index.js';\nexport * from './incr-search/index.js';\nexport * from './interaction/index.js';\nexport * from './labelled-radial-input/index.js';\nexport * from './labelled-range-input/index.js';\nexport * from './labelled-slider-input/index.js';\nexport * from './led/led.js';\nexport * as Menu from './menu';\nexport * from './miller/index.js';\nexport * from './multicol-list/multicol-list.js';\nexport * from './narrowed-text/index.js';\nexport * from './notifier/manager.js';\nexport * from './notifier/notification-pill.js';\nexport * from './notifier/pill-renderer.js';\nexport * from './notifier/types.js';\nexport * from './pan-text/index.js';\nexport * from './panel/panel-group.js';\nexport * from './panel/panel.js';\nexport * from './plots/colour-map.js';\nexport * from './plots/data.js';\nexport * from './plots/multi-axis.js';\nexport * from './plots/plot-histogram.js';\nexport * from './plots/single-axis.js';\nexport * from './plots/xy-axis.js';\nexport * from './polar-pad/polar-pad.js';\nexport * from './radial-input/radial-input.js';\nexport * from './radial-input/types.js';\nexport * from './range-input/index.js';\nexport * from './range/range-multi.js';\nexport * from './range/range.js';\nexport * from './rating/rating.js';\nexport * from './select-horiz/select-horiz.js';\nexport * from './shapefill-value/shapefill-value.js';\nexport * from './shapefill-value/types.js';\nexport * from './slider-input/slider-input.js';\nexport * from './slider-input/types.js';\nexport * from './sliding-number/sliding-number.js';\nexport * from './snackbar/snackbar.js';\nexport * from './snap-container/snap-container.js';\nexport * from './split-layout/split-layout.js';\nexport * from './split-layout/split-model.js';\nexport * from './split-layout/split-panel.js';\nexport * from './split-layout/types.js';\nexport * from './swipe/index.js';\nexport * from './tabs/tab-controller.js';\nexport * from './tabs/tab-list-item.js';\nexport * from './tabs/tab-list.js';\nexport * from './tabs/tab-panel.js';\nexport * from './tabs/tab-panels.js';\nexport * from './text-shimmer/text-shimmer.js';\nexport * from './timeline/index.js';\nexport * from './titlebar/titlebar.js';\nexport * from './toolbar/toolbar-group.js';\nexport * from './toolbar/toolbar.js';\nexport * from './toolbar/types.js';\nexport * from './transitory-label/transitory-label.js';\nexport * from './tree/index.js';\nexport { computeTreemapLayout, findTreemapNode, findTreemapPath } from './treemap/layout.js';\nexport * from './treemap/treemap-list.js';\nexport type { ComputeTreemapLayoutOptions, TreemapInteractionMode, TreemapRect, TreemapTilingMethod, TreemapValueAccessor } from './treemap/types.js';\nexport * from './twosplit-layout/split-layout.js';\nexport * from './util/checkbox.js';\nexport * from './util/tooltip.js';\nexport * from './vertical-list/vertical-list.js';\nexport * from './xy-pad/xy-pad.js';\nexport function init() {\n console.log(`Init`);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#collapsedDragging","#dragStartY","#dragStartHeight","#onTabPointerMove","#onTabPointerUp","#displayHeight","#onResizeMove","#onResizeEnd","#maxHeight","#setHeight","#syncCommands","#teardownCommands","#ownedRegistry","#commandTarget","#commandName","#commandIds","#morphProgress","#dragOpacity","#onDrawerKeyDown","#onResizeStart","#onResizeKeyDown","customElement","#updateComputedItems","#handleToggleChange","#handleRadioChange","customElement","#handleArrowDown","#handleArrowUp","#handleArrowRight","#handleArrowLeft","#handleEnter","customElement","#separator","#onQuery","#sortCompare","#pathed","#element","#siblingLookup","#segmentIconLookup","#cleanupPending","#closeDropdown","#scrollDropdownActiveIntoView","#selectSibling","#uid","#getSegments","#anchorName","#pendingController","#pendingIndex","#getRootSegments","#clickSuppressUntil","#isSegmentPrefix","#segmentDragPayloads","#getCumulativePath","#resolveFullPathSegments","#eventTargetsSegment","#leafSegment","#onSegDrop","#clicksSuppressed","#recordHintOnShorten","#onSiblingClick","#resolveSegmentIcon","#onSegmentClick","#onSegDragOver","#onSegDragLeave","#onLabelClick","#onLabelDragStart","#onLabelDragEnd","#onCaretClick","#onVirtualSegmentClick","#onRootSegmentClick","#dispatchChangeEvent","#makeCompletionProvider","#onAcChange","#onAcFocusOut","#onAcKeyDown","#onHostKeyDown","#onHostDragOver","#onHostDragLeave","#onHostDrop","#renderRootSegment","#renderSegment","#renderVirtualSegment","#onTrailingClick","#onPopoverToggle","#onDropdownKeyDown","#renderDropdownContent","customElement","#resizeObserver","#lastWidth","#updateStacked","#detailTimer","#handlePointerLeave","#handlePointerEnter","#select","customElement","customElement","DRAG_THRESHOLD_PX","customElement","DRAG_THRESHOLD_PX","customElement","prefersReducedMotion","#layout","#lastLabelIds","#preview","#currentView","#cancelAnimation","#zoomState","#focusTree","#effectiveRoot","#rootId","#ownedRegistry","#syncSearchCommands","#resizeObserver","#modelUnsubscribe","#lazy","#animFrame","#effectiveSearchModes","#unregisterSearchCommands","#resetViewState","#clearSelectionInternal","#gestures","#canSelect","#dispatchSelect","#idOf","#viewFromFrameOf","#animateTo","prefersReducedMotion","#matchesFilter","#focusAndMaybeSelect","#handleNodePointerDown","#handleItemClick","#handleItemDblClick","#nodeContext","#handleKeyDown","#renderNodes","#previewFor","#pickPreviewChild","customElement","#rects","#effectiveRoot","#ownedRegistry","#syncSearchCommands","#resizeObserver","#modelUnsubscribe","#aborters","#pendingKeys","#effectiveSearchModes","#unregisterSearchCommands","#resetViewState","#anchorIndex","#ensureVisibleChildren","#syncTooltip","#hostExtent","#labelMode","#clearSelectionInternal","#loadChildren","#canSelect","#dispatchSelect","#findKeyPath","#resolveKeyPath","#matchesFilter","#canZoom","#onCrumbSelect","#handleItemClick","#handleItemDblClick","#handleKeyDown","#renderBreadcrumb","#renderRect","customElement","#category","#categoryDefaults","#selectionMode","#dataProvider","#onSelectionChange","#onRequestData","#state","#repush","#syncGrouping","#subComponents","#host","#allSelected","#setAllSelection","#allRow","#handleSelect","#listerEl","#syncAllRow","#lastItems","#pushItems","#restoreAfterSync","#abortPending","#abortController","#applyItems","#selectedValues","#syncingSelection","#createController","#categoryToNode","#openMenuAt","#menuItem","#insertColumn","customElement","DRAG_THRESHOLD_PX","customElement","#scaleTo100","#userMin","#userMax","#scaleFrom100","#userClamp","#updateScale","customElement","customElement","#dragging","#dragStartY","#lastPointerY","#valueAtDragStart","#lastSetValue","#onPointerMove","#onPointerUp","#setValueFromRelative","#stepByRelativeDelta","#quantise","#getRelativeValue","#scheduleChangeEvent","#fireChangeEvent","#changeDebounceTimer","#onPointerDown","#onKeyDown","#renderRectangle","#renderCircle","customElement","customElement","customElement","#list","#panels","#opts","#commands","#signal","#onChange","#onReorder","#onClose","#observer","#rebuild","#tabs","#registerCommand","#unregisterCommand","#registeredCommands","#resolveTab","#selectOffset","#idsFor","#fillContent","#insertElement","#adjacentTab","#removeFromIndex","#reregisterCommand","#tabByItem","#slug","#uniqueId","#labelOf","#isSelected","#list","#unselect","#select","#findTabItem","#labelOf","customElement","customElement","customElement","customElement","normaliseValue","#rects","#effectiveRoot","#rectsForZoom","#cascadeFractions","#ownedRegistry","#syncSearchCommands","#resizeObserver","#modelUnsubscribe","#aborters","#pendingKeys","#effectiveSearchModes","#unregisterSearchCommands","#resetViewState","#anchorIndex","#ensureVisibleChildren","#pendingFlip","#applyFlip","#clearSelectionInternal","#loadChildren","#canSelect","#dispatchSelect","#planFlip","#findKeyPath","#resolveKeyPath","#matchesFilter","#rectCenter","#canZoom","#nearestInDirection","#wheelCooldownUntil","#zoomOutOneStep","#onCrumbSelect","#pixelSize","#categorySlug","#hideLabel","#categoryStyle","#handleItemClick","#handleItemDblClick","#canDescend","#renderNestedTile","#renderTileBox","#renderTile","#handleKeyDown","#handleWheel","#renderBreadcrumb","#renderTopTile","customElement","#elementBounds","#startSizeA","#startSizeB","#onResizeHandleUp","#onResizeHandleMove","#collapsedAPointerAtCollapse","#hysteresisThreshold","#dispatchCollapsedEvent","#applyConstraints","#collapsedBPointerAtCollapse","#cornerStartX","#cornerStartY","#getNestedSplit","#nestedSplitInitialSizeA","#nestedSplitBounds","#nestedHandleBounds","#onCornerResizeUp","#onCornerResizeMove","#parseSizeAsFraction","#pendingNestedUpdate","#applyPendingNestedUpdate","#observer","#setupNestedSplitObserver","#updateCornerPosition","#updateDataCollapsed","#checkForNestedSplit","#nestedSplit","#minSizeToFraction","#maxSizeToFraction","#parseSizeToPx","#getIntersectionPoint","#onCornerResizeDown","#onResizeHandleDown","customElement"],"sources":["../src/bottom-drawer/bottom-drawer.ts","../src/button/radio-group.ts","../src/interaction/tree-keyboard-controller.ts","../src/button/split-button.ts","../src/crumbs/crumb-path-controller.ts","../src/crumbs/crumb-path.ts","../src/data-table/data-table.ts","../src/dock/dock-drag.ts","../src/dock/dock-model.ts","../src/tabs/tab-list-item.ts","../src/dock/dock-panel.ts","../src/dock/dock-host.ts","../src/form/form-group.ts","../src/form/form-part.ts","../src/grouped-item-lister/tree-list-adapter.ts","../src/grouped-item-lister/vertical-list-adapter.ts","../src/hyperbolic-tree/child-preview.ts","../src/hyperbolic-tree/poincare-math.ts","../src/hyperbolic-tree/view-motion.ts","../src/hyperbolic-tree/gestures.ts","../src/hyperbolic-tree/hyperbolictree-styles.ts","../src/hyperbolic-tree/layout.ts","../src/hyperbolic-tree/keyboard.ts","../src/hyperbolic-tree/lazy-children.ts","../src/hyperbolic-tree/render-utils.ts","../src/hyperbolic-tree/render-context.ts","../src/hyperbolic-tree/render-templates.ts","../src/hyperbolic-tree/hyperbolictree-list.ts","../src/icicle-tree/layout.ts","../src/icicle-tree/icicletree-list.ts","../src/multicol-list/types.ts","../src/multicol-list/column.ts","../src/multicol-list/multicol-list.ts","../src/notifier/pill-renderer.ts","../src/notifier/manager.ts","../src/panel/panel-group.ts","../src/util/drag.ts","../src/util/near.ts","../src/range/range-multi.ts","../src/rating/rating.ts","../src/util/clamp.ts","../src/util/geometry.ts","../src/shapefill-value/shapefill-value.ts","../src/sliding-number/sliding-number.ts","../src/tabs/tab-panel.ts","../src/tabs/tab-controller.ts","../src/tabs/tab-panels.ts","../src/text-shimmer/text-shimmer.ts","../src/toolbar/toolbar-group.ts","../src/toolbar/toolbar.ts","../src/treemap/layout.ts","../src/treemap/treemap-list.ts","../src/twosplit-layout/split-layout.ts","../src/util/checkbox.ts","../src/index.ts"],"sourcesContent":["/* eslint-disable ts/no-unsafe-declaration-merging */\n/**\n * `ixfx-bottom-drawer` — an overlay that slides up over the bottom of its\n * container. Place it as a **sibling** of the content it covers, inside a\n * positioned container:\n *\n * ```html\n * <div id=\"container\" style=\"position: relative; overflow: hidden\">\n * Some stuff\n * <ixfx-bottom-drawer label=\"Inspector\" open>Drawer contents</ixfx-bottom-drawer>\n * </div>\n * ```\n *\n * The element stretches to fill the nearest positioned ancestor and clips the\n * drawer as it slides; it is `pointer-events: none` except over the drawer\n * itself, so sibling content underneath stays interactive. The drawer can be\n * resized from its top edge.\n *\n * Slots\n * (default) – drawer body content\n * `toolbar` – header toolbar items, forwarded into the `ixfx-titlebar` toolbar\n *\n * Properties\n * `open` – whether the drawer is visible (default: false)\n * `height` – drawer height in px (default: 320)\n * `min-height` – minimum height before fade-out (default: 160)\n * `dismiss-threshold` – drag below this height closes the drawer (default: 96)\n * `max-height-ratio` – max height as a fraction of host height (default: 0.85)\n * `label` – header title and accessible label (default: `Drawer`)\n * `icon-name` – header icon (default: ``)\n * `closable` – show the header close button (default: true)\n * `collapsible` – show the expand/collapse caret that toggles `open` (default: true)\n * `maintain-handle` – keep a drag handle docked to the bottom when\n * collapsed so users can drag up to reopen. Dragging the drawer down\n * gradually morphs it into the handle (default: false)\n * `name` – command namespace. When set, `expand`/`collapse`/`toggle`\n * commands are registered as `<name>.expand` etc. (default: `` = no commands)\n * `registry` – `@clinth/ui-commands` registry carrying this drawer's\n * commands. Created automatically; assign a shared registry to trigger\n * named drawers globally (default: owned registry)\n *\n * The header is an `ixfx-titlebar`. Theme variables (e.g. `--surface-4`,\n * `--accent`) set on the drawer inherit into the header, and `toolbar`-slotted\n * content stays in the consumer's light DOM so it can be styled directly.\n *\n * Commands (require `name`; see {@link bottomDrawerCommandId})\n * `<name>.expand` – open the drawer (`show()`)\n * `<name>.collapse` – close the drawer (`close()`, fires `drawer-close`)\n * `<name>.toggle` – open if closed, close if open\n *\n * ```typescript\n * drawer.registry?.invoke('inspector.expand');\n * ```\n *\n * Events\n * `drawer-close` – CustomEvent<void>, bubbles + composed\n * `drawer-resize` – CustomEvent { detail: { height: number } }, bubbles + composed\n *\n * CSS variables\n * `--bottom-drawer-background` – drawer fill\n * `--bottom-drawer-border` – drawer border\n * `--bottom-drawer-radius` – top corner radius\n * `--bottom-drawer-blur` – backdrop blur amount\n * `--bottom-drawer-shadow` – drawer drop shadow\n * `--ixfx-handle-*` – resize-grip look (shared handle primitive; see\n * docs/infra-handle.md)\n * `--bottom-drawer-collapsed-width` – width of the floating pill shown\n * when collapsed with `maintain-handle` (default: 96px)\n * `--bottom-drawer-title-background` – header fill (default: transparent,\n * so the header shares the drawer's translucency)\n */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TitlebarCloseEvent, TitlebarToggleEvent } from '../titlebar/titlebar.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../titlebar/titlebar.js';\n\nexport type BottomDrawerResizeDetail = {\n readonly height: number;\n};\n\nexport type BottomDrawerResizeEvent = CustomEvent<BottomDrawerResizeDetail>;\nexport type BottomDrawerCloseEvent = CustomEvent<void>;\n\nexport interface BottomDrawerElementEventMap {\n 'drawer-close': BottomDrawerCloseEvent;\n 'drawer-resize': BottomDrawerResizeEvent;\n}\n\n/** Commands a named drawer registers, namespaced as `<name>.<command>`. */\nexport type BottomDrawerCommand = `expand` | `collapse` | `toggle`;\n\n/** Builds the command id for a named drawer's command, e.g. `inspector.expand`. */\nexport function bottomDrawerCommandId(name: string, command: BottomDrawerCommand): string {\n return `${name.trim()}.${command}`;\n}\n\nfunction clampRange(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\n@customElement(`ixfx-bottom-drawer`)\nexport class BottomDrawerElement extends LitElement {\n static override styles = [themeFallbacks, handleStyles, css`\n :host {\n --bottom-drawer-background: color-mix(in srgb, var(--surface-2) 84%, transparent);\n --bottom-drawer-border: 1px solid color-mix(in srgb, var(--surface-2-text) 14%, transparent);\n --bottom-drawer-radius: var(--radius-l);\n --bottom-drawer-blur: 18px;\n --bottom-drawer-shadow: var(--shadow-l);\n --bottom-drawer-collapsed-width: 96px;\n\n display: block;\n position: absolute;\n inset: 0;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n pointer-events: none;\n }\n .drawer {\n --m: 0;\n position: absolute;\n z-index: 2;\n pointer-events: auto;\n right: calc(var(--m) * (50% - var(--bottom-drawer-collapsed-width) / 2));\n bottom: 0;\n left: calc(var(--m) * (50% - var(--bottom-drawer-collapsed-width) / 2));\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n height: var(--bottom-drawer-height);\n max-height: 100%;\n min-height: 0;\n color: var(--surface-2-text);\n background: var(--bottom-drawer-background);\n border: var(--bottom-drawer-border);\n border-bottom: 0;\n border-radius: var(--bottom-drawer-radius) var(--bottom-drawer-radius) 0 0;\n box-shadow: var(--bottom-drawer-shadow);\n backdrop-filter: blur(var(--bottom-drawer-blur)) saturate(1.15);\n -webkit-backdrop-filter: blur(var(--bottom-drawer-blur)) saturate(1.15);\n opacity: 0;\n transform: translateY(100%);\n visibility: hidden;\n transition:\n transform var(--transition),\n opacity var(--transition),\n left var(--transition),\n right var(--transition),\n height var(--transition),\n visibility 0s linear 0.16s;\n will-change: transform, opacity;\n }\n :host([open]) .drawer {\n opacity: var(--bottom-drawer-opacity, 1);\n transform: translateY(0);\n visibility: visible;\n transition:\n transform var(--transition),\n opacity var(--transition),\n left var(--transition),\n right var(--transition),\n height var(--transition);\n }\n :host([resizing]) {\n cursor: ns-resize;\n user-select: none;\n }\n :host([resizing]) .drawer {\n transition: none;\n }\n .resize-edge {\n position: absolute;\n z-index: 1;\n top: -5px;\n right: 0;\n left: 0;\n height: 11px;\n cursor: ns-resize;\n touch-action: none;\n outline: none;\n }\n .resize-edge .ixfx-handle {\n position: absolute;\n top: 7px;\n left: 50%;\n transform: translateX(-50%);\n --ixfx-handle-length: 44px;\n --ixfx-handle-thickness: 3px;\n --ixfx-handle-radius: 999px;\n }\n /* Inner content fades as the drawer morphs into its collapsed tab. */\n ixfx-titlebar,\n .body {\n opacity: calc(1 - var(--m, 0));\n transition: opacity var(--transition);\n }\n :host([resizing]) ixfx-titlebar,\n :host([resizing]) .body {\n transition: none;\n }\n /* Collapsed tab: docked to the bottom edge, narrowed to handle width. */\n :host([maintain-handle]:not([open])) .drawer {\n --m: 1;\n height: 20px;\n opacity: 1;\n transform: translateY(0);\n visibility: visible;\n transition:\n transform var(--transition),\n opacity var(--transition),\n left var(--transition),\n right var(--transition),\n height var(--transition);\n }\n :host([maintain-handle]:not([open])) ixfx-titlebar,\n :host([maintain-handle]:not([open])) .body {\n display: none;\n }\n :host([maintain-handle]:not([open])) .resize-edge {\n top: 0;\n height: 100%;\n }\n :host([maintain-handle]:not([open])) .resize-edge .ixfx-handle {\n top: 50%;\n transform: translate(-50%, -50%);\n }\n ixfx-titlebar {\n flex: none;\n --titlebar-background: var(--bottom-drawer-title-background, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--surface-2-text) 10%, transparent);\n }\n .body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n overscroll-behavior: contain;\n }\n .body ::slotted(*) {\n box-sizing: border-box;\n }\n @media (prefers-reduced-motion: reduce) {\n .drawer,\n ixfx-titlebar,\n .body {\n transition-duration: 0s;\n }\n }\n `];\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @property({ type: Number })\n height = 320;\n\n @property({ type: Number, attribute: `min-height` })\n minHeight = 160;\n\n @property({ type: Number, attribute: `dismiss-threshold` })\n dismissThreshold = 96;\n\n @property({ type: Number, attribute: `max-height-ratio` })\n maxHeightRatio = 0.85;\n\n @property({ type: String })\n label = `Drawer`;\n\n @property({ type: String, attribute: `icon-name` })\n iconName = ``;\n\n @property({ type: Boolean })\n closable = true;\n\n @property({ type: Boolean })\n collapsible = true;\n\n @property({ type: Boolean, attribute: `maintain-handle`, reflect: true })\n maintainHandle = false;\n\n @property({ type: String })\n name = ``;\n\n @property({ attribute: false })\n registry: CommandRegistry<unknown> | undefined;\n\n @state() private _dragHeight: number | undefined;\n\n #dragStartY = 0;\n #dragStartHeight = 0;\n #collapsedDragging = false;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #commandTarget: CommandRegistry<unknown> | undefined;\n #commandName = ``;\n #commandIds: string[] = [];\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#syncCommands();\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#teardownCommands();\n if (this.#ownedRegistry !== undefined) {\n if (this.registry === this.#ownedRegistry)\n this.registry = undefined;\n this.#ownedRegistry = undefined;\n }\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n if (changed.has(`name`) || changed.has(`registry`))\n this.#syncCommands();\n }\n\n show(): void {\n this.open = true;\n }\n\n close(): void {\n if (!this.open)\n return;\n this.open = false;\n this.dispatchEvent(new CustomEvent<void>(`drawer-close`, { bubbles: true, composed: true }));\n }\n\n toggle(): void {\n if (this.open)\n this.close();\n else\n this.show();\n }\n\n #syncCommands(): void {\n const name = this.name.trim();\n const target = this.registry ?? this.#ownedRegistry;\n if (name !== `` && this.isConnected && target !== undefined\n && this.#commandTarget === target && this.#commandName === name) {\n return;\n }\n this.#teardownCommands();\n if (name === `` || !this.isConnected)\n return;\n const resolved = this.registry ?? (this.#ownedRegistry ??= createCommandRegistry());\n if (this.#ownedRegistry !== undefined && resolved !== this.#ownedRegistry)\n this.#ownedRegistry = undefined;\n if (this.registry === undefined)\n this.registry = resolved;\n const registered: string[] = [];\n const commands: Array<{ command: BottomDrawerCommand; label: string; description: string; execute: () => void }> = [\n { command: `expand`, label: `Expand ${this.label}`, description: `Open the ${this.label} drawer`, execute: () => this.show() },\n { command: `collapse`, label: `Collapse ${this.label}`, description: `Close the ${this.label} drawer`, execute: () => this.close() },\n { command: `toggle`, label: `Toggle ${this.label}`, description: `Open the ${this.label} drawer if closed, close it if open`, execute: () => this.toggle() },\n ];\n for (const { command, label, description, execute } of commands) {\n const id = bottomDrawerCommandId(name, command);\n if (resolved.has(id))\n continue;\n resolved.register({ id, label, description, execute });\n registered.push(id);\n }\n this.#commandTarget = resolved;\n this.#commandName = name;\n this.#commandIds = registered;\n }\n\n #teardownCommands(): void {\n if (this.#commandTarget !== undefined) {\n for (const id of this.#commandIds)\n this.#commandTarget.unregister(id);\n this.#commandTarget = undefined;\n this.#commandName = ``;\n this.#commandIds = [];\n }\n }\n\n private _onTitlebarToggle(event: TitlebarToggleEvent): void {\n event.stopPropagation();\n if (event.detail.collapsed)\n this.close();\n else\n this.open = true;\n }\n\n private _onTitlebarClose(event: TitlebarCloseEvent): void {\n event.stopPropagation();\n this.close();\n }\n\n protected override render(): ReturnType<typeof html> {\n const raw = this.#displayHeight();\n const max = this.#maxHeight();\n const morph = this.#morphProgress(raw);\n const height = this.open ? raw * (1 - morph) + 20 * morph : 20;\n const opacity = this.maintainHandle && this.open ? 1 : this.#dragOpacity(raw);\n return html`\n <section\n class=\"drawer\"\n style=${`--bottom-drawer-height: ${height}px; --bottom-drawer-opacity: ${opacity}; --m: ${morph}`}\n role=\"region\"\n aria-label=${this.label}\n @keydown=${this.#onDrawerKeyDown}\n >\n <div\n class=\"resize-edge\"\n role=\"separator\"\n tabindex=\"0\"\n aria-label=${`${this.open ? `Resize` : `Expand`} ${this.label}`}\n aria-orientation=\"horizontal\"\n aria-valuemin=${this.minHeight}\n aria-valuemax=${max}\n aria-valuenow=${Math.round(raw)}\n @pointerdown=${this.#onResizeStart}\n @keydown=${this.#onResizeKeyDown}\n ><span class=\"ixfx-handle\" data-handle=\"dimpled\" data-shape=\"horizontal\" part=\"handle\"></span></div>\n <ixfx-titlebar\n .title=${this.label}\n .iconName=${this.iconName}\n .closable=${this.maintainHandle ? false : this.closable}\n .collapsible=${this.maintainHandle ? this.collapsible : false}\n .collapsed=${!this.open}\n ?inert=${!this.open}\n @toggle=${this._onTitlebarToggle}\n @close=${this._onTitlebarClose}\n >\n <slot name=\"toolbar\" slot=\"toolbar\"></slot>\n </ixfx-titlebar>\n <div class=\"body\" ?inert=${!this.open}><slot></slot></div>\n </section>\n `;\n }\n\n #maxHeight(): number {\n const availableHeight = this.clientHeight || this.height;\n return Math.max(this.minHeight, availableHeight * clampRange(this.maxHeightRatio, 0, 1));\n }\n\n #displayHeight(): number {\n return clampRange(this._dragHeight ?? this.height, 0, this.#maxHeight());\n }\n\n #dragOpacity(height: number): number {\n if (this._dragHeight === undefined || height >= this.minHeight)\n return 1;\n const fadeRange = this.minHeight - this.dismissThreshold;\n if (fadeRange <= 0)\n return height >= this.dismissThreshold ? 1 : 0;\n return clampRange((height - this.dismissThreshold) / fadeRange, 0, 1);\n }\n\n #morphProgress(raw: number): number {\n if (!this.open)\n return this.maintainHandle ? 1 : 0;\n if (this._dragHeight === undefined || !this.maintainHandle)\n return 0;\n const range = this.minHeight - this.dismissThreshold;\n if (range <= 0)\n return raw < this.dismissThreshold ? 1 : 0;\n return clampRange((this.minHeight - raw) / range, 0, 1);\n }\n\n #setHeight(height: number): void {\n this.height = clampRange(height, this.minHeight, this.#maxHeight());\n this.dispatchEvent(new CustomEvent<BottomDrawerResizeDetail>(`drawer-resize`, {\n detail: { height: this.height },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onResizeStart = (event: PointerEvent): void => {\n if (event.button !== 0)\n return;\n event.preventDefault();\n const edge = event.currentTarget as HTMLElement;\n edge.setPointerCapture(event.pointerId);\n if (!this.open) {\n this.#collapsedDragging = false;\n this.#dragStartY = event.clientY;\n this.#dragStartHeight = this.dismissThreshold;\n edge.addEventListener(`pointermove`, this.#onTabPointerMove);\n edge.addEventListener(`pointerup`, this.#onTabPointerUp, { once: true });\n edge.addEventListener(`pointercancel`, this.#onTabPointerUp, { once: true });\n return;\n }\n this.#dragStartY = event.clientY;\n this.#dragStartHeight = this.#displayHeight();\n this._dragHeight = this.#dragStartHeight;\n this.toggleAttribute(`resizing`, true);\n edge.addEventListener(`pointermove`, this.#onResizeMove);\n edge.addEventListener(`pointerup`, this.#onResizeEnd, { once: true });\n edge.addEventListener(`pointercancel`, this.#onResizeEnd, { once: true });\n };\n\n #onResizeMove = (event: PointerEvent): void => {\n this._dragHeight = clampRange(this.#dragStartHeight + this.#dragStartY - event.clientY, 0, this.#maxHeight());\n };\n\n #onResizeEnd = (event: PointerEvent): void => {\n const edge = event.currentTarget as HTMLElement;\n edge.removeEventListener(`pointermove`, this.#onResizeMove);\n edge.removeEventListener(`pointerup`, this.#onResizeEnd);\n edge.removeEventListener(`pointercancel`, this.#onResizeEnd);\n if (edge.hasPointerCapture(event.pointerId))\n edge.releasePointerCapture(event.pointerId);\n this.toggleAttribute(`resizing`, false);\n const height = this._dragHeight ?? this.height;\n this._dragHeight = undefined;\n if (height < this.dismissThreshold) {\n this.close();\n return;\n }\n this.#setHeight(height);\n };\n\n #onResizeKeyDown = (event: KeyboardEvent): void => {\n if (!this.open) {\n if (event.key === `ArrowUp` || event.key === `Enter` || event.key === ` ` || event.key === `Home` || event.key === `End`) {\n event.preventDefault();\n this.show();\n }\n return;\n }\n const delta = event.shiftKey ? 64 : 16;\n if (event.key === `ArrowUp`) {\n event.preventDefault();\n this.#setHeight(this.height + delta);\n } else if (event.key === `ArrowDown`) {\n event.preventDefault();\n if (this.height - delta < this.dismissThreshold)\n this.close();\n else\n this.#setHeight(this.height - delta);\n } else if (event.key === `Home`) {\n event.preventDefault();\n this.#setHeight(this.minHeight);\n } else if (event.key === `End`) {\n event.preventDefault();\n this.#setHeight(this.#maxHeight());\n }\n };\n\n #onTabPointerMove = (event: PointerEvent): void => {\n const delta = this.#dragStartY - event.clientY;\n if (!this.#collapsedDragging) {\n if (delta < 4)\n return;\n this.#collapsedDragging = true;\n this.show();\n this.toggleAttribute(`resizing`, true);\n }\n this._dragHeight = clampRange(this.#dragStartHeight + this.#dragStartY - event.clientY, 0, this.#maxHeight());\n };\n\n #onTabPointerUp = (event: PointerEvent): void => {\n const target = event.currentTarget as HTMLElement;\n target.removeEventListener(`pointermove`, this.#onTabPointerMove);\n target.removeEventListener(`pointerup`, this.#onTabPointerUp);\n target.removeEventListener(`pointercancel`, this.#onTabPointerUp);\n if (target.hasPointerCapture(event.pointerId))\n target.releasePointerCapture(event.pointerId);\n if (!this.#collapsedDragging) {\n this.show();\n return;\n }\n this.#collapsedDragging = false;\n this.toggleAttribute(`resizing`, false);\n const height = this._dragHeight ?? this.height;\n this._dragHeight = undefined;\n if (height < this.dismissThreshold) {\n this.close();\n return;\n }\n this.#setHeight(height);\n };\n\n #onDrawerKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== `Escape`)\n return;\n event.preventDefault();\n event.stopPropagation();\n this.close();\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-bottom-drawer': BottomDrawerElement;\n }\n}\n\nexport interface BottomDrawerElement {\n addEventListener: (<K extends keyof BottomDrawerElementEventMap>(\n type: K,\n listener: (this: BottomDrawerElement, event: BottomDrawerElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import type { PropertyValues } from 'lit';\nimport { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../icons/icon.js';\n\nexport type RadioGroupMode = `compact` | `max`;\n\nexport type RadioItem = Readonly<{\n value: string;\n label: string;\n disabled?: boolean;\n iconName?: string;\n iconNameOff?: string;\n}>;\n\n@customElement(`ixfx-radio-group`)\nexport class RadioGroup extends LitElement {\n @property({ type: String }) value = ``;\n @property({ type: String }) orientation: `horizontal` | `vertical` = `horizontal`;\n @property({ type: Array }) items: RadioItem[] = [];\n @property({ type: String }) name = ``;\n @property({ type: String }) mode: RadioGroupMode = `compact`;\n @property({ type: Boolean }) checked = false;\n @property({ type: String, attribute: `value-off` }) valueOff = ``;\n @property({ type: String, attribute: `icon-name` }) iconName = ``;\n @property({ type: String, attribute: `icon-name-off` }) iconNameOff = ``;\n @property({ type: Boolean, attribute: `hide-labels` }) hideLabels = false;\n\n @state() private _computedItems: RadioItem[] = [];\n @state() private _icons: Map<string, string> = new Map();\n @query(`slot`) private _slot?: HTMLSlotElement;\n\n private get _isSingleToggle(): boolean {\n return this._computedItems.length === 0 && Boolean(this.textContent?.trim());\n }\n\n private get _singleToggleIconName(): string | null {\n if (!this.iconName && !this.iconNameOff)\n return null;\n return this.checked ? this.iconName : (this.iconNameOff || this.iconName);\n }\n\n protected override firstUpdated(): void {\n this.#updateComputedItems();\n }\n\n protected override updated(changedProperties: PropertyValues): void {\n if (changedProperties.has(`checked`)) {\n const input = this.shadowRoot?.querySelector(`.radio-toggle-input`) as HTMLInputElement | undefined;\n if (input && input.checked !== this.checked) {\n input.checked = this.checked;\n const newValue = this.checked\n ? (this.value || `on`)\n : (this.valueOff || undefined);\n\n this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n detail: { checked: this.checked, value: newValue },\n bubbles: true,\n composed: true,\n }));\n }\n }\n\n if (changedProperties.has(`value`) && !this._isSingleToggle) {\n const inputs = this.shadowRoot?.querySelectorAll(`.radio-input`) as NodeListOf<HTMLInputElement>;\n if (inputs) {\n for (const input of inputs) {\n if (input.checked !== (input.value === this.value)) {\n input.checked = input.value === this.value;\n }\n }\n }\n }\n }\n\n #updateComputedItems(): void {\n const options = this.querySelectorAll(`option`);\n const icons = new Map<string, string>();\n\n if (options.length > 0) {\n this._computedItems = Array.from(options, (el) => {\n const tempDiv = document.createElement(`div`);\n tempDiv.innerHTML = el.innerHTML;\n const iconEl = tempDiv.querySelector(`svg`);\n if (iconEl) {\n icons.set(el.getAttribute(`value`) || ``, iconEl.outerHTML);\n }\n return {\n value: el.getAttribute(`value`) || ``,\n label: el.textContent?.trim() || ``,\n disabled: el.hasAttribute(`disabled`),\n iconName: el.getAttribute(`icon-name`) || undefined,\n iconNameOff: el.getAttribute(`icon-name-off`) || undefined,\n };\n });\n this._icons = icons;\n } else {\n this._computedItems = [...this.items];\n }\n }\n\n // #handleItemClick(item: RadioItem): void {\n // if (item.disabled || item.value === this.value)\n // return;\n\n // this.value = item.value;\n // this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n // detail: { checked: true, value: item.value },\n // bubbles: true,\n // composed: true,\n // }));\n // }\n\n #handleRadioChange(e: Event): void {\n e.stopImmediatePropagation();\n const input = e.target as HTMLInputElement;\n this.value = input.value;\n this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n detail: { checked: true, value: input.value },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleToggleChange(e: Event): void {\n e.stopImmediatePropagation();\n const input = e.target as HTMLInputElement;\n this.checked = input.checked;\n const newValue = this.checked\n ? (this.value || `on`)\n : (this.valueOff || undefined);\n\n this.dispatchEvent(new CustomEvent<RadioGroupChangeDetail>(`change`, {\n detail: { checked: this.checked, value: newValue },\n bubbles: true,\n composed: true,\n }));\n }\n\n #renderIcon(item: RadioItem): ReturnType<typeof html> | null {\n const isSelected = item.value === this.value;\n const iconName = isSelected ? (item.iconName || null) : (item.iconNameOff || item.iconName || null);\n if (iconName) {\n return html`<ixfx-icon class=\"radio-icon\" name=\"${iconName}\"></ixfx-icon>`;\n }\n const iconHtml = this._icons.get(item.value);\n if (!iconHtml)\n return null;\n return html`<span class=\"radio-icon\">${unsafeHTML(iconHtml)}</span>`;\n }\n\n protected override render(): unknown {\n if (this._isSingleToggle) {\n const iconName = this._singleToggleIconName;\n const showIcon = iconName || this.hideLabels;\n const iconPart = showIcon\n ? html`<ixfx-icon class=\"radio-icon\" name=\"${iconName || `check`}\"></ixfx-icon>`\n : null;\n const labelPart = !this.hideLabels\n ? html`<span class=\"radio-label\" data-text=\"${this.textContent?.trim()}\">${this.textContent?.trim()}</span>`\n : null;\n return html`\n <label class=\"radio-item ${this.checked ? `selected` : ``}\">\n <input\n type=\"checkbox\"\n class=\"radio-toggle-input\"\n ?checked=${this.checked}\n @change=${this.#handleToggleChange}\n />\n ${iconPart}\n ${labelPart}\n </label>\n `;\n }\n\n return html`\n <slot @slotchange=${this.#updateComputedItems} style=\"display: none;\"></slot>\n <div class=\"radio-group ${this.orientation} ${this.mode}\" role=\"radiogroup\" aria-label=${this.name}>\n ${this._computedItems.map((item) => {\n const isSelected = item.value === this.value;\n const iconName = isSelected\n ? (item.iconName || null)\n : (item.iconNameOff || item.iconName || null);\n const showIcon = iconName || this.hideLabels;\n const iconPart = showIcon\n ? html`<ixfx-icon class=\"radio-icon\" name=\"${iconName || `check`}\"></ixfx-icon>`\n : null;\n const labelPart = !this.hideLabels\n ? html`<span class=\"radio-label\" data-text=\"${item.label}\">${item.label}</span>`\n : null;\n return html`\n <label class=\"radio-item ${item.value === this.value ? `selected` : ``}\" ?disabled=${item.disabled}>\n <input\n type=\"radio\"\n class=\"radio-input\"\n name=${this.name}\n value=${item.value}\n ?disabled=${item.disabled}\n ?checked=${item.value === this.value}\n @change=${this.#handleRadioChange}\n />\n ${iconPart}\n ${labelPart}\n </label>\n `;\n })}\n </div>\n `;\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-flex;\n min-width: min-content;\n box-sizing: border-box;\n /* Default to looking like a cohesive control group */\n background: var(--surface-4, transparent);\n background: oklch(from var(--surface-4) l calc(c*0.2) h / 0.4);\n\n border: var(--border, none);\n border-radius: var(--radius-xl, 8px);\n }\n\n * {\n box-sizing: border-box;\n }\n\n .radio-toggle-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n }\n\n .radio-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n pointer-events: none;\n }\n\n .radio-group {\n display: flex;\n width: 100%;\n height: 100%;\n gap: var(--item-spacing, 0);\n overflow: hidden;\n border-radius: inherit;\n justify-content: center;\n }\n\n .radio-group.horizontal {\n flex-direction: row;\n }\n\n .radio-group.vertical {\n flex-direction: column;\n }\n\n .radio-group.max.horizontal .radio-item {\n flex: 1;\n justify-content: center;\n }\n\n .radio-group.max.vertical .radio-item {\n flex: 1;\n justify-content: flex-start;\n }\n\n .radio-item {\n display: inline-flex;\n align-items: center;\n justify-content: flex-start;\n gap: var(--icon-label-spacing, 0.5rem);\n padding: var(--space-m, 0.5rem) var(--space-l, 1rem);\n border: none;\n background: transparent;\n color: var(--color-fg-fade, var(--surface-muted-text));\n font-family: inherit;\n font-size: var(--text-m, inherit);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n cursor: pointer;\n transition: all var(--transition, 0.1s) ease;\n user-select: none;\n white-space: nowrap;\n }\n\n .radio-item:hover:not([disabled]) {\n opacity: 0.9;\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n border-color: var(--accent, #666);\n box-shadow: \n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent), \n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n .radio-item.selected {\n font-weight: bold;\n color: var(--color-fg-accent, var(--surface-2-text));\n background: var(--surface-5, rgba(255,255,255,0.1));\n }\n\n .radio-item[disabled] {\n cursor: not-allowed;\n }\n\n .radio-item:has(input:focus-visible) {\n outline: 2px solid var(--accent, #666);\n outline-offset: -2px;\n }\n\n .radio-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: var(--icon-size, 1.2rem);\n height: var(--icon-size, 1.2rem);\n flex-shrink: 0;\n }\n\n .radio-icon svg {\n width: 100%;\n height: 100%;\n }\n\n .radio-label {\n position: relative;\n display: inline-flex;\n flex-shrink: 0;\n flex-direction: column;\n align-items: center;\n justify-content: space-between;\n }\n\n .radio-label::after {\n content: attr(data-text);\n content: attr(data-text)/\"\";\n font-weight: bold;\n height: 0;\n visibility: hidden;\n overflow: hidden;\n user-select: none;\n pointer-events: none;\n @media speech {\n display: none;\n }\n }\n\n .radio-group.vertical .radio-item {\n width: 100%;\n }\n\n .radio-group.horizontal .radio-item {\n flex-shrink: 0;\n }\n\n .radio-group.compact .radio-label {\n display: var(--show-labels, inline-flex);\n }\n\n .radio-group.compact.horizontal .radio-item {\n padding: var(--compact-padding, 0.5rem);\n }\n `];\n}\n\nexport type RadioGroupChangeDetail = {\n readonly checked: boolean;\n readonly value: string | undefined;\n};\n\nexport type RadioGroupChangeEvent = CustomEvent<RadioGroupChangeDetail>;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-radio-group': RadioGroup;\n }\n}\n","import type { ReactiveController, ReactiveControllerHost } from 'lit';\nimport type { TickledController, TickledItem } from './tickled-controller.js';\n\nexport type TreeKeyboardNavItemId = string;\n\nexport type TreeKeyboardNavCallbacks = {\n getItems: () => ReadonlyArray<TickledItem<TreeKeyboardNavItemId>>;\n onExpand: (id: TreeKeyboardNavItemId) => void;\n onCollapse: (id: TreeKeyboardNavItemId) => void;\n onActivate: (id: TreeKeyboardNavItemId) => void;\n onSelect?: (id: TreeKeyboardNavItemId) => void;\n onEscape?: () => void;\n isLeaf: (id: TreeKeyboardNavItemId) => boolean;\n isExpanded: (id: TreeKeyboardNavItemId) => boolean;\n getParentId?: (id: TreeKeyboardNavItemId) => TreeKeyboardNavItemId | undefined;\n};\n\nexport type TreeKeyboardNavControllerConfig = {\n callbacks: TreeKeyboardNavCallbacks;\n disableKeyboardNavigation?: () => boolean;\n};\n\nexport class TreeKeyboardNavController implements ReactiveController {\n private host: ReactiveControllerHost;\n private tickled: TickledController<TreeKeyboardNavItemId>;\n private callbacks: TreeKeyboardNavCallbacks;\n private disableKeyboardNavigation: () => boolean;\n\n constructor(host: ReactiveControllerHost, tickled: TickledController<TreeKeyboardNavItemId>, config: TreeKeyboardNavControllerConfig) {\n this.host = host;\n this.tickled = tickled;\n this.callbacks = config.callbacks;\n this.disableKeyboardNavigation = config.disableKeyboardNavigation ?? (() => false);\n host.addController(this);\n }\n\n hostConnected(): void {}\n\n hostDisconnected(): void {}\n\n handleKeyDown = (event: KeyboardEvent): void => {\n if (this.disableKeyboardNavigation()) {\n return;\n }\n\n const { key } = event;\n\n if ([`ArrowDown`, `ArrowUp`, `ArrowLeft`, `ArrowRight`, `Enter`, `Escape`].includes(key)) {\n this.tickled.setInputMode(`keyboard`);\n }\n\n switch (key) {\n case `ArrowDown`:\n event.preventDefault();\n this.#handleArrowDown();\n break;\n case `ArrowUp`:\n event.preventDefault();\n this.#handleArrowUp();\n break;\n case `ArrowRight`:\n event.preventDefault();\n this.#handleArrowRight();\n break;\n case `ArrowLeft`:\n event.preventDefault();\n this.#handleArrowLeft();\n break;\n case `Enter`:\n event.preventDefault();\n this.#handleEnter();\n break;\n case `Escape`:\n event.preventDefault();\n this.callbacks.onEscape?.();\n break;\n }\n };\n\n #handleArrowDown(): void {\n this.tickled.handleKeyboardNavigation(`next`);\n }\n\n #handleArrowUp(): void {\n this.tickled.handleKeyboardNavigation(`previous`);\n }\n\n #handleArrowRight(): void {\n const currentId = this.tickled.tickledId;\n if (!currentId)\n return;\n\n if (this.callbacks.isLeaf(currentId)) {\n return;\n }\n\n if (!this.callbacks.isExpanded(currentId)) {\n this.callbacks.onExpand(currentId);\n this.tickled.setTickled(currentId);\n } else {\n const items = this.callbacks.getItems();\n const currentIdx = items.findIndex(item => item.id === currentId);\n if (currentIdx !== -1 && currentIdx + 1 < items.length) {\n const nextItem = items[currentIdx + 1];\n if (nextItem.enabled !== false) {\n this.tickled.setTickled(nextItem.id);\n }\n }\n }\n }\n\n #handleArrowLeft(): void {\n const currentId = this.tickled.tickledId;\n if (!currentId)\n return;\n\n if (this.callbacks.isLeaf(currentId)) {\n const parentId = this.callbacks.getParentId?.(currentId);\n if (parentId) {\n this.tickled.setTickled(parentId);\n if (this.callbacks.isExpanded(parentId)) {\n this.callbacks.onCollapse(parentId);\n }\n }\n } else if (this.callbacks.isExpanded(currentId)) {\n this.callbacks.onCollapse(currentId);\n } else {\n const parentId = this.callbacks.getParentId?.(currentId);\n if (parentId) {\n this.tickled.setTickled(parentId);\n }\n }\n }\n\n #handleEnter(): void {\n const currentId = this.tickled.tickledId;\n if (!currentId)\n return;\n\n this.callbacks.onActivate(currentId);\n this.callbacks.onSelect?.(currentId);\n }\n}","import type { CommandRegistry, KeyboardManager } from '@clinth/ui-commands';\nimport type { MenuTrigger } from '../menu/menu-trigger.js';\nimport type { ItemsProvider, PopupItem, SwitcherItem } from './types.js';\nimport { css, html, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { buttonStyles } from './button-styles.js';\nimport { ButtonElement } from './button.js';\nimport '../menu/menu-trigger.js';\nimport '../menu/menu-container.js';\nimport '../menu/menu-item.js';\nimport '../icons/icon.js';\n\nexport type SplitButtonMode = `default` | `switcher`;\n\n@customElement(`ixfx-split-button`)\nexport class SplitButton extends ButtonElement {\n @property({ attribute: false }) registry?: CommandRegistry<unknown>;\n @property({ attribute: false }) keyboardManager?: KeyboardManager;\n @property({ type: String }) mode: SplitButtonMode = `default`;\n @property({ type: String, attribute: `default-value` }) defaultValue = ``;\n /** When set, called each time the popup is opened; its return value replaces declarative items. */\n @property({ attribute: false }) itemsProvider?: ItemsProvider;\n /** Directly set popup items. Ignored when itemsProvider is also set. */\n @property({ attribute: false }) items?: PopupItem[];\n\n @query(`ixfx-menu-trigger`) private _menuTrigger!: MenuTrigger;\n\n @state() private _selectedCommand = ``;\n @state() private _selectedLabel = ``;\n @state() private _selectedIcon = ``;\n @state() private _switcherItems: SwitcherItem[] = [];\n @state() private _dynamicItems: PopupItem[] = [];\n @state() private _loadingItems = false;\n @state() private _menuHasItems = false;\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._menuTrigger?.removeEventListener(`menu-command`, this._handleSwitcherMenuCommand as EventListener);\n }\n\n override firstUpdated(): void {\n this.updateComplete.then(() => {\n this._menuTrigger?.addEventListener(`menu-command`, this._handleSwitcherMenuCommand as EventListener);\n });\n }\n\n override updated(changedProperties: Map<string, unknown>): void {\n super.updated(changedProperties);\n if ((changedProperties.has(`items`) || changedProperties.has(`mode`)) && this.items && !this.itemsProvider) {\n this._applyItems(this.items);\n }\n }\n\n // ── Programmatic API ───────────────────────────────────────────────────\n\n private _applyItems(items: PopupItem[]): void {\n if (this.mode === `switcher`) {\n this._applySwitcherItems(items.map(i => ({ command: i.command, label: i.label, icon: i.icon ?? `` })));\n } else {\n this._dynamicItems = [...items];\n this._menuHasItems = items.length > 0;\n }\n }\n\n /** In switcher mode, programmatically select the active command. Returns false if not found. */\n selectCommand(command: string): boolean {\n const item = this._switcherItems.find(i => i.command === command);\n if (!item)\n return false;\n this._selectedCommand = item.command;\n this._selectedLabel = item.label;\n this._selectedIcon = item.icon;\n return true;\n }\n\n /** Invokes the primary button action as if clicked by the user. */\n invoke(): boolean {\n if (this.disabled)\n return false;\n const primaryBtn = this.shadowRoot?.querySelector(`.split button.primary`);\n if (!primaryBtn)\n return false;\n if (this.mode === `switcher` && this._selectedCommand) {\n this.dispatchEvent(new CustomEvent(`menu-command`, {\n detail: { command: this._selectedCommand },\n bubbles: true,\n composed: true,\n }));\n return true;\n }\n primaryBtn.dispatchEvent(new MouseEvent(`click`, { bubbles: true }));\n return true;\n }\n\n // ── Caret state ────────────────────────────────────────────────────────\n\n /** True when there is (or will be) popup content. Used to dim the caret visually. */\n private get _caretHasContent(): boolean {\n if (this.itemsProvider)\n return true;\n if (this.items && this.items.length > 0)\n return true;\n if (this.mode === `switcher`)\n return this._switcherItems.length > 1;\n return this._menuHasItems;\n }\n\n // ── Default-mode slot ──────────────────────────────────────────────────\n\n private _onDefaultMenuSlotChange = (e: Event): void => {\n const slot = e.target as HTMLSlotElement;\n this._menuHasItems = slot.assignedElements({ flatten: true }).length > 0;\n };\n\n // ── Switcher helpers ───────────────────────────────────────────────────\n\n private _onSwitcherSlotChange = (e: Event): void => {\n // When itemsProvider is set, declarative items are ignored\n if (this.itemsProvider)\n return;\n const slot = e.target as HTMLSlotElement;\n this._applySwitcherItems(\n slot.assignedElements({ flatten: true })\n .filter(el => el.tagName === `IXFX-MENU-ITEM`)\n .map(el => ({\n command: el.getAttribute(`command`) ?? ``,\n label: el.getAttribute(`label`) ?? el.textContent?.trim() ?? ``,\n icon: el.getAttribute(`icon-name`) ?? ``,\n })),\n );\n };\n\n private _applySwitcherItems(items: SwitcherItem[]): void {\n this._switcherItems = items;\n if (!this._selectedCommand && items.length > 0) {\n const picked = this.defaultValue\n ? (items.find(i => i.command === this.defaultValue) ?? items[0])\n : items[0];\n this._selectedCommand = picked.command;\n this._selectedLabel = picked.label;\n this._selectedIcon = picked.icon;\n }\n }\n\n private _handleSwitcherMenuCommand = (e: CustomEvent): void => {\n if (this.mode !== `switcher`)\n return;\n e.stopPropagation();\n\n const { command } = e.detail;\n const item = this._switcherItems.find(i => i.command === command);\n if (!item)\n return;\n\n this._selectedCommand = item.command;\n this._selectedLabel = item.label;\n this._selectedIcon = item.icon;\n\n // Fire immediately\n this.dispatchEvent(new CustomEvent(`menu-command`, {\n detail: e.detail,\n bubbles: true,\n composed: true,\n }));\n };\n\n private _handleSwitcherPrimaryClick = (): void => {\n if (!this._selectedCommand)\n return;\n this.dispatchEvent(new CustomEvent(`menu-command`, {\n detail: { command: this._selectedCommand },\n bubbles: true,\n composed: true,\n }));\n };\n\n // ── Caret / menu open ──────────────────────────────────────────────────\n\n private _handleCaretClick = async (e: Event): Promise<void> => {\n e.stopPropagation();\n if (this._menuTrigger?.isOpen) {\n this._menuTrigger.closeMenu();\n return;\n }\n\n if (this.itemsProvider) {\n this._loadingItems = true;\n try {\n const result = this.itemsProvider();\n const items = result instanceof Promise ? await result : result;\n\n if (this.mode === `switcher`) {\n this._applySwitcherItems(\n items.map(i => ({ command: i.command, label: i.label, icon: i.icon ?? `` })),\n );\n } else {\n this._dynamicItems = items;\n }\n } finally {\n this._loadingItems = false;\n }\n // Let Lit render the new items before the popup opens\n await this.updateComplete;\n }\n\n this._menuTrigger?.openMenu();\n };\n\n private _handlePrimaryKeyDown = (e: KeyboardEvent): void => {\n if (e.key === `ArrowDown`) {\n e.preventDefault();\n this._menuTrigger?.openMenu();\n }\n };\n\n private _handleCaretKeyDown = (e: KeyboardEvent): void => {\n if (e.key === `ArrowDown`) {\n e.preventDefault();\n this._menuTrigger?.openMenu();\n }\n };\n\n // ── Render ─────────────────────────────────────────────────────────────\n\n protected override render() {\n return this.mode === `switcher`\n ? this._renderSwitcher()\n : this._renderDefault();\n }\n\n private _renderCaret(iconName: string, ariaLabel: string) {\n const empty = !this._caretHasContent;\n return html`\n <button\n slot=\"trigger\"\n class=\"caret\"\n part=\"caret\"\n ?disabled=${this.disabled}\n ?data-empty=${empty}\n aria-haspopup=\"true\"\n aria-label=${ariaLabel}\n @click=${this._handleCaretClick}\n @keydown=${this._handleCaretKeyDown}\n >\n <ixfx-icon name=\"${iconName}\"></ixfx-icon>\n </button>\n `;\n }\n\n private _renderLoadingOrItems(items: PopupItem[]) {\n if (this._loadingItems) {\n return html`<ixfx-menu-item label=\"Loading…\" disabled></ixfx-menu-item>`;\n }\n return items.map(i => html`\n <ixfx-menu-item\n command=${i.command}\n label=${i.label}\n icon-name=${i.icon || nothing}\n ?disabled=${i.disabled ?? false}\n ></ixfx-menu-item>\n `);\n }\n\n private _renderDefault() {\n const label = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\"><slot></slot></span>`;\n\n const menuContent = this.itemsProvider\n ? html`\n <ixfx-menu-container slot=\"menu\">\n ${this._renderLoadingOrItems(this._dynamicItems)}\n </ixfx-menu-container>\n `\n : html`<slot name=\"menu\" slot=\"menu\" @slotchange=${this._onDefaultMenuSlotChange}></slot>`;\n\n return html`\n <div class=\"split\">\n <button\n class=\"primary\"\n part=\"primary\"\n ?disabled=${this.disabled}\n @keydown=${this._handlePrimaryKeyDown}\n >\n ${this._renderIcon()}${label}\n </button>\n <ixfx-menu-trigger .registry=${this.registry} .keyboardManager=${this.keyboardManager}>\n ${this._renderCaret(`chevron-down`, `Open menu`)}\n ${menuContent}\n </ixfx-menu-trigger>\n </div>\n `;\n }\n\n private _renderSwitcher() {\n const primaryIcon = this._selectedIcon\n ? html`<ixfx-icon class=\"button-icon\" name=\"${this._selectedIcon}\"></ixfx-icon>`\n : nothing;\n\n const primaryLabel = this.hideLabel\n ? nothing\n : html`<span class=\"button-label\">${this._selectedLabel}</span>`;\n\n const popupItems = this.itemsProvider\n ? this._renderLoadingOrItems(this._dynamicItems)\n : this._switcherItems\n .filter(i => i.command !== this._selectedCommand)\n .map(i => html`\n <ixfx-menu-item\n command=${i.command}\n label=${i.label}\n icon-name=${i.icon || nothing}\n ></ixfx-menu-item>\n `);\n\n return html`\n <!-- Hidden data-capture slot reads light-DOM items as the data source -->\n <slot name=\"menu\" class=\"switcher-data\" @slotchange=${this._onSwitcherSlotChange}></slot>\n <div class=\"split switcher\">\n <button\n class=\"primary\"\n part=\"primary\"\n ?disabled=${this.disabled}\n @keydown=${this._handlePrimaryKeyDown}\n @click=${this._handleSwitcherPrimaryClick}\n >\n ${primaryIcon}${primaryLabel}\n </button>\n <ixfx-menu-trigger .registry=${this.registry} .keyboardManager=${this.keyboardManager}>\n ${this._renderCaret(`chevron-right`, `Choose action`)}\n <ixfx-menu-container slot=\"menu\">\n ${popupItems}\n </ixfx-menu-container>\n </ixfx-menu-trigger>\n </div>\n `;\n }\n\n // ── Styles ─────────────────────────────────────────────────────────────\n\n static override styles = [\n themeFallbacks,\n prominenceStyles,\n buttonStyles,\n css`\n :host {\n display: inline-flex;\n max-width: 100%;\n min-width: var(--ixfx-split-button-min-width, 0);\n vertical-align: middle;\n }\n\n slot.switcher-data {\n display: none;\n }\n\n .split {\n display: inline-flex;\n width: 100%;\n background: var(--surface-3, #ccc);\n color: var(--surface-3-text, #000);\n border: var(--border, 1px solid #999);\n border-radius: var(--radius-xl, 8px);\n corner-shape: superellipse(1);\n box-shadow:\n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-4) 30%, transparent),\n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 20%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 30%, transparent);\n overflow: hidden;\n transition: background var(--transition, 0.2s), border-color var(--transition, 0.2s);\n }\n\n /* Switcher: accent the caret separator to signal \"this changes the default\" */\n .split.switcher button.caret {\n border-inline-start-color: var(--accent, #666);\n opacity: 0.7;\n }\n\n .split.switcher button.caret:hover:not(:disabled) {\n opacity: 1;\n }\n\n /* Caret is dimmed when there is no popup content */\n button.caret[data-empty] {\n opacity: 0.3;\n pointer-events: none;\n }\n\n .split:has(button:hover:not(:disabled)) {\n border-color: var(--accent, #666);\n box-shadow:\n inset 1px 1px 1px 1px color-mix(in oklch, var(--surface-5) 70%, transparent),\n inset -1px -1px 1px 1px color-mix(in oklch, var(--surface-2) 60%, transparent),\n 2px 2px 1px 0px color-mix(in oklch, var(--surface-2) 90%, transparent);\n }\n\n .split:has(button:active:not(:disabled)) {\n transform: translateY(1px);\n box-shadow: inset 1px 1px 0px 0.5px color-mix(in oklch, var(--surface-1), transparent);\n }\n\n button.primary,\n button.caret {\n border: none;\n border-radius: 0;\n background: none;\n box-shadow: none;\n color: inherit;\n margin: 0;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background var(--transition, 0.2s), opacity var(--transition, 0.2s);\n }\n\n button.primary {\n flex: 1;\n min-width: 0;\n padding: var(--space-m, 8px) var(--space-l, 12px);\n gap: 0.5em;\n overflow: hidden;\n white-space: nowrap;\n }\n\n button.primary .button-label {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n button.caret {\n padding: var(--space-m, 8px) var(--space-s, 6px);\n border-inline-start: var(--border, 1px solid #999);\n flex-shrink: 0;\n }\n\n button.primary:hover:not(:disabled),\n button.caret:hover:not(:disabled) {\n background: color-mix(in oklch, var(--surface-4) 80%, transparent);\n }\n\n button.primary:active:not(:disabled),\n button.caret:active:not(:disabled) {\n background: var(--surface-2, #aaa);\n transform: none;\n box-shadow: none;\n }\n\n button.primary:disabled,\n button.caret:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n button.primary:focus-visible,\n button.caret:focus-visible {\n outline: 2px solid var(--accent, #666);\n outline-offset: -2px;\n }\n\n :host([subtle]) button.primary,\n :host([subtle]) button.caret,\n :host([subtle]) button.primary:hover:not(:disabled),\n :host([subtle]) button.caret:hover:not(:disabled) {\n background: none;\n }\n\n :host([subtle]) .split {\n background: color-mix(in oklch, var(--surface-3, #ccc) 40%, transparent);\n }\n\n :host([subtle]) .split:has(button:hover:not(:disabled)),\n :host([subtle]) .split:has(button:focus-visible:not(:disabled)) {\n background: color-mix(in oklch, var(--surface-3, #ccc) 70%, transparent);\n }\n\n ixfx-menu-trigger {\n display: inline-flex;\n align-items: stretch;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-split-button': SplitButton;\n }\n}\n","import type { CrumbPathElement, CrumbSegment, SegmentIconLookupFn } from './crumb-path.js';\n\nimport { Trees } from '@ixfx/collections';\n\nexport type SortCompareFn = (a: CrumbSegment, b: CrumbSegment) => number;\n\nexport type CrumbPathControllerOptions = {\n separator?: string;\n paths?: string[];\n onQuery?: (pathSegments: string[]) => Promise<CrumbSegment[]>;\n sortCompare?: SortCompareFn | null;\n};\n\nexport class CrumbPathController {\n #element: CrumbPathElement | null = null;\n #pathed: Trees.Pathed.Pathed<CrumbSegment>;\n #separator: string;\n #onQuery: ((pathSegments: string[]) => Promise<CrumbSegment[]>) | undefined;\n #sortCompare: SortCompareFn | null | undefined;\n\n constructor(options: CrumbPathControllerOptions = {}) {\n this.#separator = options.separator ?? `/`;\n this.#onQuery = options.onQuery;\n this.#sortCompare = options.sortCompare;\n this.#pathed = new Trees.Pathed.Pathed<CrumbSegment>({ separator: this.#separator });\n\n if (options.paths) {\n this.addPaths(options.paths);\n // console.log(this.#pathed.prettyPrint());\n }\n }\n\n get separator(): string {\n return this.#separator;\n }\n\n addPath(path: string): void {\n const segments = path.split(this.#separator).filter(s => s.length > 0);\n for (let i = 0; i < segments.length; i++) {\n const segmentPath = segments.slice(0, i + 1).join(this.#separator);\n const label = segments[i];\n const segment: CrumbSegment = { label };\n this.#pathed.add(segment, segmentPath);\n }\n }\n\n addPaths(paths: string[]): void {\n for (const path of paths) {\n this.addPath(path);\n }\n }\n\n addSegment(segment: CrumbSegment, path: string): void {\n this.#pathed.add(segment, path);\n }\n\n addSegments(entries: Array<{ path: string; segment: CrumbSegment }>): void {\n for (const { path, segment } of entries) {\n this.addSegment(segment, path);\n }\n }\n\n getIcon(cumulativePath: string): string | undefined {\n const value = this.#pathed.getValue(cumulativePath);\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === `object` && value !== null && `value` in value) {\n const nested = (value as { value?: CrumbSegment }).value;\n return nested?.icon;\n }\n return (value as CrumbSegment).icon;\n }\n\n getPath(): string {\n return this.#element?.getPath() ?? ``;\n }\n\n setPath(path: string): void {\n this.#element?.setPath(path);\n }\n\n #segmentIconLookup: SegmentIconLookupFn = (pathSegments: string[]): string | undefined => {\n return this.getIcon(pathSegments.join(this.#separator));\n };\n\n connect(element: CrumbPathElement): void {\n this.#element = element;\n element.separator = this.#separator;\n element.siblingLookup = this.#siblingLookup.bind(this);\n if (!element.segmentIconLookup) {\n element.segmentIconLookup = this.#segmentIconLookup;\n }\n }\n\n disconnect(): void {\n if (this.#element) {\n this.#element.siblingLookup = undefined;\n if (this.#element.segmentIconLookup === this.#segmentIconLookup) {\n this.#element.segmentIconLookup = undefined;\n }\n this.#element = null;\n }\n }\n\n async #siblingLookup(\n pathSegments: string[],\n _index: number,\n signal: AbortSignal,\n ): Promise<CrumbSegment[]> {\n const currentPath = pathSegments.join(this.#separator);\n\n const cachedChildren = this.#pathed.children(currentPath);\n const children = [...cachedChildren];\n\n if (children.length > 0) {\n const mapped = children\n .map(node => node.value)\n .filter((v): v is NonNullable<typeof v> => v !== undefined)\n .map((v) => {\n if (`value` in v) {\n return v.value ?? { label: v.label };\n }\n return { label: v.label };\n });\n return this.#sortCompare ? [...mapped].sort(this.#sortCompare) : mapped;\n }\n\n if (this.#onQuery) {\n const newChildren = await this.#onQuery(pathSegments);\n\n const sorted = this.#sortCompare ? [...newChildren].sort(this.#sortCompare) : newChildren;\n for (const child of sorted) {\n const childPath = currentPath.length > 0\n ? `${currentPath}${this.#separator}${child.label}`\n : child.label;\n this.#pathed.add(child, childPath);\n }\n\n if (signal.aborted) {\n return [];\n }\n\n return sorted;\n }\n\n return [];\n }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues } from 'lit';\nimport type { AcTextChangeEvent, AcTextItem } from '../ac-text/ac-text.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { popupSurfaceStyles } from '../styles/popup.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { scrollFadeStyles } from '../styles/scroll-fade.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../ac-text/ac-text.js';\nimport '../icons/icon.js';\n\nconst INVALID_ANCHOR_CHARS_RE = /[^\\w-]/g;\n\nexport type CrumbSegment = {\n label: string;\n icon?: string;\n isLeaf?: boolean;\n};\n\nexport type CrumbSiblingLookupFn = (\n pathSegments: string[],\n index: number,\n signal: AbortSignal,\n) => Promise<CrumbSegment[]>;\n\nexport type SegmentIconLookupFn = (\n pathSegments: string[],\n index: number,\n) => string | undefined;\n\nexport type CrumbNavNavigateDetail = { index: number; label: string; parentPath: string; fullPath: string };\nexport type CrumbNavNavigateEvent = CustomEvent<CrumbNavNavigateDetail>;\nexport type CrumbNavChangeDetail = { label: string; parentPath: string; fullPath: string };\nexport type CrumbNavChangeEvent = CustomEvent<CrumbNavChangeDetail>;\nexport type CrumbNavExpandDetail = { index: number; segments: string[]; path: string; signal: AbortSignal };\nexport type CrumbNavExpandEvent = CustomEvent<CrumbNavExpandDetail>;\n\n/** A MIME-typed payload written to the drag's `DataTransfer` when a segment drag starts. */\nexport type CrumbSegmentDragData = {\n /** MIME type, e.g. `text/plain` or an application-specific type. */\n type: string;\n /** Payload string for `type`. */\n data: string;\n};\n\n/**\n * Consulted per segment with the full cumulative path (including any\n * `pathRoot` prefix). Returning drag data marks the segment `draggable`;\n * returning `undefined` leaves it alone. Called at render time (to mark the\n * segment) and again during `dragstart` (for fresh payload data).\n */\nexport type CrumbSegmentDragLookupFn = (\n pathSegments: string[],\n index: number,\n) => CrumbSegmentDragData | readonly CrumbSegmentDragData[] | undefined;\n\n/**\n * Interprets a drop landing on a segment. Return `undefined` for drops the\n * app does not handle — no `crumb-drop` event fires for them. Only\n * `dataTransfer.types` is reliably readable during `dragover`; full data is\n * readable at `drop`.\n */\nexport type CrumbExternalDropParser = (dataTransfer: DataTransfer) => unknown;\n\nexport type CrumbDragStartDetail = {\n /** Index of the dragged segment within `pathSegments`. */\n index: number;\n label: string;\n /** Full cumulative path segments, including any `pathRoot` prefix. */\n pathSegments: string[];\n parentPath: string;\n fullPath: string;\n /** Null in stubbed environments; normally present during a real `dragstart`. */\n dataTransfer: DataTransfer | null;\n};\nexport type CrumbDragStartEvent = CustomEvent<CrumbDragStartDetail>;\n\nexport type CrumbDropDetail = {\n /** Index of the drop segment within `pathSegments`. */\n index: number;\n label: string;\n /** Full cumulative path segments, including any `pathRoot` prefix. */\n pathSegments: string[];\n parentPath: string;\n fullPath: string;\n /** Result of `parseExternalDrop` — always defined; unparsed drops emit nothing. */\n data: unknown;\n dataTransfer: DataTransfer;\n};\nexport type CrumbDropEvent = CustomEvent<CrumbDropDetail>;\n\n@customElement(`ixfx-crumb-path`)\nexport class CrumbPathElement extends LitElement {\n @property({ type: String })\n path = ``;\n\n @property({ type: String })\n separator = `/`;\n\n @property({ type: String, attribute: `path-root` })\n pathRoot = ``;\n\n @property({ type: Object })\n siblingLookup: CrumbSiblingLookupFn | undefined;\n\n @property({ type: Object })\n segmentIconLookup: SegmentIconLookupFn | undefined;\n\n /** Marks segments draggable and supplies their drag payloads. */\n @property({ type: Object })\n segmentDragLookup: CrumbSegmentDragLookupFn | undefined;\n\n /** Interprets drops landing on segments; enables drop targeting when set. */\n @property({ type: Object })\n parseExternalDrop: CrumbExternalDropParser | undefined;\n\n /**\n * When enabled, navigating up (clicking an earlier real segment) keeps\n * rendering the segments beyond it as translucent, non-interactive-drag,\n * click-to-restore \"virtual\" segments — for as long as the current path\n * stays a prefix of the deepest path visited. See `#recordHintOnShorten`.\n */\n @property({ type: Boolean, attribute: `hint-previous` })\n hintPrevious = false;\n\n @state()\n private _openIdx: number | null = null;\n\n @state()\n private _editing = false;\n\n @state()\n private _cachedSiblings: Map<string, CrumbSegment[]> = new Map();\n\n @state()\n private _leafSegmentIndex: number | null = null;\n\n @state()\n private _confirmedLeafIndices: Set<string> = new Set();\n\n @state()\n private _dropdownActiveIndex = -1;\n\n @state()\n private _editingCancelled = false;\n\n @state()\n private _editStartIndex: number | null = null;\n\n @state()\n private _openCumPath: string | null = null;\n\n /** Cumulative path of the segment currently being dragged out (`.dragging`). */\n @state()\n private _dragCumPath: string | null = null;\n\n /** Cumulative path of the segment currently hovered by an external drag (`.drop-into`). */\n @state()\n private _dropCumPath: string | null = null;\n\n /** Deepest relative-segment path visited, kept so it can be restored via virtual segments. */\n @state()\n private _hintSegments: string[] | null = null;\n\n #pendingController: AbortController | undefined;\n #pendingIndex: number | undefined;\n readonly #uid = Math.random().toString(36).slice(2, 8);\n /** Clicks within this window after a drag are ignored (post-drag click-through guard). */\n #clickSuppressUntil = 0;\n\n #anchorName(cumPath: string): string {\n return `--cp-${this.#uid}-${cumPath\n .replaceAll(this.separator, `-`)\n .replaceAll(` `, `-`)\n .replace(INVALID_ANCHOR_CHARS_RE, `-`)}`;\n }\n\n #closeDropdown() {\n if (this._openIdx !== null) {\n this._openIdx = null;\n this._openCumPath = null;\n this._dropdownActiveIndex = -1;\n this.#cleanupPending();\n const popup = this.shadowRoot?.querySelector(`.crumb-dropdown`) as HTMLElement | null;\n try {\n (popup as any)?.hidePopover();\n } catch { /* unsupported */ }\n }\n }\n\n #onPopoverToggle = (e: Event): void => {\n if ((e as ToggleEvent).newState === `closed` && this._openIdx !== null) {\n this._openIdx = null;\n this._dropdownActiveIndex = -1;\n this.#cleanupPending();\n }\n };\n\n protected override updated(changedProperties: PropertyValues): void {\n if (this._editing) {\n const el = this.shadowRoot?.querySelector(`ixfx-ac-text`);\n if (el instanceof LitElement) {\n const editValue = this.path;\n if (this._editStartIndex !== null) {\n const segments = this.#getSegments();\n const segmentLabel = segments[this._editStartIndex];\n const startPos = this.path.indexOf(segmentLabel);\n (el as any).focusWithValue(editValue, startPos);\n } else {\n (el as any).focusWithValue(editValue);\n }\n }\n }\n if (changedProperties.has(`_openIdx`) && this._openIdx !== null) {\n this.updateComplete.then(() => {\n const popup = this.shadowRoot?.querySelector(`.crumb-dropdown`) as HTMLElement | null;\n if (popup) {\n popup.style.setProperty(`position-anchor`, this.#anchorName(this._openCumPath ?? String(this._openIdx)));\n try {\n (popup as any).showPopover();\n } catch { /* unsupported */ }\n popup.focus();\n }\n });\n }\n }\n\n #cleanupPending() {\n if (this.#pendingController) {\n this.#pendingController.abort();\n this.#pendingController = undefined;\n this.#pendingIndex = undefined;\n }\n }\n\n #getSegments(): string[] {\n const fullPath = this.path;\n if (this.pathRoot.length > 0 && fullPath.startsWith(this.pathRoot)) {\n const relativePath = fullPath.slice(this.pathRoot.length);\n return relativePath.split(this.separator).filter(p => p.length > 0);\n }\n return this.path.split(this.separator).filter(p => p.length > 0);\n }\n\n #getRootSegments(): string[] {\n if (this.pathRoot.length === 0)\n return [];\n return this.pathRoot.split(this.separator).filter(p => p.length > 0);\n }\n\n #getCumulativePath(index: number, isRoot: boolean): string {\n const segments = this.#getSegments();\n const rootSegments = this.#getRootSegments();\n\n if (isRoot) {\n return rootSegments.slice(0, index + 1).join(this.separator);\n }\n\n return [...rootSegments, ...segments.slice(0, index + 1)].join(this.separator);\n }\n\n #resolveFullPathSegments(index: number, isRoot: boolean): string[] {\n const rootSegments = this.#getRootSegments();\n if (isRoot)\n return rootSegments.slice(0, index + 1);\n return [...rootSegments, ...this.#getSegments().slice(0, index + 1)];\n }\n\n #segmentDragPayloads(fullPathSegments: string[]): CrumbSegmentDragData[] {\n try {\n const result = this.segmentDragLookup?.(fullPathSegments, fullPathSegments.length - 1);\n if (result === undefined || result === null)\n return [];\n // `Array.isArray` does not narrow away `readonly T[]` in the false branch.\n return Array.isArray(result) ? [...result] : [result as CrumbSegmentDragData];\n } catch {\n return [];\n }\n }\n\n #clicksSuppressed(): boolean {\n return Date.now() < this.#clickSuppressUntil || this._dragCumPath !== null;\n }\n\n #isSegmentPrefix(prefix: string[], full: string[]): boolean {\n return prefix.length <= full.length && prefix.every((seg, i) => seg === full[i]);\n }\n\n /**\n * Called when a real segment click shortens the path. Keeps the deepest\n * known branch: only overwrites `_hintSegments` when the current hint no\n * longer covers where we're navigating to.\n */\n #recordHintOnShorten(oldSegments: string[], newSegments: string[]): void {\n if (!this.hintPrevious)\n return;\n const hint = this._hintSegments;\n const hintStillCovers = hint !== null && this.#isSegmentPrefix(newSegments, hint);\n if (!hintStillCovers) {\n this._hintSegments = oldSegments;\n }\n }\n\n #resolveSegmentIcon(fullPathSegments: string[], index: number): string | undefined {\n const direct = this.segmentIconLookup?.(fullPathSegments, index);\n if (typeof direct === `string` && direct.length > 0) {\n return direct;\n }\n const label = fullPathSegments[index];\n if (label === undefined) {\n return undefined;\n }\n const parentKey = fullPathSegments.slice(0, index).join(this.separator);\n const cached = this._cachedSiblings.get(parentKey);\n const match = cached?.find(s => s.label === label);\n return match?.icon;\n }\n\n public setPath(newPath: string): void {\n this.#cleanupPending();\n if (this.pathRoot.length > 0 && !newPath.startsWith(this.pathRoot)) {\n newPath = this.pathRoot;\n }\n this.path = newPath;\n this._cachedSiblings = new Map();\n this._openIdx = null;\n this._leafSegmentIndex = null;\n this._confirmedLeafIndices = new Set();\n }\n\n public getPath(): string {\n return this.path;\n }\n\n #onCaretClick(index: number, event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n\n if (this._openIdx === index) {\n this.#closeDropdown();\n return;\n }\n\n const target = event.currentTarget as HTMLElement;\n const cumPath = target.dataset.cumulative;\n\n this._openIdx = index;\n this._openCumPath = cumPath ?? null;\n this._dropdownActiveIndex = -1;\n const segments = this.#getSegments();\n const rootSegments = this.#getRootSegments();\n\n const pathSegments = cumPath\n ? cumPath.split(this.separator).filter(p => p.length > 0)\n : (index === -1 ? rootSegments : segments.slice(0, index + 1));\n\n const cacheKey = cumPath ?? String(index);\n if (!this._cachedSiblings.has(cacheKey) && this.siblingLookup) {\n this.#cleanupPending();\n const controller = new AbortController();\n this.#pendingController = controller;\n this.#pendingIndex = index;\n\n this.siblingLookup(pathSegments, index, controller.signal)\n .then((siblings) => {\n if (!controller.signal.aborted) {\n this._cachedSiblings.set(cacheKey, siblings);\n if (siblings.length === 0) {\n this._confirmedLeafIndices.add(cumPath ?? ``);\n }\n this.#pendingController = undefined;\n this.#pendingIndex = undefined;\n this.requestUpdate();\n }\n })\n .catch((err) => {\n if (err.name !== `AbortError`) {\n console.error(`Sibling lookup failed:`, err);\n }\n this.#pendingController = undefined;\n this.#pendingIndex = undefined;\n });\n\n this.dispatchEvent(new CustomEvent<CrumbNavExpandDetail>(`expand`, {\n detail: { index, segments: pathSegments, path: pathSegments.join(this.separator), signal: controller.signal },\n bubbles: true,\n composed: true,\n }));\n }\n\n this.requestUpdate();\n }\n\n #onLabelDragStart(fullPathSegments: string[], cumPath: string, event: DragEvent): void {\n this.#closeDropdown();\n const index = fullPathSegments.length - 1;\n const dt = event.dataTransfer;\n const detail: CrumbDragStartDetail = {\n index,\n label: fullPathSegments[index] ?? ``,\n pathSegments: fullPathSegments,\n parentPath: fullPathSegments.slice(0, -1).join(this.separator),\n fullPath: fullPathSegments.join(this.separator),\n dataTransfer: dt,\n };\n const evt = new CustomEvent<CrumbDragStartDetail>(`crumb-drag-start`, {\n detail,\n bubbles: true,\n composed: true,\n cancelable: true,\n });\n const notCancelled = this.dispatchEvent(evt);\n if (!notCancelled) {\n event.preventDefault();\n return;\n }\n this._dragCumPath = cumPath;\n this.toggleAttribute(`data-native-dragging`, true);\n if (!dt)\n return;\n try {\n // Let drop targets show a \"move\" / \"copy\" cursor.\n if (dt.effectAllowed === `none` || dt.effectAllowed === `uninitialized`) {\n dt.effectAllowed = `copyMove`;\n }\n } catch { /* read-only in some contexts — non-fatal. */ }\n try {\n for (const payload of this.#segmentDragPayloads(fullPathSegments)) {\n dt.setData(payload.type, payload.data);\n }\n // The cumulative path is the natural fallback payload for a segment.\n if (!dt.types.includes(`text/plain`)) {\n dt.setData(`text/plain`, detail.fullPath);\n }\n } catch { /* restricted / stubbed DataTransfer — non-fatal. */ }\n }\n\n #onLabelDragEnd(): void {\n this._dragCumPath = null;\n this._dropCumPath = null;\n this.toggleAttribute(`data-native-dragging`, false);\n // Suppress the click that some browsers still fire after a drag ends.\n this.#clickSuppressUntil = Date.now() + 150;\n }\n\n #onSegDragOver(cumPath: string, event: DragEvent): void {\n if (!this.parseExternalDrop)\n return;\n if (!event.dataTransfer)\n return;\n event.preventDefault();\n if (this._dropCumPath !== cumPath) {\n this._dropCumPath = cumPath;\n }\n }\n\n #onSegDragLeave(cumPath: string, _event: DragEvent): void {\n if (!this.parseExternalDrop)\n return;\n if (this._dropCumPath === cumPath) {\n this._dropCumPath = null;\n }\n }\n\n #onSegDrop(fullPathSegments: string[], event: DragEvent): void {\n if (!this.parseExternalDrop)\n return;\n event.preventDefault();\n event.stopPropagation();\n this._dropCumPath = null;\n const dt = event.dataTransfer;\n if (!dt)\n return;\n let data: unknown;\n try {\n data = this.parseExternalDrop(dt);\n } catch (err) {\n console.error(`parseExternalDrop failed:`, err);\n return;\n }\n if (data === undefined)\n return;\n const index = fullPathSegments.length - 1;\n this.dispatchEvent(new CustomEvent<CrumbDropDetail>(`crumb-drop`, {\n detail: {\n index,\n label: fullPathSegments[index] ?? ``,\n pathSegments: fullPathSegments,\n parentPath: fullPathSegments.slice(0, -1).join(this.separator),\n fullPath: fullPathSegments.join(this.separator),\n data,\n dataTransfer: dt,\n },\n bubbles: true,\n composed: true,\n }));\n }\n\n /**\n * The current leaf segment (deepest visible segment), used as the drop target\n * when a drag is released over blank space rather than a specific `.seg`.\n */\n #leafSegment(): { cumPath: string; fullPathSegments: string[] } | undefined {\n const segments = this.#getSegments();\n if (segments.length > 0) {\n const index = segments.length - 1;\n return {\n cumPath: this.#getCumulativePath(index, false),\n fullPathSegments: this.#resolveFullPathSegments(index, false),\n };\n }\n const rootSegments = this.#getRootSegments();\n if (rootSegments.length > 0) {\n const index = rootSegments.length - 1;\n return {\n cumPath: this.#getCumulativePath(index, true),\n fullPathSegments: this.#resolveFullPathSegments(index, true),\n };\n }\n return undefined;\n }\n\n /**\n * Is `event` already being handled by a `.seg`'s own drag handlers? Virtual\n * (hint) segments don't have drag handlers of their own, so a drag released\n * over one falls through to the host-level fallback (the real leaf).\n */\n #eventTargetsSegment(event: DragEvent): boolean {\n return Boolean((event.target as HTMLElement | null)?.closest?.(`.seg:not(.seg-virtual)`));\n }\n\n #onHostDragOver(event: DragEvent): void {\n if (!this.parseExternalDrop || !event.dataTransfer)\n return;\n if (this.#eventTargetsSegment(event))\n return;\n const leaf = this.#leafSegment();\n if (!leaf)\n return;\n event.preventDefault();\n if (this._dropCumPath !== leaf.cumPath) {\n this._dropCumPath = leaf.cumPath;\n }\n }\n\n #onHostDragLeave(event: DragEvent): void {\n if (!this.parseExternalDrop || this.#eventTargetsSegment(event))\n return;\n const leaf = this.#leafSegment();\n if (leaf && this._dropCumPath === leaf.cumPath) {\n this._dropCumPath = null;\n }\n }\n\n #onHostDrop(event: DragEvent): void {\n if (!this.parseExternalDrop || this.#eventTargetsSegment(event))\n return;\n const leaf = this.#leafSegment();\n if (!leaf)\n return;\n this.#onSegDrop(leaf.fullPathSegments, event);\n }\n\n #onLabelClick(index: number, event: MouseEvent) {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n this.#closeDropdown();\n\n const segments = this.#getSegments();\n const truncatedSegments = segments.slice(0, index + 1);\n this.#recordHintOnShorten(segments, truncatedSegments);\n const hadLeading = this.path.startsWith(this.separator);\n const newPath = truncatedSegments.join(this.separator);\n this.path = hadLeading ? this.separator + newPath : newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = null;\n\n const parentPath = truncatedSegments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavNavigateDetail>(`navigate`, {\n detail: { index, label: truncatedSegments[index], parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onVirtualSegmentClick(hintIndex: number, event: MouseEvent): void {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n this.#closeDropdown();\n\n const hint = this._hintSegments;\n if (!hint)\n return;\n const truncatedSegments = hint.slice(0, hintIndex + 1);\n const hadLeading = this.path.startsWith(this.separator);\n const newPath = truncatedSegments.join(this.separator);\n this.path = hadLeading ? this.separator + newPath : newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = null;\n\n const parentPath = truncatedSegments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavNavigateDetail>(`navigate`, {\n detail: { index: hintIndex, label: truncatedSegments[hintIndex], parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #selectSibling(index: number, segment: CrumbSegment): void {\n const cumPath = this._openCumPath;\n this.#closeDropdown();\n const segments = this.#getSegments();\n const rootSegments = this.#getRootSegments();\n let newSegments: string[];\n\n if (cumPath) {\n newSegments = [...cumPath.split(this.separator).filter(p => p.length > 0), segment.label];\n } else if (this.pathRoot.length > 0 && index < rootSegments.length) {\n newSegments = [...rootSegments.slice(0, index + 1), segment.label];\n } else {\n newSegments = [...rootSegments, ...segments.slice(0, index + 1 - rootSegments.length), segment.label];\n }\n\n const hadLeading = this.path.startsWith(this.separator);\n const newPath = newSegments.join(this.separator);\n this.path = hadLeading ? this.separator + newPath : newPath;\n this._cachedSiblings = new Map();\n const leafIndex = segment.isLeaf ? newSegments.length - 1 : null;\n this._leafSegmentIndex = leafIndex;\n if (segment.isLeaf) {\n this._confirmedLeafIndices.add(cumPath ?? ``);\n }\n const parentPath = newSegments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavNavigateDetail>(`navigate`, {\n detail: { index, label: segment.label, parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onSiblingClick(index: number, segment: CrumbSegment, event: MouseEvent) {\n event.preventDefault();\n event.stopPropagation();\n this.#selectSibling(index, segment);\n }\n\n #onDropdownKeyDown = (e: KeyboardEvent): void => {\n if (this._openIdx === null)\n return;\n const siblings = this._cachedSiblings.get(this._openCumPath ?? String(this._openIdx)) ?? [];\n if (!siblings.length) {\n if (e.key === `Escape`) {\n e.preventDefault(); this.#closeDropdown();\n }\n return;\n }\n switch (e.key) {\n case `ArrowDown`:\n e.preventDefault();\n this._dropdownActiveIndex = (this._dropdownActiveIndex + 1) % siblings.length;\n this.#scrollDropdownActiveIntoView();\n break;\n case `ArrowUp`:\n e.preventDefault();\n this._dropdownActiveIndex = this._dropdownActiveIndex <= 0\n ? siblings.length - 1\n : this._dropdownActiveIndex - 1;\n this.#scrollDropdownActiveIntoView();\n break;\n case `Enter`:\n if (this._dropdownActiveIndex >= 0) {\n e.preventDefault();\n this.#selectSibling(this._openIdx, siblings[this._dropdownActiveIndex]);\n }\n break;\n case `Escape`:\n e.preventDefault();\n this.#closeDropdown();\n break;\n }\n };\n\n #scrollDropdownActiveIntoView(): void {\n this.updateComplete.then(() => {\n this.shadowRoot?.querySelector(`.crumb-option.active`)\n ?.scrollIntoView({ block: `nearest` });\n });\n }\n\n #renderDropdownContent(index: number) {\n const siblings = this._cachedSiblings.get(this._openCumPath ?? String(index)) ?? [];\n const isPending = this.#pendingIndex === index;\n\n return html`\n ${isPending ? html`<span class=\"loading-spinner\"></span>` : nothing}\n ${siblings.length === 0 && !isPending\n ? html`<span class=\"crumb-option crumb-option-label\">No items</span>`\n : siblings.map((segment, i) => html`\n <div class=\"crumb-option ${i === this._dropdownActiveIndex ? `active` : ``}\"\n @click=${(e: MouseEvent) => this.#onSiblingClick(index, segment, e)}>\n ${segment.icon\n ? html`<ixfx-icon class=\"crumb-icon\" name=\"${segment.icon}\"></ixfx-icon>`\n : nothing}\n <span class=\"option-label\">${segment.label}</span>\n </div>\n `)}\n `;\n }\n\n #renderSegment(label: string, index: number, isLast: boolean) {\n const isOpen = this._openIdx === index;\n const cumPath = this.#getCumulativePath(index, false);\n const fullPathSegments = this.#resolveFullPathSegments(index, false);\n const icon = this.#resolveSegmentIcon(fullPathSegments, fullPathSegments.length - 1);\n const draggable = this.#segmentDragPayloads(fullPathSegments).length > 0;\n const dragging = this._dragCumPath === cumPath;\n const dropInto = this._dropCumPath === cumPath;\n\n return html`\n <div class=\"seg ${dragging ? `dragging` : ``} ${dropInto ? `drop-into` : ``}\"\n part=${dropInto ? `segment drop-target` : `segment`}\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onSegmentClick(index, e)}\n @dragover=${(e: DragEvent) => this.#onSegDragOver(cumPath, e)}\n @dragleave=${(e: DragEvent) => this.#onSegDragLeave(cumPath, e)}\n @drop=${(e: DragEvent) => this.#onSegDrop(fullPathSegments, e)}>\n <label title=${label}\n part=\"label\"\n draggable=${draggable ? `true` : `false`}\n @click=${(e: MouseEvent) => this.#onLabelClick(index, e)}\n @dragstart=${(e: DragEvent) => this.#onLabelDragStart(fullPathSegments, cumPath, e)}\n @dragend=${() => this.#onLabelDragEnd()}>\n ${icon\n ? html`<ixfx-icon class=\"crumb-icon segment-icon\" name=${icon}></ixfx-icon>`\n : nothing}\n ${label}\n </label>\n ${(!isLast || this.siblingLookup) && this._leafSegmentIndex !== index\n ? html`\n <div class=\"caret ${isOpen ? `open` : ``} ${this._confirmedLeafIndices.has(cumPath) ? `disabled` : ``}\"\n part=\"caret\"\n style=\"anchor-name: ${this.#anchorName(cumPath)}\"\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onCaretClick(index, e)}>\n ${this.separator}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n /**\n * A translucent, click-to-restore segment beyond the current path, shown\n * while `hintPrevious` is enabled and the current path is a prefix of the\n * deepest path visited. Doesn't participate in drag'n'drop and isn't\n * keyboard-focusable.\n */\n #renderVirtualSegment(label: string, hintIndex: number) {\n const rootSegments = this.#getRootSegments();\n const fullPathSegments = [...rootSegments, ...(this._hintSegments ?? []).slice(0, hintIndex + 1)];\n const icon = this.#resolveSegmentIcon(fullPathSegments, fullPathSegments.length - 1);\n\n return html`\n <div class=\"seg seg-virtual\" part=\"segment virtual\">\n <label title=${label}\n part=\"label\"\n @click=${(e: MouseEvent) => this.#onVirtualSegmentClick(hintIndex, e)}>\n ${icon\n ? html`<ixfx-icon class=\"crumb-icon segment-icon\" name=${icon}></ixfx-icon>`\n : nothing}\n ${label}\n </label>\n </div>\n `;\n }\n\n #renderRootSegment(label: string, index: number) {\n const rootSegments = this.#getRootSegments();\n const isLast = index === rootSegments.length - 1;\n const isOpen = this._openIdx === index;\n const cumPath = this.#getCumulativePath(index, true);\n const fullPathSegments = this.#resolveFullPathSegments(index, true);\n const icon = this.#resolveSegmentIcon(fullPathSegments, index);\n const draggable = this.#segmentDragPayloads(fullPathSegments).length > 0;\n const dragging = this._dragCumPath === cumPath;\n const dropInto = this._dropCumPath === cumPath;\n\n return html`\n <div class=\"seg seg-root ${dragging ? `dragging` : ``} ${dropInto ? `drop-into` : ``}\"\n part=${dropInto ? `segment drop-target` : `segment`}\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onRootSegmentClick(index, e)}\n @dragover=${(e: DragEvent) => this.#onSegDragOver(cumPath, e)}\n @dragleave=${(e: DragEvent) => this.#onSegDragLeave(cumPath, e)}\n @drop=${(e: DragEvent) => this.#onSegDrop(fullPathSegments, e)}>\n <label title=${label}\n part=\"label\"\n draggable=${draggable ? `true` : `false`}\n @click=${(e: MouseEvent) => this.#onLabelClick(index, e)}\n @dragstart=${(e: DragEvent) => this.#onLabelDragStart(fullPathSegments, cumPath, e)}\n @dragend=${() => this.#onLabelDragEnd()}>${icon\n ? html`<ixfx-icon class=\"crumb-icon segment-icon\" name=${icon}></ixfx-icon>`\n : nothing}${label}</label>\n ${isLast && this.siblingLookup\n ? html`\n <div class=\"caret ${isOpen ? `open` : ``} ${this._confirmedLeafIndices.has(cumPath) ? `disabled` : ``}\"\n part=\"caret\"\n style=\"anchor-name: ${this.#anchorName(cumPath)}\"\n data-cumulative=${cumPath}\n @click=${(e: MouseEvent) => this.#onCaretClick(index, e)}>\n ${this.separator}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n #onRootSegmentClick(index: number, event: MouseEvent): void {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n const rootSegments = this.#getRootSegments();\n const newPath = rootSegments.slice(0, index + 1).join(this.separator);\n this.setPath(newPath);\n }\n\n #onSegmentClick(index: number, event: MouseEvent): void {\n if (this.#clicksSuppressed())\n return;\n event.preventDefault();\n event.stopPropagation();\n this.#closeDropdown();\n this._editing = true;\n this._editStartIndex = index;\n }\n\n #onTrailingClick() {\n if (this.#clicksSuppressed())\n return;\n this.#closeDropdown();\n this._editing = true;\n this._editStartIndex = null;\n }\n\n #makeCompletionProvider() {\n return async (query: string, signal: AbortSignal): Promise<AcTextItem[]> => {\n if (!this.siblingLookup)\n return [];\n const endsWithSep = query.endsWith(this.separator);\n const parts = query.split(this.separator).filter(p => p.length > 0);\n const parentSegments = endsWithSep ? parts : parts.slice(0, -1);\n const lastSegment = endsWithSep ? `` : (parts.at(-1) ?? ``);\n const hadLeading = query.startsWith(this.separator);\n const children = await this.siblingLookup(\n parentSegments,\n parentSegments.length - 1,\n signal,\n );\n return children\n .filter(c => c.label.toLowerCase().startsWith(lastSegment.toLowerCase()))\n .map((c) => {\n const joined = [...parentSegments, c.label].join(this.separator);\n return { label: hadLeading ? this.separator + joined : joined, icon: c.icon, isLeaf: c.isLeaf };\n });\n };\n }\n\n #onAcChange(e: AcTextChangeEvent) {\n e.stopPropagation();\n const newPath = e.detail.value;\n this.path = newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = newPath.endsWith(this.separator) ? null : newPath.split(this.separator).filter((p: string) => p.length > 0).length - 1;\n this._editing = false;\n this._editingCancelled = false;\n this._editStartIndex = null;\n this.#dispatchChangeEvent(newPath);\n }\n\n #onAcFocusOut() {\n if (this._editing) {\n this._editing = false;\n if (!this._editingCancelled) {\n const el = this.shadowRoot?.querySelector(`ixfx-ac-text`) as any;\n const newPath = el?.value ?? this.path;\n if (newPath !== this.path) {\n this.path = newPath;\n this._cachedSiblings = new Map();\n this._leafSegmentIndex = newPath.endsWith(this.separator) ? null : newPath.split(this.separator).filter((p: string) => p.length > 0).length - 1;\n this.#dispatchChangeEvent(newPath);\n }\n }\n this._editingCancelled = false;\n this._editStartIndex = null;\n }\n }\n\n #dispatchChangeEvent(newPath: string): void {\n const segments = newPath.split(this.separator).filter(p => p.length > 0);\n const label = segments.at(-1) ?? ``;\n const parentPath = segments.slice(0, -1).join(this.separator);\n this.dispatchEvent(new CustomEvent<CrumbNavChangeDetail>(`change`, {\n detail: { label, parentPath, fullPath: newPath },\n bubbles: true,\n composed: true,\n }));\n }\n\n #onAcKeyDown(e: KeyboardEvent) {\n if (e.key === `Escape`) {\n this._editingCancelled = true;\n this._editing = false;\n this._editStartIndex = null;\n }\n }\n\n #onHostKeyDown = (e: KeyboardEvent): void => {\n if (this._editing)\n return;\n const nonEditKeys = [`ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`, `Enter`];\n if (!nonEditKeys.includes(e.key)) {\n this._editing = true;\n }\n };\n\n protected override render() {\n const segments = this.#getSegments();\n const hintSegments = this.hintPrevious ? this._hintSegments : null;\n const virtualSegments = hintSegments !== null\n && hintSegments.length > segments.length\n && this.#isSegmentPrefix(segments, hintSegments)\n ? hintSegments.slice(segments.length)\n : [];\n\n if (this._editing) {\n const editValue = this.path;\n return html`\n <ixfx-ac-text\n .value=${editValue}\n .tabSuffix=${this.separator}\n .completionProvider=${this.#makeCompletionProvider()}\n @change=${this.#onAcChange}\n @focusout=${this.#onAcFocusOut}\n @keydown=${this.#onAcKeyDown}\n ></ixfx-ac-text>\n `;\n }\n\n const rootSegments = this.#getRootSegments();\n const leadingCaret = this.siblingLookup && rootSegments.length === 0\n ? html`\n <div class=\"caret ${this._openIdx === -1 ? `open` : ``} ${this._confirmedLeafIndices.has(``) ? `disabled` : ``}\"\n style=\"anchor-name: ${this.#anchorName(``)}\"\n data-cumulative=\"\"\n @click=${(e: MouseEvent) => this.#onCaretClick(-1, e)}>\n ${this.separator}\n </div>`\n : nothing;\n\n return html`\n <div class=\"crumbs scroll-fade-x\" tabindex=\"0\"\n @keydown=${this.#onHostKeyDown}\n @dragover=${(e: DragEvent) => this.#onHostDragOver(e)}\n @dragleave=${(e: DragEvent) => this.#onHostDragLeave(e)}\n @drop=${(e: DragEvent) => this.#onHostDrop(e)}>\n ${rootSegments.length > 0\n ? rootSegments.map((label, i) => this.#renderRootSegment(label, i))\n : nothing}\n ${leadingCaret}\n ${segments.map((label, i) =>\n this.#renderSegment(label, i, i === segments.length - 1),\n )}\n ${virtualSegments.map((label, i) =>\n this.#renderVirtualSegment(label, segments.length + i),\n )}\n <div class=\"trailing\" @click=${this.#onTrailingClick}></div>\n </div>\n ${this._openIdx !== null\n ? html`\n <div class=\"crumb-dropdown popup-surface\" popover=\"auto\" tabindex=\"-1\"\n @toggle=${this.#onPopoverToggle}\n @keydown=${this.#onDropdownKeyDown}\n @click=${(e: Event) => e.stopPropagation()}>\n ${this.#renderDropdownContent(this._openIdx)}\n </div>\n `\n : nothing}\n `;\n }\n\n static override styles = [prominenceStyles, themeFallbacks, popupSurfaceStyles, scrollFadeStyles(`x`), css`\n :host {\n --text-highlight: var(--accent);\n --separator: var(--surface-muted-text);\n --padding-s: var(--space-xs);\n --padding-m: var(--space-s);\n --hover-bg: var(--surface-5);\n --hover-fg: var(--surface-5-text);\n --crumb-hint-opacity: 0.35;\n --crumb-hint-hover-opacity: 0.6;\n\n display: flex;\n width: 100%;\n gap: var(--padding-s);\n position: relative;\n }\n\n ixfx-ac-text {\n flex: 1;\n font-size: inherit;\n --ac-input-padding: var(--padding-s) var(--padding-m);\n --ac-input-background: var(--surface-4);\n --ac-input-border-radius: var(--radius-s, 3px);\n --ac-popup-font-size: var(--text-s, 11px);\n }\n\n .crumbs {\n display: flex;\n width: 100%;\n overflow-x:scroll;\n scroll-snap-type:x proximity;\n scrollbar-width: none;\n }\n\n .trailing {\n flex: 1;\n min-width: 1em;\n cursor: text;\n }\n\n .seg {\n scroll-snap-align:start;\n\n position: relative;\n cursor: pointer;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n user-select: none;\n pointer-events: auto;\n }\n\n .seg:hover {\n overflow: unset;\n }\n\n .seg-root {\n opacity: var(--prominence-idle-opacity);\n }\n\n .seg-root:hover {\n opacity: var(--prominence-tickled-opacity);\n }\n\n .seg-root label {\n font-weight: normal;\n }\n\n label {\n display: flex;\n align-items: center;\n gap: var(--padding-s);\n white-space: nowrap;\n text-overflow: ellipsis;\n align-content: center;\n overflow: hidden;\n padding: 0 var(--padding-m);\n transition: all 0.2s ease-in-out;\n border-radius: var(--radius-m);\n }\n\n label:hover,.caret:hover {\n color: var(--item-text-tickled);\n background: var(--item-bg-tickled);\n }\n\n .caret {\n scroll-snap-align:start;\n\n position: relative;\n padding: var(--padding-m);\n transition: all 0.2s ease-in-out;\n\n border-radius: var(--radius-m);\n }\n\n\n .caret.open {\n background: color-mix(in srgb, var(--hover-bg) 40%, transparent);\n }\n\n .caret.disabled {\n opacity: var(--prominence-disabled-opacity);\n cursor: not-allowed;\n }\n\n /* Drag and drop styles */\n label[draggable] {\n cursor: grab;\n }\n\n .seg.dragging {\n opacity: 0.4;\n }\n\n .seg.drop-into {\n outline: var(--crumb-drop-into-outline, 2px solid var(--accent));\n outline-offset: -2px;\n background: var(--crumb-drop-into-bg, color-mix(in srgb, var(--accent) 14%, transparent));\n }\n\n .seg-virtual {\n opacity: var(--crumb-hint-opacity);\n }\n\n .seg-virtual:hover {\n opacity: var(--crumb-hint-hover-opacity);\n }\n\n .crumb-icon {\n width: 1em;\n height: 1em;\n flex-shrink: 0;\n }\n\n .crumb-dropdown {\n /* Reset popover UA defaults */\n inset: unset;\n margin: 0;\n\n /* Anchor positioning — position-anchor set dynamically via JS */\n position: fixed;\n position-area: block-end span-inline-end;\n position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;\n margin-block-start: 2px;\n\n min-width: 10ch;\n max-width: min(40ch, 80vw);\n max-height: 280px;\n overflow-y: auto;\n padding: var(--padding-s);\n outline: none;\n }\n\n .crumb-option {\n display: flex;\n align-items: center;\n gap: var(--padding-s);\n padding: var(--padding-s) var(--padding-m);\n cursor: pointer;\n border-radius: var(--radius-s, 4px);\n transition: background 0.15s ease-out;\n overflow: hidden;\n }\n\n .crumb-option:hover,\n .crumb-option.active {\n background: var(--hover-bg);\n color: var(--hover-fg);\n }\n\n .option-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .crumb-option-label {\n font-style: italic;\n opacity: 0.6;\n pointer-events: none;\n user-select: none;\n }\n\n .loading-spinner {\n display: inline-block;\n width: 12px;\n height: 12px;\n border: 2px solid var(--surface-5);\n border-top-color: var(--accent);\n border-radius: 50%;\n animation: crumb-spin 0.7s linear infinite;\n }\n\n @keyframes crumb-spin {\n to { transform: rotate(360deg); }\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-crumb-path': CrumbPathElement;\n }\n}\n\nexport interface CrumbPathElementEventMap {\n \"navigate\": CrumbNavNavigateEvent;\n \"change\": CrumbNavChangeEvent;\n \"expand\": CrumbNavExpandEvent;\n 'crumb-drag-start': CrumbDragStartEvent;\n 'crumb-drop': CrumbDropEvent;\n}\n\nexport interface CrumbPathElement {\n addEventListener: (<K extends keyof CrumbPathElementEventMap>(\n type: K,\n listener: (this: CrumbPathElement, event: CrumbPathElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { PropertyValues, TemplateResult } from 'lit';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { TickledController, tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { popupSurfaceStyles } from '../styles/popup.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type DataTableRow = {\n label: string;\n value: string | number | boolean | Node | TemplateResult;\n fullWidth?: boolean;\n detail?: string | TemplateResult;\n id?: string;\n};\n\nexport type DataTableRowClickDetail = {\n readonly row: DataTableRow;\n readonly index: number;\n readonly selected: boolean;\n};\n\nexport type DataTableRowClickEvent = CustomEvent<DataTableRowClickDetail>;\n\nexport interface DataTableElementEventMap {\n 'data-table-row-click': DataTableRowClickEvent;\n}\n\n@customElement(`ixfx-data-table`)\nexport class DataTableElement extends LitElement {\n static override styles = [\n tickledStyles,\n tickledItemStyles,\n popupSurfaceStyles,\n css`\n :host {\n display: block;\n container-type: inline-size;\n }\n\n .properties {\n display: grid;\n grid-template-columns: var(--data-table-name-width, max-content)\n var(--data-table-value-width, minmax(0, 1fr));\n /* No column gap: the tickled highlight reads as one solid block.\n Separation comes from cell padding, which the highlight covers. */\n gap: 2px 0;\n }\n\n /* Widening: 2 then 3 property-pairs per row on roomy containers.\n Suppressed when stacked, or when locked to 'columns'. */\n @container (min-width: 650px) {\n :host(:not([layout='columns'])) .properties:not(.stacked) {\n grid-template-columns:\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr))\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr));\n }\n }\n\n @container (min-width: 1000px) {\n :host(:not([layout='columns'])) .properties:not(.stacked) {\n grid-template-columns:\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr))\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr))\n var(--data-table-name-width, max-content) var(--data-table-value-width, minmax(0, 1fr));\n }\n }\n\n /* Stacked (key above value). Threshold is JS-driven via 'narrowBreakpoint'.\n minmax(0, 1fr) — not 1fr — so a long value's min-content size can't\n blow the column out past the container; the value then ellipsises. */\n .properties.stacked {\n grid-template-columns: minmax(0, 1fr);\n }\n\n /* A pair is its own subgrid so the whole row is one element:\n the tickled highlight can't split, and key/value share a baseline. */\n .pair {\n display: grid;\n grid-column: span 2;\n grid-template-columns: subgrid;\n align-items: var(--data-table-cell-align, baseline);\n cursor: pointer;\n }\n\n .pair[data-full] {\n grid-column: 1 / -1;\n }\n\n .pair[data-full] > .value {\n grid-column: 2 / -1;\n }\n\n .properties.stacked .pair {\n display: block;\n grid-column: 1 / -1;\n /* Let the block shrink below its content so .value-text can clip. */\n min-width: 0;\n }\n\n .properties.stacked .pair:not(:last-child) {\n margin-bottom: var(--space-s);\n }\n\n /* Stacked keys get their own line, so a long label must wrap rather than\n run off the edge (nowrap is only wanted for the max-content column). */\n .properties.stacked .key {\n white-space: normal;\n overflow-wrap: break-word;\n }\n\n .key,\n .value {\n min-width: 0;\n /* Row rhythm comes from this padding (tunable), not line-height. */\n padding: var(--data-table-row-padding, 0.35em) 0;\n }\n\n .key {\n padding-right: var(--space-m);\n opacity: 0.6;\n white-space: nowrap;\n text-align: var(--data-table-name-align, left);\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n /* Uppercase keys have no descenders, so both edges can be trimmed to\n the glyphs for tight baseline / centre alignment. */\n text-box: trim-both cap alphabetic;\n }\n\n .value {\n position: relative;\n padding-right: var(--space-l);\n font: 12px ui-monospace, SFMono-Regular, Menlo, monospace;\n }\n\n /* The value text is clipped here — never on .value itself — so a long\n value stays within its cell even while tickled, and the detail\n popover (a child of .value) can still escape the cell. */\n .value-text {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n /* No text-box trim here: the natural line box gives descenders the room\n overflow:hidden would otherwise clip. Baseline alignment of key and\n value comes from align-items on .pair, which needs no trimming. */\n }\n\n .pair.tickled {\n background: var(--item-bg-tickled, color-mix(in oklch, var(--surface-2), var(--accent) 10%));\n }\n\n /* Lift the row whose detail is open above the rows it slides over. */\n .pair.show-detail {\n position: relative;\n z-index: 1;\n }\n\n .detail {\n position: absolute;\n z-index: 2;\n /* Flush with the bottom of the value (no gap) so the pointer can travel\n from value to panel without crossing a dead zone that would dismiss it.\n Left-aligned with the value; only as wide as its content, capped at\n the table width. */\n top: 100%;\n left: 0;\n right: auto;\n width: max-content;\n max-width: 100cqi;\n padding: var(--space-xs);\n visibility: hidden;\n transform: translateY(-4px);\n pointer-events: none;\n transition: transform var(--transition);\n }\n\n .pair.show-detail .detail {\n visibility: visible;\n transform: translateY(0);\n pointer-events: auto;\n }\n `,\n ];\n\n @property({ type: Array, attribute: false })\n rows: readonly DataTableRow[] = [];\n\n @property({ type: Number, attribute: false })\n selectedIndex: number | undefined;\n\n /**\n * How long (ms) the pointer must rest on a hovered row before its detail\n * panel is revealed. The tickled highlight itself appears immediately on\n * hover; only the detail panel is debounced. Clicking a row reveals its\n * detail straight away, ignoring this delay.\n */\n @property({ type: Number, attribute: `tickle-delay` })\n tickleDelay = 400;\n\n /**\n * Table layout.\n * - `auto` (default): responsive — widens to multiple pair-columns on wide\n * containers, and stacks key above value once narrower than\n * {@link narrowBreakpoint}.\n * - `rows`: always stacked (key above value), regardless of width.\n * - `columns`: always a two-column key/value grid, regardless of width.\n */\n @property({ type: String, reflect: true })\n layout: `auto` | `rows` | `columns` = `auto`;\n\n /**\n * Inline width (px) at or below which the `auto` layout switches to its\n * stacked, key-above-value form. Ignored when {@link layout} is locked.\n */\n @property({ type: Number, attribute: `narrow-breakpoint` })\n narrowBreakpoint = 420;\n\n @state()\n private _tickled = new TickledController<number>(this, {\n getItems: () => this.rows.map((_, i) => ({ id: i, enabled: true })),\n });\n\n /** Index of the row whose detail panel is currently revealed, if any. */\n @state()\n private _detailIndex: number | undefined;\n\n /** Whether the table is currently rendering in its stacked form. */\n @state()\n private _stacked = false;\n\n #detailTimer: ReturnType<typeof setTimeout> | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #lastWidth = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#resizeObserver = new ResizeObserver((entries) => {\n const entry = entries[0];\n if (!entry)\n return;\n this.#lastWidth = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;\n this.#updateStacked();\n });\n this.#resizeObserver.observe(this);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n clearTimeout(this.#detailTimer);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n }\n\n override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has(`layout`) || changed.has(`narrowBreakpoint`)) {\n this.#updateStacked();\n }\n }\n\n #updateStacked(): void {\n const stacked = this.layout === `rows`\n ? true\n : this.layout === `columns`\n ? false\n : this.#lastWidth > 0 && this.#lastWidth <= this.narrowBreakpoint;\n if (stacked !== this._stacked)\n this._stacked = stacked;\n }\n\n #handlePointerEnter(i: number): void {\n // Tickle straight away, exactly as a click would.\n this._tickled.handlePointerEnter(i);\n // But hold the detail panel back until the pointer has rested a while.\n clearTimeout(this.#detailTimer);\n if (this._detailIndex !== undefined)\n this._detailIndex = undefined;\n this.#detailTimer = setTimeout(() => {\n if (this._tickled.isTickled(i))\n this._detailIndex = i;\n }, this.tickleDelay);\n }\n\n #handlePointerLeave(e: PointerEvent): void {\n clearTimeout(this.#detailTimer);\n this._detailIndex = undefined;\n this._tickled.handlePointerLeave(e);\n }\n\n #select(i: number): void {\n clearTimeout(this.#detailTimer);\n this.selectedIndex = this.selectedIndex === i ? undefined : i;\n this._tickled.setTickled(i);\n // A click reveals the detail immediately, no debounce.\n this._detailIndex = i;\n this.dispatchEvent(\n new CustomEvent<DataTableRowClickDetail>(`data-table-row-click`, {\n bubbles: true,\n composed: true,\n detail: {\n row: this.rows[i]!,\n index: i,\n selected: this.selectedIndex === i,\n },\n }),\n );\n }\n\n override render(): ReturnType<typeof html> {\n return html`<div\n class=\"properties ${this._stacked ? `stacked` : ``}\"\n @pointerleave=${(e: PointerEvent) => this.#handlePointerLeave(e)}\n >\n ${this.rows.map(\n (r, i) => html`<div\n class=\"pair ${this._tickled.isTickled(i) ? `tickled` : ``} ${\n this._detailIndex === i ? `show-detail` : ``\n }\"\n ?data-full=${r.fullWidth}\n @pointerenter=${() => this.#handlePointerEnter(i)}\n @click=${() => this.#select(i)}\n ><div class=\"key\">${r.label}</div><div class=\"value\"><span class=\"value-text\">${\n typeof r.value === `boolean`\n ? r.value\n ? `Yes`\n : `No`\n : r.value\n }</span>${r.detail === undefined ? nothing : html`<div class=\"detail popup-surface\" part=\"detail\">${r.detail}</div>`}</div></div>`,\n )}</div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-data-table': DataTableElement;\n }\n}\n\nexport interface DataTableElement {\n addEventListener<K extends keyof DataTableElementEventMap>(\n type: K,\n listener: (\n this: DataTableElement,\n event: DataTableElementEventMap[K],\n ) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n","import type { DragGhost } from '../util/drag-ghost.js';\nimport type { DockHostElement } from './dock-host.js';\nimport type { DockDragBoundaryDetail, DockOperation, DockPanelTearOutDetail } from './types.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\n\nexport interface Rect {\n readonly x: number;\n readonly y: number;\n readonly w: number;\n readonly h: number;\n}\n\nexport interface DockDropZone {\n /** Host whose model would receive the drop. */\n readonly host: DockHostElement;\n readonly operation: DockOperation;\n /** Path of the target stack (`[]` = the host root). */\n readonly targetPath: number[];\n readonly side: `before` | `after`;\n /** Insert position for `tabs` drops (panel index in the target stack). */\n readonly gapIndex?: number;\n /** Highlight rect, relative to the host. */\n readonly rect: Rect;\n /** Optional insertion caret for strip gaps, relative to the host. */\n readonly caretRect?: Rect;\n}\n\ninterface DragState {\n panelId: string;\n /** Content kind at drag start — target hosts vet leaf rules without element access. */\n kind?: string;\n sourceHost: DockHostElement;\n pointerId: number;\n ghost: DragGhost | null;\n /** True while the pointer is outside every registered host (tear-out zone). */\n outside: boolean;\n}\n\nlet activeDrag: DragState | null = null;\nconst dragHosts: Set<DockHostElement> = new Set();\n\nexport function registerDockHost(host: DockHostElement): void {\n dragHosts.add(host);\n}\n\nexport function unregisterDockHost(host: DockHostElement): void {\n dragHosts.delete(host);\n if (activeDrag !== null && activeDrag.sourceHost === host) {\n abortDrag();\n }\n}\n\n/**\n * Begin a dock-panel drag. Called by hosts in response to their own\n * `dock-panel-drag-start` events (titlebar or tab-item handles).\n */\nexport function startDrag(\n panelId: string,\n sourceHost: DockHostElement,\n pointerId: number,\n clientX: number,\n clientY: number,\n kind?: string,\n): void {\n if (activeDrag !== null) {\n abortDrag();\n }\n\n const ghost = createGhostForPanel(sourceHost, panelId);\n activeDrag = { panelId, kind, sourceHost, pointerId, ghost, outside: false };\n\n for (const host of dragHosts) {\n host.setDragActive(true);\n }\n\n activeDrag.ghost?.move(clientX, clientY);\n\n window.addEventListener(`pointermove`, onPointerMove);\n window.addEventListener(`pointerup`, onPointerUp);\n window.addEventListener(`pointercancel`, onPointerCancel);\n window.addEventListener(`keydown`, onKeyDown);\n}\n\nfunction createGhostForPanel(host: DockHostElement, panelId: string): DragGhost | null {\n const panel = Array.from(host.children).find(\n (el): el is HTMLElement & { panelId: string; title: string; iconName: string } =>\n el instanceof HTMLElement && (el as { panelId?: string }).panelId === panelId,\n );\n if (!panel)\n return null;\n\n const content = document.createElement(`span`);\n content.style.display = `inline-flex`;\n content.style.alignItems = `center`;\n content.style.gap = `var(--space-xs, 4px)`;\n content.style.minWidth = `0`;\n\n if (panel.iconName) {\n const icon = document.createElement(`ixfx-icon`) as HTMLElement & { name: string };\n icon.name = panel.iconName;\n content.appendChild(icon);\n }\n\n const label = document.createElement(`span`);\n label.textContent = panel.title || panelId;\n label.style.overflow = `hidden`;\n label.style.textOverflow = `ellipsis`;\n label.style.whiteSpace = `nowrap`;\n content.appendChild(label);\n\n try {\n return createDragGhost({ anchor: panel, content });\n } catch {\n return null;\n }\n}\n\nfunction onPointerMove(event: PointerEvent): void {\n const drag = activeDrag;\n if (drag === null || event.pointerId !== drag.pointerId)\n return;\n\n drag.ghost?.move(event.clientX, event.clientY);\n\n const zone = findDropZone(drag, event.clientX, event.clientY);\n for (const host of dragHosts) {\n host.setDropZone(zone !== null && zone.host === host ? zone : null);\n }\n\n // Boundary crossings — the app uses these to start / stop a native window\n // drag when a panel is pulled out past every host.\n const outside = !pointerOverAnyHost(event.clientX, event.clientY);\n if (outside !== drag.outside) {\n drag.outside = outside;\n dispatchBoundary(drag, outside ? `dock-panel-drag-out` : `dock-panel-drag-in`, event);\n }\n}\n\nfunction onPointerUp(event: PointerEvent): void {\n const drag = activeDrag;\n if (drag === null || event.pointerId !== drag.pointerId)\n return;\n\n const zone = findDropZone(drag, event.clientX, event.clientY);\n if (zone !== null) {\n zone.host.handleDrop(drag.panelId, zone, drag.sourceHost);\n } else {\n // Released with no valid zone. If the pointer is outside every host this\n // is a tear-out request: hand the app a snapshot + screen coordinates so\n // it can open a new window and recreate the panel there. The panel is\n // left untouched in the source host — the app calls `detachPanel()` (or\n // `removePanel()`) once it has taken ownership.\n if (!pointerOverAnyHost(event.clientX, event.clientY)) {\n dispatchTearOut(drag, event);\n }\n }\n endDrag();\n}\n\nfunction onPointerCancel(event: PointerEvent): void {\n const drag = activeDrag;\n if (drag === null || event.pointerId !== drag.pointerId)\n return;\n abortDrag();\n endDrag();\n}\n\nfunction onKeyDown(event: KeyboardEvent): void {\n if (activeDrag === null)\n return;\n if (event.key !== `Escape`)\n return;\n abortDrag();\n endDrag();\n}\n\nfunction findDropZone(drag: DragState, clientX: number, clientY: number): DockDropZone | null {\n const sourceIsolated = drag.sourceHost.isolated;\n\n for (const host of dragHosts) {\n if (sourceIsolated && host !== drag.sourceHost)\n continue;\n\n const zone = host.computeDropZone(clientX, clientY, drag.panelId, drag.kind);\n if (zone !== null)\n return zone;\n }\n return null;\n}\n\n/** True when the point lies within the bounding box of any registered host. */\nexport function pointerOverAnyHost(clientX: number, clientY: number): boolean {\n for (const host of dragHosts) {\n const r = host.getBoundingClientRect();\n if (clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom)\n return true;\n }\n return false;\n}\n\nfunction dispatchBoundary(drag: DragState, type: string, event: PointerEvent): void {\n drag.sourceHost.dispatchEvent(new CustomEvent<DockDragBoundaryDetail>(type, {\n detail: {\n panelId: drag.panelId,\n clientX: event.clientX,\n clientY: event.clientY,\n screenX: event.screenX,\n screenY: event.screenY,\n },\n bubbles: true,\n composed: true,\n }));\n}\n\nfunction dispatchTearOut(drag: DragState, event: PointerEvent): void {\n const snapshot = drag.sourceHost.getPanelSnapshot(drag.panelId);\n if (snapshot === null)\n return;\n drag.sourceHost.dispatchEvent(new CustomEvent<DockPanelTearOutDetail>(`dock-panel-tear-out`, {\n detail: {\n panelId: drag.panelId,\n snapshot,\n clientX: event.clientX,\n clientY: event.clientY,\n screenX: event.screenX,\n screenY: event.screenY,\n },\n bubbles: true,\n composed: true,\n }));\n}\n\n/** Drop cancelled — no model mutation. */\nfunction abortDrag(): void {\n // Zone clearing happens in endDrag; nothing else to undo.\n}\n\nfunction endDrag(): void {\n const drag = activeDrag;\n if (drag === null)\n return;\n\n for (const host of dragHosts) {\n host.setDropZone(null);\n host.setDragActive(false);\n }\n\n drag.ghost?.destroy();\n activeDrag = null;\n\n window.removeEventListener(`pointermove`, onPointerMove);\n window.removeEventListener(`pointerup`, onPointerUp);\n window.removeEventListener(`pointercancel`, onPointerCancel);\n window.removeEventListener(`keydown`, onKeyDown);\n}\n\nexport function isDragging(): boolean {\n return activeDrag !== null;\n}\n\nexport function getActiveDragPanelId(): string | null {\n return activeDrag?.panelId ?? null;\n}\n","import type {\n DockAxis,\n DockDirection,\n DockEdge,\n DockLayout,\n DockLeafInfo,\n DockLeafRef,\n DockNeighbours,\n DockNode,\n DockSplitNode,\n DockStackNode,\n} from './types.js';\n\nexport type {\n DockAxis,\n DockDirection,\n DockEdge,\n DockLayout,\n DockLeafInfo,\n DockLeafRef,\n DockNeighbours,\n DockNode,\n DockSplitNode,\n DockStackNode,\n};\n\n/**\n * The dock model is a plain mutable tree owned exclusively by the host\n * element. Mutators below change the tree in place; the host calls\n * `normalize(root)` then `requestUpdate()` after batching mutations.\n */\nexport function isSplit(node: DockNode): node is DockSplitNode {\n return node.kind === `split`;\n}\n\nexport function isStack(node: DockNode): node is DockStackNode {\n return node.kind === `stack`;\n}\n\nexport function createEmptyStack(): DockStackNode {\n return { kind: `stack`, panels: [], active: `` };\n}\n\nexport function createEmptyLayout(): DockLayout {\n return { version: 1, root: createEmptyStack() };\n}\n\nexport function createStack(panels: string[], active?: string, name?: string): DockStackNode {\n const stack: DockStackNode = {\n kind: `stack`,\n panels: [...panels],\n active: active ?? panels[0] ?? ``,\n };\n const trimmed = name?.trim();\n if (trimmed) {\n stack.name = trimmed;\n }\n return stack;\n}\n\nexport function createSplit(direction: DockAxis, children: DockNode[], sizes?: number[]): DockSplitNode {\n const mean = children.length > 0 ? 1 / children.length : 1;\n return {\n kind: `split`,\n direction,\n children: [...children],\n sizes: sizes ? [...sizes] : children.map(() => mean),\n };\n}\n\n// ── Normalize ────────────────────────────────────────────────────────────────\n\n/**\n * Runs after every mutation:\n * - stack `active` fixed to a member of `panels` (or `''` when empty)\n * - empty *unnamed* stacks removed from their parent split (and their\n * `sizes` entry); named empty stacks are kept so the name stays addressable\n * - splits with ≤1 child replaced by that child (spliced into the parent)\n * - a child split whose direction equals its parent's is flattened into it,\n * spreading its sizes across the slot it vacated\n * - `sizes` kept parallel to `children` (padded with the mean weight)\n * - an empty root collapses to a single empty stack\n */\nexport function normalize(root: DockNode): DockNode {\n if (isStack(root)) {\n sanitizeStackName(root);\n if (!root.panels.includes(root.active)) {\n root.active = root.panels[0] ?? ``;\n }\n return root;\n }\n\n // Depth-first: normalize children, then flatten/carry-up at this level.\n for (let i = root.children.length - 1; i >= 0; i--) {\n normalize(root.children[i]);\n\n const child = root.children[i];\n\n // Drop empty stacks, unless named (names stay addressable)\n if (isStack(child) && child.panels.length === 0 && !child.name) {\n root.children.splice(i, 1);\n root.sizes.splice(i, 1);\n continue;\n }\n\n // Carry single-child splits up\n if (isSplit(child) && child.children.length === 1) {\n root.children.splice(i, 1, child.children[0]);\n root.sizes.splice(i, 1, child.sizes[0] ?? root.sizes[i] ?? 1);\n }\n }\n\n // Flatten same-direction child splits into this one\n for (let i = root.children.length - 1; i >= 0; i--) {\n const child = root.children[i];\n if (isSplit(child) && child.direction === root.direction) {\n root.children.splice(i, 1, ...child.children);\n root.sizes.splice(i, 1, ...child.sizes);\n }\n }\n\n // A split with ≤1 child dissolves\n if (root.children.length === 0) {\n return replaceNodeContents(root, createEmptyStack());\n }\n if (root.children.length === 1) {\n return root.children[0];\n }\n\n // Keep sizes parallel to children\n while (root.sizes.length < root.children.length) {\n root.sizes.push(1 / root.children.length);\n }\n if (root.sizes.length > root.children.length) {\n root.sizes.length = root.children.length;\n }\n\n return root;\n}\n\n/**\n * Turn `target` (a stack or split node object) into the shape of `source`'s\n * kind, used when the root itself must dissolve. Mutates `target` in place so\n * the host's root reference stays valid.\n */\nfunction replaceNodeContents(target: DockNode, source: DockNode): DockNode {\n if (isStack(source)) {\n target.kind = `stack`;\n const t = target as DockStackNode;\n t.panels = source.panels;\n t.active = source.active;\n if (source.name !== undefined) {\n t.name = source.name;\n } else {\n delete t.name;\n }\n if (source.hideLabels !== undefined) {\n t.hideLabels = source.hideLabels;\n } else {\n delete t.hideLabels;\n }\n delete t.collapsed;\n delete t.preCollapseSize;\n if (source.collapsed !== undefined)\n t.collapsed = source.collapsed;\n if (source.preCollapseSize !== undefined)\n t.preCollapseSize = source.preCollapseSize;\n } else {\n target.kind = `split`;\n const t = target as DockSplitNode;\n t.direction = source.direction;\n t.children = source.children;\n t.sizes = source.sizes;\n // Drop stale stack-only fields when morphing stack → split\n const stale = t as unknown as Record<string, unknown>;\n delete stale.panels;\n delete stale.active;\n delete stale.name;\n delete stale.collapsed;\n delete stale.preCollapseSize;\n }\n return target;\n}\n\n/** Trim `name`; drop it when empty / non-string so lookups stay predictable. */\nfunction sanitizeStackName(stack: DockStackNode): void {\n if (stack.name === undefined)\n return;\n const trimmed = typeof stack.name === `string` ? stack.name.trim() : ``;\n if (trimmed) {\n stack.name = trimmed;\n } else {\n delete stack.name;\n }\n}\n\n// ── Lookup ───────────────────────────────────────────────────────────────────\n\nexport function findNode(root: DockNode, path: number[]): DockNode | null {\n let current: DockNode = root;\n for (const index of path) {\n if (!isSplit(current))\n return null;\n const next = current.children[index];\n if (!next)\n return null;\n current = next;\n }\n return current;\n}\n\n/** Parent split of the node at `path`; null when path is empty or malformed. */\nexport function findParentOf(root: DockNode, path: number[]): DockSplitNode | null {\n if (path.length === 0)\n return null;\n const parent = findNode(root, path.slice(0, -1));\n return parent !== null && isSplit(parent) ? parent : null;\n}\n\n/** Path of the stack containing `panelId`, or null. */\nexport function findStackOf(root: DockNode, panelId: string): number[] | null {\n return findStackOfInner(root, panelId, []);\n}\n\nfunction findStackOfInner(node: DockNode, panelId: string, path: number[]): number[] | null {\n if (isStack(node)) {\n return node.panels.includes(panelId) ? path : null;\n }\n for (let i = 0; i < node.children.length; i++) {\n const found = findStackOfInner(node.children[i], panelId, [...path, i]);\n if (found !== null)\n return found;\n }\n return null;\n}\n\nexport function collectPanelIds(root: DockNode): string[] {\n if (isStack(root)) {\n return [...root.panels];\n }\n return root.children.flatMap(collectPanelIds);\n}\n\n/**\n * Path of the first stack (tree order) whose `name` matches, or null.\n * Names are expected to be unique per layout; duplicates resolve first-wins.\n */\nexport function findStackPathByName(root: DockNode, name: string): number[] | null {\n const wanted = name.trim();\n if (!wanted)\n return null;\n return findStackPathByNameInner(root, wanted, []);\n}\n\nfunction findStackPathByNameInner(node: DockNode, name: string, path: number[]): number[] | null {\n if (isStack(node)) {\n return node.name === name ? path : null;\n }\n for (let i = 0; i < node.children.length; i++) {\n const found = findStackPathByNameInner(node.children[i], name, [...path, i]);\n if (found !== null)\n return found;\n }\n return null;\n}\n\n/** Names of every named stack leaf, in tree order. */\nexport function collectContainerNames(root: DockNode): string[] {\n const out: string[] = [];\n const visit = (node: DockNode): void => {\n if (isStack(node)) {\n if (node.name)\n out.push(node.name);\n return;\n }\n node.children.forEach(visit);\n };\n visit(root);\n return out;\n}\n\n/**\n * Paths of every stack leaf, in tree order. `[]` is the root itself when it\n * is a stack.\n */\nexport function collectStackPaths(root: DockNode): number[][] {\n const result: number[][] = [];\n collectStackPathsInner(root, [], result);\n return result;\n}\n\nfunction collectStackPathsInner(node: DockNode, path: number[], out: number[][]): void {\n if (isStack(node)) {\n out.push(path);\n return;\n }\n node.children.forEach((child, i) => collectStackPathsInner(child, [...path, i], out));\n}\n\n// ── Mutations (in place; run `normalize` afterwards) ─────────────────────────\n\nexport function addPanelToStack(stack: DockStackNode, panelId: string, index?: number): void {\n const at = index === undefined ? stack.panels.length : Math.max(0, Math.min(index, stack.panels.length));\n stack.panels.splice(at, 0, panelId);\n stack.active = panelId;\n}\n\nexport function removePanelFromStack(stack: DockStackNode, panelId: string): void {\n const index = stack.panels.indexOf(panelId);\n if (index < 0)\n return;\n stack.panels.splice(index, 1);\n if (stack.active === panelId) {\n stack.active = stack.panels[Math.min(index, stack.panels.length - 1)] ?? ``;\n }\n}\n\nexport function setActive(stack: DockStackNode, panelId: string): boolean {\n if (!stack.panels.includes(panelId) || stack.active === panelId)\n return false;\n stack.active = panelId;\n return true;\n}\n\n/**\n * Insert `node` beside the child at `targetPath`, into the parent split when\n * its direction matches `direction`, otherwise wrap the target in a new split.\n * `side` selects before/after; the neighbour's weight is split 50/50.\n * Returns the path of the inserted node, or null.\n */\nexport function insertBeside(\n root: DockNode,\n targetPath: number[],\n direction: DockAxis,\n newNode: DockNode,\n side: `before` | `after`,\n): number[] | null {\n const target = findNode(root, targetPath);\n if (target === null)\n return null;\n\n // Root-level: insert at the edge if the root already matches, else wrap\n if (targetPath.length === 0) {\n if (isSplit(root) && root.direction === direction) {\n const edgeIndex = side === `before` ? 0 : root.children.length;\n const neighbourIndex = side === `before` ? 0 : root.children.length - 1;\n const neighbour = root.sizes[neighbourIndex];\n root.children.splice(edgeIndex, 0, newNode);\n root.sizes.splice(edgeIndex, 0, neighbour !== undefined ? neighbour / 2 : 1);\n if (neighbour !== undefined) {\n root.sizes[side === `before` ? neighbourIndex + 1 : neighbourIndex] = neighbour / 2;\n }\n return [edgeIndex];\n }\n wrapRoot(root, direction, newNode, side);\n return [side === `before` ? 0 : 1];\n }\n\n const parent = findParentOf(root, targetPath);\n if (parent === null)\n return null;\n\n const index = targetPath[targetPath.length - 1];\n\n if (parent.direction === direction) {\n const insertAt = side === `before` ? index : index + 1;\n const w = parent.sizes[index] !== undefined ? parent.sizes[index] / 2 : 1;\n parent.sizes[index] = w;\n parent.children.splice(insertAt, 0, newNode);\n parent.sizes.splice(insertAt, 0, w);\n const childPath = [...targetPath.slice(0, -1), insertAt];\n normalize(root);\n return childPath;\n }\n\n const wrapper = createSplit(direction, side === `before` ? [newNode, target] : [target, newNode]);\n parent.children[index] = wrapper;\n normalize(root);\n const childIndex = side === `before` ? 0 : 1;\n return [...targetPath.slice(0, -1), index, childIndex];\n}\n\n/**\n * Wrap the whole root in a new split of `direction`, replacing it in place so\n * the caller's reference stays valid. Returns true on success.\n */\nexport function wrapRoot(root: DockNode, direction: DockAxis, newNode: DockNode, side: `before` | `after`): boolean {\n // The wrapper's inner child must be a *copy* of the root's current contents,\n // not `root` itself: `replaceNodeContents` morphs `root` in place, so passing\n // the live reference would leave `root.children` holding `root` — a cycle that\n // makes `normalize` recurse until the stack overflows.\n const inner = cloneNodeShallow(root);\n const wrapper = createSplit(direction, side === `before` ? [newNode, inner] : [inner, newNode]);\n replaceNodeContents(root, wrapper);\n normalize(root);\n return true;\n}\n\n/**\n * Detached copy of `node` (own arrays copied) so it can become a child of a\n * wrapper that then replaces `node` in place.\n */\nfunction cloneNodeShallow(node: DockNode): DockNode {\n if (isStack(node)) {\n return { ...node, panels: [...node.panels] };\n }\n return { ...node, children: [...node.children], sizes: [...node.sizes] };\n}\n\n/**\n * Remove the stack at `stackPath` from the tree. Its panels are moved into\n * `fallbackStack` (if given and still attached) so they are not silently\n * lost; otherwise they are dropped from the model (elements return to the\n * pool). Returns the removed stack.\n */\nexport function extractStack(root: DockNode, stackPath: number[], fallbackStack?: DockStackNode): DockStackNode | null {\n const stack = findNode(root, stackPath);\n if (stack === null || !isStack(stack))\n return null;\n\n const isRoot = stackPath.length === 0;\n\n if (fallbackStack && fallbackStack !== stack) {\n for (const id of stack.panels) {\n addPanelToStack(fallbackStack, id);\n }\n // Only keep the panels in one place\n if (!isRoot) {\n stack.panels = [];\n stack.active = ``;\n }\n }\n\n if (isRoot) {\n replaceNodeContents(root, createEmptyStack());\n return stack;\n }\n\n const parent = findParentOf(root, stackPath);\n if (parent === null)\n return null;\n\n const index = stackPath[stackPath.length - 1];\n parent.children.splice(index, 1);\n parent.sizes.splice(index, 1);\n normalize(root);\n return stack;\n}\n\n// ── Spatial (geometry + leaf moves) ──────────────────────────────────────────\n//\n// Leaves are positioned by subdividing a unit square along each split\n// (child share = `sizes[i] / sum(sizes)`). Neighbour queries and moves below\n// are derived from that geometry, so they reflect what the user sees rather\n// than raw tree adjacency.\n\n/** Tolerance for edge-touch comparisons in unit-square geometry. */\nconst GEOM_EPS = 1e-9;\n\nexport interface DockRect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface LeafGeom {\n path: number[];\n name: string | null;\n rect: DockRect;\n}\n\nfunction pathsEqual(a: readonly number[], b: readonly number[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n}\n\n/**\n * Resolve a {@link DockLeafRef} to a stack path. Strings match container\n * `name` first-wins; arrays must index an existing stack leaf. Returns null\n * when unresolvable.\n */\nexport function resolveLeafPath(root: DockNode, ref: DockLeafRef): number[] | null {\n if (typeof ref === `string`) {\n return findStackPathByName(root, ref);\n }\n if (!Array.isArray(ref)) {\n return null;\n }\n let current: DockNode = root;\n for (const index of ref) {\n if (!Number.isInteger(index) || (index as number) < 0) {\n return null;\n }\n if (!isSplit(current)) {\n return null;\n }\n const next = current.children[index as number];\n if (!next) {\n return null;\n }\n current = next;\n }\n return isStack(current) ? [...ref] : null;\n}\n\n/** Absolute (unit-square) rect of every stack leaf, in tree order. */\nexport function computeLeafGeoms(root: DockNode): LeafGeom[] {\n const out: LeafGeom[] = [];\n const visit = (node: DockNode, path: number[], rect: DockRect): void => {\n if (isStack(node)) {\n out.push({ path, name: node.name ?? null, rect });\n return;\n }\n const total = node.sizes.reduce((sum, w) => sum + w, 0);\n const safe = total > 0 ? total : node.children.length || 1;\n let offset = 0;\n node.children.forEach((child, i) => {\n const frac = (node.sizes[i] ?? safe / node.children.length) / safe;\n if (node.direction === `row`) {\n const w = rect.w * frac;\n visit(child, [...path, i], { x: rect.x + offset, y: rect.y, w, h: rect.h });\n offset += w;\n } else {\n const h = rect.h * frac;\n visit(child, [...path, i], { x: rect.x, y: rect.y + offset, w: rect.w, h });\n offset += h;\n }\n });\n };\n visit(root, [], { x: 0, y: 0, w: 1, h: 1 });\n return out;\n}\n\nfunction intervalOverlap(a0: number, a1: number, b0: number, b1: number): number {\n return Math.min(a1, b1) - Math.max(a0, b0);\n}\n\n/**\n * Geometric neighbours of a leaf — what the user sees above / below / left /\n * right of it. Each list holds `{ name, path }` (name is null for unnamed\n * leaves), ordered most-overlapping first. Returns null when `ref` is\n * unresolvable.\n */\nexport function getLeafNeighbours(root: DockNode, ref: DockLeafRef): DockNeighbours | null {\n const path = resolveLeafPath(root, ref);\n if (path === null) {\n return null;\n }\n const geoms = computeLeafGeoms(root);\n const self = geoms.find(g => pathsEqual(g.path, path));\n if (!self) {\n return null;\n }\n const s = self.rect;\n type Hit = { info: DockLeafInfo; overlap: number; order: number };\n const above: Hit[] = [];\n const below: Hit[] = [];\n const left: Hit[] = [];\n const right: Hit[] = [];\n geoms.forEach((g, order) => {\n if (g === self) {\n return;\n }\n const r = g.rect;\n const info: DockLeafInfo = { name: g.name, path: [...g.path] };\n if (Math.abs(r.y + r.h - s.y) < GEOM_EPS) {\n const o = intervalOverlap(r.x, r.x + r.w, s.x, s.x + s.w);\n if (o > GEOM_EPS)\n above.push({ info, overlap: o, order });\n }\n if (Math.abs(s.y + s.h - r.y) < GEOM_EPS) {\n const o = intervalOverlap(r.x, r.x + r.w, s.x, s.x + s.w);\n if (o > GEOM_EPS)\n below.push({ info, overlap: o, order });\n }\n if (Math.abs(r.x + r.w - s.x) < GEOM_EPS) {\n const o = intervalOverlap(r.y, r.y + r.h, s.y, s.y + s.h);\n if (o > GEOM_EPS)\n left.push({ info, overlap: o, order });\n }\n if (Math.abs(s.x + s.w - r.x) < GEOM_EPS) {\n const o = intervalOverlap(r.y, r.y + r.h, s.y, s.y + s.h);\n if (o > GEOM_EPS)\n right.push({ info, overlap: o, order });\n }\n });\n const rank = (hits: Hit[]): DockLeafInfo[] =>\n hits.sort((a, b) => b.overlap - a.overlap || a.order - b.order).map(h => h.info);\n return { above: rank(above), below: rank(below), left: rank(left), right: rank(right) };\n}\n\n/**\n * Exchange two leaves' positions in the tree, each carrying its size slot so\n * the remaining structure and proportions are untouched. Returns false when\n * either path is not a stack leaf.\n */\nexport function swapLeaves(root: DockNode, pathA: number[], pathB: number[]): boolean {\n if (pathsEqual(pathA, pathB)) {\n return false;\n }\n const nodeA = findNode(root, pathA);\n const nodeB = findNode(root, pathB);\n if (nodeA === null || nodeB === null || !isStack(nodeA) || !isStack(nodeB)) {\n return false;\n }\n const parentA = findParentOf(root, pathA);\n const parentB = findParentOf(root, pathB);\n if (parentA === null || parentB === null) {\n return false;\n }\n const indexA = pathA[pathA.length - 1];\n const indexB = pathB[pathB.length - 1];\n if (parentA === parentB) {\n const p = parentA;\n [p.children[indexA], p.children[indexB]] = [p.children[indexB], p.children[indexA]];\n [p.sizes[indexA], p.sizes[indexB]] = [p.sizes[indexB] ?? 1, p.sizes[indexA] ?? 1];\n return true;\n }\n const carriedNode = parentA.children[indexA];\n const carriedSize = parentA.sizes[indexA] ?? 1;\n parentA.children[indexA] = parentB.children[indexB];\n parentA.sizes[indexA] = parentB.sizes[indexB] ?? 1;\n parentB.children[indexB] = carriedNode;\n parentB.sizes[indexB] = carriedSize;\n return true;\n}\n\n/**\n * Move a leaf one position in `direction`, swapping with the neighbour it\n * shares the longest edge with. Returns false when `ref` is unresolvable or\n * nothing adjoins in that direction. Run `normalize()` afterwards.\n */\nexport function moveLeafStep(root: DockNode, ref: DockLeafRef, direction: DockDirection): boolean {\n const path = resolveLeafPath(root, ref);\n if (path === null) {\n return false;\n }\n const neighbours = getLeafNeighbours(root, ref);\n if (neighbours === null) {\n return false;\n }\n const list = direction === `up`\n ? neighbours.above\n : direction === `down`\n ? neighbours.below\n : direction === `left`\n ? neighbours.left\n : neighbours.right;\n if (list.length === 0) {\n return false;\n }\n return swapLeaves(root, path, list[0].path);\n}\n\n/**\n * Move a leaf to an edge of the overall layout, keeping the rest of the\n * tree intact as a single subtree and preserving the leaf's absolute size\n * along the target axis. Returns false when `ref` is unresolvable or the\n * layout holds a single leaf. Run `normalize()` afterwards (also safe to\n * call it twice — the host's commit does).\n */\nexport function moveLeafNodeToEdge(root: DockNode, ref: DockLeafRef, edge: DockEdge): boolean {\n const path = resolveLeafPath(root, ref);\n if (path === null || path.length === 0) {\n return false;\n }\n const geoms = computeLeafGeoms(root);\n const self = geoms.find(g => pathsEqual(g.path, path));\n if (!self) {\n return false;\n }\n const horizontal = edge === `left` || edge === `right`;\n const frac = Math.min(Math.max(horizontal ? self.rect.w : self.rect.h, 0.05), 0.95);\n if (!(frac > 0) || frac >= 1) {\n return false;\n }\n\n const parent = findParentOf(root, path);\n if (parent === null) {\n return false;\n }\n const [node] = parent.children.splice(path[path.length - 1], 1);\n parent.sizes.splice(path[path.length - 1], 1);\n if (!node) {\n return false;\n }\n normalize(root);\n\n const atStart = edge === `left` || edge === `top`;\n const direction: DockAxis = horizontal ? `row` : `column`;\n\n if (isStack(root)) {\n // One leaf remains: wrap it so the moved leaf keeps its absolute share.\n const rest = root;\n const remaining: DockStackNode = { kind: `stack`, panels: [...rest.panels], active: rest.active };\n if (rest.name !== undefined)\n remaining.name = rest.name;\n if (rest.collapsed !== undefined)\n remaining.collapsed = rest.collapsed;\n if (rest.preCollapseSize !== undefined)\n remaining.preCollapseSize = rest.preCollapseSize;\n const wrapper: DockSplitNode = {\n kind: `split`,\n direction,\n children: atStart ? [node, remaining] : [remaining, node],\n sizes: atStart ? [frac, 1 - frac] : [1 - frac, frac],\n };\n replaceNodeContents(root, wrapper);\n return true;\n }\n\n if (isSplit(root) && root.direction === direction) {\n const sum = root.sizes.reduce((total, w) => total + w, 0) || root.children.length || 1;\n const size = frac * sum / (1 - frac);\n const at = atStart ? 0 : root.children.length;\n root.children.splice(at, 0, node);\n root.sizes.splice(at, 0, size);\n return true;\n }\n\n if (isSplit(root)) {\n // Other axis: nest the whole layout so its structure is untouched.\n const inner: DockSplitNode = { kind: `split`, direction: root.direction, children: root.children, sizes: root.sizes };\n const wrapper: DockSplitNode = {\n kind: `split`,\n direction,\n children: atStart ? [node, inner] : [inner, node],\n sizes: atStart ? [frac, 1 - frac] : [1 - frac, frac],\n };\n replaceNodeContents(root, wrapper);\n return true;\n }\n\n return false;\n}\n\n// ── Serialization ────────────────────────────────────────────────────────────\n\nexport function serializeLayout(root: DockNode): DockLayout {\n return {\n version: 1,\n root: serializeNode(root),\n };\n}\n\nfunction serializeNode(node: DockNode): DockNode {\n if (isStack(node)) {\n const out: DockStackNode = {\n kind: `stack`,\n panels: [...node.panels],\n active: node.active,\n };\n if (node.name !== undefined)\n out.name = node.name;\n if (node.hideLabels !== undefined)\n out.hideLabels = node.hideLabels;\n if (node.collapsed !== undefined)\n out.collapsed = node.collapsed;\n if (node.preCollapseSize !== undefined)\n out.preCollapseSize = node.preCollapseSize;\n return out;\n }\n return {\n kind: `split`,\n direction: node.direction,\n sizes: [...node.sizes],\n children: node.children.map(serializeNode),\n };\n}\n\n/**\n * Parse layout JSON, validate loosely, and normalize. Returns null when the\n * JSON is malformed or the root is missing/invalid.\n */\nexport function parseLayout(json: string): DockLayout | null {\n try {\n const parsed = JSON.parse(json) as DockLayout | null;\n if (parsed === null || typeof parsed !== `object`)\n return null;\n const root = (parsed as DockLayout).root;\n if (root === null || typeof root !== `object` || !(`kind` in root))\n return null;\n return { version: 1, root: normalize(root) };\n } catch {\n return null;\n }\n}\n","import type { CommandRegistry } from \"@clinth/ui-commands\";\nimport type { PropertyValues } from \"lit\";\nimport { css, html, LitElement, nothing } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport \"../icons/icon.js\";\n\n/**\n * CSS vars (can be overridden per-instance):\n * --selected-colour: text colour when selected\n * --selected-border-width: border width\n * --ixfx-tab-padding: vertical padding for the tab content (default: var(--space-m))\n * --ixfx-tab-padding-horizontal: horizontal padding (default: same as --ixfx-tab-padding)\n */\n@customElement(`ixfx-tab-list-item`)\nexport class TabListItemElement extends LitElement {\n @property({ type: Boolean })\n closeable = false;\n\n @property({ type: Boolean, attribute: `hide-labels` })\n hideLabels = false;\n\n /**\n * Label does not stretch to fill the tab (`flex: 0 0 auto` instead of\n * `1 1 auto`), so status content sits next to the label instead of being\n * pushed to the far edge. Set on the item, or on `ixfx-tab-list` which\n * mirrors it onto every item.\n */\n @property({ type: Boolean, attribute: `label-nogrow` })\n labelNogrow = false;\n\n @property({ type: String, attribute: `icon-name` })\n iconName: string | undefined = undefined;\n\n @property({ type: String })\n description: string | undefined = undefined;\n\n @property({ type: String, attribute: `command-active` })\n commandActive: string | undefined = undefined;\n\n @property({ attribute: false })\n registry: CommandRegistry<unknown> | undefined = undefined;\n\n @state() private _compact = false;\n @state() private _hasToolbarContent = false;\n @state() private _hasStatusContent = false;\n private _resizeObserver?: ResizeObserver;\n private _commandCleanup?: () => void;\n private _labelObserver: MutationObserver | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(([entry]) => {\n this._compact = entry.contentRect.width < 64;\n });\n this._resizeObserver.observe(this);\n this._wireSlotListeners();\n // In-place text edits (e.g. Lit re-rendering a title) don't fire\n // slotchange, so watch the light DOM too. Also covers status-slot\n // content added/removed before the slot itself is rendered.\n this._labelObserver = new MutationObserver(() => {\n this._syncLabelSizer();\n this._updateToolbarContent();\n this._updateStatusContent();\n });\n this._labelObserver.observe(this, {\n childList: true,\n characterData: true,\n subtree: true,\n attributes: true,\n attributeFilter: [`slot`],\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._resizeObserver?.disconnect();\n this._resizeObserver = undefined;\n this._commandCleanup?.();\n this._commandCleanup = undefined;\n this._labelObserver?.disconnect();\n this._labelObserver = null;\n this._unwireSlotListeners();\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._syncTooltipAttrs();\n if (changed.has(`registry`) || changed.has(`commandActive`)) {\n this._syncCommandListener();\n }\n }\n\n private _syncTooltipAttrs(): void {\n if (this.description) {\n this.setAttribute(`data-tooltip`, this.description);\n this.setAttribute(`data-tooltip-anchor`, `top`);\n } else {\n this.removeAttribute(`data-tooltip`);\n this.removeAttribute(`data-tooltip-anchor`);\n }\n }\n\n private _syncCommandListener(): void {\n this._commandCleanup?.();\n this._commandCleanup = undefined;\n if (this.registry && this.commandActive) {\n this._commandCleanup = this.registry.addOnInvokeHandler((id) => {\n if (id === this.commandActive)\n this.click();\n });\n }\n }\n\n private _onToolbarSlotChange = () => {\n this._updateToolbarContent();\n };\n\n private _onStatusSlotChange = () => {\n this._updateStatusContent();\n };\n\n private _onLabelSlotChange = () => {\n this._syncLabelSizer();\n };\n\n /**\n * Attach slotchange listeners. The shadow root is empty during the first\n * connectedCallback (the template only exists once rendered), so this is\n * called again from firstUpdated. addEventListener dedupes identical\n * listener registrations, so double-wiring is harmless.\n */\n private _wireSlotListeners(): void {\n const toolbarSlot = this.shadowRoot?.querySelector(`slot[name=\"toolbar\"]`);\n toolbarSlot?.addEventListener(`slotchange`, this._onToolbarSlotChange);\n const statusSlot = this.shadowRoot?.querySelector(`slot[name=\"status\"]`);\n statusSlot?.addEventListener(`slotchange`, this._onStatusSlotChange);\n const labelSlot = this.shadowRoot?.querySelector(`slot:not([name])`);\n labelSlot?.addEventListener(`slotchange`, this._onLabelSlotChange);\n }\n\n private _unwireSlotListeners(): void {\n const toolbarSlot = this.shadowRoot?.querySelector(`slot[name=\"toolbar\"]`);\n toolbarSlot?.removeEventListener(`slotchange`, this._onToolbarSlotChange);\n const statusSlot = this.shadowRoot?.querySelector(`slot[name=\"status\"]`);\n statusSlot?.removeEventListener(`slotchange`, this._onStatusSlotChange);\n const labelSlot = this.shadowRoot?.querySelector(`slot:not([name])`);\n labelSlot?.removeEventListener(`slotchange`, this._onLabelSlotChange);\n }\n\n /**\n * Mirror the default-slot text into `.label[data-label]` for the `::after`\n * width sizer. Slotted toolbar content is excluded.\n */\n private _syncLabelSizer(): void {\n const slot = this.shadowRoot?.querySelector(`slot:not([name])`) as HTMLSlotElement | null;\n const label = this.shadowRoot?.querySelector(`.label`);\n if (slot === null || slot === undefined || label === null || label === undefined) {\n return;\n }\n const text = slot.assignedNodes()\n .filter(node => !(node instanceof HTMLElement && node.hasAttribute(`slot`)))\n .map(node => node.textContent ?? ``)\n .join(``);\n if (text) {\n label.setAttribute(`data-label`, text);\n } else {\n label.removeAttribute(`data-label`);\n }\n }\n\n private _updateToolbarContent() {\n this._hasToolbarContent = Array.from(this.children).some(child => child.getAttribute(`slot`) === `toolbar`);\n }\n\n /**\n * Named slots only render once content has been detected, so reading\n * assignedElements() cannot bootstrap detection. Direct light-DOM children\n * are exactly what a slot assigns, so scan those instead.\n */\n private _updateStatusContent() {\n this._hasStatusContent = Array.from(this.children).some(child => child.getAttribute(`slot`) === `status`);\n }\n\n override firstUpdated() {\n this._wireSlotListeners();\n this._updateToolbarContent();\n this._updateStatusContent();\n this._syncLabelSizer();\n }\n\n override render() {\n const showLabel = !this.hideLabels || !this.iconName;\n const hasActions = this.closeable || this._hasToolbarContent;\n return html`\n <div>\n ${this.iconName ? html`<ixfx-icon name=\"${this.iconName}\"></ixfx-icon>` : nothing}\n ${showLabel ? html`<span class=\"label\"><slot></slot></span>` : nothing}\n ${this._hasStatusContent ? html`<div class=\"status\"><slot name=\"status\"></slot></div>` : nothing}\n ${hasActions\n ? html`\n <div class=\"actions\">\n <div class=\"toolbar\"><slot name=\"toolbar\"></slot></div>\n ${this.closeable\n ? html`\n <button\n class=\"close-btn\"\n type=\"button\"\n aria-label=\"Close tab\"\n @click=${this._onCloseClick}\n >\n <ixfx-icon name=\"close\"></ixfx-icon>\n </button>\n `\n : nothing}\n </div>\n `\n : nothing}\n </div>\n `;\n }\n\n private _onCloseClick(e: Event) {\n e.stopPropagation();\n this.dispatchEvent(\n new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }),\n );\n this.remove();\n }\n\n static override styles = [\n themeFallbacks,\n prominenceStyles,\n css`\n :host {\n --selected-tab-color: var(--ixfx-selected-tab-color, var(--surface-2-text));\n --selected-tab-icon-color: var(--ixfx-selected-tab-icon-color, var(--accent));\n --selected-tab-border-width: var(--ixfx-selected-tab-border-width, 1px);\n --selected-tab-weight: var(--ixfx-selected-tab-weight, bold);\n --selected-tab-text-decoration: var(--ixfx-selected-tab-text-decoration, none);\n --selected-tab-text-decoration-color: var(--ixfx-selected-tab-text-decoration-color, var(--accent));\n --selected-tab-text-decoration-thickness: var(--ixfx-selected-tab-text-decoration-thickness, 0px);\n --selected-tab-text-decoration-offset: var(--ixfx-selected-tab-text-decoration-offset, 2px);\n --selected-background: var(--ixfx-tab-selected-background, var(--surface-5));\n --tab-padding: var(--ixfx-tab-padding, var(--space-s));\n display: inline-flex;\n min-width: 0;\n user-select: none;\n box-sizing: border-box;\n font-size: var(--text-m);\n color: inherit;\n /* No explicit height: items stretch (align-self: stretch via the\n list's flex container) so every tab in a strip shares one height\n even when toolbars give some items taller content. */\n }\n\n :host > div {\n display: flex;\n align-items: center;\n padding: var(--tab-padding) calc(2 * var(--tab-padding-horizontal, var(--tab-padding)));\n min-width: 0;\n width: 100%;\n font-weight: 500;\n border: var(--selected-tab-border-width) solid transparent;\n gap: var(--space-s);\n transition: background var(--transition, 0.15s);\n }\n\n /* Hover (\"tickle\") background. When --ixfx-tab-hover-background is\n unset each state keeps its resting background, so existing\n consumers see no change. */\n :host(:hover:not([selected])) > div {\n background: var(--ixfx-tab-hover-background, transparent);\n }\n\n :host([selected]:hover) > div {\n background: var(--ixfx-tab-hover-background, var(--selected-background));\n }\n\n :host([selected]) > div {\n color: var(--selected-tab-color);\n border-top-color: var(--indicator-color-top, transparent);\n border-bottom-color: var(--indicator-color-bottom, transparent);\n border-left-color: var(--indicator-color-left, transparent);\n border-right-color: var(--indicator-color-right, transparent);\n background: var(--selected-background);\n font-weight: var(--selected-tab-weight);\n border-radius:var(--radius-m);\n }\n\n :host([selected]) .label {\n text-decoration: var(--selected-tab-text-decoration);\n text-decoration-color: var(--selected-tab-text-decoration-color);\n text-decoration-thickness: var(--selected-tab-text-decoration-thickness);\n text-decoration-offset: var(--selected-tab-text-decoration-offset);\n }\n\n .label {\n overflow: var(--allow-overflow, hidden);\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n flex: 1 1 auto;\n }\n\n /* Width sizer: an invisible copy of the label, always set at the\n selected weight, so activating a tab (bold) never shifts the strip.\n Text is mirrored from the default slot via the data-label attribute\n (see _syncLabelSizer). */\n .label::after {\n content: attr(data-label);\n display: block;\n height: 0;\n overflow: hidden;\n visibility: hidden;\n font-weight: var(--selected-tab-weight);\n }\n\n ixfx-icon {\n flex-shrink: 0;\n }\n\n /* Leading icon (direct child — not close/toolbar icons) picks up the\n accent when selected, so icon-only tabs read as active. */\n :host([selected]) > div > ixfx-icon {\n color: var(--selected-tab-icon-color);\n }\n\n .actions {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n margin-left: auto;\n flex-shrink: 0;\n }\n\n .toolbar {\n /* Always laid out (display: flex) so the tab's width doesn't shift when\n the toolbar appears on selection. visibility: hidden keeps the\n toolbar from receiving pointer events or painting, while preserving\n the space its contents take up. */\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n visibility: hidden;\n }\n\n :host([selected]) .toolbar {\n visibility: visible;\n }\n\n slot[name=\"toolbar\"] {\n display: contents;\n }\n\n /* Persistent status slot (e.g. an ixfx-led). Unlike .toolbar it is\n always visible, selection or not, and keeps its own size however\n much the label truncates. --size inherits through slotted content,\n so bare and button-wrapped LEDs both render smaller; consumers can\n override per element. */\n .status {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n --size: 0.75ex;\n }\n\n slot[name=\"status\"] {\n display: contents;\n }\n\n /* With label-nogrow, the label keeps its intrinsic width so status\n content lands next to the label text instead of the far edge. */\n :host([label-nogrow]) .label {\n flex: 0 0 auto;\n }\n\n /* Slotted buttons inherit these through the shadow boundary; keeps a\n toolbar button from inflating the strip height. */\n .toolbar ::slotted(ixfx-button) {\n --ixfx-button-padding-block: var(--space-xs);\n }\n\n .close-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: var(--space-xs);\n cursor: pointer;\n color: inherit;\n border-radius: var(--radius-s);\n opacity: var(--prominence-idle-opacity);\n transition: opacity var(--transition), background var(--transition);\n }\n\n .close-btn:hover {\n background: var(--surface-5);\n opacity: var(--prominence-tickled-opacity);\n }\n\n .close-btn:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 1px;\n }\n\n :host([selected]) .close-btn,\n :host(:hover) .close-btn {\n opacity: var(--prominence-tickled-opacity);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-tab-list-item\": TabListItemElement;\n }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { TitlebarCloseEvent, TitlebarToggleDetail, TitlebarToggleEvent } from '../titlebar/titlebar.js';\nimport type { DockPanelDragStartDetail, DockPanelDragStartEvent } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport '../titlebar/titlebar.js';\n\n/** Pointer movement threshold before a titlebar press becomes a dock drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\nexport type { DockPanelDragStartEvent };\n\nexport interface DockPanelElementEventMap {\n 'dock-panel-drag-start': DockPanelDragStartEvent;\n 'toggle': TitlebarToggleEvent;\n 'close': TitlebarCloseEvent;\n}\n\n/**\n * Leaf content + metadata + drag handle. Renders `ixfx-titlebar` chrome when\n * standalone (`presentation=\"solo\"`) and content only when docked\n * (`presentation=\"tabbed\"` — the host's tab strip carries the title chrome).\n * Adds `panel-id` and the titlebar drag handle. Works standalone outside a\n * host (the drag-start event has no listener and is inert).\n */\n@customElement(`ixfx-dock-panel`)\nexport class DockPanelElement extends LitElement {\n /** Stable identity: model key, slot name suffix, serialization id. */\n @property({ type: String, attribute: `panel-id`, reflect: true })\n panelId = ``;\n\n /**\n * Display text (tab label, titlebar). Stored in the `label` attribute —\n * deliberately not `title`, so browsers never tooltip it.\n */\n @property({ type: String, attribute: `label` })\n title = ``;\n\n @property({ type: String, attribute: `icon-name` })\n iconName = ``;\n\n @property({ type: Boolean })\n closable = false;\n\n @property({ type: Boolean })\n collapsible = false;\n\n /**\n * Content kind for the host's leaf placement rules\n * (`setLeafExclusiveContents` / `setLeafDenyContents`). Matched literally;\n * defaults to `'any'`.\n */\n @property({ type: String, reflect: true })\n kind = `any`;\n\n /**\n * Per-panel restriction when this panel is itself a drop target (solo\n * leaf). Space-separated `tabs` / `horizontal` / `vertical` / `all`;\n * `none` rejects everything; default is unrestricted.\n */\n @property({ type: String, attribute: `accepts` })\n accepts = ``;\n\n /**\n * Host-controlled. Docked panels are always `tabbed` (content only — the\n * leaf's tab strip carries the title chrome). `solo` (full titlebar chrome)\n * applies to panels outside a host or not currently docked.\n */\n @property({ type: String, reflect: true })\n presentation: `solo` | `tabbed` = `solo`;\n\n /** Solo-mode collapse state, mirrored from the titlebar. */\n @state()\n private _collapsed = false;\n\n private _dragPointerId: number | null = null;\n private _dragStartX = 0;\n private _dragStartY = 0;\n private _dragStarted = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Legacy alias: adopt a `title` attribute into the property, then drop\n // it — a lingering native `title` attribute would tooltip on hover.\n // (`title` is unobserved, so removal has no side effects.)\n if (this.hasAttribute(`title`)) {\n if (!this.hasAttribute(`label`)) {\n this.title = this.getAttribute(`title`) ?? ``;\n }\n this.removeAttribute(`title`);\n }\n this.addEventListener(`pointerdown`, this._onPointerDown as EventListener);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardownDragListeners();\n this.removeEventListener(`pointerdown`, this._onPointerDown as EventListener);\n }\n\n // ── Titlebar drag handle ─────────────────────────────────────────────────\n\n private _onPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0)\n return;\n if (this.presentation === `tabbed`)\n return; // tab items are the drag handle in tabbed mode (host-driven)\n if (!this._isDragHandle(event))\n return;\n\n this._dragPointerId = event.pointerId;\n this._dragStartX = event.clientX;\n this._dragStartY = event.clientY;\n this._dragStarted = false;\n\n window.addEventListener(`pointermove`, this._onPointerMove);\n window.addEventListener(`pointerup`, this._onPointerUp);\n window.addEventListener(`pointercancel`, this._onPointerUp);\n };\n\n private _onPointerMove = (event: PointerEvent): void => {\n if (this._dragPointerId === null || event.pointerId !== this._dragPointerId)\n return;\n\n if (!this._dragStarted) {\n const distance = Math.hypot(event.clientX - this._dragStartX, event.clientY - this._dragStartY);\n if (distance < DRAG_THRESHOLD_PX)\n return;\n this._dragStarted = true;\n const pointerId = this._dragPointerId;\n this._teardownDragListeners();\n this._dispatchDragStart(pointerId, event.clientX, event.clientY);\n }\n };\n\n private _onPointerUp = (event: PointerEvent): void => {\n if (this._dragPointerId === null || event.pointerId !== this._dragPointerId)\n return;\n this._teardownDragListeners();\n };\n\n private _teardownDragListeners(): void {\n this._dragPointerId = null;\n this._dragStarted = false;\n window.removeEventListener(`pointermove`, this._onPointerMove);\n window.removeEventListener(`pointerup`, this._onPointerUp);\n window.removeEventListener(`pointercancel`, this._onPointerUp);\n }\n\n /** Clicks that begin on the close / caret buttons or the toolbar are not drags. */\n private _isDragHandle(event: PointerEvent): boolean {\n for (const node of event.composedPath()) {\n if (!(node instanceof HTMLElement))\n continue;\n if (node.classList.contains(`close-btn`) || node.classList.contains(`caret-btn`) || node.classList.contains(`toolbar`)) {\n return false;\n }\n }\n return true;\n }\n\n private _dispatchDragStart(pointerId: number, clientX: number, clientY: number): void {\n if (!this.panelId)\n return;\n this.dispatchEvent(new CustomEvent<DockPanelDragStartDetail>(`dock-panel-drag-start`, {\n detail: {\n panelId: this.panelId,\n pointerId,\n clientX,\n clientY,\n },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ── Chrome event forwarding ──────────────────────────────────────────────\n\n private _onTitlebarToggle = (event: TitlebarToggleEvent): void => {\n event.stopPropagation();\n this._collapsed = event.detail.collapsed;\n this.dispatchEvent(new CustomEvent<TitlebarToggleDetail>(`toggle`, {\n detail: event.detail,\n bubbles: true,\n composed: true,\n }));\n };\n\n private _onTitlebarClose = (event: Event): void => {\n event.stopPropagation();\n this.dispatchEvent(new CustomEvent<void>(`close`, {\n bubbles: true,\n composed: true,\n }));\n // Mirror ixfx-panel's contract: a close removes the element. When docked,\n // the host's slotchange handler routes this through removePanel().\n this.remove();\n };\n\n protected override render() {\n const tabbed = this.presentation === `tabbed`;\n // Collapsed state only applies to solo chrome; docked leaves collapse at\n // the split-layout level, so ignore it there.\n const collapsed = !tabbed && this._collapsed;\n return html`\n ${tabbed\n ? nothing\n : html`\n <ixfx-titlebar\n .title=${this.title}\n .iconName=${this.iconName}\n .closable=${this.closable}\n .collapsible=${this.collapsible}\n .collapsed=${collapsed}\n .toggleInteraction=${this.collapsible ? `implicit` : `disabled`}\n @toggle=${this._onTitlebarToggle}\n @close=${this._onTitlebarClose}\n >\n <slot name=\"toolbar\" slot=\"toolbar\"></slot>\n </ixfx-titlebar>\n `}\n <div class=\"content\" ?collapsed=${collapsed}>\n <slot></slot>\n </div>\n `;\n }\n\n static override styles = [\n themeFallbacks,\n css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n\n ixfx-titlebar {\n flex-shrink: 0;\n }\n\n .content {\n flex: 1;\n min-height: 0;\n min-width: 0;\n overflow: hidden;\n }\n\n .content[collapsed] {\n display: none;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-dock-panel': DockPanelElement;\n }\n}\n\nexport interface DockPanelElement {\n addEventListener: (<K extends keyof DockPanelElementEventMap>(\n type: K,\n listener: (this: DockPanelElement, event: DockPanelElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { SplitLayoutElement } from '../split-layout/split-layout.js';\nimport type { TabListChangeEvent } from '../tabs/tab-list.js';\nimport type { DockDropZone, Rect } from './dock-drag.js';\nimport type { DockPanelElement } from './dock-panel.js';\nimport type {\n DockAddPanelTarget,\n DockChangeEvent,\n DockDirection,\n DockDragBoundaryEvent,\n DockDropTarget,\n DockEdge,\n DockLayout,\n DockLeafContentRules,\n DockLeafPlacementPolicy,\n DockLeafPlacementPolicyResolved,\n DockLeafRef,\n DockNeighbours,\n DockNode,\n DockOperation,\n DockPanelActivatedEvent,\n DockPanelAddedEvent,\n DockPanelDragStartEvent,\n DockPanelInit,\n DockPanelRemovedEvent,\n DockPanelSnapshot,\n DockPanelTearOutEvent,\n DockStackNode,\n} from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { registerDockHost, startDrag, unregisterDockHost } from './dock-drag.js';\nimport {\n addPanelToStack,\n collectContainerNames,\n collectPanelIds,\n collectStackPaths,\n createStack,\n extractStack,\n findNode,\n findStackOf,\n findStackPathByName,\n getLeafNeighbours,\n insertBeside,\n isSplit,\n isStack,\n moveLeafNodeToEdge,\n moveLeafStep,\n normalize,\n parseLayout,\n removePanelFromStack,\n serializeLayout,\n setActive,\n wrapRoot,\n} from './dock-model.js';\nimport '../split-layout/split-layout.js';\nimport '../tabs/tab-list.js';\nimport '../tabs/tab-list-item.js';\nimport './dock-panel.js';\n\nexport type {\n DockAddPanelTarget,\n DockChangeEvent,\n DockDirection,\n DockDragBoundaryEvent,\n DockEdge,\n DockLeafContentRules,\n DockLeafPlacementPolicy,\n DockLeafPlacementPolicyResolved,\n DockLeafRef,\n DockNeighbours,\n DockPanelActivatedEvent,\n DockPanelAddedEvent,\n DockPanelDragStartEvent,\n DockPanelRemovedEvent,\n DockPanelTearOutEvent,\n};\n\nexport interface DockHostElementEventMap {\n 'dock-change': DockChangeEvent;\n 'dock-panel-added': DockPanelAddedEvent;\n 'dock-panel-removed': DockPanelRemovedEvent;\n 'dock-panel-activated': DockPanelActivatedEvent;\n 'dock-panel-drag-start': DockPanelDragStartEvent;\n /** Panel released outside every host — request to move it to a new window. */\n 'dock-panel-tear-out': DockPanelTearOutEvent;\n /** Drag pointer left every host's bounds during a drag. */\n 'dock-panel-drag-out': DockDragBoundaryEvent;\n /** Drag pointer re-entered a host's bounds after being outside. */\n 'dock-panel-drag-in': DockDragBoundaryEvent;\n}\n\n/** Fraction of the leaf rect (from each edge) that forms the split bands. */\nconst BAND = 0.25;\n\n/** Pointer movement threshold before a press becomes a dock drag (matches tab-list). */\nconst DRAG_THRESHOLD_PX = 5;\n\n/** Tolerance (px) when matching a child gutter endpoint to a parent gutter line. */\nconst JUNCTION_TOL_PX = 6;\n\n/** Junction points closer than this merge into one handle (a 4-way cross yields one per side). */\nconst JUNCTION_MERGE_PX = 8;\n\ninterface DockJunctionTarget {\n split: SplitLayoutElement;\n gutterIndex: number;\n}\n\n/** A point where a parent split's gutter line crosses a nested split's gutter. */\ninterface DockJunction {\n /** Host-relative coordinates. */\n x: number;\n y: number;\n targets: DockJunctionTarget[];\n}\n\n@customElement(`ixfx-dock-host`)\nexport class DockHostElement extends LitElement {\n /** Initial layout as `DockLayout` JSON. Absent ⇒ all pooled panels go into one root stack. */\n @property({ type: String, attribute: `layout` })\n layout: string | null = null;\n\n /**\n * Space-separated drop operations this host allows: `tabs`, `horizontal`,\n * `vertical`, and convenience `all`. `\"\"` / `none` ⇒ nothing may be dropped.\n */\n @property({ type: String, attribute: `accepts` })\n accepts = `tabs horizontal vertical`;\n\n /**\n * When true, panels can be freely reorganised within this host, but\n * cannot be dragged out to another host.\n */\n @property({ type: Boolean, attribute: `isolated` })\n isolated = false;\n\n /** Finest-grained veto, consulted per candidate zone. */\n @property({ attribute: false })\n canAccept: ((panelId: string, op: DockOperation) => boolean) | undefined;\n\n @state()\n private _model: DockNode = createStack([]);\n\n @state()\n private _pool: DockPanelElement[] = [];\n\n @state()\n private _dropZone: DockDropZone | null = null;\n\n @state()\n private _dragActive = false;\n\n @state()\n private _junctions: DockJunction[] = [];\n\n /** panelId → toolbar nodes currently moved out into a tab item. */\n private _toolbarsOut: Map<string, HTMLElement[]> = new Map();\n\n /**\n * Placement policy per named leaf: `{ allow, deny }` kind sets plus an\n * `allowEdgeSplit` gate (default `true`). Host-level only — never serialized\n * into the layout, but kept across `loadLayout()` calls. Existing panels are\n * grandfathered; rules govern future placements (drags, `addPanel`,\n * re-homing). See {@link setLeafPlacementPolicy}.\n */\n private _leafContentRules: Map<string, { allow: Set<string> | null; deny: Set<string>; allowEdgeSplit: boolean }> = new Map();\n\n private _tabDragPending: { panelId: string; pointerId: number; startX: number; startY: number } | null = null;\n\n private _junctionsKey = ``;\n private _junctionsRaf: number | null = null;\n private _hostResizeObserver: ResizeObserver | null = null;\n\n /**\n * Bumped on every `loadLayout()`. Stamped onto each rendered\n * `ixfx-split-layout` as `data-dock-gen`, so `_foldLiveWeights` can tell a\n * split that still carries the *previous* generation's live weights (its\n * async re-render hasn't landed yet) from one that's caught up — and skip\n * folding the stale one back over the just-loaded model.\n */\n private _loadGeneration = 0;\n\n /** `toolbar-<name>` slot names currently provided as light-DOM children. */\n private _toolbarSlots: Set<string> = new Set();\n private _toolbarObserver: MutationObserver | null = null;\n\n /** Observers for panel element attribute changes, keyed by panelId. */\n private _panelObservers: Map<string, MutationObserver> = new Map();\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._buildInitialModel();\n registerDockHost(this);\n this.addEventListener(`dock-panel-drag-start`, this._onDragStart as EventListener);\n this._hostResizeObserver = new ResizeObserver(() => this._scheduleJunctions());\n this._hostResizeObserver.observe(this);\n this._scanToolbarSlots();\n this._toolbarObserver = new MutationObserver(() => this._scanToolbarSlots());\n this._toolbarObserver.observe(this, { childList: true, subtree: true, attributes: true, attributeFilter: [`slot`] });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n unregisterDockHost(this);\n this.removeEventListener(`dock-panel-drag-start`, this._onDragStart as EventListener);\n this._toolbarObserver?.disconnect();\n this._toolbarObserver = null;\n this._hostResizeObserver?.disconnect();\n this._hostResizeObserver = null;\n for (const observer of this._panelObservers.values()) {\n observer.disconnect();\n }\n this._panelObservers.clear();\n if (this._junctionsRaf !== null) {\n cancelAnimationFrame(this._junctionsRaf);\n this._junctionsRaf = null;\n }\n this._junctions = [];\n this._junctionsKey = ``;\n this._returnAllToolbars();\n }\n\n private _onDragStart = (event: DockPanelDragStartEvent): void => {\n const { panelId, pointerId, clientX, clientY } = event.detail;\n startDrag(panelId, this, pointerId, clientX, clientY, this._findPanelEl(panelId)?.kind);\n };\n\n override willUpdate(changed: Map<string, unknown>): void {\n super.willUpdate(changed);\n if (changed.has(`layout`) && this.layout !== null) {\n const parsed = parseLayout(this.layout);\n if (parsed) {\n this._model = parsed.root;\n this._mergePoolIntoModel();\n }\n }\n }\n\n override updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n this._syncSlots();\n this._syncToolbars();\n this._scheduleJunctions();\n }\n\n // ── Model setup ──────────────────────────────────────────────────────────\n\n private _buildInitialModel(): void {\n if (this.layout !== null) {\n const parsed = parseLayout(this.layout);\n if (parsed) {\n this._model = parsed.root;\n this._mergePoolIntoModel();\n return;\n }\n }\n this._model = createStack([]);\n this._mergePoolIntoModel();\n }\n\n /** Ensure every pooled panel element appears in the model (appended to the first stack). */\n private _mergePoolIntoModel(): void {\n const known = new Set(collectPanelIds(this._model));\n let changed = false;\n for (const el of this._scanPanels()) {\n if (!known.has(el.panelId)) {\n this._appendPanelToFirstStack(el.panelId);\n known.add(el.panelId);\n changed = true;\n }\n }\n if (changed) {\n normalize(this._model);\n }\n }\n\n private _scanPanels(): DockPanelElement[] {\n return Array.from(this.children).filter((el): el is DockPanelElement =>\n el instanceof HTMLElement && el.tagName === `IXFX-DOCK-PANEL` && Boolean((el as DockPanelElement).panelId),\n );\n }\n\n /** Refresh the set of provided `toolbar-<name>` slots; re-render on change. */\n private _scanToolbarSlots(): void {\n const found = new Set<string>();\n for (const child of this.children) {\n if (!(child instanceof HTMLElement))\n continue;\n const slot = child.getAttribute(`slot`) ?? ``;\n if (slot.startsWith(`toolbar-`) && slot.length > `toolbar-`.length) {\n found.add(slot);\n }\n }\n if (found.size !== this._toolbarSlots.size || [...found].some(s => !this._toolbarSlots.has(s))) {\n this._toolbarSlots = found;\n this.requestUpdate();\n }\n }\n\n private _findPanelEl(panelId: string): DockPanelElement | undefined {\n return this._pool.find(p => p.panelId === panelId)\n ?? this._scanPanels().find(p => p.panelId === panelId);\n }\n\n private _firstStack(): DockStackNode {\n const paths = collectStackPaths(this._model);\n const node = paths.length > 0 ? findNode(this._model, paths[0]) : null;\n if (node !== null && isStack(node))\n return node;\n const fresh = createStack([]);\n wrapRoot(this._model, `row`, fresh, `after`);\n normalize(this._model);\n return fresh;\n }\n\n private _appendPanelToFirstStack(panelId: string): void {\n const kind = this._panelKind(panelId);\n if (this._model.kind === `stack` && this._stackAllowsKind(this._model, kind)) {\n addPanelToStack(this._model, panelId);\n return;\n }\n addPanelToStack(this._firstStackAllowing(kind), panelId);\n }\n\n /** Normalized content kind of a panel (`'any'` when unknown/unset). */\n private _panelKind(panelId: string): string {\n return normalizeKind(this._findPanelEl(panelId)?.kind);\n }\n\n /** Whether `kind` may live in `stack` under the current leaf rules. */\n private _stackAllowsKind(stack: DockStackNode, kind: string): boolean {\n if (stack.name === undefined) {\n return true;\n }\n const rules = this._leafContentRules.get(stack.name);\n if (rules === undefined) {\n return true;\n }\n if (rules.deny.has(kind)) {\n return false;\n }\n return rules.allow === null || rules.allow.has(kind);\n }\n\n /**\n * Whether an edge drop may split a new sibling leaf beside `stack`. Unnamed\n * leaves and leaves with no policy always allow it; a named leaf whose\n * policy sets `allowEdgeSplit: false` does not (strict named-area\n * containment).\n */\n private _leafAllowsEdgeSplit(stack: DockStackNode): boolean {\n if (stack.name === undefined) {\n return true;\n }\n return this._leafContentRules.get(stack.name)?.allowEdgeSplit ?? true;\n }\n\n /** First stack (tree order) whose rules admit `kind`, else the first stack. */\n private _firstStackAllowing(kind: string): DockStackNode {\n for (const path of collectStackPaths(this._model)) {\n const node = findNode(this._model, path);\n if (node !== null && isStack(node) && this._stackAllowsKind(node, kind)) {\n return node;\n }\n }\n console.warn(`[ixfx-dock-host] no leaf admits kind \"${kind}\", using first stack`);\n return this._firstStack();\n }\n\n private _onPoolSlotChange = (): void => {\n this._syncPool();\n };\n\n private _observePanel(el: DockPanelElement): void {\n if (this._panelObservers.has(el.panelId))\n return;\n const observer = new MutationObserver(() => this.requestUpdate());\n observer.observe(el, {\n attributes: true,\n attributeFilter: [`label`, `icon-name`, `closable`, `collapsible`, `kind`, `accepts`],\n });\n this._panelObservers.set(el.panelId, observer);\n }\n\n private _unobservePanel(el: DockPanelElement): void {\n const observer = this._panelObservers.get(el.panelId);\n if (observer) {\n observer.disconnect();\n this._panelObservers.delete(el.panelId);\n }\n }\n\n private _syncPool(): void {\n // Scan the light DOM for all panel elements — panels placed in the model\n // carry named slots and are therefore NOT assigned to the pool slot.\n const current = this._scanPanels();\n const currentIds = new Set(current.map(p => p.panelId));\n let structuralChange = false;\n\n // Removed from DOM → drop from model\n for (const el of [...this._pool]) {\n if (!currentIds.has(el.panelId)) {\n this._unobservePanel(el);\n this._toolbarsOut.delete(el.panelId);\n this._removeFromModel(el.panelId);\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-removed`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n structuralChange = true;\n }\n }\n\n // New in DOM → add to model\n for (const el of current) {\n this._observePanel(el);\n if (!collectPanelIds(this._model).includes(el.panelId)) {\n this._appendPanelToFirstStack(el.panelId);\n normalize(this._model);\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n structuralChange = true;\n }\n }\n\n this._pool = current;\n this.requestUpdate();\n if (structuralChange) {\n this._emitChange();\n }\n }\n\n // ── Public API ───────────────────────────────────────────────────────────\n\n /** Serialize the current layout, folding live split weights from the DOM. */\n saveLayout(): DockLayout {\n this._foldLiveWeights();\n return serializeLayout(this._model);\n }\n\n loadLayout(layout: DockLayout): void {\n this._returnAllToolbars();\n this._loadGeneration++;\n this._model = normalize(cloneNode(layout.root));\n this._mergePoolIntoModel();\n this.requestUpdate();\n this._emitChange();\n }\n\n /**\n * Dock a panel. Returns false (without touching the DOM) when the\n * explicitly targeted container denies the panel's `kind`.\n */\n addPanel(panel: DockPanelElement | DockPanelInit, target?: DockAddPanelTarget): boolean {\n const kind = panel instanceof HTMLElement ? normalizeKind(panel.kind) : normalizeKind(panel.kind);\n const op = target?.op ?? `tabs`;\n\n // Resolve an explicit target first so kind denials can refuse cleanly.\n let stackPath: number[] | null = null;\n let splitTarget: number[] | null = null;\n if (target?.container !== undefined) {\n const namedPath = findStackPathByName(this._model, target.container);\n if (namedPath === null) {\n console.warn(`[ixfx-dock-host] addPanel: unknown container \"${target.container}\", appending to first admitting stack`);\n } else if (op === `tabs` && !this._stackAllowsKindAt(namedPath, kind)) {\n console.warn(`[ixfx-dock-host] addPanel: container \"${target.container}\" does not admit kind \"${kind}\"`);\n return false;\n } else if (op !== `tabs` && !this._stackAllowsEdgeSplitAt(namedPath)) {\n console.warn(`[ixfx-dock-host] addPanel: container \"${target.container}\" forbids edge splits (allowEdgeSplit: false)`);\n return false;\n } else {\n stackPath = namedPath;\n }\n } else if (target?.stack) {\n const found = findStackOf(this._model, target.stack);\n if (found === null) {\n console.warn(`[ixfx-dock-host] addPanel: unknown stack panel \"${target.stack}\", appending to first admitting stack`);\n } else if (op === `tabs` && !this._stackAllowsKindAt(found, kind)) {\n console.warn(`[ixfx-dock-host] addPanel: target stack does not admit kind \"${kind}\"`);\n return false;\n } else if (op !== `tabs` && !this._stackAllowsEdgeSplitAt(found)) {\n console.warn(`[ixfx-dock-host] addPanel: target stack forbids edge splits (allowEdgeSplit: false)`);\n return false;\n } else {\n stackPath = found;\n }\n }\n if (stackPath !== null && op !== `tabs`) {\n splitTarget = stackPath;\n stackPath = null;\n }\n\n let el: DockPanelElement;\n if (panel instanceof HTMLElement) {\n el = panel as DockPanelElement;\n } else {\n el = document.createElement(`ixfx-dock-panel`) as DockPanelElement;\n el.panelId = panel.panelId;\n if (panel.title !== undefined)\n el.title = panel.title;\n if (panel.iconName !== undefined)\n el.iconName = panel.iconName;\n if (panel.closable !== undefined)\n el.closable = panel.closable;\n if (panel.collapsible !== undefined)\n el.collapsible = panel.collapsible;\n if (panel.kind !== undefined)\n el.kind = panel.kind;\n }\n\n if (el.parentElement !== this) {\n this.appendChild(el);\n }\n if (!this._pool.some(p => p.panelId === el.panelId)) {\n this._pool = [...this._pool, el];\n }\n\n this._returnAllToolbars();\n\n // Moves are idempotent: drop an existing entry before re-inserting.\n if (collectPanelIds(this._model).includes(el.panelId)) {\n this._removeFromModel(el.panelId);\n }\n\n if (splitTarget !== null) {\n insertBeside(this._model, splitTarget, opToDirection(op), createStack([el.panelId]), `after`);\n } else if (stackPath !== null) {\n const stack = findNode(this._model, stackPath);\n if (stack !== null && isStack(stack)) {\n addPanelToStack(stack, el.panelId, target?.index);\n }\n } else {\n this._appendPanelToFirstStack(el.panelId);\n }\n\n normalize(this._model);\n this.requestUpdate();\n\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n this._emitChange();\n return true;\n }\n\n /** Whether the stack at `stackPath` admits `kind` under the leaf rules. */\n private _stackAllowsKindAt(stackPath: number[], kind: string): boolean {\n const stack = findNode(this._model, stackPath);\n return stack !== null && isStack(stack) && this._stackAllowsKind(stack, kind);\n }\n\n /** Whether the stack at `stackPath` permits an edge split beside it. */\n private _stackAllowsEdgeSplitAt(stackPath: number[]): boolean {\n const stack = findNode(this._model, stackPath);\n return stack === null || !isStack(stack) || this._leafAllowsEdgeSplit(stack);\n }\n\n removePanel(panelId: string): boolean {\n if (!collectPanelIds(this._model).includes(panelId))\n return false;\n\n this._returnAllToolbars();\n this._removeFromModel(panelId);\n this._pool = this._pool.filter(p => p.panelId !== panelId);\n this._toolbarsOut.delete(panelId);\n\n const el = this._scanPanels().find(p => p.panelId === panelId);\n el?.remove();\n\n normalize(this._model);\n this.requestUpdate();\n\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-removed`, {\n detail: { panelId },\n bubbles: true,\n composed: true,\n }));\n this._emitChange();\n return true;\n }\n\n activatePanel(panelId: string): boolean {\n const stackPath = findStackOf(this._model, panelId);\n if (stackPath === null)\n return false;\n const stack = findNode(this._model, stackPath);\n if (stack === null || !isStack(stack))\n return false;\n if (!setActive(stack, panelId))\n return false;\n\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-activated`, {\n detail: { panelId },\n bubbles: true,\n composed: true,\n }));\n return true;\n }\n\n getPanelIds(): string[] {\n return collectPanelIds(this._model);\n }\n\n /** Names of every named stack leaf, in tree order. */\n getContainerNames(): string[] {\n return collectContainerNames(this._model);\n }\n\n /**\n * Snapshot of a named container (`{ name, panels, active }`), or null when\n * no stack carries that name. First match wins when duplicated.\n */\n getContainer(name: string): { name: string; panels: string[]; active: string } | null {\n const path = findStackPathByName(this._model, name);\n if (path === null)\n return null;\n const node = findNode(this._model, path);\n if (node === null || !isStack(node) || node.name === undefined)\n return null;\n return { name: node.name, panels: [...node.panels], active: node.active };\n }\n\n /** Panel-ids in a named container, in tab order (`[]` when unknown/empty). */\n getContainerPanels(name: string): string[] {\n return this.getContainer(name)?.panels ?? [];\n }\n\n /** Panel elements in a named container, in tab order — for iterating children. */\n getContainerElements(name: string): DockPanelElement[] {\n return this.getContainerPanels(name)\n .map(id => this._findPanelEl(id))\n .filter((el): el is DockPanelElement => el !== undefined);\n }\n\n // ── Leaf placement policy (kind rules + edge-split gate) ─────────────────\n\n private _defaultLeafRule(): { allow: Set<string> | null; deny: Set<string>; allowEdgeSplit: boolean } {\n return { allow: null, deny: new Set<string>(), allowEdgeSplit: true };\n }\n\n /** A rule entry that constrains nothing — safe to drop from the map. */\n private _isEmptyLeafRule(entry: { allow: Set<string> | null; deny: Set<string>; allowEdgeSplit: boolean }): boolean {\n return entry.allow === null && entry.deny.size === 0 && entry.allowEdgeSplit;\n }\n\n private _warnUnknownContainer(method: string, key: string): void {\n if (findStackPathByName(this._model, key) === null) {\n console.warn(`[ixfx-dock-host] ${method}: no container named \"${key}\" yet; rule stored`);\n }\n }\n\n /**\n * Restrict a named container to only the given panel kinds — e.g.\n * `setLeafExclusiveContents('editor', ['document'])`. `tabs` drops,\n * `addPanel`, and re-homing into the leaf then refuse other kinds. Whether\n * edge splits beside the leaf are offered is governed separately by\n * {@link setLeafPlacementPolicy}'s `allowEdgeSplit` (default `true`).\n * Pass `[]` to seal the leaf (nothing admitted). Warns when no stack\n * currently carries `name`, but the rule is still stored and applies once\n * one appears. Rules are host policy: kept across `loadLayout()`, never\n * serialized.\n */\n setLeafExclusiveContents(name: string, kinds: readonly string[]): void {\n const key = name.trim();\n if (!key) {\n console.warn(`[ixfx-dock-host] setLeafExclusiveContents: empty container name`);\n return;\n }\n const entry = this._leafContentRules.get(key) ?? this._defaultLeafRule();\n entry.allow = new Set(kinds.map(k => k.trim()).filter(k => k.length > 0));\n this._leafContentRules.set(key, entry);\n this._warnUnknownContainer(`setLeafExclusiveContents`, key);\n }\n\n /**\n * Forbid the given panel kinds in a named container — e.g.\n * `setLeafDenyContents('footer', ['files', 'document'])`. Everything else\n * stays admitted. Pass `[]` to lift the denial. See\n * {@link setLeafExclusiveContents} for scope/ordering notes.\n */\n setLeafDenyContents(name: string, kinds: readonly string[]): void {\n const key = name.trim();\n if (!key) {\n console.warn(`[ixfx-dock-host] setLeafDenyContents: empty container name`);\n return;\n }\n const entry = this._leafContentRules.get(key) ?? this._defaultLeafRule();\n entry.deny = new Set(kinds.map(k => k.trim()).filter(k => k.length > 0));\n if (this._isEmptyLeafRule(entry)) {\n this._leafContentRules.delete(key);\n } else {\n this._leafContentRules.set(key, entry);\n }\n this._warnUnknownContainer(`setLeafDenyContents`, key);\n }\n\n /**\n * Set (merge) the full placement policy for a named leaf: kind allow/deny\n * lists plus the `allowEdgeSplit` gate. Omitted fields are left unchanged\n * — pass `clearLeafPlacementPolicy(name)` to reset. `allowKinds` /\n * `denyKinds` are equivalent to {@link setLeafExclusiveContents} /\n * {@link setLeafDenyContents} and share the same storage.\n *\n * `allowEdgeSplit: false` enforces strict named-area containment: the edge\n * drop zones beside the leaf go inert for every placement route (pointer\n * preview and drop, `queryDropTarget` / `previewExternalDrop`,\n * `addPanel` with a split `op`), so a panel cannot escape the area by\n * splitting next to it. A permitted split still creates an *unnamed,\n * unconstrained* leaf — the policy is not propagated to it.\n *\n * Warns when no stack currently carries `name`; the policy is stored and\n * applies once one appears. Host policy: kept across `loadLayout()`, never\n * serialized.\n */\n setLeafPlacementPolicy(name: string, policy: DockLeafPlacementPolicy): void {\n const key = name.trim();\n if (!key) {\n console.warn(`[ixfx-dock-host] setLeafPlacementPolicy: empty container name`);\n return;\n }\n const entry = this._leafContentRules.get(key) ?? this._defaultLeafRule();\n if (policy.allowKinds !== undefined) {\n entry.allow = new Set(policy.allowKinds.map(k => k.trim()).filter(k => k.length > 0));\n }\n if (policy.denyKinds !== undefined) {\n entry.deny = new Set(policy.denyKinds.map(k => k.trim()).filter(k => k.length > 0));\n }\n if (policy.allowEdgeSplit !== undefined) {\n entry.allowEdgeSplit = policy.allowEdgeSplit;\n }\n if (this._isEmptyLeafRule(entry)) {\n this._leafContentRules.delete(key);\n } else {\n this._leafContentRules.set(key, entry);\n }\n this._warnUnknownContainer(`setLeafPlacementPolicy`, key);\n }\n\n /** Remove every content rule and reset the edge-split gate for a named container. */\n clearLeafContentRestrictions(name: string): void {\n this._leafContentRules.delete(name.trim());\n }\n\n /** Alias of {@link clearLeafContentRestrictions} — clears kind rules and the edge-split gate. */\n clearLeafPlacementPolicy(name: string): void {\n this._leafContentRules.delete(name.trim());\n }\n\n /** Copy of a container's kind rules, or null when unrestricted. */\n getLeafContentRestrictions(name: string): DockLeafContentRules | null {\n const rules = this._leafContentRules.get(name.trim());\n if (rules === undefined) {\n return null;\n }\n return { allow: rules.allow === null ? null : [...rules.allow], deny: [...rules.deny] };\n }\n\n /** Resolved placement policy for a container, or null when it has none. */\n getLeafPlacementPolicy(name: string): DockLeafPlacementPolicyResolved | null {\n const rules = this._leafContentRules.get(name.trim());\n if (rules === undefined) {\n return null;\n }\n return {\n allowKinds: rules.allow === null ? null : [...rules.allow],\n denyKinds: [...rules.deny],\n allowEdgeSplit: rules.allowEdgeSplit,\n };\n }\n\n // ── Spatial (leaf geometry + moves) ──────────────────────────────────────\n\n /**\n * Geometric neighbours of a leaf (`name` or numeric `path`) — what sits\n * above / below / left / right of it on screen. Each entry is\n * `{ name, path }` (`name` is null for unnamed leaves), ordered\n * most-overlapping first. Returns null when the leaf is unknown.\n */\n getNeighbours(leaf: DockLeafRef): DockNeighbours | null {\n return getLeafNeighbours(this._model, leaf);\n }\n\n /**\n * Move a leaf one position in `direction`, swapping with the neighbour it\n * shares the longest edge with (both keep the remaining structure intact).\n * Returns false when the leaf is unknown or nothing adjoins that way.\n */\n moveLeaf(leaf: DockLeafRef, direction: DockDirection): boolean {\n if (!moveLeafStep(this._model, leaf, direction)) {\n return false;\n }\n this._commit();\n return true;\n }\n\n /**\n * Move a leaf to an edge of the overall layout (e.g. toggle a sidebar from\n * `left` to `right`). The rest of the layout stays intact as a single\n * subtree and the leaf keeps its absolute size along the target axis.\n * Returns false when the leaf is unknown or the layout holds one leaf.\n */\n moveLeafToEdge(leaf: DockLeafRef, edge: DockEdge): boolean {\n if (!moveLeafNodeToEdge(this._model, leaf, edge)) {\n return false;\n }\n this._commit();\n return true;\n }\n\n // ── Cross-window (tear-out / tear-in) ───────────────────────────────────\n //\n // The shared drag coordinator is per-document, so it never spans separate\n // windows / `BrowserWindow`s / `WebContentsView`s. These methods give an\n // outer coordinator (e.g. an Electron main process talking over IPC) the\n // hooks to move a panel between windows: capture a serializable snapshot on\n // one side, hit-test and recreate it on the other. See the README.\n\n /**\n * Capture a structured-clone-safe {@link DockPanelSnapshot} of a panel\n * (identity, chrome attributes, and a best-effort `innerHTML`). Returns\n * null when no such panel element is known to this host.\n */\n getPanelSnapshot(panelId: string): DockPanelSnapshot | null {\n const el = this._findPanelEl(panelId);\n if (el === undefined)\n return null;\n return {\n panelId: el.panelId,\n title: el.title,\n iconName: el.iconName,\n closable: el.closable,\n collapsible: el.collapsible,\n kind: normalizeKind(el.kind),\n accepts: el.accepts,\n contentHTML: el.innerHTML,\n };\n }\n\n /**\n * {@link getPanelSnapshot} + {@link removePanel} in one step: take the\n * snapshot, then drop the panel (and its element) from this host. Call this\n * from a `dock-panel-tear-out` handler once the receiving window has\n * recreated the panel.\n */\n detachPanel(panelId: string): DockPanelSnapshot | null {\n const snapshot = this.getPanelSnapshot(panelId);\n if (snapshot === null)\n return null;\n this.removePanel(panelId);\n return snapshot;\n }\n\n /**\n * Hit-test viewport coordinates against this host and return a plain,\n * serializable {@link DockDropTarget} (no element references) — or null when\n * the point is outside the host or the resulting zone is disallowed by\n * `accepts` / `canAccept`. Pure query: no model mutation, no overlay.\n *\n * `panelId` is passed to `canAccept`; use any stable id for an external\n * panel (defaults to `\"__external__\"`). `kind` covers leaf content rules\n * for panels unknown to this host (defaults to `'any'`).\n */\n queryDropTarget(clientX: number, clientY: number, panelId = `__external__`, kind?: string): DockDropTarget | null {\n const zone = this.computeDropZone(clientX, clientY, panelId, kind);\n return zone === null ? null : zoneToTarget(zone);\n }\n\n /**\n * Like {@link queryDropTarget}, but also shows the drop overlay so an\n * external (cross-window) drag gets the same visual feedback as an in-page\n * one. Call on every pointer update from the outer coordinator, then\n * {@link endExternalDrop} when the drag leaves or ends.\n */\n previewExternalDrop(clientX: number, clientY: number, panelId = `__external__`, kind?: string): DockDropTarget | null {\n this.setDragActive(true);\n const zone = this.computeDropZone(clientX, clientY, panelId, kind);\n this.setDropZone(zone);\n return zone === null ? null : zoneToTarget(zone);\n }\n\n /** Clear any overlay left by {@link previewExternalDrop}. */\n endExternalDrop(): void {\n this.setDropZone(null);\n this.setDragActive(false);\n }\n\n /**\n * Recreate a panel from a {@link DockPanelSnapshot} (or a bare\n * {@link DockPanelInit}) and dock it. With `at` viewport coordinates the\n * panel lands where a drop there would put it (respecting `accepts` /\n * `canAccept` and leaf content rules); without them, or when the point\n * misses the host, it goes into the first stack admitting its kind.\n * Returns the created element, or null when a panel\n * with that id is already docked here.\n */\n acceptExternalPanel(\n snapshot: DockPanelSnapshot | DockPanelInit,\n at?: { clientX: number; clientY: number },\n ): DockPanelElement | null {\n if (collectPanelIds(this._model).includes(snapshot.panelId))\n return null;\n\n const el = document.createElement(`ixfx-dock-panel`) as DockPanelElement;\n el.panelId = snapshot.panelId;\n if (snapshot.title !== undefined)\n el.title = snapshot.title;\n if (snapshot.iconName !== undefined)\n el.iconName = snapshot.iconName;\n if (snapshot.closable !== undefined)\n el.closable = snapshot.closable;\n if (snapshot.collapsible !== undefined)\n el.collapsible = snapshot.collapsible;\n if (`kind` in snapshot && snapshot.kind !== undefined)\n el.kind = snapshot.kind;\n if (`accepts` in snapshot && snapshot.accepts)\n el.setAttribute(`accepts`, snapshot.accepts);\n if (`contentHTML` in snapshot && snapshot.contentHTML)\n el.innerHTML = snapshot.contentHTML;\n\n this._returnAllToolbars();\n this.appendChild(el);\n this._pool = [...this._pool, el];\n this._appendPanelToFirstStack(el.panelId);\n normalize(this._model);\n\n this.endExternalDrop();\n const zone = at ? this.computeDropZone(at.clientX, at.clientY, el.panelId) : null;\n if (zone !== null) {\n this._applyZone(el.panelId, zone);\n }\n\n normalize(this._model);\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n this._emitChange();\n return el;\n }\n\n // ── Drop targeting (called by the drag coordinator) ──────────────────────\n\n /**\n * Hit-test a pointer position against this host's leaves and edges. Returns\n * a zone with rects relative to the host, or null when the pointer is\n * outside the host or the candidate zone is disallowed.\n */\n computeDropZone(clientX: number, clientY: number, panelId: string, kind?: string): DockDropZone | null {\n const hostRect = this.getBoundingClientRect();\n if (clientX < hostRect.left || clientX > hostRect.right\n || clientY < hostRect.top || clientY > hostRect.bottom) {\n return null;\n }\n // Explicit kind wins (cross-host / external drags); otherwise read the\n // panel element, defaulting to `'any'` for unknown panels.\n const resolvedKind = kind?.trim() ? kind.trim() : this._panelKind(panelId);\n const rel = (r: DOMRect): Rect => ({\n x: r.left - hostRect.left,\n y: r.top - hostRect.top,\n w: r.width,\n h: r.height,\n });\n\n // Leaf under the pointer?\n for (const path of collectStackPaths(this._model)) {\n const leaf = this.shadowRoot?.querySelector(`[data-dock-path=\"${path.join(`-`)}\"]`) as HTMLElement | null;\n if (!leaf)\n continue;\n const leafRect = leaf.getBoundingClientRect();\n if (clientX < leafRect.left || clientX > leafRect.right\n || clientY < leafRect.top || clientY > leafRect.bottom) {\n continue;\n }\n\n const stack = findNode(this._model, path);\n if (stack === null || !isStack(stack))\n continue;\n\n // Tab strip has priority over the leaf body\n const strip = leaf.querySelector(`ixfx-tab-list`);\n if (strip !== null) {\n const stripRect = strip.getBoundingClientRect();\n if (clientX >= stripRect.left && clientX <= stripRect.right\n && clientY >= stripRect.top && clientY <= stripRect.bottom) {\n const gapIndex = computeStripGapIndex(strip, clientX, clientY);\n const zone: DockDropZone = {\n host: this,\n operation: `tabs`,\n targetPath: path,\n side: `after`,\n gapIndex,\n rect: rel(leafRect),\n caretRect: this._stripCaretRect(strip, gapIndex, hostRect),\n };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n }\n\n const relX = (clientX - leafRect.left) / Math.max(leafRect.width, 1);\n const relY = (clientY - leafRect.top) / Math.max(leafRect.height, 1);\n\n if (relX >= BAND && relX <= 1 - BAND && relY >= BAND && relY <= 1 - BAND) {\n const zone: DockDropZone = {\n host: this,\n operation: `tabs`,\n targetPath: path,\n side: `after`,\n gapIndex: stack.panels.length,\n rect: rel(leafRect),\n };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n\n const r: Rect = rel(leafRect);\n let operation: DockOperation;\n let side: `before` | `after`;\n let zoneRect: Rect;\n if (relX < BAND) {\n operation = `split-vertical`;\n side = `before`;\n zoneRect = { ...r, w: r.w / 2 };\n } else if (relX > 1 - BAND) {\n operation = `split-vertical`;\n side = `after`;\n zoneRect = { x: r.x + r.w / 2, y: r.y, w: r.w / 2, h: r.h };\n } else if (relY < BAND) {\n operation = `split-horizontal`;\n side = `before`;\n zoneRect = { ...r, h: r.h / 2 };\n } else {\n operation = `split-horizontal`;\n side = `after`;\n zoneRect = { x: r.x, y: r.y + r.h / 2, w: r.w, h: r.h / 2 };\n }\n const zone: DockDropZone = { host: this, operation, targetPath: path, side, rect: zoneRect };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n\n // Outside every leaf: split the root against the nearest host edge\n const fromLeft = clientX - hostRect.left;\n const fromRight = hostRect.right - clientX;\n const fromTop = clientY - hostRect.top;\n const fromBottom = hostRect.bottom - clientY;\n const min = Math.min(fromLeft, fromRight, fromTop, fromBottom);\n const full: Rect = { x: 0, y: 0, w: hostRect.width, h: hostRect.height };\n\n let operation: DockOperation;\n let side: `before` | `after`;\n let zoneRect: Rect;\n if (min === fromLeft) {\n operation = `split-vertical`;\n side = `before`;\n zoneRect = { ...full, w: full.w / 2 };\n } else if (min === fromRight) {\n operation = `split-vertical`;\n side = `after`;\n zoneRect = { x: full.x + full.w / 2, y: full.y, w: full.w / 2, h: full.h };\n } else if (min === fromTop) {\n operation = `split-horizontal`;\n side = `before`;\n zoneRect = { ...full, h: full.h / 2 };\n } else {\n operation = `split-horizontal`;\n side = `after`;\n zoneRect = { x: full.x, y: full.y + full.h / 2, w: full.w, h: full.h / 2 };\n }\n const zone: DockDropZone = { host: this, operation, targetPath: [], side, rect: zoneRect };\n return this._zoneAllowed(panelId, zone, resolvedKind) ? zone : null;\n }\n\n private _zoneAllowed(panelId: string, zone: DockDropZone, kind?: string): boolean {\n if (!tokenAllows(this.accepts, operationToToken(zone.operation)))\n return false;\n\n // Per-panel restriction applies only when the drop target is a solo leaf\n const stack = findNode(this._model, zone.targetPath);\n if (stack !== null && isStack(stack) && stack.panels.length === 1) {\n const target = this._findPanelEl(stack.panels[0]);\n if (target && !panelAllows(target.accepts, operationToToken(zone.operation))) {\n return false;\n }\n }\n\n // Leaf content rules govern tabbing *into* a leaf.\n if (zone.operation === `tabs` && stack !== null && isStack(stack)) {\n if (!this._stackAllowsKind(stack, kind?.trim() ? kind.trim() : this._panelKind(panelId))) {\n return false;\n }\n }\n\n // Named-area containment: an edge split creates a new sibling leaf, so it\n // stays allowed *unless* the named leaf's policy sets `allowEdgeSplit:\n // false` — then the edge zones beside it go inert.\n if (zone.operation !== `tabs` && stack !== null && isStack(stack) && !this._leafAllowsEdgeSplit(stack)) {\n return false;\n }\n\n if (this.canAccept && !this.canAccept(panelId, zone.operation)) {\n return false;\n }\n return true;\n }\n\n /**\n * Apply a drop. `sourceHost` differs from `this` when the drag crossed\n * hosts; the panel element is adopted into this host first.\n */\n handleDrop(panelId: string, zone: DockDropZone, sourceHost?: DockHostElement): void {\n if (sourceHost !== undefined && sourceHost !== this) {\n sourceHost.releasePanel(panelId, this);\n }\n\n if (!collectPanelIds(this._model).includes(panelId)) {\n const el = this._findPanelEl(panelId);\n if (!el)\n return;\n this._appendPanelToFirstStack(panelId);\n normalize(this._model);\n }\n\n // In-page moves may carry a vacated leaf's name to the merge target (so\n // merging tabs back together doesn't strand an empty named placeholder).\n // Cross-host drops skip this: their source here is just the temporary\n // adoption stack, not the leaf the panel came from.\n this._applyZone(panelId, zone, sourceHost === undefined || sourceHost === this);\n this._commit();\n }\n\n /**\n * Move `panelId` (already present somewhere in the model) to the position\n * described by `zone`. Shared by in-page drops and external panel adoption.\n */\n private _applyZone(panelId: string, zone: DockDropZone, transferName = false): void {\n const sourcePath = findStackOf(this._model, panelId);\n let vacated: DockStackNode | null = null;\n if (sourcePath !== null) {\n const source = findNode(this._model, sourcePath);\n if (source !== null && isStack(source)) {\n removePanelFromStack(source, panelId);\n if (source.panels.length === 0) {\n vacated = source;\n }\n }\n }\n\n if (zone.operation === `tabs`) {\n const target = findNode(this._model, zone.targetPath);\n if (target !== null && isStack(target)) {\n addPanelToStack(target, panelId, zone.gapIndex);\n // A tabs drop that empties a named stack into an unnamed one hands\n // the name over, so the merged leaf keeps the container identity\n // (and its content rules) instead of leaving a placeholder behind.\n if (transferName && vacated !== null && vacated !== target\n && vacated.name !== undefined && target.name === undefined) {\n target.name = vacated.name;\n delete vacated.name;\n }\n }\n } else {\n insertBeside(this._model, zone.targetPath, opToDirection(zone.operation), createStack([panelId]), zone.side);\n }\n }\n\n /**\n * Move a panel element out of this host into `target`, dropping it from\n * this host's model. Used for cross-host drags.\n */\n releasePanel(panelId: string, target: DockHostElement): void {\n this._returnAllToolbars();\n const el = this._pool.find(p => p.panelId === panelId);\n const stackPath = findStackOf(this._model, panelId);\n if (stackPath !== null) {\n const stack = findNode(this._model, stackPath);\n if (stack !== null && isStack(stack)) {\n removePanelFromStack(stack, panelId);\n }\n }\n normalize(this._model);\n this._pool = this._pool.filter(p => p !== el);\n if (el !== undefined) {\n target.adoptPanelElement(el);\n }\n this.requestUpdate();\n }\n\n /** Adopt a panel element from another host (the one sanctioned reparent). */\n adoptPanelElement(el: DockPanelElement): void {\n this.appendChild(el);\n if (!this._pool.some(p => p.panelId === el.panelId)) {\n this._pool = [...this._pool, el];\n }\n this._appendPanelToFirstStack(el.panelId);\n normalize(this._model);\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-added`, {\n detail: { panelId: el.panelId },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ── Drag overlay (driven by the coordinator) ─────────────────────────────\n\n setDragActive(active: boolean): void {\n if (this._dragActive !== active) {\n this._dragActive = active;\n this.requestUpdate();\n }\n }\n\n setDropZone(zone: DockDropZone | null): void {\n if (this._dropZone !== zone) {\n this._dropZone = zone;\n this.requestUpdate();\n }\n }\n\n // ── Junction resize handles ──────────────────────────────────────────────\n\n private _scheduleJunctions(): void {\n if (this._junctionsRaf !== null)\n return;\n this._junctionsRaf = requestAnimationFrame(() => {\n this._junctionsRaf = null;\n this._computeJunctions();\n });\n }\n\n /**\n * Find points where a parent split's gutter line meets a nested split's\n * gutter (T and + crossings). Each junction handle starts both gutter drags\n * at once, like a corner resize in VS Code.\n */\n private _computeJunctions(): void {\n const shadow = this.shadowRoot;\n if (shadow === null)\n return;\n const hostRect = this.getBoundingClientRect();\n const found: DockJunction[] = [];\n\n for (const child of shadow.querySelectorAll<SplitLayoutElement>(`ixfx-split-layout`)) {\n // Nested splits are light children of their parent split\n const parent = child.parentElement?.closest<SplitLayoutElement>(`ixfx-split-layout`) ?? null;\n if (parent === null)\n continue;\n if (typeof child.getGutterRects !== `function` || typeof parent.getGutterRects !== `function`)\n continue;\n const childRect = child.getBoundingClientRect();\n\n for (const [pi, pg] of parent.getGutterRects().entries()) {\n for (const [ci, cg] of child.getGutterRects().entries()) {\n const pgVertical = pg.width <= pg.height;\n const cgVertical = cg.width <= cg.height;\n if (pgVertical === cgVertical)\n continue;\n let x: number;\n let y: number;\n if (pgVertical) {\n // Vertical parent line × horizontal child line: they meet where\n // the child's gutter endpoint abuts the parent's gutter.\n x = pg.left + pg.width / 2;\n y = cg.top + cg.height / 2;\n if (Math.abs(x - childRect.left) > JUNCTION_TOL_PX && Math.abs(x - childRect.right) > JUNCTION_TOL_PX)\n continue;\n if (y < pg.top || y > pg.bottom)\n continue;\n } else {\n y = pg.top + pg.height / 2;\n x = cg.left + cg.width / 2;\n if (Math.abs(y - childRect.top) > JUNCTION_TOL_PX && Math.abs(y - childRect.bottom) > JUNCTION_TOL_PX)\n continue;\n if (x < pg.left || x > pg.right)\n continue;\n }\n found.push({\n x: x - hostRect.left,\n y: y - hostRect.top,\n targets: [\n { split: parent, gutterIndex: pi },\n { split: child, gutterIndex: ci },\n ],\n });\n }\n }\n }\n\n // Merge coincident points so a 4-way cross is a single handle\n const merged: DockJunction[] = [];\n for (const j of found) {\n const near = merged.find(m => Math.abs(m.x - j.x) <= JUNCTION_MERGE_PX && Math.abs(m.y - j.y) <= JUNCTION_MERGE_PX);\n if (near === undefined) {\n merged.push(j);\n continue;\n }\n for (const t of j.targets) {\n if (!near.targets.some(o => o.split === t.split && o.gutterIndex === t.gutterIndex))\n near.targets.push(t);\n }\n }\n\n const key = merged\n .map(j => `${Math.round(j.x)},${Math.round(j.y)}:${j.targets.map(t => `${t.split.getAttribute(`data-dock-path`) ?? ``}#${t.gutterIndex}`).join(`|`)}`)\n .join(`;`);\n if (key === this._junctionsKey)\n return;\n this._junctionsKey = key;\n this._junctions = merged;\n }\n\n private _onJunctionPointerDown = (event: PointerEvent, junction: DockJunction): void => {\n if (event.button !== 0)\n return;\n event.preventDefault();\n event.stopPropagation();\n\n let started = false;\n for (const target of junction.targets) {\n if (!target.split.isConnected)\n continue;\n if (target.split.beginGutterDrag(target.gutterIndex, event.pointerId, event.clientX, event.clientY))\n started = true;\n }\n if (!started)\n return;\n\n // Swallow the trailing click so it cannot focus/select anything beneath.\n this._suppressNextClick();\n\n // Keep the handle following the intersection while both drags run.\n const follow = (): void => this._scheduleJunctions();\n const stop = (): void => {\n window.removeEventListener(`pointermove`, follow);\n window.removeEventListener(`pointerup`, stop);\n window.removeEventListener(`pointercancel`, stop);\n };\n window.addEventListener(`pointermove`, follow);\n window.addEventListener(`pointerup`, stop);\n window.addEventListener(`pointercancel`, stop);\n };\n\n // ── Split-element event consumption ──────────────────────────────────────\n\n /** Fold live weights from each rendered `ixfx-split-layout` into the model. */\n private _foldLiveWeights(): void {\n const splits = this.shadowRoot?.querySelectorAll<SplitLayoutElement>(`ixfx-split-layout[data-dock-path]`);\n if (splits === undefined)\n return;\n for (const el of splits) {\n // A split still stamped with a previous `loadLayout()` generation\n // hasn't re-rendered against the current model yet — its live weights\n // are leftovers from before the load, so folding them now would\n // silently revert the just-loaded sizes.\n if (el.getAttribute(`data-dock-gen`) !== String(this._loadGeneration))\n continue;\n\n const pathStr = el.getAttribute(`data-dock-path`);\n if (pathStr === null)\n continue;\n const node = findNode(this._model, parsePath(pathStr));\n if (node === null || !isSplit(node))\n continue;\n const live = Object.values(el.getSizes());\n if (live.length === node.children.length && !weightsEqual(live, node.sizes)) {\n node.sizes = live;\n // The fold is silent (no dock re-render, so an in-progress drag isn't\n // fought) — but that leaves each child's own `size` attribute lagging\n // the model. Write the folded weights straight onto them so a later\n // split-level rebuild (e.g. collapse/expand reading DOM attributes)\n // sees current sizes instead of stale ones.\n Array.from(el.children).forEach((child, i) => {\n if (child instanceof HTMLElement && node.sizes[i] !== undefined) {\n child.setAttribute(`size`, String(node.sizes[i]));\n }\n });\n }\n }\n }\n\n private _onSplitWeightsChanged = (): void => {\n // Live gutter weights; fold silently (no re-render, so drags aren't fought).\n this._foldLiveWeights();\n this._scheduleJunctions();\n };\n\n private _onSplitCollapsed = (event: Event, collapsed: boolean): void => {\n const detail = (event as CustomEvent<{ id?: string }>).detail;\n if (!detail?.id)\n return;\n const pathStr = this.shadowRoot?.getElementById(detail.id)?.getAttribute(`data-dock-path`);\n if (pathStr === null || pathStr === undefined)\n return;\n const node = findNode(this._model, parsePath(pathStr));\n if (node === null || !isStack(node))\n return;\n // Model mirrors the element; no re-render needed (attrs already match).\n if (collapsed) {\n node.collapsed = true;\n } else {\n delete node.collapsed;\n }\n };\n\n private _onSplitClose = (event: Event): void => {\n // Route leaf closes through the model so panel elements survive: each\n // panel re-homes into the first other stack admitting its kind (or the\n // pool when none does).\n event.preventDefault();\n const detail = (event as CustomEvent<{ id?: string }>).detail;\n if (!detail?.id)\n return;\n const pathStr = this.shadowRoot?.getElementById(detail.id)?.getAttribute(`data-dock-path`);\n if (pathStr === null || pathStr === undefined)\n return;\n const path = parsePath(pathStr);\n const closing = findNode(this._model, path);\n if (closing === null || !isStack(closing))\n return;\n const moving = [...closing.panels];\n this._returnAllToolbars();\n extractStack(this._model, path);\n for (const panelId of moving) {\n addPanelToStack(this._firstStackAllowing(this._panelKind(panelId)), panelId);\n }\n this._commit();\n };\n\n // ── Tab-strip events ─────────────────────────────────────────────────────\n\n private _onTabChange = (event: Event, path: number[]): void => {\n const panelId = (event as TabListChangeEvent).detail.selected;\n const stack = findNode(this._model, path);\n if (stack === null || !isStack(stack))\n return;\n if (!setActive(stack, panelId))\n return;\n this.requestUpdate();\n this.dispatchEvent(new CustomEvent<{ panelId: string }>(`dock-panel-activated`, {\n detail: { panelId },\n bubbles: true,\n composed: true,\n }));\n };\n\n private _onStripPointerDown = (event: PointerEvent): void => {\n if (event.button !== 0)\n return;\n\n // Presses that begin on strip chrome (toolbar buttons, close buttons) are\n // not drag handles.\n const path = event.composedPath();\n for (const node of path) {\n if (!(node instanceof HTMLElement))\n continue;\n if (node.classList.contains(`list-toolbar`) || node.classList.contains(`close-btn`)) {\n return;\n }\n }\n\n const item = path.find((node): node is HTMLElement =>\n node instanceof HTMLElement && node.tagName === `IXFX-TAB-LIST-ITEM`) ?? null;\n if (item === null || !item.id)\n return;\n\n this._tabDragPending = {\n panelId: item.id,\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n };\n\n window.addEventListener(`pointermove`, this._onTabDragMove);\n window.addEventListener(`pointerup`, this._onTabDragUp);\n window.addEventListener(`pointercancel`, this._onTabDragUp);\n };\n\n private _onTabDragMove = (event: PointerEvent): void => {\n const pending = this._tabDragPending;\n if (pending === null || event.pointerId !== pending.pointerId)\n return;\n\n const distance = Math.hypot(event.clientX - pending.startX, event.clientY - pending.startY);\n if (distance < DRAG_THRESHOLD_PX)\n return;\n\n this._tabDragPending = null;\n this._teardownTabDragListeners();\n this._suppressNextClick();\n\n this.dispatchEvent(new CustomEvent<{ panelId: string; pointerId: number; clientX: number; clientY: number }>(`dock-panel-drag-start`, {\n detail: {\n panelId: pending.panelId,\n pointerId: pending.pointerId,\n clientX: event.clientX,\n clientY: event.clientY,\n },\n bubbles: true,\n composed: true,\n }));\n };\n\n private _onTabDragUp = (event: PointerEvent): void => {\n if (this._tabDragPending === null || event.pointerId !== this._tabDragPending.pointerId)\n return;\n this._tabDragPending = null;\n this._teardownTabDragListeners();\n };\n\n private _teardownTabDragListeners(): void {\n window.removeEventListener(`pointermove`, this._onTabDragMove);\n window.removeEventListener(`pointerup`, this._onTabDragUp);\n window.removeEventListener(`pointercancel`, this._onTabDragUp);\n }\n\n /** After a dock drag from a tab/titlebar, swallow the trailing click so it cannot re-select or toggle. */\n private _suppressNextClick(): void {\n const swallow = (e: MouseEvent): void => {\n e.preventDefault();\n e.stopPropagation();\n window.removeEventListener(`click`, swallow, true);\n };\n window.addEventListener(`click`, swallow, true);\n }\n\n // ── Internal plumbing ────────────────────────────────────────────────────\n\n private _removeFromModel(panelId: string): void {\n const stackPath = findStackOf(this._model, panelId);\n if (stackPath === null)\n return;\n const stack = findNode(this._model, stackPath);\n if (stack !== null && isStack(stack)) {\n removePanelFromStack(stack, panelId);\n }\n normalize(this._model);\n }\n\n /** Normalize, re-render, and announce the structural change. */\n private _commit(): void {\n normalize(this._model);\n this.requestUpdate();\n this._emitChange();\n }\n\n private _syncSlots(): void {\n const inModel = new Set<string>();\n const visit = (node: DockNode): void => {\n if (isStack(node)) {\n for (const id of node.panels) {\n inModel.add(id);\n const el = this._findPanelEl(id);\n if (el === undefined)\n continue;\n el.setAttribute(`slot`, `dock-panel-${id}`);\n // Docked panels always render content-only; the leaf strip carries\n // the title chrome for every stack, single-panel or not.\n el.presentation = `tabbed`;\n }\n } else {\n node.children.forEach(visit);\n }\n };\n visit(this._model);\n\n for (const el of this._pool) {\n if (!inModel.has(el.panelId)) {\n el.setAttribute(`slot`, ``);\n el.presentation = `solo`;\n }\n }\n }\n\n /**\n * Per-panel toolbar routing: docked panels render content-only, so the\n * active panel's toolbar nodes live in its generated tab item (shown\n * right-aligned while active). Node moves preserve element state. Panels\n * outside the model keep their toolbar in their own (solo) chrome.\n */\n private _syncToolbars(): void {\n const wanted = new Map<string, HTMLElement[]>();\n const visit = (node: DockNode): void => {\n if (isStack(node)) {\n if (node.panels.length > 0 && node.active) {\n const el = this._findPanelEl(node.active);\n if (el !== undefined) {\n wanted.set(node.active, toolbarNodesOf(el));\n }\n }\n } else {\n node.children.forEach(visit);\n }\n };\n visit(this._model);\n\n for (const [panelId, nodes] of this._toolbarsOut) {\n if (!wanted.has(panelId)) {\n this._returnToolbar(panelId, nodes);\n }\n }\n\n for (const [panelId, nodes] of wanted) {\n if (this._toolbarsOut.has(panelId) || nodes.length === 0)\n continue;\n const item = this.shadowRoot?.getElementById(panelId);\n if (item === null || item === undefined)\n continue;\n for (const node of nodes) {\n item.appendChild(node);\n }\n this._toolbarsOut.set(panelId, nodes);\n }\n }\n\n private _returnToolbar(panelId: string, nodes: HTMLElement[]): void {\n const el = this._findPanelEl(panelId);\n if (el !== undefined) {\n for (const node of nodes) {\n if (node.isConnected) {\n el.appendChild(node);\n }\n }\n }\n this._toolbarsOut.delete(panelId);\n }\n\n private _returnAllToolbars(): void {\n for (const [panelId, nodes] of [...this._toolbarsOut]) {\n this._returnToolbar(panelId, nodes);\n }\n }\n\n private _emitChange(): void {\n this.dispatchEvent(new CustomEvent<{ layout: DockLayout }>(`dock-change`, {\n detail: { layout: this.saveLayout() },\n bubbles: true,\n composed: true,\n }));\n }\n\n // ── Render ───────────────────────────────────────────────────────────────\n\n protected override render() {\n return html`\n <div class=\"root\">\n ${this._renderNode(this._model, [])}\n </div>\n <div class=\"overlay\" ?hidden=${!this._dragActive}>\n ${this._dropZone === null\n ? nothing\n : html`\n <div class=\"zone-rect\" style=${rectStyle(this._dropZone.rect)}></div>\n ${this._dropZone.caretRect === undefined\n ? nothing\n : html`<div class=\"zone-caret\" style=${rectStyle(this._dropZone.caretRect)}></div>`}\n `}\n </div>\n <div class=\"junctions\" ?hidden=${this._dragActive}>\n ${this._junctions.map(junction => html`\n <div\n class=\"junction-handle\"\n style=${`left:${junction.x}px; top:${junction.y}px;`}\n role=\"separator\"\n aria-label=\"Resize adjacent panels\"\n @pointerdown=${(e: PointerEvent) => this._onJunctionPointerDown(e, junction)}\n ><span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"spot\" part=\"junction-handle\"></span></div>\n `)}\n </div>\n <slot @slotchange=${this._onPoolSlotChange}></slot>\n `;\n }\n\n private _renderNode(node: DockNode, path: number[], size?: number): unknown {\n if (isStack(node)) {\n return this._renderLeaf(node, path, size);\n }\n return this._renderSplit(node, path, size);\n }\n\n private _renderSplit(node: DockNode & { kind: `split` }, path: number[], size?: number): unknown {\n const pathStr = path.join(`-`);\n return html`\n <ixfx-split-layout\n class=\"split\"\n direction=${node.direction}\n size=${size === undefined ? nothing : String(size)}\n style=${`--split-gutter-size: var(--dock-split-bar-size, 2px); --split-collapsed-size: var(--dock-collapsed-size, 40px)`}\n data-dock-path=${pathStr}\n data-dock-gen=${this._loadGeneration}\n @ixfx-split-resize=${this._onSplitWeightsChanged}\n @ixfx-split-change=${this._onSplitWeightsChanged}\n @ixfx-split-collapse=${(e: Event) => this._onSplitCollapsed(e, true)}\n @ixfx-split-expand=${(e: Event) => this._onSplitCollapsed(e, false)}\n @ixfx-split-close=${this._onSplitClose}\n >\n ${node.children.map((child, i) => this._renderNode(child, [...path, i], node.sizes[i]))}\n </ixfx-split-layout>\n `;\n }\n\n private _renderLeaf(stack: DockStackNode, path: number[], size?: number): unknown {\n const pathStr = path.join(`-`);\n const collapsible = stack.panels.length === 1\n ? (this._findPanelEl(stack.panels[0])?.collapsible ?? false)\n : false;\n\n const leafAttrs = (content: unknown): unknown => html`\n <div\n id=${`dock-leaf-${pathStr}`}\n class=\"leaf\"\n data-dock-path=${pathStr}\n data-dock-name=${stack.name ?? nothing}\n size=${size === undefined ? nothing : String(size)}\n min=${collapsible ? `1px` : nothing}\n when-small=${collapsible ? `collapse` : nothing}\n ?collapsed=${stack.collapsed === true}\n >${content}</div>\n `;\n\n if (stack.panels.length === 0) {\n return leafAttrs(html`\n <div class=\"empty\" part=\"empty\">\n <slot name=\"empty\"><span>Drop panels here</span></slot>\n </div>\n `);\n }\n\n // Every leaf renders the same strip + body chrome, so titlebars are\n // consistent whether a stack holds one panel or many. Named leaves\n // forward light-DOM `toolbar-<name>` content into the strip's toolbar.\n const toolbarSlot = stack.name !== undefined && this._toolbarSlots.has(`toolbar-${stack.name}`)\n ? html`<slot name=\"toolbar-${stack.name}\" slot=\"toolbar\"></slot>`\n : nothing;\n return leafAttrs(html`\n <ixfx-tab-list\n class=\"strip\"\n orientation=\"horizontal\"\n scrollable\n shrink\n ?hide-labels=${stack.hideLabels === true}\n @change=${(e: Event) => this._onTabChange(e, path)}\n @pointerdown=${this._onStripPointerDown}\n >\n ${repeat(stack.panels, id => id, id => this._renderTabItem(stack, id))}\n ${toolbarSlot}\n </ixfx-tab-list>\n <div class=\"leaf-body\">\n <slot name=\"dock-panel-${stack.active}\"></slot>\n </div>\n `);\n }\n\n private _renderTabItem(stack: DockStackNode, panelId: string): unknown {\n const el = this._findPanelEl(panelId);\n return html`\n <ixfx-tab-list-item\n id=${panelId}\n ?selected=${panelId === stack.active}\n .iconName=${el?.iconName ?? ``}\n .closeable=${el?.closable ?? false}\n @close=${() => this.removePanel(panelId)}\n >${el?.title ?? panelId}</ixfx-tab-list-item>\n `;\n }\n\n private _stripCaretRect(strip: Element, gapIndex: number | undefined, hostRect: DOMRect): Rect | undefined {\n const items = Array.from(strip.querySelectorAll(`ixfx-tab-list-item`)) as HTMLElement[];\n if (items.length === 0)\n return undefined;\n const index = Math.max(0, Math.min(gapIndex ?? items.length, items.length));\n const edge = index < items.length\n ? items[index].getBoundingClientRect().left\n : items[items.length - 1].getBoundingClientRect().right;\n const stripRect = strip.getBoundingClientRect();\n return {\n x: edge - hostRect.left - 1,\n y: stripRect.top - hostRect.top,\n w: 2,\n h: stripRect.height,\n };\n }\n\n static override styles = [\n themeFallbacks,\n handleStyles,\n css`\n :host {\n display: block;\n width: 100%;\n height: 100%;\n --dock-drop-zone-color: var(--accent);\n --dock-drop-zone-opacity: 0.25;\n --dock-collapsed-size: 40px;\n --dock-split-bar-size: 2px;\n position: relative;\n }\n\n .root {\n width: 100%;\n height: 100%;\n }\n\n ixfx-split-layout.split {\n width: 100%;\n height: 100%;\n }\n\n .leaf {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n box-sizing: border-box;\n overflow: hidden;\n border: 1px solid var(--surface-4);\n border-radius: var(--radius-m);\n }\n\n .leaf[collapsed] {\n pointer-events: none;\n }\n\n .leaf[collapsed] .leaf-body,\n .leaf[collapsed] .empty {\n visibility: hidden;\n }\n\n .strip {\n flex-shrink: 0;\n border: 0;\n /* The leaf background shows through selected tabs; a text underline\n (not the border indicator) carries the selection. */\n --ixfx-tab-selected-background: transparent;\n --ixfx-selected-tab-border-width: 0;\n --ixfx-selected-tab-text-decoration: underline;\n --ixfx-selected-tab-text-decoration-thickness: 2px;\n --ixfx-selected-tab-text-decoration-offset: 4px;\n --ixfx-tab-hover-background: var(--surface-4);\n }\n\n /* Uniform tab height: a panel toolbar button would otherwise inflate\n its tab item, giving strips of different stacks different heights. */\n .strip ixfx-tab-list-item {\n height: var(--dock-tab-height, 30px);\n }\n\n /* Breathing room between strip toolbars and the leaf edge. */\n .strip::part(list-toolbar) {\n padding-right: var(--space-xs);\n }\n\n .leaf-body {\n flex: 1;\n min-height: 0;\n min-width: 0;\n box-sizing: border-box;\n padding: var(--dock-leaf-body-padding, var(--space-s));\n }\n\n .empty {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--surface-3-text);\n opacity: 0.6;\n font-size: var(--text-m);\n border: 1px dashed var(--border-subtle);\n border-radius: var(--radius-m);\n margin: var(--space-s);\n }\n\n .overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 100;\n }\n\n .zone-rect {\n position: absolute;\n background: var(--dock-drop-zone-color);\n opacity: var(--dock-drop-zone-opacity);\n border-radius: var(--radius-s);\n }\n\n .zone-caret {\n position: absolute;\n background: var(--dock-drop-zone-color);\n border-radius: 1px;\n }\n\n .junctions {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 99;\n }\n\n .junctions[hidden] {\n display: none;\n }\n\n .junction-handle {\n position: absolute;\n width: 14px;\n height: 14px;\n transform: translate(-50%, -50%);\n border-radius: 50%;\n cursor: nwse-resize;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .junction-handle .ixfx-handle {\n --ixfx-handle-spot-size: 12px;\n --ixfx-handle-dot-size: 3px;\n --ixfx-handle-opacity: 0;\n --ixfx-handle-opacity-active: 0.9;\n }\n\n slot:not([name]) {\n display: none;\n }\n `,\n ];\n}\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\n/** `split-horizontal` = horizontal divider = panels stacked vertically. */\nfunction opToDirection(op: DockOperation): `row` | `column` {\n return op === `split-horizontal` ? `column` : `row`;\n}\n\nfunction operationToToken(op: DockOperation): string {\n if (op === `tabs`)\n return `tabs`;\n return op === `split-horizontal` ? `horizontal` : `vertical`;\n}\n\n/** Host-level `accepts`: empty or `none` rejects everything. */\nfunction tokenAllows(tokens: string, token: string): boolean {\n const list = tokens.trim().split(/\\s+/).filter(t => t.length > 0);\n if (list.length === 0 || (list.length === 1 && list[0] === `none`))\n return false;\n return list.includes(`all`) || list.includes(token);\n}\n\n/** Panel-level `accepts`: empty means unrestricted (host rules still apply). */\nfunction panelAllows(tokens: string, token: string): boolean {\n const list = tokens.trim().split(/\\s+/).filter(t => t.length > 0);\n if (list.length === 0)\n return true;\n if (list.length === 1 && list[0] === `none`)\n return false;\n return list.includes(`all`) || list.includes(token);\n}\n\nfunction weightsEqual(a: number[], b: number[]): boolean {\n if (a.length !== b.length)\n return false;\n return a.every((v, i) => Math.abs(v - b[i]) < 0.0001);\n}\n\nfunction rectStyle(r: Rect): string {\n return `left:${r.x}px; top:${r.y}px; width:${r.w}px; height:${r.h}px;`;\n}\n\n/** Strip a live `DockDropZone` down to its serializable {@link DockDropTarget}. */\nfunction zoneToTarget(zone: DockDropZone): DockDropTarget {\n return {\n operation: zone.operation,\n targetPath: [...zone.targetPath],\n side: zone.side,\n ...(zone.gapIndex === undefined ? {} : { gapIndex: zone.gapIndex }),\n };\n}\n\nfunction cloneNode(node: DockNode): DockNode {\n return JSON.parse(JSON.stringify(node)) as DockNode;\n}\n\n/** Panel content kind, normalized (`'any'` when unset/blank). */\nfunction normalizeKind(kind: string | undefined): string {\n const trimmed = kind?.trim() ?? ``;\n return trimmed || `any`;\n}\n\nfunction parsePath(pathStr: string): number[] {\n return pathStr.length === 0 ? [] : pathStr.split(`-`).filter(s => s.length > 0).map(Number);\n}\n\n/** Toolbar-slot light children of a dock panel. */\nfunction toolbarNodesOf(el: DockPanelElement): HTMLElement[] {\n return Array.from(el.children).filter((c): c is HTMLElement =>\n c instanceof HTMLElement && c.getAttribute(`slot`) === `toolbar`);\n}\n\n/** Nearest strip gap to the pointer (reuses the tab-list midpoint rule). */\nfunction computeStripGapIndex(strip: Element, clientX: number, _clientY: number): number {\n const items = Array.from(strip.querySelectorAll(`ixfx-tab-list-item`)) as HTMLElement[];\n if (items.length === 0)\n return 0;\n for (let i = 0; i < items.length; i++) {\n const r = items[i].getBoundingClientRect();\n const mid = (r.left + r.right) / 2;\n if (clientX < mid)\n return i;\n }\n return items.length;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-dock-host': DockHostElement;\n }\n}\n\nexport interface DockHostElement {\n addEventListener: (<K extends keyof DockHostElementEventMap>(\n type: K,\n listener: (this: DockHostElement, event: DockHostElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import { html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { safeCustomElement } from '../util/custom-elements.js';\nimport \"./form.css\";\n\n@safeCustomElement(`ixfx-form-group`)\nexport class FormGroupElement extends LitElement {\n @property({ type: String })\n label = ``;\n\n private _fieldset?: HTMLFieldSetElement;\n private _observer?: MutationObserver;\n\n protected override createRenderRoot() {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._observer = new MutationObserver(() => this._moveChildren());\n }\n\n override firstUpdated(): void {\n this._fieldset = this.querySelector(`fieldset`) ?? undefined;\n if (this._fieldset) {\n this._observer?.observe(this, { childList: true });\n this._moveChildren();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._observer?.disconnect();\n }\n\n private _moveChildren(): void {\n if (!this._fieldset) {\n return;\n }\n\n const toMove = Array.from(this.children).filter(el => el.tagName !== `FIELDSET`);\n toMove.forEach((el) => {\n this._fieldset!.appendChild(el);\n });\n }\n\n protected override render() {\n return html`<fieldset><legend>${this.label}</legend></fieldset>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-form-group': FormGroupElement;\n }\n}","import { html, LitElement } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { safeCustomElement } from \"../util/custom-elements.js\";\nimport \"./form.css\";\n\nlet idCounter = 0;\n\n@safeCustomElement(`ixfx-form-part`)\nexport class FormPartElement extends LitElement {\n @property({ type: String })\n label = ``;\n\n private _id?: string;\n\n protected override createRenderRoot() {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._ensureId();\n }\n\n private _ensureId(): void {\n const control = this.querySelector(`input, select, textarea, [name]`) as HTMLElement | null;\n if (!control) {\n return;\n }\n\n if (!control.id) {\n this._id = `ixfx-form-part-${++idCounter}`;\n control.id = this._id;\n } else {\n this._id = control.id;\n }\n }\n\n protected override render() {\n if (!this._id) {\n this._ensureId();\n }\n\n return html`<label for=${this._id ?? ``}>${this.label}</label>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-form-part\": FormPartElement;\n }\n}","import type { CommandId } from '@clinth/ui-commands';\nimport type { TreeExclusivity, TreeInteractionMode, TreeItem, TreeNode, TreeSelectionFilter } from '../common/types.js';\nimport type { TreeBaseElement } from '../tree/tree-base.js';\nimport type { ListSelectionMode } from '../vertical-list/types.js';\nimport type {\n IGroupedSubComponent,\n SubComponentActivateDetail,\n SubComponentItemClickDetail,\n SubComponentSelectDetail,\n SubComponentTickleDetail,\n} from './types.js';\nimport '../tree/tree-list.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type TreeListAdapterOptions<T> = {\n /**\n * Returns the direct children of an item to build the tree hierarchy.\n * Omit for flat item lists — all items become leaf nodes at the root level.\n */\n getChildren?: (item: T) => readonly T[];\n\n /** Forwarded to the inner ixfx-tree-list. Default: `'standard'`. */\n interactionMode?: TreeInteractionMode;\n\n /**\n * Controls which node types are selectable.\n * Forwarded to the inner ixfx-tree-list. Default: `'all'`.\n */\n selectionFilter?: TreeSelectionFilter;\n\n /**\n * Controls how expanding one node affects its siblings.\n * Forwarded to the inner ixfx-tree-list. Default: `'none'`.\n */\n exclusivity?: TreeExclusivity;\n\n /**\n * Called when a command is dispatched via `ixfx-grouped-item-lister.dispatch()`.\n * Receives the inner `TreeBaseElement` (undefined until the first `setItems()` call)\n * so the handler can sort, filter, or otherwise manipulate the tree directly.\n */\n onDispatch?: (\n commandId: CommandId,\n args: Record<string, unknown> | undefined,\n tree: TreeBaseElement | undefined,\n ) => void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an `HTMLElement` that implements `IGroupedSubComponent<T>` by wrapping\n * an `ixfx-tree-list` internally.\n *\n * `toTreeItem` converts each item `T` to display metadata (`key`, `label`, etc).\n * The adapter stores the original `T` in `TreeItem.data` and uses it to map\n * tree-node selections back to typed values.\n *\n * Unlike `createVerticalListAdapter`, items can be hierarchical: provide\n * `options.getChildren` to return each item's children and the adapter will\n * recursively build the `TreeNode` tree. Omit it for a flat list of leaf nodes.\n *\n * The four interface events (`select`, `activate`, `item-click`, `tickle`) are\n * intercepted at the tree level, re-typed from `TreeNode` → `T`, and re-dispatched\n * on the adapter element so `ixfx-grouped-item-lister` can identify the source.\n *\n * @example Flat item list:\n * ```ts\n * lister.factory = () =>\n * createTreeListAdapter<FileItem>(item => ({ key: item.id, label: item.name, isLeaf: true }));\n * ```\n *\n * @example Hierarchical items:\n * ```ts\n * lister.factory = () =>\n * createTreeListAdapter<Category>(\n * cat => ({ key: cat.id, label: cat.name }),\n * { getChildren: cat => cat.subCategories },\n * );\n * ```\n */\nexport function createTreeListAdapter<T>(\n toTreeItem: (item: T) => Omit<TreeItem, `data`>,\n options?: TreeListAdapterOptions<T>,\n): HTMLElement & IGroupedSubComponent<T> {\n const container = document.createElement(`div`);\n container.style.cssText = `display:contents;`;\n\n let treeEl: TreeBaseElement | undefined;\n\n // ---- Tree building ----\n\n function buildNode(item: T): TreeNode {\n const treeItem: TreeItem = { ...toTreeItem(item), data: item };\n const children = options?.getChildren?.(item);\n return {\n item: treeItem,\n // If getChildren is provided, recurse. For known leaves (isLeaf:true or\n // no getChildren), use [] to signal \"confirmed leaf\" to the tree.\n children: children ? children.map(buildNode) : (treeItem.isLeaf ? [] : undefined),\n };\n }\n\n function getOrCreateTree(): TreeBaseElement {\n if (treeEl)\n return treeEl;\n\n treeEl = document.createElement(`ixfx-tree-list`) as TreeBaseElement;\n treeEl.interactionMode = options?.interactionMode ?? `standard`;\n treeEl.selectionFilter = options?.selectionFilter ?? `all`;\n treeEl.exclusivity = options?.exclusivity ?? `none`;\n treeEl.style.cssText = `display:block;width:100%;`;\n\n container.appendChild(treeEl);\n attachBridgeListeners();\n\n return treeEl;\n }\n\n // ---- Node → T mapping (via TreeItem.data) ----\n\n function mapNodes(nodes: ReadonlySet<TreeNode>): ReadonlySet<T> {\n const result = new Set<T>();\n for (const node of nodes) {\n if (node.item.data !== undefined)\n result.add(node.item.data as T);\n }\n return result;\n }\n\n // ---- Event bridge ----\n //\n // The tree fires the same event names as IGroupedSubComponent ('select',\n // 'activate', etc.). We must intercept them at the tree level and re-dispatch\n // on the container so grouped-item-lister can identify the correct source\n // element (the container, not the inner tree).\n\n function attachBridgeListeners(): void {\n treeEl!.addEventListener(`select`, (e) => {\n e.stopPropagation();\n const detail: SubComponentSelectDetail<T> = {\n selected: mapNodes(e.detail.selected),\n previous: mapNodes(e.detail.previous),\n };\n container.dispatchEvent(\n new CustomEvent(`select`, { detail, bubbles: true, composed: true }),\n );\n });\n\n treeEl!.addEventListener(`activate`, (e) => {\n e.stopPropagation();\n const item = (e.detail.node as TreeNode).item.data as T | undefined;\n if (item === undefined)\n return;\n const detail: SubComponentActivateDetail<T> = { item };\n container.dispatchEvent(\n new CustomEvent(`activate`, { detail, bubbles: true, composed: true }),\n );\n });\n\n treeEl!.addEventListener(`item-click`, (e) => {\n e.stopPropagation();\n const item = (e.detail.node as TreeNode).item.data as T | undefined;\n if (item === undefined)\n return;\n const detail: SubComponentItemClickDetail<T> = { item };\n container.dispatchEvent(\n new CustomEvent(`item-click`, { detail, bubbles: true, composed: true }),\n );\n });\n\n treeEl!.addEventListener(`tickle`, (e) => {\n e.stopPropagation();\n const item = (e.detail.node as TreeNode).item.data as T | undefined;\n if (item === undefined)\n return;\n const detail: SubComponentTickleDetail<T> = { item };\n container.dispatchEvent(\n new CustomEvent(`tickle`, { detail, bubbles: true, composed: true }),\n );\n });\n }\n\n // ---- IGroupedSubComponent implementation ----\n\n let selectionMode: ListSelectionMode = `single`;\n\n const adapter = Object.assign(container, {\n setItems(items: readonly T[]): void {\n const tree = getOrCreateTree();\n tree.root = {\n item: { key: `__adapter_root__`, label: ``, isLeaf: false },\n children: items.map(buildNode),\n };\n },\n\n clearSelection(): void {\n treeEl?.clearSelection();\n },\n\n dispatch(commandId: CommandId, args?: Record<string, unknown>): void {\n options?.onDispatch?.(commandId, args, treeEl);\n },\n });\n\n Object.defineProperties(adapter, {\n selectedItems: {\n get(): ReadonlySet<T> {\n return treeEl ? mapNodes(treeEl.selectedNodes) : new Set<T>();\n },\n enumerable: true,\n configurable: true,\n },\n selectionMode: {\n get(): ListSelectionMode {\n return selectionMode;\n },\n set(v: ListSelectionMode) {\n selectionMode = v;\n if (!treeEl)\n return;\n if (v === `none`) {\n treeEl.selectionFilter = `none`;\n } else if (v === `single`) {\n treeEl.selectionFilter = options?.selectionFilter ?? `all`;\n treeEl.interactionMode = `implicit`;\n } else {\n treeEl.selectionFilter = options?.selectionFilter ?? `all`;\n treeEl.interactionMode = options?.interactionMode ?? `standard`;\n }\n },\n enumerable: true,\n configurable: true,\n },\n });\n\n return adapter as unknown as HTMLElement & IGroupedSubComponent<T>;\n}\n","import type { CommandId } from '@clinth/ui-commands';\nimport type { ListInteractionMode, ListSelectionMode } from '../vertical-list/types.js';\nimport type { VerticalListElement } from '../vertical-list/vertical-list.js';\nimport type { IGroupedSubComponent, SubComponentSelectDetail } from './types.js';\nimport '../vertical-list/vertical-list.js';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type VerticalListAdapterOptions = {\n /** Initial selection mode forwarded to the inner ixfx-vertical-list. Default: `'single'`. */\n selectionMode?: ListSelectionMode;\n\n /** Interaction mode forwarded to the inner ixfx-vertical-list. Default: `'standard'`. */\n interactionMode?: ListInteractionMode;\n\n /**\n * Called when a command is dispatched via `ixfx-grouped-item-lister.dispatch()`.\n *\n * Receives the current inner `VerticalListElement` (undefined until the first\n * `setItems()` call) so the handler can sort, filter, or otherwise mutate the\n * list directly.\n *\n * @example Sort items alphabetically by text content:\n * ```ts\n * onDispatch: (id, _args, list) => {\n * if (id !== 'sort-alpha' || !list) return;\n * const rows = [...list.querySelectorAll<HTMLElement>('li')];\n * rows.sort((a, b) => (a.textContent ?? '').localeCompare(b.textContent ?? ''));\n * for (const row of rows) list.appendChild(row);\n * }\n * ```\n */\n onDispatch?: (\n commandId: CommandId,\n args: Record<string, unknown> | undefined,\n list: VerticalListElement | undefined,\n ) => void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates an `HTMLElement` that implements `IGroupedSubComponent<T>` by wrapping\n * an `ixfx-vertical-list` internally.\n *\n * Items are typed as `T`. The `renderItem` function converts each item to a DOM\n * element (typically an `<li>`) that `ixfx-vertical-list` renders and handles\n * pointer/keyboard interaction for.\n *\n * The returned element bridges the `list-*` event names fired by\n * `ixfx-vertical-list` to the `select / activate / item-click / tickle` names\n * required by `IGroupedSubComponent`, and maps element-based selection sets back\n * to typed `T` values.\n *\n * @example Basic usage with ixfx-grouped-item-lister:\n * ```ts\n * lister.factory = () =>\n * createVerticalListAdapter<MyItem>(item => {\n * const li = document.createElement('li');\n * li.textContent = item.label;\n * return li;\n * });\n * ```\n */\nexport function createVerticalListAdapter<T>(\n renderItem: (item: T) => Element,\n options?: VerticalListAdapterOptions,\n): HTMLElement & IGroupedSubComponent<T> {\n // Plain div — not a custom element, so appendChild is safe at any time.\n // display:contents makes it invisible in layout; the inner list is treated\n // as if it were a direct child of whatever the adapter is placed inside.\n const container = document.createElement(`div`);\n container.style.cssText = `display:contents;`;\n\n let listEl: VerticalListElement | undefined;\n let selectionMode: ListSelectionMode = options?.selectionMode ?? `single`;\n let elToItem = new WeakMap<Element, T>();\n\n // ---- Internal helpers ----\n\n function getOrCreateList(): VerticalListElement {\n if (listEl)\n return listEl;\n\n listEl = document.createElement(`ixfx-vertical-list`) as VerticalListElement;\n // Override :host { height:100% } so the list sizes to its content\n // when placed inside a panel with no explicit height.\n listEl.style.cssText = `height:auto;width:100%;`;\n listEl.selectionMode = selectionMode;\n if (options?.interactionMode)\n listEl.interactionMode = options.interactionMode;\n\n container.appendChild(listEl);\n attachBridgeListeners();\n\n return listEl;\n }\n\n function attachBridgeListeners(): void {\n listEl!.addEventListener(`list-select`, (e) => {\n const detail: SubComponentSelectDetail<T> = {\n selected: mapEls(e.detail.selected),\n previous: mapEls(e.detail.previous),\n };\n container.dispatchEvent(\n new CustomEvent(`select`, { detail, bubbles: true, composed: true }),\n );\n });\n\n listEl!.addEventListener(`list-activate`, (e) => {\n const item = elToItem.get(e.detail.item);\n if (item !== undefined) {\n container.dispatchEvent(\n new CustomEvent(`activate`, { detail: { item }, bubbles: true, composed: true }),\n );\n }\n });\n\n listEl!.addEventListener(`list-item-click`, (e) => {\n const item = elToItem.get(e.detail.item);\n if (item !== undefined) {\n container.dispatchEvent(\n new CustomEvent(`item-click`, { detail: { item }, bubbles: true, composed: true }),\n );\n }\n });\n\n listEl!.addEventListener(`list-tickle`, (e) => {\n const item = elToItem.get(e.detail.item);\n if (item !== undefined) {\n container.dispatchEvent(\n new CustomEvent(`tickle`, { detail: { item }, bubbles: true, composed: true }),\n );\n }\n });\n }\n\n function applyItems(items: readonly T[]): void {\n const list = getOrCreateList();\n list.clearItems();\n elToItem = new WeakMap();\n for (const item of items) {\n const el = renderItem(item);\n elToItem.set(el, item);\n list.addItem(el);\n }\n }\n\n function mapEls(els: ReadonlySet<Element>): ReadonlySet<T> {\n const result = new Set<T>();\n for (const el of els) {\n const item = elToItem.get(el);\n if (item !== undefined)\n result.add(item);\n }\n return result;\n }\n\n // ---- IGroupedSubComponent methods ----\n\n const adapter = Object.assign(container, {\n setItems(items: readonly T[]): void {\n applyItems(items);\n },\n\n clearSelection(): void {\n listEl?.clearSelection();\n },\n\n dispatch(commandId: CommandId, args?: Record<string, unknown>): void {\n options?.onDispatch?.(commandId, args, listEl);\n },\n });\n\n // Getters/setters require defineProperties — Object.assign would invoke them\n Object.defineProperties(adapter, {\n selectedItems: {\n get(): ReadonlySet<T> {\n return listEl ? mapEls(listEl.selectedItems) : new Set<T>();\n },\n enumerable: true,\n configurable: true,\n },\n selectionMode: {\n get(): ListSelectionMode {\n return listEl?.selectionMode ?? selectionMode;\n },\n set(v: ListSelectionMode) {\n selectionMode = v;\n if (listEl)\n listEl.selectionMode = v;\n },\n enumerable: true,\n configurable: true,\n },\n });\n\n return adapter as unknown as HTMLElement & IGroupedSubComponent<T>;\n}\n","/**\n * Hover preview for crowded nodes: a small popover listing a node's\n * children, shown when some of them can't be read in the current view —\n * their labels were culled, or they're beyond `maxRadius`. Each entry is\n * clickable, so a crowd can be browsed without dragging it into view.\n */\n\nimport type { TreeNode } from '../common/types.js';\nimport type { ZoomState } from './gestures.js';\nimport type { HyperbolicLayoutNode, Point } from './types.js';\nimport { html, nothing } from 'lit';\n\n/** At most this many children are listed; the rest are summarised as \"+N more\". */\nexport const PREVIEW_MAX_ITEMS = 12;\n\nexport type ChildPreview = {\n readonly node: TreeNode;\n /** Anchor point, in CSS px from the host's top-left corner. */\n readonly anchor: Point;\n /** Open upward (the node is in the lower half), so the popover stays inside the host. */\n readonly above: boolean;\n};\n\nexport type ChildPreviewHandlers = {\n readonly onPointerEnter: () => void;\n readonly onPointerLeave: () => void;\n readonly onPick: (child: TreeNode) => void;\n};\n\n/**\n * Whether `n` deserves a preview: it has children and at least one of them\n * isn't legible right now — laid out without a label, or not laid out at\n * all (outside the `maxRadius` window).\n */\nexport function needsChildPreview(\n n: HyperbolicLayoutNode,\n visible: readonly HyperbolicLayoutNode[],\n labelIds: ReadonlySet<string>,\n): boolean {\n const children = n.node.children ?? [];\n if (children.length === 0)\n return false;\n const shown = visible.filter(v => v.parentId === n.id);\n return shown.length < children.length || shown.some(v => !labelIds.has(v.id));\n}\n\n/** Where node position `p` (disk units) lands on screen, in CSS px from the host's top-left. */\nexport function diskToHostPx(p: Point, zoom: ZoomState, width: number, height: number): Point {\n const pxPerUnit = Math.min(width, height) / 2.1;\n return {\n x: width / 2 + (zoom.offset.x + zoom.zoom * p.x) * pxPerUnit,\n y: height / 2 + (zoom.offset.y + zoom.zoom * p.y) * pxPerUnit,\n };\n}\n\nexport function renderChildPreview(preview: ChildPreview | undefined, handlers: ChildPreviewHandlers): unknown {\n if (!preview)\n return nothing;\n const children = preview.node.children ?? [];\n const listed = children.slice(0, PREVIEW_MAX_ITEMS);\n const more = children.length - listed.length;\n return html`\n <div\n class=\"child-preview ${preview.above ? `above` : `below`}\"\n part=\"child-preview\"\n role=\"dialog\"\n aria-label=${`Children of ${preview.node.item.label}`}\n style=\"left: ${preview.anchor.x}px; top: ${preview.anchor.y}px\"\n @pointerenter=${handlers.onPointerEnter}\n @pointerleave=${handlers.onPointerLeave}\n @pointerdown=${(e: PointerEvent) => e.stopPropagation()}\n >\n <div class=\"child-preview-title\">${preview.node.item.label}</div>\n <ul>\n ${listed.map(child => html`<li>\n <button type=\"button\" tabindex=\"-1\" @click=${() => handlers.onPick(child)}>${child.item.label}</button>\n </li>`)}\n </ul>\n ${more > 0 ? html`<div class=\"child-preview-more\">+${more} more</div>` : nothing}\n </div>\n `;\n}\n\nexport type ChildPreviewHost = {\n /** The node `id` refers to if it should be previewed now, else `undefined`. */\n readonly candidate: (id: string | undefined) => string | undefined;\n readonly setPreviewId: (id: string | undefined) => void;\n};\n\n/** How long a preview lingers after the pointer leaves its node — time to reach the popover. */\nexport const PREVIEW_HIDE_DELAY_MS = 250;\n\n/**\n * Show/hide timing for the preview: shows at once for a qualifying node;\n * otherwise hides after a short grace period, unless the pointer is over the\n * popover itself — so it can travel from the node onto the list.\n */\nexport function createChildPreviewTiming(host: ChildPreviewHost) {\n let hovered = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const update = (id: string | undefined): void => {\n clearTimeout(timer);\n const candidate = host.candidate(id);\n if (candidate !== undefined) {\n host.setPreviewId(candidate);\n return;\n }\n timer = setTimeout(() => {\n if (!hovered)\n host.setPreviewId(undefined);\n }, PREVIEW_HIDE_DELAY_MS);\n };\n return {\n update,\n pointerEnter(): void {\n hovered = true;\n clearTimeout(timer);\n },\n pointerLeave(tickledId: string | undefined): void {\n hovered = false;\n update(tickledId);\n },\n hide(): void {\n hovered = false;\n clearTimeout(timer);\n host.setPreviewId(undefined);\n },\n dispose(): void {\n clearTimeout(timer);\n },\n };\n}\n","/**\n * Pure hyperbolic geometry primitives for the Poincaré disk model.\n * No Lit, no DOM — unit-testable in isolation.\n *\n * Points are represented as `{ x, y }`, read as the complex number `x + yi`.\n * All translation functions are hyperbolic isometries: they preserve\n * pairwise Poincaré distances between points.\n */\n\nimport type { Point } from './types.js';\n\nconst EPSILON = 1e-9;\n\nfunction complexMul(a: Point, b: Point): Point {\n return { x: a.x * b.x - a.y * b.y, y: a.x * b.y + a.y * b.x };\n}\n\nfunction complexConjugate(a: Point): Point {\n return { x: a.x, y: -a.y };\n}\n\nfunction complexAdd(a: Point, b: Point): Point {\n return { x: a.x + b.x, y: a.y + b.y };\n}\n\nfunction complexSub(a: Point, b: Point): Point {\n return { x: a.x - b.x, y: a.y - b.y };\n}\n\nfunction complexScale(a: Point, s: number): Point {\n return { x: a.x * s, y: a.y * s };\n}\n\nfunction complexDiv(a: Point, b: Point): Point {\n const denominator = b.x * b.x + b.y * b.y;\n if (denominator < EPSILON)\n return { x: 0, y: 0 };\n return complexScale(complexMul(a, complexConjugate(b)), 1 / denominator);\n}\n\n/** Euclidean norm (`|z|`) of a point. */\nexport function norm(a: Point): number {\n return Math.hypot(a.x, a.y);\n}\n\n/** Clamp a point to stay strictly inside the unit disk (the Poincaré model's boundary is never reached). */\nexport function clampToDisk(p: Point, maxNorm = 0.999999): Point {\n const n = norm(p);\n if (n <= maxNorm)\n return p;\n return complexScale(p, maxNorm / n);\n}\n\n/**\n * Möbius transform that translates `a` to the origin: `(z - a) / (1 - conj(a) * z)`.\n * A hyperbolic isometry — preserves all pairwise Poincaré distances.\n */\nexport function mobiusToOrigin(z: Point, a: Point): Point {\n const numerator = complexSub(z, a);\n const denominator = complexSub({ x: 1, y: 0 }, complexMul(complexConjugate(a), z));\n return clampToDisk(complexDiv(numerator, denominator));\n}\n\n/**\n * Inverse of {@link mobiusToOrigin}: translates the origin back to `a`, i.e.\n * `(z + a) / (1 + conj(a) * z)`.\n */\nexport function mobiusFromOrigin(z: Point, a: Point): Point {\n const numerator = complexAdd(z, a);\n const denominator = complexAdd({ x: 1, y: 0 }, complexMul(complexConjugate(a), z));\n return clampToDisk(complexDiv(numerator, denominator));\n}\n\n/**\n * Möbius addition (gyrogroup composition) of two disk-translations: the\n * canonical-space point reached by translating the origin to `a`, then\n * translating that local frame's origin by `b`.\n */\nexport function mobiusAdd(a: Point, b: Point): Point {\n return mobiusFromOrigin(b, a);\n}\n\n/** Euclidean Poincaré-disk radius corresponding to hyperbolic distance `d` from the origin. */\nexport function euclideanRadiusForHyperbolicDistance(d: number): number {\n return Math.tanh(d / 2);\n}\n\n/** Hyperbolic distance from the origin corresponding to Euclidean disk radius `r`. */\nexport function hyperbolicDistanceForEuclideanRadius(r: number): number {\n return 2 * Math.atanh(Math.min(Math.max(r, 0), 0.999999));\n}\n\n/** Hyperbolic (Poincaré) distance between two points in the unit disk. */\nexport function poincareDistance(p: Point, q: Point): number {\n const translated = mobiusToOrigin(q, p);\n return hyperbolicDistanceForEuclideanRadius(norm(translated));\n}\n\n/**\n * Point at parameter `t` (0–1) along the hyperbolic geodesic from `a` to `b`.\n * `t=0` yields `a`, `t=1` yields `b`; intermediate values move at constant\n * hyperbolic speed along the geodesic (not the Euclidean straight line).\n */\nexport function geodesicInterpolate(a: Point, b: Point, t: number): Point {\n if (t <= 0)\n return a;\n if (t >= 1)\n return b;\n const bLocal = mobiusToOrigin(b, a);\n const localNorm = norm(bLocal);\n if (localNorm < EPSILON)\n return a;\n const direction = complexScale(bLocal, 1 / localNorm);\n const hyperbolicDistance = hyperbolicDistanceForEuclideanRadius(localNorm);\n const stepRadius = euclideanRadiusForHyperbolicDistance(hyperbolicDistance * t);\n const local = complexScale(direction, stepRadius);\n return mobiusFromOrigin(local, a);\n}\n\n/**\n * An orientation-preserving isometry of the Poincaré disk, stored as the\n * SU(1,1) pair `(a, b)` of the map `z ↦ (a·z + b) / (conj(b)·z + conj(a))`.\n *\n * Every disk isometry is a translation *plus a rotation*, and composing two\n * translations generally yields a rotation too (the hyperbolic \"gyration\").\n * Tracking the full map — rather than just \"the point that goes to the\n * origin\" — is what keeps a recursively-built local frame correctly oriented.\n */\nexport type DiskIsometry = {\n readonly a: Point;\n readonly b: Point;\n};\n\nexport const identityIsometry: DiskIsometry = { a: { x: 1, y: 0 }, b: { x: 0, y: 0 } };\n\n/** Apply `m` to `z`. */\nexport function applyIsometry(m: DiskIsometry, z: Point): Point {\n const numerator = complexAdd(complexMul(m.a, z), m.b);\n const denominator = complexAdd(complexMul(complexConjugate(m.b), z), complexConjugate(m.a));\n return clampToDisk(complexDiv(numerator, denominator));\n}\n\n/** `outer ∘ inner` — apply `inner` first, then `outer`. */\nexport function composeIsometry(outer: DiskIsometry, inner: DiskIsometry): DiskIsometry {\n const a = complexAdd(complexMul(outer.a, inner.a), complexMul(outer.b, complexConjugate(inner.b)));\n const b = complexAdd(complexMul(outer.a, inner.b), complexMul(outer.b, complexConjugate(inner.a)));\n // Renormalise so |a|² − |b|² = 1, stopping floating-point drift over deep compositions.\n const det = Math.sqrt(Math.max(EPSILON, a.x * a.x + a.y * a.y - b.x * b.x - b.y * b.y));\n return { a: complexScale(a, 1 / det), b: complexScale(b, 1 / det) };\n}\n\nexport function invertIsometry(m: DiskIsometry): DiskIsometry {\n return { a: complexConjugate(m.a), b: complexScale(m.b, -1) };\n}\n\n/** Pure translation carrying the origin to `p` (same map as {@link mobiusFromOrigin}). */\nexport function translationFromOrigin(p: Point): DiskIsometry {\n const scale = 1 / Math.sqrt(Math.max(EPSILON, 1 - p.x * p.x - p.y * p.y));\n return { a: { x: scale, y: 0 }, b: complexScale(p, scale) };\n}\n\n/** `z ↦ e^{iθ}·z`. */\nexport function rotationIsometry(theta: number): DiskIsometry {\n return { a: { x: Math.cos(theta / 2), y: Math.sin(theta / 2) }, b: { x: 0, y: 0 } };\n}\n\n/**\n * The view map that sends canonical point `center` to the origin, then\n * rotates by `rotation` radians: `z ↦ e^{i·rotation}·mobiusToOrigin(z, center)`.\n */\nexport function viewIsometry(center: Point, rotation = 0): DiskIsometry {\n return composeIsometry(rotationIsometry(rotation), invertIsometry(translationFromOrigin(center)));\n}\n\n/** Decompose `m` into the `{ center, rotation }` accepted by {@link viewIsometry}. */\nexport function decomposeViewIsometry(m: DiskIsometry): { center: Point; rotation: number } {\n const center = applyIsometry(invertIsometry(m), { x: 0, y: 0 });\n return { center, rotation: 2 * Math.atan2(m.a.y, m.a.x) };\n}\n\n/**\n * Exact geodesic between `p` and `q`, for rendering: either a straight\n * segment (when the geodesic is a diameter) or a circular arc orthogonal to\n * the unit circle. `sweep` follows SVG's `sweep-flag` convention in the\n * points' own (unflipped) coordinate system; the in-disk segment of an\n * orthogonal circle is always less than a semicircle, so it's always the\n * minor arc.\n */\nexport type GeodesicSegment\n = | { readonly kind: `line` }\n | { readonly kind: `arc`; readonly center: Point; readonly radius: number; readonly sweep: 0 | 1 };\n\nexport function geodesicSegment(p: Point, q: Point): GeodesicSegment {\n // Circle centre c orthogonal to the unit circle through p satisfies 2c·p = |p|² + 1.\n const det = p.x * q.y - p.y * q.x;\n const chord = Math.hypot(q.x - p.x, q.y - p.y);\n // Near-collinear with the origin ⇒ the geodesic is (numerically) a diameter.\n if (Math.abs(det) < 1e-6 * Math.max(chord, EPSILON))\n return { kind: `line` };\n const rp = (p.x * p.x + p.y * p.y + 1) / 2;\n const rq = (q.x * q.x + q.y * q.y + 1) / 2;\n const center: Point = { x: (rp * q.y - rq * p.y) / det, y: (p.x * rq - q.x * rp) / det };\n const radius = Math.sqrt(Math.max(0, center.x * center.x + center.y * center.y - 1));\n const cross = (p.x - center.x) * (q.y - center.y) - (p.y - center.y) * (q.x - center.x);\n return { kind: `arc`, center, radius, sweep: cross > 0 ? 1 : 0 };\n}\n\n/** SVG path `d` for the geodesic from `p` to `q`, with coordinates multiplied by `scale`. */\nexport function geodesicPath(p: Point, q: Point, scale = 1): string {\n const fmt = (n: number): string => (n * scale).toFixed(2);\n const segment = geodesicSegment(p, q);\n const start = `M${fmt(p.x)},${fmt(p.y)}`;\n if (segment.kind === `line` || segment.radius * scale > 1e6)\n return `${start} L${fmt(q.x)},${fmt(q.y)}`;\n return `${start} A${fmt(segment.radius)},${fmt(segment.radius)} 0 0 ${segment.sweep} ${fmt(q.x)},${fmt(q.y)}`;\n}\n","/**\n * Pure view-transform maths for moving the hyperbolic-tree view: panning\n * and focus-change animation. No Lit, no DOM state — the element owns the\n * current view and feeds pointer positions / animation progress in here.\n */\n\nimport type { DiskIsometry } from './poincare-math.js';\nimport type { Point } from './types.js';\nimport {\n composeIsometry,\n decomposeViewIsometry,\n geodesicInterpolate,\n invertIsometry,\n mobiusToOrigin,\n translationFromOrigin,\n viewIsometry,\n} from './poincare-math.js';\n\n/** Wrap an angle into `(-π, π]`. */\nexport function wrapAngle(theta: number): number {\n return Math.atan2(Math.sin(theta), Math.cos(theta));\n}\n\nexport function easeInOutCubic(t: number): number {\n return t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2;\n}\n\nexport function prefersReducedMotion(): boolean {\n return typeof matchMedia === `function` && matchMedia(`(prefers-reduced-motion: reduce)`).matches;\n}\n\n/**\n * The view after dragging from `start` to `current` (both disk\n * coordinates), starting from `baseView`. Applies the hyperbolic translation\n * along the geodesic carrying the grabbed point to the pointer — a true\n * isometry, so the grabbed point tracks the pointer exactly and the tree\n * never distorts. (Adding a Euclidean offset to the canonical center\n * instead is not an isometry: it lurches badly near the disk boundary.)\n */\nexport function panView(baseView: DiskIsometry, start: Point, current: Point): DiskIsometry {\n const toStart = translationFromOrigin(start);\n const step = translationFromOrigin(mobiusToOrigin(current, start));\n const pan = composeIsometry(toStart, composeIsometry(step, invertIsometry(toStart)));\n return composeIsometry(pan, baseView);\n}\n\n/**\n * A focus-change animation from view `from` — the old view, re-expressed in\n * the *new* focus's local frame, so the new focus currently sits somewhere\n * off-center — to a settled view with the new focus at the center. The\n * center travels along the hyperbolic geodesic; the rotation is held, so the\n * tree glides into place without spinning, and the settled view keeps\n * whatever orientation it arrived with (`settledRotation`).\n */\nexport function focusTransition(from: DiskIsometry): { viewAt: (t: number) => DiskIsometry; settledRotation: number } {\n const { center, rotation } = decomposeViewIsometry(from);\n const settledRotation = wrapAngle(rotation);\n const origin: Point = { x: 0, y: 0 };\n return {\n settledRotation,\n viewAt: (t: number) => {\n const eased = easeInOutCubic(Math.min(1, Math.max(0, t)));\n return viewIsometry(geodesicInterpolate(center, origin, eased), settledRotation);\n },\n };\n}\n","/**\n * Pointer and wheel gestures for the hyperbolic tree: one-pointer hyperbolic\n * panning, two-pointer (touch) pinch zoom, and wheel/trackpad-pinch zoom\n * anchored at the pointer. Functional: `createGestureHandlers` closes over\n * the gesture's transient state and talks to the element only through a\n * {@link GestureHost}.\n */\n\nimport type { DiskIsometry } from './poincare-math.js';\nimport type { Point } from './types.js';\nimport { clampToDisk } from './poincare-math.js';\nimport { panView } from './view-motion.js';\n\n/** Euclidean magnification of the rendered disk: `screen = offset + zoom · disk`. */\nexport type ZoomState = {\n readonly zoom: number;\n /** Translation, in screen units (disk radii, before zoom), of the disk center from the view center. */\n readonly offset: Point;\n};\n\nexport const MIN_ZOOM = 0.5;\nexport const MAX_ZOOM = 8;\n\n/**\n * Keep the view center over the disk (so you can't zoom off into empty\n * space), and re-center entirely once the whole disk fits again.\n */\nexport function clampZoomState(state: ZoomState): ZoomState {\n const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, state.zoom));\n if (zoom <= 1)\n return { zoom, offset: { x: 0, y: 0 } };\n const limit = zoom - 1;\n const length = Math.hypot(state.offset.x, state.offset.y);\n const offset = length > limit ? { x: state.offset.x * limit / length, y: state.offset.y * limit / length } : state.offset;\n return { zoom, offset };\n}\n\n/**\n * Zoom by `factor` keeping the disk point under `screenPoint` fixed on\n * screen — the \"zoom where I'm pointing\" behaviour of maps and image viewers.\n */\nexport function zoomAt(state: ZoomState, screenPoint: Point, factor: number): ZoomState {\n const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, state.zoom * factor));\n const disk = screenToDisk(screenPoint, state);\n return clampZoomState({ zoom, offset: { x: screenPoint.x - zoom * disk.x, y: screenPoint.y - zoom * disk.y } });\n}\n\n/**\n * A client-space position in screen units: disk radii from the SVG's center,\n * before zoom. The disk fills the SVG's smaller dimension, with the\n * viewBox's 5% margin.\n */\nexport function clientToScreen(rect: DOMRectReadOnly, clientX: number, clientY: number): Point {\n const unitsPerPixel = 2.1 / (Math.min(rect.width, rect.height) || 1);\n return {\n x: (clientX - (rect.left + rect.width / 2)) * unitsPerPixel,\n y: (clientY - (rect.top + rect.height / 2)) * unitsPerPixel,\n };\n}\n\nexport function screenToDisk(p: Point, state: ZoomState): Point {\n const zoom = state.zoom || 1;\n return { x: (p.x - state.offset.x) / zoom, y: (p.y - state.offset.y) / zoom };\n}\n\nexport type GestureHost = {\n readonly svgRect: () => DOMRectReadOnly | undefined;\n /** The current view, freezing any in-flight focus animation. */\n readonly takeView: () => DiskIsometry;\n readonly setView: (view: DiskIsometry) => void;\n readonly zoomState: () => ZoomState;\n readonly setZoomState: (state: ZoomState) => void;\n readonly zoomGesturesEnabled: () => boolean;\n /** Whether keyboard focus is within the tree — gates plain (unmodified) wheel zoom. */\n readonly hasFocus: () => boolean;\n readonly focusTree: () => void;\n};\n\ntype Pinch = {\n readonly ids: readonly [number, number];\n readonly startDistance: number;\n readonly startZoom: number;\n /** The disk point under the pinch midpoint when it started — kept under the midpoint. */\n readonly anchor: Point;\n};\n\n/** Is `event` on empty disk space (the SVG itself or the boundary circle), rather than a node? */\nfunction isBackground(event: PointerEvent): boolean {\n const target = event.target as Element | null;\n return target === event.currentTarget || target?.classList.contains(`disk-boundary`) === true;\n}\n\nexport function createGestureHandlers(host: GestureHost) {\n const pointers = new Map<number, Point>();\n let pan: { pointerId: number; start: Point; baseView: DiskIsometry } | undefined;\n let pinch: Pinch | undefined;\n\n const screenOf = (event: PointerEvent | WheelEvent): Point | undefined => {\n const rect = host.svgRect();\n return rect ? clientToScreen(rect, event.clientX, event.clientY) : undefined;\n };\n const diskOf = (screen: Point): Point => clampToDisk(screenToDisk(screen, host.zoomState()), 0.98);\n const midpoint = (a: Point, b: Point): Point => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 });\n\n const startPan = (pointerId: number, screen: Point): void => {\n pan = { pointerId, start: diskOf(screen), baseView: host.takeView() };\n };\n\n const startPinch = (): void => {\n const [[idA, a], [idB, b]] = [...pointers.entries()];\n pan = undefined;\n const { zoom } = host.zoomState();\n pinch = {\n ids: [idA, idB],\n startDistance: Math.max(1e-6, Math.hypot(a.x - b.x, a.y - b.y)),\n startZoom: zoom,\n anchor: screenToDisk(midpoint(a, b), host.zoomState()),\n };\n };\n\n return {\n onPointerDown(event: PointerEvent): void {\n if (!isBackground(event))\n return;\n host.focusTree();\n const screen = screenOf(event);\n if (!screen)\n return;\n (event.currentTarget as Element).setPointerCapture?.(event.pointerId);\n pointers.set(event.pointerId, screen);\n if (pointers.size === 2 && host.zoomGesturesEnabled())\n startPinch();\n else if (pointers.size === 1)\n startPan(event.pointerId, screen);\n },\n\n onPointerMove(event: PointerEvent): void {\n if (!pointers.has(event.pointerId))\n return;\n const screen = screenOf(event);\n if (!screen)\n return;\n pointers.set(event.pointerId, screen);\n if (pinch) {\n const a = pointers.get(pinch.ids[0]);\n const b = pointers.get(pinch.ids[1]);\n if (!a || !b)\n return;\n const zoom = pinch.startZoom * Math.hypot(a.x - b.x, a.y - b.y) / pinch.startDistance;\n const mid = midpoint(a, b);\n const clampedZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n host.setZoomState(clampZoomState({\n zoom: clampedZoom,\n offset: { x: mid.x - clampedZoom * pinch.anchor.x, y: mid.y - clampedZoom * pinch.anchor.y },\n }));\n } else if (pan && pan.pointerId === event.pointerId) {\n host.setView(panView(pan.baseView, pan.start, diskOf(screen)));\n }\n },\n\n onPointerUp(event: PointerEvent): void {\n if (!pointers.delete(event.pointerId))\n return;\n if (pinch) {\n pinch = undefined;\n // Carry on panning with whichever finger is still down.\n const [remaining] = [...pointers.entries()];\n if (remaining)\n startPan(remaining[0], remaining[1]);\n } else if (pan?.pointerId === event.pointerId) {\n pan = undefined;\n }\n },\n\n /**\n * Ctrl/⌘-wheel — which is also what a trackpad pinch produces — always\n * zooms while the pointer is over the tree. A plain wheel only zooms\n * once the tree has keyboard focus (the library's focus-gated wheel\n * convention), so scrolling past it doesn't get hijacked.\n */\n onWheel(event: WheelEvent): void {\n const modified = event.ctrlKey || event.metaKey;\n if (!host.zoomGesturesEnabled() || (!modified && !host.hasFocus()))\n return;\n const screen = screenOf(event);\n if (!screen)\n return;\n event.preventDefault();\n const delta = event.deltaMode === 1 ? event.deltaY * 16 : event.deltaY;\n const factor = Math.exp(-delta * (modified ? 0.01 : 0.002));\n host.setZoomState(zoomAt(host.zoomState(), screen, factor));\n },\n\n /** Forget any in-progress pan (e.g. when a focus change takes over the view). */\n cancel(): void {\n pan = undefined;\n pinch = undefined;\n pointers.clear();\n },\n };\n}\n","import { css } from 'lit';\n\n/** Shadow-DOM styles for `ixfx-hyperbolictree-list`. */\nexport const hyperbolicTreeStyles = css`\n :host {\n --hyperbolictree-node-color: var(--surface-4);\n --hyperbolictree-node-text: var(--surface-3-text);\n --hyperbolictree-edge-color: var(--surface-6);\n --hyperbolictree-boundary-color: var(--border-subtle);\n /* Real screen px — converted to SVG units from the element's rendered size. */\n --hyperbolictree-font-size: 13px;\n --hyperbolictree-box-color: var(--hyperbolictree-node-color);\n --hyperbolictree-box-text: var(--surface-4-text);\n --hyperbolictree-box-border: var(--surface-2);\n --hyperbolictree-branch-hue-start: 250;\n --hyperbolictree-branch-chroma: 0.13;\n --hyperbolictree-branch-lightness: 62%;\n --hyperbolictree-branch-mix: 55%;\n\n display: block;\n position: relative;\n overflow: hidden;\n outline: none;\n overscroll-behavior: contain;\n }\n\n /*\n * delegatesFocus means the host itself reports as focused whenever\n * the shadow DOM's focused descendant (the svg) is — without this,\n * the host also picks up the browser's own default focus ring/fill\n * sized to the whole box.\n */\n :host(:focus),\n :host(:focus-visible) {\n outline: none;\n }\n\n .hyperbolictree {\n display: block;\n width: 100%;\n height: 100%;\n outline: none;\n touch-action: none;\n overscroll-behavior: contain;\n }\n\n .disk-boundary {\n fill: none;\n stroke: var(--hyperbolictree-boundary-color);\n stroke-width: 1;\n }\n\n .edge {\n fill: none;\n stroke: var(--hyperbolictree-edge-color);\n /* --edge-weight (0..1, average of the endpoint nodes' --node-weight) thickens heavier edges. */\n stroke-width: calc(1px + var(--edge-weight, 0.5) * 3px);\n /* Constant on-screen width, however far the disk is zoomed. */\n vector-effect: non-scaling-stroke;\n }\n\n .node {\n cursor: pointer;\n }\n\n /*\n * color-by-branch: each top-level branch gets an evenly-spaced hue,\n * mixed into the normal node/box/edge colour (rather than replacing it)\n * so it stays in keeping with — and legible in — the current theme.\n * Only sets the base colour vars, so selected/tickled states still win.\n */\n :host([color-by-branch]) .node,\n :host([color-by-branch]) .edge {\n --_branch-color: oklch(\n var(--hyperbolictree-branch-lightness)\n var(--hyperbolictree-branch-chroma)\n calc(var(--hyperbolictree-branch-hue-start) + var(--branch-index) * 360 / var(--branch-count))\n );\n }\n\n :host([color-by-branch]) .node {\n --_node-base: color-mix(in oklab, var(--hyperbolictree-node-color), var(--_branch-color) var(--hyperbolictree-branch-mix));\n --_box-base: color-mix(in oklab, var(--hyperbolictree-box-color), var(--_branch-color) var(--hyperbolictree-branch-mix));\n }\n\n :host([color-by-branch]) .edge {\n stroke: color-mix(in oklab, var(--hyperbolictree-edge-color), var(--_branch-color) 50%);\n }\n\n .node-hit {\n fill: transparent;\n pointer-events: all;\n }\n\n .node-dot {\n /* --node-weight (0..1, normalized across the visible node set) tints toward --accent for heavier nodes. */\n fill: color-mix(in oklab, var(--_node-base, var(--hyperbolictree-node-color)), var(--accent) calc(var(--node-weight, 0.5) * 50%));\n stroke: var(--surface-2);\n stroke-width: 1;\n pointer-events: none;\n }\n\n .node-box {\n fill: color-mix(in oklab, var(--_box-base, var(--hyperbolictree-box-color)), var(--accent) calc(var(--node-weight, 0.5) * 25%));\n stroke: var(--hyperbolictree-box-border);\n stroke-width: 1.5;\n /* Keep the border crisp however far the box has been scaled down. */\n vector-effect: non-scaling-stroke;\n }\n\n /* Text-less stand-in for a box too small, or too crowded, to label. */\n .node-box.marker {\n stroke-width: 1;\n }\n\n /* Pure user-space font-size; set per render from --hyperbolictree-font-size. */\n .hyperbolictree-label {\n fill: var(--hyperbolictree-node-text);\n cursor: pointer;\n user-select: none;\n }\n\n .box-label {\n fill: var(--hyperbolictree-box-text);\n pointer-events: none;\n }\n\n /*\n * State fills come paired with their theme text tokens: a box label sits\n * on the state fill itself, so e.g. --item-bg-selected needs\n * --item-text-selected on top, not the resting box text colour.\n */\n .node.tickled .node-dot,\n .node.tickled .node-box {\n fill: var(--item-bg-tickled);\n }\n\n .node.tickled .box-label {\n fill: var(--item-text-tickled);\n }\n\n .node.selected .node-dot,\n .node.selected .node-box {\n fill: var(--item-bg-selected);\n }\n\n .node.selected .box-label {\n fill: var(--item-text-selected);\n }\n\n .node.selected.tickled .node-dot,\n .node.selected.tickled .node-box {\n fill: var(--item-bg-selected-tickled);\n }\n\n .node.focused .node-dot,\n .node.focused .node-box {\n stroke: var(--accent);\n stroke-width: 3;\n }\n\n /* A hovered label may sit over busy neighbours — give it a halo so it always reads. */\n .node.tickled .hyperbolictree-label:not(.box-label) {\n paint-order: stroke;\n stroke: var(--surface-2);\n stroke-width: 4px;\n stroke-linejoin: round;\n }\n\n .node.filtered {\n opacity: 0.3;\n }\n\n .node.loading .node-dot,\n .node.loading .node-box {\n opacity: 0.6;\n }\n\n \n /* Child preview: a clickable list of a crowded node's children. */\n .child-preview {\n position: absolute;\n z-index: 1;\n min-width: 8rem;\n max-width: min(18rem, 60%);\n max-height: 45%;\n overflow: auto;\n padding: var(--space-xs, 4px);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border-subtle);\n border-radius: var(--radius-m, 6px);\n box-shadow: var(--shadow-m);\n font-size: var(--hyperbolictree-font-size);\n transform: translate(-50%, 14px);\n }\n\n .child-preview.above {\n transform: translate(-50%, calc(-100% - 14px));\n }\n\n .child-preview-title {\n padding: 2px 6px 4px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .child-preview ul {\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .child-preview button {\n display: block;\n width: 100%;\n padding: 2px 6px;\n border: none;\n border-radius: var(--radius-s, 4px);\n background: none;\n color: inherit;\n font: inherit;\n text-align: start;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n }\n\n .child-preview button:hover {\n background: var(--item-bg-tickled);\n color: var(--item-text-tickled);\n }\n\n .child-preview-more {\n padding: 2px 6px;\n color: var(--surface-muted-text);\n }\n `;\n","/**\n * Pure hyperbolic-tree layout: `TreeNode` + focus + radius window → positioned\n * nodes/edges on the Poincaré disk. No Lit, no DOM — unit-testable in isolation.\n */\n\nimport type { TreeNode } from '../common/types.js';\nimport type { DiskIsometry } from './poincare-math.js';\nimport type { ComputeHyperbolicLayoutOptions, HyperbolicLayoutEdge, HyperbolicLayoutNode, Point } from './types.js';\nimport {\n applyIsometry,\n composeIsometry,\n euclideanRadiusForHyperbolicDistance,\n identityIsometry,\n invertIsometry,\n mobiusToOrigin,\n translationFromOrigin,\n viewIsometry,\n} from './poincare-math.js';\n\ntype CanonicalEntry = {\n readonly node: TreeNode;\n /** Path-derived id, unique even when `item.key`s repeat — see {@link hyperbolicChildIds}. */\n readonly id: string;\n readonly depth: number;\n readonly parentKey: string | undefined;\n readonly parentId: string | undefined;\n /**\n * Root-anchored position. Informational only: every step away from the\n * root pushes it exponentially closer to the disk boundary, so beyond\n * ~14 hyperbolic units (e.g. depth 5 at `curvature` 3) it saturates to the\n * clamp limit and distinct nodes collapse together. Views are built from\n * {@link toParent} instead — see {@link hyperbolicRelativeFrame}.\n */\n readonly position: Point;\n /**\n * This node's local frame expressed in its parent's local frame — the\n * single short hop (a translation by one generation) from parent to\n * child. Identity for the root. Composing these outward from the focus\n * keeps every visible position precise, however deep the focus sits.\n */\n readonly toParent: DiskIsometry;\n /** Angular width (radians) this node's own parent allocated to it — root is `2π`. */\n readonly angularShare: number;\n};\n\nconst ID_SEPARATOR = `\\u001F`;\n\n/**\n * Path-derived ids for `children` of the node with id `parentId`. `TreeItem.key`\n * is meant to be unique, but real data (e.g. a file system, where `readme.md`\n * recurs in many folders) often only has keys unique among siblings. Keying\n * the layout on `item.key` alone would silently merge those nodes — edges get\n * attached to the wrong parent and clicks focus the wrong node — so the\n * layout identifies nodes by their key path instead. Repeated keys among\n * siblings are disambiguated by occurrence count. The root's id is its key.\n */\nexport function hyperbolicChildIds(parentId: string, children: readonly TreeNode[]): string[] {\n const seen = new Map<string, number>();\n return children.map((child) => {\n const key = child.item.key;\n const count = seen.get(key) ?? 0;\n seen.set(key, count + 1);\n return `${parentId}${ID_SEPARATOR}${count === 0 ? key : `${key}#${count}`}`;\n });\n}\n\n/** Depth (root is 0) of the node with layout id `id`. */\nexport function hyperbolicIdDepth(id: string): number {\n return id.split(ID_SEPARATOR).length - 1;\n}\n\n/**\n * Layout id of the root's child that `id` descends from (or is) — i.e. which\n * top-level branch it belongs to. `undefined` for the root itself.\n */\nexport function hyperbolicBranchId(id: string): string | undefined {\n const parts = id.split(ID_SEPARATOR);\n return parts.length < 2 ? undefined : `${parts[0]}${ID_SEPARATOR}${parts[1]}`;\n}\n\n/** Whether layout id `id` is a strict descendant of `ancestorId`. */\nexport function isHyperbolicDescendantId(id: string, ancestorId: string): boolean {\n return id.startsWith(`${ancestorId}${ID_SEPARATOR}`);\n}\n\n/** Chain of nodes from `root` down to the node with layout id `id`, or `undefined` if absent. */\nexport function findHyperbolicPathById(root: TreeNode | undefined, id: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n const walk = (node: TreeNode, nodeId: string): TreeNode[] | undefined => {\n if (nodeId === id)\n return [node];\n if (!isHyperbolicDescendantId(id, nodeId))\n return undefined;\n const children = node.children ?? [];\n const ids = hyperbolicChildIds(nodeId, children);\n for (let i = 0; i < children.length; i++) {\n const hit = walk(children[i], ids[i]);\n if (hit)\n return [node, ...hit];\n }\n return undefined;\n };\n return walk(root, root.item.key);\n}\n\n/** Layout id of `target` (matched by object identity) within `root`, or `undefined` if absent. */\nexport function findHyperbolicIdOf(root: TreeNode | undefined, target: TreeNode): string | undefined {\n if (!root)\n return undefined;\n const walk = (node: TreeNode, nodeId: string): string | undefined => {\n if (node === target)\n return nodeId;\n const children = node.children ?? [];\n const ids = hyperbolicChildIds(nodeId, children);\n for (let i = 0; i < children.length; i++) {\n const hit = walk(children[i], ids[i]);\n if (hit !== undefined)\n return hit;\n }\n return undefined;\n };\n return walk(root, root.item.key);\n}\n\n/** Key path (from the root's children) to the first node, depth-first, satisfying `predicate`. */\nexport function findHyperbolicKeyPath(\n nodes: readonly TreeNode[],\n predicate: (node: TreeNode) => boolean,\n prefix: readonly 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 const hit = node.children?.length ? findHyperbolicKeyPath(node.children, predicate, path) : undefined;\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/** Depth-first search for the node with `key`. Returns `undefined` when absent. */\nexport function findHyperbolicNode(root: TreeNode | undefined, key: string): TreeNode | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const hit = findHyperbolicNode(child, key);\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/**\n * Chain of nodes from `root` down to (and including) the node with `key`.\n * Returns `undefined` when the key is absent. The first entry is always `root`.\n */\nexport function findHyperbolicPath(root: TreeNode | undefined, key: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return [root];\n for (const child of root.children ?? []) {\n const hit = findHyperbolicPath(child, key);\n if (hit)\n return [root, ...hit];\n }\n return undefined;\n}\n\n/**\n * Number of nodes in `node`'s subtree, counting `node` itself, up to\n * `remainingDepth` further levels (matching the canonical-position recursion's\n * own `maxDepth` cutoff, so weighting stays consistent with what's actually\n * laid out).\n */\nfunction subtreeSize(node: TreeNode, remainingDepth: number): number {\n if (remainingDepth <= 0)\n return 1;\n const children = node.children ?? [];\n if (children.length === 0)\n return 1;\n let total = 1;\n for (const child of children)\n total += subtreeSize(child, remainingDepth - 1);\n return total;\n}\n\n/**\n * Angle (as seen from `localOrigin`, i.e. after translating `localOrigin` to\n * the disk's center) of the disk-boundary point that currently sits at angle\n * `theta` from the true origin. Möbius translation is conformal but not\n * angle-preserving in the naive sense — a wedge boundary doesn't just shift\n * by a constant offset when reparented to a new local frame, its exact\n * transformed angle depends on how far off-center `localOrigin` is. Used to\n * carry a node's *own* angular wedge (inherited from its parent) into the\n * local frame of each of its children, rather than approximating it as\n * \"the opposite direction ± half the width\" — the same technique used by\n * reference hyperbolic-tree-browser implementations (e.g. d3-hypertree's\n * `wedgeTranslate`) to keep the recursive layout accurate at any depth/width.\n */\nfunction boundaryAngleInLocalFrame(theta: number, localOrigin: Point): number {\n const boundaryPoint: Point = { x: Math.cos(theta), y: Math.sin(theta) };\n const transformed = mobiusToOrigin(boundaryPoint, localOrigin);\n return Math.atan2(transformed.y, transformed.x);\n}\n\n/** Deterministic pseudo-random value in `[-1, 1]` derived from `key`, stable across renders. */\nfunction stableUnitJitter(key: string): number {\n let hash = 0;\n for (let i = 0; i < key.length; i++)\n hash = (Math.imul(hash, 31) + key.charCodeAt(i)) | 0;\n return ((hash >>> 0) % 1000) / 1000 * 2 - 1;\n}\n\n/**\n * A single unbranching child (no siblings to fan against) would otherwise sit\n * at the exact bisector of its inherited wedge — i.e. dead-center, continuing\n * in a perfectly straight line from its own parent's edge. For a chain of\n * such nodes (a deeply-nested path with no branching), that reads as one\n * unbroken line cutting across the disk rather than a legible sequence of\n * edges. Nudging by a small, key-derived (so stable across re-renders) angle\n * breaks that up — the same purpose served by the small per-node offsets in\n * reference hyperbolic-tree-browser implementations (e.g. d3-hypertree's\n * `layoutBergé`, which staggers leaf nodes rather than stacking them exactly\n * radially).\n */\nconst CHAIN_JITTER_RADIANS = 0.22;\n\n/** Default minimum hyperbolic distance between adjacent siblings. See {@link childDistance}. */\nexport const DEFAULT_SIBLING_SPACING = 0.5;\n\n/**\n * Hyperbolic distance from parent to a child whose angular slice (in the\n * parent's frame) is `share`, such that the child sits at least `spacing`\n * from a neighbour one slice-width away: from the hyperbolic law of cosines\n * for an isosceles triangle, `sinh(d/2) = sinh(L)·sin(Δθ/2)`, solved for L.\n * Never less than `minimum` (the `curvature`), and capped so a sliver-thin\n * slice can't fling a child off to infinity.\n *\n * This is what makes panning *useful* in a crowded fan: panning is an\n * isometry — it can't change the hyperbolic distance between siblings, only\n * move them to where the disk magnifies more. If siblings are laid out\n * nearly on top of each other in hyperbolic terms, no amount of dragging\n * separates them; guaranteeing a minimum spacing means dragging a crowd\n * towards the center always fans it out.\n */\nfunction childDistance(share: number, spacing: number, minimum: number): number {\n if (spacing <= 0)\n return minimum;\n const halfAngle = Math.min(share, Math.PI) / 2;\n const needed = Math.asinh(Math.sinh(spacing / 2) / Math.max(Math.sin(halfAngle), 1e-6));\n return Math.min(Math.max(minimum, needed), minimum + 6);\n}\n\n/**\n * Canonical (true-root-anchored) hyperbolic position of every currently-loaded\n * node, keyed by layout id (see {@link hyperbolicChildIds}). Positions never depend on the current focus —\n * refocusing is purely a Möbius re-projection of these fixed coordinates, so\n * the tree never needs to be re-laid-out when the focus changes.\n *\n * Each node holds an angular wedge — inherited from its parent, expressed in\n * its *own* local frame (root starts with the full `[-π, π]`) — across which\n * its children are placed at hyperbolic distance of at least `curvature`\n * (default `1`) — further for a thin slice, per `siblingSpacing` (see\n * {@link childDistance}).\n * That wedge is partitioned among the children, weighted by √ of each child's own\n * subtree size rather than split evenly, and each child's own share is\n * carried into its local frame via {@link boundaryAngleInLocalFrame} before\n * recursing. This is a strict partition, and each child's wedge region\n * (bounded by geodesic rays to the same two ideal boundary points as its\n * slice) nests inside its parent's, which is what guarantees sibling\n * subtrees never spatially cross regardless of how deep or bushy they are.\n *\n * Every node's local frame is tracked as a full {@link DiskIsometry}\n * (local → canonical), built by composing its parent's frame with the\n * translation to the child. Composing Möbius translations introduces a\n * rotation (gyration); dropping it — i.e. assuming a node's frame is simply\n * `mobiusToOrigin(·, position)` — makes every wedge from depth 3 onward\n * point in a subtly wrong direction, so subtrees cross each other.\n *\n * A wedge wider than π is narrowed to π (around the same bisector) before\n * the child recurses into it: a near-full-circle wedge would otherwise fan\n * that child's own children back around towards — and across — its parent.\n *\n * `curvature` scales how far apart (in hyperbolic distance) each generation\n * sits. Raising it pushes each generation further out, so the Poincaré\n * metric's own `tanh` compression crowds distant generations toward the\n * boundary faster — a stronger fisheye, which is why it reads as \"zooming\n * in\" on the focus. Lowering it spreads generations out more evenly,\n * flattening the view toward a Euclidean-feeling layout.\n */\nexport function computeCanonicalPositions(\n root: TreeNode | undefined,\n maxDepth = 24,\n curvature = 1,\n siblingSpacing = DEFAULT_SIBLING_SPACING,\n): Map<string, CanonicalEntry> {\n const map = new Map<string, CanonicalEntry>();\n if (!root)\n return map;\n const origin: Point = { x: 0, y: 0 };\n map.set(root.item.key, {\n node: root,\n id: root.item.key,\n depth: 0,\n parentKey: undefined,\n parentId: undefined,\n position: origin,\n toParent: identityIsometry,\n angularShare: 2 * Math.PI,\n });\n\n const place = (\n node: TreeNode,\n id: string,\n frame: DiskIsometry,\n wedgeStart: number,\n wedgeEnd: number,\n depth: number,\n ): void => {\n if (depth >= maxDepth)\n return;\n const children = node.children ?? [];\n const n = children.length;\n if (n === 0)\n return;\n const angularWidth = wedgeEnd - wedgeStart;\n // √(subtree size), not raw size: linear weighting starves small-subtree\n // siblings (a handful of leaf folders next to one huge one get squeezed\n // into slivers) while the big subtree's wedge goes largely unused, since\n // its own descendants compress towards the boundary anyway.\n const weights = children.map(child => Math.sqrt(subtreeSize(child, maxDepth - depth - 1)));\n const totalWeight = weights.reduce((a, b) => a + b, 0);\n const ids = hyperbolicChildIds(id, children);\n let cursor = wedgeStart;\n children.forEach((child, index) => {\n const share = n === 1 ? angularWidth : (angularWidth * weights[index]) / totalWeight;\n const bisector = cursor + share / 2;\n cursor += share;\n // Only a lone, unbranching child needs the jitter — anything with\n // siblings is already visually separated by the fan itself.\n const jitter = n === 1\n ? stableUnitJitter(child.item.key) * Math.min(CHAIN_JITTER_RADIANS, share * 0.4)\n : 0;\n const theta = bisector + jitter;\n const r = euclideanRadiusForHyperbolicDistance(n === 1 ? curvature : childDistance(share, siblingSpacing, curvature));\n const local: Point = { x: r * Math.cos(theta), y: r * Math.sin(theta) };\n const toParent = translationFromOrigin(local);\n const childFrame = composeIsometry(frame, toParent);\n map.set(ids[index], {\n node: child,\n id: ids[index],\n depth: depth + 1,\n parentKey: node.item.key,\n parentId: id,\n position: applyIsometry(childFrame, origin),\n toParent,\n angularShare: share,\n });\n const halfWedge = Math.min(share, Math.PI) / 2;\n const localStart = boundaryAngleInLocalFrame(bisector - halfWedge, local);\n let localWidth = boundaryAngleInLocalFrame(bisector + halfWedge, local) - localStart;\n if (localWidth <= 0)\n localWidth += 2 * Math.PI;\n place(child, ids[index], childFrame, localStart, localStart + localWidth, depth + 1);\n });\n };\n\n place(root, root.item.key, identityIsometry, -Math.PI, Math.PI, 0);\n return map;\n}\n\ntype FocusFrame = {\n /** Tree-graph steps from the focus. */\n readonly ring: number;\n /** This node's local frame → the focus's local frame. */\n readonly frame: DiskIsometry;\n};\n\n/**\n * Every node within `maxRadius` tree-graph steps of `focusedId`, with its\n * frame relative to the focus. Built by walking outward from the focus and\n * composing one short {@link CanonicalEntry.toParent} hop per edge — so\n * precision depends only on distance *from the focus*, never on how far the\n * focus is from the root.\n */\nfunction focusFrames(\n entries: ReadonlyMap<string, CanonicalEntry>,\n focusedId: string,\n maxRadius: number,\n): Map<string, FocusFrame> {\n const frames = new Map<string, FocusFrame>();\n if (!entries.has(focusedId))\n return frames;\n frames.set(focusedId, { ring: 0, frame: identityIsometry });\n let frontier = [focusedId];\n for (let ring = 1; ring <= maxRadius && frontier.length > 0; ring++) {\n const next: string[] = [];\n for (const id of frontier) {\n const entry = entries.get(id)!;\n const { frame } = frames.get(id)!;\n const visit = (neighbourId: string, neighbourFrame: () => DiskIsometry): void => {\n if (frames.has(neighbourId) || !entries.has(neighbourId))\n return;\n frames.set(neighbourId, { ring, frame: neighbourFrame() });\n next.push(neighbourId);\n };\n for (const childId of hyperbolicChildIds(id, entry.node.children ?? []))\n visit(childId, () => composeIsometry(frame, entries.get(childId)!.toParent));\n if (entry.parentId !== undefined)\n visit(entry.parentId, () => composeIsometry(frame, invertIsometry(entry.toParent)));\n }\n frontier = next;\n }\n return frames;\n}\n\n/** `toParent` hops composed from `id` up to (not including) ancestor `ancestorId`: `id`-local → `ancestorId`-local. */\nfunction frameUpTo(entries: ReadonlyMap<string, CanonicalEntry>, id: string, ancestorId: string): DiskIsometry {\n let frame = identityIsometry;\n for (let cursor: string | undefined = id; cursor !== undefined && cursor !== ancestorId; cursor = entries.get(cursor)?.parentId)\n frame = composeIsometry(entries.get(cursor)!.toParent, frame);\n return frame;\n}\n\n/**\n * The frame of node `toId` expressed in node `fromId`'s local frame (maps\n * `toId`-local coordinates to `fromId`-local ones), composed along the tree\n * path between them via their lowest common ancestor. Used to hand a view\n * over from one focus to another without passing through root-anchored\n * coordinates. `undefined` if either id is absent.\n */\nexport function hyperbolicRelativeFrame(\n entries: ReadonlyMap<string, CanonicalEntry>,\n fromId: string,\n toId: string,\n): DiskIsometry | undefined {\n if (!entries.has(fromId) || !entries.has(toId))\n return undefined;\n const ancestors = new Set<string>();\n for (let cursor: string | undefined = fromId; cursor !== undefined; cursor = entries.get(cursor)?.parentId)\n ancestors.add(cursor);\n let lca: string | undefined = toId;\n while (lca !== undefined && !ancestors.has(lca))\n lca = entries.get(lca)?.parentId;\n if (lca === undefined)\n return undefined;\n return composeIsometry(invertIsometry(frameUpTo(entries, fromId, lca)), frameUpTo(entries, toId, lca));\n}\n\n/**\n * Resolve `focusedKey` — either a layout id, or (as a convenience, and for\n * data with globally-unique keys) a plain `item.key`, matching the first\n * node in depth-first order carrying it.\n */\nfunction resolveFocusId(canonical: ReadonlyMap<string, CanonicalEntry>, focusedKey: string | undefined): string | undefined {\n if (focusedKey === undefined)\n return undefined;\n if (canonical.has(focusedKey))\n return focusedKey;\n for (const entry of canonical.values()) {\n if (entry.node.item.key === focusedKey)\n return entry.id;\n }\n return undefined;\n}\n\n/**\n * Compute the visible nodes/edges of a hyperbolic tree view: every\n * currently-loaded node within `maxRadius` tree-graph steps of the focused\n * node, projected onto the Poincaré disk with the focus at its center.\n *\n * @param root True tree root. `undefined` yields an empty layout.\n * @param options `focusedKey` (a layout id or plain `item.key`; default the\n * true root; unknown keys fall back to the true root), `maxRadius` (default unlimited), `maxDepth` (safety\n * cap on layout recursion depth, default 24), `curvature`,\n * `siblingSpacing`, `centerOverride` (put this point of the focus's local\n * frame at the center instead of the focus itself), `view` (a full\n * focus-local → screen isometry, taking precedence over `centerOverride` —\n * used for panning and animation, which also rotate).\n */\nexport function computeHyperbolicLayout(\n root: TreeNode | undefined,\n options: ComputeHyperbolicLayoutOptions = {},\n): { nodes: HyperbolicLayoutNode[]; edges: HyperbolicLayoutEdge[] } {\n if (!root)\n return { nodes: [], edges: [] };\n const { maxRadius = Number.POSITIVE_INFINITY, maxDepth = 24, curvature = 1, siblingSpacing = DEFAULT_SIBLING_SPACING } = options;\n const canonical = computeCanonicalPositions(root, maxDepth, curvature, siblingSpacing);\n const focusedId = resolveFocusId(canonical, options.focusedKey) ?? root.item.key;\n if (!canonical.has(focusedId))\n return { nodes: [], edges: [] };\n const view = options.view ?? viewIsometry(options.centerOverride ?? { x: 0, y: 0 });\n\n const frames = focusFrames(canonical, focusedId, maxRadius);\n const rawWeights = [...frames.keys()]\n .map(key => canonical.get(key)!.node.item.weight)\n .filter((w): w is number => typeof w === `number`);\n const minWeight = rawWeights.length > 0 ? Math.min(...rawWeights) : undefined;\n const maxWeight = rawWeights.length > 0 ? Math.max(...rawWeights) : undefined;\n const normalizeWeight = (weight: number | undefined): number => {\n if (weight === undefined || minWeight === undefined || maxWeight === undefined || maxWeight === minWeight)\n return 0.5;\n return (weight - minWeight) / (maxWeight - minWeight);\n };\n\n const nodes: HyperbolicLayoutNode[] = [...frames.entries()]\n .map(([id, { ring, frame }]) => {\n const entry = canonical.get(id)!;\n const weight = entry.node.item.weight;\n return {\n node: entry.node,\n key: entry.node.item.key,\n id,\n depth: entry.depth,\n ring,\n parentKey: entry.parentKey,\n parentId: entry.parentId,\n position: applyIsometry(composeIsometry(view, frame), { x: 0, y: 0 }),\n angularShare: entry.angularShare,\n weight,\n weightNormalized: normalizeWeight(weight),\n };\n })\n .sort((a, b) => a.ring - b.ring);\n\n const byId = new Map(nodes.map(n => [n.id, n]));\n const edges: HyperbolicLayoutEdge[] = [];\n for (const n of nodes) {\n if (n.parentId === undefined)\n continue;\n const parent = byId.get(n.parentId);\n if (!parent)\n continue;\n edges.push({\n fromKey: parent.key,\n toKey: n.key,\n fromId: parent.id,\n toId: n.id,\n from: parent.position,\n to: n.position,\n weightNormalized: (parent.weightNormalized + n.weightNormalized) / 2,\n });\n }\n\n return { nodes, edges };\n}\n","/**\n * Pure keyboard-navigation resolution for the hyperbolic tree: which node a\n * key press moves to, given the current focus. The element applies the\n * resulting action (focus change, selection, events).\n */\n\nimport type { TreeNode } from '../common/types.js';\nimport type { HyperbolicLayoutNode } from './types.js';\nimport { findHyperbolicPathById } from './layout.js';\n\nexport type HyperbolicKeyAction\n = | { readonly kind: `focus`; readonly node: TreeNode }\n | { readonly kind: `activate`; readonly node: TreeNode; readonly depth: number }\n | { readonly kind: `none` };\n\nexport type HyperbolicKeyResult = {\n readonly action: HyperbolicKeyAction;\n /** Whether the key was consumed (the caller should `preventDefault()`). */\n readonly handled: boolean;\n};\n\nconst unhandled: HyperbolicKeyResult = { action: { kind: `none` }, handled: false };\n\n/** Angular distance (radians, 0–π) of a layout node from screen-\"up\" (−π/2). */\nfunction angleDistanceFromUp(n: HyperbolicLayoutNode): number {\n const angle = Math.atan2(n.position.y, n.position.x);\n let diff = Math.abs(angle - (-Math.PI / 2));\n if (diff > Math.PI)\n diff = 2 * Math.PI - diff;\n return diff;\n}\n\n/**\n * Resolve `key` against the focused node (layout id `focusId`):\n * - `ArrowUp` — the visible child closest to screen-\"up\"\n * - `ArrowDown` — the parent\n * - `ArrowLeft` / `ArrowRight` — previous / next sibling, wrapping\n * - `Enter` — activate the focus\n * - `Escape` — back to the root (unhandled when already there)\n */\nexport function resolveKeyboardAction(\n key: string,\n root: TreeNode,\n focusId: string,\n visibleNodes: readonly HyperbolicLayoutNode[],\n): HyperbolicKeyResult {\n const path = findHyperbolicPathById(root, focusId);\n const focusNode = path?.at(-1);\n if (!path || !focusNode)\n return unhandled;\n const parent = path.length >= 2 ? path[path.length - 2] : undefined;\n const none: HyperbolicKeyResult = { action: { kind: `none` }, handled: true };\n const focus = (node: TreeNode | undefined): HyperbolicKeyResult =>\n node ? { action: { kind: `focus`, node }, handled: true } : none;\n\n switch (key) {\n case `ArrowUp`: {\n const children = visibleNodes.filter(n => n.parentId === focusId);\n if (children.length === 0)\n return none;\n return focus(children.reduce((a, b) => angleDistanceFromUp(a) < angleDistanceFromUp(b) ? a : b).node);\n }\n case `ArrowDown`:\n return focus(parent);\n case `ArrowLeft`:\n case `ArrowRight`: {\n const siblings = parent?.children ?? [];\n const index = siblings.indexOf(focusNode);\n if (index === -1 || siblings.length <= 1)\n return none;\n const dir = key === `ArrowRight` ? 1 : -1;\n return focus(siblings[(index + dir + siblings.length) % siblings.length]);\n }\n case `Enter`:\n return { action: { kind: `activate`, node: focusNode, depth: path.length - 1 }, handled: true };\n case `Escape`:\n return focusNode === root ? unhandled : focus(root);\n default:\n return unhandled;\n }\n}\n","/**\n * Lazy child loading for the hyperbolic tree: fetch `children` for any\n * visible node that hasn't loaded them yet, from a `TreeDataModel` or a\n * `LoadChildrenCallback`, one request per node, abortable.\n */\n\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type { LoadChildrenCallback, TreeNode } from '../common/types.js';\nimport { collectDataResult } from '../common/data-provider.js';\n\nexport type LazyChildSource = {\n readonly model: TreeDataModel | undefined;\n readonly loadChildren: LoadChildrenCallback | undefined;\n};\n\nexport function createLazyChildLoader(source: () => LazyChildSource, onChange: () => void) {\n const pending = new Set<TreeNode>();\n const aborters = new Map<TreeNode, AbortController>();\n\n const fetchChildren = async (node: TreeNode, depth: number, signal: AbortSignal): Promise<TreeNode[]> => {\n const { model, loadChildren } = source();\n if (model)\n return model.getChildren(node, depth, signal);\n return [...await collectDataResult(loadChildren!({ node, depth }, signal), signal)];\n };\n\n const load = async (node: TreeNode, depth: number): Promise<void> => {\n pending.add(node);\n const controller = new AbortController();\n aborters.set(node, controller);\n onChange();\n try {\n const children = await fetchChildren(node, depth, controller.signal);\n if (!controller.signal.aborted)\n node.children = children;\n } catch {\n if (!controller.signal.aborted)\n node.children = [];\n } finally {\n pending.delete(node);\n aborters.delete(node);\n if (!controller.signal.aborted)\n onChange();\n }\n };\n\n return {\n /** Start loading children for every node in `visible` that has none yet. */\n ensure(visible: Iterable<{ readonly node: TreeNode; readonly depth: number }>): void {\n const { model, loadChildren } = source();\n if (!model && !loadChildren)\n return;\n for (const { node, depth } of visible) {\n if (node.children === undefined && !pending.has(node))\n void load(node, depth);\n }\n },\n isPending: (node: TreeNode): boolean => pending.has(node),\n abortAll(): void {\n for (const aborter of aborters.values())\n aborter.abort();\n aborters.clear();\n pending.clear();\n },\n };\n}\n","/**\n * Pure sizing/label helpers for rendering a hyperbolic layout. No Lit — the\n * element composes these into SVG. Units are Poincaré-disk units (radius 1)\n * unless stated otherwise.\n */\n\nimport type { HyperbolicLayoutNode, Point } from './types.js';\n\n/**\n * The Poincaré disk's math operates in a `-1..1` unit radius, but rendering\n * an SVG `viewBox` at that literal scale (then letting CSS stretch it to a\n * few hundred device pixels) is an extreme, unusual upscale factor that has\n * been observed to trigger a Chromium GPU-rasterization glitch — a `fill:\n * none` shape painting as solid-filled, matching its computed style exactly\n * but not what's on screen. Rendering in a \"normal\"-magnitude SVG coordinate\n * system (viewBox radius `RENDER_SCALE` instead of `1`) avoids it.\n */\nexport const RENDER_SCALE = 500;\n\n/**\n * How nodes are drawn:\n * - `dot` — a filled circle with the label beside it (thinned when crowded).\n * - `box` — a rectangle containing the label, shrinking with distance from\n * the focus the way the space itself does.\n */\nexport type HyperbolicNodeShape = `dot` | `box`;\n\n/**\n * The Poincaré disk's conformal factor relative to the origin, `1 − |p|²`:\n * how much a shape of fixed hyperbolic size shrinks (in Euclidean terms) when\n * moved from the center to `p`. Sizing nodes by this makes them shrink\n * exactly as the space does, rather than by an ad-hoc falloff.\n */\nexport function conformalScale(p: Point): number {\n return Math.max(0, 1 - (p.x * p.x + p.y * p.y));\n}\n\n/**\n * Euclidean distance from each node to its nearest visible neighbour, keyed\n * by layout id (`Infinity` for a lone node). Used to cap on-screen node size\n * so crowded nodes never overlap — measured in the *projected* view, so it\n * stays right whichever node is focused. O(n²), fine for the few hundred\n * nodes a `maxRadius` window typically holds.\n */\nexport function nearestNeighbourDistances(nodes: readonly HyperbolicLayoutNode[]): Map<string, number> {\n const out = new Map<string, number>();\n for (const n of nodes)\n out.set(n.id, Number.POSITIVE_INFINITY);\n for (let i = 0; i < nodes.length; i++) {\n const a = nodes[i].position;\n for (let j = i + 1; j < nodes.length; j++) {\n const b = nodes[j].position;\n const d = Math.hypot(a.x - b.x, a.y - b.y);\n if (d < out.get(nodes[i].id)!)\n out.set(nodes[i].id, d);\n if (d < out.get(nodes[j].id)!)\n out.set(nodes[j].id, d);\n }\n }\n return out;\n}\n\nexport type DotRadiusOptions = {\n readonly nodeRadius: number;\n readonly minWeightScale: number;\n readonly maxWeightScale: number;\n};\n\n/** Weight multiplier for `n`, interpolating between the min/max weight scales. */\nexport function weightScale(n: HyperbolicLayoutNode, options: Pick<DotRadiusOptions, `minWeightScale` | `maxWeightScale`>): number {\n return options.minWeightScale + (options.maxWeightScale - options.minWeightScale) * n.weightNormalized;\n}\n\n/**\n * A dot's rendered radius: base size × weight × conformal shrink, capped to\n * under half the distance to its nearest neighbour so crowded siblings keep\n * a visible gap instead of merging into a blob.\n */\nexport function dotRadius(n: HyperbolicLayoutNode, nearest: number, options: DotRadiusOptions): number {\n const radius = options.nodeRadius * conformalScale(n.position) * weightScale(n, options);\n return Math.max(Math.min(radius, nearest * 0.45), 0.003);\n}\n\n/** A label's footprint — a convex quad (possibly rotated), in render units — for overlap culling. */\nexport type LabelShape = {\n readonly id: string;\n readonly corners: readonly Point[];\n};\n\n/**\n * Footprint of a `2·halfWidth × 2·halfHeight` rectangle centered on\n * `center` and rotated by `angle` radians.\n */\nexport function orientedRect(id: string, center: Point, halfWidth: number, halfHeight: number, angle = 0): LabelShape {\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n const corner = (u: number, v: number): Point => ({\n x: center.x + u * cos - v * sin,\n y: center.y + u * sin + v * cos,\n });\n return { id, corners: [corner(-halfWidth, -halfHeight), corner(halfWidth, -halfHeight), corner(halfWidth, halfHeight), corner(-halfWidth, halfHeight)] };\n}\n\nfunction polygonArea(points: readonly Point[]): number {\n let area = 0;\n for (let i = 0; i < points.length; i++) {\n const a = points[i];\n const b = points[(i + 1) % points.length];\n area += a.x * b.y - b.x * a.y;\n }\n return Math.abs(area) / 2;\n}\n\n/** Sutherland–Hodgman: `subject` clipped to convex `clip` (either winding). */\nfunction clipPolygon(subject: readonly Point[], clip: readonly Point[]): Point[] {\n const orientation = Math.sign(\n (clip[1].x - clip[0].x) * (clip[2].y - clip[0].y) - (clip[1].y - clip[0].y) * (clip[2].x - clip[0].x),\n ) || 1;\n let output = [...subject];\n for (let i = 0; i < clip.length && output.length > 0; i++) {\n const a = clip[i];\n const b = clip[(i + 1) % clip.length];\n const side = (p: Point): number => orientation * ((b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x));\n const input = output;\n output = [];\n for (let j = 0; j < input.length; j++) {\n const current = input[j];\n const previous = input[(j + input.length - 1) % input.length];\n const sc = side(current);\n const sp = side(previous);\n if ((sc >= 0) !== (sp >= 0)) {\n const t = sp / (sp - sc);\n output.push({ x: previous.x + (current.x - previous.x) * t, y: previous.y + (current.y - previous.y) * t });\n }\n if (sc >= 0)\n output.push(current);\n }\n }\n return output;\n}\n\nfunction bounds(points: readonly Point[]): { x0: number; y0: number; x1: number; y1: number } {\n const xs = points.map(p => p.x);\n const ys = points.map(p => p.y);\n return { x0: Math.min(...xs), y0: Math.min(...ys), x1: Math.max(...xs), y1: Math.max(...ys) };\n}\n\n/** Fraction (0–1) of `candidate`'s area covered by `other`. */\nexport function overlapFraction(candidate: LabelShape, other: LabelShape): number {\n const a = bounds(candidate.corners);\n const b = bounds(other.corners);\n if (a.x1 <= b.x0 || b.x1 <= a.x0 || a.y1 <= b.y0 || b.y1 <= a.y0)\n return 0;\n const area = polygonArea(candidate.corners);\n if (area <= 0)\n return 1;\n return polygonArea(clipPolygon(candidate.corners, other.corners)) / area;\n}\n\n/**\n * Greedy label placement: walk `shapes` in priority order and keep each one\n * whose overlap with every already-kept shape is at most `maxOverlap` of its\n * own area. Returns the ids of the kept labels. Checking actual (possibly\n * rotated) label footprints, not just node positions, is what stops a fan of\n * same-radius siblings from stacking their text into an unreadable pile.\n */\nexport function cullOverlappingLabels(shapes: readonly LabelShape[], maxOverlap = 0.03): Set<string> {\n const kept: LabelShape[] = [];\n for (const shape of shapes) {\n if (kept.every(k => overlapFraction(shape, k) <= maxOverlap))\n kept.push(shape);\n }\n return new Set(kept.map(r => r.id));\n}\n\n/** `label` cut to at most `maxChars` characters, ending in `…` when cut. `0` or less disables truncation. */\nexport function truncateLabel(label: string, maxChars: number): string {\n if (maxChars <= 0 || label.length <= maxChars)\n return label;\n return `${label.slice(0, Math.max(1, maxChars - 1)).trimEnd()}…`;\n}\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\nconst widthCache = new Map<string, number>();\n\n/**\n * Rendered width of `text` at `fontSize` px in `fontFamily`, via an offscreen\n * canvas (cached). Falls back to a per-character estimate where canvas text\n * measurement is unavailable (e.g. non-browser test environments).\n */\nexport function measureTextWidth(text: string, fontSize: number, fontFamily: string): number {\n const cacheKey = `${fontFamily}\\u0000${text}`;\n let atUnitSize = widthCache.get(cacheKey);\n if (atUnitSize === undefined) {\n if (measureContext === undefined) {\n try {\n measureContext = typeof document === `undefined` ? null : document.createElement(`canvas`).getContext(`2d`);\n } catch {\n measureContext = null;\n }\n }\n const reference = 100;\n let measured: number | undefined;\n if (measureContext) {\n measureContext.font = `${reference}px ${fontFamily || `sans-serif`}`;\n const width = measureContext.measureText(text).width;\n if (Number.isFinite(width) && width > 0)\n measured = width / reference;\n }\n atUnitSize = measured ?? text.length * 0.6;\n widthCache.set(cacheKey, atUnitSize);\n }\n return atUnitSize * fontSize;\n}\n\n/**\n * Smallest scale a box shrinks to, however far from the focus. Pure conformal\n * scaling (`1 − |z|²`) is geometrically exact but shrinks the second ring to\n * well under half size, taking labels below legibility long before the\n * boundary — flooring it keeps nearby rings readable while still reading as\n * \"further away\".\n */\nexport const BOX_SCALE_FLOOR = 0.45;\n\nexport type BoxGeometry = {\n /** Uniform scale applied to the whole box (1 at the focus). */\n readonly scale: number;\n /** Unscaled size of the box when it carries its label, in render units. */\n readonly width: number;\n readonly height: number;\n /** Unscaled side of the small square drawn when the label is hidden. */\n readonly markerSize: number;\n /** The (possibly truncated) label to draw. */\n readonly text: string;\n};\n\nexport type BoxGeometryOptions = {\n /** Label font size in render units. */\n readonly fontSize: number;\n readonly fontFamily: string;\n readonly maxChars: number;\n readonly minWeightScale: number;\n readonly maxWeightScale: number;\n /**\n * The view's Euclidean zoom. Boxes grow with it — up to their full focus\n * size, never beyond — so zooming into a crowd of small boxes makes them\n * legible, while labels already at full size stay put.\n */\n readonly zoom?: number;\n};\n\n/**\n * Geometry for a `box`-shaped node. The box is laid out at its focus size and\n * then uniformly scaled — by the conformal factor, floored at\n * {@link BOX_SCALE_FLOOR} — so the label is measured just once. Weight\n * nudges the scale gently (square-rooted), so heavy nodes read as larger\n * without dwarfing their neighbours' labels.\n */\nexport function boxGeometry(n: HyperbolicLayoutNode, options: BoxGeometryOptions): BoxGeometry {\n const conformal = BOX_SCALE_FLOOR + (1 - BOX_SCALE_FLOOR) * conformalScale(n.position);\n const zoomed = Math.min(1, conformal * (options.zoom ?? 1));\n const scale = zoomed * Math.sqrt(weightScale(n, options));\n const text = truncateLabel(n.node.item.label, options.maxChars);\n const padX = options.fontSize * 0.5;\n const height = options.fontSize * 1.55;\n const width = measureTextWidth(text, options.fontSize, options.fontFamily) + padX * 2;\n return { scale, width, height, markerSize: options.fontSize * 0.55, text };\n}\n\n/** Label footprint of a box of `geometry` centered at `center` and rotated by `angle` (render units). */\nexport function boxLabelShape(id: string, center: Point, geometry: BoxGeometry, angle = 0): LabelShape {\n return orientedRect(id, center, (geometry.width * geometry.scale) / 2, (geometry.height * geometry.scale) / 2, angle);\n}\n","/**\n * Per-render derived data for the hyperbolic tree's nodes: sizes, which\n * labels survive overlap culling, branch colouring. Pure — the element\n * supplies the visible nodes plus a snapshot of its own state/properties.\n */\n\nimport type { TreeNode } from '../common/types.js';\nimport type { BoxGeometry, HyperbolicNodeShape } from './render-utils.js';\nimport type { HyperbolicLayoutNode, Point } from './types.js';\nimport { hyperbolicBranchId, hyperbolicChildIds } from './layout.js';\nimport {\n boxGeometry,\n boxLabelShape,\n cullOverlappingLabels,\n dotRadius,\n measureTextWidth,\n nearestNeighbourDistances,\n orientedRect,\n RENDER_SCALE,\n} from './render-utils.js';\n\nexport type FontMetrics = {\n /** Label size in screen px. */\n readonly px: number;\n /** The same size in render (viewBox) units. */\n readonly units: number;\n readonly family: string;\n};\n\n/**\n * How a node's label is oriented. With radial labels on, a label runs along\n * the node's incoming edge (from its neighbour one step nearer the focus),\n * so a fan of siblings needs room only for each label's *height*, not its\n * width. Labels on the left half are turned 180° (`flipped`) so text never\n * reads upside-down.\n */\nexport type LabelOrientation = {\n /** Direction (radians, screen space) the label extends in, away from the node. */\n readonly direction: number;\n /** Rotation to apply to the text itself (`direction`, or `direction + π` when flipped). */\n readonly textAngle: number;\n readonly flipped: boolean;\n};\n\nconst HORIZONTAL: LabelOrientation = { direction: 0, textAngle: 0, flipped: false };\n\n/** Per-render data shared by every node's template. */\nexport type NodeRenderContext = {\n readonly siblingGroups: ReadonlyMap<string | undefined, readonly HyperbolicLayoutNode[]>;\n readonly font: FontMetrics;\n readonly branches: ReadonlyMap<string, number>;\n readonly boxes: ReadonlyMap<string, BoxGeometry>;\n readonly radii: ReadonlyMap<string, number>;\n readonly labelIds: ReadonlySet<string>;\n readonly orientations: ReadonlyMap<string, LabelOrientation>;\n};\n\nexport type NodeRenderOptions = {\n readonly nodeShape: HyperbolicNodeShape;\n /** The view's Euclidean zoom — lets zooming reveal labels that were too small. */\n readonly zoom: number;\n readonly radialLabels: boolean;\n readonly font: FontMetrics;\n readonly branches: ReadonlyMap<string, number>;\n readonly boxMaxChars: number;\n readonly minLabelSize: number;\n readonly nodeRadius: number;\n readonly minNodeRadius: number;\n readonly minWeightScale: number;\n readonly maxWeightScale: number;\n readonly isSelected: (node: TreeNode) => boolean;\n readonly isTickled: (id: string) => boolean;\n};\n\n/**\n * Label font metrics. `--hyperbolictree-font-size` is in real screen px;\n * the SVG's viewBox is fixed, so it's converted to render units using the\n * on-screen disk size (`extentPx`) and zoom — keeping text legible whatever\n * size the element is laid out at, and constant-size while zooming\n * (zooming in spreads crowded labels apart rather than just magnifying the\n * pile).\n */\nexport function fontMetrics(host: Element, extentPx: number, zoom: number): FontMetrics {\n const style = typeof getComputedStyle === `function` ? getComputedStyle(host) : undefined;\n const parsed = Number.parseFloat(style?.getPropertyValue(`--hyperbolictree-font-size`) ?? ``);\n const px = Number.isFinite(parsed) && parsed > 0 ? parsed : 13;\n const extent = extentPx > 0 ? extentPx : 420;\n const unitsPerPx = (2.1 * RENDER_SCALE) / extent / (zoom || 1);\n return { px, units: px * unitsPerPx, family: style?.fontFamily ?? `` };\n}\n\n/** Map of top-level-branch layout id → index among the root's children. */\nexport function branchIndices(root: TreeNode | undefined): Map<string, number> {\n if (!root)\n return new Map();\n return new Map(hyperbolicChildIds(root.item.key, root.children ?? []).map((id, i) => [id, i]));\n}\n\n/** Inline `--branch-index`/`--branch-count` declarations for the node/edge with layout id `id` (empty for the root). */\nexport function branchStyle(id: string, branches: ReadonlyMap<string, number>): string {\n const branch = hyperbolicBranchId(id);\n const index = branch === undefined ? undefined : branches.get(branch);\n return index === undefined ? `` : ` --branch-index: ${index}; --branch-count: ${branches.size};`;\n}\n\nfunction groupSiblings(nodes: readonly HyperbolicLayoutNode[]): Map<string | undefined, HyperbolicLayoutNode[]> {\n const groups = new Map<string | undefined, HyperbolicLayoutNode[]>();\n for (const n of nodes) {\n const group = groups.get(n.parentId) ?? [];\n group.push(n);\n groups.set(n.parentId, group);\n }\n return groups;\n}\n\n/**\n * Label priority: the focus, then selected nodes, then larger (nearer the\n * center) first.\n */\nfunction byLabelPriority(\n nodes: readonly HyperbolicLayoutNode[],\n sizeOf: (n: HyperbolicLayoutNode) => number,\n isSelected: (node: TreeNode) => boolean,\n): HyperbolicLayoutNode[] {\n const rank = (n: HyperbolicLayoutNode): number => n.ring === 0 ? 0 : isSelected(n.node) ? 1 : 2;\n return [...nodes].sort((a, b) => rank(a) - rank(b) || sizeOf(b) - sizeOf(a) || a.ring - b.ring);\n}\n\n/**\n * Each node's label orientation. The reference neighbour is the one a step\n * nearer the focus: usually the parent, but for the focus's own ancestors\n * (which sit *behind* it) the child on the path back to the focus. The focus\n * itself stays horizontal.\n */\nexport function labelOrientations(nodes: readonly HyperbolicLayoutNode[], radial: boolean): Map<string, LabelOrientation> {\n const out = new Map<string, LabelOrientation>();\n if (!radial) {\n for (const n of nodes)\n out.set(n.id, HORIZONTAL);\n return out;\n }\n const byId = new Map(nodes.map(n => [n.id, n]));\n const nearer = new Map<string, HyperbolicLayoutNode>();\n for (const n of nodes) {\n const parent = n.parentId === undefined ? undefined : byId.get(n.parentId);\n if (!parent)\n continue;\n if (parent.ring < n.ring)\n nearer.set(n.id, parent);\n else if (n.ring < parent.ring)\n nearer.set(parent.id, n);\n }\n for (const n of nodes) {\n const from = nearer.get(n.id);\n if (!from || n.ring === 0) {\n out.set(n.id, HORIZONTAL);\n continue;\n }\n const direction = Math.atan2(n.position.y - from.position.y, n.position.x - from.position.x);\n const flipped = Math.cos(direction) < 0;\n out.set(n.id, { direction, textAngle: flipped ? direction + Math.PI : direction, flipped });\n }\n return out;\n}\n\nconst renderCenter = (n: HyperbolicLayoutNode): Point => ({ x: n.position.x * RENDER_SCALE, y: n.position.y * RENDER_SCALE });\n\nfunction boxLabels(nodes: readonly HyperbolicLayoutNode[], options: NodeRenderOptions, orientations: ReadonlyMap<string, LabelOrientation>) {\n const { font } = options;\n const boxes = new Map(nodes.map(n => [n.id, boxGeometry(n, {\n fontSize: font.units,\n fontFamily: font.family,\n maxChars: options.boxMaxChars,\n minWeightScale: options.minWeightScale,\n maxWeightScale: options.maxWeightScale,\n zoom: options.zoom,\n })]));\n const legible = nodes.filter(n => !options.isTickled(n.id) && font.px * boxes.get(n.id)!.scale >= options.minLabelSize);\n const ordered = byLabelPriority(legible, n => boxes.get(n.id)!.scale, options.isSelected);\n const labelIds = cullOverlappingLabels(ordered.map(n =>\n boxLabelShape(n.id, renderCenter(n), boxes.get(n.id)!, orientations.get(n.id)!.textAngle)));\n return { boxes, labelIds };\n}\n\nfunction dotLabels(nodes: readonly HyperbolicLayoutNode[], options: NodeRenderOptions, orientations: ReadonlyMap<string, LabelOrientation>) {\n const { font } = options;\n const nearest = nearestNeighbourDistances(nodes);\n const radii = new Map(nodes.map(n => [n.id, dotRadius(n, nearest.get(n.id)!, options)]));\n // Dots are magnified by zoom along with the disk, so judge their on-screen size.\n const eligible = nodes.filter(n => !options.isTickled(n.id) && radii.get(n.id)! * options.zoom >= options.minNodeRadius);\n const ordered = byLabelPriority(eligible, n => radii.get(n.id)!, options.isSelected);\n const labelIds = cullOverlappingLabels(ordered.map((n) => {\n // The label starts just past the dot and runs along its orientation.\n const { direction } = orientations.get(n.id)!;\n const halfWidth = measureTextWidth(n.node.item.label, font.units, font.family) / 2;\n const along = (radii.get(n.id)! + 0.01) * RENDER_SCALE + halfWidth;\n const c = renderCenter(n);\n const center = { x: c.x + Math.cos(direction) * along, y: c.y + Math.sin(direction) * along };\n // Padded lengthwise so labels that happen to line up end-to-end along\n // one ray (a node and its parent) need a gap, rather than reading as\n // one run-on word.\n return orientedRect(n.id, center, halfWidth + font.units * 0.6, font.units * 0.6, direction);\n }));\n return { radii, labelIds };\n}\n\n/**\n * Everything the node templates need for one render. Labels are placed\n * greedily by priority and dropped where they'd overlap; hovered/cursor\n * nodes are exempt from culling entirely — always labelled — so hovering a\n * marker reveals it without reshuffling everyone else's labels.\n */\nexport function buildNodeRenderContext(nodes: readonly HyperbolicLayoutNode[], options: NodeRenderOptions): NodeRenderContext {\n const orientations = labelOrientations(nodes, options.radialLabels);\n const shapeData = options.nodeShape === `box`\n ? { ...boxLabels(nodes, options, orientations), radii: new Map<string, number>() }\n : { ...dotLabels(nodes, options, orientations), boxes: new Map<string, BoxGeometry>() };\n const labelIds = new Set(shapeData.labelIds);\n for (const n of nodes) {\n if (options.isTickled(n.id))\n labelIds.add(n.id);\n }\n return {\n siblingGroups: groupSiblings(nodes),\n font: options.font,\n branches: options.branches,\n boxes: shapeData.boxes,\n radii: shapeData.radii,\n labelIds,\n orientations,\n };\n}\n\n/**\n * Paint order: far-from-focus first so nearer (larger) nodes sit on top;\n * then labelled over unlabelled; the hovered node above everything.\n */\nexport function paintOrder(nodes: readonly HyperbolicLayoutNode[], ctx: NodeRenderContext, isTickled: (id: string) => boolean): HyperbolicLayoutNode[] {\n const layer = (n: HyperbolicLayoutNode): number => isTickled(n.id) ? 2 : ctx.labelIds.has(n.id) ? 1 : 0;\n const distance = (n: HyperbolicLayoutNode): number => n.position.x ** 2 + n.position.y ** 2;\n return [...nodes].sort((a, b) => layer(a) - layer(b) || distance(b) - distance(a));\n}\n","/**\n * Lit SVG templates for the hyperbolic tree's nodes and edges. Stateless:\n * the element passes in a {@link NodeRenderContext}, a read-only view of its\n * per-node state, and the event handlers to wire up.\n */\n\nimport type { TreeNode } from '../common/types.js';\nimport type { NodeRenderContext } from './render-context.js';\nimport type { HyperbolicEdgeRenderer, HyperbolicLayoutEdge, HyperbolicLayoutNode } from './types.js';\nimport { nothing, svg } from 'lit';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { geodesicPath } from './poincare-math.js';\nimport { branchStyle, paintOrder } from './render-context.js';\nimport { RENDER_SCALE } from './render-utils.js';\n\n/**\n * Sanitizes a node key into a token safe to use inside a `part` attribute /\n * `::part()` selector — arbitrary key characters (spaces, quotes, etc.)\n * would otherwise produce a token CSS can't select without bespoke escaping.\n */\nexport function partToken(key: string): string {\n return key.replace(/[^\\w-]/g, `-`);\n}\n\n/** Read-only view of the element's per-node state. */\nexport type NodeStateView = {\n readonly isSelected: (node: TreeNode) => boolean;\n readonly isTickled: (id: string) => boolean;\n readonly isFiltered: (n: HyperbolicLayoutNode) => boolean;\n readonly isPending: (node: TreeNode) => boolean;\n /** Whether the node gets a native `<title>` tooltip (off where the child preview takes over). */\n readonly showTitle: (n: HyperbolicLayoutNode) => boolean;\n};\n\nexport type NodeHandlers = {\n readonly onPointerDown: (event: PointerEvent) => void;\n readonly onClick: (n: HyperbolicLayoutNode, event: MouseEvent) => void;\n readonly onDblClick: (n: HyperbolicLayoutNode, event: MouseEvent) => void;\n readonly onPointerEnter: (id: string) => void;\n};\n\ntype NodeTemplateArgs = {\n readonly ctx: NodeRenderContext;\n readonly state: NodeStateView;\n readonly handlers: NodeHandlers;\n};\n\n// A node's own default mousedown would focus the `<g>` itself — and paint\n// order re-sorts nodes on hover/selection, and moving a focused element in\n// the DOM drops its focus. The pointerdown handler focuses the stable\n// `<svg role=\"tree\">` instead, so cancel the node-level default.\nconst preventMouseDownFocus = (e: MouseEvent): void => e.preventDefault();\n\n/** The shared `<g part=\"node\">` wrapper — ARIA, parts, weight/branch vars, tooltip, and pointer handling. */\nfunction renderNodeGroup(n: HyperbolicLayoutNode, args: NodeTemplateArgs, transform: string, content: unknown): unknown {\n const { node, key, id } = n;\n const { ctx, state, handlers } = args;\n const selected = state.isSelected(node);\n const classes = [\n `node`,\n selected ? `selected` : ``,\n state.isTickled(id) ? `tickled` : ``,\n state.isFiltered(n) ? `filtered` : ``,\n state.isPending(node) ? `loading` : ``,\n n.ring === 0 ? `focused` : ``,\n ].filter(Boolean).join(` `);\n const siblings = ctx.siblingGroups.get(n.parentId) ?? [n];\n const weightStyle = `--node-weight: ${n.weightNormalized};${n.weight === undefined ? `` : ` --node-weight-raw: ${n.weight};`}`;\n return svg`\n <g\n class=${classes}\n data-key=${key}\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-level=${n.depth + 1}\n aria-selected=${selected}\n aria-setsize=${siblings.length}\n aria-posinset=${siblings.findIndex(sib => sib.id === id) + 1}\n aria-label=${node.item.label}\n part=\"node node-${partToken(key)}\"\n style=${weightStyle + branchStyle(id, ctx.branches)}\n transform=${transform}\n @pointerdown=${handlers.onPointerDown}\n @mousedown=${preventMouseDownFocus}\n @click=${(e: MouseEvent) => handlers.onClick(n, e)}\n @dblclick=${(e: MouseEvent) => handlers.onDblClick(n, e)}\n @pointerenter=${() => handlers.onPointerEnter(id)}\n >${state.showTitle(n) ? svg`<title>${node.item.label}</title>` : nothing}${content}</g>\n `;\n}\n\nconst degrees = (radians: number): number => radians * 180 / Math.PI;\n\n/** A dot's label: just past the dot, running along its orientation — flipped labels anchor at their end so they still read outward. */\nfunction renderDotLabel(n: HyperbolicLayoutNode, ctx: NodeRenderContext, scaledRadius: number): unknown {\n const { textAngle, flipped } = ctx.orientations.get(n.id)!;\n const gap = scaledRadius + 0.01 * RENDER_SCALE;\n return svg`<text\n class=\"hyperbolictree-label\"\n part=\"label\"\n x=${flipped ? -gap : gap}\n y=\"0\"\n transform=${textAngle === 0 ? nothing : `rotate(${degrees(textAngle)})`}\n text-anchor=${flipped ? `end` : `start`}\n font-size=${ctx.font.units}\n dominant-baseline=\"middle\"\n >${n.node.item.label}</text>`;\n}\n\nfunction renderDotNode(n: HyperbolicLayoutNode, args: NodeTemplateArgs): unknown {\n const { ctx } = args;\n const scaledRadius = ctx.radii.get(n.id)! * RENDER_SCALE;\n const transform = `translate(${n.position.x * RENDER_SCALE} ${n.position.y * RENDER_SCALE})`;\n return renderNodeGroup(n, args, transform, svg`\n <circle class=\"node-hit\" r=${Math.max(scaledRadius, 0.035 * RENDER_SCALE)} part=\"hit\" />\n <circle class=\"node-dot\" r=${scaledRadius} part=\"dot\" />\n ${ctx.labelIds.has(n.id) ? renderDotLabel(n, ctx, scaledRadius) : nothing}\n `);\n}\n\nfunction renderBoxNode(n: HyperbolicLayoutNode, args: NodeTemplateArgs): unknown {\n const { ctx } = args;\n const box = ctx.boxes.get(n.id)!;\n const showText = ctx.labelIds.has(n.id);\n const width = showText ? box.width : box.markerSize;\n const height = showText ? box.height : box.markerSize;\n const { textAngle } = ctx.orientations.get(n.id)!;\n const rotate = showText && textAngle !== 0 ? ` rotate(${degrees(textAngle)})` : ``;\n const transform = `translate(${n.position.x * RENDER_SCALE} ${n.position.y * RENDER_SCALE})${rotate} scale(${box.scale})`;\n return renderNodeGroup(n, args, transform, svg`\n <rect\n class=\"node-box ${showText ? `` : `marker`}\"\n part=\"box\"\n x=${-width / 2}\n y=${-height / 2}\n width=${width}\n height=${height}\n rx=${ctx.font.units * 0.2}\n />\n ${showText\n ? svg`<text class=\"hyperbolictree-label box-label\" part=\"label\" x=\"0\" y=\"0\" font-size=${ctx.font.units} text-anchor=\"middle\" dominant-baseline=\"central\">${box.text}</text>`\n : nothing}\n `);\n}\n\n/** Every visible node, in paint order, in the shape `ctx` was built for. */\nexport function renderNodes(\n nodes: readonly HyperbolicLayoutNode[],\n shape: `dot` | `box`,\n args: NodeTemplateArgs,\n): unknown {\n const ordered = paintOrder(nodes, args.ctx, args.state.isTickled);\n const renderOne = shape === `box` ? renderBoxNode : renderDotNode;\n return repeat(ordered, n => n.id, n => renderOne(n, args));\n}\n\nfunction renderDefaultEdge(edge: HyperbolicLayoutEdge, branches: ReadonlyMap<string, number>): unknown {\n return svg`<path\n class=\"edge\"\n d=${geodesicPath(edge.from, edge.to, RENDER_SCALE)}\n part=\"edge edge-to-${partToken(edge.toKey)} edge-from-${partToken(edge.fromKey)}\"\n data-from=${edge.fromKey}\n data-to=${edge.toKey}\n style=\"--edge-weight: ${edge.weightNormalized};${branchStyle(edge.toId, branches)}\"\n />`;\n}\n\n/** Every visible edge — via `edgeRenderer` when given, else the default geodesic arc. */\nexport function renderEdges(\n edges: readonly HyperbolicLayoutEdge[],\n byId: ReadonlyMap<string, HyperbolicLayoutNode>,\n branches: ReadonlyMap<string, number>,\n edgeRenderer: HyperbolicEdgeRenderer | undefined,\n): unknown {\n return repeat(edges, e => `${e.fromId}->${e.toId}`, (edge) => {\n const fromNode = byId.get(edge.fromId)?.node;\n const toNode = byId.get(edge.toId)?.node;\n if (edgeRenderer && fromNode && toNode) {\n // Custom renderers author against the layout's native -1..1 disk\n // coordinates; this scales that up to match RENDER_SCALE so they\n // don't need to know about it.\n return svg`<g transform=\"scale(${RENDER_SCALE})\">${edgeRenderer({ edge, fromNode, toNode })}</g>`;\n }\n return renderDefaultEdge(edge, branches);\n });\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TreeActivateDetail, TreeActivateEvent, TreeCollapseDetail, TreeCollapseEvent, TreeComponent, TreeComponentEventMap, TreeExpandDetail, TreeExpandEvent, TreeItemClickDetail, TreeItemClickEvent, TreeItemDblClickDetail, TreeItemDblClickEvent, TreeSearchHost, TreeSelectDetail, TreeSelectEvent, TreeTickleDetail, TreeTickleEvent } from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type { ChildPreview } from './child-preview.js';\nimport type { ZoomState } from './gestures.js';\nimport type { DiskIsometry } from './poincare-math.js';\nimport type { NodeRenderContext } from './render-context.js';\nimport type { HyperbolicNodeShape } from './render-utils.js';\nimport type {\n HyperbolicEdgeRenderer,\n HyperbolicFocusDetail,\n HyperbolicFocusEvent,\n HyperbolicInteractionMode,\n HyperbolicLayoutEdge,\n HyperbolicLayoutNode,\n Point,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createChildPreviewTiming, diskToHostPx, needsChildPreview, renderChildPreview } from './child-preview.js';\nimport { clampZoomState, createGestureHandlers } from './gestures.js';\nimport { hyperbolicTreeStyles } from './hyperbolictree-styles.js';\nimport { resolveKeyboardAction } from './keyboard.js';\nimport {\n computeCanonicalPositions,\n computeHyperbolicLayout,\n DEFAULT_SIBLING_SPACING,\n findHyperbolicIdOf,\n findHyperbolicKeyPath,\n findHyperbolicNode,\n findHyperbolicPathById,\n hyperbolicIdDepth,\n hyperbolicRelativeFrame,\n isHyperbolicDescendantId,\n} from './layout.js';\nimport { createLazyChildLoader } from './lazy-children.js';\nimport { composeIsometry, rotationIsometry } from './poincare-math.js';\nimport { branchIndices, buildNodeRenderContext, fontMetrics } from './render-context.js';\nimport { renderEdges, renderNodes } from './render-templates.js';\nimport { RENDER_SCALE } from './render-utils.js';\nimport { easeInOutCubic, focusTransition, prefersReducedMotion } from './view-motion.js';\n\nexport interface HyperbolicTreeListElementEventMap extends TreeComponentEventMap {\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'focus': HyperbolicFocusEvent;\n}\n\n/**\n * `ixfx-hyperbolictree-list` — a hyperbolic (Poincaré disk) browser over tree\n * data. The focused node sits at the disk's center; its neighbourhood rings\n * outward, shrinking toward the edge with tree-graph distance. Implements the\n * shared `TreeComponent` interface so existing infrastructure (`TreeDataModel`,\n * `IncrSearchTreeController`, `TreeComponent`-typed code) works unmodified.\n *\n * Deliberate differences from `ixfx-tree-list`: expand/collapse is\n * reinterpreted as focus change (`expand`/`collapse` still fire, for\n * interop); `interactionMode` drops `checked`; `exclusivity` is ignored;\n * `filterPredicate` dims rather than hides; dragging empty space pans;\n * drag-and-drop and `checkboxRenderer` are out of scope.\n *\n * See `src/hyperbolic-tree/README.md` for zoom vs. curvature, crowded fans,\n * label legibility, weighting, branch colours, `::part()` targeting and the\n * full CSS variable list.\n */\n@customElement(`ixfx-hyperbolictree-list`)\nexport class HyperbolicTreeListElement extends LitElement implements TreeComponent, TreeSearchHost {\n /** Delegates focus to the shadow-DOM `[role=\"tree\"]` SVG (nodes themselves are `tabindex=\"-1\"`). */\n static override shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\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 /**\n * Accepted for `TreeComponent` compatibility but ignored — every loaded\n * node is always laid out, so exclusivity is not meaningful here.\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 /**\n * Gesture mapping. `checked` is unsupported (see class docs).\n * @default 'standard'\n */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: HyperbolicInteractionMode = `standard`;\n\n /** Tree-graph steps from the focus to lay out and render. */\n @property({ type: Number, attribute: `max-radius` })\n maxRadius = 4;\n\n /**\n * How nodes are drawn: `dot` (filled circle, label beside it) or `box`\n * (a rectangle containing the label, shrinking with distance from focus).\n * @default 'dot'\n */\n @property({ type: String, attribute: `node-shape`, reflect: true })\n nodeShape: HyperbolicNodeShape = `dot`;\n\n /** `box` mode: labels longer than this are truncated with `…`. `0` disables truncation. */\n @property({ type: Number, attribute: `box-max-chars` })\n boxMaxChars = 24;\n\n /**\n * `box` mode: smallest on-screen label size (CSS px) worth drawing. Boxes\n * whose label would render smaller — or that would overlap a\n * higher-priority label — are drawn as small text-less markers instead\n * (hover one to reveal its label).\n */\n @property({ type: Number, attribute: `min-label-size` })\n minLabelSize = 9;\n\n /**\n * Tint each top-level branch (each child of the root, and everything under\n * it) its own hue, like a classic hyperbolic browser — makes it obvious\n * which subtree a distant node belongs to. Hues are spread evenly around\n * the colour wheel from `--hyperbolictree-branch-hue-start`.\n */\n @property({ type: Boolean, attribute: `color-by-branch`, reflect: true })\n colorByBranch = false;\n\n /** Base node dot radius, as a fraction of the disk radius (the disk has radius 1). */\n @property({ type: Number, attribute: `node-radius` })\n nodeRadius = 0.05;\n\n /** Nodes whose scaled radius falls below this (same fraction-of-disk-radius units) render without a label. */\n @property({ type: Number, attribute: `min-node-radius` })\n minNodeRadius = 0.015;\n\n /** Radius multiplier applied to a node with `weight` at the low end of the currently-visible range. */\n @property({ type: Number, attribute: `min-weight-scale` })\n minWeightScale = 0.6;\n\n /** Radius multiplier applied to a node with `weight` at the high end of the currently-visible range. */\n @property({ type: Number, attribute: `max-weight-scale` })\n maxWeightScale = 1.6;\n\n /**\n * Visual (Euclidean) magnification of the rendered disk — a post-layout\n * scale, distinct from {@link curvature} (which reshapes the layout) and\n * {@link maxRadius} (how many rings are laid out). Labels stay the same\n * size on screen, so zooming in spreads crowded labels apart. Zoom\n * gestures update it; see {@link disableZoomGestures}.\n */\n @property({ type: Number })\n zoom = 1;\n\n /**\n * Turn off zoom gestures: trackpad pinch / Ctrl-⌘-wheel (over the tree),\n * plain wheel (while the tree has keyboard focus), and two-finger touch\n * pinch. All zoom around the pointer, and update {@link zoom}.\n */\n @property({ type: Boolean, attribute: `disable-zoom-gestures` })\n disableZoomGestures = false;\n\n /**\n * Turn off radial labels. By default a label runs along its node's\n * incoming edge (flipped on the left half so it never reads upside-down),\n * so a fan of siblings only needs room for each label's height, not its\n * width. Disabled, every label is horizontal.\n */\n @property({ type: Boolean, attribute: `disable-radial-labels` })\n disableRadialLabels = false;\n\n /**\n * Turn off the child preview: hovering (or keyboard-tickling) a node whose\n * children aren't all legible in the current view — labels culled, or\n * beyond `maxRadius` — pops up a clickable list of them.\n */\n @property({ type: Boolean, attribute: `disable-child-preview` })\n disableChildPreview = false;\n\n /**\n * Minimum hyperbolic distance placed between generations — how curved the\n * space is. Raising it crowds distant generations toward the boundary\n * faster (a stronger fisheye that reads as \"zooming in\" on the focus);\n * lowering it flattens the view toward a Euclidean-feeling layout.\n */\n @property({ type: Number })\n curvature = 1;\n\n /**\n * Minimum hyperbolic distance between adjacent siblings. A bushy node's\n * children are pushed further out until they're at least this far apart,\n * so dragging a crowded fan towards the center always spreads it out —\n * panning can't change hyperbolic distances, only magnify them, so without\n * this a tightly-packed fan stays packed wherever it's dragged. Larger\n * values fan out more when inspected, at the cost of pushing crowds further\n * towards the edge in the overview. `0` disables it.\n */\n @property({ type: Number, attribute: `sibling-spacing` })\n siblingSpacing = DEFAULT_SIBLING_SPACING;\n\n /** Duration (ms) of the animated re-center on focus change. `0` snaps instantly. */\n @property({ type: Number, attribute: `focus-animation-duration` })\n focusAnimationDuration = 400;\n\n /** Optional custom renderer for edges, in place of the default geodesic-arc path. */\n @property({ attribute: false })\n edgeRenderer: HyperbolicEdgeRenderer | undefined;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n private _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 /** The node currently centered on the disk. Pure view-state — `root` is never mutated by focus changes. */\n get focusedNode(): TreeNode | undefined {\n if (this._focusId === undefined)\n return this.#effectiveRoot;\n return findHyperbolicPathById(this.#effectiveRoot, this._focusId)?.at(-1) ?? this.#effectiveRoot;\n }\n\n /**\n * Layout id (see `HyperbolicLayoutNode.id`) of the focused node —\n * `undefined` means the root. Ids rather than `item.key`s, so data that\n * repeats keys across branches still focuses the node actually clicked.\n */\n @state()\n private _focusId: string | undefined = undefined;\n\n /**\n * Canonical → screen projection overriding the settled \"focus at the\n * center\" view — set per-frame while a focus change animates, and by\n * panning. `undefined` when settled on the focus.\n */\n @state()\n private _viewOverride: DiskIsometry | undefined = undefined;\n\n /**\n * Orientation of the settled view (focus at the center). Views are\n * expressed in the focus's own local frame, and focus changes keep\n * whatever orientation the tree had when the animation started, so there\n * is no global \"up\" to snap back to — and no spin on refocus.\n */\n @state()\n private _focusRotation = 0;\n\n /** Pan of the zoomed disk, in screen units — see {@link ZoomState}. */\n @state()\n private _zoomOffset: Point = { x: 0, y: 0 };\n\n /** Layout id of the node whose children are being previewed. */\n @state()\n private _previewId: string | undefined = undefined;\n\n #preview = createChildPreviewTiming({\n candidate: (id) => {\n const nodes = this.#layout().nodes;\n const n = id === undefined || this.disableChildPreview ? undefined : nodes.find(v => v.id === id);\n return n && needsChildPreview(n, nodes, this.#lastLabelIds) ? n.id : undefined;\n },\n setPreviewId: (id) => {\n this._previewId = id;\n },\n });\n\n #lazy = createLazyChildLoader(() => ({ model: this.model, loadChildren: this.loadChildren }), () => this.requestUpdate());\n /** Labels shown in the last render — what the child preview judges legibility by. */\n #lastLabelIds: ReadonlySet<string> = new Set();\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: `.hyperbolictree-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n private tickled = new TickledController<string>(this, {\n getItems: () => this.#layout().nodes.map(n => ({ id: n.id, enabled: true })),\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n onTickle: (id) => {\n this.#preview.update(id);\n if (id === undefined)\n return;\n const n = this.#layout().nodes.find(n => n.id === id);\n if (!n)\n return;\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n },\n });\n\n #modelUnsubscribe: (() => void) | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n #animFrame: number | undefined;\n #resizeObserver: ResizeObserver | undefined;\n\n /** The host's size in CSS px. */\n @state()\n private _hostSize = { width: 0, height: 0 };\n\n #gestures = createGestureHandlers({\n svgRect: () => this.renderRoot.querySelector(`svg.hyperbolictree`)?.getBoundingClientRect(),\n takeView: () => {\n // Grabbing mid-animation freezes the view where it is.\n const view = this.#currentView();\n this.#cancelAnimation();\n this._viewOverride = view;\n return view;\n },\n setView: (view) => {\n this._viewOverride = view;\n },\n zoomState: () => this.#zoomState(),\n setZoomState: (state) => {\n this.zoom = state.zoom;\n this._zoomOffset = state.offset;\n },\n zoomGesturesEnabled: () => !this.disableZoomGestures,\n hasFocus: () => (this.renderRoot as ShadowRoot).activeElement !== null,\n focusTree: () => this.#focusTree(),\n });\n\n // --- Derived data -----------------------------------------------------\n\n get #effectiveRoot(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n #layout(): { nodes: HyperbolicLayoutNode[]; edges: HyperbolicLayoutEdge[] } {\n return computeHyperbolicLayout(this.#effectiveRoot, {\n focusedKey: this._focusId,\n maxRadius: this.maxRadius,\n curvature: this.curvature,\n siblingSpacing: this.siblingSpacing,\n view: this.#currentView(),\n });\n }\n\n get #rootId(): string | undefined {\n return this.#effectiveRoot?.item.key;\n }\n\n /** The projection currently on screen, from the focus's local frame. */\n #currentView(): DiskIsometry {\n return this._viewOverride ?? rotationIsometry(this._focusRotation);\n }\n\n /**\n * The current view re-expressed in `targetId`'s local frame — i.e. the same\n * picture, but with `targetId` as the reference node. Where the view hands\n * over on a focus change.\n */\n #viewFromFrameOf(targetId: string, currentId: string | undefined): DiskIsometry {\n const entries = computeCanonicalPositions(this.#effectiveRoot, 24, this.curvature, this.siblingSpacing);\n const relative = currentId === undefined ? undefined : hyperbolicRelativeFrame(entries, currentId, targetId);\n return relative ? composeIsometry(this.#currentView(), relative) : rotationIsometry(this._focusRotation);\n }\n\n /** Layout id of `node` — by identity, falling back to the first node sharing its key. */\n #idOf(node: TreeNode): string | undefined {\n const root = this.#effectiveRoot;\n const direct = findHyperbolicIdOf(root, node);\n if (direct !== undefined)\n return direct;\n const byKey = findHyperbolicNode(root, node.item.key);\n return byKey ? findHyperbolicIdOf(root, byKey) : undefined;\n }\n\n // --- Lifecycle ----------------------------------------------------------\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 if (typeof ResizeObserver === `function`) {\n this.#resizeObserver = new ResizeObserver(([entry]) => {\n const { width, height } = entry.contentRect;\n this._hostSize = { width, height };\n });\n this.#resizeObserver.observe(this);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n this.#preview.dispose();\n this.#lazy.abortAll();\n if (this.#animFrame !== undefined) {\n cancelAnimationFrame(this.#animFrame);\n this.#animFrame = undefined;\n }\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 #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 protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`root`) && this.root) {\n this.#resetViewState();\n }\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n if (this.model) {\n this.#modelUnsubscribe = this.model._subscribe((event) => {\n if (event.type === `root`) {\n this.#resetViewState();\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n this.requestUpdate();\n }\n });\n this.#resetViewState();\n }\n }\n if (changedProps.has(`interactionMode`)) {\n this.clearSelection();\n }\n if (changedProps.has(`searchModes`))\n this.#syncSearchCommands();\n // A new root invalidates the focus target — fall back to the true root.\n if (this._focusId !== undefined && !findHyperbolicPathById(this.#effectiveRoot, this._focusId)) {\n this._focusId = undefined;\n this._viewOverride = undefined;\n this._focusRotation = 0;\n }\n this.#lazy.ensure(this.#layout().nodes);\n }\n\n #resetViewState(): void {\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._focusId = undefined;\n this._viewOverride = undefined;\n this._focusRotation = 0;\n this._zoomOffset = { x: 0, y: 0 };\n this._previewId = undefined;\n this.#gestures.cancel();\n if (this.#animFrame !== undefined) {\n cancelAnimationFrame(this.#animFrame);\n this.#animFrame = undefined;\n }\n }\n\n // --- Selection ------------------------------------------------------------\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._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail: { selected: new Set(this._selectedNodes), previous },\n bubbles: true,\n composed: true,\n }));\n }\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 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 for (const n of this.#layout().nodes) {\n if (!this.#canSelect(n.node))\n continue;\n this._selectedNodes.add(n.node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\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 // --- Focus ------------------------------------------------------------\n\n /**\n * Re-center the disk on `node` (an animated Möbius transform of the fixed\n * layout — `root` is never mutated). Fires `focus`, plus the semantic\n * `expand`/`collapse` event when the new focus is a descendant/ancestor of\n * the previous one, for interop with generic `TreeComponent` listeners.\n */\n focusOn(node: TreeNode): void {\n const root = this.#effectiveRoot;\n const targetId = this.#idOf(node);\n const currentId = this._focusId ?? this.#rootId;\n if (targetId === undefined || currentId === targetId)\n return;\n const targetNode = findHyperbolicPathById(root, targetId)?.at(-1) ?? node;\n const previousNode = currentId === undefined ? undefined : findHyperbolicPathById(root, currentId)?.at(-1);\n const fromView = this.#viewFromFrameOf(targetId, currentId);\n this._focusId = targetId;\n this.#gestures.cancel();\n this._previewId = undefined;\n this.#animateTo(fromView);\n this.dispatchEvent(new CustomEvent<HyperbolicFocusDetail>(`focus`, {\n detail: { node: targetNode, previous: previousNode },\n bubbles: true,\n composed: true,\n }));\n if (previousNode && currentId !== undefined) {\n if (isHyperbolicDescendantId(targetId, currentId)) {\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node: targetNode, depth: hyperbolicIdDepth(targetId) },\n bubbles: true,\n composed: true,\n }));\n } else if (isHyperbolicDescendantId(currentId, targetId)) {\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node: previousNode, depth: hyperbolicIdDepth(currentId) },\n bubbles: true,\n composed: true,\n }));\n }\n }\n this.requestUpdate();\n }\n\n #cancelAnimation(): void {\n if (this.#animFrame !== undefined) {\n cancelAnimationFrame(this.#animFrame);\n this.#animFrame = undefined;\n }\n }\n\n /** Animate from view `from` (in the new focus's frame) to the settled, centered view — see {@link focusTransition}. */\n #animateTo(from: DiskIsometry): void {\n this.#cancelAnimation();\n const { viewAt, settledRotation } = focusTransition(from);\n this._focusRotation = settledRotation;\n // A zoomed-in view pans back so the new focus lands in the middle of the element.\n const fromOffset = this._zoomOffset;\n if (this.focusAnimationDuration <= 0 || prefersReducedMotion() || typeof requestAnimationFrame !== `function`) {\n this._viewOverride = undefined;\n this._zoomOffset = { x: 0, y: 0 };\n return;\n }\n const start = performance.now();\n const duration = this.focusAnimationDuration;\n const step = (now: number): void => {\n const t = Math.min(1, (now - start) / duration);\n const remaining = 1 - easeInOutCubic(t);\n this._zoomOffset = { x: fromOffset.x * remaining, y: fromOffset.y * remaining };\n this._viewOverride = t >= 1 ? undefined : viewAt(t);\n this.#animFrame = t < 1 ? requestAnimationFrame(step) : undefined;\n };\n this.#animFrame = requestAnimationFrame(step);\n }\n\n #focusAndMaybeSelect(node: TreeNode): void {\n this.focusOn(node);\n const id = this.#idOf(node);\n if (id !== undefined)\n this.tickled.setTickled(id);\n if (this.interactionMode === `implicit`)\n this.select(node);\n }\n\n // --- Navigation -----------------------------------------------------------\n\n /** Focus + select the node at `keys` (path from the root's children). Returns `true` if found. */\n navigateTo(keys: readonly string[]): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n let current: TreeNode = root;\n for (const key of keys) {\n const found = current.children?.find(n => n.item.key === key);\n if (!found)\n return false;\n current = found;\n }\n this.focusOn(current);\n this.select(current);\n const id = this.#idOf(current);\n if (id !== undefined)\n this.tickled.setTickled(id);\n this.requestUpdate();\n return true;\n }\n\n /** Focus + select the first node for which `predicate` returns `true`. Returns `true` if found. */\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const keyPath = findHyperbolicKeyPath(root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /**\n * Bring the node with `key` into the visible window and move the keyboard\n * cursor to it, without changing the selection. Used by incremental-search\n * \"navigate\" mode.\n */\n revealKey(key: string): boolean {\n const node = findHyperbolicNode(this.#effectiveRoot, key);\n const id = node ? this.#idOf(node) : undefined;\n if (!node || id === undefined)\n return false;\n if (!this.#layout().nodes.some(n => n.id === id))\n this.focusOn(node);\n this.tickled.setTickled(id);\n this.requestUpdate();\n return true;\n }\n\n /**\n * All nodes currently laid out on the disk (within `maxRadius` of the\n * focus), in render (ring-major) order. Unlike `ixfx-icicletree-list`, the\n * focused node itself is included — it is literally rendered, at the\n * center.\n */\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n return this.#layout().nodes.map(n => ({ node: n.node, depth: n.depth }));\n }\n\n // --- Pointer / keyboard ---------------------------------------------------\n\n #matchesFilter(node: TreeNode, depth: number): boolean {\n if (!this.filterPredicate)\n return true;\n if (this.filterPredicate(node, depth))\n return true;\n return node.children?.some(child => this.#matchesFilter(child, depth + 1)) ?? false;\n }\n\n #handleItemClick(n: HyperbolicLayoutNode, event: MouseEvent): void {\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.interactionMode === `standard` && (event.ctrlKey || event.metaKey)) {\n if (this._selectedNodes.has(n.node)) {\n this.deselect(n.node);\n } else if (this.#canSelect(n.node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.add(n.node);\n this.selectedNode = n.node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n } else if (this.interactionMode !== `manual`) {\n this.select(n.node);\n }\n this.tickled.setTickled(n.id);\n this.focusOn(n.node);\n }\n\n #handleItemDblClick(n: HyperbolicLayoutNode): void {\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: n.node, depth: n.depth },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n const root = this.#effectiveRoot;\n if (this.disableKeyboardNavigation || !root)\n return;\n if (event.key === `Escape` && this._previewId !== undefined) {\n event.preventDefault();\n this._previewId = undefined;\n return;\n }\n const { action, handled } = resolveKeyboardAction(event.key, root, this._focusId ?? root.item.key, this.#layout().nodes);\n if (handled)\n event.preventDefault();\n if (action.kind === `focus`) {\n this.#focusAndMaybeSelect(action.node);\n } else if (action.kind === `activate`) {\n if (this.interactionMode !== `manual`)\n this.select(action.node);\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: action.node, depth: action.depth },\n bubbles: true,\n composed: true,\n }));\n }\n }\n\n #zoomState(): ZoomState {\n return clampZoomState({ zoom: this.zoom, offset: this._zoomOffset });\n }\n\n /**\n * Any pointer interaction (a node press, or a pan) moves keyboard focus to\n * the tree, so the user can carry straight on with the arrow keys.\n * Focuses the stable `<svg role=\"tree\">` — not the node, which paint-order\n * re-sorting may move in the DOM (dropping its focus) — without scrolling.\n */\n #focusTree(): void {\n this.renderRoot.querySelector<SVGSVGElement>(`svg.hyperbolictree`)?.focus({ preventScroll: true });\n }\n\n #handleNodePointerDown(event: PointerEvent): void {\n // Keep node presses from starting a background pan.\n event.stopPropagation();\n this.#focusTree();\n }\n\n // --- Child preview --------------------------------------------------------\n\n #pickPreviewChild(child: TreeNode): void {\n this.#preview.hide();\n if (this.interactionMode !== `manual`)\n this.select(child);\n const id = this.#idOf(child);\n if (id !== undefined)\n this.tickled.setTickled(id);\n this.focusOn(child);\n this.#focusTree();\n }\n\n #previewFor(nodes: readonly HyperbolicLayoutNode[]): ChildPreview | undefined {\n const n = this._previewId === undefined || this.disableChildPreview ? undefined : nodes.find(v => v.id === this._previewId);\n if (!n)\n return undefined;\n const { width, height } = this._hostSize;\n const anchor = diskToHostPx(n.position, this.#zoomState(), width || 420, height || 420);\n return { node: n.node, anchor, above: anchor.y > (height || 420) / 2 };\n }\n\n // --- Render ---------------------------------------------------------------\n\n #nodeContext(nodes: readonly HyperbolicLayoutNode[], branches: ReadonlyMap<string, number>): NodeRenderContext {\n return buildNodeRenderContext(nodes, {\n nodeShape: this.nodeShape,\n radialLabels: !this.disableRadialLabels,\n zoom: this.#zoomState().zoom,\n font: fontMetrics(this, Math.min(this._hostSize.width, this._hostSize.height), this.zoom),\n branches,\n boxMaxChars: this.boxMaxChars,\n minLabelSize: this.minLabelSize,\n nodeRadius: this.nodeRadius,\n minNodeRadius: this.minNodeRadius,\n minWeightScale: this.minWeightScale,\n maxWeightScale: this.maxWeightScale,\n isSelected: node => this._selectedNodes.has(node),\n isTickled: id => this.tickled.isTickled(id),\n });\n }\n\n #renderNodes(nodes: readonly HyperbolicLayoutNode[], ctx: NodeRenderContext): unknown {\n return renderNodes(nodes, this.nodeShape, {\n ctx,\n state: {\n isSelected: node => this._selectedNodes.has(node),\n isTickled: id => this.tickled.isTickled(id),\n showTitle: n => this.disableChildPreview || !n.node.children?.length,\n isFiltered: n => !this.#matchesFilter(n.node, n.depth),\n isPending: node => this.#lazy.isPending(node),\n },\n handlers: {\n onPointerDown: e => this.#handleNodePointerDown(e),\n onClick: (n, e) => {\n e.stopPropagation();\n this.#handleItemClick(n, e);\n },\n onDblClick: (n, e) => {\n e.stopPropagation();\n this.#handleItemDblClick(n);\n },\n onPointerEnter: id => this.tickled.handlePointerEnter(id),\n },\n });\n }\n\n protected override render() {\n const { nodes, edges } = this.#layout();\n const byId = new Map(nodes.map(n => [n.id, n]));\n const branches = branchIndices(this.#effectiveRoot);\n const ctx = this.#nodeContext(nodes, branches);\n this.#lastLabelIds = ctx.labelIds;\n const { zoom, offset } = this.#zoomState();\n const pan = offset.x === 0 && offset.y === 0 ? `` : `translate(${offset.x * RENDER_SCALE} ${offset.y * RENDER_SCALE}) `;\n return html`\n <svg\n class=\"hyperbolictree\"\n viewBox=\"${-1.05 * RENDER_SCALE} ${-1.05 * RENDER_SCALE} ${2.1 * RENDER_SCALE} ${2.1 * RENDER_SCALE}\"\n preserveAspectRatio=\"xMidYMid meet\"\n role=\"tree\"\n tabindex=\"0\"\n data-input-mode=${this.tickled.inputMode}\n data-node-shape=${this.nodeShape}\n @keydown=${(e: KeyboardEvent) => this.#handleKeyDown(e)}\n @pointerdown=${(e: PointerEvent) => this.#gestures.onPointerDown(e)}\n @pointermove=${(e: PointerEvent) => this.#gestures.onPointerMove(e)}\n @pointerup=${(e: PointerEvent) => this.#gestures.onPointerUp(e)}\n @pointercancel=${(e: PointerEvent) => this.#gestures.onPointerUp(e)}\n @wheel=${(e: WheelEvent) => this.#gestures.onWheel(e)}\n @pointerleave=${() => this.tickled.clearTickled()}\n >\n <g class=\"zoom\" transform=\"${pan}scale(${zoom})\">\n <circle class=\"disk-boundary\" part=\"boundary\" cx=\"0\" cy=\"0\" r=${RENDER_SCALE} />\n <g class=\"edges\" part=\"edges\">\n ${renderEdges(edges, byId, branches, this.edgeRenderer)}\n </g>\n <g class=\"nodes\" part=\"nodes\">\n ${this.#renderNodes(nodes, ctx)}\n </g>\n </g>\n </svg>\n ${renderChildPreview(this.#previewFor(nodes), {\n onPointerEnter: () => this.#preview.pointerEnter(),\n onPointerLeave: () => this.#preview.pointerLeave(this.tickled.tickledId),\n onPick: child => this.#pickPreviewChild(child),\n })}\n ${this.search.renderField()}\n `;\n }\n\n static override styles = [themeFallbacks, listSearchStyles, hyperbolicTreeStyles];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-hyperbolictree-list': HyperbolicTreeListElement;\n }\n}\n\nexport interface HyperbolicTreeListElement {\n addEventListener: (<K extends keyof HyperbolicTreeListElementEventMap>(\n type: K,\n listener: (this: HyperbolicTreeListElement, event: HyperbolicTreeListElementEventMap[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 HyperbolicTreeListElementEventMap>(\n type: K,\n listener: (this: HyperbolicTreeListElement, event: HyperbolicTreeListElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","/**\n * Pure icicle layout: `TreeNode` + value accessor + depth window → positioned rects.\n * No Lit, no DOM — unit-testable in isolation.\n */\n\nimport type {\n ComputeIcicleLayoutOptions,\n IcicleRect,\n IcicleValueAccessor,\n TreeNode,\n} from './types.js';\n\n/** Coerce a raw accessor result to a non-negative finite weight. */\nexport function normaliseValue(raw: unknown): number {\n return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? raw : 0;\n}\n\n/** Depth-first search for the node with `key`. Returns `undefined` when absent. */\nexport function findIcicleNode(root: TreeNode | undefined, key: string): TreeNode | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const hit = findIcicleNode(child, key);\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/**\n * Chain of nodes from `root` down to (and including) the node with `key`.\n * Returns `undefined` when the key is absent. The first entry is always `root`.\n */\nexport function findIciclePath(root: TreeNode | undefined, key: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return [root];\n for (const child of root.children ?? []) {\n const hit = findIciclePath(child, key);\n if (hit)\n return [root, ...hit];\n }\n return undefined;\n}\n\n/**\n * Compute the visible rectangles for an icicle view.\n *\n * Bands start at the zoom node's **children** (the zoom node itself is shown in\n * the breadcrumb strip, never as a rect — matching `TreeComponent.getNodes()`,\n * where the root is never listed). Each band spans 0–1; a rect's `x`/`width`\n * are fractions of its band, proportional to `valueAccessor` shares among\n * siblings. Siblings whose weights all normalise to `0` split the band equally.\n *\n * @param root True tree root. `undefined` (or a root without children) yields `[]`.\n * @param options `valueAccessor` (default equal weights), `maxDepth` (band count,\n * default unlimited), `zoomKey` (visual root, default true root; unknown keys\n * fall back to the true root).\n */\nexport function computeIcicleLayout(\n root: TreeNode | undefined,\n options: ComputeIcicleLayoutOptions = {},\n): IcicleRect[] {\n if (!root?.children?.length)\n return [];\n const { maxDepth = Number.POSITIVE_INFINITY, valueAccessor = () => 1, zoomKey, hideLeaves = false } = options;\n if (maxDepth <= 0)\n return [];\n\n const zoomNode = zoomKey === undefined ? root : (findIcicleNode(root, zoomKey) ?? root);\n const zoomPath = findIciclePath(root, zoomNode.item.key);\n // Absolute depth of the zoom node: root is -1 so its children are depth 0.\n const zoomDepth = zoomPath ? zoomPath.length - 2 : -1;\n const siblings = zoomNode.children ?? [];\n if (siblings.length === 0)\n return [];\n\n // A \"loaded, childless\" node is a leaf; `children === undefined` means not\n // yet loaded (might still turn out to have children), so it's never hidden.\n const isLeaf = (node: TreeNode): boolean =>\n node.item.isLeaf === true || (node.children !== undefined && node.children.length === 0);\n\n const rects: IcicleRect[] = [];\n const layoutLevel = (\n nodes: readonly TreeNode[],\n depth: number,\n relativeDepth: number,\n offset: number,\n span: number,\n parentKey: string | undefined,\n ): void => {\n const visible = hideLeaves ? nodes.filter(n => !isLeaf(n)) : nodes;\n if (visible.length === 0 || relativeDepth >= maxDepth)\n return;\n const weights = visible.map(n => normaliseValue((valueAccessor as IcicleValueAccessor)(n.item)));\n const total = weights.reduce((a, b) => a + b, 0);\n const setSize = visible.length;\n let cursor = offset;\n visible.forEach((node, index) => {\n const share = total > 0 ? weights[index] / total : 1 / setSize;\n const width = span * share;\n const children = node.children ?? [];\n rects.push({\n node,\n depth,\n relativeDepth,\n x: cursor,\n width,\n parentKey,\n index,\n setSize,\n hasChildren: children.length > 0 || (node.children === undefined && node.item.isLeaf !== true),\n });\n if (children.length > 0) {\n layoutLevel(children, depth + 1, relativeDepth + 1, cursor, width, node.item.key);\n }\n cursor += width;\n });\n };\n\n layoutLevel(siblings, zoomDepth + 1, 0, 0, 1, zoomNode.item.key);\n return rects;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TreeActivateDetail, TreeActivateEvent, TreeCollapseDetail, TreeCollapseEvent, TreeComponent, TreeComponentEventMap, TreeExpandDetail, TreeExpandEvent, TreeItemClickDetail, TreeItemClickEvent, TreeItemDblClickDetail, TreeItemDblClickEvent, TreeSearchHost, TreeSelectDetail, TreeSelectEvent, TreeTickleDetail, TreeTickleEvent } from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type {\n IcicleInteractionMode,\n IcicleOrientation,\n IcicleRect,\n IcicleValueAccessor,\n} from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { computeIcicleLayout, findIcicleNode, findIciclePath } from './layout.js';\nimport '../crumbs/crumb-navigation.js';\n\n/** Fired when the zoom root changes. `node` is `undefined` on zoom-out to the full tree. */\nexport type IcicleZoomDetail = {\n readonly node: TreeNode | undefined;\n /** Absolute depth of the zoom node (root's children are depth 0); `-1` when fully zoomed out. */\n readonly depth: number;\n};\n\nexport type IcicleZoomEvent = CustomEvent<IcicleZoomDetail>;\n\nexport interface IcicleTreeListElementEventMap extends TreeComponentEventMap {\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'zoom': IcicleZoomEvent;\n}\n\n/**\n * `ixfx-icicletree-list` — an icicle (partition) view over tree data.\n *\n * Each depth is a horizontal band (or vertical band when\n * `orientation=\"vertical\"`); each node is a rectangle whose width is\n * proportional to its `valueAccessor` share of its parent, stacked within the\n * band. Implements the shared `TreeComponent` interface so existing\n * infrastructure (`TreeDataModel`, `IncrSearchTreeController`,\n * `TreeComponent`-typed code) works unmodified.\n *\n * Differences from `ixfx-tree-list` (deliberate):\n * - **Expand/collapse is reinterpreted as zoom.** Clicking a branch zooms so it\n * becomes the visual root; ancestors collapse into the breadcrumb strip.\n * `expand`/`collapse` events fire on zoom-in/zoom-out with the same detail\n * shape so existing listeners keep working conceptually.\n * - **`interactionMode` drops `checked`** — a checkbox per rectangle does not\n * hold up at small rect sizes.\n * - **`exclusivity` is accepted but ignored** — nothing is independently \"open\".\n * - **`filterPredicate` dims** non-matching rects instead of hiding rows.\n * - Drag-and-drop is out of scope.\n */\n@customElement(`ixfx-icicletree-list`)\nexport class IcicleTreeListElement extends LitElement implements TreeComponent, TreeSearchHost {\n /**\n * Delegates focus to the shadow-DOM `[role=\"tree\"]` div (the actual\n * `tabindex=\"0\"` element — rects themselves are `tabindex=\"-1\"`). Without\n * this, the host custom element has no `tabIndex` of its own: `el.focus()`\n * is a no-op, clicking a rect doesn't focus the tree (so arrow keys don't\n * work until the user separately Tabs in), and the host never reports as\n * `document.activeElement`.\n */\n static override shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true };\n\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 /**\n * Accepted for `TreeComponent` compatibility but ignored — an icicle has no\n * independently open branches, so exclusivity is not meaningful.\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 /**\n * Gesture mapping. `checked` is unsupported (see class docs).\n * @default 'standard'\n */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: IcicleInteractionMode = `standard`;\n\n /**\n * Band stacking direction.\n * - `'horizontal'` — bands stack top-down, rects flow left-to-right.\n * - `'vertical'` — bands stack left-to-right, rects flow top-down.\n */\n @property({ type: String, reflect: true })\n orientation: IcicleOrientation = `horizontal`;\n\n /** How many depth bands render at once from the current zoom root. */\n @property({ type: Number, attribute: `max-depth` })\n maxDepth = 4;\n\n /**\n * Rects narrower than this (px, horizontal orientation only) rotate their\n * label 90° (`writing-mode: vertical-rl`) to fit more characters in the\n * available band height instead of the shrinking width. Below\n * {@link minVerticalLabelWidth} even the rotated label is hidden.\n */\n @property({ type: Number, attribute: `min-label-width` })\n minLabelWidth = 40;\n\n /**\n * Rects narrower than this (px) hide their label outright — even the\n * rotated form from {@link minLabelWidth} doesn't fit. Ignored in\n * `orientation=\"vertical\"`, where labels never rotate.\n */\n @property({ type: Number, attribute: `min-vertical-label-width` })\n minVerticalLabelWidth = 16;\n\n /**\n * Omit leaf nodes entirely — no rect, no layout space — at every depth,\n * not just the deepest visible band. Non-leaf siblings renormalise to fill\n * the freed space. A node is a leaf when `item.isLeaf === true`, or its\n * `children` array has already loaded and is empty — a node whose\n * `children` is still `undefined` (not yet loaded) is never hidden.\n */\n @property({ type: Boolean, attribute: `hide-leaves`, reflect: true })\n hideLeaves = false;\n\n /** Weight per node. Default `() => 1` — equal-width siblings. */\n @property({ attribute: false })\n valueAccessor: IcicleValueAccessor = () => 1;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n private _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 /** Current zoom root. `undefined` when showing the full tree. Pure view-state — `root` is never mutated. */\n get focusedNode(): TreeNode | undefined {\n if (this._zoomKey === undefined)\n return undefined;\n return findIcicleNode(this.#effectiveRoot, this._zoomKey);\n }\n\n @state()\n private _zoomKey: string | undefined = undefined;\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: `.icicle-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n private tickled = new TickledController<string>(this, {\n getItems: () => this.#rects().map(r => ({ id: r.node.item.key, enabled: true })),\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n onTickle: (id) => {\n if (id === undefined)\n return;\n const rect = this.#rects().find(r => r.node.item.key === id);\n if (!rect)\n return;\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n },\n });\n\n #modelUnsubscribe: (() => void) | undefined;\n #pendingKeys = new Set<string>();\n #aborters = new Map<string, AbortController>();\n #anchorIndex: number | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n #resizeObserver: ResizeObserver | undefined;\n\n /**\n * Shared instant tooltip for rects whose label is rotated or hidden for\n * lack of space — positioned purely via CSS anchor positioning\n * (`anchor-name` on the tickled rect, `position-anchor` here), shown/hidden\n * via the Popover API. Deliberately not the native `title` attribute: that\n * has a UA-controlled show delay, this shows the instant the rect is\n * tickled (hover or keyboard).\n */\n @query(`#icicle-tooltip`)\n private _tooltipEl: HTMLElement | undefined;\n\n // --- Derived data ---------------------------------------------------------\n\n get #effectiveRoot(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n #rects(): IcicleRect[] {\n return computeIcicleLayout(this.#effectiveRoot, {\n valueAccessor: this.valueAccessor,\n maxDepth: this.maxDepth,\n zoomKey: this._zoomKey,\n hideLeaves: this.hideLeaves,\n });\n }\n\n // --- Lifecycle ------------------------------------------------------------\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 if (typeof ResizeObserver !== `undefined`) {\n this.#resizeObserver = new ResizeObserver(() => this.requestUpdate());\n this.#resizeObserver.observe(this);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n for (const aborter of this.#aborters.values())\n aborter.abort();\n this.#aborters.clear();\n this.#pendingKeys.clear();\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\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 #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 protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`root`) && this.root) {\n this.#resetViewState();\n }\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n if (this.model) {\n this.#modelUnsubscribe = this.model._subscribe((event) => {\n if (event.type === `root`) {\n this.#resetViewState();\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n this.requestUpdate();\n }\n });\n this.#resetViewState();\n }\n }\n if (changedProps.has(`interactionMode`)) {\n this.#anchorIndex = undefined;\n this.clearSelection();\n }\n if (changedProps.has(`searchModes`))\n this.#syncSearchCommands();\n // A new root invalidates the zoom target — fall back to the full tree.\n if (this._zoomKey !== undefined && !findIcicleNode(this.#effectiveRoot, this._zoomKey)) {\n this._zoomKey = undefined;\n }\n this.#ensureVisibleChildren();\n this.#syncTooltip();\n }\n\n /** The host's own (viewport) extent — width in horizontal orientation, height in vertical. */\n #hostExtent(): number {\n return (this.orientation === `vertical` ? this.clientHeight : this.clientWidth) || 0;\n }\n\n /**\n * Whether `rect`'s label should be rotated or hidden for lack of space, per\n * {@link minLabelWidth} / {@link minVerticalLabelWidth}. `orientation=\"vertical\"`\n * rects never rotate — hides outright at `minLabelWidth` instead, same as before.\n */\n #labelMode(rect: IcicleRect): { hidden: boolean; rotated: boolean } {\n const hostExtent = this.#hostExtent();\n if (hostExtent === 0)\n return { hidden: false, rotated: false };\n const vertical = this.orientation === `vertical`;\n const pixelWidth = rect.width * hostExtent;\n if (vertical)\n return { hidden: pixelWidth < this.minLabelWidth, rotated: false };\n if (pixelWidth < this.minVerticalLabelWidth)\n return { hidden: true, rotated: false };\n return { hidden: false, rotated: pixelWidth < this.minLabelWidth };\n }\n\n /** Anchor the shared tooltip popover to the tickled rect, if its label needs one. */\n #syncTooltip(): void {\n const popover = this._tooltipEl;\n if (!popover?.popover)\n return;\n const key = this.tickled.tickledId;\n const rect = key === undefined ? undefined : this.#rects().find(r => r.node.item.key === key);\n const mode = rect ? this.#labelMode(rect) : undefined;\n const isOpen = popover.matches(`:popover-open`);\n if (rect && mode && (mode.hidden || mode.rotated)) {\n popover.textContent = rect.node.item.label;\n if (!isOpen) {\n try {\n popover.showPopover();\n } catch {\n // Popover API unsupported — ignore.\n }\n }\n } else if (isOpen) {\n try {\n popover.hidePopover();\n } catch {\n // Popover API unsupported — ignore.\n }\n }\n }\n\n #resetViewState(): void {\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._zoomKey = undefined;\n this.#anchorIndex = undefined;\n }\n\n // --- Lazy children --------------------------------------------------------\n\n #ensureVisibleChildren(): void {\n if (!this.model && !this.loadChildren)\n return;\n for (const rect of this.#rects()) {\n const { node } = rect;\n if (node.children !== undefined || this.#pendingKeys.has(node.item.key))\n continue;\n // #rects() only ever yields rects within the visible window (relativeDepth\n // < maxDepth), so every rect reaching here is a currently-rendered node\n // whose children aren't loaded yet — fetch them so zooming in works.\n void this.#loadChildren(node, rect.depth);\n }\n }\n\n async #loadChildren(node: TreeNode, depth: number): Promise<void> {\n const key = node.item.key;\n this.#pendingKeys.add(key);\n const controller = new AbortController();\n this.#aborters.set(key, controller);\n this.requestUpdate();\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 } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n } finally {\n this.#pendingKeys.delete(key);\n this.#aborters.delete(key);\n if (!controller.signal.aborted)\n this.requestUpdate();\n }\n }\n\n // --- Selection ------------------------------------------------------------\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._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail: { selected: new Set(this._selectedNodes), previous },\n bubbles: true,\n composed: true,\n }));\n }\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 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 for (const rect of this.#rects()) {\n if (!this.#canSelect(rect.node))\n continue;\n this._selectedNodes.add(rect.node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\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 // --- Zoom -----------------------------------------------------------------\n\n /**\n * Drill down so `node` becomes the visual root (ancestors move to the\n * breadcrumb strip). Pure view-state — `root` is never mutated.\n * Fires `zoom` and the semantic `expand` event.\n */\n zoomTo(node: TreeNode): void {\n if (this._zoomKey === node.item.key)\n return;\n this._zoomKey = node.item.key;\n this.tickled.clearTickled();\n const depth = findIciclePath(this.#effectiveRoot, node.item.key)?.length;\n const absoluteDepth = depth === undefined ? -1 : depth - 2;\n this.dispatchEvent(new CustomEvent<IcicleZoomDetail>(`zoom`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n }\n\n /**\n * Zoom back out to the full tree. Fires `zoom` (with `node: undefined`) and\n * the semantic `collapse` event for the previous zoom root.\n */\n zoomOut(): void {\n if (this._zoomKey === undefined)\n return;\n const previous = this.focusedNode;\n const path = this._zoomKey === undefined\n ? undefined\n : findIciclePath(this.#effectiveRoot, this._zoomKey);\n const absoluteDepth = path === undefined ? -1 : path.length - 2;\n this._zoomKey = undefined;\n this.tickled.clearTickled();\n this.dispatchEvent(new CustomEvent<IcicleZoomDetail>(`zoom`, {\n detail: { node: undefined, depth: -1 },\n bubbles: true,\n composed: true,\n }));\n if (previous) {\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node: previous, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n }\n this.requestUpdate();\n }\n\n #canZoom(node: TreeNode): boolean {\n if (node.item.isLeaf === true)\n return false;\n if (node.children !== undefined)\n return node.children.length > 0;\n // Not yet loaded — zoomable when a loader could provide children.\n return this.model !== undefined || this.loadChildren !== undefined;\n }\n\n // --- Navigation -----------------------------------------------------------\n\n /**\n * Zoom so the node at `keys` (path from the root's children) is visible,\n * then select it. Returns `true` if the path was found.\n */\n navigateTo(keys: readonly string[]): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n let current: TreeNode = root;\n const path: TreeNode[] = [];\n for (const key of keys) {\n const found = current.children?.find(n => n.item.key === key);\n if (!found)\n return false;\n path.push(found);\n current = found;\n }\n const target = path.at(-1)!;\n // Keep the target inside the depth window: zoom to the ancestor `maxDepth`\n // bands above it, or the full tree when it already fits.\n if (path.length > this.maxDepth) {\n this.zoomTo(path[path.length - this.maxDepth - 1]);\n } else if (this._zoomKey !== undefined) {\n this.zoomOut();\n }\n this.select(target);\n this.tickled.setTickled(target.item.key);\n this.requestUpdate();\n return true;\n }\n\n /**\n * Zoom + select the first node for which `predicate` returns `true`.\n * Returns `true` if a matching node was found.\n */\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const keyPath = this.#findKeyPath(root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /**\n * Zoom so the node with `key` is visible and move the keyboard cursor to it,\n * without changing the selection. Used by incremental-search \"navigate\" mode.\n */\n revealKey(key: string): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const path = this.#findKeyPath(root.children, n => n.item.key === key);\n if (!path)\n return false;\n if (path.length > this.maxDepth) {\n const ancestor = this.#resolveKeyPath(path.slice(0, path.length - this.maxDepth));\n if (ancestor)\n this.zoomTo(ancestor);\n }\n this.tickled.setTickled(key);\n this.requestUpdate();\n return true;\n }\n\n #resolveKeyPath(keys: readonly string[]): TreeNode | undefined {\n let current = this.#effectiveRoot;\n for (const key of keys) {\n const found = key === current?.item.key ? current : current?.children?.find(n => n.item.key === key);\n if (!found)\n return undefined;\n current = found;\n }\n return current;\n }\n\n #findKeyPath(\n nodes: readonly 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 hit = this.#findKeyPath(node.children, predicate, path);\n if (hit)\n return hit;\n }\n }\n return undefined;\n }\n\n /**\n * All nodes currently visible as rectangles, in render (band-major) order,\n * with absolute depth (root's children are depth 0).\n */\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n return this.#rects().map(r => ({ node: r.node, depth: r.depth }));\n }\n\n // --- Pointer / keyboard ---------------------------------------------------\n\n #matchesFilter(node: TreeNode, depth: number): boolean {\n if (!this.filterPredicate)\n return true;\n if (this.filterPredicate(node, depth))\n return true;\n return node.children?.some(child => this.#matchesFilter(child, depth + 1)) ?? false;\n }\n\n #handleItemClick(rect: IcicleRect, index: number, event: MouseEvent): void {\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.interactionMode === `standard` && (event.ctrlKey || event.metaKey)) {\n if (this._selectedNodes.has(rect.node)) {\n this.deselect(rect.node);\n } else if (this.#canSelect(rect.node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.add(rect.node);\n this.selectedNode = rect.node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n this.#anchorIndex = index;\n } else if (this.interactionMode === `standard` && event.shiftKey && this.#anchorIndex !== undefined) {\n const rects = this.#rects();\n const from = Math.min(this.#anchorIndex, index);\n const to = Math.max(this.#anchorIndex, index);\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = new Set(\n rects.slice(from, to + 1).map(r => r.node).filter(n => this.#canSelect(n)),\n );\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n } else if (this.interactionMode !== `manual`) {\n this.select(rect.node);\n this.#anchorIndex = index;\n }\n this.tickled.setTickled(rect.node.item.key);\n if (this.#canZoom(rect.node))\n this.zoomTo(rect.node);\n }\n\n #handleItemDblClick(rect: IcicleRect): void {\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n if (this.disableKeyboardNavigation)\n return;\n const rects = this.#rects();\n if (rects.length === 0)\n return;\n const tickledKey = this.tickled.tickledId;\n const currentIndex = tickledKey === undefined\n ? -1\n : rects.findIndex(r => r.node.item.key === tickledKey);\n const current = currentIndex >= 0 ? rects[currentIndex] : undefined;\n\n const moveTo = (rect: IcicleRect | undefined) => {\n if (!rect)\n return;\n event.preventDefault();\n this.tickled.setTickled(rect.node.item.key);\n // implicit: single selection follows the keyboard cursor (mirrors tree-base's implicit mode).\n if (this.interactionMode === `implicit`)\n this.select(rect.node);\n };\n\n switch (event.key) {\n case `ArrowLeft`:\n case `ArrowRight`: {\n event.preventDefault();\n const dir = event.key === `ArrowRight` ? 1 : -1;\n if (!current) {\n moveTo(rects[0]);\n return;\n }\n // Siblings share a band (relativeDepth) and parent.\n const siblings = rects.filter(r =>\n r.relativeDepth === current.relativeDepth && r.parentKey === current.parentKey);\n const at = siblings.findIndex(r => r.node.item.key === current.node.item.key);\n moveTo(siblings[at + dir] ?? (dir > 0 ? siblings[0] : siblings.at(-1)));\n return;\n }\n case `ArrowUp`: {\n // Parent band.\n if (!current) {\n moveTo(rects[0]);\n return;\n }\n const parent = current.parentKey === undefined\n ? undefined\n : rects.find(r => r.node.item.key === current.parentKey);\n moveTo(parent ?? rects[0]);\n return;\n }\n case `ArrowDown`: {\n // First-child band.\n if (!current) {\n moveTo(rects[0]);\n return;\n }\n moveTo(rects.find(r => r.parentKey === current.node.item.key));\n return;\n }\n case `Home`:\n moveTo(rects[0]);\n return;\n case `End`:\n moveTo(rects.at(-1));\n return;\n case `Enter`: {\n if (!current)\n return;\n event.preventDefault();\n if (this.interactionMode !== `manual`)\n this.select(current.node);\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n // Mirrors #handleItemClick: Enter on a node should zoom in exactly\n // like clicking it, not just select + activate.\n if (this.#canZoom(current.node))\n this.zoomTo(current.node);\n return;\n }\n case `Escape`:\n if (this._zoomKey !== undefined) {\n event.preventDefault();\n this.zoomOut();\n }\n }\n }\n\n // --- Render ---------------------------------------------------------------\n\n #renderBreadcrumb(): unknown {\n const zoomNode = this.focusedNode;\n if (zoomNode === undefined)\n return nothing;\n return html`\n <nav class=\"breadcrumb\" part=\"breadcrumb\" aria-label=\"Icicle zoom path\">\n <ixfx-crumb-navigation\n with-up\n .root=${this.#effectiveRoot}\n .selectedNode=${zoomNode}\n @select=${this.#onCrumbSelect}\n @item-click=${(e: Event) => e.stopPropagation()}\n @tickle=${(e: Event) => e.stopPropagation()}\n @expand=${(e: Event) => e.stopPropagation()}\n ></ixfx-crumb-navigation>\n </nav>\n `;\n }\n\n /**\n * Translate crumb-trail selection (crumb clicks + the up-button) into zoom\n * state. The event is stopped: crumb clicks must not bubble as our `select`\n * (the selection set is unchanged by them).\n */\n #onCrumbSelect(event: Event): void {\n event.stopPropagation();\n const selected = (event as CustomEvent<TreeSelectDetail>).detail.selected;\n const node = [...selected].at(0);\n if (!node)\n return;\n if (node.item.key === this.#effectiveRoot?.item.key) {\n this.zoomOut();\n } else {\n this.zoomTo(node);\n }\n }\n\n #renderRect(rect: IcicleRect): unknown {\n const { node } = rect;\n const selected = this._selectedNodes.has(node);\n const tickled = this.tickled.isTickled(node.item.key);\n const filtered = !this.#matchesFilter(node, rect.depth);\n const pending = this.#pendingKeys.has(node.item.key);\n const sizePct = `${(rect.width * 100).toFixed(4)}%`;\n const xPct = `${(rect.x * 100).toFixed(4)}%`;\n const vertical = this.orientation === `vertical`;\n const { hidden: hideLabel, rotated } = this.#labelMode(rect);\n const needsTooltip = tickled && (hideLabel || rotated);\n // Positioned absolutely (not flexed) so every rect's `left`/`top` is a\n // fraction of the same band width/height its parent's rect used — a flex\n // row's per-item `gap` compounds across sibling counts and drifts child\n // bands out of alignment with their parent's boundaries.\n let sizeStyle = vertical\n ? `top:${xPct};height:calc(${sizePct} - var(--icicletree-rect-gap))`\n : `left:${xPct};width:calc(${sizePct} - var(--icicletree-rect-gap))`;\n // Only the tickled rect ever claims this anchor name — the shared tooltip\n // (`position-anchor: --icicle-rect-anchor`) follows it via pure CSS.\n if (needsTooltip)\n sizeStyle += `;anchor-name:--icicle-rect-anchor`;\n return html`\n <div\n class=\"item rect ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${filtered ? `filtered` : ``} ${pending ? `loading` : ``} ${rect.width <= 0 ? `empty` : ``} ${rotated ? `rotated` : ``}\"\n data-key=${node.item.key}\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-level=${rect.depth + 1}\n aria-selected=${selected}\n aria-setsize=${rect.setSize}\n aria-posinset=${rect.index + 1}\n aria-label=${node.item.label}\n part=\"rect\"\n style=${sizeStyle}\n @click=${(e: MouseEvent) => this.#handleItemClick(rect, this.#rects().findIndex(r => r.node.item.key === node.item.key), e)}\n @dblclick=${() => this.#handleItemDblClick(rect)}\n @pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}\n >\n <span class=\"icicle-label ${hideLabel ? `hide-label` : ``} ${rotated ? `label-vertical` : ``}\" part=\"label\">${node.item.label}</span>\n </div>\n `;\n }\n\n protected override render() {\n const rects = this.#rects();\n const bands = new Map<number, IcicleRect[]>();\n for (const rect of rects) {\n const band = bands.get(rect.relativeDepth) ?? [];\n band.push(rect);\n bands.set(rect.relativeDepth, band);\n }\n const vertical = this.orientation === `vertical`;\n return html`\n <div\n class=\"icicle ${vertical ? `vertical` : `horizontal`}\"\n role=\"tree\"\n tabindex=\"0\"\n data-input-mode=${this.tickled.inputMode}\n @keydown=${(e: KeyboardEvent) => this.#handleKeyDown(e)}\n @pointerleave=${() => this.tickled.clearTickled()}\n >\n ${this.#renderBreadcrumb()}\n ${rects.length === 0\n ? html`<div class=\"empty-state\">No data</div>`\n : [...bands.entries()].map(([depth, band]) => html`\n <div\n class=\"band\"\n role=\"presentation\"\n data-depth=${depth}\n >\n ${repeat(band, r => r.node.item.key, r => this.#renderRect(r))}\n </div>\n `)}\n </div>\n <div id=\"icicle-tooltip\" popover=\"manual\" part=\"tooltip\" class=\"icicle-tooltip\"></div>\n ${this.search.renderField()}\n `;\n }\n\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n listSearchStyles,\n css`\n :host {\n --icicletree-band-height: 44px;\n --icicletree-band-gap: 2px;\n --icicletree-rect-gap: 2px;\n --icicletree-rect-bg: var(--surface-4);\n --icicletree-rect-text: var(--surface-4-text);\n --icicletree-font-size: var(--text-s);\n\n display: block;\n overflow: auto;\n }\n\n .icicle {\n display: flex;\n gap: var(--icicletree-band-gap);\n outline: none;\n }\n\n .icicle.horizontal {\n flex-direction: column;\n }\n\n .icicle.vertical {\n flex-direction: row;\n min-height: 200px;\n }\n\n .breadcrumb {\n display: flex;\n align-items: center;\n padding: var(--space-xs) var(--space-s);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n font-size: var(--text-s);\n flex-shrink: 0;\n }\n\n .breadcrumb ixfx-crumb-navigation {\n flex: 1;\n min-width: 0;\n }\n\n .band {\n position: relative;\n }\n\n .icicle.horizontal .band {\n height: var(--icicletree-band-height);\n }\n\n .icicle.vertical .band {\n flex: 1 1 0;\n min-width: 0;\n height: 100%;\n }\n\n .rect {\n box-sizing: border-box;\n position: absolute;\n overflow: hidden;\n display: flex;\n align-items: center;\n padding: 0 var(--space-s);\n background: var(--icicletree-rect-bg);\n color: var(--icicletree-rect-text);\n font-size: var(--icicletree-font-size);\n cursor: pointer;\n transition:\n width var(--transition),\n height var(--transition),\n left var(--transition),\n top var(--transition),\n opacity var(--transition),\n background-color var(--transition);\n }\n\n .icicle.horizontal .rect {\n top: 0;\n height: 100%;\n }\n\n /*\n * A rotated label needs its full allotted width to be usable — the\n * default left/right padding (--space-s, ~4px a side) can consume\n * most or all of a rect sized down to minVerticalLabelWidth, leaving\n * the rotated text clipped to invisible. #labelMode's width estimate\n * assumes the whole rect width is usable, so drop the padding here to\n * match that assumption instead of also budgeting for it in the\n * threshold (which would make already-narrow rects need even more).\n */\n .icicle.horizontal .rect.rotated {\n padding: 0;\n }\n\n .icicle.vertical .rect {\n left: 0;\n width: 100%;\n padding: var(--space-s) 0;\n justify-content: center;\n writing-mode: horizontal-tb;\n }\n\n .rect.filtered {\n opacity: 0.3;\n filter: saturate(0.4);\n }\n\n .rect.empty {\n padding: 0;\n border: none;\n }\n\n .rect.loading {\n cursor: progress;\n opacity: 0.6;\n }\n\n .icicle-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n min-width: 0;\n }\n\n .icicle-label.hide-label {\n visibility: hidden;\n }\n\n .icicle-label.label-vertical {\n writing-mode: vertical-rl;\n text-orientation: sideways;\n flex: none;\n width: 100%;\n height: 100%;\n padding: var(--space-2xs, 2px) 0;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n /*\n * Instant tooltip for rects whose label is rotated or hidden — anchored\n * via CSS anchor positioning (anchor-name set on the tickled rect in\n * #renderRect) rather than a JS-computed position, and shown/hidden via\n * the Popover API rather than the browser's own (slow, un-stylable)\n * title tooltip.\n */\n .icicle-tooltip {\n position: fixed;\n position-anchor: --icicle-rect-anchor;\n position-area: bottom center;\n position-try-fallbacks: top center;\n margin: var(--space-xs, 4px) 0 0;\n padding: var(--space-2xs, 2px) var(--space-xs, 6px);\n background: var(--surface-5);\n color: var(--surface-5-text);\n border: var(--border-subtle);\n border-radius: var(--radius-s, 4px);\n font-size: var(--text-s);\n white-space: nowrap;\n pointer-events: none;\n inset: auto;\n }\n\n .icicle-tooltip:popover-open {\n display: block;\n }\n\n .empty-state {\n padding: var(--space-l);\n color: var(--surface-muted-text);\n font-size: var(--text-s);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-icicletree-list': IcicleTreeListElement;\n }\n}\n\nexport interface IcicleTreeListElement {\n addEventListener: (<K extends keyof IcicleTreeListElementEventMap>(\n type: K,\n listener: (this: IcicleTreeListElement, event: IcicleTreeListElementEventMap[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 IcicleTreeListElementEventMap>(\n type: K,\n listener: (this: IcicleTreeListElement, event: IcicleTreeListElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","export type SortDirection = `asc` | `desc`;\n\nexport type MulticolItem = {\n readonly key: string;\n readonly label: string;\n readonly count?: number;\n readonly data?: unknown;\n};\n\nexport type MulticolCategoryDefaults = {\n grouped?: boolean;\n groupBy?: (item: MulticolItem) => string;\n allLabel?: string;\n sort?: SortDirection;\n};\n\nexport type MulticolCategory = {\n readonly key: string;\n readonly label: string;\n readonly children?: readonly MulticolCategory[];\n readonly defaults?: MulticolCategoryDefaults;\n};\n\nexport type MulticolColumnState = {\n readonly id: string;\n readonly categoryKey: string;\n readonly sort: SortDirection;\n readonly grouped: boolean;\n readonly width?: number;\n};\n\nexport type MulticolColumnsChangeReason\n = `add` | `remove` | `reorder` | `category` | `sort` | `grouping` | `resize`;\n\nexport type MulticolQuery = {\n readonly columnId: string;\n readonly categoryKey: string;\n readonly otherSelections: ReadonlyMap<string, readonly string[]>;\n};\n\nexport type MulticolColumnSelection = {\n readonly columnId: string;\n readonly categoryKey: string;\n readonly values: readonly string[];\n};\n\nexport type MulticolSelectDetail = {\n readonly columnId: string;\n readonly columns: readonly MulticolColumnSelection[];\n};\n\nexport const ALL_KEY = `__all__`;\n","import type { IDataProvider } from '../common/data-provider.js';\nimport type { GroupedItemListerElement } from '../grouped-item-lister/grouped-item-lister.js';\nimport type { IGroupedSubComponent } from '../grouped-item-lister/types.js';\nimport type { ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type { VerticalListElement } from '../vertical-list/vertical-list.js';\nimport type { MulticolCategory, MulticolCategoryDefaults, MulticolColumnState, MulticolItem, MulticolQuery, SortDirection } from './types.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport { createVerticalListAdapter } from '../grouped-item-lister/vertical-list-adapter.js';\nimport { ALL_KEY } from './types.js';\nimport '../grouped-item-lister/grouped-item-lister.js';\n\nexport interface MulticolColumnControllerOptions {\n id: string;\n category: MulticolCategory;\n categoryDefaults: MulticolCategoryDefaults | undefined;\n selectionMode: ListSelectionMode;\n dataProvider: IDataProvider<MulticolQuery, MulticolItem> | undefined;\n onSelectionChange: (columnId: string, values: readonly string[]) => void;\n onRequestData: (columnId: string, query: MulticolQuery, signal: AbortSignal) => void;\n}\n\n/** Sorts by label, honouring direction. 'All' lives outside the list, so it is not special-cased. */\nexport function sortItems(items: readonly MulticolItem[], direction: SortDirection): MulticolItem[] {\n const dir = direction === `desc` ? -1 : 1;\n return [...items].sort((a, b) => dir * a.label.localeCompare(b.label, undefined, { sensitivity: `base`, numeric: true }));\n}\n\n/**\n * Nearest-gap math for header drag-reorder (per data-grid's `_beginHeaderDrag`).\n *\n * `offsets` is a prefix-sum of column widths (length = count + 1). `x` is the\n * pointer position in content space (already adjusted for scroll). Returns the\n * final insertion index once the source column is removed (`insert`), plus the\n * un-normalised gap offset for the drop caret (`caretOffset`).\n */\nexport function computeDropGap(offsets: readonly number[], x: number, count: number, from: number): { insert: number; caretOffset: number } {\n if (count === 0)\n return { insert: 0, caretOffset: 0 };\n\n let bestDist = Number.MAX_SAFE_INTEGER;\n let caretGap = from;\n\n for (let i = 0; i < count; i++) {\n if (i === from)\n continue;\n\n const left = offsets[i];\n const right = offsets[i + 1] ?? offsets[offsets.length - 1];\n const mid = (left + right) / 2;\n\n const gapPos = x < mid ? left : right;\n const dist = Math.abs(x - gapPos);\n\n if (dist < bestDist) {\n bestDist = dist;\n caretGap = x < mid ? i : i + 1;\n }\n }\n\n const insert = caretGap > from ? caretGap - 1 : caretGap;\n return {\n insert: Math.max(0, Math.min(count - 1, insert)),\n caretOffset: offsets[caretGap] ?? offsets[offsets.length - 1],\n };\n}\n\nexport class MulticolColumnController {\n readonly id: string;\n\n #category: MulticolCategory;\n #categoryDefaults: MulticolCategoryDefaults | undefined;\n #selectionMode: ListSelectionMode;\n #dataProvider: IDataProvider<MulticolQuery, MulticolItem> | undefined;\n #onSelectionChange: (columnId: string, values: readonly string[]) => void;\n #onRequestData: (columnId: string, query: MulticolQuery, signal: AbortSignal) => void;\n\n #abortController: AbortController | undefined = undefined;\n #host: HTMLElement | undefined;\n #allRow: HTMLDivElement | undefined;\n #listerEl: GroupedItemListerElement<MulticolItem> | undefined;\n #selectedValues: readonly string[] = [];\n #allSelected = true;\n #lastItems: readonly MulticolItem[] = [];\n #syncingSelection = false;\n #state: MulticolColumnState;\n\n constructor(options: MulticolColumnControllerOptions) {\n this.id = options.id;\n this.#category = options.category;\n this.#categoryDefaults = options.categoryDefaults;\n this.#selectionMode = options.selectionMode;\n this.#dataProvider = options.dataProvider;\n this.#onSelectionChange = options.onSelectionChange;\n this.#onRequestData = options.onRequestData;\n this.#state = {\n id: options.id,\n categoryKey: options.category.key,\n sort: options.categoryDefaults?.sort ?? `asc`,\n grouped: options.categoryDefaults?.grouped ?? false,\n width: 220,\n };\n }\n\n get state(): MulticolColumnState {\n return this.getState();\n }\n\n /** Always derived from the live category so a swap is visible everywhere. */\n get categoryKey(): string {\n return this.#category.key;\n }\n\n getState(): MulticolColumnState {\n return { ...this.#state };\n }\n\n updateState(partial: Partial<MulticolColumnState>): void {\n // Drop non-finite widths (e.g. NaN from a bad measurement/restore) —\n // otherwise they poison offset prefix-sums and wedge the update guard\n // (`NaN === NaN` is false, so offsets would never settle).\n let sanitised = partial;\n if (partial.width !== undefined && !Number.isFinite(partial.width)) {\n const { width: _dropped, ...rest } = partial;\n sanitised = rest;\n }\n const sortChanged = sanitised.sort !== undefined && sanitised.sort !== this.#state.sort;\n const groupedChanged = sanitised.grouped !== undefined && sanitised.grouped !== this.#state.grouped;\n this.#state = { ...this.#state, ...sanitised };\n if (sortChanged)\n this.#repush();\n if (groupedChanged)\n this.#syncGrouping();\n }\n\n setWidth(width: number): void {\n // Ignore non-finite measurements (NaN/Infinity from detached or hidden\n // subtrees where style reads come back empty) — storing NaN would poison\n // offset prefix-sums and wedge the host's update guard into a loop.\n if (!Number.isFinite(width))\n return;\n this.#state = { ...this.#state, width: Math.max(80, Math.min(480, Math.round(width))) };\n }\n\n setSort(sort: SortDirection): void {\n if (sort === this.#state.sort)\n return;\n this.#state = { ...this.#state, sort };\n this.#repush();\n }\n\n setGrouped(grouped: boolean): void {\n if (grouped === this.#state.grouped)\n return;\n this.#state = { ...this.#state, grouped };\n this.#syncGrouping();\n }\n\n setSelectionMode(mode: ListSelectionMode): void {\n if (mode === this.#selectionMode)\n return;\n this.#selectionMode = mode;\n for (const sub of this.#subComponents()) {\n sub.selectionMode = mode;\n }\n }\n\n setCategory(category: MulticolCategory): void {\n this.#category = category;\n this.#categoryDefaults = category.defaults;\n this.#state = {\n ...this.#state,\n categoryKey: category.key,\n sort: category.defaults?.sort ?? `asc`,\n grouped: category.defaults?.grouped ?? false,\n };\n this.clearSelection();\n this.#syncGrouping();\n }\n\n get listerHost(): HTMLElement | undefined {\n return this.#host;\n }\n\n get isMounted(): boolean {\n return this.#host !== undefined;\n }\n\n setDataProvider(provider: IDataProvider<MulticolQuery, MulticolItem> | undefined): void {\n this.#dataProvider = provider;\n }\n\n mount(host: HTMLElement): void {\n if (this.#host)\n return;\n this.#host = host;\n\n const allRow = document.createElement(`div`);\n allRow.className = `all-row`;\n allRow.dataset.key = ALL_KEY;\n allRow.setAttribute(`role`, `button`);\n allRow.setAttribute(`tabindex`, `0`);\n const allLabel = document.createElement(`span`);\n allLabel.className = `all-label`;\n allRow.appendChild(allLabel);\n const applyAll = (): void => {\n if (this.#allSelected)\n return;\n this.#setAllSelection();\n };\n allRow.addEventListener(`click`, applyAll);\n allRow.addEventListener(`keydown`, (e: KeyboardEvent) => {\n if (e.key === `Enter` || e.key === ` `) {\n e.preventDefault();\n applyAll();\n }\n });\n this.#allRow = allRow;\n\n const lister = document.createElement(`ixfx-grouped-item-lister`) as GroupedItemListerElement<MulticolItem>;\n lister.crossGroupSelection = true;\n lister.factory = () => createVerticalListAdapter<MulticolItem>(renderItem, {\n selectionMode: this.#selectionMode,\n interactionMode: `standard`,\n });\n lister.addEventListener(`select`, this.#handleSelect as EventListener);\n this.#listerEl = lister;\n\n this.#syncGrouping();\n this.#syncAllRow();\n host.append(allRow, lister);\n\n if (this.#lastItems.length > 0) {\n this.#pushItems();\n this.#restoreAfterSync();\n }\n }\n\n unmount(): void {\n this.#abortPending();\n this.#allRow?.remove();\n this.#listerEl?.remove();\n this.#allRow = undefined;\n this.#listerEl = undefined;\n this.#host = undefined;\n }\n\n // ---- Data ----\n\n requestData(query: MulticolQuery): void {\n if (!this.#dataProvider)\n return;\n\n this.#abortPending();\n\n const controller = new AbortController();\n this.#abortController = controller;\n const { signal } = controller;\n\n this.#onRequestData(this.id, query, signal);\n\n Promise.resolve().then(async () => {\n const result = this.#dataProvider!(query, signal);\n const items = await collectDataResult(result, signal);\n if (signal.aborted)\n return;\n this.#applyItems(items);\n }).catch(() => {\n // Aborted or provider error — leave current items as-is\n });\n }\n\n #applyItems(items: readonly MulticolItem[]): void {\n this.#lastItems = items;\n\n // Drop selections that no longer exist in the data\n const valid = this.#selectedValues.filter(v => items.some(i => i.key === v));\n const changed = valid.length !== this.#selectedValues.length;\n this.#selectedValues = valid;\n if (valid.length === 0)\n this.#allSelected = true;\n\n if (!this.#listerEl) {\n if (changed)\n this.#onSelectionChange(this.id, valid);\n return;\n }\n\n this.#pushItems();\n this.#restoreAfterSync();\n\n if (changed)\n this.#onSelectionChange(this.id, valid);\n }\n\n #pushItems(): void {\n if (!this.#listerEl)\n return;\n const sorted = sortItems(this.#lastItems, this.#state.sort);\n this.#listerEl.provider = () => sorted;\n }\n\n #repush(): void {\n if (!this.#listerEl || this.#lastItems.length === 0)\n return;\n this.#pushItems();\n this.#restoreAfterSync();\n }\n\n /** Grouping config from category defaults; grouping without groupBy is a no-op. */\n #syncGrouping(): void {\n if (!this.#listerEl)\n return;\n const groupBy = this.#categoryDefaults?.groupBy;\n this.#listerEl.groupBy = groupBy;\n this.#listerEl.grouped = this.#state.grouped && groupBy !== undefined;\n if (this.#lastItems.length > 0) {\n this.#restoreAfterSync();\n }\n }\n\n // ---- Selection ----\n\n #subComponents(): Iterable<HTMLElement & IGroupedSubComponent<MulticolItem>> {\n if (!this.#listerEl)\n return [];\n return this.#listerEl.querySelectorAll(`:scope > .ungrouped-host > *, :scope > ixfx-panel > *`);\n }\n\n #handleSelect = (): void => {\n if (this.#syncingSelection)\n return;\n\n const values = [...this.#listerEl?.selectedItems ?? []].map(i => i.key).filter(k => k !== ALL_KEY);\n\n const sameSize = values.length === this.#selectedValues.length;\n const sameValues = sameSize && values.every(v => this.#selectedValues.includes(v));\n if (sameValues) {\n this.#syncAllRow();\n return;\n }\n\n // Selecting a value implicitly deselects All; emptying the selection re-selects All\n this.#selectedValues = values;\n this.#allSelected = values.length === 0;\n this.#syncAllRow();\n this.#onSelectionChange(this.id, values);\n };\n\n #setAllSelection(): void {\n const previous = this.#selectedValues;\n this.#syncingSelection = true;\n try {\n this.#selectedValues = [];\n this.#allSelected = true;\n for (const sub of this.#subComponents()) {\n sub.clearSelection();\n }\n } finally {\n this.#syncingSelection = false;\n }\n this.#syncAllRow();\n\n // Going back to All is a selection change like any other — hosts and the\n // cascade must hear about it\n if (previous.length > 0) {\n this.#onSelectionChange(this.id, []);\n }\n }\n\n clearSelection(): void {\n this.#setAllSelection();\n }\n\n get selectedValues(): readonly string[] {\n return this.#selectedValues;\n }\n\n #restoreAfterSync(): void {\n if (!this.#listerEl)\n return;\n void this.#listerEl.updateComplete.then(() => {\n if (!this.#listerEl || !this.#host)\n return;\n this.#syncingSelection = true;\n try {\n const wanted = this.#selectedValues;\n for (const list of this.#listerEl.querySelectorAll<VerticalListElement>(`ixfx-vertical-list`)) {\n list.selectKeys(wanted);\n }\n const selected = [...this.#listerEl.selectedItems].map(i => i.key).filter(k => k !== ALL_KEY);\n this.#selectedValues = selected;\n this.#allSelected = selected.length === 0;\n } finally {\n this.#syncingSelection = false;\n }\n this.#syncAllRow();\n });\n }\n\n #syncAllRow(): void {\n if (!this.#allRow)\n return;\n const label = this.#categoryDefaults?.allLabel ?? `All`;\n const labelEl = this.#allRow.querySelector(`.all-label`);\n if (labelEl)\n labelEl.textContent = label;\n this.#allRow.toggleAttribute(`data-selected`, this.#allSelected);\n }\n\n // ---- Internal ----\n\n #abortPending(): void {\n if (this.#abortController) {\n this.#abortController.abort();\n this.#abortController = undefined;\n }\n }\n}\n\nfunction renderItem(item: MulticolItem): Element {\n const li = document.createElement(`li`);\n li.dataset.key = item.key;\n\n const labelSpan = document.createElement(`span`);\n labelSpan.className = `item-label`;\n labelSpan.textContent = item.label;\n li.appendChild(labelSpan);\n\n if (item.count !== undefined) {\n const countSpan = document.createElement(`span`);\n countSpan.className = `count`;\n countSpan.textContent = String(item.count);\n li.appendChild(countSpan);\n }\n\n return li;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { IDataProvider } from '../common/data-provider.js';\nimport type { TreeNode } from '../common/types.js';\nimport type { ListSelectionMode } from '../interaction/list-selection-types.js';\nimport type { MenuTrigger } from '../menu/menu-trigger.js';\nimport type { DragGhost } from '../util/drag-ghost.js';\nimport type { MulticolCategory, MulticolColumnsChangeReason, MulticolColumnState, MulticolItem, MulticolQuery, MulticolSelectDetail } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { registerIcon } from '../icons/registry.js';\nimport { menuFromTreeToElements } from '../menu/menu-from-tree.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\nimport { computeDropGap, MulticolColumnController } from './column.js';\nimport '../icons/icon.js';\nimport '../menu/menu-trigger.js';\nimport '../menu/menu-container.js';\nimport '../menu/menu-item.js';\nimport '../menu/menu-sub-trigger.js';\nimport '../menu/menu-separator.js';\n\nexport type {\n MulticolCategory,\n MulticolColumnsChangeReason,\n MulticolColumnState,\n MulticolItem,\n MulticolQuery,\n MulticolSelectDetail,\n SortDirection,\n} from './types.js';\n\nexport type MulticolSelectEvent = CustomEvent<MulticolSelectDetail>;\nexport type MulticolColumnsChangeDetail = {\n readonly columns: readonly MulticolColumnState[];\n readonly reason: MulticolColumnsChangeReason;\n};\nexport type MulticolColumnsChangeEvent = CustomEvent<MulticolColumnsChangeDetail>;\n\nexport interface MulticolListElementEventMap {\n 'multicol-select': MulticolSelectEvent;\n 'multicol-columns-change': MulticolColumnsChangeEvent;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-multicol-list': MulticolListElement;\n }\n}\n\nexport interface MulticolListElement {\n addEventListener<K extends keyof MulticolListElementEventMap>(\n type: K,\n listener: (this: MulticolListElement, event: MulticolListElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions\n ): void;\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions\n ): void;\n}\n\n// Lucide 'menu' — registered on load so the burger button always renders\nregisterIcon(`menu`, `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 12h16\"/><path d=\"M4 18h16\"/><path d=\"M4 6h16\"/></svg>`);\n\nconst DEFAULT_COLUMN_WIDTH = 220;\nconst MIN_COLUMN_WIDTH = 80;\nconst MAX_COLUMN_WIDTH = 480;\nconst DRAG_THRESHOLD = 5;\n\n@customElement(`ixfx-multicol-list`)\nexport class MulticolListElement extends LitElement {\n static override styles = [\n themeFallbacks,\n handleStyles,\n css`\n :host {\n --multicol-list-bg: var(--surface-3);\n --multicol-list-header-bg: var(--surface-2);\n --multicol-list-header-text: var(--surface-3-text);\n --multicol-list-border: var(--border);\n --multicol-list-min-column-width: ${MIN_COLUMN_WIDTH}px;\n --multicol-list-max-column-width: ${MAX_COLUMN_WIDTH}px;\n --multicol-list-header-font-size: unset;\n\n display: block;\n overflow: hidden;\n background: var(--multicol-list-bg);\n color: var(--surface-3-text);\n font-family: var(--font-family);\n }\n #container {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n overflow: hidden;\n position: relative;\n height: 100%;\n }\n .column {\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n border-right: var(--multicol-list-border);\n min-width: var(--multicol-list-min-column-width);\n max-width: var(--multicol-list-max-column-width);\n background: var(--surface-3);\n }\n .column-header {\n display: flex;\n align-items: center;\n gap: var(--space-xs);\n height: 32px;\n background: var(--multicol-list-header-bg);\n color: var(--multicol-list-header-text);\n border-bottom: var(--border);\n position: relative;\n user-select: none;\n min-width: var(--multicol-list-min-column-width);\n box-sizing: border-box;\n }\n .column-header[data-dragging] {\n opacity: 0.4;\n }\n .reorder-handle {\n cursor: grab;\n opacity: 0;\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n padding-left: var(--space-xs);\n touch-action: none;\n transition: opacity var(--transition, 0.15s ease-out);\n }\n .column-header:hover .reorder-handle, .column-header:focus-within .reorder-handle, .column-header[data-dragging] .reorder-handle { opacity: var(--ixfx-handle-opacity, 0.5); }\n .reorder-handle:active {\n cursor: grabbing;\n }\n .reorder-handle .ixfx-handle {\n --ixfx-handle-length: 14px;\n --ixfx-handle-thickness: var(--multicol-list-reorder-handle-width, 10px);\n --ixfx-handle-dot-size: 3px;\n }\n .column-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 0 var(--space-s);\n font-size: var(--multicol-list-header-font-size);\n font-weight: 600;\n background: transparent;\n border: none;\n color: inherit;\n cursor: pointer;\n text-align: left;\n min-width: 0;\n }\n .column-label:hover {\n text-decoration: underline;\n }\n .burger-btn {\n flex-shrink: 0;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n cursor: pointer;\n color: var(--surface-3-text);\n opacity: 0;\n transition: opacity var(--transition);\n border-radius: var(--radius-s);\n }\n .column:hover .burger-btn,\n .column-header:focus-within .burger-btn {\n opacity: 1;\n }\n .burger-btn:hover {\n background: var(--surface-4);\n }\n .resize-handle {\n position: absolute;\n right: -4px;\n top: 0;\n bottom: 0;\n width: 8px;\n cursor: col-resize;\n z-index: 1;\n display: flex;\n align-items: stretch;\n justify-content: center;\n touch-action: none;\n }\n .resize-handle::before {\n content: '';\n width: 2px;\n margin: 2px 0;\n border-radius: 1px;\n background: transparent;\n transition: background-color var(--transition);\n }\n .resize-handle:hover::before,\n .resize-handle[data-active]::before {\n background: var(--accent);\n }\n .lister-host {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n .all-row {\n display: flex;\n align-items: center;\n padding: var(--space-xs) var(--space-s);\n cursor: pointer;\n user-select: none;\n min-height: 28px;\n box-sizing: border-box;\n outline: 1px solid transparent;\n background: var(--surface-3);\n }\n .all-row:hover,\n .all-row[data-selected] {\n background: var(--surface-5);\n }\n .all-row[data-selected] {\n outline-color: var(--accent);\n font-weight: 600;\n }\n ixfx-grouped-item-lister {\n display: block;\n }\n .drop-caret {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--accent);\n border-radius: 1px;\n pointer-events: none;\n z-index: 10;\n }\n .item-label {\n flex: 1;\n }\n .count {\n opacity: 0.6;\n margin-left: var(--space-s);\n font-size: var(--text-s);\n }\n `,\n ];\n\n @property({ attribute: false }) categories: readonly MulticolCategory[] = [];\n @property({ attribute: false }) dataProvider?: IDataProvider<MulticolQuery, MulticolItem>;\n @property({ type: String, attribute: `selection-mode` }) selectionMode: ListSelectionMode = `multiple`;\n @property({ type: Number }) minColumns = 1;\n @property({ type: Number }) maxColumns = 5;\n\n @state() private _columns: MulticolColumnController[] = [];\n @state() private _colOffsets: number[] = [0];\n @state() private _resizingColumnId: string | undefined = undefined;\n @state() private _draggingColumnId: string | undefined = undefined;\n @state() private _dropCaretX: number | undefined = undefined;\n\n @query(`#container`) private _containerEl: HTMLElement | undefined;\n\n private _idCounter = 0;\n private _autoSeeded = false;\n private _drag = {\n pointerId: -1,\n from: -1,\n startX: 0,\n startY: 0,\n active: false,\n ghost: null as DragGhost | null,\n insert: -1,\n };\n\n get columns(): readonly MulticolColumnState[] {\n return this._columns.map(c => c.getState());\n }\n\n setColumns(states: readonly MulticolColumnState[]): void {\n const existingMap = new Map(this._columns.map(c => [c.id, c]));\n const newColumns: MulticolColumnController[] = [];\n\n for (const colState of states) {\n const existing = existingMap.get(colState.id);\n if (existing) {\n // A restored state may point the column at a different category — apply\n // it through setCategory so defaults and label stay in sync\n if (existing.categoryKey !== colState.categoryKey) {\n const newCategory = this.categories.find(c => c.key === colState.categoryKey);\n if (newCategory)\n existing.setCategory(newCategory);\n }\n existing.updateState(colState);\n newColumns.push(existing);\n existingMap.delete(colState.id);\n continue;\n }\n\n // Restore a column that has no live controller (e.g. after a page reload)\n const category = this.categories.find(c => c.key === colState.categoryKey);\n if (!category)\n continue;\n const controller = this.#createController(colState.id, category);\n controller.updateState(colState);\n newColumns.push(controller);\n }\n\n for (const col of existingMap.values()) {\n col.unmount();\n }\n\n this._columns = newColumns;\n this._updateColOffsets();\n this._emitColumnsChange(`add`);\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n addColumn(categoryKey: string, position?: number): void {\n if (this.maxColumns > 0 && this._columns.length >= this.maxColumns)\n return;\n\n const category = this.categories.find(c => c.key === categoryKey);\n if (!category)\n return;\n\n const id = `col-${++this._idCounter}`;\n const controller = this.#createController(id, category);\n\n if (position !== undefined && position >= 0 && position < this._columns.length) {\n this._columns.splice(position, 0, controller);\n } else {\n this._columns.push(controller);\n }\n\n this._updateColOffsets();\n this._emitColumnsChange(`add`);\n\n // New column starts at All, but the host decorates counts from\n // otherSelections — re-query everything so counts stay consistent\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n removeColumn(columnId: string): void {\n if (this._columns.length <= this.minColumns)\n return;\n\n const idx = this._columns.findIndex(c => c.id === columnId);\n if (idx < 0)\n return;\n\n const col = this._columns[idx];\n col.unmount();\n this._columns.splice(idx, 1);\n this._updateColOffsets();\n this._emitColumnsChange(`remove`);\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n getSelection(): ReadonlyArray<{ columnId: string; categoryKey: string; values: readonly string[] }> {\n return this._columns.map(c => ({\n columnId: c.id,\n categoryKey: c.categoryKey,\n values: c.selectedValues,\n }));\n }\n\n clearSelection(): void {\n // Each column that actually changes fires `multicol-select` and cascades\n // a re-query through the standard selection-change path\n for (const col of this._columns) {\n col.clearSelection();\n }\n this.requestUpdate();\n }\n\n protected override render() {\n return html`\n <div id=\"container\">\n ${repeat(this._columns, col => col.id, (col, idx) => this._renderColumn(col, idx))}\n ${this._dropCaretX !== undefined\n ? html`<div class=\"drop-caret\" style=\"left: ${this._dropCaretX}px\"></div>`\n : nothing}\n </div>\n `;\n }\n\n protected override updated(changedProperties: Map<string, unknown>): void {\n // Auto-seed: the component is meant to always show at least one column.\n // Skipped when the host has restored (or otherwise installed) a layout.\n if (!this._autoSeeded && this._columns.length === 0 && this.categories.length > 0) {\n this._autoSeeded = true;\n this.addColumn(this.categories[0].key);\n }\n\n if (changedProperties.has(`selectionMode`)) {\n for (const col of this._columns) {\n col.setSelectionMode(this.selectionMode);\n }\n }\n if (changedProperties.has(`dataProvider`)) {\n for (const col of this._columns) {\n col.setDataProvider(this.dataProvider);\n }\n }\n\n for (const col of this._columns) {\n if (!col.isMounted) {\n const hostEl = this.shadowRoot?.querySelector(`[data-col-id=\"${col.id}\"] .lister-host`);\n if (hostEl) {\n col.mount(hostEl as HTMLElement);\n }\n }\n }\n\n if (changedProperties.has(`categories`)) {\n this._syncColumnsWithCategories();\n }\n if (changedProperties.has(`categories`) || changedProperties.has(`dataProvider`)) {\n this._requeryAllColumns();\n }\n\n this._updateColOffsets();\n }\n\n private _renderColumn(col: MulticolColumnController, idx: number): unknown {\n const state = col.getState();\n const rawWidth = state.width ?? DEFAULT_COLUMN_WIDTH;\n const width = Number.isFinite(rawWidth) ? rawWidth : DEFAULT_COLUMN_WIDTH;\n\n return html`\n <div\n class=\"column\"\n data-col-id=\"${col.id}\"\n style=\"width: ${width}px\"\n >\n <div\n class=\"column-header\"\n ?data-dragging=${this._draggingColumnId === col.id}\n data-col-idx=${idx}\n >\n <span\n class=\"reorder-handle\"\n data-tooltip=\"Drag to reorder\"\n @pointerdown=${(e: PointerEvent) => this._onHeaderPointerDown(e, col, idx)}\n ><span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"vertical\" part=\"reorder-handle\"></span></span>\n <button\n class=\"column-label\"\n data-tooltip=\"Change category\"\n @click=${(e: Event) => {\n e.stopPropagation(); this._openCategoryPicker(col, e.currentTarget as HTMLElement);\n }}\n >${this._getCategoryLabel(col.categoryKey)}</button>\n <button\n class=\"burger-btn\"\n data-tooltip=\"Column options\"\n @click=${(e: Event) => {\n e.stopPropagation(); this._openBurgerMenu(col, e.currentTarget as HTMLElement);\n }}\n >\n <ixfx-icon name=\"menu\" size=\"14\"></ixfx-icon>\n </button>\n <span\n class=\"resize-handle\"\n ?data-active=${this._resizingColumnId === col.id}\n @pointerdown=${(e: PointerEvent) => this._onResizePointerDown(e, col)}\n @click=${(e: Event) => e.stopPropagation()}\n ></span>\n </div>\n <div class=\"lister-host\"></div>\n </div>\n `;\n }\n\n private _getCategoryLabel(key: string): string {\n const cat = this.categories.find(c => c.key === key);\n return cat?.label ?? key;\n }\n\n #createController(id: string, category: MulticolCategory): MulticolColumnController {\n return new MulticolColumnController({\n id,\n category,\n categoryDefaults: category.defaults,\n selectionMode: this.selectionMode,\n dataProvider: this.dataProvider,\n onSelectionChange: this._onColumnSelectionChange.bind(this),\n onRequestData: this._onColumnRequestData.bind(this),\n });\n }\n\n // ---------------------------------------------------------------------\n // Header drag-reorder (pattern per data-grid `_beginHeaderDrag`)\n // ---------------------------------------------------------------------\n\n private _onHeaderPointerDown(e: PointerEvent, col: MulticolColumnController, idx: number): void {\n e.stopPropagation();\n\n this._drag = {\n pointerId: e.pointerId,\n from: idx,\n startX: e.clientX,\n startY: e.clientY,\n active: false,\n ghost: null,\n insert: idx,\n };\n\n const onMove = (ev: PointerEvent): void => {\n if (ev.pointerId !== this._drag.pointerId)\n return;\n\n const dx = ev.clientX - this._drag.startX;\n const dy = ev.clientY - this._drag.startY;\n\n if (!this._drag.active) {\n if (Math.hypot(dx, dy) < DRAG_THRESHOLD)\n return;\n\n this._drag.active = true;\n this._draggingColumnId = col.id;\n\n const headerEl = this.shadowRoot?.querySelector(`[data-col-id=\"${col.id}\"] .column-header`) as HTMLElement | null;\n const content = document.createElement(`span`);\n content.textContent = this._getCategoryLabel(col.categoryKey);\n\n try {\n if (headerEl) {\n this._drag.ghost = createDragGhost({ anchor: headerEl, content });\n this._drag.ghost.move(ev.clientX, ev.clientY);\n }\n } catch { /* ignore */ }\n\n // Capture retargets the eventual click away from the header buttons,\n // so a real drag never opens a menu\n try {\n this._containerEl?.setPointerCapture(ev.pointerId);\n } catch { /* ignore */ }\n }\n\n this._drag.ghost?.move(ev.clientX, ev.clientY);\n\n const containerEl = this._containerEl;\n if (!containerEl)\n return;\n const rect = containerEl.getBoundingClientRect();\n const x = ev.clientX - rect.left + containerEl.scrollLeft;\n const gap = computeDropGap(this._colOffsets, x, this._columns.length, this._drag.from);\n this._drag.insert = gap.insert;\n this._dropCaretX = gap.caretOffset;\n this.requestUpdate();\n };\n\n const finish = (ev: PointerEvent): void => {\n if (ev.pointerId !== this._drag.pointerId)\n return;\n\n const wasActive = this._drag.active;\n const from = this._drag.from;\n const insert = this._drag.insert;\n\n this._drag.ghost?.destroy();\n this._drag.ghost = null;\n this._draggingColumnId = undefined;\n this._dropCaretX = undefined;\n\n try {\n this._containerEl?.releasePointerCapture(ev.pointerId);\n } catch { /* ignore */ }\n\n window.removeEventListener(`pointermove`, onMove);\n window.removeEventListener(`pointerup`, finish);\n window.removeEventListener(`pointercancel`, finish);\n\n if (wasActive && insert !== from) {\n const [moved] = this._columns.splice(from, 1);\n this._columns.splice(insert, 0, moved);\n this._updateColOffsets();\n this._emitColumnsChange(`reorder`);\n this.requestUpdate();\n }\n };\n\n window.addEventListener(`pointermove`, onMove);\n window.addEventListener(`pointerup`, finish);\n window.addEventListener(`pointercancel`, finish);\n }\n\n // ---------------------------------------------------------------------\n // Resize (pattern per data-grid `_onResizePointerDown`)\n // ---------------------------------------------------------------------\n\n private _onResizePointerDown(e: PointerEvent, col: MulticolColumnController): void {\n e.preventDefault();\n e.stopPropagation();\n\n const startX = e.clientX;\n const rawStartW = col.getState().width ?? DEFAULT_COLUMN_WIDTH;\n const startW = Number.isFinite(rawStartW) ? rawStartW : DEFAULT_COLUMN_WIDTH;\n this._resizingColumnId = col.id;\n\n const applyWidth = (clientX: number): number => {\n const w = Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, startW + clientX - startX));\n col.setWidth(w);\n return w;\n };\n\n const onMove = (ev: PointerEvent): void => {\n if (ev.pointerId !== e.pointerId)\n return;\n applyWidth(ev.clientX);\n this._updateColOffsets();\n this.requestUpdate();\n };\n\n const finish = (ev: PointerEvent): void => {\n window.removeEventListener(`pointermove`, onMove);\n window.removeEventListener(`pointerup`, finish);\n window.removeEventListener(`pointercancel`, finish);\n\n // A cancelled pointer restores the starting width\n applyWidth(ev.type === `pointercancel` ? startX : ev.clientX);\n this._resizingColumnId = undefined;\n this._updateColOffsets();\n this._emitColumnsChange(`resize`);\n this.requestUpdate();\n };\n\n window.addEventListener(`pointermove`, onMove);\n window.addEventListener(`pointerup`, finish);\n window.addEventListener(`pointercancel`, finish);\n }\n\n // ---------------------------------------------------------------------\n // Menus\n // ---------------------------------------------------------------------\n\n /** Floats a dropdown menu trigger over `anchorEl` and opens it immediately. */\n #openMenuAt(anchorEl: HTMLElement, placement: `bottom-start` | `bottom-end`, buildMenu: (container: HTMLElement) => void): void {\n const rect = anchorEl.getBoundingClientRect();\n const trigger = document.createElement(`ixfx-menu-trigger`) as MenuTrigger;\n trigger.mode = `dropdown`;\n trigger.tabStop = false;\n trigger.placement = placement;\n trigger.style.position = `fixed`;\n trigger.style.left = `${rect.left}px`;\n trigger.style.top = `${rect.bottom}px`;\n\n const container = document.createElement(`ixfx-menu-container`);\n container.setAttribute(`slot`, `menu`);\n buildMenu(container);\n trigger.appendChild(container);\n\n trigger.addEventListener(`menu-trigger-close`, () => trigger.remove(), { once: true });\n document.body.appendChild(trigger);\n // `openMenu()` reads `.popup` via a @query, which only resolves once Lit has\n // completed the trigger's first render — calling it synchronously right\n // after appendChild silently no-ops because the popup element doesn't exist yet.\n void trigger.updateComplete.then(() => trigger.openMenu());\n }\n\n #categoryToNode(cat: MulticolCategory): TreeNode {\n return {\n item: { key: cat.key, label: cat.label },\n children: cat.children && cat.children.length > 0 ? cat.children.map(c => this.#categoryToNode(c)) : undefined,\n };\n }\n\n private _openCategoryPicker(col: MulticolColumnController, anchorEl: HTMLElement): void {\n this.#openMenuAt(anchorEl, `bottom-start`, (container) => {\n const items = menuFromTreeToElements(this.categories.map(c => this.#categoryToNode(c)), {\n onCommand: (detail) => {\n if (detail.command === undefined)\n return;\n this._changeColumnCategory(col, detail.command);\n },\n });\n for (const el of items) {\n container.appendChild(el);\n }\n for (const item of container.querySelectorAll(`ixfx-menu-item`)) {\n if (item.getAttribute(`command`) === col.categoryKey) {\n item.setAttribute(`disabled`, ``);\n }\n }\n });\n }\n\n #menuItem(label: string, command: string, onCommand?: () => void, iconName?: string): HTMLElement {\n const el = document.createElement(`ixfx-menu-item`);\n el.setAttribute(`command`, command);\n el.setAttribute(`label`, label);\n if (iconName)\n el.setAttribute(`icon-name`, iconName);\n if (onCommand) {\n el.addEventListener(`command`, () => onCommand());\n }\n return el;\n }\n\n private _openBurgerMenu(col: MulticolColumnController, anchorEl: HTMLElement): void {\n this.#openMenuAt(anchorEl, `bottom-end`, (container) => {\n const removeItem = this.#menuItem(`Remove this column`, `remove`, () => this.removeColumn(col.id));\n removeItem.toggleAttribute(`disabled`, this._columns.length <= this.minColumns);\n container.appendChild(removeItem);\n\n const separator = document.createElement(`ixfx-menu-separator`);\n container.appendChild(separator);\n\n const atMax = this.maxColumns > 0 && this._columns.length >= this.maxColumns;\n const usedCats = new Set(this._columns.map(c => c.categoryKey));\n const unused = this.categories.filter(c => !usedCats.has(c.key));\n const canAdd = !atMax && unused.length > 0;\n\n const addSub = document.createElement(`ixfx-menu-sub-trigger`);\n addSub.setAttribute(`label`, `Add column`);\n const addContainer = document.createElement(`ixfx-menu-container`);\n addContainer.setAttribute(`slot`, `submenu`);\n\n const idx = this._columns.findIndex(c => c.id === col.id);\n for (const [label, offset] of [[`Left`, -1], [`Right`, 1]] as const) {\n const item = this.#menuItem(label, `add-${label.toLowerCase()}`, () => {\n this.#insertColumn(unused[0].key, Math.max(0, idx + Math.max(0, offset)));\n });\n item.toggleAttribute(`disabled`, !canAdd);\n addContainer.appendChild(item);\n }\n addSub.appendChild(addContainer);\n container.appendChild(addSub);\n\n const sortSub = document.createElement(`ixfx-menu-sub-trigger`);\n sortSub.setAttribute(`label`, `Sort`);\n const sortContainer = document.createElement(`ixfx-menu-container`);\n sortContainer.setAttribute(`slot`, `submenu`);\n sortContainer.appendChild(this.#menuItem(`Ascending`, `sort-asc`, () => {\n col.setSort(`asc`);\n this._emitColumnsChange(`sort`);\n this.requestUpdate();\n }, col.getState().sort === `asc` ? `check` : undefined));\n sortContainer.appendChild(this.#menuItem(`Descending`, `sort-desc`, () => {\n col.setSort(`desc`);\n this._emitColumnsChange(`sort`);\n this.requestUpdate();\n }, col.getState().sort === `desc` ? `check` : undefined));\n sortSub.appendChild(sortContainer);\n container.appendChild(sortSub);\n\n const grouped = col.getState().grouped;\n container.appendChild(this.#menuItem(grouped ? `Ungroup` : `Group`, `toggle-group`, () => {\n col.setGrouped(!grouped);\n this._emitColumnsChange(`grouping`);\n this.requestUpdate();\n }, grouped ? `check` : undefined));\n });\n }\n\n #insertColumn(categoryKey: string, position: number): void {\n this.addColumn(categoryKey, position);\n }\n\n private _changeColumnCategory(col: MulticolColumnController, categoryKey: string): void {\n const category = this.categories.find(c => c.key === categoryKey);\n if (!category)\n return;\n\n col.setCategory(category);\n this._emitColumnsChange(`category`);\n this._requeryAllColumns();\n this.requestUpdate();\n }\n\n // ---------------------------------------------------------------------\n // Selection + data coordination\n // ---------------------------------------------------------------------\n\n private _onColumnSelectionChange(columnId: string, _values: readonly string[]): void {\n const col = this._columns.find(c => c.id === columnId);\n if (!col)\n return;\n\n // Narrow every other column; the changed column keeps its list\n for (const otherCol of this._columns) {\n if (otherCol.id !== columnId) {\n otherCol.requestData(this._buildQuery(otherCol));\n }\n }\n\n const detail: MulticolSelectDetail = {\n columnId,\n columns: this.getSelection(),\n };\n\n this.dispatchEvent(new CustomEvent<MulticolSelectDetail>(`multicol-select`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n\n this.requestUpdate();\n }\n\n private _onColumnRequestData(_columnId: string, _query: MulticolQuery, _signal: AbortSignal): void {\n // Hook for subclasses; the controller drives the provider directly\n }\n\n private _buildQuery(col: MulticolColumnController): MulticolQuery {\n const otherSelections = new Map<string, readonly string[]>();\n\n for (const c of this._columns) {\n if (c.id !== col.id) {\n otherSelections.set(c.id, c.selectedValues);\n }\n }\n\n return {\n columnId: col.id,\n categoryKey: col.categoryKey,\n otherSelections,\n };\n }\n\n private _requeryAllColumns(): void {\n for (const col of this._columns) {\n col.requestData(this._buildQuery(col));\n }\n }\n\n private _syncColumnsWithCategories(): void {\n let changed = false;\n for (const col of this._columns) {\n if (this.categories.some(c => c.key === col.categoryKey))\n continue;\n if (this.categories.length === 0)\n continue;\n col.setCategory(this.categories[0]);\n changed = true;\n }\n if (changed) {\n this._emitColumnsChange(`category`);\n }\n }\n\n private _updateColOffsets(): void {\n const offsets: number[] = [0];\n let sum = 0;\n\n for (const col of this._columns) {\n const rawWidth = col.getState().width ?? DEFAULT_COLUMN_WIDTH;\n // A non-finite width (NaN from a bad measurement/restore) would poison\n // the whole prefix-sum and — since `NaN === NaN` is false — wedge the\n // change guard below into scheduling an update forever.\n const safeWidth = Number.isFinite(rawWidth) ? rawWidth : DEFAULT_COLUMN_WIDTH;\n sum += safeWidth;\n offsets.push(sum);\n }\n\n // Only write back when something changed — unconditional assignment from\n // updated() would schedule an endless chain of updates. The comparison is\n // NaN-safe so a poisoned value can settle instead of looping.\n const unchanged = offsets.length === this._colOffsets.length\n && offsets.every((v, i) => v === this._colOffsets[i] || (Number.isNaN(v) && Number.isNaN(this._colOffsets[i])));\n if (!unchanged)\n this._colOffsets = offsets;\n }\n\n private _emitColumnsChange(reason: MulticolColumnsChangeReason): void {\n this.dispatchEvent(new CustomEvent<MulticolColumnsChangeDetail>(`multicol-columns-change`, {\n detail: {\n columns: this.columns,\n reason,\n },\n bubbles: true,\n composed: true,\n }));\n }\n\n public async autoSizeColumns(options?: { minWidth?: number; maxWidth?: number }): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(() => {\n const minWidth = options?.minWidth ?? MIN_COLUMN_WIDTH;\n const maxWidth = options?.maxWidth ?? MAX_COLUMN_WIDTH;\n\n const measure = (text: string): number => {\n const span = document.createElement(`span`);\n span.style.position = `absolute`;\n span.style.visibility = `hidden`;\n span.style.whiteSpace = `nowrap`;\n span.style.font = getComputedStyle(this).font;\n span.textContent = text;\n document.body.appendChild(span);\n const w = span.getBoundingClientRect().width;\n document.body.removeChild(span);\n // Detached/hidden subtrees (and happy-dom) can yield NaN or 0 —\n // treat non-finite reads as zero so they never poison the width.\n return Number.isFinite(w) ? w : 0;\n };\n\n for (const col of this._columns) {\n const colEl = this.shadowRoot?.querySelector(`[data-col-id=\"${col.id}\"]`);\n if (!colEl)\n continue;\n\n const headerEl = colEl.querySelector(`.column-header`);\n const listerHost = colEl.querySelector(`.lister-host`);\n\n let contentWidth = 0;\n\n if (listerHost) {\n const allLabel = listerHost.querySelector(`.all-label`);\n if (allLabel) {\n contentWidth = Math.max(contentWidth, measure(allLabel.textContent ?? ``));\n }\n\n const groupedLister = listerHost.querySelector(`ixfx-grouped-item-lister`);\n if (groupedLister) {\n const verticalLists = groupedLister.querySelectorAll(`ixfx-vertical-list`);\n for (const vl of verticalLists) {\n const itemEls = vl.querySelectorAll(`li`);\n for (const li of itemEls) {\n const labelEl = li.querySelector(`.item-label`);\n const countEl = li.querySelector(`.count`);\n const labelText = labelEl?.textContent ?? ``;\n const countText = countEl?.textContent ?? ``;\n const combinedText = labelText + countText;\n contentWidth = Math.max(contentWidth, measure(combinedText));\n }\n }\n }\n }\n\n let headerWidth = 0;\n if (headerEl) {\n const labelBtn = headerEl.querySelector(`.column-label`);\n if (labelBtn) {\n const labelTextWidth = measure(labelBtn.textContent ?? ``);\n const btnStyle = getComputedStyle(labelBtn);\n // Empty style reads (detached/hidden subtrees, happy-dom) parse\n // to NaN — coerce to 0 so the sum stays finite.\n const labelBtnPaddingH = (Number.parseFloat(btnStyle.paddingLeft) || 0) + (Number.parseFloat(btnStyle.paddingRight) || 0);\n const burgerBtn = headerEl.querySelector(`.burger-btn`);\n const burgerWidth = burgerBtn ? (Number.parseFloat(getComputedStyle(burgerBtn).width) || 0) : 0;\n const headerStyle = getComputedStyle(headerEl);\n const gap = Number.parseFloat(headerStyle.gap) || 0;\n headerWidth = labelTextWidth + labelBtnPaddingH + burgerWidth + gap;\n }\n }\n\n const padding = 24;\n const extraSpace = 16;\n const neededWidth = Math.max(headerWidth, contentWidth + padding + extraSpace);\n const clampedWidth = Math.max(minWidth, Math.min(maxWidth, Math.ceil(neededWidth)));\n\n // If every measurement came back empty the math above is NaN —\n // skip the column (keep its current width) instead of storing NaN,\n // which would poison offsets and wedge the update loop.\n if (!Number.isFinite(clampedWidth))\n continue;\n col.setWidth(clampedWidth);\n }\n\n this._updateColOffsets();\n this._emitColumnsChange(`resize`);\n this.requestUpdate();\n resolve();\n }, 0);\n });\n }\n}\n","import type { Notification, NotificationRenderer, NotificationRendererHooks } from './types.js';\nimport './notification-pill.js';\n\nexport type PillPosition = `top-left` | `top-middle` | `top-right` | `bottom-left` | `bottom-middle` | `bottom-right`;\nexport type PillQueueDisplay = `list` | `stack`;\n\nexport interface PillSafeArea {\n readonly top?: number;\n readonly right?: number;\n readonly bottom?: number;\n readonly left?: number;\n}\n\nexport interface PillRendererOptions {\n position?: PillPosition;\n /** `list`: one row per message, oldest nearest the anchor edge. `stack`: only the front message is fully shown, the rest peek out behind it. Default `list`. */\n queueDisplay?: PillQueueDisplay;\n /** Extra margin (px) added to the default spacing on each side, letting pills avoid eg. a fixed header/footer/notch. */\n safeArea?: PillSafeArea;\n}\n\ntype PillEntry = {\n element: HTMLElement;\n notification: Notification;\n};\n\ntype Edges = { vertical: `top` | `bottom`; horizontal: `left` | `middle` | `right` };\n\nconst ROW_SPACING = 8;\nconst DEFAULT_ROW_HEIGHT = 40;\nconst STACK_OFFSET_STEP = 4;\nconst STACK_OPACITY_BASE = 0.7;\nconst STACK_OPACITY_DECAY = 0.15;\nconst STACK_OPACITY_MIN = 0.2;\n\nfunction edgesOf(position: PillPosition): Edges {\n const vertical = position.startsWith(`top`) ? `top` : `bottom`;\n const horizontal = position.endsWith(`-left`) ? `left` : position.endsWith(`-right`) ? `right` : `middle`;\n return { vertical, horizontal };\n}\n\nfunction anchorStyles(position: PillPosition, safeArea: PillSafeArea): string {\n const { vertical, horizontal } = edgesOf(position);\n const vMargin = `calc(var(--space-l, 12px) + ${(vertical === `top` ? safeArea.top : safeArea.bottom) ?? 0}px)`;\n let css = `position: fixed; `;\n css += vertical === `top` ? `top: ${vMargin}; bottom: auto; ` : `bottom: ${vMargin}; top: auto; `;\n\n if (horizontal === `left`) {\n const hMargin = `calc(var(--space-l, 12px) + ${safeArea.left ?? 0}px)`;\n css += `left: ${hMargin}; right: auto;`;\n } else if (horizontal === `right`) {\n const hMargin = `calc(var(--space-l, 12px) + ${safeArea.right ?? 0}px)`;\n css += `right: ${hMargin}; left: auto;`;\n } else {\n css += `left: 50%; right: auto;`;\n }\n return css;\n}\n\n/** Entry-animation starting transform: pills slide in from the edge they're anchored to. */\nfunction entryTransform(edges: Edges): string {\n const dy = edges.vertical === `top` ? -20 : 20;\n if (edges.horizontal === `middle`) {\n return `translateX(-50%) translate(0, ${dy}px)`;\n }\n const dx = edges.horizontal === `left` ? -20 : 20;\n return `translate(${dx}px, ${dy}px)`;\n}\n\nfunction restingTransform(edges: Edges, dx: number, dy: number): string {\n if (edges.horizontal === `middle`) {\n return `translateX(-50%) translate(${dx}px, ${dy}px)`;\n }\n return `translate(${dx}px, ${dy}px)`;\n}\n\nexport function createPillRenderer(options: PillRendererOptions = {}): NotificationRenderer {\n const position: PillPosition = options.position ?? `top-right`;\n const queueDisplay: PillQueueDisplay = options.queueDisplay ?? `list`;\n const safeArea: PillSafeArea = options.safeArea ?? {};\n const edges = edgesOf(position);\n\n let container: HTMLDivElement | null = null;\n let hooks: NotificationRendererHooks | null = null;\n const pills: Map<string, PillEntry> = new Map();\n let rowHeight = DEFAULT_ROW_HEIGHT;\n let measured = false;\n\n function ensureContainer(): HTMLDivElement {\n if (container)\n return container;\n\n container = document.createElement(`div`);\n container.className = `ixfx-notification-container`;\n container.setAttribute(`role`, `region`);\n container.setAttribute(`aria-label`, `Notifications`);\n document.body.appendChild(container);\n return container;\n }\n\n function updateAttributes(el: HTMLElement, notification: Notification): void {\n el.setAttribute(`notification-type`, notification.type);\n el.setAttribute(`message`, notification.message);\n if (notification.icon) {\n el.setAttribute(`icon`, notification.icon);\n } else {\n el.removeAttribute(`icon`);\n }\n }\n\n function createPillElement(notification: Notification): HTMLElement {\n const el = document.createElement(`ixfx-notification-pill`) as HTMLElement;\n el.setAttribute(`notification-id`, notification.id);\n el.style.cssText = anchorStyles(position, safeArea);\n updateAttributes(el, notification);\n\n el.style.opacity = `0`;\n el.style.transform = entryTransform(edges);\n\n el.addEventListener(`pill-tap`, (e: Event) => {\n const customEvent = e as CustomEvent<{ id: string }>;\n hooks?.onTap(customEvent.detail.id);\n });\n\n return el;\n }\n\n function measureRowHeight(el: HTMLElement): void {\n if (measured)\n return;\n requestAnimationFrame(() => {\n const height = el.getBoundingClientRect().height;\n if (height > 0) {\n rowHeight = height;\n measured = true;\n }\n });\n }\n\n /** Positions every currently-visible pill for its rank in `order` (index 0 = front/oldest). */\n function applyLayout(order: readonly Notification[]): void {\n const total = order.length;\n order.forEach((notification, index) => {\n const entry = pills.get(notification.id);\n if (!entry)\n return;\n\n const el = entry.element;\n let dx = 0;\n let dy = 0;\n let opacity = 1;\n let pointerEvents = `auto`;\n let filter = `none`;\n\n if (queueDisplay === `list`) {\n const step = index * (rowHeight + ROW_SPACING);\n dy = edges.vertical === `top` ? step : -step;\n } else {\n const step = index * STACK_OFFSET_STEP;\n dy = edges.vertical === `top` ? step : -step;\n dx = edges.horizontal === `left` ? step : edges.horizontal === `right` ? -step : 0;\n if (index > 0) {\n const hintIndex = index - 1;\n opacity = Math.max(STACK_OPACITY_MIN, STACK_OPACITY_BASE - hintIndex * STACK_OPACITY_DECAY);\n pointerEvents = `none`;\n filter = `saturate(0.6)`;\n }\n }\n\n el.style.transition = `opacity 0.2s ease-out, transform 0.2s ease-out`;\n el.style.opacity = `${opacity}`;\n el.style.zIndex = `${total - index}`;\n el.style.pointerEvents = pointerEvents;\n el.style.filter = filter;\n el.style.transform = restingTransform(edges, dx, dy);\n });\n }\n\n function dismiss(id: string): void {\n const entry = pills.get(id);\n if (!entry)\n return;\n\n const el = entry.element as HTMLElement;\n el.setAttribute(`dismissing`, `true`);\n\n const cleanup = () => {\n el.removeEventListener(`transitionend`, cleanup);\n el.remove();\n pills.delete(id);\n\n if (container && pills.size === 0) {\n container.remove();\n container = null;\n measured = false;\n rowHeight = DEFAULT_ROW_HEIGHT;\n }\n };\n\n el.addEventListener(`transitionend`, cleanup);\n setTimeout(cleanup, 300);\n }\n\n function setNotifications(notifications: Notification[], _queueSize: number): void {\n const cont = ensureContainer();\n const idsToKeep = new Set(notifications.map(n => n.id));\n\n for (const notification of notifications) {\n const existing = pills.get(notification.id);\n if (existing) {\n existing.notification = notification;\n updateAttributes(existing.element, notification);\n continue;\n }\n\n const el = createPillElement(notification);\n pills.set(notification.id, { element: el, notification });\n cont.appendChild(el);\n measureRowHeight(el);\n }\n\n for (const [id] of pills) {\n if (!idsToKeep.has(id)) {\n dismiss(id);\n }\n }\n\n requestAnimationFrame(() => applyLayout(notifications));\n }\n\n return {\n attach(newHooks: NotificationRendererHooks): void {\n hooks = newHooks;\n },\n\n detach(): void {\n for (const [id] of pills) {\n dismiss(id);\n }\n if (container) {\n container.remove();\n container = null;\n }\n },\n\n setNotifications,\n };\n}\n","import type {\n Notification,\n NotificationContent,\n NotificationRenderer,\n NotifierOptions,\n} from './types.js';\nimport { createPillRenderer } from './pill-renderer.js';\n\ntype Managed = { -readonly [K in keyof Notification]: Notification[K] } & { timer: number | null; wasQueued: boolean };\n\nconst options: {\n renderer: NotificationRenderer;\n timeout: number;\n timeoutError: number;\n queue: boolean;\n queueSize: number;\n tapBehaviour: `none` | `dismiss`;\n tapHandlerDefault: NotifierOptions[`tapHandlerDefault`];\n} = {\n renderer: undefined as unknown as NotificationRenderer,\n timeout: 4000,\n timeoutError: 8000,\n queue: true,\n queueSize: 3,\n tapBehaviour: `dismiss`,\n tapHandlerDefault: undefined,\n};\n\n/** Rank-ordered, index 0 = oldest/first (next to be evicted or timed out). Length never exceeds queueSize (or 1 when queuing is disabled). */\nconst visible: Managed[] = [];\nlet renderer: NotificationRenderer | null = null;\nlet defaultRenderer: NotificationRenderer | null = null;\n\nfunction getDefaultRenderer(): NotificationRenderer {\n defaultRenderer ??= createPillRenderer({ position: `top-right` });\n return defaultRenderer;\n}\n\nfunction getRenderer(): NotificationRenderer {\n return renderer ?? getDefaultRenderer();\n}\n\nfunction syncRenderer(): void {\n getRenderer().setNotifications([...visible], options.queueSize);\n}\n\nfunction clearTimer(managed: Managed): void {\n if (managed.timer !== null) {\n clearTimeout(managed.timer);\n managed.timer = null;\n }\n}\n\n/**\n * A message shown alone takes the full timeout. A message that joined a\n * non-empty queue at arrival time is permanently \"wasQueued\" and gets\n * 1/queueSize of the timeout once it reaches the front. The timer for a\n * given message is only ever started once - when it first becomes front.\n */\nfunction startTimer(managed: Managed): void {\n const base = managed.type === `error` ? options.timeoutError : options.timeout;\n const duration = managed.wasQueued ? base / options.queueSize : base;\n managed.timer = window.setTimeout(dismiss, duration, managed.id);\n}\n\nfunction ensureFrontTimer(): void {\n const front = visible[0];\n if (front && front.timer === null) {\n startTimer(front);\n }\n}\n\nexport const NotificationManager = {\n configure(opts: NotifierOptions): void {\n if (opts.renderer !== undefined) {\n const old = renderer;\n old?.detach?.();\n renderer = opts.renderer;\n renderer.attach({\n onTap(id: string) {\n const notification = visible.find(n => n.id === id);\n if (!notification)\n return;\n if (notification.onTap) {\n notification.onTap(id);\n } else {\n options.tapHandlerDefault?.(notification);\n }\n if (options.tapBehaviour === `dismiss`) {\n dismiss(id);\n }\n },\n });\n syncRenderer();\n }\n if (opts.timeout !== undefined)\n options.timeout = opts.timeout;\n if (opts.timeoutError !== undefined)\n options.timeoutError = opts.timeoutError;\n if (opts.queue !== undefined)\n options.queue = opts.queue;\n if (opts.queueSize !== undefined) {\n options.queueSize = Math.max(1, opts.queueSize);\n while (visible.length > options.queueSize) {\n clearTimer(visible.shift()!);\n }\n ensureFrontTimer();\n syncRenderer();\n }\n if (opts.tapBehaviour !== undefined)\n options.tapBehaviour = opts.tapBehaviour;\n if (opts.tapHandlerDefault !== undefined)\n options.tapHandlerDefault = opts.tapHandlerDefault;\n },\n\n notify(content: NotificationContent): string {\n const id = crypto.randomUUID();\n const now = Date.now();\n const icon = content.icon ?? (content.type === `error` ? `error` : undefined);\n const managed: Managed = {\n ...content,\n icon,\n id,\n createdAt: now,\n updatedAt: now,\n timer: null,\n wasQueued: false,\n };\n\n if (options.queue) {\n if (visible.length >= options.queueSize) {\n clearTimer(visible.shift()!);\n }\n managed.wasQueued = visible.length > 0;\n visible.push(managed);\n } else {\n while (visible.length > 0) {\n clearTimer(visible.pop()!);\n }\n visible.push(managed);\n }\n\n ensureFrontTimer();\n syncRenderer();\n return id;\n },\n\n update(id: string, content: Partial<NotificationContent>): void {\n const managed = visible.find(n => n.id === id);\n if (!managed)\n return;\n\n Object.assign(managed, content);\n managed.updatedAt = Date.now();\n\n if (visible[0] === managed) {\n clearTimer(managed);\n startTimer(managed);\n }\n syncRenderer();\n },\n\n dismiss(id: string): void {\n dismiss(id);\n },\n\n dismissAll(): void {\n for (const m of visible)\n clearTimer(m);\n visible.length = 0;\n syncRenderer();\n },\n};\n\nfunction dismiss(id: string): void {\n const idx = visible.findIndex(m => m.id === id);\n if (idx === -1)\n return;\n\n clearTimer(visible.splice(idx, 1)[0]);\n ensureFrontTimer();\n syncRenderer();\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { DragGhost } from '../util/drag-ghost.js';\nimport type { PanelElement, PanelOrientation, PanelToggleInteraction, PanelVariant } from './panel.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, queryAssignedElements } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\n\nexport type PanelGroupOrientation = `horizontal` | `vertical`;\n\nexport interface PanelGroupReorderDetail {\n readonly fromIndex: number;\n readonly toIndex: number;\n readonly panel: PanelElement;\n}\n\nexport type PanelGroupReorderEvent = CustomEvent<PanelGroupReorderDetail>;\n\nexport interface PanelGroupElementEventMap {\n reorder: PanelGroupReorderEvent;\n}\n\n/** Pointer movement threshold (px) before a press becomes a drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\n/**\n * Pure helper: nearest gap index for a pointer position along one axis.\n * `edges` are the [start, end] of each sibling (excluding the drag source),\n * in DOM order. Returns 0..edges.length.\n */\nexport function panelGapIndex(edges: ReadonlyArray<readonly [number, number]>, pos: number): number {\n let bestGap = 0;\n let bestDist = Number.POSITIVE_INFINITY;\n for (let i = 0; i < edges.length; i++) {\n const [start, end] = edges[i];\n const mid = (start + end) / 2;\n if (pos < mid) {\n const d = Math.abs(pos - start);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i;\n }\n } else {\n const d = Math.abs(pos - end);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i + 1;\n }\n }\n }\n return bestGap;\n}\n\nlet panelGhostStylesInjected = false;\n\n/**\n * Global ghost styling so the drag preview matches `ixfx-titlebar` chrome\n * (font, colours, padding). Injected once; the ghost lives outside shadow DOM\n * (body/theme container) so component styles cannot reach it.\n */\nfunction injectPanelGhostStyles(): void {\n if (panelGhostStylesInjected) {\n return;\n }\n panelGhostStylesInjected = true;\n const style = document.createElement(`style`);\n style.textContent = `\n .ixfx-drag-ghost.ixfx-panel-group-ghost {\n padding: var(--space-s, 8px) var(--space-m, 16px);\n background: var(--surface-4);\n color: var(--surface-3-text);\n border: none;\n border-radius: var(--radius-s, 4px);\n font-family: var(--font-family);\n font-size: var(--text-m);\n font-weight: var(--font-weight-bold, 600);\n min-height: 2em;\n user-select: none;\n -webkit-user-select: none;\n }\n .ixfx-drag-ghost.ixfx-panel-group-ghost ixfx-icon {\n width: 1.25em;\n height: 1.25em;\n flex-shrink: 0;\n }\n `;\n document.head.appendChild(style);\n}\n\n@customElement(`ixfx-panel-group`)\nexport class PanelGroupElement extends LitElement {\n @property({ type: String, reflect: true }) orientation: PanelGroupOrientation = `horizontal`;\n @property({ type: String }) variant: PanelVariant = `titlebar`;\n @property({ type: String, attribute: `toggle-interaction` }) toggleInteraction: PanelToggleInteraction = `implicit`;\n @property({ type: Boolean }) collapsible = true;\n @property({ type: Boolean, attribute: `accordion`, reflect: true }) accordion = false;\n @property({ type: Boolean, attribute: `allow-reorder`, reflect: true }) allowReorder = false;\n /** Explicit gap between panels. When unset, `--group-gap` (falling back to `--space-l`) controls the gap. */\n @property() gap?: string;\n\n @queryAssignedElements({ slot: `` }) private _panels!: PanelElement[];\n\n private _dragState: {\n pointerId: number;\n source: PanelElement;\n fromIndex: number;\n startX: number;\n startY: number;\n active: boolean;\n ghost: DragGhost | null;\n gapIndex: number | undefined;\n } | null = null;\n\n private _suppressNextClick = false;\n\n private _onPanelToggle(e: Event) {\n const panel = e.target as PanelElement;\n if (panel.collapsed) {\n return;\n }\n\n if (!this.accordion) {\n return;\n }\n\n for (const p of this._panels) {\n if (p !== panel) {\n p.collapsed = true;\n }\n }\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Capture phase so we can swallow the trailing click after a real reorder\n // before it reaches the titlebar toggle handler inside ixfx-panel.\n this.addEventListener(`click`, this._onClickCapture, true);\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener(`click`, this._onClickCapture, true);\n if (this._dragState) {\n this._abortDrag();\n this._endDrag(this._dragState.pointerId);\n }\n super.disconnectedCallback();\n }\n\n protected override firstUpdated(): void {\n if (this.gap !== undefined) {\n this.style.setProperty(`--group-gap`, this.gap);\n }\n this.updateComplete.then(() => {\n this._propagateAll();\n });\n }\n\n protected override updated(changed: Map<string, unknown>): void {\n super.updated(changed);\n if (changed.has(`gap`)) {\n if (this.gap !== undefined) {\n this.style.setProperty(`--group-gap`, this.gap);\n } else {\n this.style.removeProperty(`--group-gap`);\n }\n }\n if (changed.has(`variant`) || changed.has(`toggleInteraction`) || changed.has(`orientation`) || changed.has(`collapsible`)) {\n this.updateComplete.then(() => {\n this._propagateAll();\n });\n }\n }\n\n private _propagateAll(): void {\n const invertedOrientation: PanelOrientation\n = this.orientation === `horizontal` ? `vertical` : `horizontal`;\n\n for (const panel of this._panels) {\n panel.setAttribute(`variant`, this.variant);\n panel.setAttribute(`toggle-interaction`, this.toggleInteraction);\n panel.setAttribute(`orientation`, invertedOrientation);\n if (this.collapsible) {\n panel.setAttribute(`collapsible`, ``);\n } else {\n panel.removeAttribute(`collapsible`);\n }\n }\n }\n\n private _onSlotChange(): void {\n this.updateComplete.then(() => {\n this._propagateAll();\n });\n }\n\n private _onClickCapture = (event: Event): void => {\n if (!this._suppressNextClick) {\n return;\n }\n this._suppressNextClick = false;\n event.preventDefault();\n event.stopPropagation();\n };\n\n private _onKeyDown = (event: KeyboardEvent): void => {\n const state = this._dragState;\n if (event.key !== `Escape` || !state?.active) {\n return;\n }\n event.preventDefault();\n const pointerId = state.pointerId;\n this._abortDrag();\n this._endDrag(pointerId);\n };\n\n /**\n * Walk composedPath for the nearest ixfx-panel, requiring the press to have\n * gone through an ixfx-titlebar (titlebar-anywhere drag). Bails when the\n * path crosses interactive chrome (buttons/links/inputs/toolbar/caret/close)\n * so those controls always win over dragging.\n */\n private _findDragTarget(event: PointerEvent): PanelElement | null {\n if (!this.allowReorder) {\n return null;\n }\n const path = event.composedPath();\n let panel: PanelElement | null = null;\n let viaTitlebar = false;\n for (const node of path) {\n if (!(node instanceof HTMLElement)) {\n continue;\n }\n const tag = node.tagName;\n if (tag === `BUTTON` || tag === `A` || tag === `INPUT` || tag === `SELECT` || tag === `TEXTAREA`) {\n return null;\n }\n if (node.classList.contains(`toolbar`) || node.classList.contains(`close-btn`) || node.classList.contains(`caret-btn`)) {\n return null;\n }\n if (node.hasAttribute?.(`slot`) && node.getAttribute(`slot`) === `toolbar`) {\n return null;\n }\n if (tag === `IXFX-TITLEBAR`) {\n viaTitlebar = true;\n }\n if (!panel && tag === `IXFX-PANEL`) {\n panel = node as PanelElement;\n }\n }\n if (!panel || !viaTitlebar) {\n return null;\n }\n return panel;\n }\n\n private _onPointerDown = (event: PointerEvent): void => {\n if (!this.allowReorder || event.button !== 0) {\n return;\n }\n const target = this._findDragTarget(event);\n if (!target?.parentNode) {\n return;\n }\n const fromIndex = Array.prototype.indexOf.call(target.parentNode.children, target);\n if (fromIndex < 0) {\n return;\n }\n // Don't capture yet — capturing on pointerdown would redirect the trailing\n // click to the capture target and break the normal titlebar toggle press.\n // Capture only once the drag activates.\n this._dragState = {\n pointerId: event.pointerId,\n source: target,\n fromIndex,\n startX: event.clientX,\n startY: event.clientY,\n active: false,\n ghost: null,\n gapIndex: undefined,\n };\n window.addEventListener(`pointermove`, this._onPointerMove);\n window.addEventListener(`pointerup`, this._onPointerUp);\n window.addEventListener(`pointercancel`, this._onPointerCancel);\n };\n\n private _onPointerMove = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId) {\n return;\n }\n const distance = Math.hypot(event.clientX - state.startX, event.clientY - state.startY);\n if (!state.active) {\n if (distance < DRAG_THRESHOLD_PX) {\n return;\n }\n this._beginDrag(event);\n }\n state.ghost?.move(event.clientX, event.clientY);\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n if (gap !== state.gapIndex) {\n state.gapIndex = gap;\n this.requestUpdate();\n }\n };\n\n private _onPointerUp = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId) {\n return;\n }\n if (state.active) {\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n this._commitDrag(state.source, state.fromIndex, gap);\n }\n this._endDrag(event.pointerId);\n };\n\n private _onPointerCancel = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId) {\n return;\n }\n this._abortDrag();\n this._endDrag(event.pointerId);\n };\n\n private _beginDrag(event: PointerEvent): void {\n const state = this._dragState;\n if (!state || state.active) {\n return;\n }\n try {\n this.setPointerCapture(event.pointerId);\n } catch {\n // Fall through — window listeners still catch move/up.\n }\n state.active = true;\n // `dragging` kills text selection for the gesture (see styles).\n this.setAttribute(`dragging`, ``);\n state.source.setAttribute(`drag-source`, ``);\n state.ghost = this._createGhost(state.source);\n state.ghost?.move(event.clientX, event.clientY);\n }\n\n private _abortDrag(): void {\n const state = this._dragState;\n if (!state) {\n return;\n }\n state.source.removeAttribute(`drag-source`);\n if (state.gapIndex !== undefined) {\n state.gapIndex = undefined;\n this.requestUpdate();\n }\n }\n\n private _endDrag(pointerId: number): void {\n const state = this._dragState;\n if (!state) {\n return;\n }\n state.ghost?.destroy();\n state.ghost = null;\n this.removeAttribute(`dragging`);\n this._dragState = null;\n window.removeEventListener(`pointermove`, this._onPointerMove);\n window.removeEventListener(`pointerup`, this._onPointerUp);\n window.removeEventListener(`pointercancel`, this._onPointerCancel);\n try {\n this.releasePointerCapture(pointerId);\n } catch { /* already released */ }\n this.requestUpdate();\n }\n\n private _commitDrag(source: PanelElement, fromIndex: number, gapIndex: number | undefined): void {\n source.removeAttribute(`drag-source`);\n // Gap is an index into the without-source panel list; resolve the reference\n // node from that list, then measure the public indices against the real\n // light-DOM children (which may include non-panel elements).\n const siblings = (this._panels ?? []).filter(el => el !== source);\n const target = gapIndex === undefined\n ? siblings.length\n : Math.max(0, Math.min(gapIndex, siblings.length));\n const parent = source.parentNode;\n if (!parent) {\n return;\n }\n const ref = siblings[target] ?? null;\n parent.insertBefore(source, ref);\n const toIndex = Array.prototype.indexOf.call(parent.children, source);\n if (toIndex === fromIndex) {\n return;\n }\n // A real reorder happened — swallow the trailing click so the titlebar\n // implicit toggle doesn't also collapse/expand the dragged panel.\n this._suppressNextClick = true;\n this.dispatchEvent(new CustomEvent<PanelGroupReorderDetail>(`reorder`, {\n bubbles: true,\n composed: true,\n detail: { fromIndex, toIndex, panel: source },\n }));\n }\n\n private _createGhost(source: PanelElement): DragGhost | null {\n // Mirror ixfx-titlebar's title-text-wrapper: icon + title with 1ch indent.\n const content = document.createElement(`span`);\n content.style.display = `inline-flex`;\n content.style.alignItems = `center`;\n content.style.padding = `0 var(--space-s, 8px)`;\n content.style.minWidth = `0`;\n if (source.iconName) {\n const icon = document.createElement(`ixfx-icon`) as HTMLElement & { name: string };\n icon.name = source.iconName;\n content.appendChild(icon);\n }\n const label = document.createElement(`span`);\n label.textContent = (source.title || (source.textContent ?? ``).trim()).slice(0, 60);\n label.style.paddingLeft = `1ch`;\n label.style.overflow = `hidden`;\n label.style.textOverflow = `ellipsis`;\n label.style.whiteSpace = `nowrap`;\n content.appendChild(label);\n try {\n injectPanelGhostStyles();\n return createDragGhost({ anchor: source, content, className: `ixfx-panel-group-ghost` });\n } catch {\n return null;\n }\n }\n\n /**\n * Nearest panel gap to the pointer, ignoring the drag source.\n * The perpendicular axis is ignored — the pointer always resolves to a gap.\n */\n private _computeGapIndex(clientX: number, clientY: number): number | undefined {\n const state = this._dragState;\n if (!state) {\n return undefined;\n }\n const siblings = (this._panels ?? []).filter(el => el !== state.source);\n if (siblings.length === 0) {\n return 0;\n }\n const useX = this.orientation === `horizontal`;\n const pos = useX ? clientX : clientY;\n const edges = siblings.map((el) => {\n const rect = el.getBoundingClientRect();\n return [useX ? rect.left : rect.top, useX ? rect.right : rect.bottom] as const;\n });\n return panelGapIndex(edges, pos);\n }\n\n private _computeCaretStyle(): string | undefined {\n const state = this._dragState;\n if (!state?.active || state.gapIndex === undefined) {\n return undefined;\n }\n const siblings = (this._panels ?? []).filter(el => el !== state.source);\n if (siblings.length === 0) {\n return undefined;\n }\n const hostRect = this.getBoundingClientRect();\n if (!hostRect) {\n return undefined;\n }\n const gap = Math.max(0, Math.min(state.gapIndex, siblings.length));\n const rect = gap < siblings.length\n ? siblings[gap].getBoundingClientRect()\n : siblings[siblings.length - 1].getBoundingClientRect();\n if (this.orientation === `horizontal`) {\n const x = (gap < siblings.length ? rect.left : rect.right) - hostRect.left;\n return `transform: translate(${x - 1}px, 0); width: 2px; height: ${hostRect.height}px;`;\n }\n const y = (gap < siblings.length ? rect.top : rect.bottom) - hostRect.top;\n return `transform: translate(0, ${y - 1}px); width: ${hostRect.width}px; height: 2px;`;\n }\n\n protected override render() {\n const caretStyle = this._computeCaretStyle();\n return html`\n <slot\n @toggle=${this._onPanelToggle}\n @slotchange=${this._onSlotChange}\n @pointerdown=${this._onPointerDown}\n @keydown=${this._onKeyDown}\n ></slot>\n ${caretStyle ? html`<div class=\"drop-caret\" style=${caretStyle}></div>` : nothing}\n `;\n }\n\n static override styles = css`\n :host {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: var(--group-gap, var(--space-l));\n }\n\n :host([orientation=\"horizontal\"]) {\n flex-direction: row;\n align-items: flex-start;\n flex-wrap: wrap;\n }\n\n :host([orientation=\"vertical\"]) {\n flex-direction: column;\n }\n\n ::slotted(ixfx-panel) {\n flex-shrink: 1;\n }\n\n :host([orientation=\"horizontal\"]) ::slotted(ixfx-panel) {\n flex-basis: content;\n min-width: 0;\n }\n\n :host([allow-reorder]) ::slotted(ixfx-panel) {\n cursor: grab;\n }\n\n :host([allow-reorder]) ::slotted(ixfx-panel[drag-source]) {\n cursor: grabbing;\n opacity: 0.4;\n }\n\n /* While dragging, suppress text selection inside the panels. */\n :host([dragging]),\n :host([dragging]) ::slotted(*) {\n user-select: none;\n -webkit-user-select: none;\n }\n\n :host([dragging]) ::slotted(ixfx-panel) {\n cursor: grabbing;\n }\n\n .drop-caret {\n position: absolute;\n top: 0;\n left: 0;\n background: var(--accent);\n border-radius: 1px;\n pointer-events: none;\n z-index: 1;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-panel-group': PanelGroupElement;\n }\n}\n\nexport interface PanelGroupElement {\n addEventListener: (<K extends keyof PanelGroupElementEventMap>(\n type: K,\n listener: (this: PanelGroupElement, event: PanelGroupElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","export type DragLogicCoordinates = {\n client: { x: number; y: number };\n offset: { x: number; y: number };\n};\nexport type DragLogicHandler = {\n progress: (current: DragLogicCoordinates, start: DragLogicCoordinates) => void;\n complete: (final: DragLogicCoordinates, start: DragLogicCoordinates) => void;\n};\n\nfunction getCoordinates(event: PointerEvent): DragLogicCoordinates {\n return {\n client: { x: event.clientX, y: event.clientY },\n offset: { x: event.offsetX, y: event.offsetY },\n };\n}\n\nexport function dragLogicStart(downEvent: PointerEvent, handler: DragLogicHandler) {\n const start = getCoordinates(downEvent);\n const onMove = (event: PointerEvent) => {\n handler.progress(\n getCoordinates(event),\n start,\n );\n };\n\n const onUp = (event: PointerEvent) => {\n document.removeEventListener(`pointermove`, onMove);\n document.removeEventListener(`pointerup`, onUp);\n handler.complete(\n getCoordinates(event),\n start,\n );\n };\n\n document.addEventListener(`pointermove`, onMove);\n document.addEventListener(`pointerup`, onUp);\n}\n","export function near(target: number, range: number) {\n const min = target - range;\n const max = target + range;\n return (v: number) => (v >= min && v <= max);\n}\n","import type { NumberScaler } from \"@ixfx/numbers\";\nimport type { PropertyValues } from \"lit\";\nimport type { TooltipOrientations } from \"../util/tooltip.js\";\nimport { clamper, scaler } from \"@ixfx/numbers\";\nimport { css, html, LitElement, nothing } from \"lit\";\nimport { eventOptions, property } from \"lit/decorators.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { prominenceStyles } from \"../styles/prominence.js\";\nimport { tooltipValueStyles } from \"../styles/tooltip.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\nimport { dragLogicStart } from \"../util/drag.js\";\n// import type { ClampFn } from \"../util/clamp.js\";\nimport { near } from \"../util/near.js\";\n\nexport type Endpoints = `a` | `b`;\n\nexport type CrossoverBehaviour = `stop` | `allow`;\n\nexport type ResizeMode = `dual` | `none` | `bipolar` | `bipolar-flex`;\n\nexport type RangeMultiInputDetail = {\n readonly a: number;\n readonly b: number;\n readonly changed: `a` | `b` | `both`;\n};\n\nexport type RangeMultiInputEvent = CustomEvent<RangeMultiInputDetail>;\n\n/**\n *\n * Attributes\n * crossover: How thumbs can cross over. Default: 'allow' ('allow'/'stop')\n * a/b: Initial A/B values on 0...100 scale\n * step: Increments of input on 0...100 scale. Use 'any' for maximum precision. Default: 1 (number|'any')\n * tooltip: Whether tooltip is shown. Default: true (boolean)\n * tooltip-orientation: Orientation of tooltip if used. Default: 'top' ('top'|'right')\n *\n * CSS variables\n * --range-background: AccentColor\n * --range-height: 1.5em;\n * --range-thickness: 1em;\n * --thumb-background: ButtonFace;\n * --thumb-radius: 50%;\n * --thumb-width: 1em;\n * --thumb-height: 1em;\n */\n@customElement(`ixfx-range-multi`)\nexport class RangeMultiElement extends LitElement {\n @property({ type: Boolean })\n tooltip = true;\n\n @property({ type: String, attribute: `tooltip-orientation` })\n tooltipOrientation: TooltipOrientations = `top`;\n\n @property({ type: String })\n crossover: CrossoverBehaviour = `allow`;\n\n @property({ type: String, attribute: `resize-mode` })\n resizeMode: ResizeMode = `dual`;\n\n @property({ type: String, reflect: true })\n orientation: `horizontal` | `vertical` = `horizontal`;\n\n @property()\n step: number | `any` = 1;\n\n @property({ type: Number })\n a = 0;\n\n @property({ type: Number })\n b = 50;\n\n #userMax = 100;\n #userMin = 0;\n\n #scaleTo100: NumberScaler = (v: number) => v;\n #scaleFrom100: NumberScaler = (v: number) => v;\n #userClamp: NumberScaler = (v: number) => v;\n\n #updateScale() {\n this.#scaleTo100 = scaler(this.#userMin, this.#userMax, 0, 100);\n this.#scaleFrom100 = scaler(0, 100, this.#userMin, this.#userMax);\n this.#userClamp = clamper(this.#userMin, this.#userMax);\n this.a = this.#userClamp(this.a);\n this.b = this.#userClamp(this.b);\n }\n\n @property({ type: Number })\n set max(v: number) {\n this.#userMax = v;\n this.#updateScale();\n }\n\n get max() {\n return this.#userMax;\n }\n\n @property({ type: Number })\n set min(v: number) {\n this.#userMin = v;\n this.#updateScale();\n }\n\n get min() {\n return this.#userMin;\n }\n\n valuesAtPointerDown: undefined | { a: number; b: number };\n draggingThumb: `a` | `b` | `none` = `none`;\n\n @eventOptions({ capture: true })\n _onInput(event: Event) {\n event.stopPropagation();\n const t = event.target as HTMLInputElement;\n const v = this.#scaleFrom100(t.valueAsNumber);\n const which = t.id as Endpoints;\n let a = this.a;\n let b = this.b;\n\n if (this.resizeMode === `none`) {\n const rawDelta = v - (which === `a` ? this.a : this.b);\n let panDelta = rawDelta;\n const newA = this.a + panDelta;\n const newB = this.b + panDelta;\n if (newA < this.min) {\n panDelta = this.min - this.a;\n }\n if (newB > this.max) {\n panDelta = this.max - this.b;\n }\n\n if (panDelta === 0) {\n t.valueAsNumber = this.#scaleTo100(which === `a` ? this.a : this.b);\n return;\n }\n\n a = this.a + panDelta;\n b = this.b + panDelta;\n } else if (this.resizeMode === `bipolar`) {\n let newA: number;\n let newB: number;\n if (which === `a`) {\n const delta = v - this.a;\n newA = v;\n newB = this.b - delta;\n } else {\n const delta = v - this.b;\n newA = this.a - delta;\n newB = v;\n }\n\n if (newA < this.min || newB > this.max || newA > this.max || newB < this.min) {\n t.valueAsNumber = this.#scaleTo100(which === `a` ? this.a : this.b);\n return;\n }\n\n a = newA;\n b = newB;\n } else if (this.resizeMode === `bipolar-flex`) {\n let newA: number;\n let newB: number;\n if (which === `a`) {\n newA = v;\n if (this.b <= this.min) {\n newB = this.min;\n } else if (this.b >= this.max) {\n newB = this.max;\n } else {\n const delta = v - this.a;\n newB = this.b - delta;\n }\n } else {\n newB = v;\n if (this.a <= this.min) {\n newA = this.min;\n } else if (this.a >= this.max) {\n newA = this.max;\n } else {\n const delta = v - this.b;\n newA = this.a - delta;\n }\n }\n\n if (newA < this.min)\n newA = this.min;\n if (newA > this.max)\n newA = this.max;\n if (newB < this.min)\n newB = this.min;\n if (newB > this.max)\n newB = this.max;\n\n if (newA > newB) {\n t.valueAsNumber = this.#scaleTo100(which === `a` ? this.a : this.b);\n return;\n }\n\n a = newA;\n b = newB;\n } else {\n if (which === `a`) {\n if (v > this.b && this.crossover === `stop`) {\n t.valueAsNumber = this.#scaleTo100(this.a);\n } else {\n a = v;\n }\n } else if (which === `b`) {\n if (v < a && this.crossover === `stop`) {\n t.valueAsNumber = this.#scaleTo100(this.b);\n } else {\n b = v;\n }\n } else {\n throw new Error(`Expected 'a' or 'b', got: '${t.id}'`);\n }\n }\n\n this.setPoles(a, b);\n }\n\n setPoles(a: number, b: number) {\n const aDiff = a !== this.a;\n const bDiff = b !== this.b;\n // a = clamp(a, this.min, this.max);\n // b = clamp(b, this.min, this.max);\n this.a = this.#userClamp(a);\n this.b = this.#userClamp(b);\n this.dispatchEvent(new CustomEvent<RangeMultiInputDetail>(`input`, {\n detail: { a: this.a, b: this.b, changed: aDiff && bDiff ? `both` : aDiff ? `a` : `b` },\n }));\n }\n\n @eventOptions({ capture: true })\n _onPointerDown(event: PointerEvent) {\n const startA = this.a;\n const startB = this.b;\n this.valuesAtPointerDown = { a: startA, b: startB };\n const rect = (event.target as HTMLInputElement).getBoundingClientRect();\n const isVertical = this.orientation === `vertical`;\n const dim = isVertical ? rect.height : rect.width;\n const valuePerPix = dim / (this.max - this.min);\n const pos = isVertical ? event.offsetY : event.offsetX;\n\n const valueFromPos = (p: number): number => {\n return isVertical ? this.max - p * valuePerPix : p * valuePerPix;\n };\n const posFromValue = (v: number): number => {\n return isVertical ? dim - (v * valuePerPix) : v * valuePerPix;\n };\n\n const aPosPx = posFromValue(startA);\n const bPosPx = posFromValue(startB);\n\n const outsideClick = isVertical\n ? (this.b < this.a ? pos > bPosPx : pos < bPosPx)\n || (this.b < this.a ? pos < aPosPx : pos > aPosPx)\n : (this.b < this.a && pos < bPosPx) || (this.b > this.a && pos > bPosPx)\n || (this.a < this.b && pos < aPosPx) || (this.a > this.b && pos > aPosPx);\n\n if (outsideClick) {\n if (this.resizeMode === `none` || this.resizeMode === `bipolar` || this.resizeMode === `bipolar-flex`) {\n const newB = valueFromPos(pos);\n let panDelta = newB - this.b;\n if (this.a + panDelta < this.min) {\n panDelta = this.min - this.a;\n }\n if (this.b + panDelta > this.max) {\n panDelta = this.max - this.b;\n }\n const finalA = this.a + panDelta;\n const finalB = this.b + panDelta;\n if (finalA >= this.min && finalB <= this.max) {\n this.setPoles(finalA, finalB);\n }\n } else {\n this.b = valueFromPos(pos);\n }\n return;\n }\n\n const aPosPxNear = near(aPosPx, 10);\n const bPosPxNear = near(bPosPx, 10);\n\n const handleDrag = (draggingWhich: `a` | `b` | `none`) => {\n const setPoles = this.setPoles.bind(this);\n const resizeMode = this.resizeMode;\n const min = this.min;\n const max = this.max;\n const startPos = isVertical ? event.offsetY : event.offsetX;\n let polesChanged = false;\n dragLogicStart(event, {\n progress(current, _start) {\n const currentPos = isVertical ? current.offset.y : current.offset.x;\n const delta = isVertical ? startPos - currentPos : currentPos - startPos;\n const amt = delta / valuePerPix;\n polesChanged = true;\n\n if (draggingWhich === `a`) {\n if (resizeMode === `bipolar`) {\n const calcA = startA + amt;\n const calcB = startB - amt;\n if (calcA < min || calcB > max || calcA > max || calcB < min) {\n return;\n }\n setPoles(calcA, calcB);\n } else if (resizeMode === `bipolar-flex`) {\n let calcA = startA + amt;\n let calcB = startB;\n\n if (startB <= min) {\n calcB = min;\n } else if (startB >= max) {\n calcB = max;\n } else {\n calcA = startA + amt;\n calcB = startB - amt;\n }\n\n if (calcA < min)\n calcA = min;\n if (calcA > max)\n calcA = max;\n if (calcB < min)\n calcB = min;\n if (calcB > max)\n calcB = max;\n\n if (calcA > calcB) {\n return;\n }\n setPoles(calcA, calcB);\n } else {\n let constrainedAmt = amt;\n if (startA + amt < min) {\n constrainedAmt = min - startA;\n }\n if (startB + constrainedAmt > max) {\n constrainedAmt = max - startB;\n }\n const finalA = startA + constrainedAmt;\n const finalB = startB + constrainedAmt;\n if (finalA >= min && finalB <= max) {\n setPoles(finalA, finalB);\n }\n }\n } else if (draggingWhich === `b`) {\n if (resizeMode === `bipolar`) {\n const calcA = startA - amt;\n const calcB = startB + amt;\n if (calcA < min || calcB > max || calcA > max || calcB < min) {\n return;\n }\n setPoles(calcA, calcB);\n } else if (resizeMode === `bipolar-flex`) {\n let calcA = startA;\n let calcB = startB + amt;\n\n if (startA <= min) {\n calcA = min;\n } else if (startA >= max) {\n calcA = max;\n } else {\n calcA = startA - amt;\n calcB = startB + amt;\n }\n\n if (calcA < min)\n calcA = min;\n if (calcA > max)\n calcA = max;\n if (calcB < min)\n calcB = min;\n if (calcB > max)\n calcB = max;\n\n if (calcA > calcB) {\n return;\n }\n setPoles(calcA, calcB);\n } else {\n let constrainedAmt = amt;\n if (startA + amt < min) {\n constrainedAmt = min - startA;\n }\n if (startB + constrainedAmt > max) {\n constrainedAmt = max - startB;\n }\n const finalA = startA + constrainedAmt;\n const finalB = startB + constrainedAmt;\n if (finalA >= min && finalB <= max) {\n setPoles(finalA, finalB);\n }\n }\n } else {\n if (resizeMode === `bipolar`) {\n const calcA = startA + amt;\n const calcB = startB + amt;\n if (calcA < min || calcB > max) {\n return;\n }\n setPoles(calcA, calcB);\n } else if (resizeMode === `bipolar-flex`) {\n let calcA = startA + amt;\n let calcB = startB + amt;\n if (calcA < min) {\n calcA = min;\n calcB = min + (startB - startA);\n } else if (calcB > max) {\n calcB = max;\n calcA = max - (startB - startA);\n }\n if (calcA < min || calcB > max || calcA > calcB) {\n return;\n }\n setPoles(calcA, calcB);\n } else {\n let constrainedAmt = amt;\n if (startA + amt < min) {\n constrainedAmt = min - startA;\n }\n if (startB + constrainedAmt > max) {\n constrainedAmt = max - startB;\n }\n const finalA = startA + constrainedAmt;\n const finalB = startB + constrainedAmt;\n if (finalA >= min && finalB <= max) {\n setPoles(finalA, finalB);\n }\n }\n }\n },\n complete(_final, _start) {\n if (!polesChanged) {\n const currentPos = isVertical ? event.offsetY : event.offsetX;\n const closestA = Math.abs(currentPos - aPosPx) < Math.abs(currentPos - bPosPx);\n if (closestA) {\n setPoles(valueFromPos(currentPos), startB);\n } else {\n setPoles(startA, valueFromPos(currentPos));\n }\n }\n },\n });\n };\n\n if (aPosPxNear(pos)) {\n this.draggingThumb = `a`;\n if (this.resizeMode === `dual`) {\n return false;\n }\n event.preventDefault();\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n handleDrag(`a`);\n return;\n } else if (bPosPxNear(pos)) {\n this.draggingThumb = `b`;\n if (this.resizeMode === `dual`) {\n return false;\n }\n event.preventDefault();\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n handleDrag(`b`);\n return;\n } else {\n this.draggingThumb = `none`;\n }\n\n event.preventDefault();\n (event.target as HTMLElement).setPointerCapture(event.pointerId);\n handleDrag(`none`);\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n this.#updateScale();\n }\n\n protected render(): unknown {\n const ttA = this.tooltip ? html`<ixfx-tooltip style=\"--tooltip-background: var(--surface-5); --tooltip-color: var(--surface-5-text)\" anchor=\"--a-tooltip\" .orientation=${this.tooltipOrientation} .value=${this.a}></ixfx-tooltip>` : nothing;\n const ttB = this.tooltip ? html`<ixfx-tooltip style=\"--tooltip-background: var(--surface-5); --tooltip-color: var(--surface-5-text)\" anchor=\"--b-tooltip\" .orientation=${this.tooltipOrientation} .value=${this.b}></ixfx-tooltip>` : nothing;\n\n const scaledA = this.#scaleTo100(this.a);\n const scaledB = this.#scaleTo100(this.b);\n const verticalStyle = this.orientation === `vertical`\n ? `writing-mode: vertical-lr; direction: rtl;`\n : nothing;\n // console.log(`a->b ${ this.a }->${ this.b } scaled: ${ scaledA }->${ scaledB }`)\n return html`\n <div @pointerdown=${this._onPointerDown} @input=${this._onInput} style=\"--a: ${scaledA}; --b: ${scaledB}\">\n <input class=\"thumb-round\" .value=${scaledA} id=\"a\" step=${this.step} type=\"range\" style=\"${verticalStyle}\" anchor=\"--a-tooltip\" />\n ${ttA}\n\n <input class=\"thumb-round\" .value=${scaledB} id=\"b\" step=${this.step} type=\"range\" style=\"${verticalStyle}\" anchor=\"--b-tooltip\" />\n ${ttB}\n </div>`;\n }\n\n static styles = [\n themeFallbacks,\n tooltipValueStyles,\n prominenceStyles,\n css`\n :host {\n display: grid;\n --value-label-color: unset;\n \n --range-background: AccentColor;\n --range-height: 1.5em;\n --range-thickness: 1em;\n --thumb-background: ButtonFace;\n --thumb-radius: 50%;\n --thumb-width: 1em;\n --thumb-height: 1em;\n --js:1;\n }\n\n :host([orientation=\"vertical\"]) {\n display: block;\n width: 1.5em;\n height: 200px;\n }\n\n * {\n margin: 0;\n padding: 0;\n font: inherit;\n }\n\n div {\n --j: var(--js, 0);\n display:inline grid;\n align-content: end;\n grid-gap: 0.25em;\n place-self: center;\n min-width: 8em;\n width: calc(100% - 1.5em);\n height: 1.5rem;\n }\n\n :host([orientation=\"vertical\"]) div {\n width: 1.5rem;\n height: calc(100% - 1.5em);\n min-width: unset;\n min-height: 8em;\n }\n\n div::before, div::after {\n margin: 0.5rem 0.6875rem;\n border-radius: 0.25rem;\n box-shadow: none;\n background: var(--surface-4);\n content: \"\";\n }\n :host([orientation=\"vertical\"]) div::before,\n :host([orientation=\"vertical\"]) div::after {\n margin: 0.5rem 0;\n }\n div::after {\n --or: calc((100 - Max(var(--a), var(--b)))*1%);\n --ol: calc(Min(var(--a), var(--b))*1%);\n box-shadow: none;\n background: var(--accent);\n clip-path: inset(0 var(--or) 0 var(--ol));\n }\n :host([orientation=\"vertical\"]) div::after {\n clip-path: inset(var(--or) 0 var(--ol) 0);\n }\n div input, div::before, div::after {\n grid-area: calc(1 + var(--j))/1;\n }\n div output, div::after {\n display:'none';\n }\n\n [type=range] {\n width: 100%;\n height: var(--range-height);\n background: transparent;\n pointer-events: none;\n }\n\n :host([orientation=\"vertical\"]) [type=range] {\n writing-mode: vertical-lr;\n direction: rtl;\n width: var(--range-height);\n height: 100%;\n }\n\n [type=range], [type=range]::-webkit-slider-runnable-track, [type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n }\n [type=range], [type=range] + ixfx-tooltip {\n --sel: 0;\n z-index: calc(1 + var(--sel));\n }\n [type=range]::-webkit-slider-runnable-track {\n background: transparent;\n }\n [type=range]::-moz-range-track {\n background: transparent;\n }\n\n input.thumb-round::-webkit-slider-thumb {\n width: var(--thumb-width);\n height: var(--thumb-height);\n border-radius: var(--thumb-radius);\n }\n\n [type=range]::-webkit-slider-thumb {\n box-sizing: border-box;\n border: solid calc(0.5rem + -1px) transparent;\n\n /* box-shadow: var(--shadow-m); */\n background: var(--thumb-background);\n pointer-events: auto;\n cursor: ew-resize;\n }\n\n :host([orientation=\"vertical\"]) [type=range]::-webkit-slider-thumb {\n width: var(--thumb-height);\n height: var(--thumb-width);\n cursor: ns-resize;\n }\n\n [type=range]::-moz-range-thumb {\n box-sizing: border-box;\n border: solid calc(0.5rem + -1px) transparent;\n width: 1.375rem;\n height: 1.375rem;\n border-radius: 50%;\n box-shadow: var(--shadow-m);\n background: var(--thumb-background);\n pointer-events: auto;\n cursor: ew-resize;\n }\n\n :host([orientation=\"vertical\"]) [type=range]::-moz-range-thumb {\n cursor: ns-resize;\n }\n\n [type=range]:focus {\n outline: none;\n }\n [type=range]:focus, [type=range]:focus + ixfx-tooltip, [type=range]:hover, [type=range]:hover + ixfx-tooltip {\n --sel: 1 ;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-range-multi\": RangeMultiElement;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nexport type RatingVariant = `star` | `square` | `heart`;\nexport type RatingChangeDetail = Readonly<{ value: number; oldValue: number }>;\nexport type RatingChangeEvent = CustomEvent<RatingChangeDetail>;\nexport type RatingInputEvent = CustomEvent<RatingChangeDetail>;\nexport interface RatingElementEventMap {\n change: RatingChangeEvent;\n input: RatingInputEvent;\n}\n\n@customElement(`ixfx-rating`)\nexport class RatingElement extends LitElement {\n static override styles = [prominenceStyles, css`\n :host {\n --ixfx-rating-size: 1.5rem;\n --ixfx-rating-gap: 0.2rem;\n --ixfx-rating-color: var(--surface-4);\n --ixfx-rating-color-active: var(--accent);\n --ixfx-rating-color-hover: var(--accent);\n display: inline-flex;\n gap: var(--ixfx-rating-gap);\n align-items: center;\n user-select: none;\n --transition: 0.15s ease;\n }\n :host([readonly]) { pointer-events: none; filter: none; }\n :host(:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }\n .glyph {\n width: var(--ixfx-rating-size);\n height: var(--ixfx-rating-size);\n position: relative;\n cursor: pointer;\n flex-shrink: 0;\n color: var(--ixfx-rating-glyph-color, var(--ixfx-rating-color));\n transition: color var(--transition), transform var(--transition);\n }\n .glyph.filled { color: var(--ixfx-rating-glyph-color-active, var(--ixfx-rating-color-active)); }\n .glyph.preview { color: var(--ixfx-rating-glyph-color-hover, var(--ixfx-rating-color-hover)); }\n .glyph.half .fill { clip-path: inset(0 50% 0 0); }\n .glyph svg { width: 100%; height: 100%; display: block; }\n .glyph .fill { position: absolute; inset: 0; color: var(--ixfx-rating-glyph-color-active, var(--ixfx-rating-color-active)); }\n .glyph.preview .fill { color: var(--ixfx-rating-glyph-color-hover, var(--ixfx-rating-color-hover)); }\n .glyph .bg { color: var(--ixfx-rating-glyph-color, var(--ixfx-rating-color)); }\n /* per-rank vars: consumer sets --ixfx-rating-1-color etc outside shadow, we map via inline style fallback */\n `];\n\n @property({ type: Number }) value = 0;\n @property({ type: Number }) max = 5;\n @property({ type: Boolean, attribute: `allow-half` }) allowHalf = false;\n @property({ type: Boolean, reflect: true }) disabled = false;\n @property({ type: Boolean, reflect: true }) readonly = false;\n @property({ type: String }) variant: RatingVariant = `star`;\n\n @state() private _preview: number | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n this.setAttribute(`role`, `slider`);\n this.tabIndex = this.disabled || this.readonly ? -1 : 0;\n }\n\n protected override updated(changed: Map<string, unknown>) {\n if (changed.has(`disabled`) || changed.has(`readonly`)) {\n this.tabIndex = this.disabled || this.readonly ? -1 : 0;\n this.setAttribute(`aria-disabled`, String(this.disabled));\n }\n this.setAttribute(`aria-valuenow`, String(this.value));\n this.setAttribute(`aria-valuemin`, `0`);\n this.setAttribute(`aria-valuemax`, String(this.max));\n this.setAttribute(`aria-readonly`, String(this.readonly));\n }\n\n private _path(v: RatingVariant) {\n if (v === `heart`)\n return `M12 21s-6.5-4.2-8.5-8.2A4.5 4.5 0 0 1 12 5a4.5 4.5 0 0 1 8.5 7.8C18.5 16.8 12 21 12 21z`;\n if (v === `square`)\n return `M3 3h18v18H3z`;\n return `M12 2l2.4 7.4H22l-6.2 4.5 2.4 7.4L12 17 5.8 21.3l2.4-7.4L2 9.4h7.6z`;\n }\n\n private _effective() {\n return this._preview ?? this.value;\n }\n\n private _commit(newVal: number) {\n if (this.disabled || this.readonly)\n return;\n const oldValue = this.value;\n if (newVal === oldValue)\n newVal = 0;\n if (newVal === oldValue)\n return;\n this.value = newVal;\n this.dispatchEvent(new CustomEvent<RatingChangeDetail>(`input`, { detail: { value: newVal, oldValue }, bubbles: true, composed: true }));\n this.dispatchEvent(new CustomEvent<RatingChangeDetail>(`change`, { detail: { value: newVal, oldValue }, bubbles: true, composed: true }));\n }\n\n private _calc(e: PointerEvent, index: number) {\n if (!this.allowHalf)\n return index + 1;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n return e.clientX - rect.left < rect.width / 2 ? index + 0.5 : index + 1;\n }\n\n protected override render() {\n const eff = this._effective();\n const hovering = this._preview !== null;\n return html`${Array.from({ length: this.max }, (_, i) => {\n const rank = i + 1;\n const filled = eff >= rank;\n const half = !filled && eff >= rank - 0.5;\n const cls = `glyph ${filled ? `filled` : ``} ${half ? `half` : ``} ${hovering && (filled || half) ? `preview` : ``}`;\n // per-rank CSS var mapping via inline style so outer --ixfx-rating-N-color cascades\n const style = `--ixfx-rating-glyph-color:var(--ixfx-rating-${rank}-color, var(--ixfx-rating-color));--ixfx-rating-glyph-color-active:var(--ixfx-rating-${rank}-color-active, var(--ixfx-rating-color-active));--ixfx-rating-glyph-color-hover:var(--ixfx-rating-${rank}-color-hover, var(--ixfx-rating-color-hover));${half || filled ? `` : ``}`;\n const d = this._path(this.variant);\n return html`<span class=${cls} style=${style}\n @pointermove=${(e: PointerEvent) => {\n if (this.disabled || this.readonly)\n return; this._preview = this._calc(e, i);\n }}\n @pointerleave=${() => this._preview = null}\n @click=${(e: PointerEvent) => this._commit(this._calc(e, i))}>\n <svg viewBox=\"0 0 24 24\" class=\"bg\" fill=\"currentColor\"><path d=${d}></path></svg>\n ${(filled || half) ? html`<svg viewBox=\"0 0 24 24\" class=\"fill\" fill=\"currentColor\"><path d=${d}></path></svg>` : ``}\n </span>`;\n })}`;\n }\n\n override firstUpdated() {\n this.addEventListener(`pointerleave`, () => this._preview = null);\n this.addEventListener(`keydown`, (e: KeyboardEvent) => {\n if (this.disabled || this.readonly)\n return;\n const step = this.allowHalf ? 0.5 : 1;\n if (e.key === `ArrowRight` || e.key === `ArrowUp`) {\n e.preventDefault(); this._commit(Math.min(this.max, this.value + step));\n } else if (e.key === `ArrowLeft` || e.key === `ArrowDown`) {\n e.preventDefault(); this._commit(Math.max(0, this.value - step));\n } else if (e.key === `Home`) {\n e.preventDefault(); this._commit(0);\n } else if (e.key === `End`) {\n e.preventDefault(); this._commit(this.max);\n } else if (/^\\d$/.test(e.key)) {\n e.preventDefault(); const n = parseInt(e.key, 10); this._commit(Math.min(n, this.max));\n }\n });\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap { 'ixfx-rating': RatingElement }\n}\nexport interface IxfxRatingElement {\n addEventListener: (<K extends keyof RatingElementEventMap>(type: K, listener: (this: RatingElement, ev: RatingElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions) => void) & ((type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions) => void);\n removeEventListener: (<K extends keyof RatingElementEventMap>(type: K, listener: (this: RatingElement, ev: RatingElementEventMap[K]) => void, options?: boolean | EventListenerOptions) => void) & ((type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions) => void);\n}\n","export function clampValue(v: number, min: number, max: number): number {\n return Math.min(Math.max(v, min), max);\n}\n\nexport type ClampTypes = `none` | `bipolar` | `scalar`;\nexport type ClampFn = (value: number) => number;\nexport function clamp(clamp: ClampTypes = `none`): ClampFn {\n switch (clamp) {\n case `bipolar`:\n return (v: number) => {\n if (v > 1)\n return 1;\n if (v < -1)\n return -1;\n return v;\n };\n case `scalar`:\n return (v: number) => {\n if (v > 1)\n return 1;\n if (v < 0)\n return 0;\n return v;\n };\n default:\n return (v: number) => v;\n }\n}","export interface Point { x: number; y: number }\nexport function polarToCartesian(angle: number, radius: number, center: Point = { x: 50, y: 50 }): Point {\n return { x: center.x + Math.cos(angle) * radius, y: center.y + Math.sin(angle) * radius };\n}\nexport { clampValue as clamp } from './clamp.js';\nexport function scale(v: number, fromMin: number, fromMax: number, toMin: number, toMax: number): number {\n if (fromMax === fromMin)\n return toMin;\n return toMin + ((v - fromMin) / (fromMax - fromMin)) * (toMax - toMin);\n}\nexport function describeArc(startAngle: number, endAngle: number, radius: number, center: Point = { x: 50, y: 50 }): string {\n const PI2 = Math.PI * 2;\n let arcLen = endAngle - startAngle;\n if (arcLen < 0)\n arcLen += PI2;\n if (arcLen >= PI2 - 0.001) {\n const adj = startAngle + PI2 - 0.001;\n const s = polarToCartesian(startAngle, radius, center);\n const e = polarToCartesian(adj, radius, center);\n return `M ${s.x},${s.y} A ${radius},${radius} 0 1 1 ${e.x},${e.y}`;\n }\n const s = polarToCartesian(startAngle, radius, center);\n const e = polarToCartesian(endAngle, radius, center);\n return `M ${s.x},${s.y} A ${radius},${radius} 0 ${arcLen > Math.PI ? 1 : 0} 1 ${e.x},${e.y}`;\n}\n","/**\n * Shapefill value component\n * A click-and-drag value input, similar in interaction to `ixfx-radial-input`,\n * but depicted as a shape outline (`rectangle` or `circle`) with a concentric\n * inner shape whose size represents the current value: a value of 50% draws\n * an inner shape scaled to half the outline's size.\n */\n\nimport type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type {\n ShapefillDisplay,\n ShapefillFillMode,\n ShapefillValueChangeDetail,\n ShapefillValueInputDetail,\n} from './types.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { clampValue } from '../util/clamp.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { scale } from '../util/geometry.js';\n\n@customElement(`ixfx-shapefill-value`)\nexport class ShapefillValueElement extends WheelNudgeMixin(LitElement) {\n // Display shape\n @property({ type: String })\n display: ShapefillDisplay = `circle`;\n\n // How the inner shape grows as value increases\n @property({ type: String, attribute: `fill-mode` })\n fillMode: ShapefillFillMode = `centre`;\n\n // Value properties (matches ixfx-radial-input API)\n @property({ type: Number })\n value = 0;\n\n @property({ type: Number })\n min = 0;\n\n @property({ type: Number })\n max = 100;\n\n @property({ type: Number })\n step: number | undefined = undefined;\n\n @property({ type: Number })\n stops?: number;\n\n // Interaction\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // Internal state\n #dragging = false;\n #dragStartY = 0;\n #valueAtDragStart = 0;\n /** Client Y of the last processed pointer event, for external-write re-baselining. */\n #lastPointerY = 0;\n /** Value at the drag's last write — detects external `value` writes mid-drag. */\n #lastSetValue: number | undefined;\n #changeDebounceTimer: number | undefined;\n\n // Internal helpers\n #getRelativeValue(): number {\n return scale(this.value, this.min, this.max, 0, 1);\n }\n\n #quantise(value: number): number {\n if (this.stops && this.stops > 1) {\n const range = this.max - this.min;\n const step = range / this.stops;\n return Math.round((value - this.min) / step) * step + this.min;\n }\n return value;\n }\n\n #setValueFromRelative(relativeValue: number, isUserInteraction = false): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clampedValue = this.#quantise(clampValue(newValue, this.min, this.max));\n\n if (clampedValue === this.value)\n return;\n\n const previousValue = this.value;\n this.value = clampedValue;\n this.#lastSetValue = clampedValue;\n\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(this.#getRelativeValue() * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n if (isUserInteraction) {\n this.dispatchEvent(\n new CustomEvent<ShapefillValueInputDetail>(`input`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n this.#scheduleChangeEvent(previousValue);\n } else {\n this.#fireChangeEvent(previousValue);\n }\n }\n\n #scheduleChangeEvent(previousValue: number): void {\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n\n this.#changeDebounceTimer = window.setTimeout(() => {\n this.#fireChangeEvent(previousValue);\n this.#changeDebounceTimer = undefined;\n }, 150);\n }\n\n #fireChangeEvent(previousValue: number): void {\n this.dispatchEvent(\n new CustomEvent<ShapefillValueChangeDetail>(`change`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n previousValue,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Pointer interaction handlers\n #onPointerDown = (event: PointerEvent): void => {\n if (this.disabled)\n return;\n\n event.preventDefault();\n const svgEl = this.renderRoot.querySelector(`svg`);\n svgEl?.focus();\n this.#dragging = true;\n this.#dragStartY = event.clientY;\n this.#lastPointerY = event.clientY;\n this.#valueAtDragStart = this.value;\n this.#lastSetValue = this.value;\n this.toggleAttribute(`dragging`, true);\n\n if (svgEl) {\n svgEl.setPointerCapture(event.pointerId);\n }\n\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n #onPointerMove = (event: PointerEvent): void => {\n if (!this.#dragging)\n return;\n\n event.preventDefault();\n\n // The value moved outside the drag since our last write (two-way binding,\n // a normalising `input`/`change` handler, wheel nudge, ...). Re-baseline\n // from the previous pointer position so this event's delta still applies\n // on top of the external value, instead of stomping it back toward the\n // drag-start trajectory.\n if (this.value !== this.#lastSetValue) {\n this.#valueAtDragStart = this.value;\n this.#dragStartY = this.#lastPointerY;\n this.#lastSetValue = this.value;\n }\n\n // Calculate sensitivity: full range = 2x the component height\n const sensitivity = this.clientHeight * 2;\n const shiftDivisor = event.shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveSensitivity = sensitivity * shiftDivisor;\n\n // Calculate delta (negative because up = increase)\n const deltaY = this.#dragStartY - event.clientY;\n const deltaValue = (deltaY / effectiveSensitivity) * (this.max - this.min);\n const newValue = this.#valueAtDragStart + deltaValue;\n\n const relativeValue = scale(newValue, this.min, this.max, 0, 1);\n this.#setValueFromRelative(clampValue(relativeValue, 0, 1), true);\n this.#lastPointerY = event.clientY;\n };\n\n #onPointerUp = (): void => {\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n\n const svgEl = this.renderRoot.querySelector(`svg`);\n if (svgEl && `hasPointerCapture` in svgEl && typeof svgEl.hasPointerCapture === `function`) {\n if (svgEl.hasPointerCapture(1)) {\n svgEl.releasePointerCapture(1);\n }\n }\n\n window.removeEventListener(`pointermove`, this.#onPointerMove);\n window.removeEventListener(`pointerup`, this.#onPointerUp);\n window.removeEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n // Keyboard interaction handler\n #onKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled)\n return;\n\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n\n let handled = false;\n\n switch (event.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n this.#stepByRelativeDelta(effectiveStep / range, true);\n handled = true;\n break;\n\n case `ArrowDown`:\n case `ArrowLeft`:\n this.#stepByRelativeDelta(-effectiveStep / range, true);\n handled = true;\n break;\n\n case `Home`:\n this.#setValueFromRelative(0, true);\n handled = true;\n break;\n\n case `End`:\n this.#setValueFromRelative(1, true);\n handled = true;\n break;\n }\n\n if (handled) {\n event.preventDefault();\n }\n };\n\n /**\n * Apply a relative-delta nudge to the current value, clamped to [min, max] and\n * quantised. Shared between keyboard arrow keys and the wheel handler.\n */\n #stepByRelativeDelta(relativeDelta: number, isUserInteraction: boolean): void {\n this.#setValueFromRelative(\n clampValue(this.#getRelativeValue() + relativeDelta, 0, 1),\n isUserInteraction,\n );\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Wheel up increases,\n // wheel down decreases (standard convention, unlike the inverted rotary-dial feel\n // of ixfx-radial-input, since there's no rotational metaphor here).\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this.#stepByRelativeDelta(direction * effectiveStep / range, true);\n }\n\n // Rendering helpers\n #renderCircle() {\n const relativeValue = this.#getRelativeValue();\n const outerRadius = 45;\n const innerRadius = outerRadius * relativeValue;\n const outerCx = 50;\n const outerCy = 50;\n\n // 'left'/'right': the value circle's x-origin travels from the outline's\n // left/right perimeter (value 0) to the outline's centre (value 100%),\n // while its radius grows the same way as 'centre' — the net effect is a\n // circle that inflates outward from that edge.\n let cx = outerCx;\n if (this.fillMode === `left`)\n cx = outerCx - outerRadius + outerRadius * relativeValue;\n else if (this.fillMode === `right`)\n cx = outerCx + outerRadius - outerRadius * relativeValue;\n\n return svg`\n <circle class=\"fill\" cx=\"${cx}\" cy=\"${outerCy}\" r=\"${innerRadius}\" />\n <circle class=\"outline\" cx=\"${outerCx}\" cy=\"${outerCy}\" r=\"${outerRadius}\" fill=\"none\" />\n `;\n }\n\n #renderRectangle() {\n const relativeValue = this.#getRelativeValue();\n const outerSize = 90; // 5..95\n const outerOffset = (100 - outerSize) / 2;\n\n if (this.fillMode === `left` || this.fillMode === `right`) {\n // Classic slider-bar fill: grows from the outline's left/right edge, full height.\n const innerWidth = outerSize * relativeValue;\n const x = this.fillMode === `left` ? outerOffset : outerOffset + outerSize - innerWidth;\n return svg`\n <rect class=\"fill\" x=\"${x}\" y=\"${outerOffset}\" width=\"${innerWidth}\" height=\"${outerSize}\" />\n <rect class=\"outline\" x=\"${outerOffset}\" y=\"${outerOffset}\" width=\"${outerSize}\" height=\"${outerSize}\" fill=\"none\" />\n `;\n }\n\n const innerSize = outerSize * relativeValue;\n const innerOffset = (100 - innerSize) / 2;\n\n return svg`\n <rect class=\"fill\" x=\"${innerOffset}\" y=\"${innerOffset}\" width=\"${innerSize}\" height=\"${innerSize}\" />\n <rect class=\"outline\" x=\"${outerOffset}\" y=\"${outerOffset}\" width=\"${outerSize}\" height=\"${outerSize}\" fill=\"none\" />\n `;\n }\n\n override render(): unknown {\n // Circle keeps a fixed aspect ratio (`meet`) so it always renders as a\n // true circle, letterboxing within a non-square host. Rectangle instead\n // stretches to fill the host (`none`), so a landscape/portrait host\n // produces a matching landscape/portrait rectangle rather than a\n // letterboxed square.\n const preserveAspectRatio = this.display === `rectangle` ? `none` : `xMidYMid meet`;\n\n return html`\n <svg\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"${preserveAspectRatio}\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n @pointerdown=\"${this.#onPointerDown}\"\n @keydown=\"${this.#onKeyDown}\"\n style=\"cursor: ${this.#dragging ? `ns-resize` : `grab`}\"\n >\n ${this.display === `rectangle` ? this.#renderRectangle() : this.#renderCircle()}\n </svg>\n `;\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n this.style.setProperty(`--shapefill-value-relative`, this.#getRelativeValue().toString());\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n this.#onPointerUp();\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-block;\n width: 2em;\n height: 2em;\n touch-action: none;\n user-select: none;\n\n /* Dynamic value - set by JS */\n --shapefill-value-relative: 0;\n\n /* Public styling variables — consumer customisable */\n --shapefill-value-outline-color: var(--surface-4);\n --shapefill-value-outline-width: 2;\n --shapefill-value-fill-color: var(--accent);\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n svg {\n width: 100%;\n height: 100%;\n outline: none;\n display: block;\n }\n\n svg:active {\n cursor: grabbing;\n }\n\n svg:focus-visible {\n outline: var(--shapefill-value-focus-outline, 2px solid var(--accent));\n outline-offset: var(--shapefill-value-focus-outline-offset, 2px);\n }\n\n .outline {\n stroke: var(--shapefill-value-outline-color, var(--surface-4));\n stroke-width: var(--shapefill-value-outline-width, 2);\n vector-effect: non-scaling-stroke;\n }\n\n .fill {\n fill: var(--shapefill-value-fill-color, var(--accent));\n transition: var(--shapefill-value-fill-transition, none);\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-shapefill-value': ShapefillValueElement;\n }\n}\n","import type { PropertyValues } from 'lit';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n/**\n * Digit-roll direction.\n * - `auto` — inferred from whether the value went up or down (default)\n * - `up` / `down` — force the reels to always spin one way\n * - `none` — take the shortest path\n */\nexport type SlidingNumberTrend = `auto` | `up` | `down` | `none` | `increasing` | `decreasing`;\n\ntype CellKind = `digit` | `symbol`;\ntype CellSection = `lead` | `integer` | `fraction` | `trail` | `decimal`;\ntype CellPhase = `enter` | `active` | `leave`;\n\ninterface ViewCell {\n key: string;\n kind: CellKind;\n section: CellSection;\n char: string;\n pos: number;\n phase: CellPhase;\n}\n\n// Three stacked copies of 0–9 so a reel can roll a full wrap in either\n// direction from its canonical rest offset (the middle copy, 10 + digit).\nconst REEL_DIGITS: readonly number[] = Array.from({ length: 30 }, (_, index) => index % 10);\n\nconst SECTION_RANK: Record<CellSection, number> = {\n lead: 0,\n integer: 1,\n decimal: 2,\n fraction: 3,\n trail: 4,\n};\n\nfunction mod(n: number, m: number): number {\n return ((n % m) + m) % m;\n}\n\n/** Parse a CSS time token (`0.7s`, `700ms`, `0`) to milliseconds. */\nfunction millis(value: string): number {\n const s = value.trim();\n if (s === ``)\n return 0;\n if (s.endsWith(`ms`))\n return Number.parseFloat(s) || 0;\n if (s.endsWith(`s`))\n return (Number.parseFloat(s) || 0) * 1000;\n return Number.parseFloat(s) || 0;\n}\n\n/**\n * `ixfx-sliding-number` — an animated number readout. When `value` changes each\n * digit rolls vertically to its new figure (odometer / slot-machine style),\n * digits that appear or disappear slide + fade, and the whole thing stays lined\n * up on the decimal point.\n *\n * Inspired by [NumberFlow](https://number-flow.barvian.me/): configurable\n * timings, a `trend` to bias roll direction, decimal alignment, and `::part()`\n * hooks for styling.\n *\n * ```html\n * <ixfx-sliding-number value=\"1234.5\"></ixfx-sliding-number>\n * <ixfx-sliding-number value=\"19.99\" prefix=\"$\" format='{\"minimumFractionDigits\":2}'></ixfx-sliding-number>\n * ```\n *\n * ### CSS variables\n * | Variable | Default | Purpose |\n * |---|---|---|\n * | `--sliding-number-spin-duration` | `0.7s` | Time for a digit reel to roll |\n * | `--sliding-number-spin-easing` | `cubic-bezier(.16,1,.3,1)` | Easing for the roll |\n * | `--sliding-number-transform-duration` | `0.5s` | Time for digits to slide in/out as the number grows/shrinks |\n * | `--sliding-number-transform-easing` | `cubic-bezier(.16,1,.3,1)` | Easing for that slide |\n * | `--sliding-number-opacity-duration` | `0.35s` | Fade time for entering/leaving digits |\n * | `--sliding-number-digit-width` | `1ch` | Column width of a single digit |\n *\n * ### Parts\n * `prefix`, `suffix`, `number`, `integer`, `fraction`, `digit`, `symbol`.\n */\n@customElement(`ixfx-sliding-number`)\nexport class SlidingNumberElement extends LitElement {\n /** The number to display. */\n @property({ type: Number }) value = 0;\n\n /** BCP-47 locale(s) passed to `Intl.NumberFormat`. */\n @property({ type: String }) locales: string | undefined;\n\n /**\n * `Intl.NumberFormat` options. As an attribute, pass JSON:\n * `format='{\"style\":\"currency\",\"currency\":\"USD\"}'`.\n */\n @property({ type: Object }) format: Intl.NumberFormatOptions | undefined;\n\n /** Static text shown before the number. */\n @property({ type: String }) prefix = ``;\n\n /** Static text shown after the number. */\n @property({ type: String }) suffix = ``;\n\n /** Which way the digit reels roll. */\n @property({ type: String }) trend: SlidingNumberTrend = `auto`;\n\n /** Add the `no-animate` attribute to render every change instantly. */\n @property({ type: Boolean, attribute: `no-animate` }) noAnimate = false;\n\n /** Honour `prefers-reduced-motion: reduce` (default `true`; set the property to `false` to override). */\n @property({ type: Boolean, attribute: false }) respectMotionPreference = true;\n\n @state() private _cells: ViewCell[] = [];\n\n private _formatted = ``;\n private _ready = false;\n private _prevValue: number | undefined;\n private _pendingSpins: Array<{ key: string; from: number; to: number }> = [];\n private _pendingDir: `up` | `down` | `none` = `none`;\n private _reelAnims = new Map<string, Animation>();\n private _reapTimer = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute(`role`))\n this.setAttribute(`role`, `img`);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n for (const anim of this._reelAnims.values()) anim.cancel();\n this._reelAnims.clear();\n if (this._reapTimer)\n clearTimeout(this._reapTimer);\n }\n\n private _motionOK(): boolean {\n if (this.noAnimate)\n return false;\n if (\n this.respectMotionPreference\n && typeof window !== `undefined`\n && window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches\n ) {\n return false;\n }\n return true;\n }\n\n private _timing(kind: `spin` | `transform`): { duration: number; easing: string } {\n const cs = getComputedStyle(this);\n const duration = this._motionOK()\n ? millis(cs.getPropertyValue(`--sliding-number-${kind}-duration`))\n : 0;\n const easing = cs.getPropertyValue(`--sliding-number-${kind}-easing`).trim() || `ease`;\n return { duration, easing };\n }\n\n private _numberFormat(): Intl.NumberFormat {\n try {\n return new Intl.NumberFormat(this.locales || undefined, this.format || undefined);\n } catch {\n return new Intl.NumberFormat(this.locales || undefined);\n }\n }\n\n private _resolveDir(first: boolean): `up` | `down` | `none` {\n switch (this.trend) {\n case `up`:\n case `increasing`:\n return `up`;\n case `down`:\n case `decreasing`:\n return `down`;\n case `none`:\n return `none`;\n default: {\n if (first || this._prevValue === undefined || this.value === this._prevValue)\n return `none`;\n return this.value > this._prevValue ? `up` : `down`;\n }\n }\n }\n\n /** Split the formatted value into positioned cells. */\n private _buildCells(parts: Intl.NumberFormatPart[]): ViewCell[] {\n const intRaw: Array<{ digit: boolean; char: string }> = [];\n const fractionChars: string[] = [];\n const lead: string[] = [];\n const trail: string[] = [];\n let decimalChar = ``;\n let sawInteger = false;\n let sawDecimal = false;\n\n for (const part of parts) {\n switch (part.type) {\n case `integer`:\n sawInteger = true;\n for (const c of part.value) intRaw.push({ digit: true, char: c });\n break;\n case `group`:\n intRaw.push({ digit: false, char: part.value });\n break;\n case `decimal`:\n sawDecimal = true;\n decimalChar = part.value;\n break;\n case `fraction`:\n for (const c of part.value) fractionChars.push(c);\n break;\n default:\n (sawInteger || sawDecimal ? trail : lead).push(part.value);\n }\n }\n\n const cells: ViewCell[] = [];\n const totalIntDigits = intRaw.filter(x => x.digit).length;\n\n lead.forEach((char, index) => {\n cells.push({ key: `lead:${index}`, kind: `symbol`, section: `lead`, char, pos: index - 100, phase: `active` });\n });\n\n let seen = 0;\n for (const item of intRaw) {\n if (item.digit) {\n const place = totalIntDigits - 1 - seen;\n seen++;\n cells.push({ key: `int:${place}`, kind: `digit`, section: `integer`, char: item.char, pos: -place, phase: `active` });\n } else {\n // Separator sits just to the right of the digit at `place` (lower-place side).\n const place = totalIntDigits - seen;\n cells.push({ key: `grp:${place}`, kind: `symbol`, section: `integer`, char: item.char, pos: -place + 0.5, phase: `active` });\n }\n }\n\n if (sawDecimal) {\n cells.push({ key: `decimal`, kind: `symbol`, section: `decimal`, char: decimalChar, pos: 0, phase: `active` });\n }\n\n fractionChars.forEach((char, index) => {\n cells.push({ key: `frac:${index}`, kind: `digit`, section: `fraction`, char, pos: index + 1, phase: `active` });\n });\n\n trail.forEach((char, index) => {\n cells.push({ key: `trail:${index}`, kind: `symbol`, section: `trail`, char, pos: index + 100, phase: `active` });\n });\n\n return cells;\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n const relevant = [`value`, `format`, `locales`, `prefix`, `suffix`, `noAnimate`].some(p => changed.has(p));\n if (!relevant && this._ready)\n return;\n\n const nf = this._numberFormat();\n this._formatted = `${this.prefix}${nf.format(this.value)}${this.suffix}`;\n this.setAttribute(`aria-label`, this._formatted);\n this.toggleAttribute(`data-static`, !this._motionOK());\n\n const first = !this._ready;\n const motionOK = this._motionOK() && !first;\n const next = this._buildCells(nf.formatToParts(this.value));\n const nextKeys = new Set(next.map(c => c.key));\n const prev = this._cells.filter(c => c.phase !== `leave`);\n const prevByKey = new Map(prev.map(c => [c.key, c]));\n\n const dir = this._resolveDir(first);\n const spins: Array<{ key: string; from: number; to: number }> = [];\n const merged: ViewCell[] = [];\n\n for (const cell of next) {\n const before = prevByKey.get(cell.key);\n if (before) {\n if (motionOK && cell.kind === `digit` && before.char !== cell.char) {\n spins.push({ key: cell.key, from: Number(before.char), to: Number(cell.char) });\n }\n merged.push({ ...cell, phase: `active` });\n } else {\n merged.push({ ...cell, phase: motionOK ? `enter` : `active` });\n }\n }\n\n if (motionOK) {\n for (const cell of prev) {\n if (!nextKeys.has(cell.key))\n merged.push({ ...cell, phase: `leave` });\n }\n }\n\n merged.sort((a, b) => SECTION_RANK[a.section] - SECTION_RANK[b.section] || a.pos - b.pos);\n\n this._cells = merged;\n this._pendingSpins = spins;\n this._pendingDir = dir;\n }\n\n protected override updated(): void {\n for (const spin of this._pendingSpins) this._spin(spin.key, spin.from, spin.to, this._pendingDir);\n this._pendingSpins = [];\n\n if (this._cells.some(c => c.phase === `enter`)) {\n requestAnimationFrame(() => requestAnimationFrame(() => {\n let changed = false;\n for (const cell of this._cells) {\n if (cell.phase === `enter`) {\n cell.phase = `active`;\n changed = true;\n }\n }\n if (changed) {\n this._cells = [...this._cells];\n this.requestUpdate();\n }\n }));\n }\n\n if (this._cells.some(c => c.phase === `leave`)) {\n if (this._reapTimer)\n clearTimeout(this._reapTimer);\n this._reapTimer = window.setTimeout(() => {\n this._reapTimer = 0;\n const kept = this._cells.filter(c => c.phase !== `leave`);\n if (kept.length !== this._cells.length) {\n this._cells = kept;\n this.requestUpdate();\n }\n }, this._timing(`transform`).duration + 120);\n }\n\n this._prevValue = this.value;\n this._ready = true;\n }\n\n private _spin(key: string, fromDigit: number, toDigit: number, dir: `up` | `down` | `none`): void {\n const reel = this.renderRoot.querySelector<HTMLElement>(`[data-key=\"${key}\"] .reel`);\n if (!reel)\n return;\n\n const fromOffset = 10 + fromDigit;\n let toOffset: number;\n if (dir === `up`) {\n toOffset = fromOffset + mod(toDigit - fromDigit, 10);\n } else if (dir === `down`) {\n toOffset = fromOffset - mod(fromDigit - toDigit, 10);\n } else {\n toOffset = [toDigit, 10 + toDigit, 20 + toDigit].reduce((best, candidate) =>\n Math.abs(candidate - fromOffset) < Math.abs(best - fromOffset) ? candidate : best);\n }\n\n const { duration, easing } = this._timing(`spin`);\n this._reelAnims.get(key)?.cancel();\n\n if (duration === 0) {\n reel.style.setProperty(`--o`, String(10 + toDigit));\n return;\n }\n\n const anim = reel.animate(\n [\n { transform: `translateY(calc(-1em * ${fromOffset}))` },\n { transform: `translateY(calc(-1em * ${toOffset}))` },\n ],\n { duration, easing, fill: `both` },\n );\n this._reelAnims.set(key, anim);\n anim.finished\n .then(() => {\n reel.style.setProperty(`--o`, String(10 + toDigit));\n anim.cancel();\n this._reelAnims.delete(key);\n })\n .catch(() => { /* superseded */ });\n }\n\n private _renderCell(cell: ViewCell) {\n if (cell.kind === `digit`) {\n return html`\n <span class=\"cell digit\" part=\"digit\" data-key=${cell.key} data-phase=${cell.phase}>\n <span class=\"reel\" style=${`--o:${10 + Number(cell.char)}`}>\n ${REEL_DIGITS.map(d => html`<span>${d}</span>`)}\n </span>\n </span>\n `;\n }\n return html`\n <span class=\"cell symbol\" part=\"symbol\" data-key=${cell.key} data-phase=${cell.phase}>${cell.char}</span>\n `;\n }\n\n protected override render() {\n const section = (name: CellSection) => this._cells.filter(c => c.section === name);\n const integer = [...section(`integer`)].reverse();\n\n return html`\n ${this.prefix ? html`<span class=\"affix\" part=\"prefix\">${this.prefix}</span>` : nothing}\n <span class=\"number\" part=\"number\" aria-hidden=\"true\">\n <span class=\"run lead\">${section(`lead`).map(c => this._renderCell(c))}</span>\n <span class=\"run integer\" part=\"integer\">\n ${repeat(integer, c => c.key, c => this._renderCell(c))}\n </span>\n ${section(`decimal`).map(c => this._renderCell(c))}\n <span class=\"run fraction\" part=\"fraction\">\n ${repeat(section(`fraction`), c => c.key, c => this._renderCell(c))}\n </span>\n <span class=\"run trail\">${section(`trail`).map(c => this._renderCell(c))}</span>\n </span>\n ${this.suffix ? html`<span class=\"affix\" part=\"suffix\">${this.suffix}</span>` : nothing}\n `;\n }\n\n static override styles = css`\n :host {\n --sliding-number-spin-duration: 0.7s;\n --sliding-number-spin-easing: cubic-bezier(0.16, 1, 0.3, 1);\n --sliding-number-transform-duration: 0.5s;\n --sliding-number-transform-easing: cubic-bezier(0.16, 1, 0.3, 1);\n --sliding-number-opacity-duration: 0.35s;\n --sliding-number-digit-width: 1ch;\n\n display: inline-flex;\n align-items: flex-end;\n line-height: 1;\n font-variant-numeric: tabular-nums;\n }\n\n .number,\n .run {\n display: inline-flex;\n /* Every cell is exactly 1em tall, so aligning bottom edges keeps\n every glyph on the same line without relying on synthesised\n flex baselines (which break under overflow: hidden). */\n align-items: flex-end;\n white-space: nowrap;\n }\n\n .affix {\n line-height: 1;\n }\n\n /* Integer digits stack right-to-left so the units column (next to the\n decimal point) stays put while higher places grow outward. */\n .run.integer {\n flex-direction: row-reverse;\n }\n\n .cell {\n display: block;\n height: 1em;\n line-height: 1;\n text-align: center;\n overflow: hidden;\n transition:\n width var(--sliding-number-transform-duration) var(--sliding-number-transform-easing),\n max-width var(--sliding-number-transform-duration) var(--sliding-number-transform-easing),\n opacity var(--sliding-number-opacity-duration) var(--sliding-number-transform-easing);\n }\n\n .cell.digit {\n position: relative;\n width: var(--sliding-number-digit-width);\n }\n\n .cell.symbol {\n max-width: 4ch;\n }\n\n .cell[data-phase='enter'],\n .cell[data-phase='leave'] {\n opacity: 0;\n }\n\n .cell.digit[data-phase='enter'],\n .cell.digit[data-phase='leave'] {\n width: 0;\n }\n\n .cell.symbol[data-phase='enter'],\n .cell.symbol[data-phase='leave'] {\n max-width: 0;\n }\n\n .reel {\n position: absolute;\n inset: 0 0 auto 0;\n display: flex;\n flex-direction: column;\n will-change: transform;\n transform: translateY(calc(-1em * var(--o, 10)));\n }\n\n .reel > span {\n display: block;\n height: 1em;\n line-height: 1;\n text-align: center;\n }\n\n :host([data-static]) .cell {\n transition: none;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-sliding-number': SlidingNumberElement;\n }\n}\n","import { css, html, LitElement } from \"lit\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n@customElement(`ixfx-tab-panel`)\nexport class TabPanelElement extends LitElement {\n render() {\n return html`<slot></slot>`;\n }\n\n static styles = [themeFallbacks, css`\n :host {\n display:none;\n height:100%;\n width:100%;\n }\n\n :host([selected]) {\n background: var(--surface-3);\n display:block;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-tab-panel\": TabPanelElement;\n }\n}\n","import type { CommandRegistry } from '@clinth/ui-commands';\nimport type { TabListItemElement } from './tab-list-item.js';\nimport type { TabListChangeDetail, TabListElement } from './tab-list.js';\nimport type { TabPanelElement } from './tab-panel.js';\nimport type { TabPanelsElement } from './tab-panels.js';\nimport './tab-list-item.js';\nimport './tab-panel.js';\n\n/** A single tab managed by a {@link TabController}. */\nexport type Tab = {\n /** id of the `ixfx-tab-list-item` */\n readonly id: string;\n /** id of the `ixfx-tab-panel` (the item's `for` value) */\n readonly forId: string;\n readonly item: TabListItemElement;\n readonly panel: TabPanelElement;\n label: string;\n iconName?: string;\n};\n\nexport type TabAddOptions = {\n label: string;\n /** id for the tab item; derived from the label if omitted */\n id?: string;\n /** id for the panel (and the item's `for`); derived from the label if omitted */\n forId?: string;\n iconName?: string;\n description?: string;\n closeable?: boolean;\n /** Elements to slot into the tab's `slot=\"toolbar\"` */\n toolbar?: HTMLElement[];\n /** Panel content: a node, text, or a callback given the fresh panel element */\n content?: Node | string | ((panel: TabPanelElement) => void);\n /** Select the new tab immediately (default `true`) */\n select?: boolean;\n /** Insertion index among existing tabs (default: append) */\n index?: number;\n};\n\nexport type TabControllerOptions = {\n /**\n * When provided, a command is registered per tab (id = tab id). Invoking\n * `commands.invoke(id)` selects the tab.\n */\n commands?: CommandRegistry;\n /** Fired after a tab becomes selected (via click or programmatic select) */\n onSelect?: (tab: Tab, previous: Tab | undefined) => void;\n onAdd?: (tab: Tab) => void;\n onRemove?: (tab: Tab) => void;\n onReorder?: (tabs: Tab[]) => void;\n};\n\n/**\n * Connects an `ixfx-tab-list` to an `ixfx-tab-panels` container, handling the\n * wiring between them (header clicks show the matching panel, closing a tab\n * removes its panel, etc.) and offering an API to select, add, remove, rename\n * and reorder tabs.\n *\n * @example\n * ```ts\n * const ctrl = new TabController(\n * document.querySelector('ixfx-tab-list'),\n * document.querySelector('ixfx-tab-panels'),\n * );\n * ctrl.connect();\n *\n * ctrl.addTab({ label: 'Console', content: 'Console panel' });\n * ctrl.selectTab('Console');\n * ```\n */\nexport class TabController {\n readonly #list: TabListElement;\n readonly #panels: TabPanelsElement;\n readonly #opts: TabControllerOptions;\n\n #tabs: Tab[] = [];\n #signal: AbortController | undefined;\n #observer: MutationObserver | undefined;\n #commands: CommandRegistry | undefined;\n #registeredCommands = new Set<string>();\n\n constructor(\n list: TabListElement,\n panels: TabPanelsElement,\n options: TabControllerOptions = {},\n ) {\n this.#list = list;\n this.#panels = panels;\n this.#opts = options;\n this.#commands = options.commands;\n }\n\n connect(): void {\n this.disconnect();\n this.#signal = new AbortController();\n const { signal } = this.#signal;\n\n this.#list.addEventListener(`change`, this.#onChange, { signal });\n this.#list.addEventListener(`reorder`, this.#onReorder, { signal });\n this.#list.addEventListener(`close`, this.#onClose, { signal });\n\n this.#observer = new MutationObserver(() => this.#rebuild());\n this.#observer.observe(this.#list, { childList: true });\n this.#observer.observe(this.#panels, { childList: true });\n\n this.#rebuild();\n\n // Establish the list↔panels association and mirror the initially-selected\n // header into the panels (its internal Promise-based initial sync).\n this.#panels.syncWithList(this.#list);\n\n for (const tab of this.#tabs) {\n this.#registerCommand(tab);\n }\n }\n\n disconnect(): void {\n this.#signal?.abort();\n this.#signal = undefined;\n this.#observer?.disconnect();\n this.#observer = undefined;\n\n for (const tab of this.#tabs) {\n this.#unregisterCommand(tab);\n }\n this.#registeredCommands.clear();\n this.#tabs = [];\n }\n\n // ── Selection ────────────────────────────────────────────────────────\n\n /**\n * Select a tab as if it was clicked — activates the header (deactivating the\n * others) and shows its panel.\n *\n * `sel` may be a tab id, the panel id its `for` points at, its label text\n * (case-insensitive), or the tab item element itself.\n *\n * Returns true if a tab was found.\n */\n selectTab(sel: string | TabListItemElement): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n const previous = this.getSelected();\n if (previous?.id === tab.id) {\n // Header already active — still ensure the content panel is shown.\n this.#panels.selectPanel(tab.forId);\n return true;\n }\n\n this.#list.selectElement(tab.item);\n this.#panels.selectPanel(tab.forId);\n this.#opts.onSelect?.(tab, previous);\n return true;\n }\n\n selectNext(): boolean {\n return this.#selectOffset(1);\n }\n\n selectPrevious(): boolean {\n return this.#selectOffset(-1);\n }\n\n getSelected(): Tab | undefined {\n return this.#tabs.find(t => t.item.hasAttribute(`selected`));\n }\n\n getTabs(): Tab[] {\n return [...this.#tabs];\n }\n\n getTab(id: string): Tab | undefined {\n return this.#tabs.find(t => t.id === id);\n }\n\n // ── Mutation ─────────────────────────────────────────────────────────\n\n addTab(opts: TabAddOptions): Tab {\n const { id, forId } = this.#idsFor(opts);\n\n const item = document.createElement(`ixfx-tab-list-item`) as TabListItemElement;\n item.id = id;\n item.setAttribute(`for`, forId);\n item.closeable = opts.closeable ?? true;\n item.append(opts.label);\n if (opts.iconName) {\n item.iconName = opts.iconName;\n }\n if (opts.description) {\n item.description = opts.description;\n }\n for (const el of opts.toolbar ?? []) {\n el.slot = `toolbar`;\n item.append(el);\n }\n\n const panel = document.createElement(`ixfx-tab-panel`) as TabPanelElement;\n panel.id = forId;\n if (opts.content !== undefined) {\n this.#fillContent(panel, opts.content);\n }\n\n const index = Math.max(0, Math.min(opts.index ?? this.#tabs.length, this.#tabs.length));\n this.#insertElement(this.#list, item, index);\n this.#insertElement(this.#panels, panel, index);\n\n const tab: Tab = {\n id,\n forId,\n item,\n panel,\n label: opts.label,\n iconName: opts.iconName,\n };\n this.#tabs.splice(index, 0, tab);\n\n this.#registerCommand(tab);\n this.#opts.onAdd?.(tab);\n\n if (opts.select ?? true) {\n this.selectTab(id);\n }\n return tab;\n }\n\n removeTab(sel: string | TabListItemElement): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n const index = this.#tabs.indexOf(tab);\n const wasSelected = tab.item.hasAttribute(`selected`);\n const adjacent = wasSelected ? this.#adjacentTab(index) : undefined;\n\n tab.item.remove();\n tab.panel.remove();\n this.#removeFromIndex(tab);\n this.#unregisterCommand(tab);\n this.#opts.onRemove?.(tab);\n\n if (adjacent) {\n this.selectTab(adjacent.id);\n }\n return true;\n }\n\n renameTab(sel: string | TabListItemElement, label: string): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n for (const child of [...tab.item.childNodes]) {\n const isToolbar = child.nodeType === Node.ELEMENT_NODE\n && (child as HTMLElement).slot === `toolbar`;\n if (isToolbar)\n continue;\n tab.item.removeChild(child);\n }\n tab.item.prepend(label);\n tab.label = label;\n\n this.#reregisterCommand(tab);\n return true;\n }\n\n setTabIcon(sel: string | TabListItemElement, iconName?: string): boolean {\n const tab = this.#resolveTab(sel);\n if (!tab)\n return false;\n\n if (iconName) {\n tab.item.iconName = iconName;\n tab.iconName = iconName;\n } else {\n tab.item.iconName = undefined;\n tab.item.removeAttribute(`icon-name`);\n tab.iconName = undefined;\n }\n return true;\n }\n\n // ── Event handlers ───────────────────────────────────────────────────\n\n #onChange = (event: Event): void => {\n const detail = (event as CustomEvent<TabListChangeDetail>).detail;\n this.#panels.selectPanel(detail.for);\n\n const tab = this.#tabs.find(t => t.forId === detail.for);\n if (!tab)\n return;\n const previous = detail.previous\n ? this.#tabs.find(t => t.id === detail.previous)\n : undefined;\n this.#opts.onSelect?.(tab, previous);\n };\n\n #onReorder = (): void => {\n this.#rebuild();\n this.#opts.onReorder?.(this.#tabs);\n };\n\n #onClose = (event: Event): void => {\n const target = event.target as HTMLElement | null;\n const item = target?.closest(`ixfx-tab-list-item`) as TabListItemElement | null;\n const tab = item ? this.#tabByItem(item) : undefined;\n if (!tab)\n return;\n\n const index = this.#tabs.indexOf(tab);\n const wasSelected = tab.item.hasAttribute(`selected`);\n const adjacent = wasSelected ? this.#adjacentTab(index) : undefined;\n\n // The item removed itself (tab-list-item close handler); remove the panel\n // and drop the tab from the index.\n tab.panel.remove();\n this.#removeFromIndex(tab);\n this.#unregisterCommand(tab);\n this.#opts.onRemove?.(tab);\n\n if (adjacent) {\n this.selectTab(adjacent.id);\n }\n };\n\n // ── Internal helpers ─────────────────────────────────────────────────\n\n #selectOffset(offset: number): boolean {\n const tabs = this.#tabs;\n if (tabs.length === 0)\n return false;\n const current = this.getSelected();\n const index = current ? tabs.indexOf(current) : offset === 1 ? -1 : 0;\n const next = (index + offset + tabs.length) % tabs.length;\n return this.selectTab(tabs[next].id);\n }\n\n #resolveTab(sel: string | TabListItemElement): Tab | undefined {\n if (typeof sel !== `string`) {\n return this.#tabs.find(t => t.item === sel);\n }\n const label = sel.trim().toLowerCase();\n return this.#tabs.find(t => t.id === sel)\n ?? this.#tabs.find(t => t.forId === sel)\n ?? this.#tabs.find(t => t.label.toLowerCase() === label);\n }\n\n #tabByItem(item: TabListItemElement): Tab | undefined {\n return this.#tabs.find(t => t.item === item);\n }\n\n #adjacentTab(index: number): Tab | undefined {\n const tabs = this.#tabs;\n if (tabs.length <= 1)\n return undefined;\n return tabs[index + 1] ?? tabs[index - 1];\n }\n\n #removeFromIndex(tab: Tab): void {\n const index = this.#tabs.indexOf(tab);\n if (index >= 0) {\n this.#tabs.splice(index, 1);\n }\n }\n\n #idsFor(opts: TabAddOptions): { id: string; forId: string } {\n const base = this.#slug(opts.label) || `tab`;\n return {\n id: opts.id ?? this.#uniqueId(`tab-${base}`),\n forId: opts.forId ?? this.#uniqueId(`panel-${base}`),\n };\n }\n\n #slug(value: string): string {\n return value.toLowerCase()\n .replace(/[^a-z0-9]+/g, `-`)\n .replace(/^-+|-+$/g, ``);\n }\n\n #uniqueId(base: string): string {\n let candidate = base;\n let n = 2;\n while (document.getElementById(candidate)) {\n candidate = `${base}-${n++}`;\n }\n return candidate;\n }\n\n #fillContent(panel: TabPanelElement, content: Node | string | ((panel: TabPanelElement) => void)): void {\n if (typeof content === `function`) {\n content(panel);\n return;\n }\n if (typeof content === `string`) {\n panel.append(document.createTextNode(content));\n return;\n }\n panel.append(content);\n }\n\n #insertElement(container: HTMLElement, el: HTMLElement, index: number): void {\n const children = Array.from(container.children);\n container.insertBefore(el, children[index] ?? null);\n }\n\n #rebuild(): void {\n const panels = new Map<string, TabPanelElement>();\n for (const el of this.#panels.querySelectorAll(`ixfx-tab-panel`)) {\n panels.set(el.id, el as TabPanelElement);\n }\n\n const tabs: Tab[] = [];\n for (const item of this.#list.querySelectorAll(`ixfx-tab-list-item`) as NodeListOf<TabListItemElement>) {\n const forId = item.getAttribute(`for`) ?? ``;\n const panel = panels.get(forId);\n if (!panel)\n continue;\n tabs.push({\n id: item.id || forId,\n forId,\n item,\n panel,\n label: this.#labelOf(item),\n iconName: item.iconName,\n });\n }\n this.#tabs = tabs;\n }\n\n /** The tab's visible label text, excluding any `slot=\"toolbar\"` content. */\n #labelOf(item: TabListItemElement): string {\n const clone = item.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(`[slot=\"toolbar\"]`).forEach(el => el.remove());\n return (clone.textContent ?? ``).trim();\n }\n\n #registerCommand(tab: Tab): void {\n if (!this.#commands)\n return;\n if (tab.item.commandActive)\n return;\n if (this.#commands.has(tab.id))\n return;\n this.#commands.register({\n id: tab.id,\n label: tab.label,\n description: tab.item.description ?? tab.label,\n icon: tab.iconName,\n execute: () => {\n this.selectTab(tab.id);\n },\n });\n this.#registeredCommands.add(tab.id);\n }\n\n #unregisterCommand(tab: Tab): void {\n if (!this.#commands)\n return;\n if (this.#registeredCommands.has(tab.id)) {\n this.#commands.unregister(tab.id);\n this.#registeredCommands.delete(tab.id);\n }\n }\n\n #reregisterCommand(tab: Tab): void {\n if (!this.#commands || !this.#registeredCommands.has(tab.id))\n return;\n const existing = this.#commands.get(tab.id);\n if (!existing)\n return;\n this.#commands.unregister(tab.id);\n this.#commands.register({ ...existing, label: tab.label });\n }\n}\n","import type { TabListItemElement } from \"./tab-list-item.js\";\nimport type { TabListElement } from \"./tab-list.js\";\nimport type { TabPanelElement } from \"./tab-panel.js\";\nimport { css, html, LitElement } from \"lit\";\nimport { queryAssignedElements } from \"lit/decorators.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n@customElement(`ixfx-tab-panels`)\nexport class TabPanelsElement extends LitElement {\n @queryAssignedElements()\n _listItems!: TabPanelElement[];\n\n /**\n * The `ixfx-tab-list` this panels element is associated with, established by\n * `syncWithList()`. Used by `selectTab()` to activate the matching header.\n */\n #list: TabListElement | undefined;\n\n /**\n * Triggered when a panel is being de-selected\n */\n onUnselectedPanel?: (id: string, el: TabPanelElement) => void;\n /**\n * Triggered before panel is selected\n */\n onSelectingPanel?: (id: string, el: TabPanelElement) => void;\n /**\n * Triggered after panel is selected\n */\n onSelectedPanel?: (id: string, el: TabPanelElement) => void;\n render() {\n return html`<slot></slot>`;\n }\n\n getSelectedElement() {\n for (const el of this._listItems) {\n if (this.#isSelected(el))\n return el;\n }\n }\n\n #isSelected(el: TabPanelElement) {\n // const v = el.getAttribute(`selected`);\n // console.log(`id: ${ el.id } v: ${ v }`);\n return el.hasAttribute(`selected`);\n }\n\n #unselect(el: TabPanelElement) {\n el.removeAttribute(`selected`);\n if (this.onUnselectedPanel) {\n this.onUnselectedPanel(el.id, el);\n }\n }\n\n #select(el: TabPanelElement) {\n if (this.onSelectingPanel) {\n this.onSelectingPanel(el.id, el);\n }\n el.setAttribute(`selected`, ``);\n if (this.onSelectedPanel) {\n this.onSelectedPanel(el.id, el);\n }\n }\n\n syncWithList(el: TabListElement) {\n this.#list = el;\n const doSync = () => {\n const t = el.getSelectedElement();\n if (!t)\n return;\n const forEl = t.getAttribute(`for`);\n if (forEl)\n this.selectPanel(forEl);\n };\n // Wait for both the list and ourselves to be fully rendered\n // so that getSelectedElement() and _listItems both work.\n Promise.all([el.updateComplete, this.updateComplete]).then(doSync);\n }\n\n selectPanel(id: string) {\n const current = this.getSelectedElement();\n if (current) {\n if (current.id === id)\n return;\n this.#unselect(current);\n }\n\n let found = false;\n for (const el of this._listItems) {\n if (el.id === id) {\n this.#select(el);\n found = true;\n }\n }\n return found;\n }\n\n /**\n * Select a tab as if the user clicked it — activates the matching header in\n * the associated `ixfx-tab-list` (deactivating the others) and shows its\n * panel.\n *\n * `nameOrTitle` may be the label text of a tab (e.g. `'Home'`, matched\n * case-insensitively) or the panel id its `for` attribute points at\n * (e.g. `'panel-home'`). If no tab matches, `nameOrTitle` is tried directly\n * as a panel id.\n *\n * The tab list must first be associated via `syncWithList()` for the header\n * to be activated; panel selection works regardless.\n *\n * Returns true if a panel was found and selected.\n */\n selectTab(nameOrTitle: string): boolean {\n const item = this.#findTabItem(nameOrTitle);\n if (item) {\n this.#list?.selectElement(item);\n return this.selectPanel(item.getAttribute(`for`) ?? ``) === true;\n }\n // Fall back to treating the value as a panel id directly.\n return this.selectPanel(nameOrTitle) === true;\n }\n\n #findTabItem(nameOrTitle: string): TabListItemElement | undefined {\n const list = this.#list;\n if (!list)\n return undefined;\n const items = Array.from(list.querySelectorAll(`ixfx-tab-list-item`)) as TabListItemElement[];\n\n // Prefer an exact match against the `for` attribute (panel id).\n for (const item of items) {\n if (item.getAttribute(`for`) === nameOrTitle)\n return item;\n }\n\n // Otherwise match on the tab's label text, case-insensitively.\n const label = nameOrTitle.trim().toLowerCase();\n for (const item of items) {\n if (this.#labelOf(item).toLowerCase() === label)\n return item;\n }\n return undefined;\n }\n\n /** The tab's visible label text, excluding any `slot=\"toolbar\"` content. */\n #labelOf(item: TabListItemElement): string {\n const clone = item.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(`[slot=\"toolbar\"]`).forEach(el => el.remove());\n return (clone.textContent ?? ``).trim();\n }\n\n static styles = css`\n :host {\n display: block;\n }\n \n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-tab-panels\": TabPanelsElement;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n/**\n * `ixfx-text-shimmer` — a label whose text is dimmed at rest, with a band of\n * brighter colour that sweeps horizontally across it on a loop. Useful as a\n * lightweight \"still working…\" indicator (as seen in Claude Code / Codex).\n *\n * Content comes from the `text` property, or failing that the default slot:\n * ```html\n * <ixfx-text-shimmer text=\"Thinking…\"></ixfx-text-shimmer>\n * <ixfx-text-shimmer>Reticulating splines…</ixfx-text-shimmer>\n * ```\n *\n * CSS variables (set on the element or an ancestor):\n * | Variable | Default | Purpose |\n * |---|---|---|\n * | `--text-shimmer-color` | `var(--surface-3-text)` | Resting / base text colour |\n * | `--text-shimmer-gradient-color` | `var(--surface-2-text)` | Colour of the moving highlight |\n * | `--text-shimmer-duration` | `2s` | Time for one sweep |\n * | `--text-shimmer-spread` | `15%` | Half-width of the highlight band along the sweep track (larger = wider, softer) |\n *\n * Add the `paused` attribute to stop the sweep and show flat base colour.\n * Respects `prefers-reduced-motion`.\n */\n@customElement(`ixfx-text-shimmer`)\nexport class TextShimmerElement extends LitElement {\n /** Text to display. When empty, the default slot is used instead. */\n @property({ type: String }) text = ``;\n\n /** When set, the sweep stops and the text shows flat base colour. */\n @property({ type: Boolean, reflect: true }) paused = false;\n\n protected override render() {\n return html`<span class=\"shimmer\" part=\"text\"\n >${this.text === `` ? html`<slot></slot>` : this.text}</span\n >`;\n }\n\n static override styles = css`\n :host {\n --text-shimmer-color: var(--surface-3-text, #888);\n --text-shimmer-gradient-color: var(--surface-2-text, #fff);\n --text-shimmer-duration: 2s;\n --text-shimmer-spread: 15%;\n\n display: inline-block;\n color: var(--text-shimmer-color);\n }\n\n .shimmer {\n background-image: linear-gradient(\n 90deg,\n var(--text-shimmer-color) 0%,\n var(--text-shimmer-color) calc(50% - var(--text-shimmer-spread)),\n var(--text-shimmer-gradient-color) 50%,\n var(--text-shimmer-color) calc(50% + var(--text-shimmer-spread)),\n var(--text-shimmer-color) 100%\n );\n background-size: 250% 100%;\n background-repeat: no-repeat;\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n -webkit-text-fill-color: transparent;\n animation: ixfx-text-shimmer-sweep var(--text-shimmer-duration) linear infinite;\n }\n\n /* Sweep the highlight band from the right edge to the left edge. */\n @keyframes ixfx-text-shimmer-sweep {\n from {\n background-position: 100% center;\n }\n to {\n background-position: 0% center;\n }\n }\n\n :host([paused]) .shimmer {\n animation: none;\n background-image: none;\n color: var(--text-shimmer-color);\n -webkit-text-fill-color: var(--text-shimmer-color);\n }\n\n @media (prefers-reduced-motion: reduce) {\n .shimmer {\n animation: none;\n background-image: none;\n color: var(--text-shimmer-color);\n -webkit-text-fill-color: var(--text-shimmer-color);\n }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-text-shimmer': TextShimmerElement;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { handleStyles } from '../styles/handle.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n@customElement(`ixfx-toolbar-group`)\nexport class ToolbarGroupElement extends LitElement {\n @property({ type: String }) label = ``;\n @property({ type: Boolean, reflect: true }) grow = false;\n /**\n * Set by the parent `ixfx-toolbar` when `allow-reorder` is present.\n * Shows the vertical grab handle; drag starts from the handle only.\n */\n @property({ type: Boolean, reflect: true }) reorderable = false;\n\n static override styles = [themeFallbacks, handleStyles, css`\n :host {\n display: flex;\n flex-direction: column;\n align-items: var(--toolbar-group-align-items, center);\n justify-content: var(--toolbar-group-justify-content, flex-start);\n gap: var(--toolbar-gap, var(--space-s));\n padding: var(--toolbar-group-padding, var(--space-xs));\n border: 1px solid var(--border-subtle, var(--border));\n border-radius: var(--radius-s);\n background: var(--surface-3);\n min-width: 0;\n }\n :host([reorderable]) {\n flex-direction: row;\n align-items: center;\n }\n :host(:not([label])) {\n border: none;\n background: transparent;\n padding: 0;\n }\n .grab-handle {\n display: none;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n padding-inline: var(--space-2xs, 2px);\n cursor: grab;\n touch-action: none;\n flex: 0 0 auto;\n }\n :host([reorderable]) .grab-handle { display: inline-flex; }\n :host([reorderable]) .grab-handle .ixfx-handle {\n --ixfx-handle-length: 18px;\n }\n :host([drag-source]) .grab-handle { cursor: grabbing; }\n :host([drag-source]) .grab-handle .ixfx-handle {\n color: var(--accent);\n opacity: 1;\n }\n .body {\n display: flex;\n flex-direction: column;\n align-items: var(--toolbar-group-align-items, center);\n justify-content: var(--toolbar-group-justify-content, flex-start);\n gap: var(--toolbar-gap, var(--space-s));\n min-width: 0;\n flex: 1 1 auto;\n }\n .label-row {\n display: none;\n font-size: var(--text-s, 12px);\n color: var(--surface-muted-text);\n padding-inline: var(--space-xs);\n white-space: nowrap;\n border-bottom: 1px solid var(--border-subtle);\n margin-bottom: var(--space-xs);\n }\n :host([label][show-label]) .label-row { display: block; }\n :host(:not([label])) .label-row { display: none; }\n :host([grow]) { flex: 1 1 auto; min-width: 0; }\n :host([hidden]) { display: none !important; }\n .components { display: flex; }\n ::slotted(*) { flex: 0 0 auto; }\n ::slotted([grow]) { flex: 1 1 auto; }\n `];\n\n protected override render() {\n return html`\n <div class=\"grab-handle\" part=\"grab-handle\" title=\"Drag to reorder\" aria-hidden=\"true\">\n <span class=\"ixfx-handle\" data-handle=\"dotted\" data-shape=\"vertical\"></span>\n </div>\n <div class=\"body\">\n <div class=\"label-row\">${this.label}</div>\n <div class=\"components\">\n <slot></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap { 'ixfx-toolbar-group': ToolbarGroupElement }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { DragGhost } from '../util/drag-ghost.js';\nimport type { ToolbarGroupElement } from './toolbar-group.js';\nimport type { ToolbarAlign, ToolbarLayout, ToolbarOrientation, ToolbarVerticalWriting } from './types.js';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { popupSurfaceStyles } from '../styles/popup.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { createDragGhost } from '../util/drag-ghost.js';\n\nexport interface ToolbarGroupReorderDetail {\n readonly fromIndex: number;\n readonly toIndex: number;\n readonly group: ToolbarGroupElement;\n}\n\nexport type ToolbarGroupReorderEvent = CustomEvent<ToolbarGroupReorderDetail>;\n\nexport interface ToolbarElementEventMap {\n reorder: ToolbarGroupReorderEvent;\n}\n\n/**\n * JSON-safe snapshot of toolbar group order, suitable for `localStorage`\n * or any other user-preference store. See `getLayoutSnapshot` /\n * `applyLayoutSnapshot`.\n */\nexport interface ToolbarLayoutSnapshot {\n readonly version: 1;\n readonly order: readonly string[];\n}\n\n/** Pointer movement threshold (px) before a press becomes a drag. */\nconst DRAG_THRESHOLD_PX = 5;\n\n/**\n * Pure helper: nearest gap index for a pointer position along one axis.\n * `edges` are the [start, end] of each sibling (excluding the drag source),\n * in visual order. Returns 0..edges.length.\n */\nexport function toolbarGapIndex(edges: ReadonlyArray<readonly [number, number]>, pos: number): number {\n let bestGap = 0;\n let bestDist = Number.POSITIVE_INFINITY;\n for (let i = 0; i < edges.length; i++) {\n const [start, end] = edges[i];\n const mid = (start + end) / 2;\n if (pos < mid) {\n const d = Math.abs(pos - start);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i;\n }\n } else {\n const d = Math.abs(pos - end);\n if (d < bestDist) {\n bestDist = d;\n bestGap = i + 1;\n }\n }\n }\n return bestGap;\n}\n\nlet toolbarGhostStylesInjected = false;\n\n/**\n * Global ghost styling so the drag preview matches toolbar-group chrome.\n * Injected once; the ghost lives outside shadow DOM so component styles\n * cannot reach it.\n */\nfunction injectToolbarGhostStyles(): void {\n if (toolbarGhostStylesInjected) {\n return;\n }\n toolbarGhostStylesInjected = true;\n const style = document.createElement(`style`);\n style.textContent = `\n .ixfx-drag-ghost.ixfx-toolbar-group-ghost {\n padding: var(--space-s, 8px) var(--space-m, 16px);\n background: var(--surface-4);\n color: var(--surface-3-text);\n border: none;\n border-radius: var(--radius-s, 4px);\n font-family: var(--font-family);\n font-size: var(--text-m);\n font-weight: var(--font-weight-bold, 600);\n user-select: none;\n -webkit-user-select: none;\n }\n `;\n document.head.appendChild(style);\n}\n\n@customElement(`ixfx-toolbar`)\nexport class ToolbarElement extends LitElement {\n @property({ type: String, reflect: true }) orientation: ToolbarOrientation = `horizontal`;\n @property({ type: String, reflect: true }) layout: ToolbarLayout = `one-line`;\n @property({ type: String, attribute: `vertical-writing`, reflect: true }) verticalWriting: ToolbarVerticalWriting = `auto`;\n @property({ type: String, attribute: `toolbar-align`, reflect: true }) toolbarAlign: ToolbarAlign = `near`;\n @property({ type: Boolean, attribute: `show-group-labels`, reflect: true }) showGroupLabels = false;\n @property({ type: Boolean, attribute: `invisible-groups`, reflect: true }) invisibleGroups = false;\n @property({ type: Boolean, attribute: `allow-reorder`, reflect: true }) allowReorder = false;\n\n @state() private _overflowCount = 0;\n @state() private _popoverOpen = false;\n private _ro: ResizeObserver | null = null;\n private static _cnt = 0;\n private _anchor = `--toolbar-${ToolbarElement._cnt++}`;\n /** Natural size of items, captured while they are measurable in the main slot. */\n private _sizes = new WeakMap<HTMLElement, number>();\n private _measureQueued = false;\n\n private _dragState: {\n pointerId: number;\n source: ToolbarGroupElement;\n startX: number;\n startY: number;\n active: boolean;\n ghost: DragGhost | null;\n gapIndex: number | undefined;\n } | null = null;\n\n private _suppressNextClick = false;\n\n @query(`.inner`) private _inner!: HTMLElement;\n @query(`.overflow-popover`) private _popover!: HTMLElement;\n @query(`slot`) private _slot!: HTMLSlotElement;\n\n static override styles = [themeFallbacks, popupSurfaceStyles, css`\n :host {\n --toolbar-gap: var(--space-s);\n --toolbar-group-gap: var(--space-m);\n --toolbar-overflow: auto;\n display: block;\n position: relative;\n container-type: inline-size;\n }\n :host([orientation=\"vertical-left\"]),\n :host([orientation=\"vertical-right\"]) {\n container-type: normal;\n width: max-content;\n }\n :host([orientation=\"vertical-left\"]),\n :host([orientation=\"vertical-right\"]) { height: 100%; }\n :host([orientation=\"vertical-left\"]) .inner,\n :host([orientation=\"vertical-right\"]) .inner { height: 100%; box-sizing: border-box; width: max-content; }\n .inner {\n display: flex;\n gap: var(--toolbar-gap);\n background: var(--toolbar-bg, var(--surface-2));\n padding: var(--toolbar-padding, var(--space-s));\n border: var(--toolbar-border, var(--border-subtle));\n border-radius: var(--radius-s);\n align-items: center;\n }\n :host([orientation=\"horizontal\"]) .inner { flex-direction: row; justify-content: flex-start; }\n :host([orientation=\"vertical-left\"]) .inner { flex-direction: column-reverse; align-items: stretch; }\n :host([orientation=\"vertical-right\"]) .inner { flex-direction: column; align-items: stretch; }\n :host([layout=\"wrap\"]) .inner { flex-wrap: wrap; }\n :host([layout=\"one-line\"]) .inner { flex-wrap: nowrap; overflow: hidden; }\n :host([toolbar-align=\"far\"][orientation=\"horizontal\"]) .inner { justify-content: flex-end; }\n :host([orientation=\"vertical-left\"][vertical-writing=\"auto\"]) ::slotted(*) { writing-mode: sideways-lr; }\n :host([orientation=\"vertical-right\"][vertical-writing=\"auto\"]) ::slotted(*) { writing-mode: vertical-lr; }\n :host([vertical-writing=\"up\"]) ::slotted(*) { writing-mode: vertical-rl; text-orientation: upright; }\n :host([vertical-writing=\"down\"]) ::slotted(*) { writing-mode: vertical-lr; }\n :host([vertical-writing=\"none\"]) ::slotted(*) { writing-mode: horizontal-tb; }\n ::slotted(*) { flex: 0 0 auto; }\n ::slotted([grow]), ::slotted(ixfx-toolbar-group[grow]) { flex: 1 1 auto; }\n ::slotted([hidden]) { display: none !important; }\n :host([invisible-groups]) ::slotted(ixfx-toolbar-group) { --toolbar-group-border: none; }\n .overflow-btn {\n anchor-name: var(--anchor-name);\n flex-shrink: 0;\n }\n .overflow-btn[hidden] { display: none; }\n .overflow-popover {\n position: fixed;\n inset: auto;\n margin: 0;\n position-anchor: var(--anchor-name);\n position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;\n position-visibility: anchors-visible;\n max-height: min(60vh, 400px);\n max-width: min(90vw, 320px);\n overflow: auto;\n overscroll-behavior: contain;\n z-index: 100;\n padding: var(--space-s);\n flex-direction: column;\n gap: var(--space-s);\n }\n :host([orientation=\"horizontal\"]) .overflow-popover {\n position-area: bottom span-left;\n margin-top: var(--toolbar-overflow-gap, 8px);\n }\n :host([orientation=\"vertical-left\"]) .overflow-popover {\n position-area: right span-bottom;\n margin-left: var(--toolbar-overflow-gap, 8px);\n }\n :host([orientation=\"vertical-right\"]) .overflow-popover {\n position-area: left span-bottom;\n margin-right: var(--toolbar-overflow-gap, 8px);\n }\n .overflow-popover:popover-open { display: flex; }\n .overflow-popover ::slotted(*) { writing-mode: horizontal-tb; text-orientation: mixed; }\n\n :host([allow-reorder]) ::slotted(ixfx-toolbar-group[drag-source]) {\n opacity: 0.4;\n }\n\n /* While dragging, suppress text selection inside the toolbar. */\n :host([dragging]),\n :host([dragging]) ::slotted(*) {\n user-select: none;\n -webkit-user-select: none;\n }\n\n .drop-caret {\n position: absolute;\n top: 0;\n left: 0;\n background: var(--accent);\n border-radius: 1px;\n pointer-events: none;\n z-index: 1;\n }\n `];\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.style.setProperty(`--anchor-name`, this._anchor);\n // Capture phase so we can swallow the trailing click after a real reorder\n // before it reaches buttons inside the dragged group.\n this.addEventListener(`click`, this._onClickCapture, true);\n }\n\n protected override firstUpdated(): void {\n this._slot.addEventListener(`slotchange`, () => {\n this._updateGroups();\n this._scheduleMeasure();\n });\n this._ro = new ResizeObserver(() => this._scheduleMeasure());\n this._ro.observe(this._inner);\n this._popover.addEventListener(`toggle`, () => {\n this._popoverOpen = this._popover.matches(`:popover-open`);\n });\n this._scheduleMeasure();\n this._updateGroups();\n }\n\n protected override updated(changed: Map<string, unknown>): void {\n if (changed.has(`showGroupLabels`) || changed.has(`allowReorder`))\n this._updateGroups();\n }\n\n /** Groups in the main slot (not overflow) that can participate in reorder. */\n private _mainGroups(): ToolbarGroupElement[] {\n return (Array.from(this.children) as HTMLElement[]).filter(\n el => el.tagName === `IXFX-TOOLBAR-GROUP` && el.getAttribute(`slot`) !== `overflow`,\n ) as ToolbarGroupElement[];\n }\n\n // ── Public API: group order + layout snapshots ─────────────────────────\n\n /**\n * Stable key identifying a group across save/restore: its `id`, falling\n * back to `label`. Groups with neither get an empty key, which still\n * round-trips as long as the set of groups is unchanged. Give groups a\n * unique `id` for reliable preference persistence.\n */\n private _groupKey(group: ToolbarGroupElement): string {\n return group.id || group.label || ``;\n }\n\n /** Keys of the main-slot groups in current DOM order. */\n getGroupOrder(): string[] {\n return this._mainGroups().map(group => this._groupKey(group));\n }\n\n /**\n * Reorder main-slot groups to match `order` (keys as returned by\n * `getGroupOrder`). Unknown keys are ignored; groups not mentioned keep\n * their relative order at the end. Each moved group fires a `reorder`\n * event, exactly as if dragged.\n */\n setGroupOrder(order: readonly string[]): void {\n const groups = this._mainGroups();\n if (groups.length === 0)\n return;\n const used = new Set<ToolbarGroupElement>();\n const desired: ToolbarGroupElement[] = [];\n for (const key of order) {\n const match = groups.find(candidate => !used.has(candidate) && candidate.id === key && key !== ``)\n ?? groups.find(candidate => !used.has(candidate) && this._groupKey(candidate) === key);\n if (match) {\n used.add(match);\n desired.push(match);\n }\n }\n const sequence = [...desired, ...groups.filter(group => !used.has(group))];\n // Pairwise bubble passes until every adjacent pair is in DOM order.\n // Guarded — each pass with a move strictly reduces disorder, and a\n // quiet pass means convergence.\n let guard = sequence.length * sequence.length + 1;\n let moved = true;\n while (moved && guard-- > 0) {\n moved = false;\n for (let i = 0; i + 1 < sequence.length; i++) {\n const before = sequence[i];\n const after = sequence[i + 1];\n if (before.compareDocumentPosition(after) & Node.DOCUMENT_POSITION_FOLLOWING)\n continue;\n if (this._insertAndEmit(before, after))\n moved = true;\n }\n }\n }\n\n /**\n * Capture the current group order as a JSON-safe snapshot for preference\n * stores: `localStorage.setItem(key, JSON.stringify(toolbar.getLayoutSnapshot()))`.\n */\n getLayoutSnapshot(): ToolbarLayoutSnapshot {\n return { version: 1, order: this.getGroupOrder() };\n }\n\n /**\n * Restore a snapshot from `getLayoutSnapshot` (e.g. parsed from\n * `localStorage`). Unknown keys are ignored. Returns `false` when the\n * value is not a valid snapshot, leaving the toolbar untouched.\n */\n applyLayoutSnapshot(snapshot: unknown): boolean {\n if (typeof snapshot !== `object` || snapshot === null)\n return false;\n const { version, order } = snapshot as { version?: unknown; order?: unknown };\n if (version !== 1 || !Array.isArray(order) || !order.every((key: unknown) => typeof key === `string`))\n return false;\n this.setGroupOrder(order as string[]);\n return true;\n }\n\n /**\n * Move `source` before `ref` (or append when `ref` is null), firing a\n * `reorder` event when the position actually changed. Returns whether a\n * move happened. Indices are measured against all light-DOM children,\n * matching the `reorder` detail of drag-reorder.\n */\n private _insertAndEmit(source: ToolbarGroupElement, ref: Node | null): boolean {\n const parent = source.parentNode;\n if (!parent)\n return false;\n const fromIndex = Array.prototype.indexOf.call(parent.children, source);\n parent.insertBefore(source, ref);\n const toIndex = Array.prototype.indexOf.call(parent.children, source);\n if (toIndex === fromIndex)\n return false;\n this.dispatchEvent(new CustomEvent<ToolbarGroupReorderDetail>(`reorder`, {\n bubbles: true,\n composed: true,\n detail: { fromIndex, toIndex, group: source },\n }));\n // Order changed: group markers and overflow sizes depend on DOM order.\n this._updateGroups();\n this._scheduleMeasure();\n return true;\n }\n\n private _updateGroups(): void {\n for (const child of Array.from(this.children) as HTMLElement[]) {\n if (child.tagName !== `IXFX-TOOLBAR-GROUP`)\n continue;\n if (this.showGroupLabels) {\n child.setAttribute(`show-label`, ``);\n } else {\n child.removeAttribute(`show-label`);\n }\n if (this.allowReorder && child.getAttribute(`slot`) !== `overflow`) {\n child.setAttribute(`reorderable`, ``);\n } else {\n child.removeAttribute(`reorderable`);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`click`, this._onClickCapture, true);\n this._ro?.disconnect();\n if (this._dragState) {\n this._abortDrag();\n this._endDrag(this._dragState.pointerId);\n }\n }\n\n private _onClickCapture = (event: Event): void => {\n if (!this._suppressNextClick)\n return;\n this._suppressNextClick = false;\n event.preventDefault();\n event.stopPropagation();\n };\n\n private _onKeyDown = (event: KeyboardEvent): void => {\n const state = this._dragState;\n if (event.key !== `Escape` || !state?.active)\n return;\n event.preventDefault();\n const pointerId = state.pointerId;\n this._abortDrag();\n this._endDrag(pointerId);\n };\n\n /**\n * Walk composedPath for the nearest ixfx-toolbar-group, requiring the press\n * to have gone through its `.grab-handle`. Drag is handle-only so every\n * control inside the group (buttons, selects, inputs) keeps working.\n */\n private _findDragTarget(event: PointerEvent): ToolbarGroupElement | null {\n if (!this.allowReorder)\n return null;\n const path = event.composedPath();\n let group: ToolbarGroupElement | null = null;\n let viaHandle = false;\n for (const node of path) {\n if (!(node instanceof HTMLElement))\n continue;\n if (node.classList.contains(`grab-handle`))\n viaHandle = true;\n if (!group && node.tagName === `IXFX-TOOLBAR-GROUP`)\n group = node as ToolbarGroupElement;\n }\n if (!group || !viaHandle)\n return null;\n if (group.getAttribute(`slot`) === `overflow`)\n return null;\n return group;\n }\n\n private _onPointerDown = (event: PointerEvent): void => {\n if (!this.allowReorder || event.button !== 0)\n return;\n const target = this._findDragTarget(event);\n if (!target?.parentNode)\n return;\n if (Array.prototype.indexOf.call(target.parentNode.children, target) < 0)\n return;\n // Don't capture yet — capturing on pointerdown would redirect the trailing\n // click to the capture target and break the normal button press.\n // Capture only once the drag activates.\n this._dragState = {\n pointerId: event.pointerId,\n source: target,\n startX: event.clientX,\n startY: event.clientY,\n active: false,\n ghost: null,\n gapIndex: undefined,\n };\n window.addEventListener(`pointermove`, this._onPointerMove);\n window.addEventListener(`pointerup`, this._onPointerUp);\n window.addEventListener(`pointercancel`, this._onPointerCancel);\n };\n\n private _onPointerMove = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId)\n return;\n const distance = Math.hypot(event.clientX - state.startX, event.clientY - state.startY);\n if (!state.active) {\n if (distance < DRAG_THRESHOLD_PX)\n return;\n this._beginDrag(event);\n }\n state.ghost?.move(event.clientX, event.clientY);\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n if (gap !== state.gapIndex) {\n state.gapIndex = gap;\n this.requestUpdate();\n }\n };\n\n private _onPointerUp = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId)\n return;\n if (state.active) {\n const gap = this._computeGapIndex(event.clientX, event.clientY);\n this._commitDrag(state.source, gap);\n }\n this._endDrag(event.pointerId);\n };\n\n private _onPointerCancel = (event: PointerEvent): void => {\n const state = this._dragState;\n if (!state || event.pointerId !== state.pointerId)\n return;\n this._abortDrag();\n this._endDrag(event.pointerId);\n };\n\n private _beginDrag(event: PointerEvent): void {\n const state = this._dragState;\n if (!state || state.active)\n return;\n try {\n this.setPointerCapture(event.pointerId);\n } catch {\n // Fall through — window listeners still catch move/up.\n }\n state.active = true;\n // `dragging` kills text selection for the gesture (see styles).\n this.setAttribute(`dragging`, ``);\n state.source.setAttribute(`drag-source`, ``);\n state.ghost = this._createGhost(state.source);\n state.ghost?.move(event.clientX, event.clientY);\n }\n\n private _abortDrag(): void {\n const state = this._dragState;\n if (!state)\n return;\n state.source.removeAttribute(`drag-source`);\n if (state.gapIndex !== undefined) {\n state.gapIndex = undefined;\n this.requestUpdate();\n }\n }\n\n private _endDrag(pointerId: number): void {\n const state = this._dragState;\n if (!state)\n return;\n state.ghost?.destroy();\n state.ghost = null;\n this.removeAttribute(`dragging`);\n this._dragState = null;\n window.removeEventListener(`pointermove`, this._onPointerMove);\n window.removeEventListener(`pointerup`, this._onPointerUp);\n window.removeEventListener(`pointercancel`, this._onPointerCancel);\n try {\n this.releasePointerCapture(pointerId);\n } catch { /* already released */ }\n this.requestUpdate();\n }\n\n private _commitDrag(source: ToolbarGroupElement, gapIndex: number | undefined): void {\n source.removeAttribute(`drag-source`);\n // Gap is an index into the visual order of the without-source groups.\n // `vertical-left` lays out as column-reverse, so visual order is the\n // reverse of DOM order — map the visual gap back to a DOM reference.\n const domSiblings = this._mainGroups().filter(el => el !== source);\n const n = domSiblings.length;\n const visualGap = gapIndex === undefined\n ? n\n : Math.max(0, Math.min(gapIndex, n));\n // DOM insertion index that yields visual position `visualGap`.\n const domIndex = this.orientation === `vertical-left` ? n - visualGap : visualGap;\n const parent = source.parentNode;\n if (!parent)\n return;\n const ref = domSiblings[domIndex] ?? null;\n if (this._insertAndEmit(source, ref)) {\n // A real reorder happened — swallow the trailing click so a button inside\n // the dragged group doesn't also activate.\n this._suppressNextClick = true;\n }\n }\n\n private _createGhost(source: ToolbarGroupElement): DragGhost | null {\n const label = document.createElement(`span`);\n const text = (`label` in source && typeof source.label === `string` && source.label)\n || (source.textContent ?? ``).trim();\n label.textContent = text.slice(0, 60);\n label.style.overflow = `hidden`;\n label.style.textOverflow = `ellipsis`;\n label.style.whiteSpace = `nowrap`;\n try {\n injectToolbarGhostStyles();\n return createDragGhost({ anchor: source, content: label, className: `ixfx-toolbar-group-ghost` });\n } catch {\n return null;\n }\n }\n\n /**\n * Nearest group gap to the pointer, ignoring the drag source.\n * The perpendicular axis is ignored — the pointer always resolves to a gap.\n * Gaps are in visual order (reversed for `vertical-left`/column-reverse).\n */\n private _computeGapIndex(clientX: number, clientY: number): number | undefined {\n const state = this._dragState;\n if (!state)\n return undefined;\n const domSiblings = this._mainGroups().filter(el => el !== state.source);\n if (domSiblings.length === 0)\n return 0;\n const visual = this.orientation === `vertical-left` ? [...domSiblings].reverse() : domSiblings;\n const useX = this.orientation === `horizontal`;\n const pos = useX ? clientX : clientY;\n const edges = visual.map((el) => {\n const rect = el.getBoundingClientRect();\n return [useX ? rect.left : rect.top, useX ? rect.right : rect.bottom] as const;\n });\n return toolbarGapIndex(edges, pos);\n }\n\n private _computeCaretStyle(): string | undefined {\n const state = this._dragState;\n if (!state?.active || state.gapIndex === undefined)\n return undefined;\n const domSiblings = this._mainGroups().filter(el => el !== state.source);\n if (domSiblings.length === 0)\n return undefined;\n const hostRect = this.getBoundingClientRect();\n if (!hostRect)\n return undefined;\n const visual = this.orientation === `vertical-left` ? [...domSiblings].reverse() : domSiblings;\n const gap = Math.max(0, Math.min(state.gapIndex, visual.length));\n const rect = gap < visual.length\n ? visual[gap].getBoundingClientRect()\n : visual[visual.length - 1].getBoundingClientRect();\n if (this.orientation === `horizontal`) {\n const x = (gap < visual.length ? rect.left : rect.right) - hostRect.left;\n return `transform: translate(${x - 1}px, 0); width: 2px; height: ${hostRect.height}px;`;\n }\n const y = (gap < visual.length ? rect.top : rect.bottom) - hostRect.top;\n return `transform: translate(0, ${y - 1}px); width: ${hostRect.width}px; height: 2px;`;\n }\n\n /** Coalesce measure passes into one per frame; prevents slotchange feedback loops. */\n private _scheduleMeasure(): void {\n if (this._measureQueued)\n return;\n this._measureQueued = true;\n requestAnimationFrame(() => {\n this._measureQueued = false;\n this._measure();\n });\n }\n\n private _measure(): void {\n const children = Array.from(this.children) as HTMLElement[];\n const isGrow = (el: HTMLElement) => el.hasAttribute(`grow`) || el.matches(`[grow]`);\n const overflowable = children.filter(el => !isGrow(el));\n const isHoriz = this.orientation === `horizontal`;\n const overflowMode = getComputedStyle(this).getPropertyValue(`--toolbar-overflow`).trim() as string;\n\n if (this.layout !== `one-line` || overflowMode === `disabled`) {\n let mutated = false;\n for (const el of children) {\n if (el.getAttribute(`slot`) === `overflow`) {\n el.removeAttribute(`slot`); mutated = true;\n }\n if (el.hasAttribute(`hidden`)) {\n el.removeAttribute(`hidden`); mutated = true;\n }\n }\n if (this._overflowCount !== 0) {\n this._overflowCount = 0; mutated = true;\n }\n if (mutated)\n this.requestUpdate();\n return;\n }\n\n if (!this._inner)\n return;\n const cs = getComputedStyle(this._inner);\n const gap = (isHoriz ? Number.parseFloat(cs.columnGap) : Number.parseFloat(cs.rowGap)) || 0;\n const available = isHoriz ? this._inner.clientWidth : this._inner.clientHeight;\n const btnSize = 36;\n\n const inMain = overflowable.filter(el => el.getAttribute(`slot`) !== `overflow`);\n const inOverflow = overflowable.filter(el => el.getAttribute(`slot`) === `overflow`);\n\n // Cache natural sizes while items are measurable in the main slot\n let cum = 0;\n inMain.forEach((el, i) => {\n const s = isHoriz ? el.offsetWidth : el.offsetHeight;\n if (s > 0)\n this._sizes.set(el, s);\n cum += (i ? gap : 0) + (this._sizes.get(el) ?? s);\n });\n\n let mutated = false;\n\n // 'collapsed' mode: all overflowable items start in overflow\n if (overflowMode === `collapsed`) {\n if (inMain.length > 0) {\n for (const el of inMain) {\n el.setAttribute(`slot`, `overflow`);\n }\n inOverflow.push(...inMain);\n inMain.length = 0;\n mutated = true;\n }\n const newCount = inOverflow.length;\n if (newCount !== this._overflowCount) {\n this._overflowCount = newCount; mutated = true;\n }\n if (mutated)\n this.requestUpdate();\n return;\n }\n\n // 'auto' mode: normal overflow handling\n const btnAllowance = inOverflow.length > 0 ? gap + btnSize : 0;\n\n // Move items to overflow, last-first, until the main run fits\n while (inMain.length > 0 && cum + btnAllowance > available) {\n const last = inMain[inMain.length - 1];\n const s = this._sizes.get(last) ?? 0;\n last.setAttribute(`slot`, `overflow`);\n inMain.pop();\n inOverflow.unshift(last);\n cum -= (inMain.length ? gap : 0) + s;\n mutated = true;\n }\n\n // Move items back, first-from-overflow, only while their cached natural size fits.\n // Cached sizes are always > 0, so this cannot oscillate with the 0px measurements\n // that items report inside the closed popover.\n while (inOverflow.length > 0) {\n const first = inOverflow[0];\n const s = this._sizes.get(first);\n if (s === undefined)\n break; // never measured in main slot; stay conservative\n const addGap = inMain.length ? gap : 0;\n const nextBtnAllowance = inOverflow.length > 1 ? gap + btnSize : 0;\n if (cum + addGap + s + nextBtnAllowance > available)\n break;\n first.removeAttribute(`slot`);\n inOverflow.shift();\n inMain.push(first);\n cum += addGap + s;\n mutated = true;\n }\n\n const newCount = inOverflow.length;\n if (newCount !== this._overflowCount) {\n this._overflowCount = newCount; mutated = true;\n }\n if (mutated)\n this.requestUpdate();\n }\n\n private _toggleOverflow(): void {\n try {\n (this._popover as any).togglePopover();\n } catch {\n (this._popover as any).showPopover();\n }\n }\n\n protected override render() {\n const overflowMode = getComputedStyle(this).getPropertyValue(`--toolbar-overflow`).trim();\n const hasOverflow = this._overflowCount > 0 || overflowMode === `collapsed`;\n const caretStyle = this._computeCaretStyle();\n return html`\n <div class=\"inner\" role=\"toolbar\" aria-orientation=${this.orientation}>\n <slot @pointerdown=${this._onPointerDown} @keydown=${this._onKeyDown}></slot>\n <ixfx-button class=\"overflow-btn\" ?hidden=${!hasOverflow} @click=${this._toggleOverflow} aria-label=\"More\" aria-haspopup=\"true\" aria-expanded=${this._popoverOpen}>⋯</ixfx-button>\n </div>\n <div class=\"overflow-popover popup-surface\" popover=\"auto\" @click=${(e: Event) => e.stopPropagation()}>\n <slot name=\"overflow\"></slot>\n </div>\n ${caretStyle ? html`<div class=\"drop-caret\" style=${caretStyle}></div>` : nothing}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap { 'ixfx-toolbar': ToolbarElement }\n}\n\nexport interface ToolbarElement {\n addEventListener: (<K extends keyof ToolbarElementEventMap>(\n type: K,\n listener: (this: ToolbarElement, event: ToolbarElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","/**\n * Pure treemap layout: `TreeNode` + value accessor + tiling method + depth\n * window → positioned nested rects. No Lit, no DOM — unit-testable in isolation.\n */\n\nimport type {\n ComputeTreemapLayoutOptions,\n TreemapRect,\n TreemapTilingMethod,\n TreemapValueAccessor,\n TreeNode,\n} from './types.js';\n\n/** Coerce a raw accessor result to a non-negative finite weight. */\nexport function normaliseValue(raw: unknown): number {\n return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? raw : 0;\n}\n\n/** Depth-first search for the node with `key`. Returns `undefined` when absent. */\nexport function findTreemapNode(root: TreeNode | undefined, key: string): TreeNode | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return root;\n for (const child of root.children ?? []) {\n const hit = findTreemapNode(child, key);\n if (hit)\n return hit;\n }\n return undefined;\n}\n\n/**\n * Chain of nodes from `root` down to (and including) the node with `key`.\n * Returns `undefined` when the key is absent. The first entry is always `root`.\n */\nexport function findTreemapPath(root: TreeNode | undefined, key: string): TreeNode[] | undefined {\n if (!root)\n return undefined;\n if (root.item.key === key)\n return [root];\n for (const child of root.children ?? []) {\n const hit = findTreemapPath(child, key);\n if (hit)\n return [root, ...hit];\n }\n return undefined;\n}\n\ntype Box = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\n/**\n * Worst aspect ratio of the row items if laid out together along a strip of\n * length `side` (the short side of the remaining container). Lower is better;\n * `1` is a perfect square. Follows Bruls et al.\n */\nfunction worstAspect(areas: readonly number[], total: number, side: number): number {\n if (areas.length === 0 || total <= 0 || side <= 0)\n return Number.POSITIVE_INFINITY;\n let worst = 0;\n for (const area of areas) {\n if (area <= 0)\n return Number.POSITIVE_INFINITY;\n const ratio = (side * side * area) / (total * total);\n worst = Math.max(worst, ratio, 1 / ratio);\n }\n return worst;\n}\n\n/**\n * Squarified tiling of `items` (with pre-normalised positive areas summing to\n * `box.width * box.height`) into `box`. Returns absolute boxes in item order.\n * Sibling order is preserved — no descending sort — so output is deterministic.\n */\nfunction squarifyInto(\n items: ReadonlyArray<{ area: number }>,\n box: Box,\n): Box[] {\n const out: Box[] = Array.from({ length: items.length });\n let cx = box.x;\n let cy = box.y;\n let cw = box.width;\n let ch = box.height;\n let start = 0;\n\n while (start < items.length) {\n const side = Math.min(cw, ch);\n // Grow the row while the worst aspect ratio keeps improving.\n let end = start + 1;\n let rowAreas = items.slice(start, end).map(i => i.area);\n let rowTotal = rowAreas.reduce((a, b) => a + b, 0);\n let worst = worstAspect(rowAreas, rowTotal, side);\n while (end < items.length) {\n const nextAreas = items.slice(start, end + 1).map(i => i.area);\n const nextTotal = nextAreas.reduce((a, b) => a + b, 0);\n const nextWorst = worstAspect(nextAreas, nextTotal, side);\n if (nextWorst <= worst) {\n end++;\n rowAreas = nextAreas;\n rowTotal = nextTotal;\n worst = nextWorst;\n } else {\n break;\n }\n }\n // Lay the row out as a strip spanning the short side.\n if (cw <= ch) {\n // Narrow container: strip spans the full width, items side-by-side.\n const stripH = rowTotal / cw;\n let ix = cx;\n for (let i = start; i < end; i++) {\n const w = rowAreas[i - start] / stripH;\n out[i] = { x: ix, y: cy, width: w, height: stripH };\n ix += w;\n }\n cy += stripH;\n ch -= stripH;\n } else {\n // Wide container: strip spans the full height, items stacked vertically.\n const stripW = rowTotal / ch;\n let iy = cy;\n for (let i = start; i < end; i++) {\n const h = rowAreas[i - start] / stripW;\n out[i] = { x: cx, y: iy, width: stripW, height: h };\n iy += h;\n }\n cx += stripW;\n cw -= stripW;\n }\n start = end;\n }\n return out;\n}\n\n/** Clamp a raw cascade offset fraction to a sane range. */\nfunction normaliseOffset(raw: unknown): number {\n return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? Math.min(raw, 1) : 0;\n}\n\n/**\n * Subdivide `box` among `weights` (same length as the child list) using\n * `method` at `relativeDepth`. Returns one absolute box per weight, in order.\n * Zero-share children get degenerate (zero-area) boxes at the box origin.\n * Degenerate (zero/negative-extent) containers also yield zero-area boxes\n * rather than `NaN` — this matters for cascaded layouts where deep insets\n * can consume the whole box.\n */\nfunction subdivide(\n box: Box,\n weights: readonly number[],\n method: TreemapTilingMethod,\n relativeDepth: number,\n): Box[] {\n if (box.width <= 0 || box.height <= 0) {\n return weights.map(() => ({ x: box.x, y: box.y, width: 0, height: 0 }));\n }\n const total = weights.reduce((a, b) => a + b, 0);\n const shares = total > 0\n ? weights.map(w => w / total)\n : weights.map(() => 1 / weights.length);\n\n const dice = method === `dice` || (method === `slice-dice` && relativeDepth % 2 === 0);\n const slice = method === `slice` || (method === `slice-dice` && relativeDepth % 2 === 1);\n\n if (method === `squarify`) {\n const positive = shares.map((share, i) => ({ share, i })).filter(s => s.share > 0);\n const boxes: Box[] = weights.map(() => ({ x: box.x, y: box.y, width: 0, height: 0 }));\n if (positive.length > 0) {\n const containerArea = box.width * box.height;\n const laid = squarifyInto(\n positive.map(p => ({ area: p.share * containerArea })),\n box,\n );\n positive.forEach((p, k) => {\n boxes[p.i] = laid[k];\n });\n }\n return boxes;\n }\n\n const boxes: Box[] = [];\n if (dice) {\n // Side-by-side vertical slices.\n let cursor = box.x;\n shares.forEach((share) => {\n const w = box.width * share;\n boxes.push({ x: cursor, y: box.y, width: w, height: box.height });\n cursor += w;\n });\n } else if (slice) {\n // Stacked horizontal slices.\n let cursor = box.y;\n shares.forEach((share) => {\n const h = box.height * share;\n boxes.push({ x: box.x, y: cursor, width: box.width, height: h });\n cursor += h;\n });\n }\n return boxes;\n}\n\n/**\n * Compute the visible rectangles for a treemap view.\n *\n * The zoom node fills the whole viewport (`0,0,1,1`); its children subdivide\n * that rectangle by `valueAccessor` share, recursively, up to `maxDepth`\n * nested levels. The zoom node itself is never emitted as a rect (it is shown\n * in the breadcrumb strip instead — matching `TreeComponent.getNodes()`,\n * where the root is never listed). Siblings whose weights all normalise to\n * `0` split their parent's rectangle equally.\n *\n * @param root True tree root. `undefined` (or a root without children) yields `[]`.\n * @param options `valueAccessor` (default equal weights), `maxDepth` (nesting\n * levels, default unlimited), `zoomKey` (visual root, default true root;\n * unknown keys fall back to the true root), `tilingMethod` (default\n * `'squarify'`), `presentation` (default `'nested'`) plus `cascadeOffsetX/Y`\n * (per-level shift as a viewport fraction, cascaded only).\n */\nexport function computeTreemapLayout(\n root: TreeNode | undefined,\n options: ComputeTreemapLayoutOptions = {},\n): TreemapRect[] {\n if (!root?.children?.length)\n return [];\n const {\n maxDepth = Number.POSITIVE_INFINITY,\n valueAccessor = () => 1,\n zoomKey,\n tilingMethod = `squarify`,\n hideLeaves = false,\n presentation = `nested`,\n cascadeOffsetX: rawOx,\n cascadeOffsetY: rawOy,\n } = options;\n if (maxDepth <= 0)\n return [];\n // Nested (or zero offsets) ⇒ classic fill-the-parent behaviour.\n const cascaded = presentation === `cascaded`;\n const ox = cascaded ? normaliseOffset(rawOx) : 0;\n const oy = cascaded ? normaliseOffset(rawOy) : 0;\n\n const visibleChildren = (node: TreeNode): TreeNode[] => {\n const children = node.children ?? [];\n return hideLeaves ? children.filter(n => n.item.isLeaf !== true) : children;\n };\n\n const zoomNode = zoomKey === undefined ? root : (findTreemapNode(root, zoomKey) ?? root);\n const zoomPath = findTreemapPath(root, zoomNode.item.key);\n // Absolute depth of the zoom node: root is -1 so its children are depth 0.\n const zoomDepth = zoomPath ? zoomPath.length - 2 : -1;\n const siblings = visibleChildren(zoomNode);\n if (siblings.length === 0)\n return [];\n\n const rects: TreemapRect[] = [];\n const layoutLevel = (\n nodes: readonly TreeNode[],\n box: Box,\n depth: number,\n relativeDepth: number,\n parentKey: string | undefined,\n ): void => {\n if (nodes.length === 0 || relativeDepth >= maxDepth)\n return;\n const weights = nodes.map(n => normaliseValue((valueAccessor as TreemapValueAccessor)(n.item)));\n const boxes = subdivide(box, weights, tilingMethod, relativeDepth);\n const setSize = nodes.length;\n nodes.forEach((node, index) => {\n const childBox = boxes[index];\n const children = visibleChildren(node);\n rects.push({\n node,\n depth,\n relativeDepth,\n x: childBox.x,\n y: childBox.y,\n width: childBox.width,\n height: childBox.height,\n parentKey,\n index,\n setSize,\n hasChildren: children.length > 0 || (node.children === undefined && node.item.isLeaf !== true),\n });\n if (children.length > 0) {\n // Cascaded presentation (Lü & Fogarty 2008, Fig. 6): the children's\n // content box is shifted down+right inside the parent tile, so the\n // parent's top/left strips stay visible as a stack-of-cards depth\n // effect. Right/bottom edges stay flush with the parent. A consumed\n // box collapses to zero area (never negative) — `subdivide` then\n // emits zero-area descendants rather than `NaN`.\n const contentBox = ox <= 0 && oy <= 0\n ? childBox\n : {\n x: childBox.x + ox,\n y: childBox.y + oy,\n width: Math.max(0, childBox.width - ox),\n height: Math.max(0, childBox.height - oy),\n };\n layoutLevel(children, contentBox, depth + 1, relativeDepth + 1, node.item.key);\n }\n });\n };\n\n layoutLevel(siblings, { x: 0, y: 0, width: 1, height: 1 }, zoomDepth + 1, 0, zoomNode.item.key);\n return rects;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues } from 'lit';\nimport type { TreeActivateDetail, TreeActivateEvent, TreeCollapseDetail, TreeCollapseEvent, TreeComponent, TreeComponentEventMap, TreeExpandDetail, TreeExpandEvent, TreeItemClickDetail, TreeItemClickEvent, TreeItemDblClickDetail, TreeItemDblClickEvent, TreeSearchHost, TreeSelectDetail, TreeSelectEvent, TreeTickleDetail, TreeTickleEvent } from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type {\n TreemapCategoryAccessor,\n TreemapInteractionMode,\n TreemapPresentation,\n TreemapRect,\n TreemapTilingMethod,\n TreemapValueAccessor,\n} 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 {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { computeTreemapLayout, findTreemapNode, findTreemapPath } from './layout.js';\nimport '../crumbs/crumb-navigation.js';\n\n/** Fired when the zoom root changes. `node` is `undefined` on zoom-out to the full tree. */\nexport type TreemapZoomDetail = {\n readonly node: TreeNode | undefined;\n /** Absolute depth of the zoom node (root's children are depth 0); `-1` when fully zoomed out. */\n readonly depth: number;\n};\n\nexport type TreemapZoomEvent = CustomEvent<TreemapZoomDetail>;\n\n/**\n * A planned FLIP animation for a zoom transition — computed just before the\n * zoom state changes, then applied once the new layout has rendered.\n * - `'in'` (zooming into a tile): `rect` is that tile's position in the *old*\n * viewport's coordinate space (0–1) — the new content starts scaled/placed\n * to match it, then animates to fill the viewport (a \"grow\" effect).\n * - `'out'` (zooming to an ancestor, or fully out): `rect` is where the node\n * being zoomed *from* lands in the *new* layout — the new content starts\n * blown up so that rect fills the viewport (matching what was on screen a\n * moment ago), then animates down to its true size (a \"shrink\" effect).\n */\ntype FlipPlan = {\n readonly direction: `in` | `out`;\n readonly rect: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };\n};\n\nexport interface TreemapListElementEventMap extends TreeComponentEventMap {\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'zoom': TreemapZoomEvent;\n}\n\n/**\n * `ixfx-treemap-list` — a nested-area (treemap) view over tree data.\n *\n * The zoom root fills the whole viewport; at each level a node's rectangle is\n * subdivided among its children by `valueAccessor` share (see `tilingMethod`),\n * recursively, up to `maxDepth` nested levels. Implements the shared\n * `TreeComponent` interface so existing infrastructure (`TreeDataModel`,\n * `IncrSearchTreeController`, `TreeComponent`-typed code) works unmodified.\n *\n * Differences from `ixfx-tree-list` (deliberate):\n * - **Expand/collapse is reinterpreted as zoom.** Clicking a branch zooms so it\n * becomes the visual root; ancestors collapse into the breadcrumb strip.\n * `expand`/`collapse` events fire on zoom-in/zoom-out with the same detail\n * shape so existing listeners keep working conceptually.\n * - **`interactionMode` drops `checked`** — a checkbox per rectangle does not\n * hold up at small tile sizes.\n * - **`exclusivity` is accepted but ignored** — nothing is independently \"open\".\n * - **`filterPredicate` dims** non-matching tiles instead of hiding rows.\n * - Drag-and-drop is out of scope.\n */\n@customElement(`ixfx-treemap-list`)\nexport class TreemapListElement 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 /**\n * Accepted for `TreeComponent` compatibility but ignored — a treemap has no\n * independently open branches, so exclusivity is not meaningful.\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 /**\n * Gesture mapping. `checked` is unsupported (see class docs).\n * @default 'standard'\n */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: TreemapInteractionMode = `standard`;\n\n /**\n * Algorithm used to subdivide a node's rectangle among its children.\n * @default 'squarify'\n */\n @property({ type: String, attribute: `tiling-method` })\n tilingMethod: TreemapTilingMethod = `squarify`;\n\n /**\n * How containment is shown. Orthogonal to `tilingMethod` (Lü & Fogarty 2008:\n * any subdivision can be shown either way).\n * - `'nested'` — children fill the parent (classic nesting).\n * - `'cascaded'` — children shift down+right by `cascadeOffset` per level,\n * leaving the parent's top/left strips visible (stack-of-cards depth).\n * @default 'nested'\n */\n @property({ type: String, attribute: `presentation` })\n presentation: TreemapPresentation = `nested`;\n\n /**\n * Per-level cascade shift (px) down+right applied when\n * `presentation === 'cascaded'`. Converted to viewport fractions using the\n * host size before layout. Ignored when nested.\n * @default 6\n */\n @property({ type: Number, attribute: `cascade-offset` })\n cascadeOffset = 6;\n\n /** How many nested levels render at once from the current zoom root. */\n @property({ type: Number, attribute: `max-depth` })\n maxDepth = 4;\n\n /**\n * When `true`, leaf nodes (`item.isLeaf === true`) are excluded entirely —\n * neither rendered nor counted towards their siblings' area shares. Use\n * this to show branch structure only (e.g. folders, not files).\n */\n @property({ type: Boolean, attribute: `hide-leaves` })\n hideLeaves = false;\n\n /**\n * Tiles whose pixel area falls below this (px²) hide their label.\n * Area is estimated from the tile's area share times the host size.\n */\n @property({ type: Number, attribute: `min-label-area` })\n minLabelArea = 1600;\n\n /**\n * Minimum on-screen width (px) a tile needs before its label is shown or\n * its own children are subdivided. A tall, narrow sliver can clear\n * `minLabelArea`/`minChildArea` on area alone while still being too narrow\n * to show even a truncated character — this catches that case so it\n * renders as a plain, unlabelled block instead of a clipped-to-nothing title.\n */\n @property({ type: Number, attribute: `min-tile-width` })\n minTileWidth = 24;\n\n /**\n * Inner padding (px) between a branch tile's border and its children, so\n * nested levels are visually distinguishable.\n */\n @property({ type: Number })\n padding = 4;\n\n /**\n * Minimum on-screen area (px²) a tile must have before its own children are\n * subdivided and rendered. Below this, a tile renders as a flat block with\n * no nested detail — recursion stops by pixel size rather than by a fixed\n * node depth, so a branch with many descendants doesn't collapse into an\n * illegible cluster of near-zero-size rectangles.\n */\n @property({ type: Number, attribute: `min-child-area` })\n minChildArea = 400;\n\n /** Weight per node. Default `() => 1` — equal-area siblings. */\n @property({ attribute: false })\n valueAccessor: TreemapValueAccessor = () => 1;\n\n /**\n * Category per node, or `undefined` for none. When set, a tile's\n * background/text colour come from `--treemap-category-<slug>-bg` /\n * `--treemap-category-<slug>-text` (the category name slugified —\n * non `[a-zA-Z0-9_-]` characters become `-`), falling back to the normal\n * `--treemap-tile-bg`/`--treemap-tile-text` when that pair isn't defined.\n * Default `undefined` — no categorisation.\n */\n @property({ attribute: false })\n categoryAccessor: TreemapCategoryAccessor | undefined;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n private _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 /** Current zoom root. `undefined` when showing the full tree. Pure view-state — `root` is never mutated. */\n get focusedNode(): TreeNode | undefined {\n if (this._zoomKey === undefined)\n return undefined;\n return findTreemapNode(this.#effectiveRoot, this._zoomKey);\n }\n\n @state()\n private _zoomKey: string | undefined = undefined;\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: `.treemap-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n private tickled = new TickledController<string>(this, {\n getItems: () => this.#rects().map(r => ({ id: r.node.item.key, enabled: true })),\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n onTickle: (id) => {\n if (id === undefined)\n return;\n const rect = this.#rects().find(r => r.node.item.key === id);\n if (!rect)\n return;\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n },\n });\n\n #modelUnsubscribe: (() => void) | undefined;\n #pendingKeys = new Set<string>();\n #aborters = new Map<string, AbortController>();\n #anchorIndex: number | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n #unregisterSearchCommands: (() => void) | undefined;\n #resizeObserver: ResizeObserver | undefined;\n #pendingFlip: FlipPlan | undefined;\n /** `performance.now()` timestamp before which further Cmd+wheel zoom steps are ignored. */\n #wheelCooldownUntil = 0;\n\n // --- Derived data ---------------------------------------------------------\n\n get #effectiveRoot(): TreeNode | undefined {\n return this.model?.root ?? this.root;\n }\n\n #rects(): TreemapRect[] {\n return this.#rectsForZoom(this._zoomKey);\n }\n\n #rectsForZoom(zoomKey: string | undefined): TreemapRect[] {\n return computeTreemapLayout(this.#effectiveRoot, {\n valueAccessor: this.valueAccessor,\n maxDepth: this.maxDepth,\n zoomKey,\n tilingMethod: this.tilingMethod,\n hideLeaves: this.hideLeaves,\n presentation: this.presentation,\n ...this.#cascadeFractions(),\n });\n }\n\n /**\n * Pixel `cascadeOffset` as viewport fractions for the current host size.\n * Returns `{}` when nested, unmeasured, or non-positive — layout then falls\n * back to classic nesting for that pass (the `ResizeObserver` re-renders\n * once measured).\n */\n #cascadeFractions(): { cascadeOffsetX?: number; cascadeOffsetY?: number } {\n if (this.presentation !== `cascaded`)\n return {};\n if (!Number.isFinite(this.cascadeOffset) || this.cascadeOffset <= 0)\n return {};\n const w = this.clientWidth || 0;\n const h = this.clientHeight || 0;\n if (w <= 0 || h <= 0)\n return {};\n return { cascadeOffsetX: this.cascadeOffset / w, cascadeOffsetY: this.cascadeOffset / h };\n }\n\n // --- Lifecycle ------------------------------------------------------------\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 if (typeof ResizeObserver !== `undefined`) {\n this.#resizeObserver = new ResizeObserver(() => this.requestUpdate());\n this.#resizeObserver.observe(this);\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n for (const aborter of this.#aborters.values())\n aborter.abort();\n this.#aborters.clear();\n this.#pendingKeys.clear();\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\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 #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 protected override updated(changedProps: PropertyValues): void {\n if (changedProps.has(`root`) && this.root) {\n this.#resetViewState();\n }\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n if (this.model) {\n this.#modelUnsubscribe = this.model._subscribe((event) => {\n if (event.type === `root`) {\n this.#resetViewState();\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n this.requestUpdate();\n }\n });\n this.#resetViewState();\n }\n }\n if (changedProps.has(`interactionMode`)) {\n this.#anchorIndex = undefined;\n this.clearSelection();\n }\n if (changedProps.has(`searchModes`))\n this.#syncSearchCommands();\n // A new root invalidates the zoom target — fall back to the full tree.\n if (this._zoomKey !== undefined && !findTreemapNode(this.#effectiveRoot, this._zoomKey)) {\n this._zoomKey = undefined;\n }\n this.#ensureVisibleChildren();\n if (this.#pendingFlip) {\n const flip = this.#pendingFlip;\n this.#pendingFlip = undefined;\n this.#applyFlip(flip);\n }\n }\n\n #resetViewState(): void {\n this.#pendingFlip = undefined;\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._zoomKey = undefined;\n this.#anchorIndex = undefined;\n }\n\n // --- Lazy children --------------------------------------------------------\n\n #ensureVisibleChildren(): void {\n if (!this.model && !this.loadChildren)\n return;\n for (const rect of this.#rects()) {\n const { node } = rect;\n if (node.children !== undefined || this.#pendingKeys.has(node.item.key))\n continue;\n // #rects() only ever yields rects within the visible window\n // (relativeDepth < maxDepth), so every rect reaching here is a\n // currently-rendered node whose children aren't loaded yet — fetch them\n // so zooming in works.\n void this.#loadChildren(node, rect.depth);\n }\n }\n\n async #loadChildren(node: TreeNode, depth: number): Promise<void> {\n const key = node.item.key;\n this.#pendingKeys.add(key);\n const controller = new AbortController();\n this.#aborters.set(key, controller);\n this.requestUpdate();\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 } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n } finally {\n this.#pendingKeys.delete(key);\n this.#aborters.delete(key);\n if (!controller.signal.aborted)\n this.requestUpdate();\n }\n }\n\n // --- Selection ------------------------------------------------------------\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._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail: { selected: new Set(this._selectedNodes), previous },\n bubbles: true,\n composed: true,\n }));\n }\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 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 for (const rect of this.#rects()) {\n if (!this.#canSelect(rect.node))\n continue;\n this._selectedNodes.add(rect.node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\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 // --- Zoom -----------------------------------------------------------------\n\n /**\n * Drill down so `node` becomes the visual root (ancestors move to the\n * breadcrumb strip). Pure view-state — `root` is never mutated.\n * Fires `zoom` and the semantic `expand` event.\n */\n zoomTo(node: TreeNode): void {\n if (this._zoomKey === node.item.key)\n return;\n this.#pendingFlip = this.#planFlip(node.item.key);\n this._zoomKey = node.item.key;\n this.tickled.clearTickled();\n const depth = findTreemapPath(this.#effectiveRoot, node.item.key)?.length;\n const absoluteDepth = depth === undefined ? -1 : depth - 2;\n this.dispatchEvent(new CustomEvent<TreemapZoomDetail>(`zoom`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n }\n\n /**\n * Zoom back out to the full tree. Fires `zoom` (with `node: undefined`) and\n * the semantic `collapse` event for the previous zoom root.\n */\n zoomOut(): void {\n if (this._zoomKey === undefined)\n return;\n this.#pendingFlip = this.#planFlip(undefined);\n const previous = this.focusedNode;\n const path = this._zoomKey === undefined\n ? undefined\n : findTreemapPath(this.#effectiveRoot, this._zoomKey);\n const absoluteDepth = path === undefined ? -1 : path.length - 2;\n this._zoomKey = undefined;\n this.tickled.clearTickled();\n this.dispatchEvent(new CustomEvent<TreemapZoomDetail>(`zoom`, {\n detail: { node: undefined, depth: -1 },\n bubbles: true,\n composed: true,\n }));\n if (previous) {\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node: previous, depth: absoluteDepth },\n bubbles: true,\n composed: true,\n }));\n }\n this.requestUpdate();\n }\n\n /**\n * Work out (before `_zoomKey` changes) whether the upcoming zoom should\n * animate, and how — see `FlipPlan`. Returns `undefined` to skip the\n * animation: reduced-motion is requested, or the node needed to anchor it\n * isn't in either the old or new layout's visible window.\n */\n #planFlip(targetKey: string | undefined): FlipPlan | undefined {\n if (typeof matchMedia === `function` && matchMedia(`(prefers-reduced-motion: reduce)`).matches)\n return undefined;\n if (targetKey !== undefined) {\n // Target already visible under the current zoom root ⇒ zooming in:\n // grow from its current on-screen rect to fill the viewport.\n const visible = this.#rects().find(r => r.node.item.key === targetKey);\n if (visible) {\n return { direction: `in`, rect: { x: visible.x, y: visible.y, width: visible.width, height: visible.height } };\n }\n }\n // Otherwise zooming out (to an ancestor, or fully out): find where the\n // node we're zooming *from* lands in the new layout, and shrink into it.\n const fromKey = this._zoomKey;\n if (fromKey === undefined)\n return undefined;\n const landing = this.#rectsForZoom(targetKey).find(r => r.node.item.key === fromKey);\n if (!landing)\n return undefined;\n return { direction: `out`, rect: { x: landing.x, y: landing.y, width: landing.width, height: landing.height } };\n }\n\n /** Apply a planned FLIP animation once the new layout has rendered — see `FlipPlan`. */\n #applyFlip(flip: FlipPlan): void {\n const inner = this.renderRoot.querySelector(`.viewport-inner`);\n const viewport = this.renderRoot.querySelector(`.viewport`);\n if (!(inner instanceof HTMLElement) || !(viewport instanceof HTMLElement))\n return;\n const vw = viewport.clientWidth;\n const vh = viewport.clientHeight;\n if (vw <= 0 || vh <= 0)\n return;\n const { rect, direction } = flip;\n const startTransform = direction === `in`\n ? `translate(${rect.x * vw}px, ${rect.y * vh}px) scale(${Math.max(rect.width, 0.0001)}, ${Math.max(rect.height, 0.0001)})`\n : (() => {\n const sx = rect.width > 0 ? 1 / rect.width : 1;\n const sy = rect.height > 0 ? 1 / rect.height : 1;\n return `translate(${-rect.x * sx * vw}px, ${-rect.y * sy * vh}px) scale(${sx}, ${sy})`;\n })();\n inner.classList.remove(`flipping`);\n inner.style.transform = startTransform;\n // Force the starting transform to commit before animating away from it.\n void inner.offsetWidth;\n requestAnimationFrame(() => {\n inner.classList.add(`flipping`);\n inner.style.transform = `none`;\n });\n inner.addEventListener(`transitionend`, () => inner.classList.remove(`flipping`), { once: true });\n }\n\n #canZoom(node: TreeNode): boolean {\n if (node.item.isLeaf === true)\n return false;\n if (node.children !== undefined) {\n return this.hideLeaves\n ? node.children.some(n => n.item.isLeaf !== true)\n : node.children.length > 0;\n }\n // Not yet loaded — zoomable when a loader could provide children.\n return this.model !== undefined || this.loadChildren !== undefined;\n }\n\n // --- Navigation -----------------------------------------------------------\n\n /**\n * Zoom so the node at `keys` (path from the root's children) is visible,\n * then select it. Returns `true` if the path was found.\n */\n navigateTo(keys: readonly string[]): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n let current: TreeNode = root;\n const path: TreeNode[] = [];\n for (const key of keys) {\n const found = current.children?.find(n => n.item.key === key);\n if (!found)\n return false;\n path.push(found);\n current = found;\n }\n const target = path.at(-1)!;\n // Keep the target inside the depth window: zoom to the ancestor `maxDepth`\n // levels above it, or the full tree when it already fits.\n if (path.length > this.maxDepth) {\n this.zoomTo(path[path.length - this.maxDepth - 1]);\n } else if (this._zoomKey !== undefined) {\n this.zoomOut();\n }\n this.select(target);\n this.tickled.setTickled(target.item.key);\n this.requestUpdate();\n return true;\n }\n\n /**\n * Zoom + select the first node for which `predicate` returns `true`.\n * Returns `true` if a matching node was found.\n */\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const keyPath = this.#findKeyPath(root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /**\n * Zoom so the node with `key` is visible and move the keyboard cursor to it,\n * without changing the selection. Used by incremental-search \"navigate\" mode.\n */\n revealKey(key: string): boolean {\n const root = this.#effectiveRoot;\n if (!root?.children)\n return false;\n const path = this.#findKeyPath(root.children, n => n.item.key === key);\n if (!path)\n return false;\n if (path.length > this.maxDepth) {\n const ancestor = this.#resolveKeyPath(path.slice(0, path.length - this.maxDepth));\n if (ancestor)\n this.zoomTo(ancestor);\n }\n this.tickled.setTickled(key);\n this.requestUpdate();\n return true;\n }\n\n #resolveKeyPath(keys: readonly string[]): TreeNode | undefined {\n let current = this.#effectiveRoot;\n for (const key of keys) {\n const found = key === current?.item.key ? current : current?.children?.find(n => n.item.key === key);\n if (!found)\n return undefined;\n current = found;\n }\n return current;\n }\n\n #findKeyPath(\n nodes: readonly 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 hit = this.#findKeyPath(node.children, predicate, path);\n if (hit)\n return hit;\n }\n }\n return undefined;\n }\n\n /**\n * All nodes currently visible as tiles, in render (pre-order) order,\n * with absolute depth (root's children are depth 0).\n */\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n return this.#rects().map(r => ({ node: r.node, depth: r.depth }));\n }\n\n // --- Pointer / keyboard ---------------------------------------------------\n\n #matchesFilter(node: TreeNode, depth: number): boolean {\n if (!this.filterPredicate)\n return true;\n if (this.filterPredicate(node, depth))\n return true;\n return node.children?.some(child => this.#matchesFilter(child, depth + 1)) ?? false;\n }\n\n #rectCenter(rect: TreemapRect): { x: number; y: number } {\n return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };\n }\n\n /**\n * Geometrically nearest sibling tile in `direction` from `current`\n * (nearest-neighbour by rect center). Falls back to the parent tile\n * (Up/Left) or first-child tile (Down/Right) when no sibling lies in that\n * direction, so every visible tile stays keyboard-reachable.\n */\n #nearestInDirection(\n current: TreemapRect,\n direction: `left` | `right` | `up` | `down`,\n ): TreemapRect | undefined {\n const rects = this.#rects();\n const center = this.#rectCenter(current);\n const siblings = rects.filter(r =>\n r !== current && r.relativeDepth === current.relativeDepth && r.parentKey === current.parentKey);\n let best: TreemapRect | undefined;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const candidate of siblings) {\n const c = this.#rectCenter(candidate);\n const dx = c.x - center.x;\n const dy = c.y - center.y;\n const inDirection = direction === `left`\n ? dx < 0\n : direction === `right`\n ? dx > 0\n : direction === `up` ? dy < 0 : dy > 0;\n if (!inDirection)\n continue;\n const distance = Math.hypot(dx, dy);\n if (distance < bestDistance) {\n bestDistance = distance;\n best = candidate;\n }\n }\n if (best)\n return best;\n if (direction === `up` || direction === `left`) {\n return current.parentKey === undefined\n ? undefined\n : rects.find(r => r.node.item.key === current.parentKey);\n }\n return rects.find(r => r.parentKey === current.node.item.key);\n }\n\n #handleItemClick(rect: TreemapRect, index: number, event: MouseEvent): void {\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.interactionMode === `standard` && (event.ctrlKey || event.metaKey)) {\n if (this._selectedNodes.has(rect.node)) {\n this.deselect(rect.node);\n } else if (this.#canSelect(rect.node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.add(rect.node);\n this.selectedNode = rect.node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n this.#anchorIndex = index;\n } else if (this.interactionMode === `standard` && event.shiftKey && this.#anchorIndex !== undefined) {\n const rects = this.#rects();\n const from = Math.min(this.#anchorIndex, index);\n const to = Math.max(this.#anchorIndex, index);\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = new Set(\n rects.slice(from, to + 1).map(r => r.node).filter(n => this.#canSelect(n)),\n );\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n } else if (this.interactionMode !== `manual`) {\n this.select(rect.node);\n this.#anchorIndex = index;\n }\n this.tickled.setTickled(rect.node.item.key);\n if (this.#canZoom(rect.node))\n this.zoomTo(rect.node);\n }\n\n #handleItemDblClick(rect: TreemapRect): void {\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: rect.node, depth: rect.depth },\n bubbles: true,\n composed: true,\n }));\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n if (this.disableKeyboardNavigation)\n return;\n const rects = this.#rects();\n if (rects.length === 0)\n return;\n const tickledKey = this.tickled.tickledId;\n const currentIndex = tickledKey === undefined\n ? -1\n : rects.findIndex(r => r.node.item.key === tickledKey);\n const current = currentIndex >= 0 ? rects[currentIndex] : undefined;\n\n const moveTo = (rect: TreemapRect | undefined) => {\n if (!rect)\n return;\n event.preventDefault();\n this.tickled.setTickled(rect.node.item.key);\n // implicit: single selection follows the keyboard cursor (mirrors tree-base's implicit mode).\n if (this.interactionMode === `implicit`)\n this.select(rect.node);\n };\n\n switch (event.key) {\n case `ArrowLeft`:\n moveTo(current ? this.#nearestInDirection(current, `left`) : rects[0]);\n return;\n case `ArrowRight`:\n moveTo(current ? this.#nearestInDirection(current, `right`) : rects[0]);\n return;\n case `ArrowUp`:\n moveTo(current ? this.#nearestInDirection(current, `up`) : rects[0]);\n return;\n case `ArrowDown`:\n moveTo(current ? this.#nearestInDirection(current, `down`) : rects[0]);\n return;\n case `Home`:\n moveTo(rects[0]);\n return;\n case `End`:\n moveTo(rects.at(-1));\n return;\n case `Enter`: {\n if (!current)\n return;\n event.preventDefault();\n if (this.interactionMode !== `manual`)\n this.select(current.node);\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n if (this.#canZoom(current.node))\n this.zoomTo(current.node);\n return;\n }\n case `Backspace`:\n case `Escape`:\n if (this._zoomKey !== undefined) {\n event.preventDefault();\n this.zoomOut();\n }\n }\n }\n\n /**\n * Cmd+wheel zooms: scrolling backward (deltaY < 0, towards the user) zooms\n * into the tile under the pointer — the same as clicking it; scrolling\n * forward (deltaY > 0, away from the user) zooms out one level at a time\n * (see `#zoomOutOneStep`), not straight to the root. Plain wheel (no Cmd)\n * is left alone for normal page scroll. A short cooldown after each step\n * keeps a single trackpad gesture (which fires many small wheel events)\n * from firing a cascade of zoom steps.\n */\n #handleWheel(event: WheelEvent): void {\n if (!event.metaKey || event.deltaY === 0)\n return;\n event.preventDefault();\n if (performance.now() < this.#wheelCooldownUntil)\n return;\n if (event.deltaY > 0) {\n if (this._zoomKey === undefined)\n return;\n this.#wheelCooldownUntil = performance.now() + 260;\n this.#zoomOutOneStep();\n return;\n }\n const tileEl = (event.target as Element | null)?.closest(`.tile`);\n const key = tileEl?.getAttribute(`data-key`) ?? undefined;\n if (key === undefined)\n return;\n const rect = this.#rects().find(r => r.node.item.key === key);\n if (!rect || !this.#canZoom(rect.node))\n return;\n this.#wheelCooldownUntil = performance.now() + 260;\n this.zoomTo(rect.node);\n }\n\n /** Zoom to the current zoom node's parent, or fully out when it's a direct child of the root. */\n #zoomOutOneStep(): void {\n const path = this._zoomKey === undefined ? undefined : findTreemapPath(this.#effectiveRoot, this._zoomKey);\n // path is [root, ..., zoomNode]; length <= 2 means zoomNode is a direct child of root.\n const parent = path && path.length > 2 ? path[path.length - 2] : undefined;\n if (parent) {\n this.zoomTo(parent);\n } else {\n this.zoomOut();\n }\n }\n\n // --- Render ---------------------------------------------------------------\n\n #renderBreadcrumb(): unknown {\n const zoomNode = this.focusedNode;\n if (zoomNode === undefined)\n return nothing;\n return html`\n <nav class=\"breadcrumb\" part=\"breadcrumb\" aria-label=\"Treemap zoom path\">\n <ixfx-crumb-navigation\n with-up\n .root=${this.#effectiveRoot}\n .selectedNode=${zoomNode}\n @select=${this.#onCrumbSelect}\n @item-click=${(e: Event) => e.stopPropagation()}\n @tickle=${(e: Event) => e.stopPropagation()}\n @expand=${(e: Event) => e.stopPropagation()}\n ></ixfx-crumb-navigation>\n </nav>\n `;\n }\n\n /**\n * Translate crumb-trail selection (crumb clicks + the up-button) into zoom\n * state. The event is stopped: crumb clicks must not bubble as our `select`\n * (the selection set is unchanged by them).\n */\n #onCrumbSelect(event: Event): void {\n event.stopPropagation();\n const selected = (event as CustomEvent<TreeSelectDetail>).detail.selected;\n const node = [...selected].at(0);\n if (!node)\n return;\n if (node.item.key === this.#effectiveRoot?.item.key) {\n this.zoomOut();\n } else {\n this.zoomTo(node);\n }\n }\n\n /** On-screen size (px) of `rect`, or `undefined` before the host has been measured. */\n #pixelSize(rect: TreemapRect): { width: number; height: number } | undefined {\n const hostWidth = this.clientWidth || 0;\n const hostHeight = this.clientHeight || 0;\n if (hostWidth <= 0 || hostHeight <= 0)\n return undefined;\n return { width: rect.width * hostWidth, height: rect.height * hostHeight };\n }\n\n /** Hide when too small by area, or too narrow to fit any readable text even truncated. */\n #hideLabel(rect: TreemapRect): boolean {\n const size = this.#pixelSize(rect);\n if (size === undefined)\n return false;\n return size.width * size.height < this.minLabelArea || size.width < this.minTileWidth;\n }\n\n /** Whether `rect` is large enough on-screen for its own children to be subdivided and drawn. */\n #canDescend(rect: TreemapRect): boolean {\n const size = this.#pixelSize(rect);\n // Unmeasured (first paint, before layout) ⇒ assume yes so nesting still shows up.\n if (size === undefined)\n return true;\n // Cascaded tiles reserve `cascadeOffset` px down+right for the depth\n // effect — children only get what's left, so judge by that.\n const offset = this.presentation === `cascaded` && Number.isFinite(this.cascadeOffset) && this.cascadeOffset > 0\n ? this.cascadeOffset\n : 0;\n const w = size.width - offset;\n const h = size.height - offset;\n if (w <= 0 || h <= 0)\n return false;\n return w * h >= this.minChildArea && w >= this.minTileWidth;\n }\n\n /** Slugify a category name into a CSS custom-property-safe token. */\n #categorySlug(category: string): string {\n return category.replace(/[^\\w-]/g, `-`);\n }\n\n /**\n * Inline colour overrides for `node`'s category, or `undefined` for none.\n * Set as real `background-color`/`color` (not custom properties) so they\n * simply win over `.tile`'s CSS-variable-driven defaults by specificity —\n * no risk of an unresolvable `var()` chain leaving the property invalid.\n */\n #categoryStyle(node: TreeNode): string | undefined {\n const category = this.categoryAccessor?.(node.item);\n if (!category)\n return undefined;\n const slug = this.#categorySlug(category);\n return `background-color:var(--treemap-category-${slug}-bg, var(--treemap-tile-bg));`\n + `color:var(--treemap-category-${slug}-text, var(--treemap-tile-text));`;\n }\n\n #renderTileBox(rect: TreemapRect, positionStyle: string, hasVisibleChildren: boolean, childrenContent: unknown): unknown {\n const { node } = rect;\n const selected = this._selectedNodes.has(node);\n const tickled = this.tickled.isTickled(node.item.key);\n const filtered = !this.#matchesFilter(node, rect.depth);\n const pending = this.#pendingKeys.has(node.item.key);\n const hideLabel = this.#hideLabel(rect);\n const showHeader = hasVisibleChildren && !hideLabel;\n const category = this.categoryAccessor?.(node.item);\n const categoryStyle = this.#categoryStyle(node);\n return html`\n <div\n class=\"item tile ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${filtered ? `filtered` : ``} ${pending ? `loading` : ``} ${rect.width <= 0 || rect.height <= 0 ? `empty` : ``}\"\n data-key=${node.item.key}\n data-depth=${rect.relativeDepth}\n data-category=${category ?? nothing}\n role=\"treeitem\"\n tabindex=\"-1\"\n aria-level=${rect.depth + 1}\n aria-selected=${selected}\n aria-setsize=${rect.setSize}\n aria-posinset=${rect.index + 1}\n aria-label=${node.item.label}\n title=${node.item.label}\n part=\"tile\"\n style=${categoryStyle ? `${positionStyle};${categoryStyle}` : positionStyle}\n @click=${(e: MouseEvent) => {\n e.stopPropagation();\n this.#handleItemClick(rect, this.#rects().findIndex(r => r.node.item.key === node.item.key), e);\n }}\n @dblclick=${(e: MouseEvent) => {\n e.stopPropagation();\n this.#handleItemDblClick(rect);\n }}\n @pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}\n >\n ${showHeader\n ? html`<div class=\"tile-header\" part=\"tile-header\"><span class=\"treemap-label\" part=\"label\">${node.item.label}</span></div>`\n : html`<span class=\"treemap-label ${hideLabel ? `hide-label` : ``}\" part=\"label\">${node.item.label}</span>`}\n ${childrenContent}\n </div>\n `;\n }\n\n /**\n * Render `rect` plus (if it's large enough to descend into — see\n * `#canDescend`) a `.tile-children` holding its own children, each\n * positioned relative to `rect` itself and recursing the same way.\n *\n * Each level gets its own real `.tile-header` + `.tile-children` box, so a\n * header reserves its own space via normal box-model layout (flex column:\n * header, then the remaining space for children) at *every* level — not\n * just the top one. That matters because layout rects are purely\n * geometric (no allowance for header height), so a folder whose one child\n * fills ~100% of its area gets a child rect nearly identical to its own;\n * positioning that child against its direct parent (not some flattened\n * shared ancestor) is what keeps the parent's header from being painted\n * over by an opaque, near-identically-sized child box.\n */\n #renderTile(rect: TreemapRect, positionStyle: string, byParent: Map<string, TreemapRect[]>): unknown {\n const hasVisibleChildren = rect.hasChildren && this.#canDescend(rect);\n const children = hasVisibleChildren ? (byParent.get(rect.node.item.key) ?? []) : [];\n const childrenContent = children.length > 0\n ? html`\n <div class=\"tile-children\" role=\"group\">\n ${repeat(children, r => r.node.item.key, r => this.#renderNestedTile(r, rect, byParent))}\n </div>\n `\n : nothing;\n return this.#renderTileBox(rect, positionStyle, children.length > 0, childrenContent);\n }\n\n /** A child tile, positioned as a percentage of `parent`'s own box. */\n #renderNestedTile(rect: TreemapRect, parent: TreemapRect, byParent: Map<string, TreemapRect[]>): unknown {\n const relX = parent.width > 0 ? (rect.x - parent.x) / parent.width : 0;\n const relY = parent.height > 0 ? (rect.y - parent.y) / parent.height : 0;\n const relW = parent.width > 0 ? rect.width / parent.width : 0;\n const relH = parent.height > 0 ? rect.height / parent.height : 0;\n const style = `left:${(relX * 100).toFixed(4)}%;top:${(relY * 100).toFixed(4)}%;width:${(relW * 100).toFixed(4)}%;height:${(relH * 100).toFixed(4)}%`;\n return this.#renderTile(rect, style, byParent);\n }\n\n #renderTopTile(rect: TreemapRect, byParent: Map<string, TreemapRect[]>): unknown {\n const style = `left:${(rect.x * 100).toFixed(4)}%;top:${(rect.y * 100).toFixed(4)}%;width:${(rect.width * 100).toFixed(4)}%;height:${(rect.height * 100).toFixed(4)}%`;\n return this.#renderTile(rect, style, byParent);\n }\n\n protected override render() {\n const rects = this.#rects();\n const byParent = new Map<string, TreemapRect[]>();\n for (const rect of rects) {\n if (rect.parentKey === undefined)\n continue;\n const list = byParent.get(rect.parentKey) ?? [];\n list.push(rect);\n byParent.set(rect.parentKey, list);\n }\n // Top-level tiles: children of the (unrendered) zoom node.\n const zoomKey = this._zoomKey ?? this.#effectiveRoot?.item.key;\n const topLevel = zoomKey === undefined\n ? rects.filter(r => r.relativeDepth === 0)\n : (byParent.get(zoomKey) ?? rects.filter(r => r.relativeDepth === 0));\n return html`\n <div\n class=\"treemap\"\n role=\"tree\"\n tabindex=\"0\"\n data-presentation=${this.presentation}\n data-input-mode=${this.tickled.inputMode}\n style=${`--treemap-padding:${this.padding}px`}\n @keydown=${(e: KeyboardEvent) => this.#handleKeyDown(e)}\n @pointerleave=${() => this.tickled.clearTickled()}\n @wheel=${(e: WheelEvent) => this.#handleWheel(e)}\n >\n ${this.#renderBreadcrumb()}\n ${rects.length === 0\n ? html`<div class=\"empty-state\">No data</div>`\n : html`\n <div class=\"viewport\" part=\"viewport\">\n <div class=\"viewport-inner\">\n ${repeat(topLevel, r => r.node.item.key, r =>\n this.#renderTopTile(r, byParent))}\n </div>\n </div>\n `}\n </div>\n ${this.search.renderField()}\n `;\n }\n\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n listSearchStyles,\n css`\n :host {\n --treemap-height: 280px;\n --treemap-gap: 2px;\n --treemap-padding: 4px;\n --treemap-tile-bg: var(--surface-4);\n --treemap-tile-text: var(--surface-4-text);\n --treemap-tile-border: var(--border-subtle);\n --treemap-header-bg: rgb(0 0 0 / 0.12);\n --treemap-font-size: var(--text-s);\n --treemap-zoom-duration: 220ms;\n\n display: block;\n overflow: hidden;\n }\n\n /* Per-category tile colours (set categoryAccessor to opt in): define\n --treemap-category-SLUG-bg / -text at whatever scope suits (:host\n here, or globally) for each category your accessor can return —\n e.g. --treemap-category-urgent-bg: oklch(55% 0.18 25). A category\n with no matching pair falls back to --treemap-tile-bg/-text. */\n\n .treemap {\n display: flex;\n flex-direction: column;\n gap: var(--space-xs);\n outline: none;\n height: 100%;\n }\n\n .breadcrumb {\n display: flex;\n align-items: center;\n padding: var(--space-xs) var(--space-s);\n background: var(--surface-3);\n color: var(--surface-3-text);\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n font-size: var(--text-s);\n flex-shrink: 0;\n }\n\n .breadcrumb ixfx-crumb-navigation {\n flex: 1;\n min-width: 0;\n }\n\n .viewport {\n position: relative;\n width: 100%;\n /* flex-basis of --treemap-height (its size when nothing forces a\n different one — the common case of an auto-height host) but\n allowed to grow/shrink like any flex item, so it shares the\n .treemap column's height with the breadcrumb instead of a plain\n fixed height always claiming that full amount regardless of what\n else needs space — which is what let the breadcrumb push the\n host past its own height and scroll once a zoom made it appear. */\n flex: 1 1 var(--treemap-height);\n min-height: 0;\n overflow: hidden;\n border-radius: var(--radius-m);\n }\n\n /* Transform target for the zoom-in/zoom-out FLIP animation (see\n #planFlip/#applyFlip) — kept separate from .viewport so the\n transform never fights that element's own sizing/overflow. */\n .viewport-inner {\n position: absolute;\n inset: 0;\n transform-origin: 0 0;\n }\n\n .viewport-inner.flipping {\n transition: transform var(--treemap-zoom-duration, 220ms) ease-out;\n }\n\n .tile {\n position: absolute;\n box-sizing: border-box;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n /* Override the shared .item class's align-items:center (built for\n icon+label rows) — tiles need their flex children to stretch to\n full width, or .tile-children collapses to its (empty) content\n width and every nested tile collapses with it. */\n align-items: stretch;\n white-space: normal;\n background: var(--treemap-tile-bg);\n color: var(--treemap-tile-text);\n border: var(--treemap-tile-border);\n font-size: var(--treemap-font-size);\n cursor: pointer;\n transition:\n opacity var(--transition),\n background-color var(--transition);\n }\n\n .tile-children {\n position: relative;\n flex: 1;\n min-height: 0;\n margin: var(--treemap-padding);\n margin-top: 0;\n }\n\n /* Cascaded presentation (Lü & Fogarty 2008): the geometric inset is\n already in the layout rects — this adds the stack-of-cards depth\n cue on top. Parent tiles read as cards sitting behind their\n children. */\n .treemap[data-presentation=\"cascaded\"] .tile {\n box-shadow: 2px 2px 0 rgb(0 0 0 / 0.25);\n }\n\n .tile-header {\n flex-shrink: 0;\n padding: 1px var(--space-xs);\n background: var(--treemap-header-bg);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-weight: var(--font-weight-bold);\n }\n\n .tile > .treemap-label {\n padding: var(--space-xs);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tile-header .treemap-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .treemap-label.hide-label {\n visibility: hidden;\n }\n\n .tile.filtered {\n opacity: 0.3;\n filter: saturate(0.4);\n }\n\n .tile.empty {\n padding: 0;\n border: none;\n }\n\n .tile.loading {\n cursor: progress;\n opacity: 0.6;\n }\n\n .empty-state {\n padding: var(--space-l);\n color: var(--surface-muted-text);\n font-size: var(--text-s);\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-treemap-list': TreemapListElement;\n }\n}\n\nexport interface TreemapListElement {\n addEventListener: (<K extends keyof TreemapListElementEventMap>(\n type: K,\n listener: (this: TreemapListElement, event: TreemapListElementEventMap[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 TreemapListElementEventMap>(\n type: K,\n listener: (this: TreemapListElement, event: TreemapListElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","import { clamp } from \"@ixfx/numbers\";\nimport { css, html, LitElement } from \"lit\";\nimport { property, state } from \"lit/decorators.js\";\nimport { themeFallbacks } from \"../styles/fallbacks.js\";\nimport { handleStyles } from \"../styles/handle.js\";\nimport { safeCustomElement as customElement } from \"../util/custom-elements.js\";\n\n// TODO: Fire event when panels have been resized\n/**\n * Lays out two elements within a container, with a bar to resize them\n * proportionally.\n *\n * Events\n * ixfx-split-collapsed: Dispatched when a panel is collapsed/uncollapsed via drag.\n * detail: { panel: 'A' | 'B', collapsed: boolean }\n *\n * Attributes\n * layout: `vertical`|`horizontal`\n * sizeA/B: CSS size of section A or B. Can use relative or absolute values\n * fixedA/B: If _true_ size will be calculated in pixels. By default (_false_) it uses % of whole\n * collapsible: If _true_, panels can be collapsed by dragging to edge (default: false)\n * minSizeA/B: Minimum size for panel A or B (e.g., \"100px\" or \"20%\"). Default: none\n * maxSizeA/B: Maximum size for panel A or B (e.g., \"200px\" or \"80%\"). Default: none\n *\n * CSS variables\n * --handle-size: 2px; // Width/height of split bar\n * --handle-colour: var(--surface-5); // Colour of split bar\n * --handle-hover-colour: var(--surface-6); // Split bar on hover\n * --handle-active-colour: var(--accent); // Split bar while dragging\n * --ixfx-handle-* // Grip look — shared handle primitive\n * // (see docs/infra-handle.md)\n */\n@customElement(`ixfx-twosplit-layout`)\nexport class TwoSplitLayoutElement extends LitElement {\n @property({ type: String })\n layout: `vertical` | `horizontal` = `vertical`;\n\n @property({ type: String })\n sizeA = ``;\n\n @property({ type: String })\n sizeB = ``;\n\n @property({ type: Boolean })\n fixedA = false;\n\n @property({ type: Boolean })\n fixedB = false;\n\n @property({ type: Boolean })\n collapsible = false;\n\n @property({ type: Boolean, reflect: true })\n collapsedA = false;\n\n @property({ type: Boolean, reflect: true })\n collapsedB = false;\n\n @property({ type: String })\n minSizeA = ``;\n\n @property({ type: String })\n maxSizeA = ``;\n\n @property({ type: String })\n minSizeB = ``;\n\n @property({ type: String })\n maxSizeB = ``;\n\n @state()\n private _hasCorner = false;\n\n private get showGrabHandle(): boolean {\n const size = getComputedStyle(this).getPropertyValue(`--handle-size`).trim();\n const num = Number.parseFloat(size);\n return !Number.isNaN(num) && num > 3;\n }\n\n #elementBounds: DOMRect | undefined;\n #startSizeA = ``;\n #startSizeB = ``;\n #cornerStartX = 0;\n #cornerStartY = 0;\n #nestedSplitInitialSizeA = ``;\n\n #cornerZone: HTMLElement | undefined;\n #nestedSplit: TwoSplitLayoutElement | undefined;\n #nestedSplitBounds: DOMRect | undefined;\n #nestedHandleBounds: DOMRect | undefined;\n #observer: MutationObserver | undefined;\n #pendingNestedUpdate: { sizeA: number; sizeB: number } | null = null;\n #collapsedAPointerAtCollapse: number | undefined;\n #collapsedBPointerAtCollapse: number | undefined;\n #hysteresisThreshold = 0.1;\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.#observer?.disconnect();\n }\n\n firstUpdated() {\n this.#setupNestedSplitObserver();\n }\n\n updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has(`sizeA`) || changedProperties.has(`sizeB`)\n || changedProperties.has(`collapsedA`) || changedProperties.has(`collapsedB`)) {\n this.#updateCornerPosition();\n }\n if (changedProperties.has(`sizeA`) || changedProperties.has(`sizeB`)) {\n this.#updateDataCollapsed();\n }\n }\n\n #updateDataCollapsed() {\n if (this.collapsedA) {\n this.setAttribute(`data-collapsed-a`, ``);\n } else {\n this.removeAttribute(`data-collapsed-a`);\n }\n if (this.collapsedB) {\n this.setAttribute(`data-collapsed-b`, ``);\n } else {\n this.removeAttribute(`data-collapsed-b`);\n }\n }\n\n #dispatchCollapsedEvent(panel: `A` | `B`, collapsed: boolean) {\n this.dispatchEvent(new CustomEvent(`ixfx-split-collapsed`, {\n detail: { panel, collapsed },\n bubbles: true,\n composed: true,\n }));\n }\n\n #setupNestedSplitObserver() {\n const slotA = this.shadowRoot?.querySelector(`slot[name=\"a\"]`) as HTMLSlotElement | undefined;\n if (!slotA)\n return;\n\n this.#observer = new MutationObserver(() => {\n this.#checkForNestedSplit();\n });\n\n this.#observer.observe(slotA, { characterData: true, childList: true, subtree: true });\n this.#checkForNestedSplit();\n }\n\n #checkForNestedSplit() {\n const slotA = this.shadowRoot?.querySelector(`slot[name=\"a\"]`) as HTMLSlotElement | undefined;\n if (!slotA)\n return;\n\n const assignedElements = slotA.assignedElements();\n\n const findNestedSplit = (elements: Element[]): TwoSplitLayoutElement | undefined => {\n for (const el of elements) {\n if (el.tagName === `IXFX-SPLIT-LAYOUT`) {\n return el as TwoSplitLayoutElement;\n }\n const nested = findNestedSplit(Array.from(el.children));\n if (nested)\n return nested;\n }\n return undefined;\n };\n\n const nestedSplit = findNestedSplit(assignedElements);\n\n if (nestedSplit) {\n this.#nestedSplit = nestedSplit;\n this._hasCorner = true;\n requestAnimationFrame(() => this.#updateCornerPosition());\n } else {\n this.#nestedSplit = undefined;\n this._hasCorner = false;\n }\n }\n\n #getNestedSplit(): TwoSplitLayoutElement | undefined {\n if (this.#nestedSplit)\n return this.#nestedSplit;\n\n const slotA = this.shadowRoot?.querySelector(`slot[name=\"a\"]`) as HTMLSlotElement | undefined;\n if (!slotA)\n return undefined;\n const assignedElements = slotA.assignedElements();\n return assignedElements.find(\n el => el.tagName === `IXFX-SPLIT-LAYOUT`,\n ) as TwoSplitLayoutElement | undefined;\n }\n\n #parseSizeAsFraction(size: string, total: number): number {\n if (size.endsWith(`px`)) {\n return Number.parseFloat(size.replace(`px`, ``)) / total;\n } else if (size.endsWith(`%`)) {\n return Number.parseFloat(size.replace(`%`, ``)) / 100;\n }\n return 0.5;\n }\n\n #parseSizeToPx(size: string, total: number): number | null {\n if (size.endsWith(`px`)) {\n return Number.parseFloat(size.replace(`px`, ``));\n } else if (size.endsWith(`%`)) {\n return (Number.parseFloat(size.replace(`%`, ``)) / 100) * total;\n }\n return null;\n }\n\n #applyConstraints(sizeA: string, sizeB: string, total: number): { sizeA: string; sizeB: string } {\n let fractionA = this.#parseSizeAsFraction(sizeA, total);\n let fractionB = this.#parseSizeAsFraction(sizeB, total);\n\n const minA = this.#minSizeToFraction(this.minSizeA, total);\n const minB = this.#minSizeToFraction(this.minSizeB, total);\n const maxA = this.#maxSizeToFraction(this.maxSizeA, total);\n const maxB = this.#maxSizeToFraction(this.maxSizeB, total);\n\n if (minA !== null || minB !== null) {\n const minSum = (minA ?? 0) + (minB ?? 0);\n if (minSum > 1) {\n const scale = 1 / minSum;\n if (minA !== null)\n minA !== null ? fractionA = minA * scale : fractionA = 0;\n if (minB !== null)\n minB !== null ? fractionB = minB * scale : fractionB = 0;\n }\n\n if (fractionA < (minA ?? 0))\n fractionA = minA ?? 0;\n if (fractionB < (minB ?? 0))\n fractionB = minB ?? 0;\n }\n\n if (maxA !== null) {\n if (fractionA > maxA)\n fractionA = maxA;\n }\n if (maxB !== null) {\n if (fractionB > maxB)\n fractionB = maxB;\n }\n\n fractionB = 1 - fractionA;\n\n const isPercentA = !this.sizeA.endsWith(`px`);\n const _isPercentB = !this.sizeB.endsWith(`px`);\n\n if (isPercentA) {\n return { sizeA: `${fractionA * 100}%`, sizeB: `${fractionB * 100}%` };\n } else {\n return { sizeA: `${fractionA * total}px`, sizeB: `${fractionB * total}px` };\n }\n }\n\n #minSizeToFraction(minSize: string, total: number): number | null {\n if (minSize.length === 0)\n return null;\n const px = this.#parseSizeToPx(minSize, total);\n if (px !== null)\n return px / total;\n if (minSize.endsWith(`%`))\n return Number.parseFloat(minSize.replace(`%`, ``)) / 100;\n return null;\n }\n\n #maxSizeToFraction(maxSize: string, total: number): number | null {\n if (maxSize.length === 0)\n return null;\n const px = this.#parseSizeToPx(maxSize, total);\n if (px !== null)\n return px / total;\n if (maxSize.endsWith(`%`))\n return Number.parseFloat(maxSize.replace(`%`, ``)) / 100;\n return null;\n }\n\n #getIntersectionPoint(): { x: number; y: number } | null {\n const outerBounds = this.getBoundingClientRect();\n const zoneEl = this.getZone();\n if (!zoneEl)\n return null;\n\n const nestedSplit = this.#getNestedSplit();\n if (!nestedSplit)\n return null;\n\n const _zoneBounds = zoneEl.getBoundingClientRect();\n\n const outerFraction = this.#parseSizeAsFraction(this.sizeA || `50%`, outerBounds.width);\n\n let x: number, y: number;\n\n if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {\n x = outerFraction * outerBounds.width;\n const nestedFraction = this.#parseSizeAsFraction(nestedSplit.sizeA || `50%`, outerBounds.height);\n y = nestedFraction * outerBounds.height;\n } else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {\n const nestedFraction = this.#parseSizeAsFraction(nestedSplit.sizeA || `50%`, outerBounds.width);\n x = nestedFraction * outerBounds.width;\n y = outerFraction * outerBounds.height;\n } else {\n return null;\n }\n\n return { x, y };\n }\n\n #updateCornerPosition() {\n if (!this._hasCorner)\n return;\n\n const cornerZone = this.shadowRoot?.querySelector(`.corner-zone`) as HTMLElement | undefined;\n if (!cornerZone)\n return;\n\n const zoneEl = this.getZone();\n if (!zoneEl)\n return;\n\n const intersection = this.#getIntersectionPoint();\n if (!intersection) {\n cornerZone.style.display = `none`;\n return;\n }\n\n const cornerX = intersection.x - 6;\n const cornerY = intersection.y - 6;\n\n cornerZone.style.left = `${cornerX}px`;\n cornerZone.style.top = `${cornerY}px`;\n cornerZone.style.display = `block`;\n\n const nestedSplit = this.#getNestedSplit();\n if (nestedSplit) {\n if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {\n cornerZone.style.cursor = `nwse-resize`;\n } else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {\n cornerZone.style.cursor = `nesw-resize`;\n }\n }\n }\n\n getZone(): HTMLElement | undefined {\n if (!this.shadowRoot)\n return;\n const el = this.shadowRoot.querySelector(`#zone`);\n if (!el)\n return undefined;\n return el as HTMLElement;\n }\n\n #onResizeHandleDown = (event: PointerEvent) => {\n event.preventDefault();\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.add(`user-resizing`);\n }\n this.#elementBounds = this.getBoundingClientRect();\n this.#startSizeA = this.sizeA;\n this.#startSizeB = this.sizeB;\n window.addEventListener(`pointerup`, this.#onResizeHandleUp);\n window.addEventListener(`pointermove`, this.#onResizeHandleMove);\n };\n\n #onResizeHandleUp = (event: PointerEvent) => {\n event.preventDefault();\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.remove(`user-resizing`);\n }\n window.removeEventListener(`pointerup`, this.#onResizeHandleUp);\n window.removeEventListener(`pointermove`, this.#onResizeHandleMove);\n };\n\n #onResizeHandleMove = (event: PointerEvent) => {\n const bounds = this.#elementBounds;\n if (!bounds)\n return;\n\n const threshold = 5;\n\n if (this.layout === `horizontal`) {\n const y = event.y - bounds.y;\n const relativeY = clamp(y / bounds.height);\n\n if (this.collapsible && this.collapsedA) {\n if (relativeY > (this.#collapsedAPointerAtCollapse ?? 0.05) + this.#hysteresisThreshold) {\n this.collapsedA = false;\n this.#dispatchCollapsedEvent(`A`, false);\n this.#collapsedAPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeY * 100}%`,\n `${(1 - relativeY) * 100}%`,\n bounds.height,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedA && relativeY < threshold / bounds.height) {\n this.collapsedA = true;\n this.#dispatchCollapsedEvent(`A`, true);\n this.sizeA = `0px`;\n this.sizeB = `100%`;\n this.#collapsedAPointerAtCollapse = relativeY;\n } else if (!this.collapsedA) {\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeY * 100}%`,\n `${(1 - relativeY) * 100}%`,\n bounds.height,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n\n if (this.collapsible && this.collapsedB) {\n if (relativeY < (this.#collapsedBPointerAtCollapse ?? 0.95) - this.#hysteresisThreshold) {\n this.collapsedB = false;\n this.#dispatchCollapsedEvent(`B`, false);\n this.#collapsedBPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeY * 100}%`,\n `${(1 - relativeY) * 100}%`,\n bounds.height,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedB && relativeY > (1 - threshold / bounds.height)) {\n this.collapsedB = true;\n this.#dispatchCollapsedEvent(`B`, true);\n this.sizeA = `100%`;\n this.sizeB = `0px`;\n this.#collapsedBPointerAtCollapse = relativeY;\n }\n } else {\n const x = event.x - bounds.x;\n const relativeX = clamp(x / bounds.width);\n\n if (this.collapsible && this.collapsedA) {\n if (relativeX > (this.#collapsedAPointerAtCollapse ?? 0.05) + this.#hysteresisThreshold) {\n this.collapsedA = false;\n this.#dispatchCollapsedEvent(`A`, false);\n this.#collapsedAPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeX * 100}%`,\n `${(1 - relativeX) * 100}%`,\n bounds.width,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedA && relativeX < threshold / bounds.width) {\n this.collapsedA = true;\n this.#dispatchCollapsedEvent(`A`, true);\n this.sizeA = `0px`;\n this.sizeB = `100%`;\n this.#collapsedAPointerAtCollapse = relativeX;\n } else if (!this.collapsedA) {\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeX * 100}%`,\n `${(1 - relativeX) * 100}%`,\n bounds.width,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n\n if (this.collapsible && this.collapsedB) {\n if (relativeX < (this.#collapsedBPointerAtCollapse ?? 0.95) - this.#hysteresisThreshold) {\n this.collapsedB = false;\n this.#dispatchCollapsedEvent(`B`, false);\n this.#collapsedBPointerAtCollapse = undefined;\n const { sizeA, sizeB } = this.#applyConstraints(\n `${relativeX * 100}%`,\n `${(1 - relativeX) * 100}%`,\n bounds.width,\n );\n this.sizeA = sizeA;\n this.sizeB = sizeB;\n }\n } else if (this.collapsible && !this.collapsedB && relativeX > (1 - threshold / bounds.width)) {\n this.collapsedB = true;\n this.#dispatchCollapsedEvent(`B`, true);\n this.sizeA = `100%`;\n this.sizeB = `0px`;\n this.#collapsedBPointerAtCollapse = relativeX;\n }\n }\n event.preventDefault();\n };\n\n #onCornerResizeDown = (event: PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.add(`user-resizing`);\n }\n\n this.#elementBounds = this.getBoundingClientRect();\n this.#cornerStartX = event.clientX;\n this.#cornerStartY = event.clientY;\n this.#startSizeA = this.sizeA;\n this.#startSizeB = this.sizeB;\n\n const nestedSplit = this.#getNestedSplit();\n if (nestedSplit) {\n this.#nestedSplitInitialSizeA = nestedSplit.sizeA;\n const nestedBounds = nestedSplit.getBoundingClientRect();\n const nestedHandle = nestedSplit.shadowRoot?.querySelector(`.split-bar`) as HTMLElement;\n if (nestedHandle) {\n this.#nestedSplitBounds = nestedBounds;\n this.#nestedHandleBounds = nestedHandle.getBoundingClientRect();\n }\n const nestedZoneEl = nestedSplit.getZone();\n if (nestedZoneEl) {\n nestedZoneEl.classList.add(`user-resizing`);\n }\n }\n\n window.addEventListener(`pointerup`, this.#onCornerResizeUp);\n window.addEventListener(`pointermove`, this.#onCornerResizeMove);\n };\n\n #onCornerResizeUp = (event: PointerEvent) => {\n event.preventDefault();\n const zoneEl = this.getZone();\n if (zoneEl) {\n zoneEl.classList.remove(`user-resizing`);\n }\n const nestedSplit = this.#getNestedSplit();\n if (nestedSplit) {\n const nestedZoneEl = nestedSplit.getZone();\n if (nestedZoneEl) {\n nestedZoneEl.classList.remove(`user-resizing`);\n }\n }\n window.removeEventListener(`pointerup`, this.#onCornerResizeUp);\n window.removeEventListener(`pointermove`, this.#onCornerResizeMove);\n };\n\n #applyPendingNestedUpdate() {\n if (!this.#pendingNestedUpdate)\n return;\n const { sizeA, sizeB } = this.#pendingNestedUpdate;\n const nested = this.#getNestedSplit();\n if (nested) {\n nested.sizeA = `${sizeA * 100}%`;\n nested.sizeB = `${sizeB * 100}%`;\n }\n this.#pendingNestedUpdate = null;\n }\n\n #onCornerResizeMove = (event: PointerEvent) => {\n const outerBounds = this.#elementBounds;\n const zoneEl = this.getZone();\n const nestedSplit = this.#getNestedSplit();\n if (!outerBounds || !zoneEl || !nestedSplit)\n return;\n\n const zoneBounds = zoneEl.getBoundingClientRect();\n const cursorZoneLocalX = event.clientX - zoneBounds.left;\n const cursorZoneLocalY = event.clientY - zoneBounds.top;\n\n if (this.layout === `vertical` && nestedSplit.layout === `horizontal`) {\n let newOuterFraction = cursorZoneLocalX / outerBounds.width;\n const newNestedFraction = cursorZoneLocalY / outerBounds.height;\n\n const { sizeA: constrainedA, sizeB: constrainedB } = this.#applyConstraints(\n `${newOuterFraction * 100}%`,\n `${(1 - newOuterFraction) * 100}%`,\n outerBounds.width,\n );\n newOuterFraction = this.#parseSizeAsFraction(constrainedA, outerBounds.width);\n\n this.sizeA = constrainedA;\n this.sizeB = constrainedB;\n\n this.#pendingNestedUpdate = {\n sizeA: newNestedFraction,\n sizeB: 1 - newNestedFraction,\n };\n requestAnimationFrame(() => this.#applyPendingNestedUpdate());\n\n const cornerZone = this.shadowRoot?.querySelector(`.corner-zone`) as HTMLElement | undefined;\n if (cornerZone) {\n cornerZone.style.left = `${cursorZoneLocalX - 6}px`;\n cornerZone.style.top = `${cursorZoneLocalY - 6}px`;\n }\n } else if (this.layout === `horizontal` && nestedSplit.layout === `vertical`) {\n const newNestedFraction = cursorZoneLocalX / outerBounds.width;\n let newOuterFraction = cursorZoneLocalY / outerBounds.height;\n\n const { sizeA: constrainedA, sizeB: constrainedB } = this.#applyConstraints(\n `${newOuterFraction * 100}%`,\n `${(1 - newOuterFraction) * 100}%`,\n outerBounds.height,\n );\n newOuterFraction = this.#parseSizeAsFraction(constrainedA, outerBounds.height);\n\n this.sizeA = constrainedA;\n this.sizeB = constrainedB;\n\n this.#pendingNestedUpdate = {\n sizeA: newNestedFraction,\n sizeB: 1 - newNestedFraction,\n };\n requestAnimationFrame(() => this.#applyPendingNestedUpdate());\n\n const cornerZone = this.shadowRoot?.querySelector(`.corner-zone`) as HTMLElement | undefined;\n if (cornerZone) {\n cornerZone.style.left = `${cursorZoneLocalX - 6}px`;\n cornerZone.style.top = `${cursorZoneLocalY - 6}px`;\n }\n }\n\n event.preventDefault();\n };\n\n render() {\n const sizePrefix = this.layout === `vertical` ? `width` : `height`;\n let sizeA = this.sizeA;\n let sizeB = this.sizeB;\n\n if (this.collapsedA) {\n sizeA = `0px`;\n } else if (sizeA.length === 0 && sizeB.length === 0) {\n sizeB = sizeA = `50%`;\n } else if (sizeA.length === 0) {\n sizeA = `auto`;\n } else if (sizeB.length === 0) {\n sizeB = `auto`;\n }\n\n if (this.collapsedB) {\n sizeB = `0px`;\n }\n\n sizeA = `${sizePrefix}:${sizeA}`;\n sizeB = `${sizePrefix}:${sizeB}`;\n\n return html`\n <div id=\"zone\">\n <slot style=${sizeA} name=\"a\"></slot>\n ${this._hasCorner ? html`<div class=\"corner-zone\" @pointerdown=${this.#onCornerResizeDown}></div>` : ``}\n <div @pointerdown=${this.#onResizeHandleDown} class=\"split-bar\">\n ${this.showGrabHandle\n ? html`<span\n class=\"ixfx-handle\"\n part=\"grip\"\n data-handle=\"dimpled\"\n data-shape=${this.layout === `horizontal` ? `horizontal` : `vertical`}\n ></span>`\n : ``}\n </div>\n <slot style=${sizeB} name=\"b\"></slot>\n </div>`;\n }\n\n static styles = [themeFallbacks, handleStyles, css`\n :host {\n --handle-size: 2px;\n --handle-colour: transparent;\n --handle-hover-colour: var(--surface-6);\n --handle-active-colour: var(--accent);\n /* Grip — shared handle primitive (docs/infra-handle.md). */\n --ixfx-handle-length: 16px;\n --ixfx-handle-thickness: 8px;\n\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n }\n * {\n box-sizing: border-box;\n }\n #zone {\n display: flex;\n height: 100%;\n position: relative;\n }\n slot {\n display: block;\n overflow: hidden;\n border: var(--border-subtle);\n border-radius: var(--radius-m);\n }\n :slotted(*) {\n width: 100%;\n height: 100%;\n }\n\n .split-bar {\n position: relative;\n background-color: var(--handle-colour);\n transition: background-color 0.3s ease 0s;\n width: var(--handle-size);\n height: 100%;\n cursor: ew-resize;\n flex-shrink: 0;\n border-radius: var(--radius-m);\n\n }\n\n @keyframes handle-hover {\n from { background-color: var(--handle-colour); }\n to { background-color: var(--handle-hover-colour); }\n }\n\n .split-bar .ixfx-handle {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n }\n\n #zone.user-resizing .ixfx-handle {\n display: none;\n }\n #zone.user-resizing {\n slot {\n opacity: 0.5;\n }\n .split-bar {\n background-color: var(--handle-active-colour);\n transition: none;\n animation: none !important;\n }\n }\n\n #zone:not(.user-resizing) .split-bar:hover {\n animation: handle-hover 0.001s ease-out 0.7s both;\n }\n\n .corner-zone {\n position: absolute;\n width: 12px;\n height: 12px;\n z-index: 10;\n border-radius: 50%;\n background: transparent;\n }\n .corner-zone:hover {\n background: transparent;\n }\n\n :host([layout='horizontal']) {\n #zone {\n flex-direction: column;\n }\n .split-bar {\n position: relative;\n background-color: var(--handle-colour);\n transition: background-color 0.3s ease 0s;\n height: var(--handle-size);\n width: 100%;\n cursor: ns-resize;\n }\n #zone.user-resizing .split-bar {\n background-color: var(--handle-active-colour);\n transition: none;\n animation: none !important;\n }\n }\n\n :host([data-collapsed-a]) slot[name=\"a\"],\n :host([data-collapsed-b]) slot[name=\"b\"] {\n display: none;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"ixfx-twosplit-layout\": TwoSplitLayoutElement;\n }\n}\n","interface CheckboxLike extends HTMLElement {\n checked: boolean;\n indeterminate?: boolean;\n}\n\nfunction isCheckboxLike(el: unknown): el is CheckboxLike {\n if (!(el instanceof HTMLElement))\n return false;\n return `checked` in el;\n}\n\nfunction resolveElement(elOrQuery: string | HTMLElement): HTMLElement {\n if (typeof elOrQuery === `string`) {\n const found = document.querySelector(elOrQuery);\n if (!(found instanceof HTMLElement))\n throw new Error(`Element not found or not HTMLElement: ${elOrQuery}`);\n return found;\n }\n return elOrQuery;\n}\n\nexport function monitorIndeterminate(\n targetElOrQuery: string | HTMLElement,\n watchedElsOrQueries: Array<string | HTMLElement>,\n): () => void {\n const target = resolveElement(targetElOrQuery);\n if (!isCheckboxLike(target)) {\n throw new Error(`Target element is not a checkbox-like element`);\n }\n\n const watched: CheckboxLike[] = [];\n for (const elOrQuery of watchedElsOrQueries) {\n const el = resolveElement(elOrQuery);\n if (isCheckboxLike(el)) {\n watched.push(el);\n }\n }\n\n const updateTarget = () => {\n if (watched.length === 0) {\n target.checked = false;\n target.indeterminate = false;\n return;\n }\n\n let checkedCount = 0;\n let uncheckedCount = 0;\n\n for (const el of watched) {\n if (el.checked) {\n checkedCount++;\n } else {\n uncheckedCount++;\n }\n }\n\n if (checkedCount > 0 && uncheckedCount > 0) {\n target.checked = false;\n target.indeterminate = true;\n } else if (checkedCount === watched.length) {\n target.checked = true;\n target.indeterminate = false;\n } else {\n target.checked = false;\n target.indeterminate = false;\n }\n };\n\n const handleChange = () => {\n updateTarget();\n };\n\n for (const el of watched) {\n el.addEventListener(`change`, handleChange);\n }\n\n updateTarget();\n\n return () => {\n for (const el of watched) {\n el.removeEventListener(`change`, handleChange);\n }\n };\n}\n","import \"./style.css\";\n\nexport * from './ac-text/ac-text.js';\nexport * from './ac-token/ac-token.js';\nexport * from './bottom-drawer/bottom-drawer.js';\nexport * from './button/button.js';\nexport * from './button/radio-group.js';\nexport * from './button/split-button.js';\nexport * from './button/types.js';\nexport * from './checkbox/checkbox.js';\nexport * from './colour-picker/index.js';\nexport * from './common/data-controller.js';\nexport * from './common/data-provider.js';\nexport * from './common/searchable.js';\nexport * from './common/tree-component.js';\nexport * from './common/tree-data-model.js';\nexport * from './common/tree-drop-apply.js';\nexport * from './common/types.js';\nexport * from './crumbs/crumb-navigation.js';\nexport * from './crumbs/crumb-path-controller.js';\nexport * from './crumbs/crumb-path.js';\n\nexport * from './data-display/data-display.js';\nexport * from './data-grid/data-grid.js';\nexport * from './data-table/data-table.js';\nexport * from './detail-list/detail-list.js';\nexport {\n getActiveDragPanelId,\n isDragging,\n pointerOverAnyHost,\n} from './dock/dock-drag.js';\nexport type { DockDropZone } from './dock/dock-drag.js';\nexport * from './dock/dock-host.js';\nexport * from './dock/dock-model.js';\nexport * from './dock/dock-panel.js';\nexport * from './dock/types.js';\nexport * from './editable-label/editable-label.js';\nexport * from './editable-label/editable-number.js';\nexport * from './form/form-group.js';\nexport * from './form/form-part.js';\nexport * from './form/form.js';\nexport * from './grid-list/grid-list.js';\nexport * from './grouped-item-lister/grouped-item-lister.js';\nexport * from './grouped-item-lister/tree-list-adapter.js';\nexport * from './grouped-item-lister/vertical-list-adapter.js';\nexport * from './hex/hex-editor.js';\nexport * from './hyperbolic-tree/hyperbolictree-list.js';\nexport * from './hyperbolic-tree/layout.js';\nexport * from './hyperbolic-tree/poincare-math.js';\nexport type { HyperbolicNodeShape } from './hyperbolic-tree/render-utils.js';\nexport type {\n ComputeHyperbolicLayoutOptions,\n HyperbolicEdgeRenderContext,\n HyperbolicEdgeRenderer,\n HyperbolicFocusDetail,\n HyperbolicFocusEvent,\n HyperbolicInteractionMode,\n HyperbolicLayoutEdge,\n HyperbolicLayoutNode,\n Point as HyperbolicPoint,\n} from './hyperbolic-tree/types.js';\nexport * from './icicle-tree/icicletree-list.js';\nexport * from './icicle-tree/layout.js';\nexport * from './icicle-tree/types.js';\nexport * from './icons/index.js';\nexport * from './incr-search/index.js';\nexport * from './interaction/index.js';\nexport * from './labelled-radial-input/index.js';\nexport * from './labelled-range-input/index.js';\nexport * from './labelled-slider-input/index.js';\nexport * from './led/led.js';\nexport * as Menu from './menu';\nexport * from './miller/index.js';\nexport * from './multicol-list/multicol-list.js';\nexport * from './narrowed-text/index.js';\nexport * from './notifier/manager.js';\nexport * from './notifier/notification-pill.js';\nexport * from './notifier/pill-renderer.js';\nexport * from './notifier/types.js';\nexport * from './pan-text/index.js';\nexport * from './panel/panel-group.js';\nexport * from './panel/panel.js';\nexport * from './plots/colour-map.js';\nexport * from './plots/data.js';\nexport * from './plots/multi-axis.js';\nexport * from './plots/plot-histogram.js';\nexport * from './plots/single-axis.js';\nexport * from './plots/xy-axis.js';\nexport * from './polar-pad/polar-pad.js';\nexport * from './radial-input/radial-input.js';\nexport * from './radial-input/types.js';\nexport * from './range-input/index.js';\nexport * from './range/range-multi.js';\nexport * from './range/range.js';\nexport * from './rating/rating.js';\nexport * from './select-horiz/select-horiz.js';\nexport * from './shapefill-value/shapefill-value.js';\nexport * from './shapefill-value/types.js';\nexport * from './slider-input/slider-input.js';\nexport * from './slider-input/types.js';\nexport * from './sliding-number/sliding-number.js';\nexport * from './snackbar/snackbar.js';\nexport * from './snap-container/snap-container.js';\nexport * from './split-layout/split-layout.js';\nexport * from './split-layout/split-model.js';\nexport * from './split-layout/split-panel.js';\nexport * from './split-layout/types.js';\nexport * from './swipe/index.js';\nexport * from './tabs/tab-controller.js';\nexport * from './tabs/tab-list-item.js';\nexport * from './tabs/tab-list.js';\nexport * from './tabs/tab-panel.js';\nexport * from './tabs/tab-panels.js';\nexport * from './text-shimmer/text-shimmer.js';\nexport * from './timeline/index.js';\nexport * from './titlebar/titlebar.js';\nexport * from './toolbar/toolbar-group.js';\nexport * from './toolbar/toolbar.js';\nexport * from './toolbar/types.js';\nexport * from './transitory-label/transitory-label.js';\nexport * from './tree/index.js';\nexport { computeTreemapLayout, findTreemapNode, findTreemapPath } from './treemap/layout.js';\nexport * from './treemap/treemap-list.js';\nexport type { ComputeTreemapLayoutOptions, TreemapInteractionMode, TreemapRect, TreemapTilingMethod, TreemapValueAccessor } from './treemap/types.js';\nexport * from './twosplit-layout/split-layout.js';\nexport * from './util/checkbox.js';\nexport * from './util/tooltip.js';\nexport * from './vertical-list/vertical-list.js';\nexport * from './xy-pad/xy-pad.js';\nexport function init() {\n console.log(`Init`);\n}\n"],"mappings":"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"}
|