@ixfx/components 0.5.19 → 0.6.0

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 (198) hide show
  1. package/bundle/index.d.ts +462 -210
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +8027 -6493
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +3 -3
  6. package/dist/ac-token-DVbmHmky.d.ts +107 -0
  7. package/dist/ac-token-DVbmHmky.d.ts.map +1 -0
  8. package/dist/ac-token.d.ts +2 -0
  9. package/dist/ac-token.js +646 -0
  10. package/dist/ac-token.js.map +1 -0
  11. package/dist/{button-CphdEaZd.js → button-Bn0BuLpO.js} +2 -3
  12. package/dist/{button-CphdEaZd.js.map → button-Bn0BuLpO.js.map} +1 -1
  13. package/dist/button.d.ts +1 -1
  14. package/dist/button.d.ts.map +1 -1
  15. package/dist/button.js +1 -1
  16. package/dist/checkbox.js +1 -1
  17. package/dist/{colour-picker-37NyVenk.js → colour-picker-0stHB90J.js} +18 -8
  18. package/dist/colour-picker-0stHB90J.js.map +1 -0
  19. package/dist/colour-picker.d.ts +1 -1
  20. package/dist/colour-picker.js +1 -1
  21. package/dist/crumbs.d.ts +2 -2
  22. package/dist/crumbs.js +1152 -1
  23. package/dist/crumbs.js.map +1 -0
  24. package/dist/data-controller-DOlmqNKb.js +171 -0
  25. package/dist/data-controller-DOlmqNKb.js.map +1 -0
  26. package/dist/data-display.js +1 -1
  27. package/dist/data-grid-BeAkORz2.d.ts +215 -0
  28. package/dist/data-grid-BeAkORz2.d.ts.map +1 -0
  29. package/dist/data-grid.d.ts +2 -0
  30. package/dist/data-grid.js +1225 -0
  31. package/dist/data-grid.js.map +1 -0
  32. package/dist/data-provider-BAn_-oR1.d.ts +61 -0
  33. package/dist/data-provider-BAn_-oR1.d.ts.map +1 -0
  34. package/dist/{defaults-BkWCPJFL.js → defaults-BCiDhZbF.js} +20 -3
  35. package/dist/defaults-BCiDhZbF.js.map +1 -0
  36. package/dist/drag-ghost-DtSDvjri.js +85 -0
  37. package/dist/drag-ghost-DtSDvjri.js.map +1 -0
  38. package/dist/editable-label.js +1 -1
  39. package/dist/{incr-search-2pz21xtR.js → element-search-Y8SRfPGM.js} +2 -133
  40. package/dist/element-search-Y8SRfPGM.js.map +1 -0
  41. package/dist/fallbacks-DEE1nCTt.js +406 -0
  42. package/dist/fallbacks-DEE1nCTt.js.map +1 -0
  43. package/dist/form-CsXJX15p.js +64 -0
  44. package/dist/form-CsXJX15p.js.map +1 -0
  45. package/dist/form.d.ts +15 -0
  46. package/dist/form.d.ts.map +1 -0
  47. package/dist/form.js +2 -0
  48. package/dist/grouped-item-lister-CNLMgdIr.d.ts +121 -0
  49. package/dist/grouped-item-lister-CNLMgdIr.d.ts.map +1 -0
  50. package/dist/grouped-item-lister.d.ts +2 -0
  51. package/dist/grouped-item-lister.js +177 -0
  52. package/dist/grouped-item-lister.js.map +1 -0
  53. package/dist/{icon-DG9Lm3LT.js → icons-Bm2ByQ3s.js} +6 -3
  54. package/dist/icons-Bm2ByQ3s.js.map +1 -0
  55. package/dist/icons.js +2 -8
  56. package/dist/incr-search-vCzuao-2.js +137 -0
  57. package/dist/incr-search-vCzuao-2.js.map +1 -0
  58. package/dist/incr-search.d.ts +1 -1
  59. package/dist/incr-search.js +2 -1
  60. package/dist/{index-BKAlRgbq.d.ts → index-BOUaDIW-.d.ts} +4 -1
  61. package/dist/index-BOUaDIW-.d.ts.map +1 -0
  62. package/dist/{index-D9u_Q7-b.d.ts → index-Cu5i8zZY.d.ts} +3 -3
  63. package/dist/{index-D9u_Q7-b.d.ts.map → index-Cu5i8zZY.d.ts.map} +1 -1
  64. package/dist/{index-DkhBGHgF.d.ts → index-ovq_GTdl.d.ts} +2 -2
  65. package/dist/{index-DkhBGHgF.d.ts.map → index-ovq_GTdl.d.ts.map} +1 -1
  66. package/dist/index.d.ts +54 -572
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +1898 -4253
  69. package/dist/index.js.map +1 -1
  70. package/dist/labelled-radial-input.d.ts +1 -1
  71. package/dist/labelled-radial-input.js +1 -2
  72. package/dist/labelled-radial-input.js.map +1 -1
  73. package/dist/led.d.ts +0 -1
  74. package/dist/led.d.ts.map +1 -1
  75. package/dist/led.js +2 -4
  76. package/dist/led.js.map +1 -1
  77. package/dist/menu-DIfU70AA.js +1609 -0
  78. package/dist/menu-DIfU70AA.js.map +1 -0
  79. package/dist/menu-item-BG5w7fi4.d.ts.map +1 -1
  80. package/dist/menu.d.ts +1 -1
  81. package/dist/menu.js +1 -2
  82. package/dist/miller.d.ts +3 -3
  83. package/dist/miller.js +3 -3
  84. package/dist/narrowed-text.d.ts.map +1 -1
  85. package/dist/narrowed-text.js +4 -4
  86. package/dist/narrowed-text.js.map +1 -1
  87. package/dist/notification-pill-DyZydXoZ.d.ts +68 -0
  88. package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -0
  89. package/dist/notifier.d.ts +2 -0
  90. package/dist/notifier.js +146 -0
  91. package/dist/notifier.js.map +1 -0
  92. package/dist/panel.js +1 -2
  93. package/dist/panel.js.map +1 -1
  94. package/dist/plots.js +1 -1
  95. package/dist/polar-pad.d.ts +1 -1
  96. package/dist/polar-pad.js +1 -1
  97. package/dist/{radial-input-BhZeyyP-.d.ts → radial-input-DXMN55Nz.d.ts} +2 -2
  98. package/dist/{radial-input-BhZeyyP-.d.ts.map → radial-input-DXMN55Nz.d.ts.map} +1 -1
  99. package/dist/{radial-input-CVxGH-Cp.js → radial-input-Dk8Wydp5.js} +4 -4
  100. package/dist/radial-input-Dk8Wydp5.js.map +1 -0
  101. package/dist/radial-input.d.ts +1 -1
  102. package/dist/radial-input.js +1 -1
  103. package/dist/range-input.d.ts +1 -1
  104. package/dist/range-input.js +1 -1
  105. package/dist/range.d.ts +1 -1
  106. package/dist/range.js +1 -1
  107. package/dist/scroll-fade-CAs1EabA.js +70 -0
  108. package/dist/scroll-fade-CAs1EabA.js.map +1 -0
  109. package/dist/select-horiz.d.ts +50 -0
  110. package/dist/select-horiz.d.ts.map +1 -0
  111. package/dist/select-horiz.js +263 -0
  112. package/dist/select-horiz.js.map +1 -0
  113. package/dist/{slider-input-CzmSVgm7.js → slider-input-CT4gcF-o.js} +2 -2
  114. package/dist/{slider-input-CzmSVgm7.js.map → slider-input-CT4gcF-o.js.map} +1 -1
  115. package/dist/{slider-input-TidGhvXt.d.ts → slider-input-XppH3vcy.d.ts} +2 -2
  116. package/dist/{slider-input-TidGhvXt.d.ts.map → slider-input-XppH3vcy.d.ts.map} +1 -1
  117. package/dist/slider-input.d.ts +1 -1
  118. package/dist/slider-input.js +1 -1
  119. package/dist/snackbar.d.ts +58 -0
  120. package/dist/snackbar.d.ts.map +1 -0
  121. package/dist/snackbar.js +265 -0
  122. package/dist/snackbar.js.map +1 -0
  123. package/dist/split-layout.js +1 -1
  124. package/dist/swipe.d.ts +1 -1
  125. package/dist/swipe.js +1 -1
  126. package/dist/tabs.js +533 -1
  127. package/dist/tabs.js.map +1 -0
  128. package/dist/{tickled-controller-BF2Ea0DE.d.ts → tickled-controller-BtevrRLV.d.ts} +8 -6
  129. package/dist/tickled-controller-BtevrRLV.d.ts.map +1 -0
  130. package/dist/{tickled-styles-fNDdqf6l.js → tickled-controller-DkAU-0qL.js} +19 -105
  131. package/dist/tickled-controller-DkAU-0qL.js.map +1 -0
  132. package/dist/tickled-styles-BrAHEj1q.js +89 -0
  133. package/dist/tickled-styles-BrAHEj1q.js.map +1 -0
  134. package/dist/transitory-label.d.ts +30 -0
  135. package/dist/transitory-label.d.ts.map +1 -0
  136. package/dist/transitory-label.js +249 -0
  137. package/dist/transitory-label.js.map +1 -0
  138. package/dist/{tree-BtiiDX1a.js → tree-BO6BXI2b.js} +4 -4
  139. package/dist/{tree-BtiiDX1a.js.map → tree-BO6BXI2b.js.map} +1 -1
  140. package/dist/{tree-component-DQ9vzdy5.d.ts → tree-component-BvV4muxx.d.ts} +2 -2
  141. package/dist/{tree-component-DQ9vzdy5.d.ts.map → tree-component-BvV4muxx.d.ts.map} +1 -1
  142. package/dist/tree.d.ts +3 -3
  143. package/dist/tree.js +1 -1
  144. package/dist/{types-DO3gt5vg.d.ts → types-Bc23SI94.d.ts} +3 -61
  145. package/dist/types-Bc23SI94.d.ts.map +1 -0
  146. package/dist/types-DlVNJez_.d.ts +41 -0
  147. package/dist/types-DlVNJez_.d.ts.map +1 -0
  148. package/dist/vertical-list.d.ts +122 -0
  149. package/dist/vertical-list.d.ts.map +1 -0
  150. package/dist/vertical-list.js +737 -0
  151. package/dist/vertical-list.js.map +1 -0
  152. package/dist/wheel-nudge-BlSCe_hD.js.map +1 -1
  153. package/dist/{wheel-nudge-DgMTRYlh.d.ts → wheel-nudge-DGrNzWuE.d.ts} +3 -3
  154. package/dist/wheel-nudge-DGrNzWuE.d.ts.map +1 -0
  155. package/dist/{xy-axis-CxHC8z5E.js → xy-axis-B6yMjckW.js} +3 -109
  156. package/dist/xy-axis-B6yMjckW.js.map +1 -0
  157. package/dist/xy-pad.d.ts +1 -1
  158. package/dist/xy-pad.js +1 -1
  159. package/docs-user/README.md +3 -2
  160. package/docs-user/ac-token.md +7 -1
  161. package/docs-user/colour-picker.md +8 -4
  162. package/docs-user/data-grid.md +248 -0
  163. package/docs-user/index.json +217 -0
  164. package/docs-user/llms.txt +57 -0
  165. package/docs-user/menu.md +11 -8
  166. package/docs-user/rating.md +102 -0
  167. package/llms.txt +57 -0
  168. package/package.json +21 -11
  169. package/dist/colour-picker-37NyVenk.js.map +0 -1
  170. package/dist/crumb-navigation-BrB0r14u.js +0 -1220
  171. package/dist/crumb-navigation-BrB0r14u.js.map +0 -1
  172. package/dist/defaults-BkWCPJFL.js.map +0 -1
  173. package/dist/fallbacks-DPgPEqo8.js +0 -218
  174. package/dist/fallbacks-DPgPEqo8.js.map +0 -1
  175. package/dist/icon-DG9Lm3LT.js.map +0 -1
  176. package/dist/icons.js.map +0 -1
  177. package/dist/incr-search-2pz21xtR.js.map +0 -1
  178. package/dist/index-BKAlRgbq.d.ts.map +0 -1
  179. package/dist/interaction-D6efrBLo.js +0 -1
  180. package/dist/menu-CdwSe_XN.js +0 -825
  181. package/dist/menu-CdwSe_XN.js.map +0 -1
  182. package/dist/menu-item-CrmUwIoJ.js +0 -782
  183. package/dist/menu-item-CrmUwIoJ.js.map +0 -1
  184. package/dist/radial-input-CVxGH-Cp.js.map +0 -1
  185. package/dist/registry-CkW7q09Q.js +0 -21
  186. package/dist/registry-CkW7q09Q.js.map +0 -1
  187. package/dist/selecthorizontal.d.ts +0 -15
  188. package/dist/selecthorizontal.d.ts.map +0 -1
  189. package/dist/selecthorizontal.js +0 -43
  190. package/dist/selecthorizontal.js.map +0 -1
  191. package/dist/tab-list-mAoD6L0e.js +0 -615
  192. package/dist/tab-list-mAoD6L0e.js.map +0 -1
  193. package/dist/tickled-controller-BF2Ea0DE.d.ts.map +0 -1
  194. package/dist/tickled-styles-fNDdqf6l.js.map +0 -1
  195. package/dist/types-DO3gt5vg.d.ts.map +0 -1
  196. package/dist/wheel-nudge-DgMTRYlh.d.ts.map +0 -1
  197. package/dist/xy-axis-CxHC8z5E.js.map +0 -1
  198. package/docs-user/selecthorizontal.md +0 -32
