@ixfx/components 0.10.1 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/bundle/index.d.ts +186 -20
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +1925 -127
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +1 -1
  6. package/dist/ac-token.js +2 -2
  7. package/dist/{colour-picker-R73i0QTP.js → colour-picker-WDrPuqoO.js} +2 -2
  8. package/dist/{colour-picker-R73i0QTP.js.map → colour-picker-WDrPuqoO.js.map} +1 -1
  9. package/dist/colour-picker.js +1 -1
  10. package/dist/crumbs.js +2 -2
  11. package/dist/{data-grid-BT1d_nlu.d.ts → data-grid-f9W2uzaR.d.ts} +3 -2
  12. package/dist/data-grid-f9W2uzaR.d.ts.map +1 -0
  13. package/dist/data-grid.d.ts +1 -1
  14. package/dist/data-grid.js +27 -9
  15. package/dist/data-grid.js.map +1 -1
  16. package/dist/defaults-kVl1t2tT.js +59 -0
  17. package/dist/defaults-kVl1t2tT.js.map +1 -0
  18. package/dist/{detail-list-BCaIN7nx.d.ts → detail-list-C3tozzBT.d.ts} +3 -3
  19. package/dist/{detail-list-BCaIN7nx.d.ts.map → detail-list-C3tozzBT.d.ts.map} +1 -1
  20. package/dist/detail-list.d.ts +2 -2
  21. package/dist/detail-list.js +3 -3
  22. package/dist/{grid-list-CiwlNE4c.d.ts → grid-list-CM1XhTaW.d.ts} +15 -2
  23. package/dist/{grid-list-CiwlNE4c.d.ts.map → grid-list-CM1XhTaW.d.ts.map} +1 -1
  24. package/dist/{grid-list-DLfw5HI4.js → grid-list-WE92nfX5.js} +103 -7
  25. package/dist/grid-list-WE92nfX5.js.map +1 -0
  26. package/dist/grid-list.d.ts +1 -1
  27. package/dist/grid-list.js +1 -1
  28. package/dist/handle-DAXs7kbJ.js +656 -0
  29. package/dist/handle-DAXs7kbJ.js.map +1 -0
  30. package/dist/{icon-BCJJYEpm.js → icon-1gpwtPx8.js} +10 -1
  31. package/dist/icon-1gpwtPx8.js.map +1 -0
  32. package/dist/icon-DR_3rSyZ.d.ts.map +1 -1
  33. package/dist/icons.d.ts +1 -1
  34. package/dist/icons.js +2 -2
  35. package/dist/{incr-search-C05WjbZh.js → incr-search-D91M4Ozq.js} +5 -4
  36. package/dist/incr-search-D91M4Ozq.js.map +1 -0
  37. package/dist/incr-search.d.ts +1 -1
  38. package/dist/incr-search.js +1 -1
  39. package/dist/{index-DPFrRhKL.d.ts → index-BXafRK-_.d.ts} +2 -1
  40. package/dist/index-BXafRK-_.d.ts.map +1 -0
  41. package/dist/index-C59-JEPl.d.ts.map +1 -1
  42. package/dist/index-garxxqgV.d.ts +38 -0
  43. package/dist/index-garxxqgV.d.ts.map +1 -0
  44. package/dist/index.d.ts +158 -8
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +1053 -18
  47. package/dist/index.js.map +1 -1
  48. package/dist/{menu-C8a-84S5.js → menu-B2Qv3Oiz.js} +6 -5
  49. package/dist/menu-B2Qv3Oiz.js.map +1 -0
  50. package/dist/{menu-item-DzizkMH-.js → menu-item-Woc8jJc1.js} +4 -4
  51. package/dist/menu-item-Woc8jJc1.js.map +1 -0
  52. package/dist/menu.js +2 -2
  53. package/dist/miller.d.ts +1 -1
  54. package/dist/miller.js +1 -1
  55. package/dist/narrowed-text.js +1 -1
  56. package/dist/{scroll-fade-CAs1EabA.js → scroll-fade-BrNUIYnm.js} +16 -3
  57. package/dist/scroll-fade-BrNUIYnm.js.map +1 -0
  58. package/dist/select-horiz.js +1 -1
  59. package/dist/{split-layout-3yBOEVZW.js → split-layout-BJEU1W0d.js} +2 -2
  60. package/dist/{split-layout-3yBOEVZW.js.map → split-layout-BJEU1W0d.js.map} +1 -1
  61. package/dist/split-layout.js +1 -1
  62. package/dist/tabs.js +1 -1
  63. package/dist/{timeline-CFlBFFGZ.js → timeline-BP1Ux2EV.js} +2 -2
  64. package/dist/{timeline-CFlBFFGZ.js.map → timeline-BP1Ux2EV.js.map} +1 -1
  65. package/dist/timeline.js +1 -1
  66. package/dist/titlebar.js +1 -1
  67. package/dist/{tree-BuzWn18_.js → tree-Bm2TzTfe.js} +233 -14
  68. package/dist/tree-Bm2TzTfe.js.map +1 -0
  69. package/dist/tree.d.ts +13 -1
  70. package/dist/tree.d.ts.map +1 -1
  71. package/dist/tree.js +1 -1
  72. package/dist/{vertical-list-BLvJ4-Zf.d.ts → vertical-list-DdaYcvHQ.d.ts} +2 -2
  73. package/dist/{vertical-list-BLvJ4-Zf.d.ts.map → vertical-list-DdaYcvHQ.d.ts.map} +1 -1
  74. package/dist/vertical-list.d.ts +1 -1
  75. package/dist/vertical-list.js +1 -1
  76. package/docs-user/README.md +1 -0
  77. package/docs-user/grid-list.md +15 -0
  78. package/docs-user/icons.md +24 -10
  79. package/docs-user/index.json +8 -3
  80. package/docs-user/llms.txt +2 -1
  81. package/docs-user/multicol-list.md +128 -0
  82. package/docs-user/tree.md +12 -0
  83. package/docs-user/vertical-list.md +65 -9
  84. package/llms.txt +2 -1
  85. package/package.json +1 -1
  86. package/dist/data-grid-BT1d_nlu.d.ts.map +0 -1
  87. package/dist/defaults-BJwDsMH4.js +0 -86
  88. package/dist/defaults-BJwDsMH4.js.map +0 -1
  89. package/dist/grid-list-DLfw5HI4.js.map +0 -1
  90. package/dist/handle-BPOxBOKf.js +0 -219
  91. package/dist/handle-BPOxBOKf.js.map +0 -1
  92. package/dist/icon-BCJJYEpm.js.map +0 -1
  93. package/dist/incr-search-C05WjbZh.js.map +0 -1
  94. package/dist/index-DPFrRhKL.d.ts.map +0 -1
  95. package/dist/index-DsjpDksO.d.ts +0 -47
  96. package/dist/index-DsjpDksO.d.ts.map +0 -1
  97. package/dist/menu-C8a-84S5.js.map +0 -1
  98. package/dist/menu-item-DzizkMH-.js.map +0 -1
  99. package/dist/scroll-fade-CAs1EabA.js.map +0 -1
  100. package/dist/tree-BuzWn18_.js.map +0 -1
package/bundle/index.js CHANGED
@@ -1545,6 +1545,15 @@ let IxfxIconElement = class IxfxIconElement extends i {
1545
1545
  if (this.rotate?.length > 0) this.style.setProperty(`--rotate`, this.rotate);
1546
1546
  else this.style.removeProperty(`--rotate`);
1547
1547
  }
1548
+ if (changed.has(`size`)) {
1549
+ if (this.size !== void 0) {
1550
+ this.style.width = `${this.size}px`;
1551
+ this.style.height = `${this.size}px`;
1552
+ } else {
1553
+ this.style.removeProperty(`width`);
1554
+ this.style.removeProperty(`height`);
1555
+ }
1556
+ }
1548
1557
  }
