@ixfx/components 0.15.4 → 0.16.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 (101) hide show
  1. package/bundle/index.d.ts +1223 -48
  2. package/bundle/index.js +875 -700
  3. package/dist/ac-text.d.ts +1 -1
  4. package/dist/{ac-token-Cq7lsYf-.d.ts → ac-token-qEs3FsQv.d.ts} +1 -1
  5. package/dist/ac-token.d.ts +1 -1
  6. package/dist/colour-picker.d.ts +1 -1
  7. package/dist/crumb-navigation-BbqfmkYs.d.ts +147 -0
  8. package/dist/crumb-navigation-YnFVFqrx.js +1290 -0
  9. package/dist/crumbs.d.ts +2 -115
  10. package/dist/crumbs.js +1 -1179
  11. package/dist/{data-grid-CbiubdG2.d.ts → data-grid-CIG2DVip.d.ts} +58 -9
  12. package/dist/{data-grid-Dx3l3dxw.js → data-grid-rMkLX2qo.js} +630 -215
  13. package/dist/data-grid.d.ts +3 -3
  14. package/dist/data-grid.js +1 -1
  15. package/dist/{detail-list-ClkMV0SN.d.ts → detail-list-6iMTNP4N.d.ts} +35 -5
  16. package/dist/{detail-list-q8bs67BM.js → detail-list-C4pDSoI8.js} +218 -7
  17. package/dist/detail-list.d.ts +4 -4
  18. package/dist/detail-list.js +1 -1
  19. package/dist/{flat-list-0xTZdXzh.d.ts → flat-list-JPgQSmLW.d.ts} +28 -5
  20. package/dist/flat-list.d.ts +2 -2
  21. package/dist/flat-list.js +123 -4
  22. package/dist/{grid-list-y6dWJYu3.js → grid-list-CdEkScn-.js} +276 -75
  23. package/dist/{grid-list-BnWJUIBC.d.ts → grid-list-D6n7WH8l.d.ts} +128 -22
  24. package/dist/grid-list.d.ts +3 -3
  25. package/dist/grid-list.js +1 -1
  26. package/dist/{grouped-item-lister-Bhyo-dkH.d.ts → grouped-item-lister-DETte0Dh.d.ts} +1 -1
  27. package/dist/grouped-item-lister.d.ts +1 -1
  28. package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +1 -1
  29. package/dist/icons.d.ts +2 -2
  30. package/dist/incr-search.d.ts +1 -1
  31. package/dist/index-9ttcdwlL.d.ts +71 -0
  32. package/dist/{index-BAuqR9El.d.ts → index-Bx0BXPxI.d.ts} +52 -6
  33. package/dist/index-CYRc6Dah.d.ts +475 -0
  34. package/dist/{index-garxxqgV.d.ts → index-CYndvTWH.d.ts} +1 -1
  35. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +1 -1
  36. package/dist/{index-Bz3loIAf.d.ts → index-DN2BWctP.d.ts} +1 -1
  37. package/dist/{index-BPTuCRGb.d.ts → index-Dr80Zdl6.d.ts} +2 -2
  38. package/dist/{index-cnaRPQPp.d.ts → index-DxyyVqzA.d.ts} +2 -2
  39. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +1 -1
  40. package/dist/index.d.ts +380 -33
  41. package/dist/index.js +2247 -866
  42. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +1 -1
  43. package/dist/labelled-radial-input.d.ts +2 -2
  44. package/dist/labelled-range-input.d.ts +1 -1
  45. package/dist/labelled-slider-input.d.ts +1 -1
  46. package/dist/list-group-header.d.ts +1 -1
  47. package/dist/{list-native-drag-controller-O2Nruqpi.d.ts → list-native-drag-controller-D_UrXipS.d.ts} +1 -1
  48. package/dist/{list-selection-controller-BeE70lbB.js → list-selection-controller-5L0Nj9tR.js} +87 -2
  49. package/dist/{menu-item-B0zqw2xp.d.ts → menu-item-bF6narIz.d.ts} +1 -1
  50. package/dist/menu.d.ts +2 -2
  51. package/dist/miller-BFRfn0ve.js +2237 -0
  52. package/dist/miller.d.ts +4 -437
  53. package/dist/miller.js +1 -1815
  54. package/dist/panel.d.ts +1 -1
  55. package/dist/pending-BGidHppL.js +91 -0
  56. package/dist/scroll-hover-guard-Cjw6179Q.js +35 -0
  57. package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-CophkNeU.d.ts} +42 -4
  58. package/dist/{split-layout-Deoxy47d.js → split-layout-DTY4PJRp.js} +251 -19
  59. package/dist/split-layout.d.ts +1 -1
  60. package/dist/split-layout.js +1 -1
  61. package/dist/sunburst-tree.d.ts +2 -0
  62. package/dist/sunburst-tree.js +2 -0
  63. package/dist/sunbursttree-list-B_VxOHlo.js +1556 -0
  64. package/dist/sunbursttree-list-D6j5BxVQ.d.ts +303 -0
  65. package/dist/{tab-list-wC0xNz1b.d.ts → tab-list-Df371rqw.d.ts} +1 -1
  66. package/dist/tabs.d.ts +1 -1
  67. package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +1 -1
  68. package/dist/titlebar.d.ts +1 -1
  69. package/dist/tree-CftHwtEb.js +146 -0
  70. package/dist/{tree-D8VxvR9u.js → tree-Crdpl4nc.js} +275 -47
  71. package/dist/{tree-component-C6UHO-w9.d.ts → tree-component-DgfkxmVY.d.ts} +19 -8
  72. package/dist/tree.d.ts +3 -3
  73. package/dist/tree.js +1 -1
  74. package/dist/types-LU1u0CB8.d.ts +87 -0
  75. package/dist/vertical-list-1V1Vg2O5.js +1993 -0
  76. package/dist/{vertical-list-B8FoU-pU.d.ts → vertical-list-BPDmZx6T.d.ts} +31 -3
  77. package/dist/vertical-list.d.ts +3 -3
  78. package/dist/vertical-list.js +1 -1789
  79. package/dist/view-state-controller-BdyXWUUM.js +305 -0
  80. package/docs-user/README.md +3 -0
  81. package/docs-user/crumbs.md +27 -0
  82. package/docs-user/data-grid.md +77 -5
  83. package/docs-user/detail-list.md +54 -0
  84. package/docs-user/dock.md +54 -12
  85. package/docs-user/flat-list.md +27 -0
  86. package/docs-user/grid-list.md +64 -11
  87. package/docs-user/hyperbolic-tree.md +31 -4
  88. package/docs-user/icicle-tree.md +36 -0
  89. package/docs-user/index.json +17 -2
  90. package/docs-user/llms.txt +3 -0
  91. package/docs-user/miller.md +52 -21
  92. package/docs-user/multicol-list.md +50 -8
  93. package/docs-user/split-layout.md +45 -17
  94. package/docs-user/sunburst-tree.md +223 -0
  95. package/docs-user/tree.md +46 -7
  96. package/docs-user/treemap.md +32 -0
  97. package/docs-user/twosplit-layout.md +22 -0
  98. package/docs-user/user-catalog.md +1 -1
  99. package/docs-user/vertical-list.md +55 -7
  100. package/llms.txt +3 -0
  101. package/package.json +5 -1
