@ixfx/components 0.8.7 → 0.8.9

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.
Files changed (85) hide show
  1. package/bundle/index.d.ts +743 -383
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +2093 -222
  4. package/bundle/index.js.map +1 -1
  5. package/dist/crumbs.d.ts +1 -1
  6. package/dist/crumbs.js +2 -2
  7. package/dist/{data-grid-CYVPSUwh.d.ts → data-grid-C588pTgt.d.ts} +15 -2
  8. package/dist/data-grid-C588pTgt.d.ts.map +1 -0
  9. package/dist/data-grid.d.ts +3 -2
  10. package/dist/data-grid.js +95 -5
  11. package/dist/data-grid.js.map +1 -1
  12. package/dist/{detail-list-vH56z7WE.d.ts → detail-list-IKl76Wnp.d.ts} +22 -5
  13. package/dist/detail-list-IKl76Wnp.d.ts.map +1 -0
  14. package/dist/detail-list.d.ts +4 -3
  15. package/dist/detail-list.js +103 -3
  16. package/dist/detail-list.js.map +1 -1
  17. package/dist/{grid-list-Cq8ga2WZ.d.ts → grid-list-BUlUnisU.d.ts} +214 -112
  18. package/dist/grid-list-BUlUnisU.d.ts.map +1 -0
  19. package/dist/{grid-list-j5C7qtlG.js → grid-list-D18FNJRH.js} +77 -164
  20. package/dist/grid-list-D18FNJRH.js.map +1 -0
  21. package/dist/grid-list.d.ts +3 -2
  22. package/dist/grid-list.js +1 -1
  23. package/dist/incr-search.d.ts +1 -1
  24. package/dist/{index-DDREWqMm.d.ts → index--qnhBWZJ.d.ts} +2 -2
  25. package/dist/{index-DDREWqMm.d.ts.map → index--qnhBWZJ.d.ts.map} +1 -1
  26. package/dist/index.d.ts +212 -253
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +13 -12
  29. package/dist/index.js.map +1 -1
  30. package/dist/{interaction-B9AAlsFO.js → interaction-BskmlA9t.js} +1 -1
  31. package/dist/{labelled-slider-input-BCH9968c.js → labelled-slider-input-aEYDvW2S.js} +2 -2
  32. package/dist/{labelled-slider-input-BCH9968c.js.map → labelled-slider-input-aEYDvW2S.js.map} +1 -1
  33. package/dist/labelled-slider-input.js +1 -1
  34. package/dist/{list-item-animation-DuiwgN3l.js → list-item-animation-BUoEKi5s.js} +29 -10
  35. package/dist/list-item-animation-BUoEKi5s.js.map +1 -0
  36. package/dist/list-native-drag-controller-CFyrkKUj.d.ts +61 -0
  37. package/dist/list-native-drag-controller-CFyrkKUj.d.ts.map +1 -0
  38. package/dist/list-native-drag-controller-DxD6Yjci.js +567 -0
  39. package/dist/list-native-drag-controller-DxD6Yjci.js.map +1 -0
  40. package/dist/{menu-HMoxCPY2.js → menu-CMXhIaNZ.js} +3 -3
  41. package/dist/{menu-HMoxCPY2.js.map → menu-CMXhIaNZ.js.map} +1 -1
  42. package/dist/{menu-item-BQDYxk5A.js → menu-item-BYGQzyCe.js} +2 -2
  43. package/dist/{menu-item-BQDYxk5A.js.map → menu-item-BYGQzyCe.js.map} +1 -1
  44. package/dist/menu.js +2 -2
  45. package/dist/miller.d.ts +2 -2
  46. package/dist/miller.js +1 -1
  47. package/dist/narrowed-text.js +1 -1
  48. package/dist/plots.js +1 -1
  49. package/dist/select-horiz.js +1 -1
  50. package/dist/slider-input-BxURAAmD.d.ts.map +1 -1
  51. package/dist/{slider-input-WR8_RwHg.js → slider-input-Cb5uSV42.js} +78 -11
  52. package/dist/slider-input-Cb5uSV42.js.map +1 -0
  53. package/dist/slider-input.js +1 -1
  54. package/dist/{tree-CozQj01a.js → tree-a14n9y7i.js} +1055 -32
  55. package/dist/tree-a14n9y7i.js.map +1 -0
  56. package/dist/{tree-component-BMpxpdTi.d.ts → tree-component-BW2iCFq9.d.ts} +108 -4
  57. package/dist/tree-component-BW2iCFq9.d.ts.map +1 -0
  58. package/dist/tree.d.ts +102 -4
  59. package/dist/tree.d.ts.map +1 -1
  60. package/dist/tree.js +2 -2
  61. package/dist/{vertical-list-BGn9nyKh.d.ts → vertical-list-CHrXmmQ3.d.ts} +21 -4
  62. package/dist/vertical-list-CHrXmmQ3.d.ts.map +1 -0
  63. package/dist/vertical-list.d.ts +3 -2
  64. package/dist/vertical-list.js +103 -3
  65. package/dist/vertical-list.js.map +1 -1
  66. package/dist/{xy-axis-CrrVdDFe.js → xy-axis-COKw338Q.js} +2 -2
  67. package/dist/xy-axis-COKw338Q.js.map +1 -0
  68. package/dist/xy-axis-DQqd2yXJ.d.ts.map +1 -1
  69. package/docs-user/data-grid.md +30 -0
  70. package/docs-user/detail-list.md +29 -0
  71. package/docs-user/grid-list.md +34 -4
  72. package/docs-user/index.json +2 -2
  73. package/docs-user/tree.md +76 -1
  74. package/docs-user/vertical-list.md +30 -1
  75. package/package.json +1 -1
  76. package/dist/data-grid-CYVPSUwh.d.ts.map +0 -1
  77. package/dist/detail-list-vH56z7WE.d.ts.map +0 -1
  78. package/dist/grid-list-Cq8ga2WZ.d.ts.map +0 -1
  79. package/dist/grid-list-j5C7qtlG.js.map +0 -1
  80. package/dist/list-item-animation-DuiwgN3l.js.map +0 -1
  81. package/dist/slider-input-WR8_RwHg.js.map +0 -1
  82. package/dist/tree-CozQj01a.js.map +0 -1
  83. package/dist/tree-component-BMpxpdTi.d.ts.map +0 -1
  84. package/dist/vertical-list-BGn9nyKh.d.ts.map +0 -1
  85. package/dist/xy-axis-CrrVdDFe.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"slider-input-WR8_RwHg.js","names":["#currentCrossPx","#currentLongPx","#onKeyDown","#ensureUserGradientDefs","#applySwipeFromPointer","#relativeFromTrackPos","#lastInteractedHandle","#dragHandle","#setSingleValueFromRelative","#dragging","#activePointerId","#dragStartClientPos","#poleValueAtDragStart","#onPointerMove","#onPointerUp","#getRelativeValueA","#getRelativeValueB","#poleA","#poleB","#getRelativeValueC","#lowKey","#highKey","#lengthDragStart","#lengthDragLowKey","#lengthDragHighKey","#lengthDragLength","#lengthDragStartLow","#lengthDragStartRelative","#setDualOrTripleValueFromRelative","#applyLengthDragFromRelative","#onPointerMoveCursor","#lastPointerClient","#poleC","#low","#stepHandleByRelativeDelta","#cursorAtRelative","#lanes","#onHostKeyDown","#onSwipePointerDown","#onSwipePointerMove","#onSwipePointerEnter","#syncGradientDefs","#gradientObserver","#sizeObserver","#onHostResize","#userGradientDefs","#quantise","#isUserInteraction","#applySingleStyleValueLane","#emitInputAndChange","#resolvePoleChange","#poles","#syncPoleProperties","#detectChanged","#high","#hasInitialisedValueC","#getEffectiveValueMin","#buildInputDetail","#buildChangeDetail","#scheduleChangeEvent","#fireChangeEvent","#changeDebounceTimer","#laneWidthNumber","#currentLanePxMax","#getCssVar","#dotRadiusPx","#dotRadiusFraction","#activeMarkerStyles","#contentFraction","#currentInsetStart","#currentInsetEnd","#relativeFromSwipePointer","#currentCross","#getCssVarColor","#laneStrokePx","#circleRadiiUnits","#measureLanes","#computeCross","#computeInsets","#isMultiHandle","#renderHandleGroup","#renderValueMarker","#viewBox","#onPointerDown","#onPointerLeaveCursor","#onFocusIn","#renderTrack","#renderLane","#renderMidpointMarker","customElement"],"sources":["../src/slider-input/svg-utils.ts","../src/slider-input/slider-input.ts"],"sourcesContent":["/**\n * SVG utilities for the slider-input component.\n * Linear track geometry helpers (mirrors radial-input's svg-utils for arc maths).\n */\n\nimport type { SliderOrientation, SliderSingleStyle } from './types.js';\n\nexport interface Point {\n x: number;\n y: number;\n}\n\n/**\n * Track geometry in viewBox units.\n * Horizontal: trackStart = insetStart, trackEnd = 100 - insetEnd (along x).\n * Vertical: trackStart = insetStart, trackEnd = 100 - insetEnd (along y,\n * top = high). \"Start\" is the low-value end (left / bottom).\n */\nexport interface TrackBounds {\n trackStart: number;\n trackEnd: number;\n /** Centre along the long axis (midpoint of the drawn track span). */\n centre: number;\n /** Cross-axis size of the viewBox (dynamic per instance; CROSS is the legacy default). */\n cross: number;\n /** Centre along the cross axis (cross / 2). */\n crossCentre: number;\n}\n\nexport const INSET = 5;\nexport const LONG = 100;\nexport const CROSS = 24;\n\n/**\n * Get the track bounds in viewBox units for a given orientation.\n *\n * `cross` is the dynamic cross-axis size (see `SliderInputElement`'s\n * cross computation); `insetStart`/`insetEnd` are the long-axis end\n * paddings (low-value end / high-value end). LONG stays fixed at 100.\n */\nexport function getTrackBounds(\n orientation: SliderOrientation,\n cross: number = CROSS,\n insetStart: number = INSET,\n insetEnd: number = INSET,\n): TrackBounds {\n const trackStart = insetStart;\n const trackEnd = LONG - insetEnd;\n if (orientation === `horizontal`) {\n return {\n trackStart,\n trackEnd,\n centre: (trackStart + trackEnd) / 2,\n cross,\n crossCentre: cross / 2,\n };\n }\n // Vertical: viewBox is 0 0 cross LONG; the track runs along the y axis from\n // insetStart to LONG-insetEnd. `centre` is the middle of the drawn track\n // span; `crossCentre` is the middle of the cross (x) axis.\n return {\n trackStart,\n trackEnd,\n centre: (trackStart + trackEnd) / 2,\n cross,\n crossCentre: cross / 2,\n };\n}\n\n/**\n * Map a relative value (0..1) to a leader point on the track for the given\n * orientation and single-style.\n *\n * Range: grows from trackStart to trackEnd.\n * Bipolar: track centre is 0.5; values spread from centre outward.\n * Unipolar: spread symmetrically around centre.\n *\n * For vertical orientation, higher values are toward the top of the track,\n * matching the spec (\"higher values → top of track\").\n */\nexport function valueToPosition(\n relativeValue: number,\n singleStyle: SliderSingleStyle,\n trackBounds: TrackBounds,\n orientation: SliderOrientation,\n): Point {\n const span = trackBounds.trackEnd - trackBounds.trackStart;\n const centre = trackBounds.centre;\n const crossCentre = trackBounds.crossCentre;\n\n let pos: number;\n if (singleStyle === `range`) {\n pos = trackBounds.trackStart + relativeValue * span;\n } else if (singleStyle === `bipolar`) {\n // Mid (0.5) -> centre; <0.5 below centre, >0.5 above.\n if (relativeValue <= 0.5) {\n const t = relativeValue / 0.5;\n pos = trackBounds.trackStart + t * (centre - trackBounds.trackStart);\n } else {\n const t = (relativeValue - 0.5) / 0.5;\n pos = centre + t * (trackBounds.trackEnd - centre);\n }\n } else {\n // unipolar: spread symmetrically around centre\n const halfLen = (relativeValue * span) / 2;\n pos = centre + halfLen;\n }\n\n if (orientation === `horizontal`) {\n return { x: pos, y: crossCentre };\n }\n // Vertical: higher values toward top (smaller y). `pos` is a value along the\n // long axis (0..LONG), so the SVG y coordinate (0 at top) is LONG - pos.\n return { x: crossCentre, y: LONG - pos };\n}\n\n/**\n * Get the segment endpoints for a 'value' lane. The lane is drawn from\n * the lane's lower relative value to its upper relative value.\n *\n * For 'range' and 'bipolar' styles, the endpoints are obtained by mapping\n * each value through `valueToPosition`. For 'unipolar', the bar is centred\n * on the track centre with length proportional to valueMax (valueMin is\n * ignored), matching the spec: \"spreads symmetrically around centre\".\n */\nexport function getValueSegment(\n valueMin: number,\n valueMax: number,\n singleStyle: SliderSingleStyle,\n trackBounds: TrackBounds,\n orientation: SliderOrientation,\n): { start: Point; end: Point } {\n if (singleStyle === `unipolar`) {\n const span = trackBounds.trackEnd - trackBounds.trackStart;\n const centre = trackBounds.centre;\n const crossCentre = trackBounds.crossCentre;\n const halfLen = (valueMax * span) / 2;\n if (orientation === `horizontal`) {\n return {\n start: { x: centre - halfLen, y: crossCentre },\n end: { x: centre + halfLen, y: crossCentre },\n };\n }\n // Vertical: spread the bar symmetrically around the track centre along y.\n return {\n start: { x: crossCentre, y: centre - halfLen },\n end: { x: crossCentre, y: centre + halfLen },\n };\n }\n\n return {\n start: valueToPosition(valueMin, singleStyle, trackBounds, orientation),\n end: valueToPosition(valueMax, singleStyle, trackBounds, orientation),\n };\n}\n\n/**\n * Get the segment endpoints for an 'anchored' lane. The lane is centered\n * on the current value, with length controlled by laneValue (0..1).\n */\nexport function getAnchoredSegment(\n relativeValue: number,\n laneValue: number,\n singleStyle: SliderSingleStyle,\n trackBounds: TrackBounds,\n orientation: SliderOrientation,\n): { start: Point; end: Point } {\n const span = trackBounds.trackEnd - trackBounds.trackStart;\n const halfLen = (laneValue * span) / 2;\n\n // For unipolar, the value represents the size of a bar centred on the track\n // centre, not a spatial position. Anchor the lane to the track centre so it\n // follows the value's \"magnitude\" rather than the bar's right-end.\n // Mirrors radial-input's getAnchoredArcAngles for unipolar.\n // `centre.x` is along the track axis; `centre.y` is perpendicular. For\n // horizontal that's (LONG/2, cross/2); for vertical that's (cross/2, LONG/2).\n const centre = singleStyle === `unipolar`\n ? (orientation === `horizontal`\n ? { x: trackBounds.centre, y: trackBounds.crossCentre }\n : { x: trackBounds.crossCentre, y: trackBounds.centre })\n : valueToPosition(relativeValue, singleStyle, trackBounds, orientation);\n\n // Compute along-axis offsets\n let startPos: number;\n let endPos: number;\n if (orientation === `horizontal`) {\n startPos = centre.x - halfLen;\n endPos = centre.x + halfLen;\n } else {\n startPos = centre.y - halfLen;\n endPos = centre.y + halfLen;\n }\n\n const start = orientation === `horizontal`\n ? { x: startPos, y: centre.y }\n : { x: centre.x, y: startPos };\n const end = orientation === `horizontal`\n ? { x: endPos, y: centre.y }\n : { x: centre.x, y: endPos };\n return { start, end };\n}\n\n/**\n * Generate an SVG path string for a straight line. Returns '' for a\n * zero-length segment (start ≈ end), mirroring the radial-input arc\n * helper's edge case.\n */\nexport function generateLinePath(start: Point, end: Point): string {\n if (Math.abs(start.x - end.x) < 0.001 && Math.abs(start.y - end.y) < 0.001) {\n return ``;\n }\n return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n}\n\n/**\n * Generate a closed SVG `<path>` for a filled rectangle (used for filled\n * lane segments). `halfWidth` is the perpendicular half-thickness; `perpOffset`\n * shifts the rect perpendicularly from the track centreline.\n */\nexport function generateRectPath(\n start: Point,\n end: Point,\n halfWidth: number,\n perpOffset: number,\n orientation: SliderOrientation,\n): string {\n // Direction vector along the track\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len < 0.001)\n return ``;\n\n // Unit perpendicular\n const perpX = -dy / len;\n const perpY = dx / len;\n\n // Inset corners slightly so the rect's ends don't extend past the start/end\n const insetX = (dx / len) * halfWidth;\n const insetY = (dy / len) * halfWidth;\n\n const sIn = { x: start.x + insetX, y: start.y + insetY };\n const eIn = { x: end.x - insetX, y: end.y - insetY };\n\n const c1 = { x: sIn.x + perpX * (halfWidth + perpOffset), y: sIn.y + perpY * (halfWidth + perpOffset) };\n const c2 = { x: eIn.x + perpX * (halfWidth + perpOffset), y: eIn.y + perpY * (halfWidth + perpOffset) };\n const c3 = { x: eIn.x + perpX * (-halfWidth + perpOffset), y: eIn.y + perpY * (-halfWidth + perpOffset) };\n const c4 = { x: sIn.x + perpX * (-halfWidth + perpOffset), y: sIn.y + perpY * (-halfWidth + perpOffset) };\n\n // Silence unused-orientation warning — kept for API parity\n void orientation;\n\n return `M ${c1.x} ${c1.y} L ${c2.x} ${c2.y} L ${c3.x} ${c3.y} L ${c4.x} ${c4.y} Z`;\n}\n\n/**\n * Clamp `value` to the [min, max] range.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Linear-reinterpolate `value` from [fromMin, fromMax] to [toMin, toMax].\n */\nexport function scale(\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number,\n): number {\n if (fromMax === fromMin)\n return toMin;\n const normalized = (value - fromMin) / (fromMax - fromMin);\n return toMin + normalized * (toMax - toMin);\n}\n\n/**\n * Convert a relative value (0..1) to an absolute value in the min..max range.\n */\nexport function relativeToValue(\n relativeValue: number,\n min: number,\n max: number,\n): number {\n return scale(relativeValue, 0, 1, min, max);\n}\n\n/**\n * Convert an absolute value to a relative (0..1) position.\n */\nexport function valueToRelative(\n value: number,\n min: number,\n max: number,\n): number {\n return scale(value, min, max, 0, 1);\n}\n\n/**\n * Convert a pointer client position (clientX or clientY depending on\n * orientation) to a relative value (0..1) given the host element's\n * bounding rect on the long axis.\n */\nexport function clientPosToRelative(\n clientPos: number,\n hostStart: number,\n hostSize: number,\n): number {\n if (hostSize <= 0)\n return 0;\n return clamp((clientPos - hostStart) / hostSize, 0, 1);\n}\n\n/**\n * Inverse: relative value (0..1) → client position offset from host start.\n */\nexport function relativeToClientPos(\n relativeValue: number,\n hostStart: number,\n hostSize: number,\n): number {\n return hostStart + relativeValue * hostSize;\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\n/**\n * <ixfx-slider-input> — linear SVG-based slider.\n *\n * Mirrors `ixfx-radial-input` as closely as possible, swapping arc geometry\n * for a linear track. Supports horizontal and vertical orientations, three\n * value modes (single/dual/triple), triple-segment \"value\" lanes, and\n * `value-drag` length-drag gestures for dual/triple modes.\n *\n * Attributes / properties\n * value-a, value-b, value-c — primary/secondary/tertiary handle values\n * min, max — value range\n * step, stops — keyboard/wheel/pointer step resolution\n * value-mode — 'single' | 'dual' | 'triple'\n * single-style — 'range' | 'bipolar' | 'unipolar' (single mode only)\n * orientation — 'horizontal' | 'vertical'\n * marker-style — 'needle' | 'dot' | 'none'\n * crossover — 'none' | 'allow' (dual/triple modes)\n * value-drag — 'none' | 'stop' | 'flex' (dual/triple modes)\n * value-min — minimum gap between A and B (dual/triple modes)\n * disabled — boolean\n * lighttouch — boolean — wheel adjusts value on hover instead of requiring focus\n * swipeable — boolean — swipe-to-draw gesture (no pointer capture,\n * enter/move with buttons pressed sets value, for\n * step-sequencer layouts; mirrors ixfx-range-input)\n *\n * Events\n * input — fires continuously during user interaction\n * change — debounced 150ms after interaction; immediate for programmatic\n *\n * Mouse wheel (via WheelNudgeMixin): up = increase, down = decrease. In multi-handle\n * modes wheel targets the last-interacted-with handle (focus or pointerdown).\n * Shift+wheel halves the step. See docs/infra-mousewheel.md.\n */\nimport type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type { Point } from './svg-utils.js';\nimport type {\n SliderChangedField,\n SliderCrossover,\n SliderHandleKey,\n SliderInputChangeDetail,\n SliderInputElementEventMap,\n SliderInputInputDetail,\n SliderLaneData,\n SliderLaneType,\n SliderMarkerStyle,\n SliderOrientation,\n SliderSingleStyle,\n SliderValueCFollow,\n SliderValueDrag,\n SliderValueMode,\n} from './types.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport {\n clamp,\n CROSS,\n generateLinePath,\n getAnchoredSegment,\n getTrackBounds,\n getValueSegment,\n INSET,\n LONG,\n scale,\n valueToPosition,\n valueToRelative,\n} from './svg-utils.js';\n\nconst HANDLE_HIT_RADIUS = 0.06;\nconst DEFAULT_VALUE_MIN_FRACTION = 0.01;\nconst CHANGE_DEBOUNCE_MS = 150;\n\n@customElement(`ixfx-slider-input`)\nexport class SliderInputElement extends WheelNudgeMixin(LitElement) {\n // ─── Public properties ───────────────────────────────────────────────\n @property({ type: Number, attribute: `value-a` })\n valueA = 50;\n\n @property({ type: Number, attribute: `value-b` })\n valueB = 0;\n\n /**\n * Triple-mode middle handle. `undefined` until first willUpdate, then\n * defaulted to the midpoint of valueA/valueB (matching radial-input's\n * deferred lane-correction pattern).\n */\n @property({ type: Number, attribute: `value-c` })\n valueC: number | undefined = undefined;\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 | undefined = undefined;\n\n @property({ type: String, attribute: `value-mode` })\n valueMode: SliderValueMode = `single`;\n\n @property({ type: String, attribute: `single-style` })\n singleStyle: SliderSingleStyle = `range`;\n\n @property({ type: String })\n orientation: SliderOrientation = `horizontal`;\n\n @property({ type: String, attribute: `marker-style` })\n markerStyle: SliderMarkerStyle = `needle`;\n\n /**\n * Optional marker-style override for the C handle in triple mode. Lets\n * consumers give C a different shape (e.g. dot) from the global\n * `markerStyle` applied to A/B.\n */\n @property({ type: String, attribute: `marker-style-c` })\n markerStyleC: SliderMarkerStyle | undefined = undefined;\n\n @property({ type: String })\n crossover: SliderCrossover = `allow`;\n\n @property({ type: String, attribute: `value-drag` })\n valueDrag: SliderValueDrag = `none`;\n\n /**\n * In triple mode, how the C handle reacts when A or B moves the [A, B]\n * band. `none` (default): C keeps its value unless pushed outside the\n * new band. `proportional`: C is re-anchored at the same fractional\n * position it had within the *old* band, so it moves with A/B.\n */\n @property({ type: String, attribute: `value-c-follow` })\n valueCFollow: SliderValueCFollow = `none`;\n\n @property({ type: Number, attribute: `value-min` })\n valueMin = 1;\n\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n /**\n * Swipe-to-draw gesture, mirroring `ixfx-range-input[swipeable]`.\n * When active, pressing down on the slider or entering it while the\n * pointer is pressed sets the value from the cursor coordinate.\n * Pointer capture is NOT held, so the cursor can move to adjacent\n * swipeable sliders and update them too (step-sequencer style).\n * Leaving the slider (above/below for horizontal, left/right for\n * vertical) freezes the value; re-entering re-engages.\n *\n * Single mode sets value-A directly. Dual/triple modes move the\n * nearest handle to the cursor.\n */\n @property({ type: Boolean, reflect: true })\n swipeable = false;\n\n // ─── Internal state ──────────────────────────────────────────────────\n #lanes: Map<string, SliderLaneData> = new Map();\n\n /** Raw pole values: independent of which is \"low\" or \"high\". */\n #poleA = 50;\n #poleB = 0;\n #poleC: number | undefined = undefined;\n\n #dragging = false;\n /** Pointer ID being tracked (fixes radial-input's hardcoded pointerId). */\n #activePointerId: number | undefined = undefined;\n #dragStartClientPos = 0;\n #poleValueAtDragStart = 0;\n /** Which handle is currently being dragged, or 'length' for segment drag. */\n #dragHandle: SliderHandleKey | `length` | undefined = undefined;\n /** Snapshotted poles at length-drag start. */\n #lengthDragStart: { poleA: number; poleB: number } | undefined = undefined;\n /** Track the low/high identity at length-drag start (so we know which raw pole gets which end). */\n #lengthDragLowKey: SliderHandleKey | undefined = undefined;\n #lengthDragHighKey: SliderHandleKey | undefined = undefined;\n #lengthDragLength = 0;\n #lengthDragStartLow = 0;\n /**\n * Where the pointer was when the length drag began (in host-relative\n * 0..1 terms). Preserves the grab offset so dragging the bar doesn't snap\n * its low edge under the cursor.\n */\n #lengthDragStartRelative = 0;\n\n /** The handle that last received direct interaction (pointerdown/keydown/wheel/focus). */\n #lastInteractedHandle: SliderHandleKey = `a`;\n\n /**\n * Last pointer client position seen by #onPointerMoveCursor, used to\n * recompute the cursor after a drag ends (without waiting for a fresh\n * pointermove).\n */\n #lastPointerClient = { x: 0, y: 0 };\n\n #changeDebounceTimer: number | undefined = undefined;\n #isUserInteraction = false;\n #hasInitialisedValueC = false;\n\n /**\n * Holds `<linearGradient>`/`<radialGradient>` elements authored as light-DOM\n * children of this element, once relocated into the shadow root (see\n * `#syncGradientDefs`). Lets consumers reference `url(#id)` paint servers\n * from `--lane-*-color` / `--track-color` etc. — CSS custom properties\n * pierce the shadow boundary, but `url(#id)` paint-server *resolution* does\n * not, so the gradient definitions themselves must physically live inside\n * this element's shadow root to be resolvable by lanes/track painted there.\n */\n #userGradientDefs: SVGDefsElement | undefined;\n #gradientObserver: MutationObserver | undefined;\n /**\n * Lane strokes are resolved to screen px per render (see #laneStrokePx), so\n * a host resize must re-render to keep them (and the measured box) exact.\n */\n #sizeObserver: ResizeObserver | undefined;\n\n // ─── Construction ───────────────────────────────────────────────────\n constructor() {\n super();\n // Make the host focusable so users can Tab to the slider. The actual\n // focus indicator + keyboard listener are on the inner <svg> (which\n // sits inside the shadow DOM), but the host needs an HTML tabindex\n // attribute to be reachable from the document's tab order.\n if (!this.disabled) {\n this.setAttribute(`tabindex`, `0`);\n }\n this.#lanes.set(`track`, {\n key: `track`,\n value: 1,\n type: `fixed`,\n offset: 0,\n width: 0.16,\n });\n this.#lanes.set(`value`, {\n key: `value`,\n valueMin: 0,\n valueMax: 0,\n type: `value`,\n offset: 0,\n width: 0.24,\n });\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute(`tabindex`, this.disabled ? `-1` : `0`);\n // Listen for keydown on the host itself (in addition to the SVG in\n // shadow DOM) so the keyboard handler fires when the host has focus\n // from Tab navigation. The host is the focusable element (via its\n // tabindex attribute set in the constructor); events fired while the\n // host is focused don't reach the inner <svg>'s lit listener.\n this.addEventListener(`keydown`, this.#onHostKeyDown as EventListener);\n this.addEventListener(`pointerdown`, this.#onSwipePointerDown as EventListener);\n this.addEventListener(`pointermove`, this.#onSwipePointerMove as EventListener);\n this.addEventListener(`pointerenter`, this.#onSwipePointerEnter as EventListener);\n this.#syncGradientDefs();\n this.#gradientObserver = new MutationObserver(this.#syncGradientDefs);\n this.#gradientObserver.observe(this, { childList: true, subtree: true });\n this.#sizeObserver = new ResizeObserver(this.#onHostResize);\n this.#sizeObserver.observe(this);\n }\n\n #onHostResize = (): void => {\n const rect = this.getBoundingClientRect();\n const crossPx = this.orientation === `vertical` ? rect.width : rect.height;\n const longPx = this.orientation === `vertical` ? rect.height : rect.width;\n if (crossPx !== this.#currentCrossPx || longPx !== this.#currentLongPx) {\n this.requestUpdate();\n }\n };\n\n #onHostKeyDown = (event: KeyboardEvent): void => {\n this.#onKeyDown(event);\n };\n\n // ─── Gradient defs relocation ───────────────────────────────────────\n /**\n * Lazily creates the inert `<svg><defs>` carrier that user-authored\n * gradients get moved into. Kept entirely outside Lit's managed template —\n * it's a plain sibling of the interactive `<svg class=\"slider-svg\">` inside\n * the shadow root, so `url(#id)` references from lane/track paint\n * properties resolve against it regardless of render() re-runs.\n */\n #ensureUserGradientDefs(): SVGDefsElement {\n if (this.#userGradientDefs)\n return this.#userGradientDefs;\n const svgNs = `http://www.w3.org/2000/svg`;\n const carrier = document.createElementNS(svgNs, `svg`);\n carrier.setAttribute(`width`, `0`);\n carrier.setAttribute(`height`, `0`);\n carrier.setAttribute(`aria-hidden`, `true`);\n // Inline (not classed) so no shadow stylesheet rule — including a broad\n // `svg { width: 100%; ... }` selector — can ever stretch this carrier\n // into a click-blocking overlay; `:host` has no explicit `position`, so\n // an accidentally-enlarged `position: absolute` box here would escape to\n // whatever ancestor up the *light* DOM happens to be positioned.\n carrier.style.cssText = `position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none;`;\n const defs = document.createElementNS(svgNs, `defs`) as SVGDefsElement;\n carrier.append(defs);\n this.renderRoot.append(carrier);\n this.#userGradientDefs = defs;\n return defs;\n }\n\n /**\n * Moves any `<linearGradient>`/`<radialGradient>` authored as light-DOM\n * descendants of this element into the shadow root (see\n * `#ensureUserGradientDefs`). This *reparents* rather than clones the\n * nodes, so consumers get normal, live SVG paint-server semantics — e.g.\n * animating a `<stop>`'s `stop-color` \"just works\" — with no gradient\n * management on the component's part. Idempotent: once moved, a node is no\n * longer a light-DOM descendant of `this`, so it won't be found again.\n */\n #syncGradientDefs = (): void => {\n const found = this.querySelectorAll(`linearGradient, radialGradient`);\n if (found.length === 0)\n return;\n const defs = this.#ensureUserGradientDefs();\n for (const node of found) {\n defs.append(node);\n }\n };\n\n // ─── Lane management API ────────────────────────────────────────────\n addLane(\n key: string,\n options?: {\n value?: number;\n valueMin?: number;\n valueMax?: number;\n type?: SliderLaneType;\n offset?: number;\n width?: number;\n },\n ): void {\n const rel = this.#getRelativeValueA();\n this.#lanes.set(key, {\n key,\n value: options?.value ?? rel,\n valueMin: options?.valueMin ?? 0,\n valueMax: options?.valueMax ?? rel,\n type: options?.type ?? `value`,\n offset: options?.offset ?? 0,\n width: options?.width ?? 0.1,\n });\n this.requestUpdate();\n }\n\n setLaneValue(key: string, value: number): void {\n const lane = this.#lanes.get(key);\n if (lane) {\n lane.value = clamp(value, 0, 1);\n this.requestUpdate();\n }\n }\n\n setLaneRange(key: string, valueMin: number, valueMax: number): void {\n const lane = this.#lanes.get(key);\n if (!lane)\n return;\n const lo = clamp(Math.min(valueMin, valueMax), 0, 1);\n const hi = clamp(Math.max(valueMin, valueMax), 0, 1);\n lane.valueMin = lo;\n lane.valueMax = hi;\n this.requestUpdate();\n }\n\n removeLane(key: string): void {\n this.#lanes.delete(key);\n this.requestUpdate();\n }\n\n getLanes(): ReadonlyMap<string, SliderLaneData> {\n return new Map(this.#lanes);\n }\n\n getLane(key: string): SliderLaneData | undefined {\n return this.#lanes.get(key);\n }\n\n // ─── Derived getters ────────────────────────────────────────────────\n #getRelativeValueA(): number {\n return valueToRelative(this.valueA, this.min, this.max);\n }\n\n #getRelativeValueB(): number {\n return valueToRelative(this.valueB, this.min, this.max);\n }\n\n #getRelativeValueC(): number {\n const c = this.valueC ?? (this.#poleA + this.#poleB) / 2;\n return valueToRelative(c, this.min, this.max);\n }\n\n #low(): number {\n return Math.min(this.#poleA, this.#poleB);\n }\n\n #high(): number {\n return Math.max(this.#poleA, this.#poleB);\n }\n\n #lowKey(): SliderHandleKey {\n return this.#poleA <= this.#poleB ? `a` : `b`;\n }\n\n #highKey(): SliderHandleKey {\n return this.#poleA > this.#poleB ? `a` : `b`;\n }\n\n /**\n * Effective `valueMin` in value units between A and B. Mirrors radial-input's\n * default of 1% of max-min when the property holds the literal minimum.\n */\n #getEffectiveValueMin(): number {\n const range = this.max - this.min;\n if (this.valueMin && this.valueMin > 0)\n return this.valueMin;\n return range * DEFAULT_VALUE_MIN_FRACTION;\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 const snapped = Math.round((value - this.min) / step) * step + this.min;\n return clamp(snapped, this.min, this.max);\n }\n if (this.step !== undefined && this.step > 0) {\n const snapped = Math.round((value - this.min) / this.step) * this.step + this.min;\n return clamp(snapped, this.min, this.max);\n }\n return value;\n }\n\n // ─── Value setting ──────────────────────────────────────────────────\n #setSingleValueFromRelative(relativeValue: number, isUserInteraction = false): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clampedValue = this.#quantise(clamp(newValue, this.min, this.max));\n\n if (clampedValue === this.valueA)\n return;\n\n const previousValue = this.valueA;\n this.valueA = clampedValue;\n this.#poleA = clampedValue;\n this.#isUserInteraction = isUserInteraction;\n\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n this.#applySingleStyleValueLane(valueLane, this.#getRelativeValueA());\n }\n\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(this.#getRelativeValueA() * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n this.#emitInputAndChange(\n { previousValue },\n isUserInteraction,\n );\n }\n\n #setDualOrTripleValueFromRelative(\n relativeValue: number,\n handle: SliderHandleKey,\n isUserInteraction = false,\n ): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clamped = clamp(newValue, this.min, this.max);\n\n const result = this.#resolvePoleChange(handle, clamped, this.#lastInteractedHandle);\n if (!result)\n return;\n\n const previous = { ...this.#poles() };\n this.#poleA = result.poleA;\n this.#poleB = result.poleB;\n if (result.poleC !== undefined)\n this.#poleC = result.poleC;\n this.#syncPoleProperties();\n\n const changed = this.#detectChanged(previous, this.#poles());\n this.#isUserInteraction = isUserInteraction;\n\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.valueMin = valueToRelative(this.#low(), this.min, this.max);\n valueLane.valueMax = valueToRelative(this.#high(), this.min, this.max);\n }\n\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(valueToRelative(this.#high(), this.min, this.max) * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n this.#emitInputAndChange(\n {\n previousValue: Math.max(previous.poleA, previous.poleB),\n previousValueMin: Math.min(previous.poleA, previous.poleB),\n previousValueMax: Math.max(previous.poleA, previous.poleB),\n previousValueC: previous.poleC,\n },\n isUserInteraction,\n changed,\n );\n }\n\n #poles(): { poleA: number; poleB: number; poleC: number | undefined } {\n return { poleA: this.#poleA, poleB: this.#poleB, poleC: this.#poleC };\n }\n\n #syncPoleProperties(): void {\n this.valueA = this.#poleA;\n this.valueB = this.#poleB;\n if (this.valueMode === `triple` && this.#poleC !== undefined) {\n this.valueC = this.#poleC;\n this.#hasInitialisedValueC = true;\n }\n }\n\n #resolvePoleChange(\n handle: SliderHandleKey,\n proposed: number,\n originalHandle: SliderHandleKey,\n ): { poleA: number; poleB: number; poleC?: number } | null {\n let poleA = this.#poleA;\n let poleB = this.#poleB;\n let poleC = this.#poleC;\n\n if (this.valueMode === `triple` && handle === `c`) {\n const lo = this.#low();\n const hi = this.#high();\n const clamped = clamp(proposed, lo, hi);\n const quantised = this.#quantise(clamped);\n if (quantised === this.#poleC)\n return null;\n return { poleA, poleB, poleC: quantised };\n }\n\n const gap = this.#getEffectiveValueMin();\n const other = handle === `a` ? poleB : poleA;\n\n let desired = this.#quantise(clamp(proposed, this.min, this.max));\n\n if (this.crossover === `none`) {\n // Pin to the side this handle started on relative to the other one.\n const startedLow = (handle === `a` ? poleA : poleB) <= other;\n if (startedLow) {\n desired = Math.min(desired, other - gap);\n } else {\n desired = Math.max(desired, other + gap);\n }\n } else {\n // 'allow' — snap into the forbidden band, but allow crossover beyond.\n if (desired > other - gap && desired < other + gap) {\n // Within forbidden band; snap to nearer edge.\n const distToLow = Math.abs(desired - (other - gap));\n const distToHigh = Math.abs(desired - (other + gap));\n desired = distToLow <= distToHigh ? other - gap : other + gap;\n }\n }\n\n // Final clamp to [min, max]\n desired = clamp(desired, this.min, this.max);\n\n if (handle === `a`) {\n if (desired === poleA)\n return null;\n poleA = desired;\n } else {\n if (desired === poleB)\n return null;\n poleB = desired;\n }\n\n // Triple-mode: re-anchor C relative to the new [low, high]\n if (this.valueMode === `triple` && poleC !== undefined) {\n const oldLo = Math.min(this.#poleA, this.#poleB);\n const oldHi = Math.max(this.#poleA, this.#poleB);\n const newLo = Math.min(poleA, poleB);\n const newHi = Math.max(poleA, poleB);\n if (this.valueCFollow === `proportional` && oldHi > oldLo) {\n const frac = clamp((poleC - oldLo) / (oldHi - oldLo), 0, 1);\n poleC = newLo + frac * (newHi - newLo);\n } else {\n if (poleC < newLo)\n poleC = newLo;\n if (poleC > newHi)\n poleC = newHi;\n }\n }\n\n // Avoid unused-warning for originalHandle (used in caller for tie-breaking)\n void originalHandle;\n return { poleA, poleB, poleC };\n }\n\n #detectChanged(\n prev: { poleA: number; poleB: number; poleC: number | undefined },\n curr: { poleA: number; poleB: number; poleC: number | undefined },\n ): SliderChangedField {\n const aDiff = prev.poleA !== curr.poleA;\n const bDiff = prev.poleB !== curr.poleB;\n const cDiff = prev.poleC !== curr.poleC;\n\n if (this.valueMode === `triple`) {\n if (aDiff && bDiff && !cDiff)\n return `both`;\n if (aDiff && bDiff)\n return `both`;\n if (aDiff)\n return `min`;\n if (bDiff)\n return `max`;\n if (cDiff)\n return `c`;\n return `min`;\n }\n if (aDiff && bDiff)\n return `both`;\n if (aDiff)\n return `min`;\n if (bDiff)\n return `max`;\n return `min`;\n }\n\n #emitInputAndChange(\n previous: {\n previousValue: number;\n previousValueMin?: number;\n previousValueMax?: number;\n previousValueC?: number;\n },\n isUserInteraction: boolean,\n changed?: SliderChangedField,\n ): void {\n const detailInput = this.#buildInputDetail(changed);\n const detailChange = this.#buildChangeDetail(previous, changed);\n\n if (isUserInteraction) {\n this.dispatchEvent(\n new CustomEvent<SliderInputInputDetail>(`input`, {\n detail: detailInput,\n bubbles: true,\n composed: true,\n }),\n );\n this.#scheduleChangeEvent(detailChange);\n } else {\n this.#fireChangeEvent(detailChange);\n }\n }\n\n #buildInputDetail(changed?: SliderChangedField): SliderInputInputDetail {\n if (this.valueMode === `single`) {\n return {\n value: this.valueA,\n valueRelative: this.#getRelativeValueA(),\n };\n }\n\n const lo = this.#low();\n const hi = this.#high();\n const valueMinRel = valueToRelative(lo, this.min, this.max);\n const valueMaxRel = valueToRelative(hi, this.min, this.max);\n\n if (this.valueMode === `triple` && this.#poleC !== undefined) {\n return {\n value: hi,\n valueRelative: valueMaxRel,\n valueMin: lo,\n valueMax: hi,\n valueMinRelative: valueMinRel,\n valueMaxRelative: valueMaxRel,\n valueC: this.#poleC,\n valueCRelative: valueToRelative(this.#poleC, this.min, this.max),\n changed,\n };\n }\n\n return {\n value: hi,\n valueRelative: valueMaxRel,\n valueMin: lo,\n valueMax: hi,\n valueMinRelative: valueMinRel,\n valueMaxRelative: valueMaxRel,\n changed,\n };\n }\n\n #buildChangeDetail(\n previous: {\n previousValue: number;\n previousValueMin?: number;\n previousValueMax?: number;\n previousValueC?: number;\n },\n changed?: SliderChangedField,\n ): SliderInputChangeDetail {\n if (this.valueMode === `single`) {\n return {\n value: this.valueA,\n valueRelative: this.#getRelativeValueA(),\n previousValue: previous.previousValue,\n };\n }\n\n const lo = this.#low();\n const hi = this.#high();\n const valueMaxRel = valueToRelative(hi, this.min, this.max);\n\n if (this.valueMode === `triple` && this.#poleC !== undefined) {\n return {\n value: hi,\n valueRelative: valueMaxRel,\n previousValue: previous.previousValue,\n valueMin: lo,\n valueMax: hi,\n previousValueMin: previous.previousValueMin ?? lo,\n previousValueMax: previous.previousValueMax ?? hi,\n valueC: this.#poleC,\n previousValueC: previous.previousValueC ?? this.#poleC,\n changed,\n };\n }\n\n return {\n value: hi,\n valueRelative: valueMaxRel,\n previousValue: previous.previousValue,\n valueMin: lo,\n valueMax: hi,\n previousValueMin: previous.previousValueMin ?? lo,\n previousValueMax: previous.previousValueMax ?? hi,\n changed,\n };\n }\n\n #scheduleChangeEvent(detail: SliderInputChangeDetail): void {\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n this.#changeDebounceTimer = window.setTimeout(() => {\n this.#fireChangeEvent(detail);\n this.#changeDebounceTimer = undefined;\n }, CHANGE_DEBOUNCE_MS);\n }\n\n #fireChangeEvent(detail: SliderInputChangeDetail): void {\n this.dispatchEvent(\n new CustomEvent<SliderInputChangeDetail>(`change`, {\n detail,\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // ─── Dynamic cross-axis sizing ────────────────────────────────────\n /**\n * Cross-axis viewBox size for this render, hugging the actual content.\n * Computed once per render into `#currentCross` (sub-renderers read it\n * via `getTrackBounds(orientation, cross)` / `bounds.cross`).\n *\n * LONG stays fixed; only the cross axis and the long-axis end inset\n * tighten. Pointer mapping is calibrated to the drawn track span, so\n * clicks on the visible track ends hit min/max exactly.\n */\n #currentCross = CROSS;\n\n /**\n * Long-axis end insets (viewBox units) for this render: low-value end /\n * high-value end (left/right horizontal, bottom/top vertical).\n */\n #currentInsetStart = INSET;\n #currentInsetEnd = INSET;\n\n /**\n * Lane width variable cascade for `key`:\n * 1. `--lane-<key>-width` (explicit per-lane width)\n * 2. for the `value` lane only: `--lane-track-width`, so the value bar\n * matches a customised track thickness automatically\n * 3. for custom lanes only: the generic `--lane-width`\n * 4. `fallback` (0.08 track / 0.12 value / 0.16 custom)\n *\n * Mirrors the `var()` fallback chains in `#renderLane` — the two must stay\n * in sync or the measured viewBox diverges from the drawn strokes.\n */\n #laneWidthNumber(key: string, fallback: number): number {\n const style = getComputedStyle(this);\n const parse = (raw: string): number | undefined => {\n const trimmed = raw.trim();\n if (!trimmed)\n return undefined;\n const parsed = Number.parseFloat(trimmed);\n return Number.isNaN(parsed) ? undefined : parsed;\n };\n const perLane = parse(style.getPropertyValue(`--lane-${key}-width`));\n if (perLane !== undefined)\n return perLane;\n if (key === `value`) {\n const track = parse(style.getPropertyValue(`--lane-track-width`));\n if (track !== undefined)\n return track;\n return fallback;\n }\n if (key !== `track`) {\n const generic = parse(style.getPropertyValue(`--lane-width`));\n if (generic !== undefined)\n return generic;\n }\n return fallback;\n }\n\n /**\n * Lane `key` as screen px: width fraction × measured cross-axis px. Lane\n * widths are fractions of the cross axis, so multiplying by the host's\n * cross px (measured per render in #measureLanes) is exact — unlike the old\n * `calc(var * 24%)` percentage, which resolved against the\n * host-size-independent viewBox diagonal and painted ~10x too thin.\n */\n #laneStrokePx(key: string): number {\n const fallback = key === `track` ? 0.08 : key === `value` ? 0.12 : 0.16;\n return this.#laneWidthNumber(key, fallback) * this.#currentCrossPx;\n }\n\n /**\n * Widest lane stroke in screen px + the host's cross-axis px, measured\n * once per render. Lane strokes render as JS-computed px (see\n * #laneStrokePx) with `non-scaling-stroke`, so the number paints verbatim\n * in screen px regardless of the viewBox.\n */\n #currentLanePxMax = 0;\n #currentCrossPx = 0;\n #currentLongPx = 0;\n\n #measureLanes(): void {\n const rect = this.getBoundingClientRect();\n const crossPx = this.orientation === `vertical` ? rect.width : rect.height;\n this.#currentCrossPx = crossPx;\n this.#currentLongPx = this.orientation === `vertical` ? rect.height : rect.width;\n if (rect.width <= 0 || rect.height <= 0) {\n this.#currentLanePxMax = 0;\n return;\n }\n let max = 0;\n for (const lane of this.#lanes.values()) {\n const fallback = lane.key === `track` ? 0.08 : lane.key === `value` ? 0.12 : 0.16;\n max = Math.max(max, Math.abs(this.#laneWidthNumber(lane.key, fallback)) * crossPx);\n }\n this.#currentLanePxMax = max;\n }\n\n /**\n * Dot radius as a fraction of the cross axis. The fractional\n * `--marker-thickness` size shrinks with the tight box, so a screen-px\n * floor (widest lane + 2px) guarantees the dot always reads larger than\n * the value track it sits on.\n */\n #dotRadiusFraction(): number {\n if (this.#currentCrossPx <= 0) {\n const markerThickness = Math.abs(this.#getCssVar(`--marker-thickness`, 0.15));\n return markerThickness / 2;\n }\n return this.#dotRadiusPx() / this.#currentCrossPx;\n }\n\n /** Desired dot radius in screen px (fractional size vs lane-based floor). */\n #dotRadiusPx(): number {\n const markerThickness = Math.abs(this.#getCssVar(`--marker-thickness`, 0.15));\n if (this.#currentCrossPx <= 0)\n return 0;\n return Math.max(markerThickness * this.#currentCrossPx / 2, this.#currentLanePxMax / 2 + 1);\n }\n\n /**\n * Radii (viewBox units) for a screen-space circle of `rPx` px.\n * `preserveAspectRatio=\"none\"` scales axes differently, so a viewBox\n * `<circle>` renders as an oval — pre-compensate with an `<ellipse>`.\n */\n #circleRadiiUnits(rPx: number, cross: number): { rx: number; ry: number } {\n const longPx = this.#currentLongPx;\n const crossPx = this.#currentCrossPx;\n if (longPx <= 0 || crossPx <= 0 || cross <= 0)\n return { rx: rPx, ry: rPx };\n const longScale = longPx / 100;\n const crossScale = crossPx / cross;\n if (this.orientation === `vertical`)\n return { rx: rPx / crossScale, ry: rPx / longScale };\n return { rx: rPx / longScale, ry: rPx / crossScale };\n }\n\n /** Marker styles actually rendered this render (global + triple C override). */\n #activeMarkerStyles(): SliderMarkerStyle[] {\n if (this.valueMode === `single`)\n return [this.markerStyle];\n if (this.valueMode === `triple` && this.markerStyleC)\n return [...new Set([this.markerStyle, this.markerStyleC])];\n return [this.markerStyle];\n }\n\n /**\n * Largest fractional half-extent of the content, as a fraction of the\n * (unknown) cross size: boxHalf = F * cross + pad. Markers, lane widths\n * and offsets are all defined as fractions of the cross axis, so the\n * tightest box is the fixed point cross = pad / (0.5 - F).\n */\n #contentFraction(): number {\n let f = 0;\n\n for (const lane of this.#lanes.values()) {\n const fallback = lane.key === `track` ? 0.08 : lane.key === `value` ? 0.12 : 0.16;\n const w = this.#laneWidthNumber(lane.key, fallback);\n f = Math.max(f, Math.abs(w) / 2 + Math.abs(lane.offset) / 2);\n }\n\n const markerOffset = Math.abs(this.#getCssVar(`--marker-offset`, 0));\n const markerLength = Math.abs(this.#getCssVar(`--marker-length`, 0.8));\n const styleF = (marker: SliderMarkerStyle): number => {\n if (marker === `none`)\n return 0;\n if (marker === `dot`)\n return this.#dotRadiusFraction() + markerOffset / 2;\n // needle + triangle extend markerLength/4 from the centreline\n return markerLength / 4 + markerOffset / 2;\n };\n for (const marker of this.#activeMarkerStyles()) {\n f = Math.max(f, styleF(marker));\n }\n\n if (this.valueMode === `single` && (this.singleStyle === `bipolar` || this.singleStyle === `unipolar`)) {\n const midLength = Math.abs(this.#getCssVar(`--midpoint-length`, 0.15));\n f = Math.max(f, midLength / 4);\n }\n\n const trackWidth = Math.abs(this.#getCssVar(`--track-width`, 2));\n // Track width is absolute viewBox units (legacy CROSS=24 scale).\n f = Math.max(f, trackWidth / 2 / CROSS);\n\n // Clamp so the fixed point stays finite and leaves room for strokes.\n return Math.min(f, 0.45);\n }\n\n #computeCross(): number {\n const pad = 2;\n const cross = pad / (0.5 - this.#contentFraction());\n return clamp(cross, 4, 40);\n }\n\n /**\n * Long-axis end inset (viewBox units) hugging the markers: dot/triangle\n * markers extend half their width past the track ends at min/max, so the\n * inset is that extent plus a stroke pad. Needle markers are\n * perpendicular to the track and need no along-axis room beyond the pad.\n *\n * Authored `--track-margin` (both ends) / `--track-margin-start` /\n * `--track-margin-end` (viewBox units) are added on top, so demos can\n * reserve room for things like anchored lanes that overhang the value\n * at the extremes. Start = low-value end (left / bottom).\n */\n #computeInsets(cross: number): { start: number; end: number } {\n const markerThickness = Math.abs(this.#getCssVar(`--marker-thickness`, 0.15));\n // Dot along-axis half-width: aspect-corrected rx (falls back to the\n // cross-axis radius when unlaid-out).\n const dotHalf = this.#currentLongPx > 0\n ? this.#dotRadiusPx() * 100 / this.#currentLongPx\n : this.#dotRadiusFraction() * cross;\n let half = 0;\n for (const marker of this.#activeMarkerStyles()) {\n if (marker === `dot`)\n half = Math.max(half, dotHalf);\n else if (marker === `triangle`)\n half = Math.max(half, markerThickness * cross / 4);\n }\n const base = clamp(half + 1.5, 1, INSET);\n const both = Math.max(0, this.#getCssVar(`--track-margin`, 0));\n const extraStart = Math.max(0, this.#getCssVar(`--track-margin-start`, both));\n const extraEnd = Math.max(0, this.#getCssVar(`--track-margin-end`, both));\n let start = base + extraStart;\n let end = base + extraEnd;\n // Keep a usable track span: scale back proportionally if overbooked.\n const maxTotal = LONG - 10;\n if (start + end > maxTotal && start + end > 0) {\n const scale = maxTotal / (start + end);\n start *= scale;\n end *= scale;\n }\n return { start, end };\n }\n\n /**\n * Pointer client position (clientX/clientY along the long axis) mapped\n * onto the *drawn track span* (0 at track start, 1 at track end, clamped;\n * flipped for vertical where the top is the high value). Mapping to the\n * track rather than the host edges means the visible track ends hit\n * min/max exactly and no horizontal space is dead.\n */\n #relativeFromTrackPos(clientPos: number): number {\n const rect = this.getBoundingClientRect();\n const isVertical = this.orientation === `vertical`;\n const hostStart = isVertical ? rect.top : rect.left;\n const hostSize = isVertical ? rect.height : rect.width;\n if (hostSize <= 0)\n return 0;\n const trackStart = hostStart + hostSize * this.#currentInsetStart / LONG;\n const trackSpan = hostSize * (LONG - this.#currentInsetStart - this.#currentInsetEnd) / LONG;\n if (trackSpan <= 0)\n return 0;\n const raw = clamp((clientPos - trackStart) / trackSpan, 0, 1);\n return isVertical ? 1 - raw : raw;\n }\n\n // ─── CSS-var lookup ────────────────────────────────────────────────\n #getCssVar(name: string, defaultValue: number): number {\n const style = getComputedStyle(this);\n const val = style.getPropertyValue(name).trim();\n if (!val)\n return defaultValue;\n\n if (val.includes(`calc(`)) {\n const valueRelative = style.getPropertyValue(`--value-relative`).trim();\n if (!valueRelative) {\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n const evalStr = val.replace(/var\\(--value-relative\\)/g, valueRelative);\n try {\n const fn = new Function(`return ${evalStr.replace(/calc\\s*\\(([^)]+)\\)/g, `$1`)}`);\n const result = fn();\n return typeof result === `number` && !Number.isNaN(result) ? result : defaultValue;\n } catch {\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n }\n\n const parsed = Number.parseFloat(val);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // ─── Swipeable mode (mirrors ixfx-range-input) ──────────────────────\n /**\n * Track-span-relative 0..1 position for a pointer event, with vertical\n * flip and unipolar V-shape mapping applied. Positions outside the drawn\n * track are clamped to 0..1.\n */\n #relativeFromSwipePointer(event: PointerEvent): number {\n const clientPos = this.orientation === `vertical` ? event.clientY : event.clientX;\n const relativeValue = this.#relativeFromTrackPos(clientPos);\n if (this.valueMode === `single` && this.singleStyle === `unipolar`) {\n return Math.abs(2 * relativeValue - 1);\n }\n return relativeValue;\n }\n\n /**\n * Apply a swipe value from a pointer coordinate. Single mode sets\n * value-A directly; dual/triple modes move the nearest handle.\n * Focus follows the slider being controlled, so keyboard/wheel keep\n * working on the slider under the cursor as a swipe travels across\n * adjacent sliders (no-op when already focused).\n */\n #applySwipeFromPointer(event: PointerEvent): void {\n this.focus();\n const relativeValue = this.#relativeFromSwipePointer(event);\n if (this.valueMode === `single`) {\n this.#lastInteractedHandle = `a`;\n this.#setSingleValueFromRelative(relativeValue, true);\n return;\n }\n const aRel = this.#getRelativeValueA();\n const bRel = this.#getRelativeValueB();\n let nearest: SliderHandleKey = Math.abs(relativeValue - aRel) <= Math.abs(relativeValue - bRel) ? `a` : `b`;\n if (this.valueMode === `triple`) {\n const cRel = this.#getRelativeValueC();\n const distA = Math.abs(relativeValue - aRel);\n const distB = Math.abs(relativeValue - bRel);\n const distC = Math.abs(relativeValue - cRel);\n nearest = distA <= distB && distA <= distC ? `a` : distB <= distC ? `b` : `c`;\n }\n // Raw-pole identity for tie-breaking is irrelevant here (unlike the\n // drag hit-test which distinguishes overlapping handles); nearest wins.\n if (nearest === `a` || nearest === `b`) {\n this.#lastInteractedHandle = nearest;\n } else {\n this.#lastInteractedHandle = `c`;\n }\n this.#setDualOrTripleValueFromRelative(relativeValue, nearest, true);\n }\n\n #onSwipePointerDown = (event: PointerEvent): void => {\n if (!this.swipeable || this.disabled)\n return;\n event.preventDefault();\n this.#applySwipeFromPointer(event);\n };\n\n #onSwipePointerMove = (event: PointerEvent): void => {\n if (!this.swipeable || this.disabled || event.buttons === 0)\n return;\n this.#applySwipeFromPointer(event);\n };\n\n #onSwipePointerEnter = (event: PointerEvent): void => {\n if (!this.swipeable || this.disabled || event.buttons === 0)\n return;\n this.#applySwipeFromPointer(event);\n };\n\n // ─── Pointer interaction ────────────────────────────────────────────\n #onPointerDown = (event: PointerEvent): void => {\n if (this.disabled)\n return;\n // In swipeable mode the host-level swipe handlers own the gesture\n // (no pointer capture, so the pointer can travel across sliders).\n if (this.swipeable)\n return;\n\n const svg = this.renderRoot.querySelector(`svg.slider-svg`) as SVGElement | null;\n if (!svg)\n return;\n\n event.preventDefault();\n\n // Move focus to the host so keyboard interaction (arrows, wheel)\n // continues to work after a click/drag, and the focus indicator shows.\n this.focus();\n\n // Force the dragging cursor immediately, since the pointer may move\n // outside the SVG bounds while dragged (and #onPointerMoveCursor is\n // bound to the SVG only).\n svg.style.cursor = `grabbing`;\n\n const clientPos = this.orientation === `vertical` ? event.clientY : event.clientX;\n // Calibrated to the drawn track span (track ends hit min/max exactly).\n let relativeValue = this.#relativeFromTrackPos(clientPos);\n // For unipolar (single mode), the value bar is symmetric around the track\n // centre, so the click position maps to the value via a V-shape: 0 at\n // the centre, 1 at either end. Clicking 25% in from either side sets\n // the same value (0.5), as does clicking at the very start or end (1).\n if (this.valueMode === `single` && this.singleStyle === `unipolar`) {\n relativeValue = Math.abs(2 * relativeValue - 1);\n }\n\n // Resolve handle\n if (this.valueMode === `single`) {\n this.#lastInteractedHandle = `a`;\n this.#dragHandle = `a`;\n this.#setSingleValueFromRelative(relativeValue, true);\n this.#dragging = true;\n this.toggleAttribute(`dragging`, true);\n this.#activePointerId = event.pointerId;\n try {\n svg.setPointerCapture(event.pointerId);\n } catch {\n // ignore\n }\n this.#dragStartClientPos = clientPos;\n this.#poleValueAtDragStart = this.valueA;\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n return;\n }\n\n // Multi-handle: hit-test\n const aRel = this.#getRelativeValueA();\n const bRel = this.#getRelativeValueB();\n const lo = Math.min(aRel, bRel);\n const hi = Math.max(aRel, bRel);\n const aHandle = this.#poleA <= this.#poleB ? `a` : `b`;\n const bHandle = this.#poleA > this.#poleB ? `a` : `b`;\n const posA = aRel;\n const posB = bRel;\n const isTriple = this.valueMode === `triple`;\n const cRel = isTriple ? this.#getRelativeValueC() : 0;\n const posC = cRel;\n const nearA = Math.abs(relativeValue - posA) < HANDLE_HIT_RADIUS;\n const nearB = Math.abs(relativeValue - posB) < HANDLE_HIT_RADIUS;\n const nearC = isTriple && Math.abs(relativeValue - posC) < HANDLE_HIT_RADIUS;\n\n let chosenHandle: SliderHandleKey | `length` | undefined;\n\n // When two or more handles overlap (e.g. A and C, A and B, etc.), pick\n // the one whose raw pole was NOT last-interacted, so repeated clicks\n // on a near-coincident pair alternate rather than sticking.\n const pickNonLast = (candidates: SliderHandleKey[]): SliderHandleKey => {\n const notLast = candidates.find(h => h !== this.#lastInteractedHandle);\n return notLast ?? candidates[0];\n };\n if (nearA && nearB && nearC) {\n chosenHandle = pickNonLast([aHandle, bHandle, `c`]);\n } else if (nearA && nearB) {\n chosenHandle = pickNonLast([aHandle, bHandle]);\n } else if (nearA && nearC) {\n chosenHandle = pickNonLast([aHandle, `c`]);\n } else if (nearB && nearC) {\n chosenHandle = pickNonLast([bHandle, `c`]);\n } else if (nearA) {\n chosenHandle = aHandle;\n } else if (nearB) {\n chosenHandle = bHandle;\n } else if (nearC) {\n chosenHandle = `c`;\n } else if (this.valueDrag !== `none` && relativeValue > lo && relativeValue < hi) {\n chosenHandle = `length`;\n } else if (this.valueDrag === `none` && relativeValue <= lo) {\n // Dead zone on low side — click-to-set low handle (only when\n // value-drag is off; otherwise clicks outside the bar are a no-op).\n chosenHandle = this.#lowKey();\n } else if (this.valueDrag === `none` && relativeValue >= hi) {\n // Dead zone on high side — click-to-set high handle (only when\n // value-drag is off; otherwise clicks outside the bar are a no-op).\n chosenHandle = this.#highKey();\n } else {\n // Not on a handle, not on a draggable segment, not on a click-to-set\n // dead zone (when value-drag is off). No-op — the pointer event will\n // still register and release cleanly via #onPointerUp, but no value\n // changes.\n chosenHandle = undefined;\n }\n\n this.#dragging = true;\n this.toggleAttribute(`dragging`, true);\n this.#activePointerId = event.pointerId;\n try {\n svg.setPointerCapture(event.pointerId);\n } catch {\n // ignore\n }\n this.#dragStartClientPos = clientPos;\n\n if (chosenHandle === undefined) {\n // Linger-as-track-click but no drag started.\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n return;\n }\n\n this.#dragHandle = chosenHandle;\n\n if (chosenHandle === `length`) {\n this.#lengthDragStart = { poleA: this.#poleA, poleB: this.#poleB };\n this.#lengthDragLowKey = this.#lowKey();\n this.#lengthDragHighKey = this.#highKey();\n this.#lengthDragLength = this.#poleB - this.#poleA < 0\n ? this.#poleA - this.#poleB\n : this.#poleB - this.#poleA;\n this.#lengthDragStartLow = Math.min(this.#poleA, this.#poleB);\n // Remember where the user grabbed the bar (host-relative). Without\n // this, the low edge would jump under the cursor at drag-start.\n this.#lengthDragStartRelative = relativeValue;\n } else {\n this.#lastInteractedHandle = chosenHandle;\n this.#poleValueAtDragStart = chosenHandle === `a` ? this.#poleA : this.#poleB;\n // Click-to-set immediately\n this.#setDualOrTripleValueFromRelative(relativeValue, chosenHandle, true);\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 const clientPos = this.orientation === `vertical` ? event.clientY : event.clientX;\n let relativeValue = this.#relativeFromTrackPos(clientPos);\n if (this.valueMode === `single` && this.singleStyle === `unipolar`) {\n relativeValue = Math.abs(2 * relativeValue - 1);\n }\n\n if (this.valueMode === `single`) {\n this.#setSingleValueFromRelative(relativeValue, true);\n return;\n }\n\n if (this.#dragHandle === `length`) {\n this.#applyLengthDragFromRelative(relativeValue);\n } else if (this.#dragHandle) {\n this.#setDualOrTripleValueFromRelative(relativeValue, this.#dragHandle, true);\n }\n };\n\n #applyLengthDragFromRelative(relativeValue: number): void {\n if (!this.#lengthDragStart)\n return;\n const range = this.max - this.min;\n const deltaR = relativeValue - this.#lengthDragStartRelative;\n const deltaValue = deltaR * range;\n\n let proposedLow = this.#lengthDragStartLow + deltaValue;\n let proposedHigh = proposedLow + this.#lengthDragLength;\n\n if (this.valueDrag === `stop`) {\n const originalLength = this.#lengthDragLength;\n let candidateLow = proposedLow;\n let candidateHigh = proposedLow + originalLength;\n if (candidateLow < this.min) {\n const maxDelta = this.min - this.#lengthDragStartLow;\n candidateLow = this.#lengthDragStartLow + maxDelta;\n candidateHigh = candidateLow + originalLength;\n }\n if (candidateHigh > this.max) {\n // Translate back so high sits at max.\n const shift = this.max - candidateHigh;\n candidateLow += shift;\n candidateHigh += shift;\n }\n proposedLow = candidateLow;\n proposedHigh = candidateHigh;\n } else if (this.valueDrag === `flex`) {\n proposedLow = clamp(proposedLow, this.min, this.max);\n proposedHigh = clamp(proposedHigh, this.min, this.max);\n }\n\n const lowKey = this.#lengthDragLowKey ?? this.#lowKey();\n const highKey = this.#lengthDragHighKey ?? this.#highKey();\n\n const previous = this.#poles();\n const newPoleA = lowKey === `a` ? proposedLow : proposedHigh;\n const newPoleB = lowKey === `b` ? proposedLow : proposedHigh;\n this.#poleA = newPoleA;\n this.#poleB = newPoleB;\n if (this.valueMode === `triple` && this.#poleC !== undefined) {\n const oldLo = Math.min(previous.poleA, previous.poleB);\n const oldHi = Math.max(previous.poleA, previous.poleB);\n const newLo = Math.min(newPoleA, newPoleB);\n const newHi = Math.max(newPoleA, newPoleB);\n if (this.valueCFollow === `proportional` && oldHi > oldLo) {\n const frac = clamp((this.#poleC - oldLo) / (oldHi - oldLo), 0, 1);\n this.#poleC = newLo + frac * (newHi - newLo);\n } else {\n if (this.#poleC < newLo)\n this.#poleC = newLo;\n if (this.#poleC > newHi)\n this.#poleC = newHi;\n }\n }\n this.#syncPoleProperties();\n\n const changed: SliderChangedField = `both`;\n this.#isUserInteraction = true;\n\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.valueMin = valueToRelative(this.#low(), this.min, this.max);\n valueLane.valueMax = valueToRelative(this.#high(), this.min, this.max);\n }\n\n this.#emitInputAndChange(\n {\n previousValue: previous.poleA,\n previousValueMin: Math.min(previous.poleA, previous.poleB),\n previousValueMax: Math.max(previous.poleA, previous.poleB),\n previousValueC: previous.poleC,\n },\n true,\n changed,\n );\n }\n\n #onPointerUp = (): void => {\n this.#dragging = false;\n this.#dragHandle = undefined;\n this.#lengthDragStart = undefined;\n this.#lengthDragLowKey = undefined;\n this.#lengthDragHighKey = undefined;\n this.toggleAttribute(`dragging`, false);\n\n // Re-evaluate cursor at the last known pointer position so the cursor\n // doesn't stay stuck at `grabbing` after release.\n this.#onPointerMoveCursor(\n new PointerEvent(`pointermove`, {\n clientX: this.#lastPointerClient.x,\n clientY: this.#lastPointerClient.y,\n }),\n );\n\n const svg = this.renderRoot.querySelector(`svg.slider-svg`);\n if (\n svg\n && this.#activePointerId !== undefined\n && `hasPointerCapture` in svg\n && typeof (svg as Element & { hasPointerCapture?: (id: number) => boolean }).hasPointerCapture === `function`\n ) {\n const has = (svg as Element & { hasPointerCapture: (id: number) => boolean }).hasPointerCapture;\n if (has.call(svg, this.#activePointerId)) {\n try {\n (svg as Element & { releasePointerCapture: (id: number) => void }).releasePointerCapture(this.#activePointerId);\n } catch {\n // ignore\n }\n }\n }\n this.#activePointerId = undefined;\n\n window.removeEventListener(`pointermove`, this.#onPointerMove);\n window.removeEventListener(`pointerup`, this.#onPointerUp);\n window.removeEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n // ─── Keyboard interaction ───────────────────────────────────────────\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 // Determine which handle to act on\n let handle: SliderHandleKey = `a`;\n const target = event.target as Element | null;\n if (target && typeof target.closest === `function`) {\n const handleEl = target.closest(`[data-handle]`) as HTMLElement | null;\n if (handleEl) {\n const h = handleEl.dataset?.handle as SliderHandleKey | undefined;\n if (h === `a` || h === `b` || h === `c`)\n handle = h;\n }\n }\n if (this.valueMode === `single`)\n handle = `a`;\n this.#lastInteractedHandle = handle;\n\n let handled = false;\n\n switch (event.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n if (this.valueMode === `single`) {\n const r = this.#getRelativeValueA() + effectiveStep / range;\n this.#setSingleValueFromRelative(clamp(r, 0, 1), true);\n } else {\n const current = handle === `a` ? this.#poleA : (handle === `b` ? this.#poleB : (this.#poleC ?? this.#low()));\n const r = valueToRelative(current, this.min, this.max) + effectiveStep / range;\n this.#stepHandleByRelativeDelta(handle, r);\n }\n handled = true;\n break;\n\n case `ArrowDown`:\n case `ArrowLeft`:\n if (this.valueMode === `single`) {\n const r = this.#getRelativeValueA() - effectiveStep / range;\n this.#setSingleValueFromRelative(clamp(r, 0, 1), true);\n } else {\n const current = handle === `a` ? this.#poleA : (handle === `b` ? this.#poleB : (this.#poleC ?? this.#low()));\n const r = valueToRelative(current, this.min, this.max) - effectiveStep / range;\n this.#stepHandleByRelativeDelta(handle, r);\n }\n handled = true;\n break;\n\n case `Home`:\n if (this.valueMode === `single`) {\n this.#setSingleValueFromRelative(0, true);\n } else {\n this.#stepHandleByRelativeDelta(handle, 0);\n }\n handled = true;\n break;\n\n case `End`:\n if (this.valueMode === `single`) {\n this.#setSingleValueFromRelative(1, true);\n } else {\n this.#stepHandleByRelativeDelta(handle, 1);\n }\n handled = true;\n break;\n }\n\n if (handled)\n event.preventDefault();\n };\n\n #stepHandleByRelativeDelta(handle: SliderHandleKey, targetRelative: number): void {\n if (this.valueMode === `single`) {\n this.#setSingleValueFromRelative(clamp(targetRelative, 0, 1), true);\n return;\n }\n if (handle === `c`) {\n const lo = this.#low();\n const hi = this.#high();\n const proposed = scale(clamp(targetRelative, 0, 1), 0, 1, this.min, this.max);\n const clamped = clamp(proposed, lo, hi);\n const q = this.#quantise(clamped);\n if (q === this.#poleC)\n return;\n const previous = this.#poles();\n this.#poleC = q;\n this.#syncPoleProperties();\n this.#isUserInteraction = true;\n this.#emitInputAndChange(\n {\n previousValue: previous.poleA,\n previousValueMin: Math.min(previous.poleA, previous.poleB),\n previousValueMax: Math.max(previous.poleA, previous.poleB),\n previousValueC: previous.poleC,\n },\n true,\n `c`,\n );\n return;\n }\n\n this.#setDualOrTripleValueFromRelative(clamp(targetRelative, 0, 1), handle, true);\n }\n\n // ─── Wheel interaction ──────────────────────────────────────────────\n // The WheelNudgeMixin installs a host-level `wheel` listener; this method is\n // called once per handled tick with the resolved direction.\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n // Resolve target handle from event target, falling back to last-interacted.\n let handle: SliderHandleKey = this.#lastInteractedHandle;\n const target = event.target as Element | null;\n if (target && typeof target.closest === `function`) {\n const handleEl = target.closest(`[data-handle]`) as HTMLElement | null;\n if (handleEl) {\n const h = handleEl.dataset?.handle as SliderHandleKey | undefined;\n if (h === `a` || h === `b` || h === `c`)\n handle = h;\n }\n }\n if (this.valueMode === `single`)\n handle = `a`;\n this.#lastInteractedHandle = handle;\n\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n\n const current = handle === `a`\n ? this.#poleA\n : handle === `b`\n ? this.#poleB\n : (this.#poleC ?? this.#low());\n const currentRel = valueToRelative(current, this.min, this.max);\n // Negate the direction so \"wheel forward\" always increases the value,\n // regardless of the platform's deltaY convention (Windows reports\n // deltaY < 0 for forward, Mac natural-scrolling reports deltaY > 0).\n // Shift narrows the step but doesn't change polarity.\n const targetRel = clamp(currentRel - direction * effectiveStep / range, 0, 1);\n\n this.#stepHandleByRelativeDelta(handle, targetRel);\n }\n\n #onFocusIn = (event: FocusEvent): void => {\n const target = event.target as Element | null;\n if (target && typeof target.closest === `function`) {\n const handleEl = target.closest(`[data-handle]`) as HTMLElement | null;\n if (handleEl) {\n const h = handleEl.dataset?.handle as SliderHandleKey | undefined;\n if (h === `a` || h === `b` || h === `c`)\n this.#lastInteractedHandle = h;\n }\n }\n };\n\n // ─── Rendering ──────────────────────────────────────────────────────\n #viewBox(): string {\n const cross = this.#currentCross;\n if (this.orientation === `horizontal`)\n return `0 0 ${LONG} ${cross}`;\n return `0 0 ${cross} ${LONG}`;\n }\n\n #renderTrack() {\n const isVertical = this.orientation === `vertical`;\n const cross = this.#currentCross;\n const insetStart = this.#currentInsetStart;\n const insetEnd = this.#currentInsetEnd;\n const strokeWidth = this.#getCssVar(`--track-width`, 2);\n const color = this.#getCssVarColor(`--track-color`, `var(--surface-4)`);\n const fill = this.#getCssVarColor(`--track-fill`, `transparent`);\n\n if (isVertical) {\n return svg`\n <rect\n class=\"track\"\n x=\"${cross / 2 - strokeWidth / 2}\"\n y=\"${insetStart}\"\n width=\"${strokeWidth}\"\n height=\"${LONG - insetStart - insetEnd}\"\n fill=\"${fill}\"\n stroke=\"${color}\"\n stroke-width=\"0\"\n />\n `;\n }\n return svg`\n <rect\n class=\"track\"\n x=\"${insetStart}\"\n y=\"${cross / 2 - strokeWidth / 2}\"\n width=\"${LONG - insetStart - insetEnd}\"\n height=\"${strokeWidth}\"\n fill=\"${fill}\"\n stroke=\"${color}\"\n stroke-width=\"0\"\n />\n `;\n }\n\n #getCssVarColor(name: string, fallback: string): string {\n const style = getComputedStyle(this);\n const val = style.getPropertyValue(name).trim();\n return val || fallback;\n }\n\n #renderLane(lane: SliderLaneData) {\n const bounds = getTrackBounds(this.orientation, this.#currentCross, this.#currentInsetStart, this.#currentInsetEnd);\n let path = ``;\n\n if (lane.type === `fixed`) {\n const start = this.orientation === `horizontal`\n ? { x: bounds.trackStart, y: bounds.crossCentre }\n : { x: bounds.crossCentre, y: bounds.trackStart };\n const end = this.orientation === `horizontal`\n ? { x: bounds.trackEnd, y: bounds.crossCentre }\n : { x: bounds.crossCentre, y: bounds.trackEnd };\n path = generateLinePath(start, end);\n } else if (lane.type === `anchored`) {\n const rel = this.#getRelativeValueA();\n const seg = getAnchoredSegment(rel, lane.value ?? 0.1, this.singleStyle, bounds, this.orientation);\n path = generateLinePath(seg.start, seg.end);\n } else {\n // 'value' lane: from valueMin to valueMax.\n const lo = lane.valueMin ?? 0;\n const hi = lane.valueMax ?? 0;\n const seg = getValueSegment(lo, hi, this.singleStyle, bounds, this.orientation);\n path = generateLinePath(seg.start, seg.end);\n }\n\n if (!path)\n return svg``;\n\n // Lane widths are true fractions of the cross axis, resolved to screen px\n // per render (see #laneStrokePx). A `calc(var * 24%)` percentage cannot do\n // this: percentages resolve against the viewBox-local diagonal (~71 units\n // and host-size independent), so documented 0..1 fractions painted ~10x\n // too thin and never scaled with the host. With `non-scaling-stroke` the\n // px number below renders verbatim, keeping dashes frozen as before.\n // Width cascade mirrors #laneWidthNumber: the value lane follows the\n // track width unless explicitly overridden, so a thick track doesn't end\n // up with a hairline value bar.\n const w = `${this.#laneStrokePx(lane.key)}px`;\n // Offsets are likewise cross-relative (see SliderLaneData), not legacy\n // CROSS units.\n const offsetPx = lane.offset * this.#currentCrossPx / 2;\n const transform = this.orientation === `horizontal`\n ? `translateY(${offsetPx}px)`\n : `translateX(${offsetPx}px)`;\n\n return svg`\n <path\n class=\"lane\"\n data-lane-key=\"${lane.key}\"\n part=\"lane lane-${lane.key}\"\n d=\"${path}\"\n style=\"\n stroke-width: ${w};\n stroke-linecap: var(--lane-linecap, round);\n transform: ${transform};\n \"\n />\n `;\n }\n\n #renderValueMarker(handle: SliderHandleKey | undefined, defs: unknown[]) {\n const bounds = getTrackBounds(this.orientation, this.#currentCross, this.#currentInsetStart, this.#currentInsetEnd);\n const cross = bounds.cross;\n const isHorizontal = this.orientation === `horizontal`;\n\n let value: number;\n if (this.valueMode === `single`) {\n value = this.#getRelativeValueA();\n } else {\n if (handle === `a`)\n value = this.#getRelativeValueA();\n else if (handle === `b`)\n value = this.#getRelativeValueB();\n else value = this.#getRelativeValueC();\n }\n\n const pos = valueToPosition(value, this.singleStyle, bounds, this.orientation);\n\n const markerOffset = this.#getCssVar(`--marker-offset`, 0);\n const markerLength = this.#getCssVar(`--marker-length`, 0.8);\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n\n const center = isHorizontal\n ? { x: pos.x, y: bounds.crossCentre + markerOffset * (cross / 2) }\n : { x: bounds.crossCentre + markerOffset * (cross / 2), y: pos.y };\n\n // For unipolar, the value bar is symmetric around the track centre, so\n // the \"low end\" is the reflection of the high end across the centre.\n const isUnipolarSingle = this.valueMode === `single` && this.singleStyle === `unipolar`;\n const lowCenter = isUnipolarSingle\n ? (isHorizontal\n ? { x: 2 * bounds.centre - center.x, y: center.y }\n : { x: center.x, y: 2 * bounds.centre - center.y })\n : undefined;\n\n const id = handle ?? `s`;\n\n // Per-handle marker-style override: in triple mode the C handle can\n // take a different shape than the global `markerStyle` applied to A/B.\n const effectiveMarkerStyle = handle === `c` && this.markerStyleC\n ? this.markerStyleC\n : this.markerStyle;\n\n if (effectiveMarkerStyle === `dot`) {\n const { rx, ry } = this.#circleRadiiUnits(this.#dotRadiusPx(), cross);\n const renderDot = (cx: number, cy: number, mid: string) => {\n if (markerBorderWidth > 0) {\n defs.push(svg`<ellipse id=\"dot-${mid}-path\" cx=\"${cx}\" cy=\"${cy}\" rx=\"${rx}\" ry=\"${ry}\" />`);\n return svg`\n <use href=\"#dot-${mid}-path\" class=\"marker-border\" />\n <use href=\"#dot-${mid}-path\" class=\"marker-fill\" />\n `;\n }\n return svg`<ellipse cx=\"${cx}\" cy=\"${cy}\" rx=\"${rx}\" ry=\"${ry}\" />`;\n };\n\n const high = renderDot(center.x, center.y, id);\n if (lowCenter) {\n return svg`${high}${renderDot(lowCenter.x, lowCenter.y, `${id}-low`)}`;\n }\n return high;\n }\n\n if (effectiveMarkerStyle === `needle`) {\n const halfLen = (markerLength * cross) / 4;\n // Draw perpendicular to the track\n const renderNeedle = (cx: number, cy: number, mid: string) => {\n let start: Point;\n let end: Point;\n if (isHorizontal) {\n start = { x: cx, y: cy - halfLen };\n end = { x: cx, y: cy + halfLen };\n } else {\n start = { x: cx - halfLen, y: cy };\n end = { x: cx + halfLen, y: cy };\n }\n const path = `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n if (markerBorderWidth > 0) {\n defs.push(svg`<path id=\"needle-${mid}-path\" d=\"${path}\" />`);\n return svg`\n <use href=\"#needle-${mid}-path\" class=\"marker-border\" />\n <use href=\"#needle-${mid}-path\" class=\"marker-fill\" />\n `;\n }\n return svg`<path d=\"${path}\" stroke-linecap=\"round\" />`;\n };\n\n const high = renderNeedle(center.x, center.y, id);\n if (lowCenter) {\n return svg`${high}${renderNeedle(lowCenter.x, lowCenter.y, `${id}-low`)}`;\n }\n return high;\n }\n\n if (effectiveMarkerStyle === `triangle`) {\n // Apex sits on the value-track centreline at `center`; base sits\n // perpendicular to the track, offset *outward* by markerLength so the\n // shape hangs outside the value band with its point facing in.\n const halfLen = (markerLength * cross) / 4;\n // Narrow base: half the cross-fraction so the triangle reads as a\n // pointer rather than a flattened wedge once axes are scaled.\n const halfBase = (markerThickness * cross) / 4;\n const renderTriangle = (cx: number, cy: number, mid: string) => {\n let apex: Point;\n let base1: Point;\n let base2: Point;\n if (isHorizontal) {\n apex = { x: cx, y: cy };\n base1 = { x: cx - halfBase, y: cy + halfLen };\n base2 = { x: cx + halfBase, y: cy + halfLen };\n } else {\n apex = { x: cx, y: cy };\n base1 = { x: cx + halfLen, y: cy - halfBase };\n base2 = { x: cx + halfLen, y: cy + halfBase };\n }\n const points = `${apex.x},${apex.y} ${base1.x},${base1.y} ${base2.x},${base2.y}`;\n if (markerBorderWidth > 0) {\n defs.push(svg`<polygon id=\"triangle-${mid}-path\" points=\"${points}\" />`);\n return svg`\n <use href=\"#triangle-${mid}-path\" class=\"marker-border\" />\n <use href=\"#triangle-${mid}-path\" class=\"marker-fill\" />\n `;\n }\n return svg`<polygon points=\"${points}\" />`;\n };\n\n const high = renderTriangle(center.x, center.y, id);\n if (lowCenter) {\n return svg`${high}${renderTriangle(lowCenter.x, lowCenter.y, `${id}-low`)}`;\n }\n return high;\n }\n\n return svg``;\n }\n\n #renderMidpointMarker() {\n if (this.valueMode !== `single`)\n return svg``;\n if (this.singleStyle !== `bipolar` && this.singleStyle !== `unipolar`)\n return svg``;\n const bounds = getTrackBounds(this.orientation, this.#currentCross, this.#currentInsetStart, this.#currentInsetEnd);\n const cross = bounds.cross;\n const isHorizontal = this.orientation === `horizontal`;\n const length = this.#getCssVar(`--midpoint-length`, 0.15);\n const halfLen = (length * cross) / 4;\n\n const center = isHorizontal\n ? { x: bounds.centre, y: bounds.crossCentre }\n : { x: bounds.crossCentre, y: bounds.centre };\n\n if (this.markerStyle === `dot`) {\n const size = this.#getCssVar(`--midpoint-thickness`, 0.08);\n const rPx = this.#currentCrossPx > 0 ? size * this.#currentCrossPx / 2 : size * (cross / 2);\n const { rx, ry } = this.#circleRadiiUnits(rPx, cross);\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <ellipse cx=\"${center.x}\" cy=\"${center.y}\" rx=\"${rx}\" ry=\"${ry}\" />\n </g>\n `;\n }\n\n let start: Point;\n let end: Point;\n if (isHorizontal) {\n start = { x: center.x, y: center.y - halfLen };\n end = { x: center.x, y: center.y + halfLen };\n } else {\n start = { x: center.x - halfLen, y: center.y };\n end = { x: center.x + halfLen, y: center.y };\n }\n\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <line x1=\"${start.x}\" y1=\"${start.y}\" x2=\"${end.x}\" y2=\"${end.y}\" />\n </g>\n `;\n }\n\n #renderHandleGroup(handle: SliderHandleKey | undefined, content: unknown) {\n if (!handle) {\n // Single-mode: don't put tabindex on the `<g>`. The host itself is\n // the focusable element (the inner SVG is tabindex=-1 so there is\n // exactly one tab stop and one focus outline), and keydown reaches\n // the handler via the host-level listener.\n return svg`<g role=\"slider\"\n class=\"value-marker\"\n aria-orientation=\"${this.orientation}\"\n aria-valuemin=\"${this.min}\" aria-valuemax=\"${this.max}\"\n aria-valuenow=\"${this.valueA}\"\n part=\"value-marker\">${content}</g>`;\n }\n const partName = `value-marker value-marker-${handle}`;\n const value = handle === `a`\n ? this.valueA\n : handle === `b`\n ? this.valueB\n : (this.valueC ?? (this.#poleA + this.#poleB) / 2);\n // Multi-handle: each handle is its own focusable group so Tab moves\n // between them independently.\n return svg`<g tabindex=\"${this.disabled ? -1 : 0}\" role=\"slider\"\n class=\"value-marker\"\n data-handle=\"${handle}\"\n aria-label=\"${handle}\"\n aria-orientation=\"${this.orientation}\"\n aria-valuemin=\"${this.min}\" aria-valuemax=\"${this.max}\"\n aria-valuenow=\"${value}\"\n part=\"${partName}\">${content}</g>`;\n }\n\n #isMultiHandle(): boolean {\n return this.valueMode !== `single`;\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n // Sync internal poles from public properties\n if (changed.has(`valueA`) || changed.has(`valueB`) || !this.hasUpdated) {\n this.#poleA = this.valueA;\n this.#poleB = this.valueB;\n }\n\n // Initial / mode-change valueC defaulting\n if (this.valueMode === `triple`) {\n if (\n this.valueC === undefined\n || !this.#hasInitialisedValueC\n || changed.has(`valueMode`)\n ) {\n this.#poleC = (this.#poleA + this.#poleB) / 2;\n this.valueC = this.#poleC;\n this.#hasInitialisedValueC = true;\n } else {\n this.#poleC = this.valueC;\n }\n // Clamp C to [low, high]\n const lo = Math.min(this.#poleA, this.#poleB);\n const hi = Math.max(this.#poleA, this.#poleB);\n if (this.#poleC < lo)\n this.#poleC = lo;\n if (this.#poleC > hi)\n this.#poleC = hi;\n this.valueC = this.#poleC;\n } else {\n this.#poleC = undefined;\n }\n\n // Sync value lane before render\n if (\n changed.has(`valueA`)\n || changed.has(`valueB`)\n || changed.has(`valueMode`)\n || changed.has(`singleStyle`)\n || !this.hasUpdated\n ) {\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n if (this.valueMode === `single`) {\n this.#applySingleStyleValueLane(valueLane, this.#getRelativeValueA());\n } else {\n valueLane.valueMin = valueToRelative(this.#low(), this.min, this.max);\n valueLane.valueMax = valueToRelative(this.#high(), this.min, this.max);\n }\n }\n }\n }\n\n /**\n * Sync the default 'value' lane's valueMin/valueMax for single-mode single-styles.\n * Range: bar from trackStart to value.\n * Bipolar: bar grows from track centre outward to value (or value to centre if below midpoint).\n * Unipolar: bar is centred on the track centre with length proportional to value.\n */\n #applySingleStyleValueLane(valueLane: SliderLaneData, relativeValue: number): void {\n if (this.singleStyle === `bipolar`) {\n valueLane.valueMin = Math.min(0.5, relativeValue);\n valueLane.valueMax = Math.max(0.5, relativeValue);\n } else {\n valueLane.valueMin = 0;\n valueLane.valueMax = relativeValue;\n }\n }\n\n override render(): unknown {\n // Size the viewBox to hug this render's content (markers, lanes,\n // track) before any sub-renderer reads the current insets.\n // Lane measuring comes first (dot floor + box math depend on it);\n // insets need the cross (dot/triangle along-axis extent scales with it).\n this.#measureLanes();\n this.#currentCross = this.#computeCross();\n const insets = this.#computeInsets(this.#currentCross);\n this.#currentInsetStart = insets.start;\n this.#currentInsetEnd = insets.end;\n const lanes = Array.from(this.#lanes.values());\n\n // Initial cursor before the first pointermove arrives. The dynamic\n // cursor (#onPointerMoveCursor) takes over as soon as the user moves\n // the pointer. In single mode the default `pointer` matches \"click to\n // set\"; in multi mode `default` matches \"no implicit interaction for\n // arbitrary track positions\".\n const cursor = this.disabled\n ? `not-allowed`\n : this.valueMode === `single`\n ? `pointer`\n : `default`;\n\n const handles: SliderHandleKey[] = this.#isMultiHandle()\n ? (this.valueMode === `triple` ? [`a`, `b`, `c`] : [`a`, `b`])\n : [];\n\n // Halo shapes for --marker-border-width>0 are pushed here so they end up\n // inside a single root <defs>, matching radial-input's pattern.\n // Compute marker content first so the defs list is populated, then\n // reference both in the template below.\n const markerDefs: unknown[] = [];\n const handleGroups = this.#isMultiHandle()\n ? handles.map(h => this.#renderHandleGroup(h, this.#renderValueMarker(h, markerDefs)))\n : this.#renderHandleGroup(undefined, this.#renderValueMarker(undefined, markerDefs));\n\n return html`\n <svg\n class=\"slider-svg\"\n viewBox=\"${this.#viewBox()}\"\n preserveAspectRatio=\"none\"\n tabindex=\"-1\"\n style=\"cursor: ${cursor}; width: 100%; height: 100%;\"\n @pointerdown=\"${this.#onPointerDown}\"\n @pointermove=\"${this.#onPointerMoveCursor}\"\n @pointerleave=\"${this.#onPointerLeaveCursor}\"\n @keydown=\"${this.#onKeyDown}\"\n @focusin=\"${this.#onFocusIn}\"\n >\n ${markerDefs.length > 0 ? svg`<defs>${markerDefs}</defs>` : svg``}\n ${this.#renderTrack()}\n ${lanes.map(lane => this.#renderLane(lane))}\n ${this.#renderMidpointMarker()}\n ${handleGroups}\n </svg>\n `;\n }\n\n /**\n * Compute the cursor for the current pointer position. The mapping:\n * - `grab` over a marker handle (single A, or multi A/B/C)\n * - `move` over a draggable segment (between A and B when value-drag is on)\n * - `pointer` over empty track where clicking sets a value (single mode,\n * or the dead zones outside A/B in multi mode)\n * - `default` over no-op segments (between A and B in dual mode when\n * value-drag is none, or between A-C/C-B in triple when value-drag is none)\n * - `not-allowed` when disabled\n *\n * `relativeValue` is in the host's long-axis space (0 = start, 1 = end,\n * already flipped for vertical). For unipolar single mode, the value\n * bar's marker positions are computed in the same space; the abs(2x-1)\n * remap only applies when setting the value on click/drag.\n */\n #cursorAtRelative(relativeValue: number): string {\n if (this.disabled)\n return `not-allowed`;\n if (this.#dragging)\n return `grabbing`;\n\n const HANDLE_HIT = 0.06;\n\n if (this.valueMode === `single`) {\n if (this.singleStyle === `unipolar`) {\n // In unipolar the bar is symmetric around the track centre; the\n // value bar's two ends sit at `0.5 ± value/2`.\n const halfLen = this.#getRelativeValueA() / 2;\n const low = 0.5 - halfLen;\n const high = 0.5 + halfLen;\n if (\n Math.abs(relativeValue - low) < HANDLE_HIT\n || Math.abs(relativeValue - high) < HANDLE_HIT\n ) {\n return `grab`;\n }\n return `pointer`;\n }\n const aRel = this.#getRelativeValueA();\n if (Math.abs(relativeValue - aRel) < HANDLE_HIT) {\n return `grab`;\n }\n return `pointer`;\n }\n\n const aRel = this.#getRelativeValueA();\n const bRel = this.#getRelativeValueB();\n const lo = Math.min(aRel, bRel);\n const hi = Math.max(aRel, bRel);\n\n // Over a handle: grab\n if (Math.abs(relativeValue - aRel) < HANDLE_HIT)\n return `grab`;\n if (Math.abs(relativeValue - bRel) < HANDLE_HIT)\n return `grab`;\n if (this.valueMode === `triple`) {\n const cRel = this.#getRelativeValueC();\n if (Math.abs(relativeValue - cRel) < HANDLE_HIT)\n return `grab`;\n }\n\n // Inside the segment between A and B\n if (relativeValue > lo && relativeValue < hi) {\n return this.valueDrag !== `none` ? `move` : `default`;\n }\n\n // Outside A/B (dead zone) — clicking here jumps A or B to that position\n return `pointer`;\n }\n\n #onPointerMoveCursor = (event: PointerEvent): void => {\n const svg = this.renderRoot.querySelector(`svg.slider-svg`) as SVGElement | null;\n if (!svg)\n return;\n this.#lastPointerClient = { x: event.clientX, y: event.clientY };\n const clientPos = this.orientation === `vertical` ? event.clientY : event.clientX;\n // Unipolar click mapping is NOT applied here — it's only for click-to-set;\n // the cursor needs the track-relative position to find the markers.\n const relativeValue = this.#relativeFromTrackPos(clientPos);\n const cursor = this.#cursorAtRelative(relativeValue);\n if (svg.style.cursor !== cursor) {\n svg.style.cursor = cursor;\n }\n };\n\n #onPointerLeaveCursor = (): void => {\n // Reset to the default cursor (whatever the host sets) when the pointer\n // leaves the slider area, so the cursor doesn't stay stuck on `grab` etc.\n const svg = this.renderRoot.querySelector(`svg.slider-svg`) as SVGElement | null;\n if (!svg)\n return;\n const cursor = this.disabled ? `not-allowed` : `default`;\n if (svg.style.cursor !== cursor) {\n svg.style.cursor = cursor;\n }\n };\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n // Update --value-relative / min/max/c CSS variables unconditionally\n if (this.valueMode === `single`) {\n this.style.setProperty(`--value-relative`, this.#getRelativeValueA().toString());\n } else {\n const lo = valueToRelative(this.#low(), this.min, this.max);\n const hi = valueToRelative(this.#high(), this.min, this.max);\n this.style.setProperty(`--value-min-relative`, lo.toString());\n this.style.setProperty(`--value-max-relative`, hi.toString());\n this.style.setProperty(`--value-relative`, hi.toString());\n if (this.valueMode === `triple` && this.#poleC !== undefined) {\n this.style.setProperty(`--value-c-relative`, valueToRelative(this.#poleC, this.min, this.max).toString());\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener(`keydown`, this.#onHostKeyDown);\n this.removeEventListener(`pointerdown`, this.#onSwipePointerDown as EventListener);\n this.removeEventListener(`pointermove`, this.#onSwipePointerMove as EventListener);\n this.removeEventListener(`pointerenter`, this.#onSwipePointerEnter as EventListener);\n this.#gradientObserver?.disconnect();\n this.#gradientObserver = undefined;\n this.#sizeObserver?.disconnect();\n this.#sizeObserver = undefined;\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n this.#changeDebounceTimer = undefined;\n }\n this.#onPointerUp();\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-block;\n width: 200px;\n height: 12px;\n touch-action: none;\n user-select: none;\n tabindex: 0;\n --value-relative: 0;\n --value-min-relative: 0;\n --value-max-relative: 0;\n --value-c-relative: 0;\n\n --lane-width: 0.16;\n }\n\n :host([orientation=\"vertical\"]) {\n width: 12px;\n height: 200px;\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n :host {\n outline: none;\n }\n\n :host(:focus-visible) {\n outline: var(--slider-input-svg-focus-outline, 2px solid var(--accent));\n outline-offset: var(--slider-input-svg-focus-outline-offset, 2px);\n }\n\n svg.slider-svg {\n display: block;\n width: 100%;\n height: 100%;\n outline: none;\n overflow: visible;\n }\n\n svg.slider-svg:focus {\n outline: none;\n }\n\n svg.slider-svg:focus-visible {\n outline: var(--slider-input-svg-focus-outline, 2px solid var(--accent));\n outline-offset: var(--slider-input-svg-focus-outline-offset, 2px);\n }\n\n .track {\n stroke: var(--track-color, var(--surface-4));\n /* Default 0 (not the stroke-width=\"0\" attribute below, which this\n rule overrides): the lanes carry the default visuals, so the rect\n is an opt-in backdrop via --track-fill / --track-width. A nonzero\n default here ballooned with the tight viewBox (2 units ≈ 60% of\n the cross axis) and swamped the lanes. */\n stroke-width: var(--track-width, 0);\n }\n\n .lane {\n fill: none;\n /* Rounded ends by default; set --lane-linecap: butt for square ends\n (reads cleaner under a needle/line marker). The inline style on the\n <path> repeats this so it wins over authored .lane rules. */\n stroke-linecap: var(--lane-linecap, round);\n stroke-dasharray: var(--lane-dasharray, none);\n stroke-dashoffset: var(--lane-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .lane[data-lane-key='track'] {\n stroke: var(--lane-track-color, var(--surface-4));\n }\n\n .lane[data-lane-key='value'] {\n stroke: var(--lane-value-color, var(--accent));\n }\n\n .lane:not([data-lane-key='track']):not([data-lane-key='value']) {\n stroke: var(--lane-color, var(--accent));\n }\n\n .value-marker > path:not(.marker-border):not(.marker-fill),\n .value-marker > .marker-fill {\n stroke: var(--marker-color, var(--accent));\n stroke-width: calc(var(--marker-thickness, 0.15) * 12px);\n stroke-linecap: round;\n stroke-dasharray: var(--marker-dasharray, none);\n stroke-dashoffset: var(--marker-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker > .marker-border {\n stroke: var(--marker-border-color, transparent);\n stroke-width: calc((var(--marker-thickness, 0.15) + var(--marker-border-width, 0) * 2) * 12px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-fill,\n .value-marker circle,\n .value-marker polygon {\n fill: var(--marker-color, var(--accent));\n stroke-width: calc(var(--marker-thickness, 0.15) * 12px);\n }\n\n .value-marker[data-handle=\"a\"] > path:not(.marker-border):not(.marker-fill),\n .value-marker[data-handle=\"a\"] > .marker-fill,\n .value-marker[data-handle=\"a\"] > circle,\n .value-marker[data-handle=\"a\"] > polygon {\n stroke: var(--marker-a-color, var(--marker-color, var(--accent)));\n fill: var(--marker-a-color, var(--marker-color, var(--accent)));\n }\n\n .value-marker[data-handle=\"b\"] > path:not(.marker-border):not(.marker-fill),\n .value-marker[data-handle=\"b\"] > .marker-fill,\n .value-marker[data-handle=\"b\"] > circle,\n .value-marker[data-handle=\"b\"] > polygon {\n stroke: var(--marker-b-color, var(--marker-color, var(--accent)));\n fill: var(--marker-b-color, var(--marker-color, var(--accent)));\n }\n\n .value-marker[data-handle=\"c\"] > path:not(.marker-border):not(.marker-fill),\n .value-marker[data-handle=\"c\"] > .marker-fill,\n .value-marker[data-handle=\"c\"] > circle,\n .value-marker[data-handle=\"c\"] > polygon {\n stroke: var(--marker-c-color, var(--marker-color, var(--accent)));\n fill: var(--marker-c-color, var(--marker-color, var(--accent)));\n }\n\n .midpoint-marker line {\n stroke: var(--midpoint-color, var(--surface-muted-text));\n stroke-width: var(--midpoint-thickness, 1px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .midpoint-marker circle {\n fill: var(--midpoint-color, var(--surface-muted-text));\n stroke: var(--midpoint-border-color, transparent);\n stroke-width: var(--midpoint-border-width, 0);\n vector-effect: non-scaling-stroke;\n }\n `];\n}\n\n// ─── Tag-name registration ───────────────────────────────────────────\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-slider-input': SliderInputElement;\n }\n}\n\n// ─── Module-scope interface merge (typed addEventListener) ─────────────\nexport interface SliderInputElement {\n addEventListener: (<K extends keyof SliderInputElementEventMap>(\n type: K,\n listener: (this: SliderInputElement, event: SliderInputElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree-CozQj01a.js","names":["#root","#loadChildren","#cache","#notify","#subscribers","#getAllNodes","#getFocusedIndex","#setFocusedIndex","#extendRangeSelection","#anchor","#toggleExpand","#toggleSelection","#abortPending","#ownedRegistry","#effectiveSearchModes","#unregisterSearchCommands","#diffVisibleNodes","#enteringKeys","#treeAnimReady","#renderedKeys","#leaving","#lastNodeByKey","#leavingAnimating","#matchesFilter","#clearSelectionInternal","#modelUnsubscribe","#runItemAnimations","#syncSearchCommands","#config","#canSelect","#dispatchSelect","#applyCheckedToggle","#applyExclusivity","#scrollKeyIntoView","#findNodePath","#pendingNode","#handleImplicitClick","#handleStandardClick","#handleManualClick","#handleExpandOnly","#clickedOnCaret","#getFlatIndexOf","#allDescendantsSelected","#pendingController","#invokeLoadChildren","#collapseSiblingsAtDepth","#findAncestorKeys","#findParent","#getVisibleNodes","#scrollTickledIntoView","#onKeyDown","#onDblClick","#renderNodes","#weaveLeaving","customElement","#detectIcons","#depthsWithIcons","#renderCheckbox","customElement","#root","#element","#options","#connectSignal","#childrenOf","#nodeToTree","#findTreePath","#toTreeNode","#identityToTreeNode"],"sources":["../src/common/tree-data-model.ts","../src/tree/tree-base.ts","../src/tree/tree-list.ts","../src/tree/tree-controller.ts"],"sourcesContent":["import type { LoadChildrenCallback, TreeItem, TreeNode } from './types.js';\nimport { collectDataResult } from './data-provider.js';\n\n// ---------------------------------------------------------------------------\n// Subscription event types (internal — not part of the public API)\n// ---------------------------------------------------------------------------\n\ntype InvalidateEvent = { type: `invalidate`; key: string };\ntype RootEvent = { type: `root`; root: TreeNode };\ntype ModelEvent = InvalidateEvent | RootEvent;\n\ntype ModelSubscriber = (event: ModelEvent) => void;\n\n// ---------------------------------------------------------------------------\n// Pure tree-mutation helpers (functional, produce new roots)\n// ---------------------------------------------------------------------------\n\n// function cloneNode(node: TreeNode): TreeNode {\n// if (node.children === undefined)\n// return { item: { ...node.item } };\n// return { item: { ...node.item }, children: node.children.map(cloneNode) };\n// }\n\nfunction findNode(root: TreeNode, key: string): TreeNode | undefined {\n if (root.item.key === key)\n return root;\n if (!root.children)\n return undefined;\n for (const child of root.children) {\n const found = findNode(child, key);\n if (found)\n return found;\n }\n return undefined;\n}\n\n/** Return a new root with the node at `key` replaced by `replacer(node)`. */\nfunction mapNode(root: TreeNode, key: string, replacer: (n: TreeNode) => TreeNode): TreeNode {\n if (root.item.key === key)\n return replacer(root);\n if (!root.children)\n return root;\n return { item: root.item, children: root.children.map(c => mapNode(c, key, replacer)) };\n}\n\n/** Return a new root with `newChild` appended to the children of the node at `parentKey`. */\nfunction addChildTo(root: TreeNode, parentKey: string, newChild: TreeNode): TreeNode {\n return mapNode(root, parentKey, parent => ({\n item: parent.item,\n children: [...(parent.children ?? []), newChild],\n }));\n}\n\n/** Return a new root with the node at `key` removed (along with all its descendants). */\nfunction removeNodeFrom(root: TreeNode, key: string): TreeNode {\n if (!root.children)\n return root;\n return {\n item: root.item,\n children: root.children\n .filter(c => c.item.key !== key)\n .map(c => removeNodeFrom(c, key)),\n };\n}\n\n/** Return a new root with the node at `key` moved to become a child of `newParentKey`. */\nfunction moveNodeTo(root: TreeNode, key: string, newParentKey: string): TreeNode {\n const target = findNode(root, key);\n if (!target)\n return root;\n const withoutTarget = removeNodeFrom(root, key);\n return addChildTo(withoutTarget, newParentKey, target);\n}\n\n// ---------------------------------------------------------------------------\n// TreeDataModelOptions\n// ---------------------------------------------------------------------------\n\nexport type TreeDataModelOptions = {\n /** The initial root node. Required. */\n root: TreeNode;\n /**\n * Optional callback for lazily loading children.\n * If omitted, nodes with `children === undefined` are treated as empty branches.\n */\n loadChildren?: LoadChildrenCallback;\n};\n\n// ---------------------------------------------------------------------------\n// TreeDataModel\n// ---------------------------------------------------------------------------\n\n/**\n * Manages tree data for tree-like components.\n *\n * Handles two concerns:\n * 1. **Lazy loading** — caches children fetched via `loadChildren` and can invalidate\n * specific branches so they are re-fetched on next expand.\n * 2. **Structural mutations** — convenience methods to add, remove, update, or move\n * nodes. Each mutation produces a new immutable root and notifies connected components.\n *\n * Assign an instance to a component's `model` property instead of setting `root`/`loadChildren`\n * directly. The same model instance can be shared across multiple components.\n *\n * @example\n * ```typescript\n * const model = new TreeDataModel({\n * root: { item: { key: 'root', label: 'Root' }, children: [] },\n * loadChildren: async (node, depth, signal) => fetchChildren(node.item.key),\n * });\n * myTreeList.model = model;\n * myMillerList.model = model;\n *\n * // Later — invalidate a branch to force a re-fetch on next expand:\n * model.invalidate('some-key');\n * ```\n */\nexport class TreeDataModel {\n #root: TreeNode;\n #loadChildren: LoadChildrenCallback | undefined;\n #cache = new Map<string, TreeNode[]>();\n #subscribers = new Set<ModelSubscriber>();\n\n constructor(options: TreeDataModelOptions) {\n this.#root = options.root;\n this.#loadChildren = options.loadChildren;\n }\n\n // ---------------------------------------------------------------------------\n // Root\n // ---------------------------------------------------------------------------\n\n /** The current immutable root snapshot. */\n get root(): TreeNode {\n return this.#root;\n }\n\n /**\n * Replace the entire root with a new immutable snapshot.\n * All cached children are cleared. Connected components re-render.\n */\n setRoot(root: TreeNode): void {\n this.#root = root;\n this.#cache.clear();\n this.#notify({ type: `root`, root });\n }\n\n // ---------------------------------------------------------------------------\n // Child loading\n // ---------------------------------------------------------------------------\n\n /**\n * Returns children for the given node.\n * If children are cached, they are returned immediately (as a resolved Promise).\n * Otherwise the `loadChildren` callback is invoked and the result is cached.\n * If no `loadChildren` is set and no cache entry exists, returns `[]`.\n *\n * Called by components internally — not typically called by application code.\n */\n async getChildren(node: TreeNode, depth: number, signal: AbortSignal): Promise<TreeNode[]> {\n const key = node.item.key;\n if (this.#cache.has(key)) {\n return this.#cache.get(key)!;\n }\n if (!this.#loadChildren) {\n return [];\n }\n const items = await collectDataResult(this.#loadChildren({ node, depth }, signal), signal);\n const children = [...items] as TreeNode[];\n if (!signal.aborted) {\n this.#cache.set(key, children);\n }\n return children;\n }\n\n // ---------------------------------------------------------------------------\n // Cache invalidation\n // ---------------------------------------------------------------------------\n\n /**\n * Clears the cached children for the node with the given key.\n * Connected components will collapse that node (if currently expanded), so that\n * the next expand triggers a fresh `loadChildren` call.\n */\n invalidate(key: string): void {\n this.#cache.delete(key);\n this.#notify({ type: `invalidate`, key });\n }\n\n // ---------------------------------------------------------------------------\n // Convenience mutators\n // ---------------------------------------------------------------------------\n\n /**\n * Adds `node` as a child of the node identified by `parentKey`.\n * Returns the new root (connected components are notified automatically).\n */\n addNode(parentKey: string, node: TreeNode): TreeNode {\n this.#root = addChildTo(this.#root, parentKey, node);\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n /**\n * Removes the node with the given key and all its descendants.\n * Returns the new root (connected components are notified automatically).\n */\n removeNode(key: string): TreeNode {\n this.#cache.delete(key);\n this.#root = removeNodeFrom(this.#root, key);\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n /**\n * Applies a partial update to the `item` of the node with the given key.\n * Returns the new root (connected components are notified automatically).\n */\n updateItem(key: string, patch: Partial<TreeItem>): TreeNode {\n this.#root = mapNode(this.#root, key, n => ({\n item: { ...n.item, ...patch },\n children: n.children,\n }));\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n /**\n * Moves the node with the given key to become a child of `newParentKey`.\n * Returns the new root (connected components are notified automatically).\n */\n moveNode(key: string, newParentKey: string): TreeNode {\n this.#root = moveNodeTo(this.#root, key, newParentKey);\n this.#notify({ type: `root`, root: this.#root });\n return this.#root;\n }\n\n // ---------------------------------------------------------------------------\n // Internal subscription (used by components — not part of the public API)\n // ---------------------------------------------------------------------------\n\n /**\n * Subscribe to model events. Returns an unsubscribe function.\n * Components call this when the `model` property is set, and unsubscribe when it is unset.\n *\n * @internal\n */\n _subscribe(callback: ModelSubscriber): () => void {\n this.#subscribers.add(callback);\n return () => this.#subscribers.delete(callback);\n }\n\n #notify(event: ModelEvent): void {\n for (const sub of this.#subscribers) {\n sub(event);\n }\n }\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { CommandRegistry } from '@clinth/ui-commands';\nimport type { PropertyValues, TemplateResult } from 'lit';\nimport type { TreeSearchHost } from '../common/searchable.js';\nimport type {\n TreeActivateDetail,\n TreeActivateEvent,\n TreeCollapseDetail,\n TreeCollapseEvent,\n TreeComponent,\n TreeComponentEventMap,\n TreeExpandDetail,\n TreeExpandEvent,\n TreeItemClickDetail,\n TreeItemClickEvent,\n TreeItemDblClickDetail,\n TreeItemDblClickEvent,\n TreeSelectDetail,\n TreeSelectEvent,\n TreeTickleDetail,\n TreeTickleEvent,\n} from '../common/tree-component.js';\nimport type { TreeDataModel } from '../common/tree-data-model.js';\nimport type {\n LoadChildrenCallback,\n TreeExclusivity,\n TreeFilterPredicate,\n TreeInteractionMode,\n TreeNode,\n TreeSelectionFilter,\n} from '../common/types.js';\nimport type { ListSearchMode } from '../incr-search/index.js';\nimport type { TreeConfig } from './types.js';\nimport { createCommandRegistry } from '@clinth/ui-commands';\nimport { css, html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { collectDataResult } from '../common/data-provider.js';\nimport {\n createTreeListSearchAdapter,\n LIST_SEARCH_MODES,\n ListSearchController,\n\n listSearchStyles,\n registerListSearchCommands,\n} from '../incr-search/index.js';\nimport { tickledItemStyles, tickledStyles } from '../interaction/index.js';\nimport { animateListItemIn, animateListItemOut } from '../interaction/list-item-animation.js';\nimport { TickledController } from '../interaction/tickled-controller.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\n/** Above this many rows entering / leaving at once, skip the animation entirely. */\nconst MAX_ANIMATED_ROWS = 50;\n\n@customElement(`ixfx-tree-base`)\nexport class TreeBaseElement extends LitElement implements TreeComponent, TreeSearchHost {\n @property({ type: Object })\n root: TreeNode | undefined;\n\n @property({ attribute: false })\n model: TreeDataModel | undefined;\n\n /** Callback to lazily load children for a node. Superseded by `model` when both are set. */\n @property({ attribute: false })\n loadChildren: LoadChildrenCallback | undefined;\n\n @property({ reflect: true, attribute: `exclusivity` })\n exclusivity: TreeExclusivity = `none`;\n\n @property({ reflect: true, attribute: `selection-filter` })\n selectionFilter: TreeSelectionFilter = `all`;\n\n /** Controls how pointer/keyboard gestures map to selection changes. Default: `'standard'`. */\n @property({ type: String, attribute: `interaction-mode` })\n interactionMode: TreeInteractionMode = `standard`;\n\n @property({ attribute: false })\n selectedNode: TreeNode | undefined;\n\n @state()\n protected _selectedNodes = new Set<TreeNode>();\n\n get selectedNodes(): ReadonlySet<TreeNode> {\n return this._selectedNodes;\n }\n\n @property({ attribute: false })\n filterPredicate: TreeFilterPredicate | undefined;\n\n @property({ type: Boolean, attribute: `disable-keyboard-navigation` })\n disableKeyboardNavigation = false;\n\n @property({ attribute: false })\n registry: CommandRegistry<unknown> | undefined = undefined;\n\n /**\n * Space-separated subset of `navigate select filter` — limits which\n * incremental-search modes are offered. Unset ⇒ all three; empty ⇒ search\n * disabled. See `docs/infra-incremental.md`.\n */\n @property({ type: String, attribute: `search-modes`, reflect: true })\n searchModes: string | undefined;\n\n @state()\n protected _expandedKeys = new Set<string>();\n\n protected tickled = new TickledController<string>(this, {\n getItems: () => {\n const nodes = this.#getAllNodes();\n return nodes.map(({ node }) => ({ id: node.item.key, enabled: true }));\n },\n onStateChange: () => {\n this.setAttribute(`data-input-mode`, this.tickled.inputMode);\n },\n });\n\n @state()\n protected _focusedDepth = 0;\n\n /** Incremental search (navigate / select / filter). See `docs/infra-incremental.md`. */\n readonly search = new ListSearchController<{ node: TreeNode; depth: number }>(this, {\n adapter: createTreeListSearchAdapter(this, {\n labelSelector: `.tree-label`,\n highlightKey: `incr-search-highlight`,\n }),\n });\n\n #unregisterSearchCommands: (() => void) | undefined;\n\n #effectiveSearchModes(): ListSearchMode[] {\n const raw = this.searchModes?.trim();\n if (raw === undefined)\n return [...LIST_SEARCH_MODES];\n const requested = new Set(raw.split(/\\s+/));\n return LIST_SEARCH_MODES.filter(m => requested.has(m));\n }\n\n #syncSearchCommands(): void {\n if (!this.#ownedRegistry)\n return;\n this.search.setModes(this.#effectiveSearchModes());\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = registerListSearchCommands(this.#ownedRegistry, this.search);\n }\n\n #pendingNode: TreeNode | undefined;\n #pendingController: AbortController | undefined;\n #modelUnsubscribe: (() => void) | undefined;\n // Range-select anchor: the flat-list index and node from which a Shift-range is measured.\n #anchor: { node: TreeNode; flatIndex: number; selectionSnapshot?: ReadonlySet<TreeNode> } | undefined;\n #ownedRegistry: CommandRegistry<unknown> | undefined;\n\n #config: TreeConfig = {\n indent: 20,\n };\n\n // --- Insertion / removal animation ---\n // The visible node list is diffed each update: rows that appear (a branch\n // expanded, a node added to the model) collapse in; rows that disappear (a\n // branch collapsed, a node removed) are kept as fading \"ghost\" rows until\n // their collapse-out finishes. All no-ops under `prefers-reduced-motion`.\n #renderedKeys: string[] = [];\n #lastNodeByKey = new Map<string, { node: TreeNode; depth: number }>();\n #enteringKeys = new Set<string>();\n #leaving = new Map<string, { node: TreeNode; depth: number }>();\n #leavingAnimating = new Set<string>();\n #treeAnimReady = false;\n\n override willUpdate(changedProps: PropertyValues) {\n super.willUpdate(changedProps);\n this.#diffVisibleNodes();\n }\n\n #diffVisibleNodes(): void {\n const nodes = this.root ? this.#getAllNodes() : [];\n const nowKeys = new Set(nodes.map(n => n.node.item.key));\n\n this.#enteringKeys.clear();\n if (this.#treeAnimReady && this.#renderedKeys.length > 0) {\n const prevSet = new Set(this.#renderedKeys);\n for (const { node } of nodes) {\n if (!prevSet.has(node.item.key))\n this.#enteringKeys.add(node.item.key);\n }\n if (this.#enteringKeys.size > MAX_ANIMATED_ROWS)\n this.#enteringKeys.clear();\n\n for (const key of this.#renderedKeys) {\n if (!nowKeys.has(key) && !this.#leaving.has(key)) {\n const last = this.#lastNodeByKey.get(key);\n if (last)\n this.#leaving.set(key, last);\n }\n }\n }\n // A ghost whose key is visible again (re-expanded fast) stops being a ghost.\n for (const key of [...this.#leaving.keys()]) {\n if (nowKeys.has(key)) {\n this.#leaving.delete(key);\n this.#leavingAnimating.delete(key);\n }\n }\n if (this.#leaving.size > MAX_ANIMATED_ROWS) {\n this.#leaving.clear();\n this.#leavingAnimating.clear();\n }\n }\n\n /** True while `node` is a fading ghost row (removed / collapsed, still animating out). */\n protected _isLeaving(node: TreeNode): boolean {\n return this.#leaving.has(node.item.key);\n }\n\n /**\n * True when `filterPredicate` is set and neither `node` nor any descendant\n * matches — the row should carry the `filtered` class (`display: none`).\n */\n protected _isFilteredOut(node: TreeNode, depth: number): boolean {\n return this.filterPredicate !== undefined && !this.#matchesFilter(node, depth);\n }\n\n /** Splice the fading ghost rows back into the visible list near where they were. */\n #weaveLeaving(nodes: Array<{ node: TreeNode; depth: number }>): Array<{ node: TreeNode; depth: number }> {\n if (this.#leaving.size === 0)\n return nodes;\n const result = [...nodes];\n const indexOfKey = (key: string): number => result.findIndex(e => e.node.item.key === key);\n for (const [key, entry] of this.#leaving) {\n const prevIdx = this.#renderedKeys.indexOf(key);\n let insertAt = result.length;\n for (let j = prevIdx + 1; j < this.#renderedKeys.length; j++) {\n const at = indexOfKey(this.#renderedKeys[j]);\n if (at !== -1) {\n insertAt = at;\n break;\n }\n }\n result.splice(insertAt, 0, entry);\n }\n return result;\n }\n\n #runItemAnimations(): void {\n if (this.#enteringKeys.size > 0) {\n for (const el of this.renderRoot.querySelectorAll<HTMLElement>(`.item`)) {\n const key = el.dataset.key;\n if (key !== undefined && this.#enteringKeys.has(key))\n animateListItemIn(el);\n }\n this.#enteringKeys.clear();\n }\n if (this.#leaving.size > 0) {\n for (const el of this.renderRoot.querySelectorAll<HTMLElement>(`.item.leaving`)) {\n const key = el.dataset.key;\n if (key === undefined || this.#leavingAnimating.has(key))\n continue;\n this.#leavingAnimating.add(key);\n void animateListItemOut(el).then(() => {\n this.#leaving.delete(key);\n this.#leavingAnimating.delete(key);\n this.requestUpdate();\n });\n }\n }\n const visible = this.root ? this.#getAllNodes() : [];\n this.#renderedKeys = visible.map(n => n.node.item.key);\n this.#lastNodeByKey.clear();\n for (const entry of visible)\n this.#lastNodeByKey.set(entry.node.item.key, entry);\n this.#treeAnimReady = true;\n }\n\n override updated(changedProps: PropertyValues) {\n if (changedProps.has(`root`) && this.root) {\n this.#abortPending();\n this._expandedKeys.clear();\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._focusedDepth = 0;\n }\n\n if (changedProps.has(`model`)) {\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n const model = this.model;\n if (model) {\n this.root = model.root;\n this.#modelUnsubscribe = model._subscribe((event) => {\n if (event.type === `root`) {\n this.root = event.root;\n this.requestUpdate();\n } else if (event.type === `invalidate`) {\n // If the invalidated node is currently expanded, collapse it\n if (this._expandedKeys.has(event.key)) {\n this._expandedKeys.delete(event.key);\n this.requestUpdate();\n }\n }\n });\n }\n }\n\n if (changedProps.has(`interactionMode`)) {\n this.#anchor = undefined;\n this.clearSelection();\n }\n\n // When selectedNode is set externally, sync focus to match\n if (changedProps.has(`selectedNode`) && this.selectedNode) {\n const prev = changedProps.get(`selectedNode`) as TreeNode | undefined;\n if (prev !== this.selectedNode) {\n this.tickled.setTickled(this.selectedNode.item.key);\n }\n }\n\n this.#runItemAnimations();\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.setAttribute(`data-input-mode`, `mouse`);\n const registry = this.#ownedRegistry = createCommandRegistry();\n registry.register({\n id: `select-all`,\n label: `Select All`,\n description: `Select all visible items`,\n execute: () => this.selectAll(),\n });\n registry.register({\n id: `deselect-all`,\n label: `Deselect All`,\n description: `Clear all selection`,\n execute: () => this.deselectAll(),\n });\n this.registry = registry;\n this.#syncSearchCommands();\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.#modelUnsubscribe?.();\n this.#modelUnsubscribe = undefined;\n this.#unregisterSearchCommands?.();\n this.#unregisterSearchCommands = 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 getConfig(): TreeConfig {\n return { ...this.#config };\n }\n\n setConfig(config: Partial<TreeConfig>) {\n this.#config = { ...this.#config, ...config };\n this.requestUpdate();\n }\n\n // --- Programmatic selection ---\n\n select(node: TreeNode): void {\n if (!this.#canSelect(node))\n return;\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.clear();\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselect(node: TreeNode): void {\n if (!this._selectedNodes.has(node))\n return;\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.delete(node);\n if (this.selectedNode === node) {\n this.selectedNode = [...this._selectedNodes].at(-1);\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n clearSelection(): void {\n if (this._selectedNodes.size === 0)\n return;\n const prev = new Set(this._selectedNodes);\n this.#clearSelectionInternal();\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n selectAll(): void {\n const prev = new Set(this._selectedNodes);\n if (this.interactionMode === `checked`) {\n for (const { node } of this.#getAllNodes()) {\n if (!this.#canSelect(node))\n continue;\n this.#applyCheckedToggle(node, true);\n }\n } else {\n for (const { node } of this.#getAllNodes()) {\n if (!this.#canSelect(node))\n continue;\n this._selectedNodes.add(node);\n }\n this.selectedNode = [...this._selectedNodes].at(-1);\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n deselectAll(): void {\n const prev = new Set(this._selectedNodes);\n if (this.interactionMode === `checked`) {\n for (const { node } of this.#getAllNodes()) {\n if (!this.#canSelect(node))\n continue;\n this.#applyCheckedToggle(node, false);\n }\n } else {\n this.#clearSelectionInternal();\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n // --- Navigation ---\n\n navigateTo(keys: readonly string[]): boolean {\n if (!this.root?.children)\n return false;\n\n this.#abortPending();\n this.#clearSelectionInternal();\n this.tickled.clearTickled();\n this._focusedDepth = 0;\n\n let currentNode: TreeNode | undefined = this.root;\n\n for (const key of keys) {\n const children: TreeNode[] | undefined = currentNode?.children;\n if (!children)\n return false;\n\n const found: TreeNode | undefined = children.find(n => n.item.key === key);\n if (!found)\n return false;\n\n this.#applyExclusivity(found.item.key);\n this._expandedKeys.add(found.item.key);\n\n if (key === keys.at(-1)) {\n this.select(found);\n this.tickled.setTickled(found.item.key);\n }\n\n currentNode = found;\n }\n\n this.requestUpdate();\n this.#scrollKeyIntoView(keys.at(-1)!);\n return true;\n }\n\n navigateToNode(predicate: (node: TreeNode) => boolean): boolean {\n if (!this.root?.children)\n return false;\n const keyPath = this.#findNodePath(this.root.children, predicate);\n if (!keyPath)\n return false;\n return this.navigateTo(keyPath);\n }\n\n /** Expand ancestors + move the cursor to `key`, without touching the selection (search \"navigate\" mode). */\n revealKey(key: string): boolean {\n if (!this.root?.children)\n return false;\n const path = this.#findNodePath(this.root.children, n => n.item.key === key);\n if (!path)\n return false;\n for (let i = 0; i < path.length - 1; i++) {\n this.#applyExclusivity(path[i]);\n this._expandedKeys.add(path[i]);\n }\n this.tickled.setTickled(key);\n this.requestUpdate();\n void this.updateComplete.then(() => this.#scrollKeyIntoView(key));\n return true;\n }\n\n /** Replace the selection with `nodes` (subject to `selectionFilter`) — search \"select\" mode. */\n selectMany(nodes: Iterable<TreeNode>): void {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = new Set([...nodes].filter(n => this.#canSelect(n)));\n this.selectedNode = [...this._selectedNodes].at(-1);\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n getNodes(): ReadonlyArray<{ node: TreeNode; depth: number }> {\n if (!this.root?.children)\n return [];\n const result: Array<{ node: TreeNode; depth: number }> = [];\n const visit = (node: TreeNode, depth: number) => {\n result.push({ node, depth });\n if (node.children) {\n for (const child of node.children) visit(child, depth + 1);\n }\n };\n for (const child of this.root.children) visit(child, 0);\n return result;\n }\n\n // --- Internal helpers ---\n\n #canSelect(node: TreeNode): boolean {\n if (this.selectionFilter === `none`)\n return false;\n if (this.selectionFilter === `leaf`)\n return node.item.isLeaf === true;\n if (this.selectionFilter === `branch`)\n return node.item.isLeaf === false || (node.children !== undefined && node.children.length > 0);\n return true;\n }\n\n #clearSelectionInternal(): void {\n this._selectedNodes.clear();\n this.selectedNode = undefined;\n }\n\n #dispatchSelect(previous: ReadonlySet<TreeNode>): void {\n const detail: TreeSelectDetail = {\n selected: new Set(this._selectedNodes),\n previous,\n };\n this.dispatchEvent(new CustomEvent<TreeSelectDetail>(`select`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n }\n\n #findNodePath(\n nodes: TreeNode[],\n predicate: (node: TreeNode) => boolean,\n prefix: string[] = [],\n ): string[] | undefined {\n for (const node of nodes) {\n const path = [...prefix, node.item.key];\n if (predicate(node))\n return path;\n if (node.children?.length) {\n const result = this.#findNodePath(node.children, predicate, path);\n if (result)\n return result;\n }\n }\n return undefined;\n }\n\n protected renderNodeContent(node: TreeNode, depth: number): TemplateResult | typeof nothing {\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n return html`\n <span class=\"tree-caret\">\n ${isBranch ? html`<ixfx-icon class=\"caret-icon\" name=\"chevron-down\" .rotate=${isExpanded ? nothing : `-90deg`}></ixfx-icon>` : ``}\n </span>\n <span class=\"tree-label\">${node.item.label}</span>\n `;\n }\n\n protected _handleItemClick(node: TreeNode, depth: number, event?: MouseEvent) {\n // Second (or later) click of a double-click. `MouseEvent.detail` is the\n // running click count, so this is 2 during the second click. Swallow it:\n // the container's dblclick handler dispatches `item-dblclick`, and skipping\n // the switch below means the branch is never toggled twice.\n if (event && event.detail >= 2)\n return;\n\n if (this.#pendingNode && this._expandedKeys.has(this.#pendingNode.item.key)) {\n this.#abortPending();\n }\n\n this.tickled.handlePointerEnter(node.item.key);\n this._focusedDepth = depth;\n\n this.dispatchEvent(new CustomEvent<TreeItemClickDetail>(`item-click`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n\n switch (this.interactionMode) {\n case `implicit`: this.#handleImplicitClick(node, depth, event); break;\n case `standard`: this.#handleStandardClick(node, depth, event); break;\n case `vscode`: this.#handleStandardClick(node, depth, event); break;\n case `manual`: this.#handleManualClick(node, depth, event); break;\n case `checked`: this.#handleExpandOnly(node, depth); break;\n }\n\n this.requestUpdate();\n }\n\n /**\n * True when a click landed on the expand/collapse caret rather than the node\n * label. Caret clicks should only toggle expansion, never select or navigate.\n * The caret and label are siblings in the same shadow root, so `closest` on\n * the event target resolves reliably. See tree-fix.md.\n */\n #clickedOnCaret(node: TreeNode, event?: MouseEvent): boolean {\n // Leaf nodes still render an (empty) caret gutter for alignment; clicking\n // there should behave like a label click, so only guard branch nodes.\n if (node.item.isLeaf === true)\n return false;\n const target = event?.target;\n if (!(target instanceof Element))\n return false;\n return target.closest(`.tree-caret`) !== null;\n }\n\n #handleImplicitClick(node: TreeNode, depth: number, event?: MouseEvent): void {\n if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.clear();\n this._selectedNodes.add(node);\n this.selectedNode = node;\n if (!prev.has(node) || prev.size !== 1)\n this.#dispatchSelect(prev);\n }\n this.#toggleExpand(node, depth);\n }\n\n #handleStandardClick(node: TreeNode, depth: number, event?: MouseEvent): void {\n const isMeta = event ? (event.metaKey || event.ctrlKey) : false;\n const isShift = event ? event.shiftKey : false;\n\n if (isMeta) {\n if (this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n if (this._selectedNodes.has(node)) {\n this._selectedNodes.delete(node);\n if (this.selectedNode === node)\n this.selectedNode = [...this._selectedNodes].at(-1);\n } else {\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n }\n this.#dispatchSelect(prev);\n }\n return; // no expand on Ctrl+click\n }\n\n if (isShift && this.#anchor) {\n const visible = this.#getAllNodes();\n const anchorIdx = visible.findIndex(n => n.node === this.#anchor!.node);\n const targetIdx = visible.findIndex(n => n.node === node);\n if (anchorIdx >= 0 && targetIdx >= 0) {\n const prev = new Set(this._selectedNodes);\n const from = Math.min(anchorIdx, targetIdx);\n const to = Math.max(anchorIdx, targetIdx);\n const rangeNodes = visible.slice(from, to + 1)\n .map(n => n.node)\n .filter(n => this.#canSelect(n));\n this._selectedNodes = new Set(rangeNodes);\n this.selectedNode = node;\n this.#dispatchSelect(prev);\n }\n return; // no expand on Shift+click\n }\n\n // Plain click: select + toggle expand. A click on the caret only toggles\n // expansion — it must not change selection or trigger navigation.\n if (!this.#clickedOnCaret(node, event) && this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n this._selectedNodes.clear();\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n if (!prev.has(node) || prev.size !== 1)\n this.#dispatchSelect(prev);\n }\n this.#toggleExpand(node, depth);\n }\n\n #handleExpandOnly(node: TreeNode, depth: number): void {\n this.#toggleExpand(node, depth);\n }\n\n #handleManualClick(node: TreeNode, depth: number, event?: MouseEvent): void {\n const isMeta = event ? (event.metaKey || event.ctrlKey) : false;\n const isShift = event ? event.shiftKey : false;\n\n if (isMeta) {\n if (this.#canSelect(node)) {\n const prev = new Set(this._selectedNodes);\n if (this._selectedNodes.has(node)) {\n this._selectedNodes.delete(node);\n if (this.selectedNode === node)\n this.selectedNode = [...this._selectedNodes].at(-1);\n } else {\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n }\n this.#dispatchSelect(prev);\n }\n return; // no expand on Meta+click\n }\n\n if (isShift && this.#anchor) {\n const visible = this.#getAllNodes();\n const anchorIdx = visible.findIndex(n => n.node === this.#anchor!.node);\n const targetIdx = visible.findIndex(n => n.node === node);\n if (anchorIdx >= 0 && targetIdx >= 0) {\n const prev = new Set(this._selectedNodes);\n const from = Math.min(anchorIdx, targetIdx);\n const to = Math.max(anchorIdx, targetIdx);\n const rangeNodes = visible.slice(from, to + 1)\n .map(n => n.node)\n .filter(n => this.#canSelect(n));\n this._selectedNodes = new Set(rangeNodes);\n this.selectedNode = node;\n this.#dispatchSelect(prev);\n }\n return; // no expand on Shift+click\n }\n\n this.#toggleExpand(node, depth);\n }\n\n #toggleSelection(node: TreeNode, _depth: number): void {\n if (!this.#canSelect(node))\n return;\n const prev = new Set(this._selectedNodes);\n if (this._selectedNodes.has(node)) {\n this._selectedNodes.delete(node);\n if (this.selectedNode === node)\n this.selectedNode = [...this._selectedNodes].at(-1);\n } else {\n this._selectedNodes.add(node);\n this.selectedNode = node;\n this.#anchor = { node, flatIndex: this.#getFlatIndexOf(node) };\n }\n this.#dispatchSelect(prev);\n }\n\n protected _handleCheckboxClick(event: MouseEvent, node: TreeNode, _depth: number): void {\n event.stopPropagation();\n const prev = new Set(this._selectedNodes);\n const allSelected = this.#allDescendantsSelected(node);\n this.#applyCheckedToggle(node, !allSelected);\n if (this.selectedNode === undefined || !this._selectedNodes.has(this.selectedNode)) {\n this.selectedNode = [...this._selectedNodes].at(-1);\n }\n this.#dispatchSelect(prev);\n this.requestUpdate();\n }\n\n #toggleExpand(node: TreeNode, depth: number): void {\n const isExpanded = this._expandedKeys.has(node.item.key);\n if (isExpanded) {\n this._expandedKeys.delete(node.item.key);\n this.dispatchEvent(new CustomEvent<TreeCollapseDetail>(`collapse`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n } else {\n if (node.children === undefined) {\n if (node.item.isLeaf !== false)\n return;\n const loader = this.model ?? (this.loadChildren ? this : undefined);\n if (loader) {\n this.#pendingNode = node;\n const controller = new AbortController();\n this.#pendingController = controller;\n this.#invokeLoadChildren(node, depth, controller).catch(() => {});\n }\n } else {\n this.#applyExclusivity(node.item.key);\n this._expandedKeys.add(node.item.key);\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n }\n }\n }\n\n #allDescendantsSelected(node: TreeNode): boolean {\n if (!this._selectedNodes.has(node))\n return false;\n if (!node.children?.length)\n return true;\n return node.children.every(child => this.#allDescendantsSelected(child));\n }\n\n #applyCheckedToggle(node: TreeNode, selected: boolean): void {\n if (this.#canSelect(node)) {\n if (selected) {\n this._selectedNodes.add(node);\n } else {\n this._selectedNodes.delete(node);\n }\n }\n if (node.children) {\n for (const child of node.children) {\n this.#applyCheckedToggle(child, selected);\n }\n }\n }\n\n #getFlatIndexOf(node: TreeNode): number {\n return this.#getAllNodes().findIndex(n => n.node === node);\n }\n\n #extendRangeSelection(nodes: Array<{ node: TreeNode; depth: number }>, fromIdx: number, toIdx: number): void {\n // Set anchor at `fromIdx` if not already anchored\n if (!this.#anchor) {\n const anchorNode = nodes[fromIdx]?.node;\n if (anchorNode)\n this.#anchor = { node: anchorNode, flatIndex: fromIdx };\n }\n if (!this.#anchor)\n return;\n\n const anchorIdx = nodes.findIndex(n => n.node === this.#anchor!.node);\n if (anchorIdx < 0)\n return;\n\n const from = Math.min(anchorIdx, toIdx);\n const to = Math.max(anchorIdx, toIdx);\n\n if (this.interactionMode === `vscode`) {\n // On first Shift+arrow: snapshot current selection\n if (!this.#anchor.selectionSnapshot) {\n this.#anchor = { ...this.#anchor, selectionSnapshot: new Set(this._selectedNodes) };\n }\n const snap = this.#anchor.selectionSnapshot!;\n const rangeNodes = nodes.slice(from, to + 1).map(n => n.node).filter(n => this.#canSelect(n));\n // Toggle: items in snapshot stay toggled based on presence in snapshot\n const next = new Set(snap);\n for (const n of rangeNodes) {\n if (snap.has(n))\n next.delete(n);\n else next.add(n);\n }\n const prev = new Set(this._selectedNodes);\n this._selectedNodes = next;\n this.selectedNode = nodes[toIdx]?.node ?? this.selectedNode;\n this.#dispatchSelect(prev);\n } else {\n // standard: range replaces selection\n const prev = new Set(this._selectedNodes);\n const rangeNodes = nodes.slice(from, to + 1).map(n => n.node).filter(n => this.#canSelect(n));\n this._selectedNodes = new Set(rangeNodes);\n this.selectedNode = nodes[toIdx]?.node ?? this.selectedNode;\n this.#dispatchSelect(prev);\n }\n }\n\n async #invokeLoadChildren(node: TreeNode, depth: number, controller: AbortController): Promise<void> {\n try {\n let children: TreeNode[];\n if (this.model) {\n children = await this.model.getChildren(node, depth, controller.signal);\n } else {\n children = [...await collectDataResult(\n this.loadChildren!({ node, depth }, controller.signal),\n controller.signal,\n )];\n }\n if (controller.signal.aborted)\n return;\n node.children = children;\n this.#applyExclusivity(node.item.key);\n this._expandedKeys.add(node.item.key);\n this.#pendingNode = undefined;\n this.#pendingController = undefined;\n this.dispatchEvent(new CustomEvent<TreeExpandDetail>(`expand`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n } catch {\n if (controller.signal.aborted)\n return;\n node.children = [];\n this.#pendingNode = undefined;\n this.#pendingController = undefined;\n this.requestUpdate();\n }\n }\n\n protected _isSelected(node: TreeNode): boolean {\n return this._selectedNodes.has(node);\n }\n\n protected _isFocused(node: TreeNode): boolean {\n return this.tickled.isTickled(node.item.key);\n }\n\n protected _isExpanded(node: TreeNode, depth = 0): boolean {\n if (this._expandedKeys.has(node.item.key))\n return true;\n if (this.filterPredicate && node.children) {\n return node.children.some(child => this.#matchesFilter(child, depth + 1));\n }\n return false;\n }\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 protected get _pendingNode(): TreeNode | undefined {\n return this.#pendingNode;\n }\n\n #scrollKeyIntoView(key: string) {\n requestAnimationFrame(() => {\n const el = this.shadowRoot?.querySelector(`[data-key=\"${CSS.escape(key)}\"]`) as HTMLElement | null;\n if (!el)\n return;\n const elRect = el.getBoundingClientRect();\n const hostRect = this.getBoundingClientRect();\n const relativeTop = elRect.top - hostRect.top;\n const relativeBottom = relativeTop + elRect.height;\n if (relativeTop < 0) {\n this.scrollTop += relativeTop;\n } else if (relativeBottom > this.clientHeight) {\n this.scrollTop += relativeBottom - this.clientHeight;\n }\n });\n }\n\n #abortPending() {\n if (this.#pendingController) {\n this.#pendingController.abort();\n this.#pendingController = undefined;\n this.#pendingNode = undefined;\n }\n }\n\n /** Apply exclusivity rules when a node is about to be expanded. */\n #applyExclusivity(expandKey: string): void {\n if (this.exclusivity === `none`)\n return;\n\n if (this.exclusivity === `depth`) {\n this.#collapseSiblingsAtDepth(expandKey);\n } else if (this.exclusivity === `global`) {\n // Collapse all expanded nodes except direct ancestors of the expanding node\n const ancestorKeys = this.#findAncestorKeys(expandKey);\n for (const key of [...this._expandedKeys]) {\n if (!ancestorKeys.has(key) && key !== expandKey) {\n this._expandedKeys.delete(key);\n }\n }\n }\n }\n\n #collapseSiblingsAtDepth(expandKey: string): void {\n if (!this.root)\n return;\n\n const parent = this.#findParent(this.root, expandKey);\n if (!parent?.children)\n return;\n\n for (const child of parent.children) {\n if (child.item.key !== expandKey && this._expandedKeys.has(child.item.key)) {\n this._expandedKeys.delete(child.item.key);\n }\n }\n }\n\n #findAncestorKeys(targetKey: string): Set<string> {\n const keys = new Set<string>();\n const walk = (node: TreeNode): boolean => {\n if (node.item.key === targetKey)\n return true;\n if (!node.children)\n return false;\n for (const child of node.children) {\n if (walk(child)) {\n keys.add(node.item.key);\n return true;\n }\n }\n return false;\n };\n if (this.root)\n walk(this.root);\n return keys;\n }\n\n #findParent(node: TreeNode, targetKey: string, parent: TreeNode | undefined = undefined): TreeNode | undefined {\n if (!node.children)\n return undefined;\n\n for (const child of node.children) {\n if (child.item.key === targetKey) {\n return parent ?? node;\n }\n const found = this.#findParent(child, targetKey, child);\n if (found)\n return found;\n }\n return undefined;\n }\n\n #getVisibleNodes(node: TreeNode, depth: number): Array<{ node: TreeNode; depth: number }> {\n const result: Array<{ node: TreeNode; depth: number }> = [];\n\n const visit = (n: TreeNode, d: number) => {\n result.push({ node: n, depth: d });\n // `_isExpanded` also returns true for branches that have a filter match\n // among their descendants, so filter-search reveals the matches rather\n // than just narrowing the collapsed top level.\n if (n.children && this._isExpanded(n, d)) {\n for (const child of n.children) {\n visit(child, d + 1);\n }\n }\n };\n\n if (node.children) {\n for (const child of node.children) {\n visit(child, depth + 1);\n }\n }\n\n return result;\n }\n\n #getAllNodes(): Array<{ node: TreeNode; depth: number }> {\n if (!this.root)\n return [];\n // Root itself is never rendered — start at -1 so its children are depth 0\n return this.#getVisibleNodes(this.root, -1);\n }\n\n #getFocusedIndex(): number {\n const nodes = this.#getAllNodes();\n const tickledKey = this.tickled.tickledId;\n if (!tickledKey)\n return 0;\n return nodes.findIndex(n => n.node.item.key === tickledKey);\n }\n\n #setFocusedIndex(index: number) {\n const nodes = this.#getAllNodes();\n if (index < 0 || index >= nodes.length)\n return;\n const { node, depth } = nodes[index];\n this.tickled.setTickled(node.item.key);\n this._focusedDepth = depth;\n // Emit tickle for keyboard cursor movement\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n this.updateComplete.then(() => this.#scrollTickledIntoView());\n }\n\n #scrollTickledIntoView() {\n const tickledKey = this.tickled.tickledId;\n if (tickledKey === undefined)\n return;\n const item = this.shadowRoot?.querySelector(`[data-key=\"${tickledKey}\"]`);\n item?.scrollIntoView({ block: `nearest`, behavior: `smooth` });\n }\n\n #onKeyDown = (event: KeyboardEvent) => {\n if (this.search.isOpen)\n return;\n const nodes = this.#getAllNodes();\n if (nodes.length === 0)\n return;\n\n if ((event.ctrlKey || event.metaKey) && event.key === `a`) {\n event.preventDefault();\n this.selectAll();\n return;\n }\n\n // Switch to keyboard mode for any navigation key\n if ([`ArrowDown`, `ArrowUp`, `ArrowLeft`, `ArrowRight`, `Enter`, ` `].includes(event.key)) {\n this.tickled.setInputMode(`keyboard`);\n }\n\n const currentIdx = this.#getFocusedIndex();\n\n switch (event.key) {\n case `ArrowDown`: {\n event.preventDefault();\n const nextIdx = Math.min(currentIdx + 1, nodes.length - 1);\n if (this.interactionMode === `implicit`) {\n this.select(nodes[nextIdx].node);\n }\n this.#setFocusedIndex(nextIdx);\n if (event.shiftKey && (this.interactionMode === `standard` || this.interactionMode === `vscode`)) {\n this.#extendRangeSelection(nodes, currentIdx, nextIdx);\n } else if (this.interactionMode === `vscode`) {\n this.#anchor = undefined; // clear snapshot on plain navigation\n }\n this.requestUpdate();\n break;\n }\n case `ArrowUp`: {\n event.preventDefault();\n const prevIdx = Math.max(currentIdx - 1, 0);\n if (this.interactionMode === `implicit`) {\n this.select(nodes[prevIdx].node);\n }\n this.#setFocusedIndex(prevIdx);\n if (event.shiftKey && (this.interactionMode === `standard` || this.interactionMode === `vscode`)) {\n this.#extendRangeSelection(nodes, currentIdx, prevIdx);\n } else if (this.interactionMode === `vscode`) {\n this.#anchor = undefined; // clear snapshot on plain navigation\n }\n this.requestUpdate();\n break;\n }\n case `ArrowRight`: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (current && current.node.item.isLeaf !== true) {\n if (!this._expandedKeys.has(current.node.item.key)) {\n this.#toggleExpand(current.node, current.depth);\n } else if (currentIdx + 1 < nodes.length) {\n this.#setFocusedIndex(currentIdx + 1);\n }\n }\n this.requestUpdate();\n break;\n }\n case `ArrowLeft`: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (current && this._expandedKeys.has(current.node.item.key)) {\n this._expandedKeys.delete(current.node.item.key);\n this.dispatchEvent(new CustomEvent(`collapse`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n } else if (current.depth > 0) {\n const parentDepth = current.depth - 1;\n for (let i = currentIdx - 1; i >= 0; i--) {\n if (nodes[i].depth === parentDepth) {\n this.#setFocusedIndex(i);\n break;\n }\n }\n }\n this.requestUpdate();\n break;\n }\n case `Enter`: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (current) {\n if (this.interactionMode !== `manual` && this.interactionMode !== `checked`) {\n this.select(current.node);\n }\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail: { node: current.node, depth: current.depth },\n bubbles: true,\n composed: true,\n }));\n this.requestUpdate();\n }\n break;\n }\n case ` `: {\n event.preventDefault();\n const current = nodes[currentIdx];\n if (!current)\n break;\n\n if (this.interactionMode === `checked`) {\n this._handleCheckboxClick(new MouseEvent(`click`), current.node, current.depth);\n } else if (this.interactionMode === `standard` || this.interactionMode === `vscode` || this.interactionMode === `manual`) {\n this.#toggleSelection(current.node, current.depth);\n }\n break;\n }\n case `Escape`: {\n event.preventDefault();\n this.#abortPending();\n break;\n }\n }\n };\n\n protected renderLoadingIndicator(): TemplateResult | typeof nothing {\n return html`<span class=\"loading-spinner\"></span>`;\n }\n\n protected override render() {\n const nodes = this.#getAllNodes();\n\n return html`\n <div\n id=\"container\"\n data-input-mode=${this.tickled.inputMode}\n @keydown=${this.#onKeyDown}\n @dblclick=${this.#onDblClick}\n @pointerleave=${(e: PointerEvent) => this.tickled.handlePointerLeave(e)}\n tabindex=\"0\"\n >\n ${this.root ? this.#renderNodes(nodes) : nothing}\n </div>\n ${this.search.renderField()}\n `;\n }\n\n #onDblClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n const li = target.closest(`li`) as HTMLElement | null;\n if (!li)\n return;\n const key = li.dataset.key;\n if (!key)\n return;\n const nodes = this.#getAllNodes();\n const node = nodes.find(n => n.node.item.key === key);\n if (!node)\n return;\n const detail = { node: node.node, depth: node.depth };\n this.dispatchEvent(new CustomEvent<TreeItemDblClickDetail>(`item-dblclick`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n // `activate` still fires here for back-compat (Enter key also dispatches it).\n this.dispatchEvent(new CustomEvent<TreeActivateDetail>(`activate`, {\n detail,\n bubbles: true,\n composed: true,\n }));\n };\n\n #renderNodes(nodes: Array<{ node: TreeNode; depth: number }>) {\n if (nodes.length === 0 && this.#pendingNode && this.#leaving.size === 0) {\n return html`\n <div class=\"tree-loading\">\n ${this.renderLoadingIndicator()}\n </div>\n `;\n }\n\n // Keyed by node key so Lit never recycles a <li> across nodes — otherwise a\n // running leave animation (WAAPI, fill:forwards) would land on whatever node\n // reuses that <li> after the list shrinks, squashing it to 0 height.\n return html`\n <ul class=\"tree-list\" role=\"tree\">\n ${repeat(\n this.#weaveLeaving(nodes),\n ({ node }) => node.item.key,\n ({ node, depth }) => this._renderNode(node, depth),\n )}\n </ul>\n `;\n }\n\n protected _renderNode(node: TreeNode, depth: number): TemplateResult {\n const selected = this._isSelected(node);\n const tickled = this._isFocused(node);\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n const isPending = this.#pendingNode === node;\n const isFiltered = this._isFilteredOut(node, depth);\n const isLeaving = this._isLeaving(node);\n\n return html`\n <li\n class=\"item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${isFiltered ? `filtered` : ``} ${isLeaving ? `leaving` : ``}\"\n role=\"treeitem\"\n aria-selected=${selected}\n aria-expanded=${isBranch ? isExpanded : nothing}\n aria-hidden=${isLeaving ? `true` : nothing}\n aria-level=${depth + 1}\n data-key=${node.item.key}\n style=${`--depth: ${depth}`}\n @click=${(e: MouseEvent) => this._handleItemClick(node, depth, e)}\n @pointerenter=${() => {\n this.tickled.handlePointerEnter(node.item.key);\n this.dispatchEvent(new CustomEvent<TreeTickleDetail>(`tickle`, {\n detail: { node, depth },\n bubbles: true,\n composed: true,\n }));\n }}\n >\n ${this.renderNodeContent(node, depth)}\n ${isPending ? this.renderLoadingIndicator() : nothing}\n </li>\n `;\n }\n\n static override styles = [\n themeFallbacks,\n tickledStyles,\n tickledItemStyles,\n listSearchStyles,\n css`\n :host {\n --tree-bg: var(--surface-3);\n --tree-text: var(--surface-3-text);\n --tree-muted-text: var(--surface-muted-text);\n --tree-indent: 1ch;\n --tree-item-height: 2ch;\n --tree-caret-size: 30px;\n --tree-radius: var(--radius-s);\n\n position: relative;\n display: block;\n overflow: hidden;\n box-sizing: border-box;\n background: var(--tree-bg);\n color: var(--tree-text);\n }\n\n /* min-height (not height) so the tree still grows to its content when the\n host has no explicit height; when it does, this fills it and scrolls.\n The scroll lives here, not on :host, so the search popover (a sibling of\n #container, positioned against :host) stays put while the list scrolls. */\n #container {\n outline: none;\n min-height: 100%;\n max-height: 100%;\n overflow: auto;\n }\n\n .tree-list {\n list-style: none;\n margin: 0;\n padding: var(--space-xs);\n }\n\n .item {\n display: flex;\n align-items: center;\n height: var(--tree-item-height);\n padding-left: calc(var(--tree-indent) * var(--depth, 0) + var(--space-s));\n cursor: pointer;\n user-select: none;\n font-family: var(--font-family);\n font-size: var(--text-m);\n border-radius: var(--tree-radius);\n transition: background var(--transition, 0.15s ease-out);\n margin: 1px 0;\n }\n\n .tree-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Deliberately narrower than the icon: Lucide chevrons fill only ~half\n their viewBox, so letting the glyph overflow a slim box closes the\n visual gap to the label without shifting the indent. */\n width: calc(var(--tree-caret-size) * 0.5);\n height: var(--tree-caret-size);\n flex-shrink: 0;\n margin-right: 1px;\n overflow: visible;\n }\n\n .caret-icon {\n width: var(--tree-caret-size);\n height: var(--tree-caret-size);\n color: var(--tree-muted-text);\n transition: transform var(--transition, 0.15s ease-out);\n }\n\n .item.selected .caret-icon {\n color: var(--accent-text);\n }\n\n .tree-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tree-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--space-m);\n }\n\n .loading-spinner {\n width: 16px;\n height: 16px;\n border: 2px solid var(--surface-5);\n border-top-color: var(--accent);\n border-radius: 50%;\n animation: tree-spin 0.7s linear infinite;\n }\n\n @keyframes tree-spin {\n to { transform: rotate(360deg); }\n }\n\n .item.filtered {\n display: none;\n }\n\n /* Fading-out ghost row (see #runItemAnimations) — inert while it collapses. */\n .item.leaving {\n pointer-events: none;\n overflow: hidden;\n }\n\n ::highlight(incr-search-highlight) {\n background: var(--search-highlight-bg, var(--accent));\n color: var(--search-highlight-color, var(--accent-text, #fff));\n border-radius: 2px;\n padding: 0 1px;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-tree-base': TreeBaseElement;\n }\n}\n\nexport interface TreeBaseElementEventMap extends TreeComponentEventMap {\n 'item-click': TreeItemClickEvent;\n 'item-dblclick': TreeItemDblClickEvent;\n 'expand': TreeExpandEvent;\n 'collapse': TreeCollapseEvent;\n 'select': TreeSelectEvent;\n 'tickle': TreeTickleEvent;\n 'activate': TreeActivateEvent;\n}\n\nexport interface TreeBaseElement {\n addEventListener: (<K extends keyof TreeBaseElementEventMap>(\n type: K,\n listener: (this: TreeBaseElement, event: TreeBaseElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n removeEventListener: (<K extends keyof TreeBaseElementEventMap>(\n type: K,\n listener: (this: TreeBaseElement, event: TreeBaseElementEventMap[K]) => void,\n options?: boolean | EventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) => void);\n}\n","/* eslint-disable ts/no-unsafe-declaration-merging */\nimport type { TemplateResult } from 'lit';\nimport type { TreeBaseElementEventMap } from './tree-base.js';\nimport type { TreeNode } from './types.js';\nimport { css, html, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport { TreeBaseElement } from './tree-base.js';\n\n/** Checkbox tri-state in `checked` interactionMode: a branch node is `indeterminate` when some but not all of its descendants are selected. */\nexport type TreeCheckboxState = `checked` | `unchecked` | `indeterminate`;\n\nfunction computeCheckboxState(node: TreeNode, selectedNodes: ReadonlySet<TreeNode>): TreeCheckboxState {\n if (node.item.isLeaf || !node.children?.length) {\n return selectedNodes.has(node) ? `checked` : `unchecked`;\n }\n const childStates = node.children.map(c => computeCheckboxState(c, selectedNodes));\n const allChecked = childStates.every(s => s === `checked`);\n const allUnchecked = childStates.every(s => s === `unchecked`);\n if (allChecked)\n return `checked`;\n if (allUnchecked)\n return `unchecked`;\n return `indeterminate`;\n}\n\n@customElement(`ixfx-tree-list`)\nexport class TreeListElement extends TreeBaseElement {\n /**\n * Optional renderer for the checkbox shown in `checked` interactionMode.\n * Receives the node's current tri-state (`checked` / `unchecked` / `indeterminate`,\n * the latter when some but not all descendants are selected) and returns a Lit\n * template.\n *\n * When set, the checkbox becomes a `<span role=\"checkbox\">` whose contents are\n * whatever this returns. When unset, a native `<input type=\"checkbox\">` is used.\n *\n * @example\n * list.checkboxRenderer = (state) => state === `unchecked`\n * ? html``\n * : html`<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\"\n * fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\n * stroke-linecap=\"round\" stroke-linejoin=\"round\"\n * style=\"opacity:${state === `indeterminate` ? 0.35 : 0.6}\">\n * <polyline points=\"3,8 7,12 13,4\" />\n * </svg>`;\n */\n @property({ attribute: false })\n checkboxRenderer: ((state: TreeCheckboxState) => unknown) | undefined;\n\n #depthsWithIcons = new Set<number>();\n\n protected override render() {\n this.#detectIcons();\n return super.render();\n }\n\n #detectIcons() {\n this.#depthsWithIcons.clear();\n const visit = (node: TreeNode, depth: number) => {\n if (node.item.icon) {\n this.#depthsWithIcons.add(depth);\n }\n if (node.children) {\n for (const child of node.children) {\n visit(child, depth + 1);\n }\n }\n };\n if (this.root) {\n // Root itself is never rendered — start at -1 so its children are depth 0\n visit(this.root, -1);\n }\n }\n\n protected override renderNodeContent(node: TreeNode, depth: number): TemplateResult {\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n const icon = node.item.icon;\n const tooltip = node.item.tooltip;\n\n const caretAndLabel = html`\n <span class=\"tree-caret\">\n ${isBranch ? html`<ixfx-icon class=\"caret-icon\" name=\"chevron-down\" .rotate=${isExpanded ? nothing : `-90deg`}></ixfx-icon>` : ``}\n </span>\n ${icon ? html`<ixfx-icon class=\"tree-icon\" name=\"${icon}\"></ixfx-icon>` : nothing}\n <span class=\"tree-label\">\n ${node.item.label}\n ${tooltip ? html`<ixfx-tooltip class=\"tree-tooltip\" anchor=\"--tooltip-tree-${node.item.key}\" .value=${tooltip}></ixfx-tooltip>` : nothing}\n </span>\n `;\n\n if (this.interactionMode === `checked`) {\n const state = computeCheckboxState(node, this._selectedNodes);\n return html`${this.#renderCheckbox(node, depth, state)}${caretAndLabel}`;\n }\n\n return caretAndLabel;\n }\n\n #renderCheckbox(node: TreeNode, depth: number, state: TreeCheckboxState): TemplateResult {\n const onClick = (e: MouseEvent) => this._handleCheckboxClick(e, node, depth);\n\n if (this.checkboxRenderer) {\n const ariaChecked = state === `indeterminate` ? `mixed` : state === `checked` ? `true` : `false`;\n return html`\n <span\n class=\"tree-checkbox tree-checkbox-custom\"\n part=\"checkbox\"\n role=\"checkbox\"\n tabindex=\"-1\"\n aria-checked=${ariaChecked}\n aria-label=\"Select ${node.item.label}\"\n @click=${onClick}\n >${this.checkboxRenderer(state)}</span>`;\n }\n\n return html`\n <input\n type=\"checkbox\"\n class=\"tree-checkbox\"\n part=\"checkbox\"\n .checked=${state === `checked`}\n .indeterminate=${state === `indeterminate`}\n aria-label=\"Select ${node.item.label}\"\n @click=${onClick}\n />`;\n }\n\n protected override _renderNode(node: TreeNode, depth: number): TemplateResult {\n const selected = this._isSelected(node);\n const tickled = this._isFocused(node);\n const isBranch = node.item.isLeaf !== true;\n const isExpanded = this._isExpanded(node, depth);\n const isPending = this._pendingNode === node;\n const hasIconAtDepth = this.#depthsWithIcons.has(depth);\n const isLeaving = this._isLeaving(node);\n const isFiltered = this._isFilteredOut(node, depth);\n\n return html`\n <li\n class=\"item ${selected ? `selected` : ``} ${tickled ? `tickled` : ``} ${isBranch ? `branch` : `leaf`} ${hasIconAtDepth ? `has-icon-at-depth` : ``} ${isLeaving ? `leaving` : ``} ${isFiltered ? `filtered` : ``}\"\n data-key=${node.item.key}\n role=\"treeitem\"\n aria-selected=${selected}\n aria-expanded=${isBranch ? isExpanded : nothing}\n aria-hidden=${isLeaving ? `true` : nothing}\n aria-level=${depth + 1}\n style=${`--depth: ${depth}`}\n @click=${(e: MouseEvent) => this._handleItemClick(node, depth, e)}\n @pointerenter=${() => this.tickled.handlePointerEnter(node.item.key)}\n >\n ${this.renderNodeContent(node, depth)}\n ${isPending ? this.renderLoadingIndicator() : nothing}\n </li>\n `;\n }\n\n static override styles = [\n themeFallbacks,\n ...TreeBaseElement.styles,\n css`\n .tree-caret {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Deliberately narrower than the icon: Lucide chevrons fill only ~half\n their viewBox, so letting the glyph overflow a slim box closes the\n visual gap to the label without shifting the indent. */\n width: calc(var(--tree-caret-size) * 0.5);\n height: var(--tree-caret-size);\n flex-shrink: 0;\n margin-right: 1px;\n overflow: visible;\n }\n\n .caret-icon {\n width: var(--tree-caret-size);\n height: var(--tree-caret-size);\n color: var(--tree-muted-text);\n transition: transform var(--transition, 0.15s ease-out);\n }\n\n .item.selected .caret-icon {\n color: var(--accent-text);\n }\n\n .tree-icon {\n flex-shrink: 0;\n width: var(--icon-size, 1em);\n height: var(--icon-size, 1em);\n margin-right: var(--icon-spacing, 0px);\n }\n\n .item:not(.has-icon-at-depth) .tree-icon {\n display: none;\n }\n\n .item.has-icon-at-depth .tree-label {\n margin-left: var(--icon-size, 1em);\n }\n\n .tree-tooltip {\n position: absolute;\n anchor-name: --tooltip-tree;\n }\n\n .tree-checkbox {\n flex-shrink: 0;\n margin-right: var(--space-xs, 3px);\n cursor: pointer;\n accent-color: var(--accent);\n pointer-events: auto;\n }\n\n .tree-checkbox-custom {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n /* Reserves a click target even when the renderer returns empty content\n (e.g. the \"nothing when unchecked\" subtle style) — without an explicit\n size the empty span collapses to 0×0 and becomes unclickable. */\n width: var(--tree-checkbox-size, 14px);\n height: var(--tree-checkbox-size, 14px);\n }\n\n /* In checked mode the checkbox communicates selection state —\n suppress the row highlight so it doesn't double-signal */\n :host([interaction-mode=\"checked\"]) .item.selected {\n background: transparent;\n color: inherit;\n outline: none;\n }\n\n \n\n .tree-label {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n position: relative;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-tree-list': TreeListElement;\n }\n}\n\nexport interface TreeListElement {\n addEventListener: (<K extends keyof TreeBaseElementEventMap>(\n type: K,\n listener: (this: TreeListElement, event: TreeBaseElementEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n ) => void) & ((\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) => void);\n}\n","import type { TraversableTree } from '@ixfx/collections';\nimport type { TreeBaseElement } from './tree-base.js';\nimport type { TreeItem, TreeNode } from './types.js';\n\nexport type TreeControllerOptions<T> = {\n valueToItem: (value: T, node: TraversableTree<T>) => TreeItem;\n};\n\nexport class TreeController<T> {\n #root: TraversableTree<T>;\n #element: TreeBaseElement;\n #options: TreeControllerOptions<T>;\n\n #nodeToTree = new WeakMap<TreeNode, TraversableTree<T>>();\n #identityToTreeNode = new Map<unknown, TraversableTree<T>>();\n\n #connectSignal: AbortController | undefined;\n\n constructor(\n root: TraversableTree<T>,\n element: TreeBaseElement,\n options: TreeControllerOptions<T>,\n ) {\n this.#root = root;\n this.#element = element;\n this.#options = options;\n }\n\n connect() {\n this.disconnect();\n this.#connectSignal = new AbortController();\n const { signal } = this.#connectSignal;\n\n const rootValue = this.#root.getValue();\n const rootItem = this.#options.valueToItem(rootValue, this.#root);\n const rootChildren = this.#childrenOf(this.#root);\n\n this.#element.root = { item: rootItem, children: rootChildren };\n\n this.#element.addEventListener(`expand`, (e: Event) => {\n const { node } = (e as CustomEvent<{ node: TreeNode }>).detail;\n const treeNode = this.#nodeToTree.get(node);\n if (!treeNode)\n return;\n node.children = this.#childrenOf(treeNode);\n this.#element.requestUpdate();\n }, { signal });\n\n this.#element.addEventListener(`collapse`, (_e: Event) => {\n }, { signal });\n }\n\n disconnect() {\n this.#connectSignal?.abort();\n this.#connectSignal = undefined;\n }\n\n navigateToValue(predicate: (value: T) => boolean): boolean {\n const treePath = this.#findTreePath(this.#root, predicate);\n if (!treePath)\n return false;\n\n let currentColumn = this.#element.root?.children ?? [];\n const keys: string[] = [];\n\n for (let i = 1; i < treePath.length; i++) {\n const treeNode = treePath[i];\n const key = this.#options.valueToItem(treeNode.getValue(), treeNode).key;\n keys.push(key);\n\n if (i < treePath.length - 1) {\n const node = currentColumn.find(n => n.item.key === key);\n if (!node)\n return false;\n\n if (node.children === undefined) {\n const mapped = this.#nodeToTree.get(node);\n if (mapped)\n node.children = this.#childrenOf(mapped);\n }\n currentColumn = node.children ?? [];\n }\n }\n\n return this.#element.navigateTo(keys);\n }\n\n #childrenOf(treeNode: TraversableTree<T>): TreeNode[] {\n return Array.from(treeNode.children(), child => this.#toTreeNode(child));\n }\n\n #toTreeNode(treeNode: TraversableTree<T>): TreeNode {\n const value = treeNode.getValue();\n const childList = [...treeNode.children()];\n const userItem = this.#options.valueToItem(value, treeNode);\n\n const isLeaf = userItem.isLeaf ?? childList.length === 0;\n\n const treeNodeMap: TreeNode = {\n item: { ...userItem, isLeaf },\n };\n\n this.#nodeToTree.set(treeNodeMap, treeNode);\n this.#identityToTreeNode.set(treeNode.getIdentity(), treeNode);\n return treeNodeMap;\n }\n\n #findTreePath(\n node: TraversableTree<T>,\n predicate: (value: T) => boolean,\n ancestors: Array<TraversableTree<T>> = [],\n ): Array<TraversableTree<T>> | undefined {\n const path = [...ancestors, node];\n if (predicate(node.getValue()))\n return path;\n for (const child of node.children()) {\n const result = this.#findTreePath(child, predicate, path);\n if (result)\n return result;\n }\n return undefined;\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tree-component-BMpxpdTi.d.ts","names":[],"sources":["../src/common/tree-data-model.ts","../src/common/tree-component.ts"],"mappings":";;KAOK;EAAoB;EAAoB;;KACxC;EAAc;EAAc,MAAM;;KAClC,aAAa,kBAAkB;KAE/B,mBAAmB,OAAO;KAmEnB;;EAEV,MAAM;;;;;EAKN,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgCJ;;EAMC,YAAA,SAAS;;MAUjB,QAAQ;;;;;EAQZ,QAAQ,MAAM;;;;;;;;;EAkBR,YAAY,MAAM,UAAU,eAAe,QAAQ,cAAc,QAAQ;;;;;;EAyB/E,WAAW;;;;;EAaX,QAAQ,mBAAmB,MAAM,WAAW;;;;;EAU5C,WAAW,cAAc;;;;;EAWzB,WAAW,aAAa,OAAO,QAAQ,YAAY;;;;;EAanD,SAAS,aAAa,uBAAuB;;;;;;;EAgB7C,WAAW,UAAU;;;;;;;;KC/NX;;WAED,UAAU,YAAY;;WAEtB,UAAU,YAAY;;;;;;;KAQrB;WACD,MAAM;WACN;;;;;;KAOC;WACD,MAAM;WACN;;;;;;KAOC;WACD,MAAM;WACN;;;;;;;KAQC;WACD,MAAM;WACN;;;;;;KAOC;WACD,MAAM;WACN;;;;;;KAOC;WACD,MAAM;WACN;;KAIC,kBAAkB,YAAY;KAC9B,kBAAkB,YAAY;KAC9B,oBAAoB,YAAY;KAChC,qBAAqB,YAAY;KACjC,wBAAwB,YAAY;KACpC,kBAAkB,YAAY;KAC9B,oBAAoB,YAAY;UAM3B;EACf,UAAU;EACV,UAAU;EACV,YAAY;EACZ,cAAc;EACd,UAAU;EACV,YAAY;;;;;;;;;;;;;;;UAoBG,sBAAsB;;;;;;EAQrC,MAAM;;;;;;;EAQN,OAAO;;;;;;EAOP,cAAc;;;;;EAQd,cAAc;;;;;WAML,eAAe,YAAY;;;;;;EASpC,iBAAiB;;;;;;EASjB,iBAAiB;;;;;;EASjB,aAAa;;EAKb,SAAS,MAAM;;EAEf,WAAW,MAAM;;EAEjB;;;;;;EAMA;;EAEA;;;;;EAQA,aAAa;;;;;EAMb,iBAAiB,YAAY,MAAM;;;;;;EAOnC,YAAY;;EAGZ,aAAa,OAAO,SAAS;;;;;EAQ7B,gBAAgB;IAAgB,MAAM;IAAU;;;;;;;;;;;UAejC,uBAAuB;WAC7B,YAAY;WACZ,gBAAgB"}