1549
1558
  static {
1550
1559
  this.styles = [themeFallbacks, i$3`
@@ -3019,10 +3028,10 @@ var ListSearchController = class {
3019
3028
  />
3020
3029
  ${hasQuery ? b`<span class="list-search-count">${this.#matches.length === 0 ? `0` : this.#matchIndex + 1} / ${this.#matches.length}</span>` : A}
3021
3030
  ${this.#mode === `navigate` && this.#matches.length > 1 ? b`
3022
- <button class="list-search-icon-btn" title="Previous match (↑)" @click=${() => this.prevMatch()}>‹</button>
3023
- <button class="list-search-icon-btn" title="Next match (↓)" @click=${() => this.nextMatch()}>›</button>
3031
+ <button class="list-search-icon-btn" title="Previous match (↑)" @click=${() => this.prevMatch()}><ixfx-icon name="chevron-left" size="14"></ixfx-icon></button>
3032
+ <button class="list-search-icon-btn" title="Next match (↓)" @click=${() => this.nextMatch()}><ixfx-icon name="chevron-right" size="14"></ixfx-icon></button>
3024
3033
  ` : A}
3025
- <button class="list-search-icon-btn" title="Close (Esc)" @click=${() => this.close()}>✕</button>
3034
+ <button class="list-search-icon-btn" title="Close (Esc)" @click=${() => this.close()}><ixfx-icon name="close" size="14"></ixfx-icon></button>
3026
3035
  </div>
3027
3036
  ${others.length > 0 || showSelectMatches ? b`
3028
3037
  <div class="list-search-switch">
@@ -3926,11 +3935,20 @@ AcTokenElement = __decorate([safeCustomElement(`ixfx-ac-token`)], AcTokenElement
3926
3935
  * - **flat** — a solid rounded capsule (bar) or dot (`spot`), filled with
3927
3936
  * `--ixfx-handle-color`.
3928
3937
  * - **dotted** — marks in the [Lucide *grip*](https://lucide.dev/icons/grip)
3929
- * arrangement: three in a row (`horizontal`), three in a column (`vertical`) or a
3930
- * 3×3 block (`spot`). Tinted by `--ixfx-handle-color`. Each mark's corner
3931
- * rounding is `--ixfx-handle-radius` (→ the theme `--radius-l`), so a flat,
3932
- * squared-off theme renders them as **squares** instead of circles.
3933
- * - **dimpled** — that same layout, but each bar mark is pressed in: a lighter
3938
+ * arrangement: one or more marks along the long axis (`horizontal`: a row,
3939
+ * `vertical`: a column), repeated in one or more rows/columns across the
3940
+ * bar's cross axis (or a 3×3 block for `spot`, unaffected by the row/column
3941
+ * / mark-count behaviour below). Tinted by `--ixfx-handle-color`. Each
3942
+ * mark's corner rounding is `--ixfx-handle-radius` (→ the theme
3943
+ * `--radius-l`), so a flat, squared-off theme renders them as **squares**
3944
+ * instead of circles. For `horizontal` / `vertical`, `--ixfx-handle-length`
3945
+ * decides how many marks (1-7) fit along the long axis — spaced by
3946
+ * `--ixfx-handle-dot-gap` — the same way `--ixfx-handle-thickness` decides
3947
+ * how many rows (or columns) of marks (1-7) fit across the cross axis —
3948
+ * spaced by `--ixfx-handle-dot-pitch`. Both the bar's rendered length and
3949
+ * its thickness snap to the nearest whole multiple of the relevant spacing
3950
+ * so marks never clip at the edges.
3951
+ * - **dimpled** — that same layout, but each mark is pressed in: a lighter
3934
3952
  * copy peeking out above-left and a darker copy below-right of the base mark.
3935
3953
  * - **grated** — fine 45° knurling: each ridge is a lit edge, the base colour,
3936
3954
  * then a shaded edge. `spot` is the same hatch on a square crop.
@@ -3961,14 +3979,26 @@ AcTokenElement = __decorate([safeCustomElement(`ixfx-ac-token`)], AcTokenElement
3961
3979
  * ## CSS variables (defaults shown; override on the element or any ancestor)
3962
3980
  * - `--ixfx-handle-color` `var(--surface-muted-text)` — `flat` / `dotted` fill
3963
3981
  * - `--ixfx-handle-color-active` `var(--accent)` — `flat` / `dotted` hover / focus
3964
- * - `--ixfx-handle-thickness` `6px` — cross-axis size of a bar
3965
- * - `--ixfx-handle-length` `44px` — long-axis size of a bar (`100%` to fill)
3982
+ * - `--ixfx-handle-thickness` `6px` — cross-axis size of a bar (dotted /
3983
+ * dimpled `horizontal` / `vertical` bars snap this to the nearest whole multiple
3984
+ * of `--ixfx-handle-dot-pitch` so their mark rows / columns fit exactly)
3985
+ * - `--ixfx-handle-length` `44px` — long-axis size of a bar (`100%` to
3986
+ * fill). For dotted / dimpled `horizontal` / `vertical` bars this also decides
3987
+ * how many marks (1-7) fit along the long axis — spaced by
3988
+ * `--ixfx-handle-dot-gap` — the same way `--ixfx-handle-thickness` decides row /
3989
+ * column count across the cross axis, and the bar's rendered length likewise
3990
+ * snaps to the nearest whole multiple of `--ixfx-handle-dot-gap` so marks
3991
+ * never clip at the edges.
3966
3992
  * - `--ixfx-handle-spot-size` `14px` — width = height of a `spot`
3967
3993
  * - `--ixfx-handle-radius` `var(--radius-l)` — `flat` capsule / dotted & dimpled mark rounding
3968
3994
  * - `--ixfx-handle-opacity` `0.55` — rest opacity
3969
3995
  * - `--ixfx-handle-opacity-active` `1`
3970
3996
  * - `--ixfx-handle-dot-size` `3px` — mark size (dotted / dimpled)
3971
- * - `--ixfx-handle-dot-gap` `length/4` (bar) · `spot/3` — mark centre-to-centre step
3997
+ * - `--ixfx-handle-dot-gap` `length/4` (bar) · `spot/3` — mark centre-to-centre
3998
+ * step along the long axis (dotted / dimpled `horizontal` / `vertical` bars fit up
3999
+ * to 7 marks, driven by `--ixfx-handle-length`; `spot` is a fixed 3×3 block)
4000
+ * - `--ixfx-handle-dot-pitch` `dot-size * 2` — row/column centre-to-centre step across
4001
+ * the cross axis (dotted / dimpled `horizontal` / `vertical` only; up to 7 rows/columns)
3972
4002
  * - `--ixfx-handle-tile` `5px` — knurl period (grated)
3973
4003
  * - `--ixfx-handle-highlight` `color-mix(currentColor 35%, #fff)` — lit deboss edge
3974
4004
  * - `--ixfx-handle-shadow` `color-mix(currentColor 60%, #000)` — shaded deboss edge
@@ -3989,6 +4019,28 @@ const handleStyles = i$3`
3989
4019
  /* Centre-to-centre step of the dotted / dimpled marks (a length). Defaults to
3990
4020
  a share of the long axis; a bar shows ~3 marks. */
3991
4021
  --_handle-gap: var(--ixfx-handle-dot-gap, calc(var(--_handle-length) / 4));
4022
+ /* Centre-to-centre step between rows (horizontal) / columns (vertical) of
4023
+ marks across the bar's cross axis. */
4024
+ --_handle-pitch: var(--ixfx-handle-dot-pitch, calc(var(--_handle-dot) * 2));
4025
+ /* How many whole pitch-steps fit across the thickness, rounded to the
4026
+ nearest step and clamped to 1-7 rows/columns. */
4027
+ --_handle-rows: clamp(1, round(nearest, calc(var(--_handle-thickness) / var(--_handle-pitch)), 1), 7);
4028
+ /* An even row/column count has no centre step, so the whole grid (the
4029
+ ::before mark and its box-shadow copies, spaced at whole --_handle-pitch
4030
+ steps from it) is nudged by half a pitch to stay centred and symmetric. */
4031
+ --_handle-row-shift: calc((1 - mod(var(--_handle-rows), 2)) * var(--_handle-pitch) / 2);
4032
+ /* The bar's cross-axis size snapped to exactly --_handle-rows steps of
4033
+ --_handle-pitch, so mark rows/columns fit without clipping. */
4034
+ --_handle-thickness-snapped: calc(var(--_handle-rows) * var(--_handle-pitch));
4035
+ /* How many whole gap-steps fit across the long axis, rounded to the
4036
+ nearest step and clamped to 1-7 marks. */
4037
+ --_handle-cols: clamp(1, round(nearest, calc(var(--_handle-length) / var(--_handle-gap)), 1), 7);
4038
+ /* An even mark count has no centre step, so the whole grid is nudged by
4039
+ half a gap along the long axis to stay centred and symmetric. */
4040
+ --_handle-col-shift: calc((1 - mod(var(--_handle-cols), 2)) * var(--_handle-gap) / 2);
4041
+ /* The bar's long-axis size snapped to exactly --_handle-cols steps of
4042
+ --_handle-gap, so marks fit without clipping. */
4043
+ --_handle-length-snapped: calc(var(--_handle-cols) * var(--_handle-gap));
3992
4044
  /* How far a dimpled mark's highlight / shadow copy is offset. */
3993
4045
  --_dimple-off: calc(var(--_handle-dot) * 0.15);
3994
4046
  /* The mark colour lightened / darkened for the two deboss edges. */
@@ -4038,14 +4090,32 @@ const handleStyles = i$3`
4038
4090
  border-radius: 50%;
4039
4091
  }
4040
4092
 
4041
- /* ── dotted / dimpled: 3 marks in a row / column (or 3×3 for spot), drawn as
4042
- one ::before mark whose border-radius follows the theme — round normally,
4043
- square in a flat / squared-off theme (--radius-l: 0). box-shadow paints
4044
- the rest of the marks. ─────────────────────────────────────────────── */
4093
+ /* ── dotted / dimpled: 3 marks in a row / column (or 3×3 for spot), repeated
4094
+ in --_handle-rows rows/columns across the cross axis for horizontal /
4095
+ vertical, drawn as one ::before mark whose border-radius follows the
4096
+ theme — round normally, square in a flat / squared-off theme
4097
+ (--radius-l: 0). box-shadow paints the rest of the marks. The extra
4098
+ rows/columns beyond --_handle-rows are still emitted (a fixed 7-row
4099
+ grid, CSS can't loop) but land outside the snapped, overflow: hidden
4100
+ bar, so they're clipped cleanly rather than shown or partially cut. ── */
4045
4101
  .ixfx-handle[data-handle='dotted'],
4046
4102
  .ixfx-handle[data-handle='dimpled'] {
4047
4103
  position: relative;
4048
4104
  }
4105
+ .ixfx-handle[data-handle='dotted']:not([data-shape='spot']),
4106
+ .ixfx-handle[data-handle='dimpled']:not([data-shape='spot']) {
4107
+ overflow: hidden;
4108
+ }
4109
+ .ixfx-handle[data-handle='dotted']:not([data-shape='vertical']):not([data-shape='spot']),
4110
+ .ixfx-handle[data-handle='dimpled']:not([data-shape='vertical']):not([data-shape='spot']) {
4111
+ width: var(--_handle-length-snapped);
4112
+ height: var(--_handle-thickness-snapped);
4113
+ }
4114
+ .ixfx-handle[data-handle='dotted'][data-shape='vertical'],
4115
+ .ixfx-handle[data-handle='dimpled'][data-shape='vertical'] {
4116
+ width: var(--_handle-thickness-snapped);
4117
+ height: var(--_handle-length-snapped);
4118
+ }
4049
4119
  .ixfx-handle[data-handle='dotted']::before,
4050
4120
  .ixfx-handle[data-handle='dimpled']::before {
4051
4121
  content: '';
@@ -4059,16 +4129,112 @@ const handleStyles = i$3`
4059
4129
  background: currentColor;
4060
4130
  }
4061
4131
 
4062
- /* dotted — the two other marks are plain copies along the axis. */
4063
- .ixfx-handle[data-handle='dotted']::before {
4132
+ /* dotted — the other marks are plain copies: 2 more along the long axis,
4133
+ repeated across up to 7 rows/columns on the cross axis (clipped to
4134
+ --_handle-rows by the snapped, overflow: hidden bar — see above). */
4135
+ .ixfx-handle[data-handle='dotted']:not([data-shape='vertical']):not([data-shape='spot'])::before {
4136
+ transform: translate(calc(-50% + var(--_handle-col-shift)), calc(-50% + var(--_handle-row-shift)));
4064
4137
  box-shadow:
4138
+ calc(-3 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4139
+ calc(-2 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4140
+ calc(-1 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4141
+ 0 calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4142
+ calc(var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4143
+ calc(2 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4144
+ calc(3 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4145
+ calc(-3 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4146
+ calc(-2 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4147
+ calc(-1 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4148
+ 0 calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4149
+ calc(var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4150
+ calc(2 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4151
+ calc(3 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4152
+ calc(-3 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4153
+ calc(-2 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4154
+ calc(-1 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4155
+ 0 calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4156
+ calc(var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4157
+ calc(2 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4158
+ calc(3 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4159
+ calc(-3 * var(--_handle-gap)) 0 0 0 currentColor,
4160
+ calc(-2 * var(--_handle-gap)) 0 0 0 currentColor,
4065
4161
  calc(-1 * var(--_handle-gap)) 0 0 0 currentColor,
4066
- var(--_handle-gap) 0 0 0 currentColor;
4162
+ calc(var(--_handle-gap)) 0 0 0 currentColor,
4163
+ calc(2 * var(--_handle-gap)) 0 0 0 currentColor,
4164
+ calc(3 * var(--_handle-gap)) 0 0 0 currentColor,
4165
+ calc(-3 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4166
+ calc(-2 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4167
+ calc(-1 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4168
+ 0 calc(var(--_handle-pitch)) 0 0 currentColor,
4169
+ calc(var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4170
+ calc(2 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4171
+ calc(3 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4172
+ calc(-3 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4173
+ calc(-2 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4174
+ calc(-1 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4175
+ 0 calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4176
+ calc(var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4177
+ calc(2 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4178
+ calc(3 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4179
+ calc(-3 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4180
+ calc(-2 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4181
+ calc(-1 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4182
+ 0 calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4183
+ calc(var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4184
+ calc(2 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4185
+ calc(3 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor;
4067
4186
  }
4068
4187
  .ixfx-handle[data-handle='dotted'][data-shape='vertical']::before {
4188
+ transform: translate(calc(-50% + var(--_handle-row-shift)), calc(-50% + var(--_handle-col-shift)));
4069
4189
  box-shadow:
4190
+ calc(-3 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4191
+ calc(-3 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4192
+ calc(-3 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4193
+ calc(-3 * var(--_handle-pitch)) 0 0 0 currentColor,
4194
+ calc(-3 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4195
+ calc(-3 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4196
+ calc(-3 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4197
+ calc(-2 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4198
+ calc(-2 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4199
+ calc(-2 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4200
+ calc(-2 * var(--_handle-pitch)) 0 0 0 currentColor,
4201
+ calc(-2 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4202
+ calc(-2 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4203
+ calc(-2 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4204
+ calc(-1 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4205
+ calc(-1 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4206
+ calc(-1 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4207
+ calc(-1 * var(--_handle-pitch)) 0 0 0 currentColor,
4208
+ calc(-1 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4209
+ calc(-1 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4210
+ calc(-1 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4211
+ 0 calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4212
+ 0 calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4070
4213
  0 calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4071
- 0 var(--_handle-gap) 0 0 currentColor;
4214
+ 0 calc(var(--_handle-gap)) 0 0 currentColor,
4215
+ 0 calc(2 * var(--_handle-gap)) 0 0 currentColor,
4216
+ 0 calc(3 * var(--_handle-gap)) 0 0 currentColor,
4217
+ calc(var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4218
+ calc(var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4219
+ calc(var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4220
+ calc(var(--_handle-pitch)) 0 0 0 currentColor,
4221
+ calc(var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4222
+ calc(var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4223
+ calc(var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4224
+ calc(2 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4225
+ calc(2 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4226
+ calc(2 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4227
+ calc(2 * var(--_handle-pitch)) 0 0 0 currentColor,
4228
+ calc(2 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4229
+ calc(2 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4230
+ calc(2 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4231
+ calc(3 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4232
+ calc(3 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4233
+ calc(3 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4234
+ calc(3 * var(--_handle-pitch)) 0 0 0 currentColor,
4235
+ calc(3 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4236
+ calc(3 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4237
+ calc(3 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor;
4072
4238
  }
4073
4239
  .ixfx-handle[data-handle='dotted'][data-shape='spot']::before,
4074
4240
  .ixfx-handle[data-handle='dimpled'][data-shape='spot']::before {
@@ -4083,29 +4249,309 @@ const handleStyles = i$3`
4083
4249
  var(--_handle-gap) var(--_handle-gap) 0 0 currentColor;
4084
4250
  }
4085
4251
 
4086
- /* dimpled — each bar mark also gets a lighter copy up-left and a darker copy
4087
- down-right (spot stays plain — the 3D is imperceptible at that size). */
4088
- .ixfx-handle[data-handle='dimpled']:not([data-shape='spot'])::before {
4252
+ /* dimpled — each mark also gets a lighter copy up-left and a darker copy
4253
+ down-right, repeated across up to 7 rows/columns on the cross axis
4254
+ (clipped to --_handle-rows — see above). Spot stays plain — the 3D is
4255
+ imperceptible at that size. */
4256
+ .ixfx-handle[data-handle='dimpled']:not([data-shape='vertical']):not([data-shape='spot'])::before {
4257
+ transform: translate(calc(-50% + var(--_handle-col-shift)), calc(-50% + var(--_handle-row-shift)));
4089
4258
  box-shadow:
4090
4259
  calc(-1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4091
4260
  var(--_dimple-off) var(--_dimple-off) 0 0 var(--_handle-lo),
4261
+ calc(-3 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4262
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4263
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4264
+ calc(-2 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4265
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4266
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4267
+ calc(-1 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4268
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4269
+ calc(-1 * var(--_handle-gap) + var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4270
+ 0 calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4271
+ calc(-1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4272
+ var(--_dimple-off) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4273
+ calc(var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4274
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4275
+ calc(var(--_handle-gap) + var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4276
+ calc(2 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4277
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4278
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4279
+ calc(3 * var(--_handle-gap)) calc(-3 * var(--_handle-pitch)) 0 0 currentColor,
4280
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4281
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4282
+ calc(-3 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4283
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4284
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4285
+ calc(-2 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4286
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4287
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4288
+ calc(-1 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4289
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4290
+ calc(-1 * var(--_handle-gap) + var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4291
+ 0 calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4292
+ calc(-1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4293
+ var(--_dimple-off) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4294
+ calc(var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4295
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4296
+ calc(var(--_handle-gap) + var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4297
+ calc(2 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4298
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4299
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4300
+ calc(3 * var(--_handle-gap)) calc(-2 * var(--_handle-pitch)) 0 0 currentColor,
4301
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4302
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4303
+ calc(-3 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4304
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4305
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4306
+ calc(-2 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4307
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4308
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4309
+ calc(-1 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4310
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4311
+ calc(-1 * var(--_handle-gap) + var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4312
+ 0 calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4313
+ calc(-1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4314
+ var(--_dimple-off) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4315
+ calc(var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4316
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4317
+ calc(var(--_handle-gap) + var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4318
+ calc(2 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4319
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4320
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4321
+ calc(3 * var(--_handle-gap)) calc(-1 * var(--_handle-pitch)) 0 0 currentColor,
4322
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4323
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4324
+ calc(-3 * var(--_handle-gap)) 0 0 0 currentColor,
4325
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4326
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4327
+ calc(-2 * var(--_handle-gap)) 0 0 0 currentColor,
4328
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4329
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4092
4330
  calc(-1 * var(--_handle-gap)) 0 0 0 currentColor,
4093
- calc(-1 * var(--_handle-gap) - var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4331
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4094
4332
  calc(-1 * var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4095
- var(--_handle-gap) 0 0 0 currentColor,
4096
- calc(var(--_handle-gap) - var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4097
- calc(var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo);
4333
+ calc(var(--_handle-gap)) 0 0 0 currentColor,
4334
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4335
+ calc(var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4336
+ calc(2 * var(--_handle-gap)) 0 0 0 currentColor,
4337
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4338
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4339
+ calc(3 * var(--_handle-gap)) 0 0 0 currentColor,
4340
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4341
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4342
+ calc(-3 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4343
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4344
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4345
+ calc(-2 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4346
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4347
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4348
+ calc(-1 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4349
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4350
+ calc(-1 * var(--_handle-gap) + var(--_dimple-off)) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4351
+ 0 calc(var(--_handle-pitch)) 0 0 currentColor,
4352
+ calc(-1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4353
+ var(--_dimple-off) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4354
+ calc(var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4355
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4356
+ calc(var(--_handle-gap) + var(--_dimple-off)) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4357
+ calc(2 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4358
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4359
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4360
+ calc(3 * var(--_handle-gap)) calc(var(--_handle-pitch)) 0 0 currentColor,
4361
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4362
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) calc(var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4363
+ calc(-3 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4364
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4365
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4366
+ calc(-2 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4367
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4368
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4369
+ calc(-1 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4370
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4371
+ calc(-1 * var(--_handle-gap) + var(--_dimple-off)) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4372
+ 0 calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4373
+ calc(-1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4374
+ var(--_dimple-off) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4375
+ calc(var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4376
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4377
+ calc(var(--_handle-gap) + var(--_dimple-off)) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4378
+ calc(2 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4379
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4380
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4381
+ calc(3 * var(--_handle-gap)) calc(2 * var(--_handle-pitch)) 0 0 currentColor,
4382
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4383
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) calc(2 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4384
+ calc(-3 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4385
+ calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4386
+ calc(-3 * var(--_handle-gap) + var(--_dimple-off)) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4387
+ calc(-2 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4388
+ calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4389
+ calc(-2 * var(--_handle-gap) + var(--_dimple-off)) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4390
+ calc(-1 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4391
+ calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4392
+ calc(-1 * var(--_handle-gap) + var(--_dimple-off)) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4393
+ 0 calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4394
+ calc(-1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4395
+ var(--_dimple-off) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4396
+ calc(var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4397
+ calc(var(--_handle-gap) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4398
+ calc(var(--_handle-gap) + var(--_dimple-off)) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4399
+ calc(2 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4400
+ calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4401
+ calc(2 * var(--_handle-gap) + var(--_dimple-off)) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4402
+ calc(3 * var(--_handle-gap)) calc(3 * var(--_handle-pitch)) 0 0 currentColor,
4403
+ calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4404
+ calc(3 * var(--_handle-gap) + var(--_dimple-off)) calc(3 * var(--_handle-pitch) + var(--_dimple-off)) 0 0 var(--_handle-lo);
4098
4405
  }
4099
4406
  .ixfx-handle[data-handle='dimpled'][data-shape='vertical']::before {
4407
+ transform: translate(calc(-50% + var(--_handle-row-shift)), calc(-50% + var(--_handle-col-shift)));
4100
4408
  box-shadow:
4101
4409
  calc(-1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4102
4410
  var(--_dimple-off) var(--_dimple-off) 0 0 var(--_handle-lo),
4411
+ calc(-3 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4412
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4413
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4414
+ calc(-3 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4415
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4416
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4417
+ calc(-3 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4418
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4419
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4420
+ calc(-3 * var(--_handle-pitch)) 0 0 0 currentColor,
4421
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4422
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4423
+ calc(-3 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4424
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4425
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4426
+ calc(-3 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4427
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4428
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4429
+ calc(-3 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4430
+ calc(-3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4431
+ calc(-3 * var(--_handle-pitch) + var(--_dimple-off)) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4432
+ calc(-2 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4433
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4434
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4435
+ calc(-2 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4436
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4437
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4438
+ calc(-2 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4439
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4440
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4441
+ calc(-2 * var(--_handle-pitch)) 0 0 0 currentColor,
4442
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4443
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4444
+ calc(-2 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4445
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4446
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4447
+ calc(-2 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4448
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4449
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4450
+ calc(-2 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4451
+ calc(-2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4452
+ calc(-2 * var(--_handle-pitch) + var(--_dimple-off)) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4453
+ calc(-1 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4454
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4455
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4456
+ calc(-1 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4457
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4458
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4459
+ calc(-1 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4460
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4461
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4462
+ calc(-1 * var(--_handle-pitch)) 0 0 0 currentColor,
4463
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4464
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4465
+ calc(-1 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4466
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4467
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4468
+ calc(-1 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4469
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4470
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4471
+ calc(-1 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4472
+ calc(-1 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4473
+ calc(-1 * var(--_handle-pitch) + var(--_dimple-off)) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4474
+ 0 calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4475
+ calc(-1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4476
+ var(--_dimple-off) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4477
+ 0 calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4478
+ calc(-1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4479
+ var(--_dimple-off) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4103
4480
  0 calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4104
- calc(-1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) - var(--_dimple-off)) 0 0 var(--_handle-hi),
4481
+ calc(-1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4105
4482
  var(--_dimple-off) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4106
- 0 var(--_handle-gap) 0 0 currentColor,
4107
- calc(-1 * var(--_dimple-off)) calc(var(--_handle-gap) - var(--_dimple-off)) 0 0 var(--_handle-hi),
4108
- var(--_dimple-off) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo);
4483
+ 0 calc(var(--_handle-gap)) 0 0 currentColor,
4484
+ calc(-1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4485
+ var(--_dimple-off) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4486
+ 0 calc(2 * var(--_handle-gap)) 0 0 currentColor,
4487
+ calc(-1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4488
+ var(--_dimple-off) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4489
+ 0 calc(3 * var(--_handle-gap)) 0 0 currentColor,
4490
+ calc(-1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4491
+ var(--_dimple-off) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4492
+ calc(var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4493
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4494
+ calc(var(--_handle-pitch) + var(--_dimple-off)) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4495
+ calc(var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4496
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4497
+ calc(var(--_handle-pitch) + var(--_dimple-off)) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4498
+ calc(var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4499
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4500
+ calc(var(--_handle-pitch) + var(--_dimple-off)) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4501
+ calc(var(--_handle-pitch)) 0 0 0 currentColor,
4502
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4503
+ calc(var(--_handle-pitch) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4504
+ calc(var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4505
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4506
+ calc(var(--_handle-pitch) + var(--_dimple-off)) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4507
+ calc(var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4508
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4509
+ calc(var(--_handle-pitch) + var(--_dimple-off)) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4510
+ calc(var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4511
+ calc(var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4512
+ calc(var(--_handle-pitch) + var(--_dimple-off)) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4513
+ calc(2 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4514
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4515
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4516
+ calc(2 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4517
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4518
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4519
+ calc(2 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4520
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4521
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4522
+ calc(2 * var(--_handle-pitch)) 0 0 0 currentColor,
4523
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4524
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4525
+ calc(2 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4526
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4527
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4528
+ calc(2 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4529
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4530
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4531
+ calc(2 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4532
+ calc(2 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4533
+ calc(2 * var(--_handle-pitch) + var(--_dimple-off)) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4534
+ calc(3 * var(--_handle-pitch)) calc(-3 * var(--_handle-gap)) 0 0 currentColor,
4535
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4536
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) calc(-3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4537
+ calc(3 * var(--_handle-pitch)) calc(-2 * var(--_handle-gap)) 0 0 currentColor,
4538
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4539
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) calc(-2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4540
+ calc(3 * var(--_handle-pitch)) calc(-1 * var(--_handle-gap)) 0 0 currentColor,
4541
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4542
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) calc(-1 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4543
+ calc(3 * var(--_handle-pitch)) 0 0 0 currentColor,
4544
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(-1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4545
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) var(--_dimple-off) 0 0 var(--_handle-lo),
4546
+ calc(3 * var(--_handle-pitch)) calc(var(--_handle-gap)) 0 0 currentColor,
4547
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4548
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) calc(var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4549
+ calc(3 * var(--_handle-pitch)) calc(2 * var(--_handle-gap)) 0 0 currentColor,
4550
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(2 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4551
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) calc(2 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo),
4552
+ calc(3 * var(--_handle-pitch)) calc(3 * var(--_handle-gap)) 0 0 currentColor,
4553
+ calc(3 * var(--_handle-pitch) + -1 * var(--_dimple-off)) calc(3 * var(--_handle-gap) + -1 * var(--_dimple-off)) 0 0 var(--_handle-hi),
4554
+ calc(3 * var(--_handle-pitch) + var(--_dimple-off)) calc(3 * var(--_handle-gap) + var(--_dimple-off)) 0 0 var(--_handle-lo);
4109
4555
  }
4110
4556
 
4111
4557
  /* ── grated: fine 45° knurling — each ridge is a lit edge, the base colour,
@@ -5021,71 +5467,41 @@ __decorate([state()], BottomDrawerElement.prototype, "_dragHeight", void 0);
5021
5467
  BottomDrawerElement = __decorate([safeCustomElement(`ixfx-bottom-drawer`)], BottomDrawerElement);
5022
5468
  //#endregion
5023
5469
  //#region src/icons/defaults.ts
5470
+ /** Chevron pointing down (Lucide `chevron-down`). Used for split-button dropdown toggle. */
5471
+ const ICON_CHEVRON_DOWN = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>`;
5024
5472
  /**
5025
- * Chevron pointing down. Used for split-button dropdown toggle.
5026
- * fill="currentColor" so it inherits CSS color.
5027
- */
5028
- const ICON_CHEVRON_DOWN = `<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"/></svg>`;
5029
- /**
5030
- * Caret pointing right. Used for tree-basic expand indicator as a CSS mask.
5031
- * fill="black" is correct for CSS mask-image use (shape only, color comes from background-color).
5032
- */
5033
- const ICON_CARET_RIGHT = `<svg viewBox="0 0 24 24" fill="black" xmlns="http://www.w3.org/2000/svg"><path d="M10 7l6 5-6 5V7z"/></svg>`;
5034
- /**
5035
- * Checkmark. Useful for menu-check-item or confirmation states.
5036
- * fill="currentColor" so it inherits CSS color.
5037
- */
5038
- const ICON_CHECK = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"/></svg>`;
5039
- /**
5040
- * Close / X icon. Useful for dialogs, notifications, dismissible elements.
5041
- * fill="currentColor" so it inherits CSS color.
5042
- */
5043
- const ICON_CLOSE = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>`;
5044
- /**
5045
- * Plus / add icon. Pairs with `close` for add/remove actions.
5046
- * fill="currentColor" so it inherits CSS color.
5047
- */
5048
- const ICON_ADD = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>`;
5049
- /**
5050
- * Error / warning icon. Useful for error notifications.
5051
- * fill="currentColor" so it inherits CSS color.
5052
- */
5053
- const ICON_ERROR = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>`;
5054
- /**
5055
- * Info icon. Useful for info notifications.
5056
- * fill="currentColor" so it inherits CSS color.
5057
- */
5058
- const ICON_INFO = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>`;
5059
- /**
5060
- * Warning icon. Useful for warning notifications.
5061
- * fill="currentColor" so it inherits CSS color.
5062
- */
5063
- const ICON_WARNING = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/></svg>`;
5064
- /**
5065
- * Chevron pointing right. Used for split-button switcher toggle.
5066
- * fill="currentColor" so it inherits CSS color.
5067
- */
5068
- const ICON_CHEVRON_RIGHT = `<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>`;
5069
- /**
5070
- * Folder with up arrow. Angled line style for navigating up one level.
5071
- * fill="currentColor" so it inherits CSS color.
5072
- */
5073
- const ICON_FOLDER_UP = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 4L4 12h5v8h6v-8h5L12 4z"/></svg>`;
5074
- /**
5075
- * Folder. Useful for file explorers and sidebars.
5076
- * fill="currentColor" so it inherits CSS color.
5473
+ * Chevron pointing right (Lucide `chevron-right`). Used for tree-basic expand
5474
+ * indicator as a CSS mask — shape only, color comes from background-color.
5077
5475
  */
5078
- const ICON_FOLDER = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 1.99-.9 1.99-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg>`;
5079
- /**
5080
- * Document / file page. Useful for file lists and document tabs.
5081
- * fill="currentColor" so it inherits CSS color.
5082
- */
5083
- const ICON_FILE = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/></svg>`;
5084
- /**
5085
- * Magnifying glass. Useful for search panels and inputs.
5086
- * fill="currentColor" so it inherits CSS color.
5087
- */
5088
- const ICON_SEARCH = `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>`;
5476
+ const ICON_CARET_RIGHT = `<svg viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><path d="m9 18 6-6-6-6"/></svg>`;
5477
+ /** Checkmark (Lucide `check`). Useful for menu-check-item or confirmation states. */
5478
+ const ICON_CHECK = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>`;
5479
+ /** Close / X icon (Lucide `x`). Useful for dialogs, notifications, dismissible elements. */
5480
+ const ICON_CLOSE = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`;
5481
+ /** Plus / add icon (Lucide `plus`). Pairs with `close` for add/remove actions. */
5482
+ const ICON_ADD = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14"/><path d="M12 5v14"/></svg>`;
5483
+ /** Error icon (Lucide `circle-alert`). Useful for error notifications. */
5484
+ const ICON_ERROR = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>`;
5485
+ /** Info icon (Lucide `info`). Useful for info notifications. */
5486
+ const ICON_INFO = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>`;
5487
+ /** Warning icon (Lucide `triangle-alert`). Useful for warning notifications. */
5488
+ const ICON_WARNING = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>`;
5489
+ /** Chevron pointing right (Lucide `chevron-right`). Used for split-button switcher toggle. */
5490
+ const ICON_CHEVRON_RIGHT = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg>`;
5491
+ /** Folder with up arrow (Lucide `folder-up`). Angled line style for navigating up one level. */
5492
+ const ICON_FOLDER_UP = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 9V5c0-1.1.9-2 2-2h3.93a2 2 0 0 1 1.66.9l.82 1.2a2 2 0 0 0 1.66.9H20a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-1"/><path d="M12 10v6"/><path d="m9 13 3-3 3 3"/></svg>`;
5493
+ /** Folder (Lucide `folder`). Useful for file explorers and sidebars. */
5494
+ const ICON_FOLDER = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/></svg>`;
5495
+ /** Document / file page (Lucide `file`). Useful for file lists and document tabs. */
5496
+ const ICON_FILE = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/></svg>`;
5497
+ /** Magnifying glass (Lucide `search`). Useful for search panels and inputs. */
5498
+ const ICON_SEARCH = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>`;
5499
+ /** Chevron pointing up (Lucide `chevron-up`). Sort/collapse direction indicators. */
5500
+ const ICON_CHEVRON_UP = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m18 15-6-6-6 6"/></svg>`;
5501
+ /** Chevron pointing left (Lucide `chevron-left`). Previous/back affordances. */
5502
+ const ICON_CHEVRON_LEFT = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg>`;
5503
+ /** Vertical ellipsis (Lucide `ellipsis-vertical`). Default glyph for an unlabelled menu trigger. */
5504
+ const ICON_ELLIPSIS_VERTICAL = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>`;
5089
5505
  function registerDefaults() {
5090
5506
  registerIcon(`chevron-down`, ICON_CHEVRON_DOWN);
5091
5507
  registerIcon(`chevron-right`, ICON_CHEVRON_RIGHT);
@@ -5100,6 +5516,9 @@ function registerDefaults() {
5100
5516
  registerIcon(`folder-up`, ICON_FOLDER_UP);
5101
5517
  registerIcon(`info`, ICON_INFO);
5102
5518
  registerIcon(`warning`, ICON_WARNING);
5519
+ registerIcon(`chevron-up`, ICON_CHEVRON_UP);
5520
+ registerIcon(`chevron-left`, ICON_CHEVRON_LEFT);
5521
+ registerIcon(`ellipsis-vertical`, ICON_ELLIPSIS_VERTICAL);
5103
5522
  }
5104
5523
  //#endregion
5105
5524
  //#region src/icons/index.ts
@@ -7375,7 +7794,7 @@ let MenuTrigger = class MenuTrigger extends i {
7375
7794
  constructor(..._args) {
7376
7795
  super(..._args);
7377
7796
  this.mode = `trigger`;
7378
- this.label = `⋮`;
7797
+ this.label = ``;
7379
7798
  this.iconName = ``;
7380
7799
  this.placement = `bottom-start`;
7381
7800
  this.tabStop = true;
@@ -7662,7 +8081,7 @@ let MenuTrigger = class MenuTrigger extends i {
7662
8081
  @click=${this._handleTriggerClick}
7663
8082
  @contextmenu=${this._handleContextMenu}
7664
8083
  >
7665
- ${showButton ? b`<button class="trigger-btn" part="base" tabindex=${this.tabStop ? `0` : `-1`}>${this.iconName ? b`<ixfx-icon name=${this.iconName}></ixfx-icon>` : this.label}</button>` : null}
8084
+ ${showButton ? b`<button class="trigger-btn" part="base" tabindex=${this.tabStop ? `0` : `-1`}>${this.iconName ? b`<ixfx-icon name=${this.iconName}></ixfx-icon>` : this.label || b`<ixfx-icon name="ellipsis-vertical"></ixfx-icon>`}</button>` : null}
7666
8085
  <slot name="trigger" @slotchange=${this._handleTriggerSlotChange}></slot>
7667
8086
  </div>
7668
8087
  <div
@@ -10204,8 +10623,21 @@ var TreeDataModel = class {
10204
10623
  * Apply the returned `.scroll-fade-x` / `.scroll-fade-y` class to
10205
10624
  * whichever element actually has `overflow` scrolling on that axis.
10206
10625
  *
10626
+ * NOTE: apply only one axis class per element. Each class sets
10627
+ * `mask-image`, so putting both on the same element makes the second
10628
+ * overwrite the first. An element that scrolls on both axes at once (e.g.
10629
+ * a grid viewport with `overflow: auto`) should use the vertical fade on
10630
+ * the viewport itself and handle the horizontal axis separately (e.g. a
10631
+ * synced header strip with its own `scroll-fade-x`).
10632
+ *
10207
10633
  * CSS variables:
10208
10634
  * - `--scroll-fade-width` (default `30px`): how far the fade extends from each edge.
10635
+ * - `--scroll-fade-strength` (default `1`): how completely content fades out
10636
+ * at the edge, `0`–`1`. `1` fades to fully transparent (current behaviour);
10637
+ * `0` disables the fade entirely. Dense layouts (e.g. a data grid) typically
10638
+ * want something like `0.7`–`0.8` so the edge row stays partly readable.
10639
+ * Deliberately *not* `@property`-registered, so it inherits normally and a
10640
+ * consumer override on the host reaches the shadow-DOM scroller.
10209
10641
  *
10210
10642
  * ```ts
10211
10643
  * import { scrollFadeStyles } from '../styles/scroll-fade.js';
@@ -10248,9 +10680,9 @@ function scrollFadeStyles(axis) {
10248
10680
  animation: ${r$2(keyframesName)};
10249
10681
  animation-timeline: ${r$2(timeline)};
10250
10682
  mask-image: linear-gradient(${r$2(gradientDirection)},
10251
- transparent,
10683
+ rgb(0 0 0 / calc(1 - var(--scroll-fade-strength, 1))),
10252
10684
  black var(${r$2(start)}, 0px) calc(100% - var(${r$2(end)}, 0px)),
10253
- transparent
10685
+ rgb(0 0 0 / calc(1 - var(--scroll-fade-strength, 1)))
10254
10686
  );
10255
10687
  }
10256
10688
  `;
@@ -13323,7 +13755,8 @@ let MenuCheckItem = class MenuCheckItem extends i {
13323
13755
  .check {
13324
13756
  width: 1em;
13325
13757
  margin-left: var(--space-xs);
13326
- font-size: var(--text-m);
13758
+ display: inline-flex;
13759
+ align-items: center;
13327
13760
  color: var(--accent);
13328
13761
  }
13329
13762
 
@@ -13366,7 +13799,7 @@ let MenuCheckItem = class MenuCheckItem extends i {
13366
13799
  role="menuitemcheckbox"
13367
13800
  aria-checked="${this.checked}"
13368
13801
  >
13369
- <span class="check">${this.checked ? `✓` : ``}</span>
13802
+ <span class="check">${this.checked ? b`<ixfx-icon name="check" size="14"></ixfx-icon>` : ``}</span>
13370
13803
  <span class="icon-slot">${resolvedIcon ? b`<ixfx-icon name="${resolvedIcon}"></ixfx-icon>` : null}</span>
13371
13804
  <span class="label">${this._resolvedLabel()}</span>
13372
13805
  ${shortcut ? b`<span class="shortcut">${shortcut}</span>` : null}
@@ -14489,6 +14922,8 @@ let DataGridElement = class DataGridElement extends i {
14489
14922
  tickledItemStyles,
14490
14923
  listItemFadeKeyframes,
14491
14924
  listSearchStyles,
14925
+ scrollFadeStyles(`x`),
14926
+ scrollFadeStyles(`y`),
14492
14927
  i$3`
14493
14928
  :host {
14494
14929
  --data-grid-row-height: 28px;
@@ -14505,6 +14940,11 @@ let DataGridElement = class DataGridElement extends i {
14505
14940
  autoSizeColumn(). Read back in JS (_columnResizeAnimationMs) to know
14506
14941
  when the animation has finished, so keep it a plain time value. */
14507
14942
  --data-grid-column-resize-duration: 180ms;
14943
+ /* Dense 28px rows read badly under the global 30px full-strength fade,
14944
+ so default to a shorter, shallower edge hint. Consumers can override
14945
+ --scroll-fade-width / --scroll-fade-strength per instance. */
14946
+ --scroll-fade-width: 20px;
14947
+ --scroll-fade-strength: 0.8;
14508
14948
  position: relative;
14509
14949
  display: block;
14510
14950
  overflow: hidden;
@@ -14524,6 +14964,9 @@ let DataGridElement = class DataGridElement extends i {
14524
14964
  }
14525
14965
  .header-scroll {
14526
14966
  display: flex; flex: 1; overflow: hidden;
14967
+ /* Horizontal edge fade comes from the shared .scroll-fade-x class
14968
+ (see ../styles/scroll-fade.ts). Its scrollLeft is synced from the
14969
+ viewport in _onScroll, which drives its own scroll-timeline. */
14527
14970
  }
14528
14971
  .header-cell {
14529
14972
  display: flex; align-items: center; gap: var(--space-xs);
@@ -14542,7 +14985,7 @@ let DataGridElement = class DataGridElement extends i {
14542
14985
  .header-cell.width-animating, .cell.width-animating { transition: none; }
14543
14986
  }
14544
14987
  .header-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
14545
- .sort-icon { font-size: 10px; opacity: 0.7; }
14988
+ .sort-icon { display: inline-flex; align-items: center; opacity: 0.7; }
14546
14989
  .resize-handle {
14547
14990
  position: absolute; right: -4px; top: 0; bottom: 0; width: 8px; cursor: col-resize; z-index: 1;
14548
14991
  display: flex; align-items: stretch; justify-content: center;
@@ -14553,10 +14996,16 @@ let DataGridElement = class DataGridElement extends i {
14553
14996
  }
14554
14997
  .resize-handle:hover::before { background: var(--split-gutter-hover-color, var(--surface-6)); }
14555
14998
  .resize-handle[data-active]::before { background: var(--split-gutter-active-color, var(--accent)); }
14556
- .reorder-handle { cursor: grab; opacity: 0.5; display: inline-flex; align-items: center; }
14999
+ .reorder-handle { cursor: grab; opacity: 0; display: inline-flex; align-items: center; transition: opacity var(--transition, 0.15s ease-out); }
15000
+ .header-cell:hover .reorder-handle, .header-cell:focus-within .reorder-handle, .header-cell[drag-source] .reorder-handle { opacity: var(--ixfx-handle-opacity, 0.5); }
14557
15001
  .reorder-handle .ixfx-handle { --ixfx-handle-length: 14px; --ixfx-handle-thickness: var(--data-grid-reorder-handle-width, 10px); --ixfx-handle-dot-size: 3px; }
14558
15002
  .flyout-trigger { flex-shrink: 0; width: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; border-left: var(--border-subtle); background: var(--data-grid-header-bg); }
14559
15003
  .viewport { flex: 1; overflow: auto; position: relative; }
15004
+ /* Vertical edge fade from the shared .scroll-fade-y class
15005
+ (see ../styles/scroll-fade.ts). The mask lives on the viewport —
15006
+ below the header bar — so the top fade never covers the column
15007
+ headers. Reach/strength tune via --scroll-fade-width /
15008
+ --scroll-fade-strength (defaults set on :host above). */
14560
15009
  .spacer { position: relative; }
14561
15010
  .row.item {
14562
15011
  position: absolute; left: 0; right: 0; display: flex; align-items: stretch;
@@ -15598,7 +16047,7 @@ let DataGridElement = class DataGridElement extends i {
15598
16047
  return b`
15599
16048
  <div class="grid">
15600
16049
  <div class="header-bar">
15601
- <div class="header-scroll">
16050
+ <div class="header-scroll scroll-fade-x">
15602
16051
  ${showCheckbox ? b`<div class="header-cell checkbox-col"></div>` : A}
15603
16052
  ${repeat(this._visibleColumns, (c) => c.key, (col, idx) => b`
15604
16053
  <div class="header-cell ${this._animatingColKeys.has(col.key) ? `width-animating` : ``}" style="width:${col.width ?? 150}px" ?drag-source=${this._drag?.active && this._drag.sourceCol.key === col.key}
@@ -15608,7 +16057,7 @@ let DataGridElement = class DataGridElement extends i {
15608
16057
  @pointerdown=${(e) => this._beginHeaderDrag(e, col, idx)}
15609
16058
  ><span class="ixfx-handle" data-handle="dotted" data-shape="vertical" part="reorder-handle"></span></span>` : A}
15610
16059
  <span class="header-label">${col.label}</span>
15611
- ${this.sortState?.key === col.key ? b`<span class="sort-icon">${this.sortState.direction === `asc` ? `▲` : `▼`}</span>` : A}
16060
+ ${this.sortState?.key === col.key ? b`<span class="sort-icon"><ixfx-icon name=${this.sortState.direction === `asc` ? `chevron-up` : `chevron-down`} size="12"></ixfx-icon></span>` : A}
15612
16061
  ${col.resizable !== false ? b`<span class="resize-handle" ?data-active=${this._resizingColKey === col.key} @pointerdown=${(e) => this._onResizePointerDown(e, col)} @click=${(e) => e.stopPropagation()} @dblclick=${(e) => {
15613
16062
  e.preventDefault();
15614
16063
  e.stopPropagation();
@@ -15665,14 +16114,14 @@ let DataGridElement = class DataGridElement extends i {
15665
16114
  </ixfx-menu-container>
15666
16115
  </ixfx-menu-trigger>`}
15667
16116
  </div>
15668
- <div class="viewport" @scroll=${this._onScroll}>
16117
+ <div class="viewport scroll-fade-y" @scroll=${this._onScroll}>
15669
16118
  <div class="spacer" style="height:${this._flat.length * rh}px; width:${this._colWidthSum}px">
15670
16119
  ${repeat(visibleFlat, (f) => f.key, (entry, i) => {
15671
16120
  const absIdx = startRow + i;
15672
16121
  if (entry.type === `group`) {
15673
16122
  const gKey = entry.key.replace(/^__group__/, ``);
15674
16123
  const collapsed = this._collapsedGroups.has(gKey);
15675
- return b`<div class="group-row ${collapsed ? `collapsed` : ``}" style="top:${absIdx * rh}px; height:${rh}px" @click=${() => this._toggleGroup(gKey)}><span class="caret">▼</span><span>${entry.label}</span><span class="count">(${entry.count})</span><span class="divider"></span></div>`;
16124
+ return b`<div class="group-row ${collapsed ? `collapsed` : ``}" style="top:${absIdx * rh}px; height:${rh}px" @click=${() => this._toggleGroup(gKey)}><span class="caret"><ixfx-icon name="chevron-down" size="12"></ixfx-icon></span><span>${entry.label}</span><span class="count">(${entry.count})</span><span class="divider"></span></div>`;
15676
16125
  }
15677
16126
  const row = entry.row;
15678
16127
  const absIdx2 = entry.idx;
@@ -23186,6 +23635,7 @@ let GridListElement = class GridListElement extends i {
23186
23635
  this.selectionMode = `single`;
23187
23636
  this.interactionMode = `standard`;
23188
23637
  this.disableHoverTickle = false;
23638
+ this.disableScrollHoverTickle = false;
23189
23639
  this.itemSize = 160;
23190
23640
  this.gap = 8;
23191
23641
  this.orientation = `grid`;
@@ -23242,6 +23692,9 @@ let GridListElement = class GridListElement extends i {
23242
23692
  itemWrap: this.#itemWrap,
23243
23693
  hoverDisabled: () => this.disableHoverTickle || this.#dragSelect.isDragging || this.#nativeDrag.isDragging
23244
23694
  });
23695
+ this.#scrollHoverSuppress = false;
23696
+ this.#lastPointerX = NaN;
23697
+ this.#lastPointerY = NaN;
23245
23698
  this.#marqueePreview = /* @__PURE__ */ new Set();
23246
23699
  this.#nativeDragging = false;
23247
23700
  this.#dragOriginKey = void 0;
@@ -23324,6 +23777,7 @@ let GridListElement = class GridListElement extends i {
23324
23777
  this.#selectedSnapshot = /* @__PURE__ */ new Set();
23325
23778
  this.#onScroll = (e) => {
23326
23779
  const el = e.target;
23780
+ this.#markScrollHoverSuppress();
23327
23781
  this.#cancelScrollRaf();
23328
23782
  this.#scrollRaf = requestAnimationFrame(() => {
23329
23783
  this.#scrollRaf = 0;
@@ -23333,6 +23787,30 @@ let GridListElement = class GridListElement extends i {
23333
23787
  });
23334
23788
  this.#scheduleSnap();
23335
23789
  };
23790
+ this.#onWheel = (e) => {
23791
+ if (this.orientation !== `row`) return;
23792
+ if (e.ctrlKey || e.metaKey) return;
23793
+ if (e.deltaY === 0) return;
23794
+ const vp = this.#viewportRef.value ?? e.currentTarget;
23795
+ if (!vp) return;
23796
+ if (vp.scrollWidth <= vp.clientWidth + 1) return;
23797
+ this.#markScrollHoverSuppress();
23798
+ vp.scrollLeft += e.deltaX + e.deltaY;
23799
+ e.preventDefault();
23800
+ };
23801
+ this.#onHostPointerMove = (e) => {
23802
+ const moved = !Number.isNaN(this.#lastPointerX) && (e.clientX !== this.#lastPointerX || e.clientY !== this.#lastPointerY);
23803
+ this.#lastPointerX = e.clientX;
23804
+ this.#lastPointerY = e.clientY;
23805
+ if (!moved || !this.#scrollHoverSuppress) return;
23806
+ this.#endScrollHoverSuppress();
23807
+ if (this.disableHoverTickle) return;
23808
+ const key = this.shadowRoot?.elementFromPoint?.(e.clientX, e.clientY)?.closest(`.cell`)?.getAttribute(`data-key`);
23809
+ if (key) this.tickled.handlePointerEnter(key);
23810
+ };
23811
+ this.#onHostPointerLeave = () => {
23812
+ this.#endScrollHoverSuppress();
23813
+ };
23336
23814
  this._onKeyDown = (e) => {
23337
23815
  if ((e.ctrlKey || e.metaKey) && e.key === `f`) return;
23338
23816
  if ((e.ctrlKey || e.metaKey) && e.key === `a`) {
@@ -23578,7 +24056,10 @@ let GridListElement = class GridListElement extends i {
23578
24056
  transition: background var(--transition), border-color var(--transition);
23579
24057
  }
23580
24058
  :host(:not([caption-style="separate"])) .cell.tickled,
23581
- :host(:not([caption-style="separate"]):not([disable-hover-tickle])) .cell:hover {
24059
+ /* [data-scroll-hover-suppress] is set while a scroll gesture moves
24060
+ cells beneath a stationary pointer (see disable-scroll-hover-tickle):
24061
+ the :hover highlight is gated so the visual cursor holds still too. */
24062
+ :host(:not([caption-style="separate"]):not([disable-hover-tickle]):not([data-scroll-hover-suppress])) .cell:hover {
23582
24063
  background: var(--item-bg-tickled);
23583
24064
  border: var(--item-border-tickled);
23584
24065
  }
@@ -23654,7 +24135,7 @@ let GridListElement = class GridListElement extends i {
23654
24135
  border: 1px solid transparent;
23655
24136
  }
23656
24137
  :host([caption-style="separate"]) .cell.tickled .thumb,
23657
- :host([caption-style="separate"]:not([disable-hover-tickle])) .cell:hover .thumb {
24138
+ :host([caption-style="separate"]:not([disable-hover-tickle]):not([data-scroll-hover-suppress])) .cell:hover .thumb {
23658
24139
  background: var(--grid-list-thumb-bg-tickled, var(--item-bg-tickled));
23659
24140
  border: var(--item-border-tickled);
23660
24141
  }
@@ -23775,6 +24256,16 @@ let GridListElement = class GridListElement extends i {
23775
24256
  */
23776
24257
  #sourceElement;
23777
24258
  #source;
24259
+ /**
24260
+ * True while cell `pointerenter` tickling is suppressed by an active or
24261
+ * just-finished scroll gesture (`disable-scroll-hover-tickle`). While set,
24262
+ * the host carries `[data-scroll-hover-suppress]`, which gates the CSS
24263
+ * `:hover` highlight so the visual cursor does not churn either.
24264
+ */
24265
+ #scrollHoverSuppress;
24266
+ /** Last pointer position seen over the host; real movement ends suppression. */
24267
+ #lastPointerX;
24268
+ #lastPointerY;
23778
24269
  /** Live drag-select preview: covered keys + the surface-relative rect. */
23779
24270
  #marqueePreview;
23780
24271
  #marqueeRect;
@@ -23944,6 +24435,8 @@ let GridListElement = class GridListElement extends i {
23944
24435
  [`caption-backdrop`, this.captionBackdrop]
23945
24436
  ]) if (!this.hasAttribute(attr)) this.setAttribute(attr, value);
23946
24437
  this.addEventListener(`keydown`, this._onKeyDown);
24438
+ this.addEventListener(`pointermove`, this.#onHostPointerMove, { passive: true });
24439
+ this.addEventListener(`pointerleave`, this.#onHostPointerLeave);
23947
24440
  this.#mutationObserver ??= new MutationObserver((records) => this.#onChildrenChanged(records));
23948
24441
  this.#mutationObserver.observe(this, {
23949
24442
  childList: true,
@@ -23957,6 +24450,9 @@ let GridListElement = class GridListElement extends i {
23957
24450
  super.disconnectedCallback();
23958
24451
  this.#stopActiveCaptionPan();
23959
24452
  this.removeEventListener(`keydown`, this._onKeyDown);
24453
+ this.removeEventListener(`pointermove`, this.#onHostPointerMove);
24454
+ this.removeEventListener(`pointerleave`, this.#onHostPointerLeave);
24455
+ this.#endScrollHoverSuppress();
23960
24456
  this.#resizeObserver?.disconnect();
23961
24457
  this.#resizeObserver = void 0;
23962
24458
  this.#mutationObserver?.disconnect();
@@ -24140,6 +24636,7 @@ let GridListElement = class GridListElement extends i {
24140
24636
  this.selection.clearAnchor();
24141
24637
  this.#syncAriaMultiselectable();
24142
24638
  }
24639
+ if (changed.has(`disableScrollHoverTickle`) && !this.disableScrollHoverTickle) this.#endScrollHoverSuppress();
24143
24640
  if (changed.has(`itemsDraggable`)) this.#nativeDrag.refreshDraggable();
24144
24641
  if (changed.has(`orientation`)) {
24145
24642
  const vp = this.#viewportRef.value;
@@ -24515,6 +25012,7 @@ let GridListElement = class GridListElement extends i {
24515
25012
  ${ref(this.#viewportRef)}
24516
25013
  data-input-mode=${this.tickled.inputMode}
24517
25014
  @scroll=${this.#onScroll}
25015
+ @wheel=${this.#onWheel}
24518
25016
  >
24519
25017
  <div class="spacer" style=${spacerStyle}>
24520
25018
  ${this.#source instanceof DataGridListSource ? this.#renderDataCells(win) : this.#renderElementCells(win)}
@@ -24558,7 +25056,7 @@ let GridListElement = class GridListElement extends i {
24558
25056
  ?data-marquee=${marquee}
24559
25057
  @click=${(e) => this.#onCellClick(e, key)}
24560
25058
  @dblclick=${() => this.#onCellActivate(key)}
24561
- @pointerenter=${() => this.tickled.handlePointerEnter(key)}
25059
+ @pointerenter=${() => this.#handleCellPointerEnter(key)}
24562
25060
  >
24563
25061
  <div class="content" part="content">${this.#source.renderCellContent(index)}</div>
24564
25062
  ${showCaption ? this.#renderCaption(caption, captionCss, tickled) : ``}
@@ -24642,7 +25140,7 @@ let GridListElement = class GridListElement extends i {
24642
25140
  ?data-marquee=${marquee}
24643
25141
  @click=${(e) => this.#onCellClick(e, key)}
24644
25142
  @dblclick=${() => this.#onCellActivate(key)}
24645
- @pointerenter=${() => this.tickled.handlePointerEnter(key)}
25143
+ @pointerenter=${() => this.#handleCellPointerEnter(key)}
24646
25144
  >
24647
25145
  <div class="thumb" part="thumb" style=${thumbStyle}>
24648
25146
  ${this.#source.renderCellContent(index)}
@@ -24652,6 +25150,48 @@ let GridListElement = class GridListElement extends i {
24652
25150
  `;
24653
25151
  }
24654
25152
  #onScroll;
25153
+ /**
25154
+ * Translate vertical wheel deltas into horizontal scroll when the list runs
25155
+ * in `row` orientation. Without this the default browser behaviour needs
25156
+ * Shift+wheel or a physical horizontal wheel — neither of which most users
25157
+ * reach for on a single-row strip.
25158
+ *
25159
+ * Only kicks in for a plain vertical wheel over a viewport that can actually
25160
+ * scroll horizontally; native horizontal deltas (trackpad, Shift+wheel) are
25161
+ * left to the browser when there is no vertical component.
25162
+ */
25163
+ #onWheel;
25164
+ /**
25165
+ * Cell `pointerenter` funnel. While a scroll gesture moves cells beneath a
25166
+ * stationary pointer (`disable-scroll-hover-tickle`), the freshly
25167
+ * virtualised cell's enter event is ignored so the cursor holds still.
25168
+ */
25169
+ #handleCellPointerEnter(key) {
25170
+ if (this.#scrollHoverSuppress) return;
25171
+ this.tickled.handlePointerEnter(key);
25172
+ }
25173
+ /** Open the scroll-hover suppression window (no-op unless opted in and not already open). */
25174
+ #markScrollHoverSuppress() {
25175
+ if (!this.disableScrollHoverTickle || this.#scrollHoverSuppress) return;
25176
+ this.#scrollHoverSuppress = true;
25177
+ this.toggleAttribute(`data-scroll-hover-suppress`, true);
25178
+ }
25179
+ #endScrollHoverSuppress() {
25180
+ if (!this.#scrollHoverSuppress) return;
25181
+ this.#scrollHoverSuppress = false;
25182
+ this.toggleAttribute(`data-scroll-hover-suppress`, false);
25183
+ }
25184
+ /**
25185
+ * A real pointer movement ends scroll-hover suppression. The first
25186
+ * `pointerenter` on a real move is swallowed by design (it can be
25187
+ * indistinguishable from a virtualisation enter), so the cell already under
25188
+ * the pointer is re-tickled here — otherwise the cursor would lag one cell
25189
+ * boundary behind the pointer. The very first tracked `pointermove` only
25190
+ * establishes the baseline; it cannot know the pointer moved.
25191
+ */
25192
+ #onHostPointerMove;
25193
+ /** The pointer leaving the list ends suppression, so re-entry hovers normally. */
25194
+ #onHostPointerLeave;
24655
25195
  #cancelScrollRaf() {
24656
25196
  if (this.#scrollRaf !== 0) {
24657
25197
  cancelAnimationFrame(this.#scrollRaf);
@@ -24735,6 +25275,11 @@ __decorate([property({
24735
25275
  attribute: `disable-hover-tickle`,
24736
25276
  reflect: true
24737
25277
  })], GridListElement.prototype, "disableHoverTickle", void 0);
25278
+ __decorate([property({
25279
+ type: Boolean,
25280
+ attribute: `disable-scroll-hover-tickle`,
25281
+ reflect: true
25282
+ })], GridListElement.prototype, "disableScrollHoverTickle", void 0);
24738
25283
  __decorate([property({
24739
25284
  type: Number,
24740
25285
  attribute: `item-size`
@@ -25554,6 +26099,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
25554
26099
  this.itemDnd = `none`;
25555
26100
  this.dndExpandHoverMs = 500;
25556
26101
  this.reorderable = true;
26102
+ this.stickyHeaders = true;
25557
26103
  this.applyInternalDrop = true;
25558
26104
  this._expandedKeys = /* @__PURE__ */ new Set();
25559
26105
  this.tickled = new TickledController(this, {
@@ -25586,6 +26132,18 @@ let TreeBaseElement = class TreeBaseElement extends i {
25586
26132
  this.#onContainerScroll = () => {
25587
26133
  this.#rowsCache = void 0;
25588
26134
  };
26135
+ this.#onStickyScroll = () => {
26136
+ if (this.#stickyRaf !== 0) return;
26137
+ this.#stickyRaf = requestAnimationFrame(() => {
26138
+ this.#stickyRaf = 0;
26139
+ this.#updateStickyHeaders();
26140
+ });
26141
+ };
26142
+ this._stickyKeys = [];
26143
+ this.#stickyEntries = /* @__PURE__ */ new Map();
26144
+ this.#stickyDirty = true;
26145
+ this.#stickyRaf = 0;
26146
+ this.#stickyScrollBound = false;
25589
26147
  this.#onKeyDown = (event) => {
25590
26148
  if (this.search.isOpen) return;
25591
26149
  const nodes = this.#getAllNodes();
@@ -25689,7 +26247,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
25689
26247
  }
25690
26248
  };
25691
26249
  this.#onDblClick = (e) => {
25692
- const li = e.target.closest(`li`);
26250
+ const li = e.target.closest(`ul.tree-list li`);
25693
26251
  if (!li) return;
25694
26252
  const key = li.dataset.key;
25695
26253
  if (!key) return;
@@ -25751,6 +26309,157 @@ let TreeBaseElement = class TreeBaseElement extends i {
25751
26309
  /** Per-drag cache of measured rows; invalidated on scroll / update. */
25752
26310
  #rowsCache;
25753
26311
  #onContainerScroll;
26312
+ /** Bind the sticky scroll listener once the container exists; unbind on opt-out. */
26313
+ #syncStickyScroll() {
26314
+ const container = this.#container();
26315
+ if (this.stickyHeaders && container) {
26316
+ if (!this.#stickyScrollBound || this.#stickyScrollContainer !== container) {
26317
+ this.#stickyScrollContainer?.removeEventListener(`scroll`, this.#onStickyScroll);
26318
+ container.addEventListener(`scroll`, this.#onStickyScroll, { passive: true });
26319
+ this.#stickyScrollContainer = container;
26320
+ this.#stickyScrollBound = true;
26321
+ }
26322
+ } else if (this.#stickyScrollBound) {
26323
+ this.#stickyScrollContainer?.removeEventListener(`scroll`, this.#onStickyScroll);
26324
+ this.#stickyScrollContainer = void 0;
26325
+ this.#stickyScrollBound = false;
26326
+ }
26327
+ }
26328
+ #onStickyScroll;
26329
+ /** Real (non-sticky) row element for `key`, or `null`. */
26330
+ #stickyRowEl(key) {
26331
+ return this.renderRoot.querySelector(`ul.tree-list li[data-key="${CSS.escape(key)}"]`);
26332
+ }
26333
+ /**
26334
+ * Recompute which ancestors stick to the top: the ancestors of the first
26335
+ * row whose bottom clears the container top, minus any ancestor that is
26336
+ * itself still visible below the overlay. Synchronous — reads current
26337
+ * geometry, renders nothing, expands nothing.
26338
+ */
26339
+ #updateStickyHeaders() {
26340
+ this.#stickyDirty = false;
26341
+ const empty = /* @__PURE__ */ new Map();
26342
+ if (!this.stickyHeaders || !this.root) {
26343
+ this.#setStickyKeys([], empty);
26344
+ return;
26345
+ }
26346
+ const container = this.#container();
26347
+ if (!container) {
26348
+ this.#setStickyKeys([], empty);
26349
+ return;
26350
+ }
26351
+ const nodes = this.#getAllNodes();
26352
+ if (nodes.length === 0) {
26353
+ this.#setStickyKeys([], empty);
26354
+ return;
26355
+ }
26356
+ const parent = /* @__PURE__ */ new Map();
26357
+ const walk = (n) => {
26358
+ for (const child of n.children ?? []) {
26359
+ parent.set(child.item.key, n.item.key);
26360
+ walk(child);
26361
+ }
26362
+ };
26363
+ walk(this.root);
26364
+ const containerTop = container.getBoundingClientRect().top;
26365
+ const visibleThreshold = containerTop + (this.renderRoot.querySelector(`.sticky-headers`)?.getBoundingClientRect().height ?? 0);
26366
+ let topKey;
26367
+ for (const { node } of nodes) {
26368
+ const li = this.#stickyRowEl(node.item.key);
26369
+ if (!li || li.classList.contains(`leaving`)) continue;
26370
+ if (li.getBoundingClientRect().bottom > containerTop) {
26371
+ topKey = node.item.key;
26372
+ break;
26373
+ }
26374
+ }
26375
+ if (topKey === void 0) {
26376
+ this.#setStickyKeys([], empty);
26377
+ return;
26378
+ }
26379
+ const rootKey = this.root.item.key;
26380
+ const chain = [];
26381
+ let cursor = parent.get(topKey);
26382
+ while (cursor !== void 0 && cursor !== rootKey) {
26383
+ chain.unshift(cursor);
26384
+ cursor = parent.get(cursor);
26385
+ }
26386
+ const byKey = new Map(nodes.map((entry) => [entry.node.item.key, entry]));
26387
+ const entries = /* @__PURE__ */ new Map();
26388
+ const stuck = [];
26389
+ for (const key of chain) {
26390
+ const li = this.#stickyRowEl(key);
26391
+ if (!li || li.getBoundingClientRect().bottom > visibleThreshold) continue;
26392
+ const entry = byKey.get(key);
26393
+ if (!entry) continue;
26394
+ stuck.push(key);
26395
+ entries.set(key, entry);
26396
+ }
26397
+ this.#setStickyKeys(stuck, entries);
26398
+ }
26399
+ #setStickyKeys(keys, entries) {
26400
+ const prev = this._stickyKeys;
26401
+ if (prev.length === keys.length && prev.every((key, i) => key === keys[i])) return;
26402
+ this.#stickyEntries = entries;
26403
+ this._stickyKeys = keys;
26404
+ }
26405
+ #renderStickyHeaders() {
26406
+ if (!this.stickyHeaders || this._stickyKeys.length === 0) return A;
26407
+ return b`
26408
+ <div class="sticky-headers" part="sticky-headers">
26409
+ ${this._stickyKeys.map((key) => {
26410
+ const entry = this.#stickyEntries.get(key);
26411
+ if (!entry) return A;
26412
+ return this.#renderStickyHeader(entry.node, entry.depth);
26413
+ })}
26414
+ </div>
26415
+ `;
26416
+ }
26417
+ #renderStickyHeader(node, depth) {
26418
+ const selected = this._isSelected(node);
26419
+ const isBranch = node.item.isLeaf !== true;
26420
+ return b`
26421
+ <div
26422
+ class="item ${isBranch ? `branch` : `leaf`} sticky-header${selected ? ` selected` : ``}"
26423
+ part="sticky-header"
26424
+ role="button"
26425
+ tabindex="0"
26426
+ aria-label="Go to ${node.item.label}"
26427
+ data-key=${node.item.key}
26428
+ style=${`--depth: ${depth}`}
26429
+ @click=${(e) => this.#onStickyClick(e, node)}
26430
+ @keydown=${(e) => {
26431
+ if (e.key === `Enter` || e.key === ` `) {
26432
+ e.preventDefault();
26433
+ this.#activateSticky(node);
26434
+ }
26435
+ }}
26436
+ >${this.renderNodeContent(node, depth)}</div>
26437
+ `;
26438
+ }
26439
+ #onStickyClick(event, node) {
26440
+ if (this.#drop?.isDragging || this.#nativeDrag?.isDragging) return;
26441
+ if (node.item.isLeaf !== true && event.target instanceof Element && event.target.closest(`.tree-caret`)) {
26442
+ const depth = this.#stickyEntries.get(node.item.key)?.depth ?? 0;
26443
+ this.#toggleExpand(node, depth);
26444
+ this.#stickyDirty = true;
26445
+ this.requestUpdate();
26446
+ return;
26447
+ }
26448
+ this.#activateSticky(node);
26449
+ }
26450
+ #activateSticky(node) {
26451
+ if (this.#canSelect(node)) this.select(node);
26452
+ this.#scrollKeyIntoView(node.item.key);
26453
+ this.#stickyDirty = true;
26454
+ this.requestUpdate();
26455
+ }
26456
+ /** Visible `{ node, depth }` entries for `_stickyKeys` — depths drive the indent. */
26457
+ #stickyEntries;
26458
+ /** Set when expansion / data / filter changes may have altered the sticky set. Consumed in `updated()`. */
26459
+ #stickyDirty;
26460
+ #stickyRaf;
26461
+ #stickyScrollContainer;
26462
+ #stickyScrollBound;
25754
26463
  get nativeDrag() {
25755
26464
  return this.#nativeDrag;
25756
26465
  }
@@ -25774,6 +26483,8 @@ let TreeBaseElement = class TreeBaseElement extends i {
25774
26483
  willUpdate(changedProps) {
25775
26484
  super.willUpdate(changedProps);
25776
26485
  this.#diffVisibleNodes();
26486
+ if (changedProps.has(`root`) || changedProps.has(`model`) || changedProps.has(`filterPredicate`) || changedProps.has(`stickyHeaders`)) this.#stickyDirty = true;
26487
+ if (this.#stickyDirty) this.#updateStickyHeaders();
25777
26488
  }
25778
26489
  #diffVisibleNodes() {
25779
26490
  const nodes = this.root ? this.#getAllNodes() : [];
@@ -25873,6 +26584,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
25873
26584
  }
25874
26585
  updated(changedProps) {
25875
26586
  this.#rowsCache = void 0;
26587
+ this.#syncStickyScroll();
25876
26588
  if (changedProps.has(`root`) && this.root) {
25877
26589
  this.#abortPending();
25878
26590
  this._expandedKeys.clear();
@@ -25896,6 +26608,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
25896
26608
  } else if (event.type === `invalidate`) {
25897
26609
  if (this._expandedKeys.has(event.key)) {
25898
26610
  this._expandedKeys.delete(event.key);
26611
+ this.#stickyDirty = true;
25899
26612
  this.requestUpdate();
25900
26613
  }
25901
26614
  }
@@ -25938,7 +26651,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
25938
26651
  isEnabled: () => this.itemDnd !== `none` && this.#anyRowDraggable(),
25939
26652
  resolveEventToKey: (target) => {
25940
26653
  if (!(target instanceof Element)) return void 0;
25941
- return target.closest(`li[data-key]`)?.getAttribute(`data-key`) ?? void 0;
26654
+ return target.closest(`ul.tree-list li[data-key]`)?.getAttribute(`data-key`) ?? void 0;
25942
26655
  },
25943
26656
  prepareSelection: (originKey) => {
25944
26657
  const allNodes = this.#getAllNodes();
@@ -25953,7 +26666,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
25953
26666
  key: n.node.item.key,
25954
26667
  index: i,
25955
26668
  item: n.node,
25956
- element: this.shadowRoot?.querySelector(`li[data-key="${CSS.escape(n.node.item.key)}"]`) ?? void 0
26669
+ element: this.shadowRoot?.querySelector(`ul.tree-list li[data-key="${CSS.escape(n.node.item.key)}"]`) ?? void 0
25957
26670
  }));
25958
26671
  const origin = selected.find((e) => e.key === originKey) ?? {
25959
26672
  key: originKey,
@@ -26108,7 +26821,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
26108
26821
  if (this.#rowsCache) return this.#rowsCache;
26109
26822
  const rows = [];
26110
26823
  for (const { node, depth } of this.#getAllNodes()) {
26111
- const li = this.shadowRoot?.querySelector(`li[data-key="${CSS.escape(node.item.key)}"]`);
26824
+ const li = this.shadowRoot?.querySelector(`ul.tree-list li[data-key="${CSS.escape(node.item.key)}"]`);
26112
26825
  if (li) rows.push({
26113
26826
  key: node.item.key,
26114
26827
  node,
@@ -26230,6 +26943,15 @@ let TreeBaseElement = class TreeBaseElement extends i {
26230
26943
  this.#postDragSuppressTimer = void 0;
26231
26944
  }
26232
26945
  this.#container()?.removeEventListener(`scroll`, this.#onContainerScroll);
26946
+ if (this.#stickyScrollBound) {
26947
+ this.#stickyScrollContainer?.removeEventListener(`scroll`, this.#onStickyScroll);
26948
+ this.#stickyScrollContainer = void 0;
26949
+ this.#stickyScrollBound = false;
26950
+ }
26951
+ if (this.#stickyRaf !== 0) {
26952
+ cancelAnimationFrame(this.#stickyRaf);
26953
+ this.#stickyRaf = 0;
26954
+ }
26233
26955
  treeDragUnregister(this.#dragSourceId);
26234
26956
  if (this.#ownedRegistry) {
26235
26957
  this.#ownedRegistry.unregister(`select-all`);
@@ -26318,6 +27040,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
26318
27040
  }
26319
27041
  currentNode = found;
26320
27042
  }
27043
+ this.#stickyDirty = true;
26321
27044
  this.requestUpdate();
26322
27045
  this.#scrollKeyIntoView(keys.at(-1));
26323
27046
  return true;
@@ -26338,6 +27061,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
26338
27061
  this._expandedKeys.add(path[i]);
26339
27062
  }
26340
27063
  this.tickled.setTickled(key);
27064
+ this.#stickyDirty = true;
26341
27065
  this.requestUpdate();
26342
27066
  this.updateComplete.then(() => this.#scrollKeyIntoView(key));
26343
27067
  return true;
@@ -26573,7 +27297,9 @@ let TreeBaseElement = class TreeBaseElement extends i {
26573
27297
  this.requestUpdate();
26574
27298
  }
26575
27299
  #toggleExpand(node, depth) {
26576
- if (this._expandedKeys.has(node.item.key)) {
27300
+ const isExpanded = this._expandedKeys.has(node.item.key);
27301
+ this.#stickyDirty = true;
27302
+ if (isExpanded) {
26577
27303
  this._expandedKeys.delete(node.item.key);
26578
27304
  this.dispatchEvent(new CustomEvent(`collapse`, {
26579
27305
  detail: {
@@ -26666,6 +27392,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
26666
27392
  node.children = children;
26667
27393
  this.#applyExclusivity(node.item.key);
26668
27394
  this._expandedKeys.add(node.item.key);
27395
+ this.#stickyDirty = true;
26669
27396
  this.#pendingNode = void 0;
26670
27397
  this.#pendingController = void 0;
26671
27398
  this.dispatchEvent(new CustomEvent(`expand`, {
@@ -26706,14 +27433,16 @@ let TreeBaseElement = class TreeBaseElement extends i {
26706
27433
  }
26707
27434
  #scrollKeyIntoView(key) {
26708
27435
  requestAnimationFrame(() => {
26709
- const el = this.shadowRoot?.querySelector(`[data-key="${CSS.escape(key)}"]`);
26710
- if (!el) return;
27436
+ const container = this.#container();
27437
+ const el = this.shadowRoot?.querySelector(`ul.tree-list [data-key="${CSS.escape(key)}"]`);
27438
+ if (!el || !container) return;
26711
27439
  const elRect = el.getBoundingClientRect();
26712
- const hostRect = this.getBoundingClientRect();
26713
- const relativeTop = elRect.top - hostRect.top;
27440
+ const containerRect = container.getBoundingClientRect();
27441
+ const relativeTop = elRect.top - containerRect.top;
26714
27442
  const relativeBottom = relativeTop + elRect.height;
26715
- if (relativeTop < 0) this.scrollTop += relativeTop;
26716
- else if (relativeBottom > this.clientHeight) this.scrollTop += relativeBottom - this.clientHeight;
27443
+ const overlayHeight = this.renderRoot.querySelector(`.sticky-headers`)?.getBoundingClientRect().height ?? 0;
27444
+ if (relativeTop < overlayHeight) container.scrollTop += relativeTop - overlayHeight;
27445
+ else if (relativeBottom > container.clientHeight) container.scrollTop += relativeBottom - container.clientHeight;
26717
27446
  });
26718
27447
  }
26719
27448
  #abortPending() {
@@ -26802,7 +27531,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
26802
27531
  #scrollTickledIntoView() {
26803
27532
  const tickledKey = this.tickled.tickledId;
26804
27533
  if (tickledKey === void 0) return;
26805
- (this.shadowRoot?.querySelector(`[data-key="${tickledKey}"]`))?.scrollIntoView({
27534
+ (this.shadowRoot?.querySelector(`ul.tree-list [data-key="${CSS.escape(tickledKey)}"]`))?.scrollIntoView({
26806
27535
  block: `nearest`,
26807
27536
  behavior: `smooth`
26808
27537
  });
@@ -26822,6 +27551,7 @@ let TreeBaseElement = class TreeBaseElement extends i {
26822
27551
  @pointerleave=${(e) => this.tickled.handlePointerLeave(e)}
26823
27552
  tabindex="0"
26824
27553
  >
27554
+ ${this.#renderStickyHeaders()}
26825
27555
  ${this.root ? this.#renderNodes(nodes) : A}
26826
27556
  </div>
26827
27557
  ${this.search.renderField()}
@@ -26920,6 +27650,9 @@ let TreeBaseElement = class TreeBaseElement extends i {
26920
27650
  --tree-drop-nub-size: 5px;
26921
27651
  --tree-drop-into-outline: 2px solid var(--accent);
26922
27652
  --tree-drop-into-bg: color-mix(in srgb, var(--accent) 14%, transparent);
27653
+ --tree-sticky-bg: var(--tree-bg);
27654
+ --tree-sticky-border: var(--border, transparent);
27655
+ --tree-sticky-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
26923
27656
 
26924
27657
  position: relative;
26925
27658
  display: block;
@@ -26946,6 +27679,28 @@ let TreeBaseElement = class TreeBaseElement extends i {
26946
27679
  padding: var(--space-xs);
26947
27680
  }
26948
27681
 
27682
+ /* VS Code-style sticky headers: ancestors of the top-visible row, pinned
27683
+ to the top of the scroll container. Rows reuse the item class for
27684
+ identical metrics; the overlay itself is opaque so rows slide under it. */
27685
+ .sticky-headers {
27686
+ position: sticky;
27687
+ top: 0;
27688
+ z-index: 5;
27689
+ background: var(--tree-sticky-bg);
27690
+ border-bottom: 1px solid var(--tree-sticky-border);
27691
+ box-shadow: var(--tree-sticky-shadow);
27692
+ }
27693
+
27694
+ .sticky-header {
27695
+ margin: 0;
27696
+ border-radius: 0;
27697
+ }
27698
+
27699
+ .sticky-header:focus-visible {
27700
+ outline: 2px solid var(--accent);
27701
+ outline-offset: -2px;
27702
+ }
27703
+
26949
27704
  .item {
26950
27705
  position: relative; /* anchor for the .drop-line before/after indicator */
26951
27706
  display: flex;
@@ -27119,6 +27874,14 @@ __decorate([property({
27119
27874
  toAttribute: (value) => value ? null : `false`
27120
27875
  }
27121
27876
  })], TreeBaseElement.prototype, "reorderable", void 0);
27877
+ __decorate([property({
27878
+ reflect: true,
27879
+ attribute: `sticky-headers`,
27880
+ converter: {
27881
+ fromAttribute: (value) => value !== `false`,
27882
+ toAttribute: (value) => value ? null : `false`
27883
+ }
27884
+ })], TreeBaseElement.prototype, "stickyHeaders", void 0);
27122
27885
  __decorate([property({ attribute: false })], TreeBaseElement.prototype, "dragPreviewRenderer", void 0);
27123
27886
  __decorate([property({ attribute: false })], TreeBaseElement.prototype, "dragPreviewSource", void 0);
27124
27887
  __decorate([property({ attribute: false })], TreeBaseElement.prototype, "canDrag", void 0);
@@ -27127,6 +27890,7 @@ __decorate([property({ attribute: false })], TreeBaseElement.prototype, "parseEx
27127
27890
  __decorate([property({ attribute: false })], TreeBaseElement.prototype, "applyInternalDrop", void 0);
27128
27891
  __decorate([state()], TreeBaseElement.prototype, "_expandedKeys", void 0);
27129
27892
  __decorate([state()], TreeBaseElement.prototype, "_focusedDepth", void 0);
27893
+ __decorate([state()], TreeBaseElement.prototype, "_stickyKeys", void 0);
27130
27894
  TreeBaseElement = __decorate([safeCustomElement(`ixfx-tree-base`)], TreeBaseElement);
27131
27895
  //#endregion
27132
27896
  //#region src/tree/tree-list.ts
@@ -36159,6 +36923,973 @@ var MillerTreeController = class {
36159
36923
  }
36160
36924
  };
36161
36925
  //#endregion
36926
+ //#region src/multicol-list/types.ts
36927
+ const ALL_KEY = `__all__`;
36928
+ //#endregion
36929
+ //#region src/multicol-list/column.ts
36930
+ /** Sorts by label, honouring direction. 'All' lives outside the list, so it is not special-cased. */
36931
+ function sortItems(items, direction) {
36932
+ const dir = direction === `desc` ? -1 : 1;
36933
+ return [...items].sort((a, b) => dir * a.label.localeCompare(b.label, void 0, {
36934
+ sensitivity: `base`,
36935
+ numeric: true
36936
+ }));
36937
+ }
36938
+ /**
36939
+ * Nearest-gap math for header drag-reorder (per data-grid's `_beginHeaderDrag`).
36940
+ *
36941
+ * `offsets` is a prefix-sum of column widths (length = count + 1). `x` is the
36942
+ * pointer position in content space (already adjusted for scroll). Returns the
36943
+ * final insertion index once the source column is removed (`insert`), plus the
36944
+ * un-normalised gap offset for the drop caret (`caretOffset`).
36945
+ */
36946
+ function computeDropGap(offsets, x, count, from) {
36947
+ if (count === 0) return {
36948
+ insert: 0,
36949
+ caretOffset: 0
36950
+ };
36951
+ let bestDist = Number.MAX_SAFE_INTEGER;
36952
+ let caretGap = from;
36953
+ for (let i = 0; i < count; i++) {
36954
+ if (i === from) continue;
36955
+ const left = offsets[i];
36956
+ const right = offsets[i + 1] ?? offsets[offsets.length - 1];
36957
+ const mid = (left + right) / 2;
36958
+ const dist = Math.abs(x - (x < mid ? left : right));
36959
+ if (dist < bestDist) {
36960
+ bestDist = dist;
36961
+ caretGap = x < mid ? i : i + 1;
36962
+ }
36963
+ }
36964
+ const insert = caretGap > from ? caretGap - 1 : caretGap;
36965
+ return {
36966
+ insert: Math.max(0, Math.min(count - 1, insert)),
36967
+ caretOffset: offsets[caretGap] ?? offsets[offsets.length - 1]
36968
+ };
36969
+ }
36970
+ var MulticolColumnController = class {
36971
+ #category;
36972
+ #categoryDefaults;
36973
+ #selectionMode;
36974
+ #dataProvider;
36975
+ #onSelectionChange;
36976
+ #onRequestData;
36977
+ #abortController = void 0;
36978
+ #host;
36979
+ #allRow;
36980
+ #listerEl;
36981
+ #selectedValues = [];
36982
+ #allSelected = true;
36983
+ #lastItems = [];
36984
+ #syncingSelection = false;
36985
+ #state;
36986
+ constructor(options) {
36987
+ this.id = options.id;
36988
+ this.#category = options.category;
36989
+ this.#categoryDefaults = options.categoryDefaults;
36990
+ this.#selectionMode = options.selectionMode;
36991
+ this.#dataProvider = options.dataProvider;
36992
+ this.#onSelectionChange = options.onSelectionChange;
36993
+ this.#onRequestData = options.onRequestData;
36994
+ this.#state = {
36995
+ id: options.id,
36996
+ categoryKey: options.category.key,
36997
+ sort: options.categoryDefaults?.sort ?? `asc`,
36998
+ grouped: options.categoryDefaults?.grouped ?? false,
36999
+ width: 220
37000
+ };
37001
+ }
37002
+ get state() {
37003
+ return this.getState();
37004
+ }
37005
+ /** Always derived from the live category so a swap is visible everywhere. */
37006
+ get categoryKey() {
37007
+ return this.#category.key;
37008
+ }
37009
+ getState() {
37010
+ return { ...this.#state };
37011
+ }
37012
+ updateState(partial) {
37013
+ const sortChanged = partial.sort !== void 0 && partial.sort !== this.#state.sort;
37014
+ const groupedChanged = partial.grouped !== void 0 && partial.grouped !== this.#state.grouped;
37015
+ this.#state = {
37016
+ ...this.#state,
37017
+ ...partial
37018
+ };
37019
+ if (sortChanged) this.#repush();
37020
+ if (groupedChanged) this.#syncGrouping();
37021
+ }
37022
+ setWidth(width) {
37023
+ this.#state = {
37024
+ ...this.#state,
37025
+ width: Math.max(80, Math.min(480, Math.round(width)))
37026
+ };
37027
+ }
37028
+ setSort(sort) {
37029
+ if (sort === this.#state.sort) return;
37030
+ this.#state = {
37031
+ ...this.#state,
37032
+ sort
37033
+ };
37034
+ this.#repush();
37035
+ }
37036
+ setGrouped(grouped) {
37037
+ if (grouped === this.#state.grouped) return;
37038
+ this.#state = {
37039
+ ...this.#state,
37040
+ grouped
37041
+ };
37042
+ this.#syncGrouping();
37043
+ }
37044
+ setSelectionMode(mode) {
37045
+ if (mode === this.#selectionMode) return;
37046
+ this.#selectionMode = mode;
37047
+ for (const sub of this.#subComponents()) sub.selectionMode = mode;
37048
+ }
37049
+ setCategory(category) {
37050
+ this.#category = category;
37051
+ this.#categoryDefaults = category.defaults;
37052
+ this.#state = {
37053
+ ...this.#state,
37054
+ categoryKey: category.key,
37055
+ sort: category.defaults?.sort ?? `asc`,
37056
+ grouped: category.defaults?.grouped ?? false
37057
+ };
37058
+ this.clearSelection();
37059
+ this.#syncGrouping();
37060
+ }
37061
+ get listerHost() {
37062
+ return this.#host;
37063
+ }
37064
+ get isMounted() {
37065
+ return this.#host !== void 0;
37066
+ }
37067
+ setDataProvider(provider) {
37068
+ this.#dataProvider = provider;
37069
+ }
37070
+ mount(host) {
37071
+ if (this.#host) return;
37072
+ this.#host = host;
37073
+ const allRow = document.createElement(`div`);
37074
+ allRow.className = `all-row`;
37075
+ allRow.dataset.key = ALL_KEY;
37076
+ allRow.setAttribute(`role`, `button`);
37077
+ allRow.setAttribute(`tabindex`, `0`);
37078
+ const allLabel = document.createElement(`span`);
37079
+ allLabel.className = `all-label`;
37080
+ allRow.appendChild(allLabel);
37081
+ const applyAll = () => {
37082
+ if (this.#allSelected) return;
37083
+ this.#setAllSelection();
37084
+ };
37085
+ allRow.addEventListener(`click`, applyAll);
37086
+ allRow.addEventListener(`keydown`, (e) => {
37087
+ if (e.key === `Enter` || e.key === ` `) {
37088
+ e.preventDefault();
37089
+ applyAll();
37090
+ }
37091
+ });
37092
+ this.#allRow = allRow;
37093
+ const lister = document.createElement(`ixfx-grouped-item-lister`);
37094
+ lister.crossGroupSelection = true;
37095
+ lister.factory = () => createVerticalListAdapter(renderItem, {
37096
+ selectionMode: this.#selectionMode,
37097
+ interactionMode: `standard`
37098
+ });
37099
+ lister.addEventListener(`select`, this.#handleSelect);
37100
+ this.#listerEl = lister;
37101
+ this.#syncGrouping();
37102
+ this.#syncAllRow();
37103
+ host.append(allRow, lister);
37104
+ if (this.#lastItems.length > 0) {
37105
+ this.#pushItems();
37106
+ this.#restoreAfterSync();
37107
+ }
37108
+ }
37109
+ unmount() {
37110
+ this.#abortPending();
37111
+ this.#allRow?.remove();
37112
+ this.#listerEl?.remove();
37113
+ this.#allRow = void 0;
37114
+ this.#listerEl = void 0;
37115
+ this.#host = void 0;
37116
+ }
37117
+ requestData(query) {
37118
+ if (!this.#dataProvider) return;
37119
+ this.#abortPending();
37120
+ const controller = new AbortController();
37121
+ this.#abortController = controller;
37122
+ const { signal } = controller;
37123
+ this.#onRequestData(this.id, query, signal);
37124
+ Promise.resolve().then(async () => {
37125
+ const items = await collectDataResult(this.#dataProvider(query, signal), signal);
37126
+ if (signal.aborted) return;
37127
+ this.#applyItems(items);
37128
+ }).catch(() => {});
37129
+ }
37130
+ #applyItems(items) {
37131
+ this.#lastItems = items;
37132
+ const valid = this.#selectedValues.filter((v) => items.some((i) => i.key === v));
37133
+ const changed = valid.length !== this.#selectedValues.length;
37134
+ this.#selectedValues = valid;
37135
+ if (valid.length === 0) this.#allSelected = true;
37136
+ if (!this.#listerEl) {
37137
+ if (changed) this.#onSelectionChange(this.id, valid);
37138
+ return;
37139
+ }
37140
+ this.#pushItems();
37141
+ this.#restoreAfterSync();
37142
+ if (changed) this.#onSelectionChange(this.id, valid);
37143
+ }
37144
+ #pushItems() {
37145
+ if (!this.#listerEl) return;
37146
+ const sorted = sortItems(this.#lastItems, this.#state.sort);
37147
+ this.#listerEl.provider = () => sorted;
37148
+ }
37149
+ #repush() {
37150
+ if (!this.#listerEl || this.#lastItems.length === 0) return;
37151
+ this.#pushItems();
37152
+ this.#restoreAfterSync();
37153
+ }
37154
+ /** Grouping config from category defaults; grouping without groupBy is a no-op. */
37155
+ #syncGrouping() {
37156
+ if (!this.#listerEl) return;
37157
+ const groupBy = this.#categoryDefaults?.groupBy;
37158
+ this.#listerEl.groupBy = groupBy;
37159
+ this.#listerEl.grouped = this.#state.grouped && groupBy !== void 0;
37160
+ if (this.#lastItems.length > 0) this.#restoreAfterSync();
37161
+ }
37162
+ #subComponents() {
37163
+ if (!this.#listerEl) return [];
37164
+ return this.#listerEl.querySelectorAll(`:scope > .ungrouped-host > *, :scope > ixfx-panel > *`);
37165
+ }
37166
+ #handleSelect = () => {
37167
+ if (this.#syncingSelection) return;
37168
+ const values = [...this.#listerEl?.selectedItems ?? []].map((i) => i.key).filter((k) => k !== ALL_KEY);
37169
+ if (values.length === this.#selectedValues.length && values.every((v) => this.#selectedValues.includes(v))) {
37170
+ this.#syncAllRow();
37171
+ return;
37172
+ }
37173
+ this.#selectedValues = values;
37174
+ this.#allSelected = values.length === 0;
37175
+ this.#syncAllRow();
37176
+ this.#onSelectionChange(this.id, values);
37177
+ };
37178
+ #setAllSelection() {
37179
+ const previous = this.#selectedValues;
37180
+ this.#syncingSelection = true;
37181
+ try {
37182
+ this.#selectedValues = [];
37183
+ this.#allSelected = true;
37184
+ for (const sub of this.#subComponents()) sub.clearSelection();
37185
+ } finally {
37186
+ this.#syncingSelection = false;
37187
+ }
37188
+ this.#syncAllRow();
37189
+ if (previous.length > 0) this.#onSelectionChange(this.id, []);
37190
+ }
37191
+ clearSelection() {
37192
+ this.#setAllSelection();
37193
+ }
37194
+ get selectedValues() {
37195
+ return this.#selectedValues;
37196
+ }
37197
+ #restoreAfterSync() {
37198
+ if (!this.#listerEl) return;
37199
+ this.#listerEl.updateComplete.then(() => {
37200
+ if (!this.#listerEl || !this.#host) return;
37201
+ this.#syncingSelection = true;
37202
+ try {
37203
+ const wanted = this.#selectedValues;
37204
+ for (const list of this.#listerEl.querySelectorAll(`ixfx-vertical-list`)) list.selectKeys(wanted);
37205
+ const selected = [...this.#listerEl.selectedItems].map((i) => i.key).filter((k) => k !== ALL_KEY);
37206
+ this.#selectedValues = selected;
37207
+ this.#allSelected = selected.length === 0;
37208
+ } finally {
37209
+ this.#syncingSelection = false;
37210
+ }
37211
+ this.#syncAllRow();
37212
+ });
37213
+ }
37214
+ #syncAllRow() {
37215
+ if (!this.#allRow) return;
37216
+ const label = this.#categoryDefaults?.allLabel ?? `All`;
37217
+ const labelEl = this.#allRow.querySelector(`.all-label`);
37218
+ if (labelEl) labelEl.textContent = label;
37219
+ this.#allRow.toggleAttribute(`data-selected`, this.#allSelected);
37220
+ }
37221
+ #abortPending() {
37222
+ if (this.#abortController) {
37223
+ this.#abortController.abort();
37224
+ this.#abortController = void 0;
37225
+ }
37226
+ }
37227
+ };
37228
+ function renderItem(item) {
37229
+ const li = document.createElement(`li`);
37230
+ li.dataset.key = item.key;
37231
+ const labelSpan = document.createElement(`span`);
37232
+ labelSpan.className = `item-label`;
37233
+ labelSpan.textContent = item.label;
37234
+ li.appendChild(labelSpan);
37235
+ if (item.count !== void 0) {
37236
+ const countSpan = document.createElement(`span`);
37237
+ countSpan.className = `count`;
37238
+ countSpan.textContent = String(item.count);
37239
+ li.appendChild(countSpan);
37240
+ }
37241
+ return li;
37242
+ }
37243
+ //#endregion
37244
+ //#region src/multicol-list/multicol-list.ts
37245
+ registerIcon(`menu`, `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12h16"/><path d="M4 18h16"/><path d="M4 6h16"/></svg>`);
37246
+ const DEFAULT_COLUMN_WIDTH = 220;
37247
+ const MIN_COLUMN_WIDTH = 80;
37248
+ const MAX_COLUMN_WIDTH = 480;
37249
+ const DRAG_THRESHOLD = 5;
37250
+ let MulticolListElement = class MulticolListElement extends i {
37251
+ constructor(..._args) {
37252
+ super(..._args);
37253
+ this.categories = [];
37254
+ this.selectionMode = `multiple`;
37255
+ this.minColumns = 1;
37256
+ this.maxColumns = 5;
37257
+ this._columns = [];
37258
+ this._colOffsets = [0];
37259
+ this._resizingColumnId = void 0;
37260
+ this._draggingColumnId = void 0;
37261
+ this._dropCaretX = void 0;
37262
+ this._idCounter = 0;
37263
+ this._autoSeeded = false;
37264
+ this._drag = {
37265
+ pointerId: -1,
37266
+ from: -1,
37267
+ startX: 0,
37268
+ startY: 0,
37269
+ active: false,
37270
+ ghost: null,
37271
+ insert: -1
37272
+ };
37273
+ }
37274
+ static {
37275
+ this.styles = [
37276
+ themeFallbacks,
37277
+ handleStyles,
37278
+ i$3`
37279
+ :host {
37280
+ --multicol-list-bg: var(--surface-3);
37281
+ --multicol-list-header-bg: var(--surface-2);
37282
+ --multicol-list-header-text: var(--surface-3-text);
37283
+ --multicol-list-border: var(--border);
37284
+ --multicol-list-min-column-width: ${MIN_COLUMN_WIDTH}px;
37285
+ --multicol-list-max-column-width: ${MAX_COLUMN_WIDTH}px;
37286
+
37287
+ display: block;
37288
+ overflow: hidden;
37289
+ background: var(--multicol-list-bg);
37290
+ color: var(--surface-3-text);
37291
+ font-family: var(--font-family);
37292
+ }
37293
+ #container {
37294
+ display: flex;
37295
+ flex-direction: row;
37296
+ align-items: stretch;
37297
+ overflow-x: auto;
37298
+ overflow-y: hidden;
37299
+ position: relative;
37300
+ height: 100%;
37301
+ }
37302
+ .column {
37303
+ flex-shrink: 0;
37304
+ display: flex;
37305
+ flex-direction: column;
37306
+ border-right: var(--multicol-list-border);
37307
+ min-width: var(--multicol-list-min-column-width);
37308
+ max-width: var(--multicol-list-max-column-width);
37309
+ background: var(--surface-3);
37310
+ }
37311
+ .column-header {
37312
+ display: flex;
37313
+ align-items: center;
37314
+ gap: var(--space-xs);
37315
+ height: 32px;
37316
+ background: var(--multicol-list-header-bg);
37317
+ color: var(--multicol-list-header-text);
37318
+ border-bottom: var(--border);
37319
+ position: relative;
37320
+ user-select: none;
37321
+ min-width: var(--multicol-list-min-column-width);
37322
+ box-sizing: border-box;
37323
+ }
37324
+ .column-header[data-dragging] {
37325
+ opacity: 0.4;
37326
+ }
37327
+ .reorder-handle {
37328
+ cursor: grab;
37329
+ opacity: 0;
37330
+ display: inline-flex;
37331
+ align-items: center;
37332
+ flex-shrink: 0;
37333
+ padding-left: var(--space-xs);
37334
+ touch-action: none;
37335
+ transition: opacity var(--transition, 0.15s ease-out);
37336
+ }
37337
+ .column-header:hover .reorder-handle, .column-header:focus-within .reorder-handle, .column-header[data-dragging] .reorder-handle { opacity: var(--ixfx-handle-opacity, 0.5); }
37338
+ .reorder-handle:active {
37339
+ cursor: grabbing;
37340
+ }
37341
+ .reorder-handle .ixfx-handle {
37342
+ --ixfx-handle-length: 14px;
37343
+ --ixfx-handle-thickness: var(--multicol-list-reorder-handle-width, 10px);
37344
+ --ixfx-handle-dot-size: 3px;
37345
+ }
37346
+ .column-label {
37347
+ flex: 1;
37348
+ overflow: hidden;
37349
+ text-overflow: ellipsis;
37350
+ white-space: nowrap;
37351
+ padding: 0 var(--space-s);
37352
+ font-size: var(--text-m);
37353
+ font-weight: 600;
37354
+ background: transparent;
37355
+ border: none;
37356
+ color: inherit;
37357
+ cursor: pointer;
37358
+ text-align: left;
37359
+ min-width: 0;
37360
+ }
37361
+ .column-label:hover {
37362
+ text-decoration: underline;
37363
+ }
37364
+ .burger-btn {
37365
+ flex-shrink: 0;
37366
+ width: 28px;
37367
+ height: 28px;
37368
+ display: flex;
37369
+ align-items: center;
37370
+ justify-content: center;
37371
+ background: transparent;
37372
+ border: none;
37373
+ cursor: pointer;
37374
+ color: var(--surface-3-text);
37375
+ opacity: 0;
37376
+ transition: opacity var(--transition);
37377
+ border-radius: var(--radius-s);
37378
+ }
37379
+ .column:hover .burger-btn,
37380
+ .column-header:focus-within .burger-btn {
37381
+ opacity: 1;
37382
+ }
37383
+ .burger-btn:hover {
37384
+ background: var(--surface-4);
37385
+ }
37386
+ .resize-handle {
37387
+ position: absolute;
37388
+ right: -4px;
37389
+ top: 0;
37390
+ bottom: 0;
37391
+ width: 8px;
37392
+ cursor: col-resize;
37393
+ z-index: 1;
37394
+ display: flex;
37395
+ align-items: stretch;
37396
+ justify-content: center;
37397
+ touch-action: none;
37398
+ }
37399
+ .resize-handle::before {
37400
+ content: '';
37401
+ width: 2px;
37402
+ margin: 2px 0;
37403
+ border-radius: 1px;
37404
+ background: transparent;
37405
+ transition: background-color var(--transition);
37406
+ }
37407
+ .resize-handle:hover::before,
37408
+ .resize-handle[data-active]::before {
37409
+ background: var(--accent);
37410
+ }
37411
+ .lister-host {
37412
+ flex: 1;
37413
+ overflow-y: auto;
37414
+ overflow-x: hidden;
37415
+ position: relative;
37416
+ display: flex;
37417
+ flex-direction: column;
37418
+ }
37419
+ .all-row {
37420
+ display: flex;
37421
+ align-items: center;
37422
+ padding: var(--space-xs) var(--space-s);
37423
+ cursor: pointer;
37424
+ user-select: none;
37425
+ min-height: 28px;
37426
+ box-sizing: border-box;
37427
+ outline: 1px solid transparent;
37428
+ background: var(--surface-3);
37429
+ }
37430
+ .all-row:hover,
37431
+ .all-row[data-selected] {
37432
+ background: var(--surface-5);
37433
+ }
37434
+ .all-row[data-selected] {
37435
+ outline-color: var(--accent);
37436
+ font-weight: 600;
37437
+ }
37438
+ ixfx-grouped-item-lister {
37439
+ display: block;
37440
+ }
37441
+ .drop-caret {
37442
+ position: absolute;
37443
+ top: 0;
37444
+ bottom: 0;
37445
+ width: 2px;
37446
+ background: var(--accent);
37447
+ border-radius: 1px;
37448
+ pointer-events: none;
37449
+ z-index: 10;
37450
+ }
37451
+ .item-label {
37452
+ flex: 1;
37453
+ }
37454
+ .count {
37455
+ opacity: 0.6;
37456
+ margin-left: var(--space-s);
37457
+ font-size: var(--text-s);
37458
+ }
37459
+ `
37460
+ ];
37461
+ }
37462
+ get columns() {
37463
+ return this._columns.map((c) => c.getState());
37464
+ }
37465
+ setColumns(states) {
37466
+ const existingMap = new Map(this._columns.map((c) => [c.id, c]));
37467
+ const newColumns = [];
37468
+ for (const colState of states) {
37469
+ const existing = existingMap.get(colState.id);
37470
+ if (existing) {
37471
+ if (existing.categoryKey !== colState.categoryKey) {
37472
+ const newCategory = this.categories.find((c) => c.key === colState.categoryKey);
37473
+ if (newCategory) existing.setCategory(newCategory);
37474
+ }
37475
+ existing.updateState(colState);
37476
+ newColumns.push(existing);
37477
+ existingMap.delete(colState.id);
37478
+ continue;
37479
+ }
37480
+ const category = this.categories.find((c) => c.key === colState.categoryKey);
37481
+ if (!category) continue;
37482
+ const controller = this.#createController(colState.id, category);
37483
+ controller.updateState(colState);
37484
+ newColumns.push(controller);
37485
+ }
37486
+ for (const col of existingMap.values()) col.unmount();
37487
+ this._columns = newColumns;
37488
+ this._updateColOffsets();
37489
+ this._emitColumnsChange(`add`);
37490
+ this._requeryAllColumns();
37491
+ this.requestUpdate();
37492
+ }
37493
+ addColumn(categoryKey, position) {
37494
+ if (this.maxColumns > 0 && this._columns.length >= this.maxColumns) return;
37495
+ const category = this.categories.find((c) => c.key === categoryKey);
37496
+ if (!category) return;
37497
+ const id = `col-${++this._idCounter}`;
37498
+ const controller = this.#createController(id, category);
37499
+ if (position !== void 0 && position >= 0 && position < this._columns.length) this._columns.splice(position, 0, controller);
37500
+ else this._columns.push(controller);
37501
+ this._updateColOffsets();
37502
+ this._emitColumnsChange(`add`);
37503
+ this._requeryAllColumns();
37504
+ this.requestUpdate();
37505
+ }
37506
+ removeColumn(columnId) {
37507
+ if (this._columns.length <= this.minColumns) return;
37508
+ const idx = this._columns.findIndex((c) => c.id === columnId);
37509
+ if (idx < 0) return;
37510
+ this._columns[idx].unmount();
37511
+ this._columns.splice(idx, 1);
37512
+ this._updateColOffsets();
37513
+ this._emitColumnsChange(`remove`);
37514
+ this._requeryAllColumns();
37515
+ this.requestUpdate();
37516
+ }
37517
+ getSelection() {
37518
+ return this._columns.map((c) => ({
37519
+ columnId: c.id,
37520
+ categoryKey: c.categoryKey,
37521
+ values: c.selectedValues
37522
+ }));
37523
+ }
37524
+ clearSelection() {
37525
+ for (const col of this._columns) col.clearSelection();
37526
+ this.requestUpdate();
37527
+ }
37528
+ render() {
37529
+ return b`
37530
+ <div id="container">
37531
+ ${repeat(this._columns, (col) => col.id, (col, idx) => this._renderColumn(col, idx))}
37532
+ ${this._dropCaretX !== void 0 ? b`<div class="drop-caret" style="left: ${this._dropCaretX}px"></div>` : A}
37533
+ </div>
37534
+ `;
37535
+ }
37536
+ updated(changedProperties) {
37537
+ if (!this._autoSeeded && this._columns.length === 0 && this.categories.length > 0) {
37538
+ this._autoSeeded = true;
37539
+ this.addColumn(this.categories[0].key);
37540
+ }
37541
+ if (changedProperties.has(`selectionMode`)) for (const col of this._columns) col.setSelectionMode(this.selectionMode);
37542
+ if (changedProperties.has(`dataProvider`)) for (const col of this._columns) col.setDataProvider(this.dataProvider);
37543
+ for (const col of this._columns) if (!col.isMounted) {
37544
+ const hostEl = this.shadowRoot?.querySelector(`[data-col-id="${col.id}"] .lister-host`);
37545
+ if (hostEl) col.mount(hostEl);
37546
+ }
37547
+ if (changedProperties.has(`categories`)) this._syncColumnsWithCategories();
37548
+ if (changedProperties.has(`categories`) || changedProperties.has(`dataProvider`)) this._requeryAllColumns();
37549
+ this._updateColOffsets();
37550
+ }
37551
+ _renderColumn(col, idx) {
37552
+ const width = col.getState().width ?? DEFAULT_COLUMN_WIDTH;
37553
+ return b`
37554
+ <div
37555
+ class="column"
37556
+ data-col-id="${col.id}"
37557
+ style="width: ${width}px"
37558
+ >
37559
+ <div
37560
+ class="column-header"
37561
+ ?data-dragging=${this._draggingColumnId === col.id}
37562
+ data-col-idx=${idx}
37563
+ >
37564
+ <span
37565
+ class="reorder-handle"
37566
+ data-tooltip="Drag to reorder"
37567
+ @pointerdown=${(e) => this._onHeaderPointerDown(e, col, idx)}
37568
+ ><span class="ixfx-handle" data-handle="dotted" data-shape="vertical" part="reorder-handle"></span></span>
37569
+ <button
37570
+ class="column-label"
37571
+ data-tooltip="Change category"
37572
+ @click=${(e) => {
37573
+ e.stopPropagation();
37574
+ this._openCategoryPicker(col, e.currentTarget);
37575
+ }}
37576
+ >${this._getCategoryLabel(col.categoryKey)}</button>
37577
+ <button
37578
+ class="burger-btn"
37579
+ data-tooltip="Column options"
37580
+ @click=${(e) => {
37581
+ e.stopPropagation();
37582
+ this._openBurgerMenu(col, e.currentTarget);
37583
+ }}
37584
+ >
37585
+ <ixfx-icon name="menu" size="14"></ixfx-icon>
37586
+ </button>
37587
+ <span
37588
+ class="resize-handle"
37589
+ ?data-active=${this._resizingColumnId === col.id}
37590
+ @pointerdown=${(e) => this._onResizePointerDown(e, col)}
37591
+ @click=${(e) => e.stopPropagation()}
37592
+ ></span>
37593
+ </div>
37594
+ <div class="lister-host"></div>
37595
+ </div>
37596
+ `;
37597
+ }
37598
+ _getCategoryLabel(key) {
37599
+ return this.categories.find((c) => c.key === key)?.label ?? key;
37600
+ }
37601
+ #createController(id, category) {
37602
+ return new MulticolColumnController({
37603
+ id,
37604
+ category,
37605
+ categoryDefaults: category.defaults,
37606
+ selectionMode: this.selectionMode,
37607
+ dataProvider: this.dataProvider,
37608
+ onSelectionChange: this._onColumnSelectionChange.bind(this),
37609
+ onRequestData: this._onColumnRequestData.bind(this)
37610
+ });
37611
+ }
37612
+ _onHeaderPointerDown(e, col, idx) {
37613
+ e.stopPropagation();
37614
+ this._drag = {
37615
+ pointerId: e.pointerId,
37616
+ from: idx,
37617
+ startX: e.clientX,
37618
+ startY: e.clientY,
37619
+ active: false,
37620
+ ghost: null,
37621
+ insert: idx
37622
+ };
37623
+ const onMove = (ev) => {
37624
+ if (ev.pointerId !== this._drag.pointerId) return;
37625
+ const dx = ev.clientX - this._drag.startX;
37626
+ const dy = ev.clientY - this._drag.startY;
37627
+ if (!this._drag.active) {
37628
+ if (Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
37629
+ this._drag.active = true;
37630
+ this._draggingColumnId = col.id;
37631
+ const headerEl = this.shadowRoot?.querySelector(`[data-col-id="${col.id}"] .column-header`);
37632
+ const content = document.createElement(`span`);
37633
+ content.textContent = this._getCategoryLabel(col.categoryKey);
37634
+ try {
37635
+ if (headerEl) {
37636
+ this._drag.ghost = createDragGhost({
37637
+ anchor: headerEl,
37638
+ content
37639
+ });
37640
+ this._drag.ghost.move(ev.clientX, ev.clientY);
37641
+ }
37642
+ } catch {}
37643
+ try {
37644
+ this._containerEl?.setPointerCapture(ev.pointerId);
37645
+ } catch {}
37646
+ }
37647
+ this._drag.ghost?.move(ev.clientX, ev.clientY);
37648
+ const containerEl = this._containerEl;
37649
+ if (!containerEl) return;
37650
+ const rect = containerEl.getBoundingClientRect();
37651
+ const x = ev.clientX - rect.left + containerEl.scrollLeft;
37652
+ const gap = computeDropGap(this._colOffsets, x, this._columns.length, this._drag.from);
37653
+ this._drag.insert = gap.insert;
37654
+ this._dropCaretX = gap.caretOffset;
37655
+ this.requestUpdate();
37656
+ };
37657
+ const finish = (ev) => {
37658
+ if (ev.pointerId !== this._drag.pointerId) return;
37659
+ const wasActive = this._drag.active;
37660
+ const from = this._drag.from;
37661
+ const insert = this._drag.insert;
37662
+ this._drag.ghost?.destroy();
37663
+ this._drag.ghost = null;
37664
+ this._draggingColumnId = void 0;
37665
+ this._dropCaretX = void 0;
37666
+ try {
37667
+ this._containerEl?.releasePointerCapture(ev.pointerId);
37668
+ } catch {}
37669
+ window.removeEventListener(`pointermove`, onMove);
37670
+ window.removeEventListener(`pointerup`, finish);
37671
+ window.removeEventListener(`pointercancel`, finish);
37672
+ if (wasActive && insert !== from) {
37673
+ const [moved] = this._columns.splice(from, 1);
37674
+ this._columns.splice(insert, 0, moved);
37675
+ this._updateColOffsets();
37676
+ this._emitColumnsChange(`reorder`);
37677
+ this.requestUpdate();
37678
+ }
37679
+ };
37680
+ window.addEventListener(`pointermove`, onMove);
37681
+ window.addEventListener(`pointerup`, finish);
37682
+ window.addEventListener(`pointercancel`, finish);
37683
+ }
37684
+ _onResizePointerDown(e, col) {
37685
+ e.preventDefault();
37686
+ e.stopPropagation();
37687
+ const startX = e.clientX;
37688
+ const startW = col.getState().width ?? DEFAULT_COLUMN_WIDTH;
37689
+ this._resizingColumnId = col.id;
37690
+ const applyWidth = (clientX) => {
37691
+ const w = Math.max(MIN_COLUMN_WIDTH, Math.min(MAX_COLUMN_WIDTH, startW + clientX - startX));
37692
+ col.setWidth(w);
37693
+ return w;
37694
+ };
37695
+ const onMove = (ev) => {
37696
+ if (ev.pointerId !== e.pointerId) return;
37697
+ applyWidth(ev.clientX);
37698
+ this._updateColOffsets();
37699
+ this.requestUpdate();
37700
+ };
37701
+ const finish = (ev) => {
37702
+ window.removeEventListener(`pointermove`, onMove);
37703
+ window.removeEventListener(`pointerup`, finish);
37704
+ window.removeEventListener(`pointercancel`, finish);
37705
+ applyWidth(ev.type === `pointercancel` ? startX : ev.clientX);
37706
+ this._resizingColumnId = void 0;
37707
+ this._updateColOffsets();
37708
+ this._emitColumnsChange(`resize`);
37709
+ this.requestUpdate();
37710
+ };
37711
+ window.addEventListener(`pointermove`, onMove);
37712
+ window.addEventListener(`pointerup`, finish);
37713
+ window.addEventListener(`pointercancel`, finish);
37714
+ }
37715
+ /** Floats a dropdown menu trigger over `anchorEl` and opens it immediately. */
37716
+ #openMenuAt(anchorEl, placement, buildMenu) {
37717
+ const rect = anchorEl.getBoundingClientRect();
37718
+ const trigger = document.createElement(`ixfx-menu-trigger`);
37719
+ trigger.mode = `dropdown`;
37720
+ trigger.tabStop = false;
37721
+ trigger.placement = placement;
37722
+ trigger.style.position = `fixed`;
37723
+ trigger.style.left = `${rect.left}px`;
37724
+ trigger.style.top = `${rect.bottom}px`;
37725
+ const container = document.createElement(`ixfx-menu-container`);
37726
+ container.setAttribute(`slot`, `menu`);
37727
+ buildMenu(container);
37728
+ trigger.appendChild(container);
37729
+ trigger.addEventListener(`menu-trigger-close`, () => trigger.remove(), { once: true });
37730
+ document.body.appendChild(trigger);
37731
+ trigger.updateComplete.then(() => trigger.openMenu());
37732
+ }
37733
+ #categoryToNode(cat) {
37734
+ return {
37735
+ item: {
37736
+ key: cat.key,
37737
+ label: cat.label
37738
+ },
37739
+ children: cat.children && cat.children.length > 0 ? cat.children.map((c) => this.#categoryToNode(c)) : void 0
37740
+ };
37741
+ }
37742
+ _openCategoryPicker(col, anchorEl) {
37743
+ this.#openMenuAt(anchorEl, `bottom-start`, (container) => {
37744
+ const items = menuFromTreeToElements(this.categories.map((c) => this.#categoryToNode(c)), { onCommand: (detail) => {
37745
+ if (detail.command === void 0) return;
37746
+ this._changeColumnCategory(col, detail.command);
37747
+ } });
37748
+ for (const el of items) container.appendChild(el);
37749
+ for (const item of container.querySelectorAll(`ixfx-menu-item`)) if (item.getAttribute(`command`) === col.categoryKey) item.setAttribute(`disabled`, ``);
37750
+ });
37751
+ }
37752
+ #menuItem(label, command, onCommand, iconName) {
37753
+ const el = document.createElement(`ixfx-menu-item`);
37754
+ el.setAttribute(`command`, command);
37755
+ el.setAttribute(`label`, label);
37756
+ if (iconName) el.setAttribute(`icon-name`, iconName);
37757
+ if (onCommand) el.addEventListener(`command`, () => onCommand());
37758
+ return el;
37759
+ }
37760
+ _openBurgerMenu(col, anchorEl) {
37761
+ this.#openMenuAt(anchorEl, `bottom-end`, (container) => {
37762
+ const removeItem = this.#menuItem(`Remove this column`, `remove`, () => this.removeColumn(col.id));
37763
+ removeItem.toggleAttribute(`disabled`, this._columns.length <= this.minColumns);
37764
+ container.appendChild(removeItem);
37765
+ const separator = document.createElement(`ixfx-menu-separator`);
37766
+ container.appendChild(separator);
37767
+ const atMax = this.maxColumns > 0 && this._columns.length >= this.maxColumns;
37768
+ const usedCats = new Set(this._columns.map((c) => c.categoryKey));
37769
+ const unused = this.categories.filter((c) => !usedCats.has(c.key));
37770
+ const canAdd = !atMax && unused.length > 0;
37771
+ const addSub = document.createElement(`ixfx-menu-sub-trigger`);
37772
+ addSub.setAttribute(`label`, `Add column`);
37773
+ const addContainer = document.createElement(`ixfx-menu-container`);
37774
+ addContainer.setAttribute(`slot`, `submenu`);
37775
+ const idx = this._columns.findIndex((c) => c.id === col.id);
37776
+ for (const [label, offset] of [[`Left`, -1], [`Right`, 1]]) {
37777
+ const item = this.#menuItem(label, `add-${label.toLowerCase()}`, () => {
37778
+ this.#insertColumn(unused[0].key, Math.max(0, idx + Math.max(0, offset)));
37779
+ });
37780
+ item.toggleAttribute(`disabled`, !canAdd);
37781
+ addContainer.appendChild(item);
37782
+ }
37783
+ addSub.appendChild(addContainer);
37784
+ container.appendChild(addSub);
37785
+ const sortSub = document.createElement(`ixfx-menu-sub-trigger`);
37786
+ sortSub.setAttribute(`label`, `Sort`);
37787
+ const sortContainer = document.createElement(`ixfx-menu-container`);
37788
+ sortContainer.setAttribute(`slot`, `submenu`);
37789
+ sortContainer.appendChild(this.#menuItem(`Ascending`, `sort-asc`, () => {
37790
+ col.setSort(`asc`);
37791
+ this._emitColumnsChange(`sort`);
37792
+ this.requestUpdate();
37793
+ }, col.getState().sort === `asc` ? `check` : void 0));
37794
+ sortContainer.appendChild(this.#menuItem(`Descending`, `sort-desc`, () => {
37795
+ col.setSort(`desc`);
37796
+ this._emitColumnsChange(`sort`);
37797
+ this.requestUpdate();
37798
+ }, col.getState().sort === `desc` ? `check` : void 0));
37799
+ sortSub.appendChild(sortContainer);
37800
+ container.appendChild(sortSub);
37801
+ const grouped = col.getState().grouped;
37802
+ container.appendChild(this.#menuItem(grouped ? `Ungroup` : `Group`, `toggle-group`, () => {
37803
+ col.setGrouped(!grouped);
37804
+ this._emitColumnsChange(`grouping`);
37805
+ this.requestUpdate();
37806
+ }, grouped ? `check` : void 0));
37807
+ });
37808
+ }
37809
+ #insertColumn(categoryKey, position) {
37810
+ this.addColumn(categoryKey, position);
37811
+ }
37812
+ _changeColumnCategory(col, categoryKey) {
37813
+ const category = this.categories.find((c) => c.key === categoryKey);
37814
+ if (!category) return;
37815
+ col.setCategory(category);
37816
+ this._emitColumnsChange(`category`);
37817
+ this._requeryAllColumns();
37818
+ this.requestUpdate();
37819
+ }
37820
+ _onColumnSelectionChange(columnId, _values) {
37821
+ if (!this._columns.find((c) => c.id === columnId)) return;
37822
+ for (const otherCol of this._columns) if (otherCol.id !== columnId) otherCol.requestData(this._buildQuery(otherCol));
37823
+ const detail = {
37824
+ columnId,
37825
+ columns: this.getSelection()
37826
+ };
37827
+ this.dispatchEvent(new CustomEvent(`multicol-select`, {
37828
+ detail,
37829
+ bubbles: true,
37830
+ composed: true
37831
+ }));
37832
+ this.requestUpdate();
37833
+ }
37834
+ _onColumnRequestData(_columnId, _query, _signal) {}
37835
+ _buildQuery(col) {
37836
+ const otherSelections = /* @__PURE__ */ new Map();
37837
+ for (const c of this._columns) if (c.id !== col.id) otherSelections.set(c.id, c.selectedValues);
37838
+ return {
37839
+ columnId: col.id,
37840
+ categoryKey: col.categoryKey,
37841
+ otherSelections
37842
+ };
37843
+ }
37844
+ _requeryAllColumns() {
37845
+ for (const col of this._columns) col.requestData(this._buildQuery(col));
37846
+ }
37847
+ _syncColumnsWithCategories() {
37848
+ let changed = false;
37849
+ for (const col of this._columns) {
37850
+ if (this.categories.some((c) => c.key === col.categoryKey)) continue;
37851
+ if (this.categories.length === 0) continue;
37852
+ col.setCategory(this.categories[0]);
37853
+ changed = true;
37854
+ }
37855
+ if (changed) this._emitColumnsChange(`category`);
37856
+ }
37857
+ _updateColOffsets() {
37858
+ const offsets = [0];
37859
+ let sum = 0;
37860
+ for (const col of this._columns) {
37861
+ sum += col.getState().width ?? DEFAULT_COLUMN_WIDTH;
37862
+ offsets.push(sum);
37863
+ }
37864
+ if (!(offsets.length === this._colOffsets.length && offsets.every((v, i) => v === this._colOffsets[i]))) this._colOffsets = offsets;
37865
+ }
37866
+ _emitColumnsChange(reason) {
37867
+ this.dispatchEvent(new CustomEvent(`multicol-columns-change`, {
37868
+ detail: {
37869
+ columns: this.columns,
37870
+ reason
37871
+ },
37872
+ bubbles: true,
37873
+ composed: true
37874
+ }));
37875
+ }
37876
+ };
37877
+ __decorate([property({ attribute: false })], MulticolListElement.prototype, "categories", void 0);
37878
+ __decorate([property({ attribute: false })], MulticolListElement.prototype, "dataProvider", void 0);
37879
+ __decorate([property({
37880
+ type: String,
37881
+ attribute: `selection-mode`
37882
+ })], MulticolListElement.prototype, "selectionMode", void 0);
37883
+ __decorate([property({ type: Number })], MulticolListElement.prototype, "minColumns", void 0);
37884
+ __decorate([property({ type: Number })], MulticolListElement.prototype, "maxColumns", void 0);
37885
+ __decorate([state()], MulticolListElement.prototype, "_columns", void 0);
37886
+ __decorate([state()], MulticolListElement.prototype, "_colOffsets", void 0);
37887
+ __decorate([state()], MulticolListElement.prototype, "_resizingColumnId", void 0);
37888
+ __decorate([state()], MulticolListElement.prototype, "_draggingColumnId", void 0);
37889
+ __decorate([state()], MulticolListElement.prototype, "_dropCaretX", void 0);
37890
+ __decorate([query(`#container`)], MulticolListElement.prototype, "_containerEl", void 0);
37891
+ MulticolListElement = __decorate([customElement(`ixfx-multicol-list`)], MulticolListElement);
37892
+ //#endregion
36162
37893
  //#region src/notifier/notification-pill.ts
36163
37894
  let NotificationPillElement = class NotificationPillElement extends i {
36164
37895
  constructor(..._args) {
@@ -45863,12 +47594,25 @@ function squarifyInto(items, box) {
45863
47594
  }
45864
47595
  return out;
45865
47596
  }
47597
+ /** Clamp a raw cascade offset fraction to a sane range. */
47598
+ function normaliseOffset(raw) {
47599
+ return typeof raw === `number` && Number.isFinite(raw) && raw > 0 ? Math.min(raw, 1) : 0;
47600
+ }
45866
47601
  /**
45867
47602
  * Subdivide `box` among `weights` (same length as the child list) using
45868
47603
  * `method` at `relativeDepth`. Returns one absolute box per weight, in order.
45869
47604
  * Zero-share children get degenerate (zero-area) boxes at the box origin.
47605
+ * Degenerate (zero/negative-extent) containers also yield zero-area boxes
47606
+ * rather than `NaN` — this matters for cascaded layouts where deep insets
47607
+ * can consume the whole box.
45870
47608
  */
45871
47609
  function subdivide(box, weights, method, relativeDepth) {
47610
+ if (box.width <= 0 || box.height <= 0) return weights.map(() => ({
47611
+ x: box.x,
47612
+ y: box.y,
47613
+ width: 0,
47614
+ height: 0
47615
+ }));
45872
47616
  const total = weights.reduce((a, b) => a + b, 0);
45873
47617
  const shares = total > 0 ? weights.map((w) => w / total) : weights.map(() => 1 / weights.length);
45874
47618
  const dice = method === `dice` || method === `slice-dice` && relativeDepth % 2 === 0;
@@ -45935,12 +47679,16 @@ function subdivide(box, weights, method, relativeDepth) {
45935
47679
  * @param options `valueAccessor` (default equal weights), `maxDepth` (nesting
45936
47680
  * levels, default unlimited), `zoomKey` (visual root, default true root;
45937
47681
  * unknown keys fall back to the true root), `tilingMethod` (default
45938
- * `'squarify'`).
47682
+ * `'squarify'`), `presentation` (default `'nested'`) plus `cascadeOffsetX/Y`
47683
+ * (per-level shift as a viewport fraction, cascaded only).
45939
47684
  */
45940
47685
  function computeTreemapLayout(root, options = {}) {
45941
47686
  if (!root?.children?.length) return [];
45942
- const { maxDepth = Number.POSITIVE_INFINITY, valueAccessor = () => 1, zoomKey, tilingMethod = `squarify`, hideLeaves = false } = options;
47687
+ const { maxDepth = Number.POSITIVE_INFINITY, valueAccessor = () => 1, zoomKey, tilingMethod = `squarify`, hideLeaves = false, presentation = `nested`, cascadeOffsetX: rawOx, cascadeOffsetY: rawOy } = options;
45943
47688
  if (maxDepth <= 0) return [];
47689
+ const cascaded = presentation === `cascaded`;
47690
+ const ox = cascaded ? normaliseOffset(rawOx) : 0;
47691
+ const oy = cascaded ? normaliseOffset(rawOy) : 0;
45944
47692
  const visibleChildren = (node) => {
45945
47693
  const children = node.children ?? [];
45946
47694
  return hideLeaves ? children.filter((n) => n.item.isLeaf !== true) : children;
@@ -45971,7 +47719,15 @@ function computeTreemapLayout(root, options = {}) {
45971
47719
  setSize,
45972
47720
  hasChildren: children.length > 0 || node.children === void 0 && node.item.isLeaf !== true
45973
47721
  });
45974
- if (children.length > 0) layoutLevel(children, childBox, depth + 1, relativeDepth + 1, node.item.key);
47722
+ if (children.length > 0) {
47723
+ const contentBox = ox <= 0 && oy <= 0 ? childBox : {
47724
+ x: childBox.x + ox,
47725
+ y: childBox.y + oy,
47726
+ width: Math.max(0, childBox.width - ox),
47727
+ height: Math.max(0, childBox.height - oy)
47728
+ };
47729
+ layoutLevel(children, contentBox, depth + 1, relativeDepth + 1, node.item.key);
47730
+ }
45975
47731
  });
45976
47732
  };
45977
47733
  layoutLevel(siblings, {
@@ -45991,6 +47747,8 @@ let TreemapListElement = class TreemapListElement extends i {
45991
47747
  this.selectionFilter = `all`;
45992
47748
  this.interactionMode = `standard`;
45993
47749
  this.tilingMethod = `squarify`;
47750
+ this.presentation = `nested`;
47751
+ this.cascadeOffset = 6;
45994
47752
  this.maxDepth = 4;
45995
47753
  this.hideLeaves = false;
45996
47754
  this.minLabelArea = 1600;
@@ -46062,9 +47820,28 @@ let TreemapListElement = class TreemapListElement extends i {
46062
47820
  maxDepth: this.maxDepth,
46063
47821
  zoomKey,
46064
47822
  tilingMethod: this.tilingMethod,
46065
- hideLeaves: this.hideLeaves
47823
+ hideLeaves: this.hideLeaves,
47824
+ presentation: this.presentation,
47825
+ ...this.#cascadeFractions()
46066
47826
  });
46067
47827
  }
47828
+ /**
47829
+ * Pixel `cascadeOffset` as viewport fractions for the current host size.
47830
+ * Returns `{}` when nested, unmeasured, or non-positive — layout then falls
47831
+ * back to classic nesting for that pass (the `ResizeObserver` re-renders
47832
+ * once measured).
47833
+ */
47834
+ #cascadeFractions() {
47835
+ if (this.presentation !== `cascaded`) return {};
47836
+ if (!Number.isFinite(this.cascadeOffset) || this.cascadeOffset <= 0) return {};
47837
+ const w = this.clientWidth || 0;
47838
+ const h = this.clientHeight || 0;
47839
+ if (w <= 0 || h <= 0) return {};
47840
+ return {
47841
+ cascadeOffsetX: this.cascadeOffset / w,
47842
+ cascadeOffsetY: this.cascadeOffset / h
47843
+ };
47844
+ }
46068
47845
  connectedCallback() {
46069
47846
  super.connectedCallback();
46070
47847
  this.setAttribute(`data-input-mode`, `mouse`);
@@ -46679,7 +48456,11 @@ let TreemapListElement = class TreemapListElement extends i {
46679
48456
  #canDescend(rect) {
46680
48457
  const size = this.#pixelSize(rect);
46681
48458
  if (size === void 0) return true;
46682
- return size.width * size.height >= this.minChildArea && size.width >= this.minTileWidth;
48459
+ const offset = this.presentation === `cascaded` && Number.isFinite(this.cascadeOffset) && this.cascadeOffset > 0 ? this.cascadeOffset : 0;
48460
+ const w = size.width - offset;
48461
+ const h = size.height - offset;
48462
+ if (w <= 0 || h <= 0) return false;
48463
+ return w * h >= this.minChildArea && w >= this.minTileWidth;
46683
48464
  }
46684
48465
  /** Slugify a category name into a CSS custom-property-safe token. */
46685
48466
  #categorySlug(category) {
@@ -46791,6 +48572,7 @@ let TreemapListElement = class TreemapListElement extends i {
46791
48572
  class="treemap"
46792
48573
  role="tree"
46793
48574
  tabindex="0"
48575
+ data-presentation=${this.presentation}
46794
48576
  data-input-mode=${this.tickled.inputMode}
46795
48577
  style=${`--treemap-padding:${this.padding}px`}
46796
48578
  @keydown=${(e) => this.#handleKeyDown(e)}
@@ -46921,6 +48703,14 @@ let TreemapListElement = class TreemapListElement extends i {
46921
48703
  margin-top: 0;
46922
48704
  }
46923
48705
 
48706
+ /* Cascaded presentation (Lü & Fogarty 2008): the geometric inset is
48707
+ already in the layout rects — this adds the stack-of-cards depth
48708
+ cue on top. Parent tiles read as cards sitting behind their
48709
+ children. */
48710
+ .treemap[data-presentation="cascaded"] .tile {
48711
+ box-shadow: 2px 2px 0 rgb(0 0 0 / 0.25);
48712
+ }
48713
+
46924
48714
  .tile-header {
46925
48715
  flex-shrink: 0;
46926
48716
  padding: 1px var(--space-xs);
@@ -46991,6 +48781,14 @@ __decorate([property({
46991
48781
  type: String,
46992
48782
  attribute: `tiling-method`
46993
48783
  })], TreemapListElement.prototype, "tilingMethod", void 0);
48784
+ __decorate([property({
48785
+ type: String,
48786
+ attribute: `presentation`
48787
+ })], TreemapListElement.prototype, "presentation", void 0);
48788
+ __decorate([property({
48789
+ type: Number,
48790
+ attribute: `cascade-offset`
48791
+ })], TreemapListElement.prototype, "cascadeOffset", void 0);
46994
48792
  __decorate([property({
46995
48793
  type: Number,
46996
48794
  attribute: `max-depth`
@@ -48143,6 +49941,6 @@ function init() {
48143
49941
  console.log(`Init`);
48144
49942
  }
48145
49943
  //#endregion
48146
- export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IcicleTreeListElement, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeKeyboardNavController, TreeListElement, TreemapListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeIcicleLayout, computeLeafGeoms, computeTreemapLayout, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, dropTargetFor, extractStack, findIcicleNode, findIciclePath, findNode, findParentOf, findStackOf, findStackPathByName, findTreemapNode, findTreemapPath, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normaliseValue, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, toolbarGapIndex, walk, wrapRoot };
49944
+ export { AcTextElement, AcTokenElement, BottomDrawerElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, DataGridElement, DataTableElement, DetailListElement, DockHostElement, DockPanelElement, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GridListElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IcicleTreeListElement, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, KeyedElementIndex, LIST_ITEM_MOTION_MS, LIST_SEARCH_COMMAND_IDS, LIST_SEARCH_MODES, LabelledRadialInput, LabelledRangeInput, LabelledSliderInput, LedElement, ListDragSelectController, ListNativeDragController, ListSearchController, ListSelectionController, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, MulticolListElement, NarrowedTextElement, NotificationManager, NotificationPillElement, PanTextElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, RatingElement, SelectHorizElement, SliderInputElement, SlidingNumberElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SplitPanelElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TextShimmerElement, TickledController, TimelineController, TimelineTrackTabElement, TitlebarElement, ToolbarElement, ToolbarGroupElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeDropController, TreeKeyboardNavController, TreeListElement, TreemapListElement, TwoSplitLayoutElement, VerticalListElement, XyPad, addPanelToStack, animateListItemIn, animateListItemOut, applyAgeModification, applyHighlights, applySnapshot, applyTreeDrop, attachTimelineInteractions, bottomDrawerCommandId, buildHighlightTargets, buildModel, captionForEntry, clearHighlights, collectContainerNames, collectDataResult, collectPanelIds, collectStackPaths, computeColour, computeIcicleLayout, computeLeafGeoms, computeTreemapLayout, createAcCompletionProvider, createDataListSearchAdapter, createDefaultListDragPreview, createElementIncrSearch, createElementListSearchAdapter, createEmptyLayout, createEmptyStack, createFuzzySearch, createIncrSearch, createPillRenderer, createSplit, createStack, createTreeListAdapter, createTreeListSearchAdapter, createVerticalListAdapter, distribute, dropTargetFor, extractStack, findIcicleNode, findIciclePath, findNode, findParentOf, findStackOf, findStackPathByName, findTreemapNode, findTreemapPath, getActiveDragPanelId, getIcon, getIconEntry, getIconFont, getLeafNeighbours, hasIcon, iconBus, init, insertBeside, isDragging, isMultiMode, isSplit, isStack, keyForElement, listItemFadeKeyframes, listSearchStyles, monitorIndeterminate, moveLeafNodeToEdge, moveLeafStep, normalise, normaliseValue, normalize, panelGapIndex, parseColourScaleAttr, parseLayout, pointerOverAnyHost, prefersReducedMotion, pruneDraggedDescendants, readBaseColour, registerFontIcon, registerIcon, registerListSearchCommands, removePanelFromStack, resolveCssVars, resolveGrid, resolveLeafPath, resolveTracks, serializeLayout, setActive, setIconFont, startListItemOutAnimation, svgToDataUri, swapLeaves, tickledItemStyles, tickledStyles, timelineStyles, toSnapshot, toolbarGapIndex, walk, wrapRoot };
48147
49945
 
48148
49946
  //# sourceMappingURL=index.js.map