package/dist/crumbs.js CHANGED
@@ -1,1180 +1,2 @@
1
- import { t as TickledController } from "./tickled-controller-D-HZymaZ.js";
2
- import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
3
- import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
4
- import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
5
- import "./interaction-E-uMGHkJ.js";
6
- import "./menu-item-BUv8An2k.js";
7
- import { t as collectDataResult } from "./data-provider-35TyWclX.js";
8
- import { t as scrollFadeStyles } from "./scroll-fade-Xx28D7mH.js";
9
- import "./narrowed-text.js";
10
- import { LitElement, css, html, nothing } from "lit";
11
- import { property, state } from "lit/decorators.js";
12
- //#region src/crumbs/crumb-navigation.ts
13
- /** Menu / suggestion order: by label, without mutating the tree's own order. */
14
- function sortNodesByLabel(nodes) {
15
- return [...nodes].sort((a, b) => (a.item.label ?? ``).localeCompare(b.item.label ?? ``));
16
- }
17
- let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
18
- constructor(..._args) {
19
- super(..._args);
20
- this._selectedNodes = /* @__PURE__ */ new Set();
21
- this.exclusivity = `none`;
22
- this.selectionFilter = `leaf`;
23
- this._openIdx = -1;
24
- this._isFocused = false;
25
- this._menuOpen = false;
26
- this._focusOnNarrowedText = false;
27
- this.inputMode = ``;
28
- this.noTruncate = false;
29
- this.showSuggestions = false;
30
- this.leadingCaret = false;
31
- this.caretEmbedded = true;
32
- this.hideRoot = false;
33
- this.padEnding = false;
34
- this.withUp = false;
35
- this.#previousSelectionKey = ``;
36
- this.#menuOpenedByKeyboard = false;
37
- this.#currentOpenTrigger = null;
38
- this.tickled = new TickledController(this, {
39
- getItems: () => this.#getTickledItems(),
40
- onTickle: (index) => {
41
- if (index !== void 0) this.#onTickled(index);
42
- }
43
- });
44
- this.#onFocus = () => {
45
- this._isFocused = true;
46
- };
47
- this.#onBlur = () => {
48
- this._isFocused = false;
49
- };
50
- this.#onHostClick = () => {
51
- this.#getHostContainer()?.focus();
52
- };
53
- this.#onMenuTriggerClose = () => {
54
- document.removeEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
55
- this.#currentOpenTrigger = null;
56
- this.#menuOpenedByKeyboard = false;
57
- requestAnimationFrame(() => {
58
- this.#getHostContainer()?.focus();
59
- });
60
- };
61
- this.#onMenuKeyNav = (e) => {
62
- if (!this.#currentOpenTrigger?.querySelector(`ixfx-menu-container`) || !this.#currentOpenTrigger?.isOpen) return;
63
- switch (e.key) {
64
- case `ArrowLeft`:
65
- case `ArrowRight`: {
66
- e.preventDefault();
67
- e.stopPropagation();
68
- this.#currentOpenTrigger.closeMenu();
69
- const r = this.root;
70
- const sel = this.selectedNode;
71
- if (!r || !sel) break;
72
- const totalItems = this.#getTickledItems().length;
73
- const currentTickled = this.tickled.tickledId ?? -1;
74
- if (e.key === `ArrowLeft`) {
75
- if (currentTickled > 0) this.tickled.handleKeyboardNavigation(`previous`);
76
- } else if (currentTickled < totalItems - 1) this.tickled.handleKeyboardNavigation(`next`);
77
- break;
78
- }
79
- }
80
- };
81
- this.#onKeyDown = (e) => {
82
- const r = this.root;
83
- const sel = this.selectedNode;
84
- if (!r || !sel) return;
85
- const totalItems = this.#getTickledItems().length;
86
- const currentTickled = this.tickled.tickledId ?? -1;
87
- switch (e.key) {
88
- case `ArrowRight`:
89
- e.preventDefault();
90
- if (currentTickled < totalItems - 1) this.tickled.handleKeyboardNavigation(`next`);
91
- else if (currentTickled === totalItems - 1 && this.#canFocusSuggestions()) this.#shiftFocusToNarrowedText();
92
- break;
93
- case `ArrowLeft`:
94
- e.preventDefault();
95
- if (currentTickled > 0) this.tickled.handleKeyboardNavigation(`previous`);
96
- break;
97
- case `ArrowDown`:
98
- case `ArrowUp`:
99
- if (this.tickled.tickledId !== void 0) {
100
- e.preventDefault();
101
- if (this.#currentOpenTrigger?.isOpen) {
102
- const popover = this.#currentOpenTrigger.querySelector(`ixfx-menu-container`)?.shadowRoot?.querySelector(`.popover`);
103
- if (popover) popover.dispatchEvent(new KeyboardEvent(`keydown`, {
104
- key: e.key,
105
- bubbles: true
106
- }));
107
- } else this.#handleOpenCaretMenu();
108
- }
109
- break;
110
- case `Enter`:
111
- case ` `:
112
- e.preventDefault();
113
- this.#activateTickled();
114
- break;
115
- case `Escape`:
116
- e.preventDefault();
117
- this._menuOpen = false;
118
- this.tickled.clearTickled();
119
- this.blur();
120
- break;
121
- case `Tab`:
122
- if (e.shiftKey) break;
123
- if (currentTickled === totalItems - 1 && this.#canFocusSuggestions()) {
124
- e.preventDefault();
125
- this.#shiftFocusToNarrowedText();
126
- }
127
- }
128
- };
129
- this.#onNarrowedTextBlur = () => {
130
- this._focusOnNarrowedText = false;
131
- this.#shiftFocusToPath();
132
- };
133
- this.#onNarrowedTextShiftTab = () => {
134
- this._focusOnNarrowedText = false;
135
- this.#shiftFocusToPath();
136
- };
137
- this.#isWheelScrolling = false;
138
- this.#onWheel = (e) => {
139
- const wheelEvent = e;
140
- if (wheelEvent.deltaX !== 0 || wheelEvent.deltaY !== 0) {
141
- e.preventDefault();
142
- if (!this.#isWheelScrolling) {
143
- this.#isWheelScrolling = true;
144
- this.tickled.clearTickled();
145
- }
146
- const hostContainer = this.#getHostContainer();
147
- if (hostContainer) hostContainer.scrollLeft += wheelEvent.deltaX + wheelEvent.deltaY;
148
- clearTimeout(this.#wheelScrollTimeout);
149
- this.#wheelScrollTimeout = setTimeout(() => {
150
- this.#isWheelScrolling = false;
151
- }, 150);
152
- }
153
- };
154
- this.#currentLeadingSiblings = void 0;
155
- }
156
- get selectedNodes() {
157
- return this._selectedNodes;
158
- }
159
- #pendingNode;
160
- #pendingController;
161
- #modelUnsubscribe;
162
- #previousSelectionKey;
163
- #menuOpenedByKeyboard;
164
- #currentOpenTrigger;
165
- #getTickledItems() {
166
- const r = this.root;
167
- const sel = this.selectedNode;
168
- if (!r || !sel) return [];
169
- const pathNodes = this.#findPath(r, sel) ?? [r];
170
- const items = [];
171
- if (this.caretEmbedded) {
172
- pathNodes.forEach((_node, i) => {
173
- items.push({
174
- id: i,
175
- enabled: true
176
- });
177
- });
178
- if (this.#canFocusSuggestions()) items.push({
179
- id: pathNodes.length,
180
- enabled: true
181
- });
182
- } else {
183
- let segmentId = 0;
184
- pathNodes.forEach((node, i) => {
185
- const isLast = i === pathNodes.length - 1;
186
- const hasChildren = node.item.isLeaf !== true && (node.children === void 0 || node.children.length > 0);
187
- const showLeadingCaret = this.leadingCaret && (i > 0 || this.hideRoot) && hasChildren;
188
- const showTrailingCaret = !this.leadingCaret && hasChildren || this.leadingCaret && isLast && hasChildren;
189
- if (showLeadingCaret) items.push({
190
- id: segmentId++,
191
- enabled: true
192
- });
193
- items.push({
194
- id: segmentId++,
195
- enabled: true
196
- });
197
- if (showTrailingCaret) items.push({
198
- id: segmentId++,
199
- enabled: true
200
- });
201
- });
202
- }
203
- return items;
204
- }
205
- #onTickled(index) {
206
- if (this.tickled.inputMode === `keyboard`) this.#scrollTickledIntoView(index);
207
- }
208
- #scrollTickledIntoView(index) {
209
- const r = this.root;
210
- const sel = this.selectedNode;
211
- if (!r || !sel) return;
212
- const pathNodes = this.#findPath(r, sel) ?? [r];
213
- let el = null;
214
- if (this.caretEmbedded && this.#canFocusSuggestions() && index === pathNodes.length) el = this.shadowRoot?.querySelector(`ixfx-narrowed-text`) ?? null;
215
- else el = this.shadowRoot?.querySelectorAll(`.crumb-segment`)[index] ?? null;
216
- el?.scrollIntoView({
217
- inline: `nearest`,
218
- block: `nearest`,
219
- behavior: `smooth`
220
- });
221
- }
222
- #hasChildOptions() {
223
- const s = this.selectedNode;
224
- if (s === void 0) return false;
225
- const isPending = this.#pendingNode === s;
226
- return (s.children ?? []).length > 0 || isPending;
227
- }
228
- /** True when the suggestions (narrowed-text) sub-part is renderable and focusable. */
229
- #canFocusSuggestions() {
230
- return this.showSuggestions && this.#hasChildOptions();
231
- }
232
- #onFocus;
233
- #onBlur;
234
- #getHostContainer() {
235
- return this.shadowRoot?.querySelector(`.host-container`) ?? null;
236
- }
237
- #onHostClick;
238
- #handleOpenCaretMenu() {
239
- const currentTickled = this.tickled.tickledId;
240
- if (currentTickled === void 0) return;
241
- const r = this.root;
242
- const sel = this.selectedNode;
243
- if (!r || !sel) return;
244
- const pathNodes = this.#findPath(r, sel) ?? [r];
245
- if (this.caretEmbedded && this.#canFocusSuggestions() && currentTickled === pathNodes.length) {
246
- this.#shiftFocusToNarrowedText();
247
- return;
248
- }
249
- const trigger = (this.shadowRoot?.querySelectorAll(`.crumb-segment`))?.[currentTickled]?.querySelector(`.caret ixfx-menu-trigger`);
250
- if (trigger) {
251
- this.#menuOpenedByKeyboard = true;
252
- this.#currentOpenTrigger = trigger;
253
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
254
- trigger.openMenu();
255
- this.#propagateInputModeToMenu();
256
- }
257
- }
258
- #propagateInputModeToMenu() {
259
- const inputMode = this.tickled.inputMode;
260
- requestAnimationFrame(() => {
261
- const container = this.#currentOpenTrigger?.querySelector(`ixfx-menu-container`);
262
- if (container) container.setAttribute(`data-input-mode`, inputMode);
263
- });
264
- }
265
- #onMenuTriggerClose;
266
- #onMenuKeyNav;
267
- #onKeyDown;
268
- /** Activates the currently tickled item, as if it had been clicked. */
269
- #activateTickled() {
270
- const currentTickled = this.tickled.tickledId;
271
- if (currentTickled === void 0) return;
272
- const r = this.root;
273
- const sel = this.selectedNode;
274
- if (!r || !sel) return;
275
- const pathNodes = this.#findPath(r, sel) ?? [r];
276
- if (this.caretEmbedded && this.#canFocusSuggestions() && currentTickled === pathNodes.length) {
277
- this.#shiftFocusToNarrowedText();
278
- return;
279
- }
280
- (this.shadowRoot?.querySelector(`.crumb-segment[data-segment-id="${currentTickled}"]`))?.click();
281
- }
282
- #shiftFocusToNarrowedText() {
283
- const narrowedText = this.shadowRoot?.querySelector(`ixfx-narrowed-text`);
284
- if (narrowedText) {
285
- this._menuOpen = false;
286
- this._focusOnNarrowedText = true;
287
- narrowedText.focus();
288
- }
289
- }
290
- #shiftFocusToPath() {
291
- this._focusOnNarrowedText = false;
292
- const hostContainer = this.#getHostContainer();
293
- if (hostContainer) hostContainer.focus();
294
- }
295
- #onNarrowedTextBlur;
296
- #onNarrowedTextShiftTab;
297
- select(node) {
298
- this.#setSelected(node);
299
- }
300
- deselect(_node) {}
301
- clearSelection() {
302
- if (this.root) this.#setSelected(this.root);
303
- }
304
- /** Not implemented on crumb-navigation. */
305
- selectAll() {}
306
- /** Not implemented on crumb-navigation. */
307
- deselectAll() {}
308
- getNodes() {
309
- if (!this.root) return [];
310
- const result = [];
311
- const visit = (node, depth) => {
312
- result.push({
313
- node,
314
- depth
315
- });
316
- if (node.children) for (const child of node.children) visit(child, depth + 1);
317
- };
318
- for (const child of this.root.children ?? []) visit(child, 0);
319
- return result;
320
- }
321
- updated(changedProps) {
322
- if (changedProps.has(`model`)) {
323
- this.#modelUnsubscribe?.();
324
- this.#modelUnsubscribe = void 0;
325
- const model = this.model;
326
- if (model) {
327
- this.root = model.root;
328
- this.#modelUnsubscribe = model._subscribe((event) => {
329
- if (event.type === `root`) {
330
- this.root = event.root;
331
- this.requestUpdate();
332
- }
333
- });
334
- }
335
- }
336
- this.#runLayoutUpdate(changedProps);
337
- }
338
- connectedCallback() {
339
- super.connectedCallback();
340
- this.addEventListener(`click`, this.#onHostClick);
341
- this.addEventListener(`wheel`, this.#onWheel, { passive: false });
342
- }
343
- disconnectedCallback() {
344
- super.disconnectedCallback();
345
- this.removeEventListener(`click`, this.#onHostClick);
346
- this.removeEventListener(`wheel`, this.#onWheel);
347
- this.#modelUnsubscribe?.();
348
- this.#modelUnsubscribe = void 0;
349
- document.removeEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
350
- this.#currentOpenTrigger = null;
351
- }
352
- firstUpdated() {
353
- const hostContainer = this.#getHostContainer();
354
- if (hostContainer) hostContainer.scrollLeft = hostContainer.scrollWidth - hostContainer.clientWidth;
355
- }
356
- #isWheelScrolling;
357
- #onWheel;
358
- #wheelScrollTimeout;
359
- #runLayoutUpdate(_changedProperties) {
360
- if (!this.shadowRoot) return;
361
- const hsiElement = this.shadowRoot.querySelector(`.horiz-select-items`);
362
- if (!hsiElement) return;
363
- const ulElement = hsiElement.querySelector(`ul`);
364
- if (!ulElement) return;
365
- const menuTrigger = this.shadowRoot.querySelector(`ixfx-menu-trigger`);
366
- if (!menuTrigger) return;
367
- if (ulElement.getBoundingClientRect().width > hsiElement.getBoundingClientRect().width) menuTrigger.style.display = `inline-flex`;
368
- else menuTrigger.style.display = `none`;
369
- for (const li of ulElement.querySelectorAll(`li`)) if ((li.getAttribute(`data-key`) ?? ``) === this.#previousSelectionKey) {
370
- this.#scrollToValue(li);
371
- break;
372
- }
373
- }
374
- #scrollToValue(li) {
375
- let l = li.offsetLeft;
376
- const ul = li.parentElement;
377
- if (!ul) return;
378
- l -= ul.offsetLeft;
379
- const horizSelectItems = ul.parentElement;
380
- if (!horizSelectItems) return;
381
- horizSelectItems.scroll({
382
- left: l,
383
- top: 0,
384
- behavior: `smooth`
385
- });
386
- const horizSelect = horizSelectItems.parentElement;
387
- if (!horizSelect) return;
388
- horizSelect.style.minWidth = `${li.getBoundingClientRect().width}px`;
389
- }
390
- #abortPending() {
391
- if (this.#pendingController) {
392
- this.#pendingController.abort();
393
- this.#pendingController = void 0;
394
- this.#pendingNode = void 0;
395
- }
396
- }
397
- #findPath(node, target, acc = []) {
398
- const path = [...acc, node];
399
- if (node === target) return path;
400
- if (!node.children) return void 0;
401
- for (const child of node.children) {
402
- const result = this.#findPath(child, target, path);
403
- if (result) return result;
404
- }
405
- }
406
- #scrollSegmentIntoView(depth) {
407
- if (!this.shadowRoot) return;
408
- this.shadowRoot.querySelectorAll(`.crumb-segment`)[depth]?.scrollIntoView({
409
- block: `nearest`,
410
- inline: `start`
411
- });
412
- }
413
- #updateTrailingWidth() {
414
- if (!this.padEnding || !this.shadowRoot) return;
415
- const hostContainer = this.shadowRoot.querySelector(`.host-container`);
416
- const trailing = this.shadowRoot.querySelector(`.trailing`);
417
- if (!hostContainer || !trailing) return;
418
- const segments = this.shadowRoot.querySelectorAll(`.crumb-segment`);
419
- const lastSegment = segments[segments.length - 1];
420
- if (!lastSegment) return;
421
- const containerWidth = hostContainer.getBoundingClientRect().width;
422
- const itemWidth = lastSegment.getBoundingClientRect().width;
423
- if (itemWidth < containerWidth) {
424
- trailing.style.width = `${containerWidth - itemWidth - 5}px`;
425
- requestAnimationFrame(() => {
426
- if (hostContainer.scrollWidth <= hostContainer.clientWidth) hostContainer.style.setProperty(`--scroll-fade-x-start`, `0px`, `important`);
427
- else hostContainer.style.removeProperty(`--scroll-fade-x-start`);
428
- });
429
- } else trailing.style.width = ``;
430
- }
431
- #setSelected(node) {
432
- const previous = this.selectedNode;
433
- if (previous) this.#previousSelectionKey = previous.item?.key ?? ``;
434
- else this.#previousSelectionKey = ``;
435
- const previousSet = previous ? /* @__PURE__ */ new Set([previous]) : /* @__PURE__ */ new Set();
436
- this.selectedNode = node;
437
- this._selectedNodes = /* @__PURE__ */ new Set([node]);
438
- if (this.root) {
439
- const path = this.#findPath(this.root, node);
440
- if (path) {
441
- const depth = this.hideRoot && path.length > 1 ? path.length - 2 : path.length - 1;
442
- requestAnimationFrame(() => {
443
- this.#updateTrailingWidth();
444
- const hostContainer = this.#getHostContainer();
445
- if (hostContainer) hostContainer.scrollLeft = 0;
446
- this.#scrollSegmentIntoView(depth);
447
- });
448
- }
449
- }
450
- this.dispatchEvent(new CustomEvent(`select`, {
451
- detail: {
452
- selected: /* @__PURE__ */ new Set([node]),
453
- previous: previousSet
454
- },
455
- bubbles: true,
456
- composed: true
457
- }));
458
- }
459
- #onLabelClick(node, depth) {
460
- this._openIdx = -1;
461
- this.#setSelected(node);
462
- this.#scrollSegmentIntoView(depth);
463
- this.dispatchEvent(new CustomEvent(`item-click`, {
464
- detail: {
465
- node,
466
- depth
467
- },
468
- bubbles: true,
469
- composed: true
470
- }));
471
- }
472
- #onCaretClick(node, depth, e) {
473
- e.preventDefault();
474
- e.stopPropagation();
475
- if (this._openIdx === depth) {
476
- this._openIdx = -1;
477
- return;
478
- }
479
- this._openIdx = depth;
480
- if (node.children === void 0 && this.#pendingNode !== node) {
481
- this.#abortPending();
482
- this.#pendingNode = node;
483
- const controller = new AbortController();
484
- this.#pendingController = controller;
485
- if (this.loadChildren) this.#invokeLoadChildren(node, depth, controller).catch(() => {});
486
- }
487
- this.requestUpdate();
488
- }
489
- async #invokeLoadChildren(node, depth, controller) {
490
- try {
491
- const children = [...await collectDataResult(this.loadChildren({
492
- node,
493
- depth
494
- }, controller.signal), controller.signal)];
495
- if (controller.signal.aborted) return;
496
- node.children = children;
497
- this.#pendingNode = void 0;
498
- this.#pendingController = void 0;
499
- this.dispatchEvent(new CustomEvent(`expand`, {
500
- detail: {
501
- node,
502
- depth
503
- },
504
- bubbles: true,
505
- composed: true
506
- }));
507
- this.requestUpdate();
508
- } catch {
509
- if (controller.signal.aborted) return;
510
- node.children = [];
511
- this.#pendingNode = void 0;
512
- this.#pendingController = void 0;
513
- this.requestUpdate();
514
- }
515
- }
516
- #onSegmentMenuCommand(e, node, depth) {
517
- const key = e.detail.command;
518
- if (this.leadingCaret) {
519
- const child = node.children?.find((c) => c.item.key === key);
520
- if (child) {
521
- this.#onChildClick(child, depth + 1);
522
- return;
523
- }
524
- if (this.#currentLeadingSiblings) {
525
- const sibling = this.#currentLeadingSiblings.find((c) => c.item.key === key);
526
- if (sibling) this.#onChildClick(sibling, depth);
527
- this.#currentLeadingSiblings = void 0;
528
- return;
529
- }
530
- }
531
- const child = node.children?.find((c) => c.item.key === key);
532
- if (child) this.#onChildClick(child, depth + 1);
533
- }
534
- #currentLeadingSiblings;
535
- #getSiblingMenuItems(pathNodes, index) {
536
- if (index === 0) {
537
- if (!this.hideRoot || !this.root) return [];
538
- const siblings = sortNodesByLabel(this.root.children ?? []);
539
- this.#currentLeadingSiblings = siblings;
540
- return siblings.map((sibling) => html`
541
- <ixfx-menu-item
542
- label="${sibling.item.label}"
543
- command="${sibling.item.key}"
544
- icon-name="${sibling.item.icon ?? nothing}"
545
- @click=${() => {
546
- this.#onChildClick(sibling, index);
547
- }}
548
- ></ixfx-menu-item>
549
- `);
550
- }
551
- const parent = pathNodes[index - 1];
552
- const siblings = sortNodesByLabel(parent.children ?? []);
553
- this.#currentLeadingSiblings = siblings;
554
- return siblings.map((sibling) => html`
555
- <ixfx-menu-item
556
- label="${sibling.item.label}"
557
- command="${sibling.item.key}"
558
- icon-name="${sibling.item.icon ?? nothing}"
559
- @click=${() => {
560
- this.#onChildClick(sibling, index);
561
- }}
562
- ></ixfx-menu-item>
563
- `);
564
- }
565
- #onChildClick(node, depth) {
566
- this._openIdx = -1;
567
- this.#setSelected(node);
568
- this.dispatchEvent(new CustomEvent(`item-click`, {
569
- detail: {
570
- node,
571
- depth
572
- },
573
- bubbles: true,
574
- composed: true
575
- }));
576
- }
577
- #onUpClick() {
578
- const r = this.root;
579
- const sel = this.selectedNode;
580
- if (!r || !sel) return;
581
- const path = this.#findPath(r, sel);
582
- if (!path || path.length <= 1) return;
583
- const parent = path[path.length - 2];
584
- this.#setSelected(parent);
585
- }
586
- /** Navigate to a node by key path. Returns false if any key is not found in already-loaded children. */
587
- navigateTo(keys) {
588
- if (!this.root?.children) return false;
589
- let current = this.root;
590
- for (const key of keys) {
591
- const found = current?.children?.find((n) => n.item.key === key);
592
- if (!found) return false;
593
- current = found;
594
- }
595
- if (current && current !== this.root) this.#setSelected(current);
596
- return true;
597
- }
598
- /** Navigate to the first node matching the predicate. Returns false if not found. */
599
- navigateToNode(predicate) {
600
- if (!this.root) return false;
601
- const keyPath = this.#findNodePath(this.root.children ?? [], predicate);
602
- if (!keyPath) return false;
603
- return this.navigateTo(keyPath);
604
- }
605
- /** `TreeComponent` parity — a crumb path always follows the selection, so this just navigates to `key`. */
606
- revealKey(key) {
607
- return this.navigateToNode((n) => n.item.key === key);
608
- }
609
- /** `TreeComponent` parity — a crumb path is a single selection, so only the last node is kept. */
610
- selectMany(nodes) {
611
- const last = [...nodes].at(-1);
612
- if (last) this.select(last);
613
- else this.clearSelection();
614
- }
615
- #findNodePath(nodes, predicate, prefix = []) {
616
- for (const node of nodes) {
617
- const path = [...prefix, node.item.key];
618
- if (predicate(node)) return path;
619
- if (node.children?.length) {
620
- const result = this.#findNodePath(node.children, predicate, path);
621
- if (result) return result;
622
- }
623
- }
624
- }
625
- #onMenuCommand(e) {
626
- const node = this.selectedNode;
627
- if (!node?.children) return;
628
- const key = e.detail.command;
629
- const child = node.children.find((c) => c.item.key === key);
630
- if (child) {
631
- const depth = this.root ? this.#findPath(this.root, node)?.length ?? 1 : 1;
632
- this.#onChildClick(child, depth);
633
- }
634
- }
635
- render() {
636
- const r = this.root;
637
- const sel = this.selectedNode;
638
- if (!r || !sel) return html``;
639
- this.inputMode = this.tickled.inputMode;
640
- let pathNodes = this.#findPath(r, sel) ?? [r];
641
- if (this.hideRoot && pathNodes.length > 1) pathNodes = pathNodes.slice(1);
642
- this.#hasChildOptions();
643
- const isAtRoot = (() => {
644
- return (this.#findPath(r, sel) ?? [r]).length <= 1;
645
- })();
646
- const parts = [];
647
- let segmentId = 0;
648
- pathNodes.forEach((node, i) => {
649
- const isLast = i === pathNodes.length - 1;
650
- const isPending = this.#pendingNode === node;
651
- const isOpen = this._openIdx === i;
652
- const hasChildren = node.item.isLeaf !== true && (node.children === void 0 || node.children.length > 0);
653
- const isTickled = this.tickled.isTickled(i);
654
- const showLeadingCaret = this.leadingCaret && (i > 0 || this.hideRoot) && hasChildren;
655
- const showTrailingCaret = !this.leadingCaret && hasChildren || this.leadingCaret && isLast && hasChildren;
656
- const siblingMenuItems = showLeadingCaret ? this.#getSiblingMenuItems(pathNodes, i) : [];
657
- const childMenuItems = sortNodesByLabel(node.children ?? []).map((c) => html`
658
- <ixfx-menu-item
659
- label="${c.item.label}"
660
- command="${c.item.key}"
661
- icon-name="${c.item.icon ?? nothing}"
662
- ></ixfx-menu-item>
663
- `);
664
- if (this.caretEmbedded) {
665
- const canTruncate = !this.noTruncate && !isLast && !isTickled;
666
- parts.push(html`
667
- <div class="item crumb-segment ${isTickled ? `tickled` : ``} ${canTruncate ? `truncatable` : ``} ${this.leadingCaret ? `leading-caret` : ``} ${isLast ? `last-label` : ``}" data-segment-id="${i}" data-path-index="${i}"
668
- @click=${(e) => {
669
- if (e.target.closest(`.caret`)) return;
670
- this.#onLabelClick(node, i);
671
- }}
672
- >
673
- ${showLeadingCaret ? html`
674
- <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
675
- ${isPending ? html`<span class="loading-spinner"></span>` : html`
676
- <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
677
- <ixfx-menu-container slot="menu">
678
- ${siblingMenuItems}
679
- </ixfx-menu-container>
680
- </ixfx-menu-trigger>
681
- `}
682
- </span>
683
- ` : nothing}
684
- <span class="label">${node.item.label}</span>
685
- ${showTrailingCaret ? html`
686
- <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
687
- ${isPending ? html`<span class="loading-spinner"></span>` : html`
688
- <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
689
- <ixfx-menu-container slot="menu">
690
- ${childMenuItems}
691
- </ixfx-menu-container>
692
- </ixfx-menu-trigger>
693
- `}
694
- </span>
695
- ` : nothing}
696
- </div>
697
- `);
698
- } else {
699
- const leadingCaretTickled = showLeadingCaret ? this.tickled.isTickled(segmentId) : false;
700
- if (showLeadingCaret) {
701
- parts.push(html`
702
- <div class="item crumb-segment ${leadingCaretTickled ? `tickled` : ``}" data-segment-id="${segmentId}" data-path-index="${i}"
703
- @click=${(e) => {
704
- const trigger = e.target.closest(`.crumb-segment`)?.querySelector(`ixfx-menu-trigger`);
705
- if (trigger) trigger.openMenu();
706
- }}
707
- >
708
- <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
709
- ${isPending ? html`<span class="loading-spinner"></span>` : html`
710
- <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
711
- <ixfx-menu-container slot="menu">
712
- ${siblingMenuItems}
713
- </ixfx-menu-container>
714
- </ixfx-menu-trigger>
715
- `}
716
- </span>
717
- </div>
718
- `);
719
- segmentId++;
720
- }
721
- const labelTickled = this.tickled.isTickled(segmentId);
722
- const canTruncate = !this.noTruncate && !isLast && !labelTickled;
723
- parts.push(html`
724
- <div class="item crumb-segment ${labelTickled ? `tickled` : ``} ${canTruncate ? `truncatable` : ``} ${isLast ? `last-label` : ``}" data-segment-id="${segmentId}" data-path-index="${i}"
725
- @click=${(e) => {
726
- if (e.target.closest(`.caret`)) return;
727
- this.#onLabelClick(node, i);
728
- }}
729
- >
730
- <span class="label">${node.item.label}</span>
731
- </div>
732
- `);
733
- segmentId++;
734
- if (showTrailingCaret) {
735
- const trailingCaretTickled = this.tickled.isTickled(segmentId);
736
- parts.push(html`
737
- <div class="item crumb-segment ${trailingCaretTickled ? `tickled` : ``}" data-segment-id="${segmentId}" data-path-index="${i}"
738
- @click=${(e) => {
739
- const trigger = e.target.closest(`.crumb-segment`)?.querySelector(`ixfx-menu-trigger`);
740
- if (trigger) trigger.openMenu();
741
- }}
742
- >
743
- <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
744
- ${isPending ? html`<span class="loading-spinner"></span>` : html`
745
- <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
746
- <ixfx-menu-container slot="menu">
747
- ${childMenuItems}
748
- </ixfx-menu-container>
749
- </ixfx-menu-trigger>
750
- `}
751
- </span>
752
- </div>
753
- `);
754
- segmentId++;
755
- }
756
- }
757
- });
758
- return html`
759
- <div class="crumb-wrapper">
760
- ${this.withUp ? html`
761
- <button
762
- class="up-button"
763
- ?disabled=${isAtRoot}
764
- aria-label="Go up one level"
765
- @click=${this.#onUpClick}
766
- >
767
- <span class="label"><ixfx-icon name="folder-up"></ixfx-icon></span>
768
- </button>
769
- ` : nothing}
770
- <div
771
- class="host-container scroll-fade-x"
772
- tabindex="0"
773
- @focus=${this.#onFocus}
774
- @blur=${this.#onBlur}
775
- @keydown=${this.#onKeyDown}
776
- @click=${this.#onHostClick}
777
- @menu-trigger-close=${this.#onMenuTriggerClose}
778
- @mouseout=${(e) => this.tickled.handlePointerLeave(e)}
779
- >
780
- <div class="parts"
781
- @mouseover=${(e) => {
782
- if (this.#isWheelScrolling) return;
783
- const target = e.target;
784
- if (!(target instanceof HTMLElement)) return;
785
- const segment = target.closest(`.crumb-segment`);
786
- if (!segment) return;
787
- const segmentId = parseInt(segment.dataset.segmentId ?? ``, 10);
788
- if (Number.isNaN(segmentId)) return;
789
- const pathIndex = parseInt(segment.dataset.pathIndex ?? ``, 10);
790
- const node = pathNodes[pathIndex];
791
- if (!node) return;
792
- this.tickled.handlePointerEnter(segmentId);
793
- this.dispatchEvent(new CustomEvent(`tickle`, {
794
- detail: {
795
- node,
796
- depth: pathIndex
797
- },
798
- bubbles: true,
799
- composed: true
800
- }));
801
- }}
802
- >${parts}${this.padEnding ? html`<div class="trailing"></div>` : nothing}</div>
803
- ${this.showSuggestions ? this.#renderChildOptions() : nothing}
804
- </div>
805
- </div>
806
- `;
807
- }
808
- #renderChildOptions() {
809
- const s = this.selectedNode;
810
- if (s === void 0) return nothing;
811
- const isPending = this.#pendingNode === s;
812
- const children = s.children ?? [];
813
- if (children.length === 0 && !isPending) return nothing;
814
- if (isPending) return html`
815
- <div class="horiz-select">
816
- <div class="horiz-select-items">
817
- <span class="loading-spinner"></span>
818
- </div>
819
- </div>
820
- `;
821
- return html`
822
- <ixfx-narrowed-text
823
- class="horiz-select"
824
- selection-mode="single"
825
- orientation="horizontal"
826
- nowrap
827
- width=${this.#getChildOptionsWidth()}
828
- @change=${this.#onNarrowedTextChange}
829
- @narrowed-text-blur=${this.#onNarrowedTextBlur}
830
- @narrowed-text-shift-tab=${this.#onNarrowedTextShiftTab}
831
- >
832
- ${sortNodesByLabel(children).map((c) => html`
833
- <span data-value="${c.item.key}" data-label="${c.item.label}"></span>
834
- `)}
835
- </ixfx-narrowed-text>
836
- `;
837
- }
838
- #onNarrowedTextChange(e) {
839
- e.stopPropagation();
840
- const detail = e.detail;
841
- const node = this.selectedNode;
842
- if (!node?.children) return;
843
- const child = node.children.find((c) => c.item.key === detail.item.value);
844
- if (child) {
845
- const depth = this.root ? this.#findPath(this.root, node)?.length ?? 1 : 1;
846
- this.#onChildClick(child, depth);
847
- }
848
- }
849
- #getChildOptionsWidth() {
850
- return `var(--child-options-width, 50ch)`;
851
- }
852
- static {
853
- this.styles = [
854
- themeFallbacks,
855
- tickledStyles,
856
- tickledItemStyles,
857
- scrollFadeStyles(`x`),
858
- css`
859
- :host {
860
- --crumb-item-bg: var(--item-bg, transparent);
861
- --crumb-item-bg-tickled: var(--item-bg-tickled);
862
- --crumb-item-text-tickled: var(--item-text-tickled);
863
- --crumb-item-border: var(--item-border);
864
- --crumb-item-border-tickled: var(--item-border-tickled);
865
- --crumb-item-padding: var(--space-s, 2px);
866
- --crumb-item-border-radius: var(--item-border-radius);
867
- --crumb-item-gap: var(--item-gap, var(--space-xs));
868
- --crumb-separator: var(--surface-muted-text);
869
- --crumb-truncate-min-width: 10ch;
870
- display: flex;
871
- width: 100%;
872
- }
873
-
874
- /* Outline goes on :host, not .host-container: .host-container carries the
875
- * scroll-fade mask-image, and CSS masks clip everything painted outside
876
- * the masked box - including an outline, which paints outside the border edge. */
877
- :host(:focus-within) {
878
- outline: 2px solid var(--accent);
879
- outline-offset: 2px;
880
- }
881
-
882
- .crumb-wrapper {
883
- display: flex;
884
- align-items: center;
885
- gap: var(--crumb-item-gap);
886
- width: 100%;
887
- }
888
-
889
- .up-button {
890
- box-sizing: border-box;
891
- display: inline-flex;
892
- align-items: center;
893
- justify-content: center;
894
- flex-shrink: 0;
895
- background: var(--crumb-item-bg);
896
- border: var(--crumb-item-border);
897
- border-radius: var(--crumb-item-border-radius);
898
- padding: 0;
899
- margin: 0;
900
- cursor: pointer;
901
- color: inherit;
902
- font: inherit;
903
- line-height: normal;
904
- }
905
-
906
- .up-button:disabled {
907
- opacity: 0.5;
908
- cursor: not-allowed;
909
- }
910
-
911
- .up-button:hover:not(:disabled) {
912
- background: var(--crumb-item-bg-tickled);
913
- border-color: var(--crumb-item-border-tickled);
914
- }
915
-
916
- .up-button .label {
917
- display: flex;
918
- align-items: center;
919
- padding: var(--crumb-item-padding);
920
- }
921
-
922
- .up-button .label ixfx-icon {
923
- display: block;
924
- width: 1em;
925
- height: 1em;
926
- pointer-events: none;
927
- }
928
-
929
- /* Edge fade (shows/hides based on scroll position) comes from the
930
- * shared .scroll-fade-x class - see ../styles/scroll-fade.ts */
931
- .host-container {
932
- display: flex;
933
- flex: 1;
934
- min-width: 0;
935
- outline: none;
936
- overflow: scroll;
937
- scroll-snap-type: x mandatory;
938
- scrollbar-width: none;
939
- overscroll-behavior: none;
940
- }
941
-
942
- .host-container::-webkit-scrollbar {
943
- display: none;
944
- }
945
-
946
- .parts {
947
- display: flex;
948
- gap: var(--space-s);
949
- }
950
-
951
- .trailing {
952
- flex-shrink: 0;
953
- }
954
-
955
- .crumb-segment {
956
- display: flex;
957
- align-items: center;
958
- flex-shrink: 0;
959
- background: var(--crumb-item-bg);
960
- border: var(--crumb-item-border);
961
- border-radius: var(--crumb-item-border-radius);
962
- padding:0;
963
- }
964
-
965
- .crumb-segment.leading-caret {
966
- flex-direction: row;
967
- }
968
-
969
- .crumb-segment.tickled {
970
- background: var(--crumb-item-bg-tickled);
971
- border-color: var(--crumb-item-border-tickled);
972
- color: var(--crumb-item-text-tickled);
973
- flex-shrink: 0;
974
- min-width: auto;
975
- }
976
-
977
- .crumb-segment.truncatable {
978
- flex-shrink: 1;
979
- min-width: min(var(--crumb-truncate-min-width), auto);
980
- overflow: hidden;
981
- }
982
-
983
- .crumb-segment.truncatable .label {
984
- overflow: hidden;
985
- text-overflow: ellipsis;
986
- white-space: nowrap;
987
- min-width: 0;
988
- }
989
-
990
- .label {
991
- padding: var(--crumb-item-padding);
992
- cursor: pointer;
993
- white-space: nowrap;
994
- color: inherit;
995
- }
996
-
997
- .crumb-segment.last-label .label {
998
- color: var(--crumb-last-label-color, inherit);
999
- font-style: var(--crumb-last-label-font-style, inherit);
1000
- font-weight: var(--crumb-last-label-font-weight, inherit);
1001
- text-decoration: var(--crumb-last-label-text-decoration, inherit);
1002
- text-underline-offset: var(--crumb-last-label-text-underline-offset, auto);
1003
- }
1004
-
1005
- .crumb-segment.tickled .label {
1006
- color: var(--crumb-item-text-tickled);
1007
- overflow: visible;
1008
- text-overflow: clip;
1009
- }
1010
-
1011
- .crumb-segment ixfx-menu-trigger {
1012
- --ixfx-button-padding: var(--space-s, 2px);
1013
- }
1014
-
1015
- .caret {
1016
- position: relative;
1017
- cursor: pointer;
1018
- color: var(--crumb-separator);
1019
- display: inline-flex;
1020
- align-items: center;
1021
- justify-content: center;
1022
- transition: all 0.2s ease-in-out;
1023
- }
1024
-
1025
- .caret.open {
1026
- background: color-mix(in srgb, var(--surface-5) 40%, transparent);
1027
- }
1028
-
1029
- .caret.pending {
1030
- display: inline-flex;
1031
- }
1032
-
1033
- .caret > ixfx-menu-trigger {
1034
- display: inline-flex;
1035
- margin: 0;
1036
- --_trigger-hover-bg: transparent;
1037
- --_trigger-hover-opacity: 0.6;
1038
- }
1039
-
1040
- .caret > ixfx-menu-trigger::part(base) {
1041
- background: none;
1042
- border: none;
1043
- color: inherit;
1044
- cursor: pointer;
1045
- font-size: inherit;
1046
- line-height: 1;
1047
- }
1048
-
1049
- .caret > ixfx-menu-trigger::part(base):hover {
1050
- background: none;
1051
- opacity: 0.6;
1052
- }
1053
-
1054
- .separator {
1055
- margin-left: var(--crumb-item-gap);
1056
- margin-right: var(--crumb-item-gap);
1057
- color: var(--crumb-separator);
1058
- }
1059
-
1060
- .separator-trigger {
1061
- display: inline-flex;
1062
- margin-left: var(--crumb-item-gap);
1063
- margin-right: var(--crumb-item-gap);
1064
- --_trigger-hover-bg: transparent;
1065
- --_trigger-hover-opacity: 0.6;
1066
- }
1067
-
1068
- .separator-trigger::part(base) {
1069
- background: none;
1070
- border: none;
1071
- color: var(--crumb-separator);
1072
- padding: 0;
1073
- cursor: pointer;
1074
- font-size: inherit;
1075
- line-height: 1;
1076
- }
1077
-
1078
- .separator-trigger::part(base):hover {
1079
- background: none;
1080
- opacity: 0.6;
1081
- }
1082
-
1083
- .separator-trigger.tickled::part(base) {
1084
- }
1085
-
1086
- ixfx-menu-trigger {
1087
- display: none;
1088
- }
1089
-
1090
- .horiz-select > ixfx-menu-trigger {
1091
- display: inline-flex;
1092
- }
1093
-
1094
- .horiz-select {
1095
- display: flex;
1096
- min-width: 5ch;
1097
- }
1098
-
1099
- .loading-spinner {
1100
- display: inline-block;
1101
- width: 12px;
1102
- height: 12px;
1103
- border: 2px solid var(--surface-5);
1104
- border-top-color: var(--accent);
1105
- border-radius: 50%;
1106
- animation: crumb-spin 0.7s linear infinite;
1107
- }
1108
-
1109
- @keyframes crumb-spin {
1110
- to { transform: rotate(360deg); }
1111
- }
1112
-
1113
- ::slotted(*), option {
1114
- user-select: none;
1115
- scroll-snap-align: start;
1116
- }
1117
- `
1118
- ];
1119
- }
1120
- };
1121
- __decorate([property({ type: Object })], CrumbNavigationElement.prototype, "root", void 0);
1122
- __decorate([property({ attribute: false })], CrumbNavigationElement.prototype, "model", void 0);
1123
- __decorate([property({ type: Object })], CrumbNavigationElement.prototype, "selectedNode", void 0);
1124
- __decorate([state()], CrumbNavigationElement.prototype, "_selectedNodes", void 0);
1125
- __decorate([property({ attribute: false })], CrumbNavigationElement.prototype, "loadChildren", void 0);
1126
- __decorate([property({ attribute: false })], CrumbNavigationElement.prototype, "filterPredicate", void 0);
1127
- __decorate([property({
1128
- reflect: true,
1129
- attribute: `exclusivity`
1130
- })], CrumbNavigationElement.prototype, "exclusivity", void 0);
1131
- __decorate([property({
1132
- reflect: true,
1133
- attribute: `selection-filter`
1134
- })], CrumbNavigationElement.prototype, "selectionFilter", void 0);
1135
- __decorate([state()], CrumbNavigationElement.prototype, "_openIdx", void 0);
1136
- __decorate([state()], CrumbNavigationElement.prototype, "_isFocused", void 0);
1137
- __decorate([state()], CrumbNavigationElement.prototype, "_menuOpen", void 0);
1138
- __decorate([state()], CrumbNavigationElement.prototype, "_focusOnNarrowedText", void 0);
1139
- __decorate([property({
1140
- reflect: true,
1141
- attribute: `input-mode`
1142
- })], CrumbNavigationElement.prototype, "inputMode", void 0);
1143
- __decorate([property({
1144
- type: Boolean,
1145
- reflect: true,
1146
- attribute: `no-truncate`
1147
- })], CrumbNavigationElement.prototype, "noTruncate", void 0);
1148
- __decorate([property({
1149
- type: Boolean,
1150
- reflect: true,
1151
- attribute: `show-suggestions`
1152
- })], CrumbNavigationElement.prototype, "showSuggestions", void 0);
1153
- __decorate([property({
1154
- type: Boolean,
1155
- reflect: true,
1156
- attribute: `leading-caret`
1157
- })], CrumbNavigationElement.prototype, "leadingCaret", void 0);
1158
- __decorate([property({
1159
- type: Boolean,
1160
- reflect: true,
1161
- attribute: `caret-embedded`
1162
- })], CrumbNavigationElement.prototype, "caretEmbedded", void 0);
1163
- __decorate([property({
1164
- type: Boolean,
1165
- reflect: true,
1166
- attribute: `hide-root`
1167
- })], CrumbNavigationElement.prototype, "hideRoot", void 0);
1168
- __decorate([property({
1169
- type: Boolean,
1170
- reflect: true,
1171
- attribute: `pad-ending`
1172
- })], CrumbNavigationElement.prototype, "padEnding", void 0);
1173
- __decorate([property({
1174
- type: Boolean,
1175
- reflect: true,
1176
- attribute: `with-up`
1177
- })], CrumbNavigationElement.prototype, "withUp", void 0);
1178
- CrumbNavigationElement = __decorate([safeCustomElement(`ixfx-crumb-navigation`)], CrumbNavigationElement);
1179
- //#endregion
1
+ import { t as CrumbNavigationElement } from "./crumb-navigation-YnFVFqrx.js";
1180
2
  export { CrumbNavigationElement };