@@ -1,615 +0,0 @@
1
- import { t as themeFallbacks } from "./fallbacks-DPgPEqo8.js";
2
- import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
- import { LitElement, css, html, nothing } from "lit";
4
- import { property } from "lit/decorators.js";
5
- //#region src/util/drag-ghost.ts
6
- /**
7
- * Theme-aware floating element helper.
8
- *
9
- * Creates a `position: fixed`, `pointer-events: none` element anchored to a
10
- * source element's theme container, then exposes imperative `move` / `destroy`
11
- * hooks. Used by `ixfx-tab-list` for its drag-ghost; intended to be reusable
12
- * by future drag/detach features.
13
- *
14
- * Theme container lookup mirrors `tooltip-controller.ts` so the floating
15
- * element still inherits the right CSS custom properties when the source lives
16
- * inside a `.theme-dark` / `.theme-light` subtree (used by the loader iframes).
17
- */
18
- let stylesInjected = false;
19
- function injectGhostStyles() {
20
- if (stylesInjected) return;
21
- stylesInjected = true;
22
- const style = document.createElement(`style`);
23
- style.textContent = `
24
- .ixfx-drag-ghost {
25
- position: fixed;
26
- top: 0;
27
- left: 0;
28
- pointer-events: none;
29
- z-index: 10000;
30
- will-change: transform;
31
- opacity: 0.9;
32
- display: inline-flex;
33
- align-items: center;
34
- gap: var(--space-xs, 4px);
35
- padding: var(--padding, var(--space-m, 8px)) calc(2 * var(--padding, var(--space-m, 8px)));
36
- background: var(--surface-4);
37
- color: var(--surface-4-text);
38
- border: 1px solid var(--border-subtle);
39
- border-radius: var(--radius-m, 6px);
40
- font-family: inherit;
41
- font-size: inherit;
42
- font-weight: 500;
43
- white-space: nowrap;
44
- max-width: 240px;
45
- overflow: hidden;
46
- text-overflow: ellipsis;
47
- box-shadow: var(--shadow-m);
48
- }
49
- .ixfx-drag-ghost ixfx-icon {
50
- flex-shrink: 0;
51
- }
52
- `;
53
- document.head.appendChild(style);
54
- }
55
- /**
56
- * Create a theme-aware floating ghost element.
57
- *
58
- * The ghost is appended to the closest `.theme-dark` / `.theme-light` ancestor
59
- * of `anchor`, falling back to `document.body`. This preserves CSS variable
60
- * inheritance for theming.
61
- */
62
- function createDragGhost(opts) {
63
- injectGhostStyles();
64
- const ghost = document.createElement(`div`);
65
- ghost.className = `ixfx-drag-ghost`;
66
- if (opts.className) ghost.classList.add(opts.className);
67
- ghost.appendChild(opts.content);
68
- ghost.style.transform = `translate3d(-9999px, -9999px, 0)`;
69
- const targetDoc = opts.anchor.ownerDocument;
70
- const themeContainer = opts.anchor.closest(`.theme-dark, .theme-light`);
71
- if (themeContainer) themeContainer.appendChild(ghost);
72
- else targetDoc.body.appendChild(ghost);
73
- const anchorRect = opts.anchor.getBoundingClientRect();
74
- const offsetX = anchorRect.width / 2;
75
- const offsetY = anchorRect.height / 2;
76
- return {
77
- element: ghost,
78
- move(x, y) {
79
- ghost.style.transform = `translate3d(${x - offsetX}px, ${y - offsetY}px, 0)`;
80
- },
81
- destroy() {
82
- ghost.remove();
83
- }
84
- };
85
- }
86
- //#endregion
87
- //#region src/tabs/tab-list.ts
88
- /** Pointer movement threshold (px) before a press becomes a drag. */
89
- const DRAG_THRESHOLD_PX = 5;
90
- let TabListElement = class TabListElement extends LitElement {
91
- constructor(..._args) {
92
- super(..._args);
93
- this.orientation = `horizontal`;
94
- this.flip = false;
95
- this.scrollable = false;
96
- this.hideLabels = false;
97
- this.dragMode = `off`;
98
- this.#items = [];
99
- this.#dragState = null;
100
- this.#suppressNextClick = false;
101
- this.#onSlotChange = () => {
102
- this.updateComplete.then(() => {
103
- this.#items = (this.shadowRoot?.querySelector(`slot`))?.assignedElements({ flatten: true }) ?? [];
104
- this.#syncIndicatorColors();
105
- this.#syncHideLabels();
106
- });
107
- };
108
- this.#onKeyUp = (event) => {
109
- const key = event.key;
110
- if (this.#isVertical) {
111
- if (key === `ArrowUp`) this.#selectPrevious();
112
- else if (key === `ArrowDown`) this.#selectNext();
113
- } else if (key === `ArrowRight`) this.#selectNext();
114
- else if (key === `ArrowLeft`) this.#selectPrevious();
115
- };
116
- this.#onKeyDown = (event) => {
117
- const state = this.#dragState;
118
- if (event.key !== `Escape` || !state?.active) return;
119
- event.preventDefault();
120
- const pointerId = state.pointerId;
121
- this.#abortDrag();
122
- this.#endDrag(pointerId);
123
- };
124
- this.#onWheel = (event) => {
125
- if (!this.scrollable) return;
126
- const el = this.#containerEl;
127
- if (!el) return;
128
- if (!this.#isVertical) {
129
- if (event.deltaY === 0 || el.scrollWidth <= el.clientWidth) return;
130
- const prev = el.scrollLeft;
131
- el.scrollLeft = prev + event.deltaY;
132
- if (el.scrollLeft !== prev) event.preventDefault();
133
- } else {
134
- if (event.deltaX === 0 || el.scrollHeight <= el.clientHeight) return;
135
- const prev = el.scrollTop;
136
- el.scrollTop = prev + event.deltaX;
137
- if (el.scrollTop !== prev) event.preventDefault();
138
- }
139
- };
140
- this.#onSlotClick = (event) => {
141
- if (this.#suppressNextClick) {
142
- this.#suppressNextClick = false;
143
- event.preventDefault();
144
- event.stopPropagation();
145
- return;
146
- }
147
- this.focus();
148
- const t = event.target.closest(`ixfx-tab-list-item`);
149
- if (!t) return;
150
- const previous = this.getSelectedElement();
151
- this.selectElement(t);
152
- const forId = t.getAttribute(`for`);
153
- const previousId = previous?.id;
154
- this.dispatchEvent(new CustomEvent(`change`, {
155
- bubbles: true,
156
- detail: {
157
- previous: previousId,
158
- selected: t.id,
159
- for: forId ?? ``
160
- }
161
- }));
162
- };
163
- this.#onPointerDown = (event) => {
164
- if (this.dragMode !== `reorder`) return;
165
- if (event.button !== 0) return;
166
- const target = this.#findDragTarget(event);
167
- if (!target) return;
168
- const fromIndex = this.#items.indexOf(target);
169
- if (fromIndex < 0) return;
170
- this.#dragState = {
171
- pointerId: event.pointerId,
172
- source: target,
173
- fromIndex,
174
- startX: event.clientX,
175
- startY: event.clientY,
176
- active: false,
177
- ghost: null,
178
- gapIndex: void 0
179
- };
180
- window.addEventListener(`pointermove`, this.#onPointerMove);
181
- window.addEventListener(`pointerup`, this.#onPointerUp);
182
- window.addEventListener(`pointercancel`, this.#onPointerCancel);
183
- };
184
- this.#onPointerMove = (event) => {
185
- const state = this.#dragState;
186
- if (!state || event.pointerId !== state.pointerId) return;
187
- const dx = event.clientX - state.startX;
188
- const dy = event.clientY - state.startY;
189
- const distance = Math.hypot(dx, dy);
190
- if (!state.active) {
191
- if (distance < DRAG_THRESHOLD_PX) return;
192
- this.#beginDrag(event);
193
- }
194
- state.ghost?.move(event.clientX, event.clientY);
195
- const gap = this.#computeGapIndex(event.clientX, event.clientY);
196
- if (gap !== state.gapIndex) {
197
- state.gapIndex = gap;
198
- this.requestUpdate();
199
- }
200
- };
201
- this.#onPointerUp = (event) => {
202
- const state = this.#dragState;
203
- if (!state || event.pointerId !== state.pointerId) return;
204
- if (state.active) {
205
- const gap = this.#computeGapIndex(event.clientX, event.clientY);
206
- this.#commitDrag(state.source, state.fromIndex, gap);
207
- }
208
- this.#endDrag(event.pointerId);
209
- };
210
- this.#onPointerCancel = (event) => {
211
- const state = this.#dragState;
212
- if (!state || event.pointerId !== state.pointerId) return;
213
- this.#abortDrag();
214
- this.#endDrag(event.pointerId);
215
- };
216
- }
217
- #items;
218
- #dragState;
219
- #suppressNextClick;
220
- get #isVertical() {
221
- return this.orientation === `vertical-stack` || this.orientation === `vertical-side`;
222
- }
223
- get #containerClass() {
224
- const base = this.scrollable ? `${this.orientation} scrollable` : this.orientation;
225
- return this.dragMode === `reorder` ? `${base} reorder` : base;
226
- }
227
- render() {
228
- const caretStyle = this.#computeCaretStyle();
229
- return html`
230
- <div
231
- tabindex=0
232
- @keyup=${this.#onKeyUp}
233
- @click=${this.#onSlotClick}
234
- @pointerdown=${this.#onPointerDown}
235
- @keydown=${this.#onKeyDown}
236
- @wheel=${this.#onWheel}
237
- id="container"
238
- class=${this.#containerClass}
239
- >
240
- <slot @slotchange=${this.#onSlotChange}></slot>
241
- ${caretStyle ? html`<div class="drop-caret" style=${caretStyle}></div>` : nothing}
242
- </div>`;
243
- }
244
- #onSlotChange;
245
- firstUpdated() {
246
- this.updateComplete.then(() => {
247
- if (this.#items.length > 0) {
248
- this.#syncIndicatorColors();
249
- this.#syncHideLabels();
250
- }
251
- });
252
- }
253
- updated(changedProperties) {
254
- super.updated(changedProperties);
255
- this.classList.toggle(`scrollable`, this.scrollable);
256
- if (changedProperties.has(`dragMode`)) this.toggleAttribute(`drag-mode`, this.dragMode !== `off`);
257
- if (changedProperties.has(`hideLabels`)) this.#syncHideLabels();
258
- }
259
- #syncHideLabels() {
260
- for (const item of this.#items) if (this.hideLabels) item.setAttribute(`hide-labels`, ``);
261
- else item.removeAttribute(`hide-labels`);
262
- }
263
- #syncIndicatorColors() {
264
- for (const item of this.#items) {
265
- item.style.setProperty(`--indicator-color-bottom`, `transparent`);
266
- item.style.setProperty(`--indicator-color-top`, `transparent`);
267
- item.style.setProperty(`--indicator-color-left`, `transparent`);
268
- item.style.setProperty(`--indicator-color-right`, `transparent`);
269
- if (item.hasAttribute(`selected`)) {
270
- if (this.orientation === `horizontal` && !this.flip) item.style.setProperty(`--indicator-color-bottom`, `var(--accent)`);
271
- else if (this.orientation === `horizontal` && this.flip) item.style.setProperty(`--indicator-color-top`, `var(--accent)`);
272
- else if (this.#isVertical && !this.flip) item.style.setProperty(`--indicator-color-right`, `var(--accent)`);
273
- else if (this.#isVertical && this.flip) item.style.setProperty(`--indicator-color-left`, `var(--accent)`);
274
- }
275
- }
276
- }
277
- #onKeyUp;
278
- #onKeyDown;
279
- /**
280
- * Translate vertical wheel deltas into horizontal scroll on a scrollable
281
- * horizontal list (and vice-versa for vertical lists). Without this, the
282
- * default browser behaviour only scrolls horizontally with Shift+wheel or a
283
- * physical horizontal wheel — neither of which most users reach for on a
284
- * VS Code-style tab strip.
285
- *
286
- * Only kicks in when the list is actually scrollable (overflow content
287
- * present), and is a no-op when nothing is scrollable in that direction.
288
- */
289
- #onWheel;
290
- getSelectedElement() {
291
- for (const el of this.#items) if (this.#isSelected(el)) return el;
292
- const slot = this.shadowRoot?.querySelector(`slot`);
293
- if (slot) {
294
- const els = slot.assignedElements({ flatten: true });
295
- for (const el of els) if (this.#isSelected(el)) return el;
296
- }
297
- }
298
- #isSelected(el) {
299
- if (el.getAttribute(`selected`) === null) return false;
300
- return el.hasAttribute(`selected`);
301
- }
302
- selectElement(el) {
303
- const existing = this.getSelectedElement();
304
- if (existing) {
305
- existing.removeAttribute(`selected`);
306
- existing.style.setProperty(`--indicator-color-bottom`, `transparent`);
307
- existing.style.setProperty(`--indicator-color-top`, `transparent`);
308
- existing.style.setProperty(`--indicator-color-left`, `transparent`);
309
- existing.style.setProperty(`--indicator-color-right`, `transparent`);
310
- }
311
- el.setAttribute(`selected`, ``);
312
- if (this.orientation === `horizontal` && !this.flip) el.style.setProperty(`--indicator-color-bottom`, `var(--accent)`);
313
- else if (this.orientation === `horizontal` && this.flip) el.style.setProperty(`--indicator-color-top`, `var(--accent)`);
314
- else if (this.#isVertical && !this.flip) el.style.setProperty(`--indicator-color-right`, `var(--accent)`);
315
- else if (this.#isVertical && this.flip) el.style.setProperty(`--indicator-color-left`, `var(--accent)`);
316
- }
317
- #selectNext() {
318
- let found = false;
319
- for (const el of this.#items) if (this.#isSelected(el) && !found) found = true;
320
- else if (found) {
321
- this.selectElement(el);
322
- break;
323
- }
324
- }
325
- #selectPrevious() {
326
- let prev;
327
- for (const el of this.#items) if (this.#isSelected(el) && prev) this.selectElement(prev);
328
- else prev = el;
329
- }
330
- #onSlotClick;
331
- /**
332
- * Walk composedPath looking for the nearest ancestor tab-list-item, but bail
333
- * if the path goes through a `.close-btn` or `.toolbar` (so close/toolbar
334
- * buttons always win — same delegation pattern used by tooltip-controller).
335
- */
336
- #findDragTarget(event) {
337
- if (this.dragMode === `off`) return null;
338
- const path = event.composedPath();
339
- let item = null;
340
- for (const node of path) {
341
- if (!(node instanceof HTMLElement)) continue;
342
- if (node.classList.contains(`close-btn`) || node.classList.contains(`toolbar`)) return null;
343
- if (!item && node.tagName === `IXFX-TAB-LIST-ITEM`) item = node;
344
- }
345
- return item;
346
- }
347
- #onPointerDown;
348
- #onPointerMove;
349
- #onPointerUp;
350
- #onPointerCancel;
351
- #beginDrag(event) {
352
- const state = this.#dragState;
353
- if (!state || state.active) return;
354
- try {
355
- this.#containerEl?.setPointerCapture(event.pointerId);
356
- } catch {}
357
- state.active = true;
358
- state.source.setAttribute(`drag-source`, ``);
359
- state.ghost = this.#createGhost(state.source);
360
- if (state.ghost) state.ghost.move(event.clientX, event.clientY);
361
- }
362
- #abortDrag() {
363
- const state = this.#dragState;
364
- if (!state) return;
365
- state.source.removeAttribute(`drag-source`);
366
- if (state.gapIndex !== void 0) {
367
- state.gapIndex = void 0;
368
- this.requestUpdate();
369
- }
370
- }
371
- #endDrag(pointerId) {
372
- const state = this.#dragState;
373
- if (!state) return;
374
- state.ghost?.destroy();
375
- state.ghost = null;
376
- this.#dragState = null;
377
- window.removeEventListener(`pointermove`, this.#onPointerMove);
378
- window.removeEventListener(`pointerup`, this.#onPointerUp);
379
- window.removeEventListener(`pointercancel`, this.#onPointerCancel);
380
- try {
381
- this.#containerEl?.releasePointerCapture(pointerId);
382
- } catch {}
383
- this.requestUpdate();
384
- }
385
- #commitDrag(source, fromIndex, gapIndex) {
386
- source.removeAttribute(`drag-source`);
387
- const siblings = this.#items.filter((el) => el !== source);
388
- const target = gapIndex === void 0 ? siblings.length : Math.max(0, Math.min(gapIndex, siblings.length));
389
- const parent = source.parentNode;
390
- if (!parent) return;
391
- const ref = siblings[target] ?? null;
392
- parent.insertBefore(source, ref);
393
- const toIndex = Array.prototype.indexOf.call(parent.children, source);
394
- if (toIndex === fromIndex) return;
395
- this.#items = (this.shadowRoot?.querySelector(`slot`))?.assignedElements({ flatten: true }) ?? [];
396
- this.#syncIndicatorColors();
397
- this.#suppressNextClick = true;
398
- this.dispatchEvent(new CustomEvent(`reorder`, {
399
- bubbles: true,
400
- detail: {
401
- id: source.id,
402
- fromIndex,
403
- toIndex
404
- }
405
- }));
406
- }
407
- #createGhost(source) {
408
- const content = document.createElement(`span`);
409
- content.style.display = `inline-flex`;
410
- content.style.alignItems = `center`;
411
- content.style.gap = `var(--space-xs, 4px)`;
412
- content.style.minWidth = `0`;
413
- const iconName = source.iconName;
414
- if (iconName) {
415
- const icon = document.createElement(`ixfx-icon`);
416
- icon.name = iconName;
417
- content.appendChild(icon);
418
- }
419
- const label = document.createElement(`span`);
420
- label.textContent = (source.textContent ?? ``).trim();
421
- label.style.overflow = `hidden`;
422
- label.style.textOverflow = `ellipsis`;
423
- label.style.whiteSpace = `nowrap`;
424
- content.appendChild(label);
425
- try {
426
- return createDragGhost({
427
- anchor: source,
428
- content
429
- });
430
- } catch {
431
- return null;
432
- }
433
- }
434
- /**
435
- * Compute the index of the gap nearest the pointer, ignoring the source item.
436
- * Returns 0..#items.length-1; undefined if no siblings.
437
- *
438
- * Per the plan: drag-mode="reorder" has "no sense of breaking out", so the
439
- * perpendicular axis is ignored — the pointer always resolves to some gap.
440
- */
441
- #computeGapIndex(clientX, clientY) {
442
- const state = this.#dragState;
443
- if (!state) return void 0;
444
- const siblings = this.#items.filter((el) => el !== state.source);
445
- if (siblings.length === 0) return 0;
446
- const useX = !this.#isVertical;
447
- let bestGap = 0;
448
- let bestDist = Infinity;
449
- for (let i = 0; i < siblings.length; i++) {
450
- const rect = siblings[i].getBoundingClientRect();
451
- const start = useX ? rect.left : rect.top;
452
- const end = useX ? rect.right : rect.bottom;
453
- const mid = (start + end) / 2;
454
- const pos = useX ? clientX : clientY;
455
- const dStart = Math.abs(pos - start);
456
- Math.abs(pos - mid);
457
- const dEnd = Math.abs(pos - end);
458
- if (pos < mid) {
459
- if (dStart < bestDist) {
460
- bestDist = dStart;
461
- bestGap = i;
462
- }
463
- } else if (dEnd < bestDist) {
464
- bestDist = dEnd;
465
- bestGap = i + 1;
466
- }
467
- }
468
- return bestGap;
469
- }
470
- #computeCaretStyle() {
471
- const state = this.#dragState;
472
- if (!state?.active || state.gapIndex === void 0) return void 0;
473
- const siblings = this.#items.filter((el) => el !== state.source);
474
- if (siblings.length === 0) return void 0;
475
- const useX = !this.#isVertical;
476
- const containerRect = this.#containerEl?.getBoundingClientRect();
477
- if (!containerRect) return void 0;
478
- const gap = Math.max(0, Math.min(state.gapIndex, siblings.length));
479
- let rect = null;
480
- if (gap < siblings.length) rect = siblings[gap].getBoundingClientRect();
481
- else rect = siblings[siblings.length - 1].getBoundingClientRect();
482
- if (useX) {
483
- const x = (gap < siblings.length ? rect.left : rect.right) - containerRect.left;
484
- const y = 0;
485
- const h = containerRect.height;
486
- const w = 2;
487
- return `transform: translate(${x - w / 2}px, ${y}px); width: ${w}px; height: ${h}px;`;
488
- } else {
489
- const y = (gap < siblings.length ? rect.top : rect.bottom) - containerRect.top;
490
- const x = 0;
491
- const w = containerRect.width;
492
- const h = 2;
493
- return `transform: translate(${x}px, ${y - h / 2}px); width: ${w}px; height: ${h}px;`;
494
- }
495
- }
496
- get #containerEl() {
497
- return this.shadowRoot?.getElementById(`container`) ?? null;
498
- }
499
- static {
500
- this.styles = [themeFallbacks, css`
501
- :host {
502
- display: inline-block;
503
- --activated-colour: var(--accent);
504
- --colour: var(--surface-3-text);
505
- --scroll-max-height: 200px;
506
- --allow-overflow: hidden;
507
- color: var(--colour);
508
- border: var(--border, none);
509
- border-color: var(--surface-5);
510
- border-radius: var(--radius-l, 8px) var(--radius-l, 8px) 0 0;
511
-
512
- }
513
- :host(.scrollable) {
514
- max-height: var(--scroll-max-height);
515
- }
516
- :host([hide-labels]) {
517
- display: inline-flex;
518
- width: auto;
519
- }
520
- text {
521
- user-select:none;
522
- }
523
- #container {
524
- display:flex;
525
- position: relative;
526
- }
527
- #container.horizontal {
528
- flex-direction: row;
529
- overflow: hidden;
530
- }
531
- #container.horizontal.scrollable {
532
- overflow-x: auto;
533
- --allow-overflow: visible;
534
- }
535
- #container.horizontal.scrollable ::slotted(ixfx-tab-list-item) {
536
- flex-shrink: 0;
537
- }
538
- #container.vertical-stack {
539
- flex-direction: column;
540
- }
541
- #container.vertical-stack.flip {
542
- flex-direction: column-reverse;
543
- }
544
- #container.vertical-stack.scrollable {
545
- overflow-y: auto;
546
- max-height: var(--scroll-max-height);
547
- --allow-overflow: visible;
548
- }
549
- #container.vertical-side {
550
- flex-direction: column;
551
- }
552
- #container.vertical-side.flip {
553
- flex-direction: column-reverse;
554
- }
555
- #container.vertical-side.scrollable {
556
- overflow-y: auto;
557
- max-height: var(--scroll-max-height);
558
- --allow-overflow: visible;
559
- }
560
-
561
- ::slotted(ixfx-tab-list-item) {
562
- flex: 1 1 auto;
563
- min-width: 0;
564
- }
565
-
566
- #container.vertical-side ::slotted(ixfx-tab-list-item) {
567
- writing-mode: vertical-lr;
568
- text-orientation: mixed;
569
- }
570
- #container.vertical-side.flip ::slotted(ixfx-tab-list-item) {
571
- writing-mode: vertical-rl;
572
- text-orientation: mixed;
573
- }
574
-
575
- /* Drag affordances — opt-in via drag-mode="reorder" on the host (list). */
576
- #container.reorder ::slotted(ixfx-tab-list-item) {
577
- cursor: grab;
578
- }
579
- :host([drag-mode]) ::slotted(ixfx-tab-list-item[drag-source]) {
580
- cursor: grabbing;
581
- opacity: 0.4;
582
- transition: opacity var(--transition, 0.15s ease-out);
583
- }
584
-
585
- /* Insertion caret shown during an active drag. */
586
- .drop-caret {
587
- position: absolute;
588
- background: var(--accent);
589
- border-radius: 1px;
590
- pointer-events: none;
591
- z-index: 1;
592
- }
593
-
594
- ::slotted(.activated) {
595
- --colour: var(--activated-colour);
596
- }
597
- `];
598
- }
599
- };
600
- __decorate([property({ type: String })], TabListElement.prototype, "orientation", void 0);
601
- __decorate([property({ type: Boolean })], TabListElement.prototype, "flip", void 0);
602
- __decorate([property({ type: Boolean })], TabListElement.prototype, "scrollable", void 0);
603
- __decorate([property({
604
- type: Boolean,
605
- attribute: `hide-labels`
606
- })], TabListElement.prototype, "hideLabels", void 0);
607
- __decorate([property({
608
- type: String,
609
- attribute: `drag-mode`
610
- })], TabListElement.prototype, "dragMode", void 0);
611
- TabListElement = __decorate([safeCustomElement(`ixfx-tab-list`)], TabListElement);
612
- //#endregion
613
- export { TabListElement as t };
614
-
615
- //# sourceMappingURL=tab-list-mAoD6L0e.js.map