@ixfx/components 0.5.15 → 0.5.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.d.ts +17 -5
- package/bundle/index.d.ts.map +1 -1
- package/bundle/index.js +459 -127
- package/bundle/index.js.map +1 -1
- package/dist/ac-text.js +2 -2
- package/dist/checkbox.js +1 -1
- package/dist/{colour-picker-DGso9ZOp.js → colour-picker-DbypcEp6.js} +2 -2
- package/dist/{colour-picker-DGso9ZOp.js.map → colour-picker-DbypcEp6.js.map} +1 -1
- package/dist/colour-picker.js +1 -1
- package/dist/crumbs.d.ts +16 -4
- package/dist/crumbs.d.ts.map +1 -1
- package/dist/crumbs.js +405 -125
- package/dist/crumbs.js.map +1 -1
- package/dist/data-display.js +1 -1
- package/dist/editable-label.js +1 -1
- package/dist/{fallbacks-pNMOMx38.js → fallbacks-DPgPEqo8.js} +51 -1
- package/dist/{fallbacks-pNMOMx38.js.map → fallbacks-DPgPEqo8.js.map} +1 -1
- package/dist/{icon-B22XVlCt.js → icon-DG9Lm3LT.js} +2 -2
- package/dist/{icon-B22XVlCt.js.map → icon-DG9Lm3LT.js.map} +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -12
- package/dist/index.js.map +1 -1
- package/dist/labelled-radial-input.js +2 -2
- package/dist/{menu-nuOIUD9K.js → menu-B8gE2MSo.js} +4 -4
- package/dist/{menu-nuOIUD9K.js.map → menu-B8gE2MSo.js.map} +1 -1
- package/dist/{menu-item-BBTZnjAR.js → menu-item-BYRvfyXK.js} +5 -4
- package/dist/menu-item-BYRvfyXK.js.map +1 -0
- package/dist/menu-item-DSyf9f_L.d.ts.map +1 -1
- package/dist/menu.js +2 -2
- package/dist/miller.js +1 -1
- package/dist/narrowed-text.js +1 -1
- package/dist/panel.js +2 -2
- package/dist/polar-pad.js +1 -1
- package/dist/{radial-input-DxCrt_NE.js → radial-input-CVxGH-Cp.js} +2 -2
- package/dist/{radial-input-DxCrt_NE.js.map → radial-input-CVxGH-Cp.js.map} +1 -1
- package/dist/radial-input.js +1 -1
- package/dist/range-input.js +1 -1
- package/dist/range.js +1 -1
- package/dist/selecthorizontal.js +1 -1
- package/dist/{slider-input-DFpG23bS.js → slider-input-CzmSVgm7.js} +2 -2
- package/dist/{slider-input-DFpG23bS.js.map → slider-input-CzmSVgm7.js.map} +1 -1
- package/dist/slider-input.js +1 -1
- package/dist/split-layout.js +1 -1
- package/dist/swipe.js +1 -1
- package/dist/{tab-list-DhkVhRQc.js → tab-list-6W5CgXix.js} +2 -2
- package/dist/{tab-list-DhkVhRQc.js.map → tab-list-6W5CgXix.js.map} +1 -1
- package/dist/{tab-list-BohmbvqF.d.ts → tab-list-ih-0I0NE.d.ts} +2 -2
- package/dist/{tab-list-BohmbvqF.d.ts.map → tab-list-ih-0I0NE.d.ts.map} +1 -1
- package/dist/tabs.d.ts +1 -1
- package/dist/tabs.js +1 -1
- package/dist/{tree-CL-txefQ.js → tree-BtiiDX1a.js} +2 -2
- package/dist/{tree-CL-txefQ.js.map → tree-BtiiDX1a.js.map} +1 -1
- package/dist/tree.js +1 -1
- package/dist/xy-pad.js +1 -1
- package/docs-user/crumbs.md +24 -9
- package/docs-user/tabs.md +19 -2
- package/package.json +1 -1
- package/dist/menu-item-BBTZnjAR.js.map +0 -1
package/dist/crumbs.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as tickledStyles, r as TickledController, t as tickledItemStyles } from "./tickled-styles-fNDdqf6l.js";
|
|
2
|
-
import { t as themeFallbacks } from "./fallbacks-
|
|
2
|
+
import { t as themeFallbacks } from "./fallbacks-DPgPEqo8.js";
|
|
3
3
|
import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
|
|
4
4
|
import "./interaction-D6efrBLo.js";
|
|
5
|
-
import "./menu-item-
|
|
5
|
+
import "./menu-item-BYRvfyXK.js";
|
|
6
6
|
import { t as collectDataResult } from "./data-provider-35TyWclX.js";
|
|
7
7
|
import "./narrowed-text.js";
|
|
8
8
|
import { LitElement, css, html, nothing } from "lit";
|
|
@@ -15,10 +15,14 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
15
15
|
this.exclusivity = `none`;
|
|
16
16
|
this.selectionFilter = `leaf`;
|
|
17
17
|
this._openIdx = -1;
|
|
18
|
-
this._isFocused = false;
|
|
19
18
|
this._menuOpen = false;
|
|
20
19
|
this._focusOnNarrowedText = false;
|
|
21
20
|
this.inputMode = ``;
|
|
21
|
+
this.noTruncate = false;
|
|
22
|
+
this.showSuggestions = false;
|
|
23
|
+
this.leadingCaret = false;
|
|
24
|
+
this.caretEmbedded = true;
|
|
25
|
+
this.hideRoot = false;
|
|
22
26
|
this.#previousSelectionKey = ``;
|
|
23
27
|
this.#menuOpenedByKeyboard = false;
|
|
24
28
|
this.#currentOpenTrigger = null;
|
|
@@ -28,21 +32,15 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
28
32
|
if (index !== void 0) this.#onTickled(index);
|
|
29
33
|
}
|
|
30
34
|
});
|
|
31
|
-
this.#onFocus = () => {
|
|
32
|
-
this._isFocused = true;
|
|
33
|
-
};
|
|
34
|
-
this.#onBlur = () => {
|
|
35
|
-
this._isFocused = false;
|
|
36
|
-
};
|
|
37
35
|
this.#onHostClick = () => {
|
|
38
|
-
this.
|
|
36
|
+
this.focus();
|
|
39
37
|
};
|
|
40
38
|
this.#onMenuTriggerClose = () => {
|
|
41
39
|
document.removeEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
|
|
42
40
|
this.#currentOpenTrigger = null;
|
|
43
41
|
this.#menuOpenedByKeyboard = false;
|
|
44
42
|
requestAnimationFrame(() => {
|
|
45
|
-
this.
|
|
43
|
+
this.focus();
|
|
46
44
|
});
|
|
47
45
|
};
|
|
48
46
|
this.#onMenuKeyNav = (e) => {
|
|
@@ -65,7 +63,8 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
};
|
|
68
|
-
this.#onKeyDown = (
|
|
66
|
+
this.#onKeyDown = (event) => {
|
|
67
|
+
const e = event;
|
|
69
68
|
const r = this.root;
|
|
70
69
|
const sel = this.selectedNode;
|
|
71
70
|
if (!r || !sel) return;
|
|
@@ -124,6 +123,29 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
124
123
|
this._focusOnNarrowedText = false;
|
|
125
124
|
this.#shiftFocusToPath();
|
|
126
125
|
};
|
|
126
|
+
this.#onMouseOut = (e) => {
|
|
127
|
+
this.tickled.handlePointerLeave(e);
|
|
128
|
+
};
|
|
129
|
+
this.#isWheelScrolling = false;
|
|
130
|
+
this.#onWheel = (e) => {
|
|
131
|
+
const wheelEvent = e;
|
|
132
|
+
if (wheelEvent.deltaX !== 0 || wheelEvent.deltaY !== 0) {
|
|
133
|
+
e.preventDefault();
|
|
134
|
+
if (!this.#isWheelScrolling) {
|
|
135
|
+
this.#isWheelScrolling = true;
|
|
136
|
+
this.tickled.clearTickled();
|
|
137
|
+
}
|
|
138
|
+
this.scrollLeft += wheelEvent.deltaX + wheelEvent.deltaY;
|
|
139
|
+
clearTimeout(this.#wheelScrollTimeout);
|
|
140
|
+
this.#wheelScrollTimeout = setTimeout(() => {
|
|
141
|
+
this.#isWheelScrolling = false;
|
|
142
|
+
}, 150);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
this.#onScroll = () => {
|
|
146
|
+
this.#updateFade();
|
|
147
|
+
};
|
|
148
|
+
this.#currentLeadingSiblings = void 0;
|
|
127
149
|
}
|
|
128
150
|
get selectedNodes() {
|
|
129
151
|
return this._selectedNodes;
|
|
@@ -140,26 +162,41 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
140
162
|
if (!r || !sel) return [];
|
|
141
163
|
const pathNodes = this.#findPath(r, sel) ?? [r];
|
|
142
164
|
const items = [];
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
165
|
+
if (this.caretEmbedded) {
|
|
166
|
+
pathNodes.forEach((_node, i) => {
|
|
167
|
+
items.push({
|
|
168
|
+
id: i,
|
|
169
|
+
enabled: true
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
if (this.#hasChildOptions()) items.push({
|
|
173
|
+
id: pathNodes.length,
|
|
146
174
|
enabled: true
|
|
147
175
|
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
176
|
+
} else {
|
|
177
|
+
let segmentId = 0;
|
|
178
|
+
pathNodes.forEach((node, i) => {
|
|
179
|
+
const isLast = i === pathNodes.length - 1;
|
|
180
|
+
const hasChildren = node.item.isLeaf !== true && (node.children === void 0 || node.children.length > 0);
|
|
181
|
+
const showLeadingCaret = this.leadingCaret && (i > 0 || this.hideRoot) && hasChildren;
|
|
182
|
+
const showTrailingCaret = !this.leadingCaret && hasChildren || this.leadingCaret && isLast && hasChildren;
|
|
183
|
+
if (showLeadingCaret) items.push({
|
|
184
|
+
id: segmentId++,
|
|
185
|
+
enabled: true
|
|
186
|
+
});
|
|
187
|
+
items.push({
|
|
188
|
+
id: segmentId++,
|
|
189
|
+
enabled: true
|
|
190
|
+
});
|
|
191
|
+
if (showTrailingCaret) items.push({
|
|
192
|
+
id: segmentId++,
|
|
193
|
+
enabled: true
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
}
|
|
153
197
|
return items;
|
|
154
198
|
}
|
|
155
199
|
#onTickled(index) {
|
|
156
|
-
const r = this.root;
|
|
157
|
-
const sel = this.selectedNode;
|
|
158
|
-
if (!r || !sel) return;
|
|
159
|
-
const pathNodes = this.#findPath(r, sel) ?? [r];
|
|
160
|
-
const hasChildOptions = this.#hasChildOptions();
|
|
161
|
-
if (index < pathNodes.length) this._openIdx = index;
|
|
162
|
-
else if (hasChildOptions && index === pathNodes.length) this._openIdx = pathNodes.length - 1;
|
|
163
200
|
if (this.tickled.inputMode === `keyboard`) this.#scrollTickledIntoView(index);
|
|
164
201
|
}
|
|
165
202
|
#scrollTickledIntoView(index) {
|
|
@@ -182,8 +219,6 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
182
219
|
const isPending = this.#pendingNode === s;
|
|
183
220
|
return (s.children ?? []).length > 0 || isPending;
|
|
184
221
|
}
|
|
185
|
-
#onFocus;
|
|
186
|
-
#onBlur;
|
|
187
222
|
#onHostClick;
|
|
188
223
|
#handleOpenCaretMenu() {
|
|
189
224
|
const currentTickled = this.tickled.tickledId;
|
|
@@ -263,8 +298,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
263
298
|
}
|
|
264
299
|
#shiftFocusToPath() {
|
|
265
300
|
this._focusOnNarrowedText = false;
|
|
266
|
-
|
|
267
|
-
if (hostContainer) hostContainer.focus();
|
|
301
|
+
this.focus();
|
|
268
302
|
}
|
|
269
303
|
#onNarrowedTextBlur;
|
|
270
304
|
#onNarrowedTextShiftTab;
|
|
@@ -311,16 +345,42 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
311
345
|
}
|
|
312
346
|
connectedCallback() {
|
|
313
347
|
super.connectedCallback();
|
|
348
|
+
this.tabIndex = 0;
|
|
314
349
|
this.addEventListener(`click`, this.#onHostClick);
|
|
350
|
+
this.addEventListener(`wheel`, this.#onWheel, { passive: false });
|
|
351
|
+
this.addEventListener(`scroll`, this.#onScroll);
|
|
352
|
+
this.addEventListener(`keydown`, this.#onKeyDown);
|
|
353
|
+
this.addEventListener(`menu-trigger-close`, this.#onMenuTriggerClose);
|
|
354
|
+
this.addEventListener(`mouseout`, this.#onMouseOut);
|
|
315
355
|
}
|
|
316
356
|
disconnectedCallback() {
|
|
317
357
|
super.disconnectedCallback();
|
|
318
358
|
this.removeEventListener(`click`, this.#onHostClick);
|
|
359
|
+
this.removeEventListener(`wheel`, this.#onWheel);
|
|
360
|
+
this.removeEventListener(`scroll`, this.#onScroll);
|
|
361
|
+
this.removeEventListener(`keydown`, this.#onKeyDown);
|
|
362
|
+
this.removeEventListener(`menu-trigger-close`, this.#onMenuTriggerClose);
|
|
363
|
+
this.removeEventListener(`mouseout`, this.#onMouseOut);
|
|
319
364
|
this.#modelUnsubscribe?.();
|
|
320
365
|
this.#modelUnsubscribe = void 0;
|
|
321
366
|
document.removeEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
|
|
322
367
|
this.#currentOpenTrigger = null;
|
|
323
368
|
}
|
|
369
|
+
firstUpdated() {
|
|
370
|
+
this.scrollLeft = this.scrollWidth - this.clientWidth;
|
|
371
|
+
this.#updateFade();
|
|
372
|
+
}
|
|
373
|
+
#onMouseOut;
|
|
374
|
+
#isWheelScrolling;
|
|
375
|
+
#onWheel;
|
|
376
|
+
#wheelScrollTimeout;
|
|
377
|
+
#onScroll;
|
|
378
|
+
#updateFade() {
|
|
379
|
+
const hasLeftFade = this.scrollLeft > 0;
|
|
380
|
+
const hasRightFade = this.scrollLeft < this.scrollWidth - this.clientWidth - 1;
|
|
381
|
+
this.classList.toggle(`has-left-fade`, hasLeftFade);
|
|
382
|
+
this.classList.toggle(`has-right-fade`, hasRightFade);
|
|
383
|
+
}
|
|
324
384
|
#runLayoutUpdate(_changedProperties) {
|
|
325
385
|
if (!this.shadowRoot) return;
|
|
326
386
|
const hsiElement = this.shadowRoot.querySelector(`.horiz-select-items`);
|
|
@@ -368,6 +428,13 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
368
428
|
if (result) return result;
|
|
369
429
|
}
|
|
370
430
|
}
|
|
431
|
+
#scrollSegmentIntoView(depth) {
|
|
432
|
+
if (!this.shadowRoot) return;
|
|
433
|
+
this.shadowRoot.querySelectorAll(`.crumb-segment`)[depth]?.scrollIntoView({
|
|
434
|
+
block: `nearest`,
|
|
435
|
+
inline: `start`
|
|
436
|
+
});
|
|
437
|
+
}
|
|
371
438
|
#setSelected(node) {
|
|
372
439
|
const previous = this.selectedNode;
|
|
373
440
|
if (previous) this.#previousSelectionKey = previous.item?.key ?? ``;
|
|
@@ -375,6 +442,15 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
375
442
|
const previousSet = previous ? /* @__PURE__ */ new Set([previous]) : /* @__PURE__ */ new Set();
|
|
376
443
|
this.selectedNode = node;
|
|
377
444
|
this._selectedNodes = /* @__PURE__ */ new Set([node]);
|
|
445
|
+
if (this.root) {
|
|
446
|
+
const path = this.#findPath(this.root, node);
|
|
447
|
+
if (path) {
|
|
448
|
+
const depth = this.hideRoot && path.length > 1 ? path.length - 2 : path.length - 1;
|
|
449
|
+
requestAnimationFrame(() => {
|
|
450
|
+
this.#scrollSegmentIntoView(depth);
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
}
|
|
378
454
|
this.dispatchEvent(new CustomEvent(`select`, {
|
|
379
455
|
detail: {
|
|
380
456
|
selected: /* @__PURE__ */ new Set([node]),
|
|
@@ -387,6 +463,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
387
463
|
#onLabelClick(node, depth) {
|
|
388
464
|
this._openIdx = -1;
|
|
389
465
|
this.#setSelected(node);
|
|
466
|
+
if (this.leadingCaret) this.#scrollSegmentIntoView(depth);
|
|
390
467
|
this.dispatchEvent(new CustomEvent(`item-click`, {
|
|
391
468
|
detail: {
|
|
392
469
|
node,
|
|
@@ -442,9 +519,52 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
442
519
|
}
|
|
443
520
|
#onSegmentMenuCommand(e, node, depth) {
|
|
444
521
|
const key = e.detail.command;
|
|
522
|
+
if (this.leadingCaret) {
|
|
523
|
+
const child = node.children?.find((c) => c.item.key === key);
|
|
524
|
+
if (child) {
|
|
525
|
+
this.#onChildClick(child, depth + 1);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
if (this.#currentLeadingSiblings) {
|
|
529
|
+
const sibling = this.#currentLeadingSiblings.find((c) => c.item.key === key);
|
|
530
|
+
if (sibling) this.#onChildClick(sibling, depth);
|
|
531
|
+
this.#currentLeadingSiblings = void 0;
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
445
535
|
const child = node.children?.find((c) => c.item.key === key);
|
|
446
536
|
if (child) this.#onChildClick(child, depth + 1);
|
|
447
537
|
}
|
|
538
|
+
#currentLeadingSiblings;
|
|
539
|
+
#getSiblingMenuItems(pathNodes, index) {
|
|
540
|
+
if (index === 0) {
|
|
541
|
+
if (!this.hideRoot || !this.root) return [];
|
|
542
|
+
const siblings = [...this.root.children ?? []].sort((a, b) => (a.item.label ?? ``).localeCompare(b.item.label ?? ``));
|
|
543
|
+
this.#currentLeadingSiblings = siblings;
|
|
544
|
+
return siblings.map((sibling) => html`
|
|
545
|
+
<ixfx-menu-item
|
|
546
|
+
label="${sibling.item.label}"
|
|
547
|
+
command="${sibling.item.key}"
|
|
548
|
+
icon-name="${sibling.item.icon ?? nothing}"
|
|
549
|
+
@click=${() => {
|
|
550
|
+
this.#onChildClick(sibling, index);
|
|
551
|
+
}}
|
|
552
|
+
></ixfx-menu-item>
|
|
553
|
+
`);
|
|
554
|
+
}
|
|
555
|
+
const siblings = [...pathNodes[index - 1].children ?? []].sort((a, b) => (a.item.label ?? ``).localeCompare(b.item.label ?? ``));
|
|
556
|
+
this.#currentLeadingSiblings = siblings;
|
|
557
|
+
return siblings.map((sibling) => html`
|
|
558
|
+
<ixfx-menu-item
|
|
559
|
+
label="${sibling.item.label}"
|
|
560
|
+
command="${sibling.item.key}"
|
|
561
|
+
icon-name="${sibling.item.icon ?? nothing}"
|
|
562
|
+
@click=${() => {
|
|
563
|
+
this.#onChildClick(sibling, index);
|
|
564
|
+
}}
|
|
565
|
+
></ixfx-menu-item>
|
|
566
|
+
`);
|
|
567
|
+
}
|
|
448
568
|
#onChildClick(node, depth) {
|
|
449
569
|
this._openIdx = -1;
|
|
450
570
|
this.#setSelected(node);
|
|
@@ -501,87 +621,146 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
501
621
|
const sel = this.selectedNode;
|
|
502
622
|
if (!r || !sel) return html``;
|
|
503
623
|
this.inputMode = this.tickled.inputMode;
|
|
504
|
-
|
|
624
|
+
let pathNodes = this.#findPath(r, sel) ?? [r];
|
|
625
|
+
if (this.hideRoot && pathNodes.length > 1) pathNodes = pathNodes.slice(1);
|
|
505
626
|
this.#hasChildOptions();
|
|
506
|
-
const parts =
|
|
627
|
+
const parts = [];
|
|
628
|
+
let segmentId = 0;
|
|
629
|
+
pathNodes.forEach((node, i) => {
|
|
507
630
|
const isLast = i === pathNodes.length - 1;
|
|
508
631
|
const isPending = this.#pendingNode === node;
|
|
509
632
|
const isOpen = this._openIdx === i;
|
|
510
633
|
const hasChildren = node.item.isLeaf !== true && (node.children === void 0 || node.children.length > 0);
|
|
511
|
-
const showCaret = !isLast && hasChildren;
|
|
512
634
|
const isTickled = this.tickled.isTickled(i);
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
635
|
+
const showLeadingCaret = this.leadingCaret && (i > 0 || this.hideRoot) && hasChildren;
|
|
636
|
+
const showTrailingCaret = !this.leadingCaret && hasChildren || this.leadingCaret && isLast && hasChildren;
|
|
637
|
+
const siblingMenuItems = showLeadingCaret ? this.#getSiblingMenuItems(pathNodes, i) : [];
|
|
638
|
+
const childMenuItems = (node.children ?? []).map((c) => html`
|
|
639
|
+
<ixfx-menu-item
|
|
640
|
+
label="${c.item.label}"
|
|
516
641
|
command="${c.item.key}"
|
|
517
642
|
icon-name="${c.item.icon ?? nothing}"
|
|
518
643
|
></ixfx-menu-item>
|
|
519
644
|
`);
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
`
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
645
|
+
if (this.caretEmbedded) {
|
|
646
|
+
const canTruncate = !this.noTruncate && !isLast && !isTickled;
|
|
647
|
+
parts.push(html`
|
|
648
|
+
<div class="item crumb-segment ${isTickled ? `tickled` : ``} ${canTruncate ? `truncatable` : ``} ${this.leadingCaret ? `leading-caret` : ``}" data-segment-id="${i}" data-path-index="${i}"
|
|
649
|
+
@click=${(e) => {
|
|
650
|
+
if (e.target.closest(`.caret`)) return;
|
|
651
|
+
this.#onLabelClick(node, i);
|
|
652
|
+
}}
|
|
653
|
+
>
|
|
654
|
+
${showLeadingCaret ? html`
|
|
655
|
+
<span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
|
|
656
|
+
${isPending ? html`<span class="loading-spinner"></span>` : html`
|
|
657
|
+
<ixfx-menu-trigger mode="trigger" label="›" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
|
|
658
|
+
<ixfx-menu-container slot="menu">
|
|
659
|
+
${siblingMenuItems}
|
|
660
|
+
</ixfx-menu-container>
|
|
661
|
+
</ixfx-menu-trigger>
|
|
662
|
+
`}
|
|
663
|
+
</span>
|
|
664
|
+
` : nothing}
|
|
665
|
+
<span class="label">${node.item.label}</span>
|
|
666
|
+
${showTrailingCaret ? html`
|
|
667
|
+
<span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
|
|
668
|
+
${isPending ? html`<span class="loading-spinner"></span>` : html`
|
|
669
|
+
<ixfx-menu-trigger mode="trigger" label="›" placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
|
|
670
|
+
<ixfx-menu-container slot="menu">
|
|
671
|
+
${childMenuItems}
|
|
672
|
+
</ixfx-menu-container>
|
|
673
|
+
</ixfx-menu-trigger>
|
|
674
|
+
`}
|
|
675
|
+
</span>
|
|
676
|
+
` : nothing}
|
|
677
|
+
</div>
|
|
678
|
+
`);
|
|
679
|
+
} else {
|
|
680
|
+
const leadingCaretTickled = showLeadingCaret ? this.tickled.isTickled(segmentId) : false;
|
|
681
|
+
if (showLeadingCaret) {
|
|
682
|
+
parts.push(html`
|
|
683
|
+
<div class="item crumb-segment ${leadingCaretTickled ? `tickled` : ``}" data-segment-id="${segmentId}" data-path-index="${i}"
|
|
684
|
+
@click=${(e) => {
|
|
685
|
+
const trigger = e.target.closest(`.crumb-segment`)?.querySelector(`ixfx-menu-trigger`);
|
|
686
|
+
if (trigger) trigger.openMenu();
|
|
687
|
+
}}
|
|
688
|
+
>
|
|
689
|
+
<span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
|
|
690
|
+
${isPending ? html`<span class="loading-spinner"></span>` : html`
|
|
691
|
+
<ixfx-menu-trigger mode="trigger" label="›" placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
|
|
692
|
+
<ixfx-menu-container slot="menu">
|
|
693
|
+
${siblingMenuItems}
|
|
694
|
+
</ixfx-menu-container>
|
|
695
|
+
</ixfx-menu-trigger>
|
|
696
|
+
`}
|
|
697
|
+
</span>
|
|
698
|
+
</div>
|
|
699
|
+
`);
|
|
700
|
+
segmentId++;
|
|
701
|
+
}
|
|
702
|
+
const labelTickled = this.tickled.isTickled(segmentId);
|
|
703
|
+
const canTruncate = !this.noTruncate && !isLast && !labelTickled;
|
|
704
|
+
parts.push(html`
|
|
705
|
+
<div class="item crumb-segment ${labelTickled ? `tickled` : ``} ${canTruncate ? `truncatable` : ``}" data-segment-id="${segmentId}" data-path-index="${i}"
|
|
706
|
+
@click=${(e) => {
|
|
707
|
+
if (e.target.closest(`.caret`)) return;
|
|
708
|
+
this.#onLabelClick(node, i);
|
|
709
|
+
}}
|
|
710
|
+
>
|
|
711
|
+
<span class="label">${node.item.label}</span>
|
|
712
|
+
</div>
|
|
713
|
+
`);
|
|
714
|
+
segmentId++;
|
|
715
|
+
if (showTrailingCaret) {
|
|
716
|
+
const trailingCaretTickled = this.tickled.isTickled(segmentId);
|
|
717
|
+
parts.push(html`
|
|
718
|
+
<div class="item crumb-segment ${trailingCaretTickled ? `tickled` : ``}" data-segment-id="${segmentId}" data-path-index="${i}"
|
|
719
|
+
@click=${(e) => {
|
|
720
|
+
const trigger = e.target.closest(`.crumb-segment`)?.querySelector(`ixfx-menu-trigger`);
|
|
721
|
+
if (trigger) trigger.openMenu();
|
|
722
|
+
}}
|
|
723
|
+
>
|
|
724
|
+
<span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
|
|
725
|
+
${isPending ? html`<span class="loading-spinner"></span>` : html`
|
|
726
|
+
<ixfx-menu-trigger mode="trigger" label="›" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
|
|
727
|
+
<ixfx-menu-container slot="menu">
|
|
728
|
+
${childMenuItems}
|
|
729
|
+
</ixfx-menu-container>
|
|
730
|
+
</ixfx-menu-trigger>
|
|
731
|
+
`}
|
|
732
|
+
</span>
|
|
733
|
+
</div>
|
|
734
|
+
`);
|
|
735
|
+
segmentId++;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
548
738
|
});
|
|
549
|
-
const childOptions = this.#renderChildOptions();
|
|
550
|
-
const isLastItemTickled = this.tickled.isTickled(pathNodes.length);
|
|
551
739
|
return html`
|
|
552
|
-
<div
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
command="${c.item.key}"
|
|
577
|
-
icon-name="${c.item.icon ?? nothing}"
|
|
578
|
-
></ixfx-menu-item>
|
|
579
|
-
`)}
|
|
580
|
-
</ixfx-menu-container>
|
|
581
|
-
</ixfx-menu-trigger>
|
|
582
|
-
` : nothing}
|
|
583
|
-
${childOptions}
|
|
584
|
-
</div>
|
|
740
|
+
<div class="parts"
|
|
741
|
+
@mouseover=${(e) => {
|
|
742
|
+
if (this.#isWheelScrolling) return;
|
|
743
|
+
const target = e.target;
|
|
744
|
+
if (!(target instanceof HTMLElement)) return;
|
|
745
|
+
const segment = target.closest(`.crumb-segment`);
|
|
746
|
+
if (!segment) return;
|
|
747
|
+
const segmentId = parseInt(segment.dataset.segmentId ?? ``, 10);
|
|
748
|
+
if (Number.isNaN(segmentId)) return;
|
|
749
|
+
const pathIndex = parseInt(segment.dataset.pathIndex ?? ``, 10);
|
|
750
|
+
const node = pathNodes[pathIndex];
|
|
751
|
+
if (!node) return;
|
|
752
|
+
this.tickled.handlePointerEnter(segmentId);
|
|
753
|
+
this.dispatchEvent(new CustomEvent(`tickle`, {
|
|
754
|
+
detail: {
|
|
755
|
+
node,
|
|
756
|
+
depth: pathIndex
|
|
757
|
+
},
|
|
758
|
+
bubbles: true,
|
|
759
|
+
composed: true
|
|
760
|
+
}));
|
|
761
|
+
}}
|
|
762
|
+
>${parts}<div class="trailing"></div></div>
|
|
763
|
+
${this.showSuggestions ? this.#renderChildOptions() : nothing}
|
|
585
764
|
`;
|
|
586
765
|
}
|
|
587
766
|
#renderChildOptions() {
|
|
@@ -635,36 +814,66 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
635
814
|
tickledItemStyles,
|
|
636
815
|
css`
|
|
637
816
|
:host {
|
|
638
|
-
--
|
|
639
|
-
--
|
|
640
|
-
--
|
|
817
|
+
--crumb-item-bg: var(--item-bg, transparent);
|
|
818
|
+
--crumb-item-bg-tickled: var(--item-bg-tickled);
|
|
819
|
+
--crumb-item-text-tickled: var(--item-text-tickled);
|
|
820
|
+
--crumb-item-border: var(--item-border);
|
|
821
|
+
--crumb-item-border-tickled: var(--item-border-tickled);
|
|
822
|
+
--crumb-item-padding: var(--space-xs);
|
|
823
|
+
--crumb-item-border-radius: var(--item-border-radius);
|
|
824
|
+
--crumb-item-gap: var(--space-xs);
|
|
825
|
+
--crumb-separator: var(--surface-muted-text);
|
|
826
|
+
--crumb-truncate-min-width: 10ch;
|
|
827
|
+
--crumb-fade-width: 30px;
|
|
828
|
+
--crumb-fade-color: var(--surface-3);
|
|
829
|
+
position: relative;
|
|
641
830
|
display: flex;
|
|
642
831
|
overflow: scroll;
|
|
643
832
|
width: 100%;
|
|
644
833
|
scroll-snap-type: x mandatory;
|
|
645
834
|
scrollbar-width: none;
|
|
646
|
-
|
|
647
|
-
/* Breadcrumb tickled overrides — no layout shift: keep transparent border at rest */
|
|
648
|
-
--item-padding: 0;
|
|
649
835
|
}
|
|
650
836
|
|
|
651
|
-
:host(
|
|
837
|
+
:host(:focus) {
|
|
652
838
|
outline: none;
|
|
653
839
|
}
|
|
654
840
|
|
|
655
|
-
:host(:focus
|
|
841
|
+
:host(:focus) .parts {
|
|
656
842
|
outline: 2px solid var(--accent);
|
|
657
843
|
outline-offset: 2px;
|
|
658
844
|
}
|
|
659
845
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
846
|
+
:host::before,
|
|
847
|
+
:host::after {
|
|
848
|
+
content: '';
|
|
849
|
+
position: absolute;
|
|
850
|
+
top: 0;
|
|
851
|
+
bottom: 0;
|
|
852
|
+
width: var(--crumb-fade-width);
|
|
853
|
+
pointer-events: none;
|
|
854
|
+
opacity: 0;
|
|
855
|
+
transition: opacity 0.2s ease;
|
|
856
|
+
z-index: 1;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
:host::before {
|
|
860
|
+
left: 0;
|
|
861
|
+
background: linear-gradient(to right, var(--crumb-fade-color), transparent);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
:host::after {
|
|
865
|
+
right: 0;
|
|
866
|
+
background: linear-gradient(to left, var(--crumb-fade-color), transparent);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
:host(.has-left-fade)::before,
|
|
870
|
+
:host(.has-right-fade)::after {
|
|
871
|
+
opacity: 1;
|
|
664
872
|
}
|
|
665
873
|
|
|
666
874
|
.parts {
|
|
667
875
|
display: flex;
|
|
876
|
+
gap: var(--space-s);
|
|
668
877
|
}
|
|
669
878
|
|
|
670
879
|
.trailing {
|
|
@@ -676,21 +885,68 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
676
885
|
.crumb-segment {
|
|
677
886
|
display: flex;
|
|
678
887
|
align-items: center;
|
|
888
|
+
flex-shrink: 0;
|
|
889
|
+
background: var(--crumb-item-bg);
|
|
890
|
+
border: var(--crumb-item-border);
|
|
891
|
+
border-radius: var(--crumb-item-border-radius);
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.crumb-segment.leading-caret {
|
|
895
|
+
flex-direction: row;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.crumb-segment.leading-caret-only {
|
|
899
|
+
flex-direction: row;
|
|
900
|
+
padding: var(--crumb-item-padding);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.crumb-segment.trailing-caret-only {
|
|
904
|
+
flex-direction: row;
|
|
905
|
+
padding: var(--crumb-item-padding);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
.crumb-segment.tickled {
|
|
909
|
+
background: var(--crumb-item-bg-tickled);
|
|
910
|
+
border-color: var(--crumb-item-border-tickled);
|
|
911
|
+
color: var(--crumb-item-text-tickled);
|
|
912
|
+
flex-shrink: 0;
|
|
913
|
+
min-width: auto;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.crumb-segment.truncatable {
|
|
917
|
+
flex-shrink: 1;
|
|
918
|
+
min-width: min(var(--crumb-truncate-min-width), auto);
|
|
919
|
+
overflow: hidden;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.crumb-segment.truncatable .label {
|
|
923
|
+
overflow: hidden;
|
|
924
|
+
text-overflow: ellipsis;
|
|
925
|
+
white-space: nowrap;
|
|
926
|
+
min-width: 0;
|
|
679
927
|
}
|
|
680
928
|
|
|
681
929
|
.label {
|
|
682
930
|
cursor: pointer;
|
|
683
|
-
margin-right: var(--padding-s);
|
|
684
931
|
white-space: nowrap;
|
|
932
|
+
color: inherit;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
.crumb-segment.tickled .label {
|
|
936
|
+
color: var(--crumb-item-text-tickled);
|
|
937
|
+
overflow: visible;
|
|
938
|
+
text-overflow: clip;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
.crumb-segment ixfx-menu-trigger {
|
|
942
|
+
--ixfx-button-padding: var(--space-xs) 8px;
|
|
685
943
|
}
|
|
686
944
|
|
|
687
945
|
.caret {
|
|
688
946
|
position: relative;
|
|
689
|
-
cursor: pointer;
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
margin-right: var(--padding-s);
|
|
693
|
-
color: var(--separator);
|
|
947
|
+
cursor: pointer;
|
|
948
|
+
|
|
949
|
+
color: var(--crumb-separator);
|
|
694
950
|
display: inline-flex;
|
|
695
951
|
align-items: center;
|
|
696
952
|
justify-content: center;
|
|
@@ -728,15 +984,15 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
728
984
|
}
|
|
729
985
|
|
|
730
986
|
.separator {
|
|
731
|
-
margin-left: var(--
|
|
732
|
-
margin-right: var(--
|
|
733
|
-
color: var(--separator);
|
|
987
|
+
margin-left: var(--crumb-item-gap);
|
|
988
|
+
margin-right: var(--crumb-item-gap);
|
|
989
|
+
color: var(--crumb-separator);
|
|
734
990
|
}
|
|
735
991
|
|
|
736
992
|
.separator-trigger {
|
|
737
993
|
display: inline-flex;
|
|
738
|
-
margin-left: var(--
|
|
739
|
-
margin-right: var(--
|
|
994
|
+
margin-left: var(--crumb-item-gap);
|
|
995
|
+
margin-right: var(--crumb-item-gap);
|
|
740
996
|
--_trigger-hover-bg: transparent;
|
|
741
997
|
--_trigger-hover-opacity: 0.6;
|
|
742
998
|
}
|
|
@@ -744,7 +1000,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
|
|
|
744
1000
|
.separator-trigger::part(base) {
|
|
745
1001
|
background: none;
|
|
746
1002
|
border: none;
|
|
747
|
-
color: var(--separator);
|
|
1003
|
+
color: var(--crumb-separator);
|
|
748
1004
|
padding: 0;
|
|
749
1005
|
cursor: pointer;
|
|
750
1006
|
font-size: inherit;
|
|
@@ -809,13 +1065,37 @@ __decorate([property({
|
|
|
809
1065
|
attribute: `selection-filter`
|
|
810
1066
|
})], CrumbNavigationElement.prototype, "selectionFilter", void 0);
|
|
811
1067
|
__decorate([state()], CrumbNavigationElement.prototype, "_openIdx", void 0);
|
|
812
|
-
__decorate([state()], CrumbNavigationElement.prototype, "_isFocused", void 0);
|
|
813
1068
|
__decorate([state()], CrumbNavigationElement.prototype, "_menuOpen", void 0);
|
|
814
1069
|
__decorate([state()], CrumbNavigationElement.prototype, "_focusOnNarrowedText", void 0);
|
|
815
1070
|
__decorate([property({
|
|
816
1071
|
reflect: true,
|
|
817
1072
|
attribute: `input-mode`
|
|
818
1073
|
})], CrumbNavigationElement.prototype, "inputMode", void 0);
|
|
1074
|
+
__decorate([property({
|
|
1075
|
+
type: Boolean,
|
|
1076
|
+
reflect: true,
|
|
1077
|
+
attribute: `no-truncate`
|
|
1078
|
+
})], CrumbNavigationElement.prototype, "noTruncate", void 0);
|
|
1079
|
+
__decorate([property({
|
|
1080
|
+
type: Boolean,
|
|
1081
|
+
reflect: true,
|
|
1082
|
+
attribute: `show-suggestions`
|
|
1083
|
+
})], CrumbNavigationElement.prototype, "showSuggestions", void 0);
|
|
1084
|
+
__decorate([property({
|
|
1085
|
+
type: Boolean,
|
|
1086
|
+
reflect: true,
|
|
1087
|
+
attribute: `leading-caret`
|
|
1088
|
+
})], CrumbNavigationElement.prototype, "leadingCaret", void 0);
|
|
1089
|
+
__decorate([property({
|
|
1090
|
+
type: Boolean,
|
|
1091
|
+
reflect: true,
|
|
1092
|
+
attribute: `caret-embedded`
|
|
1093
|
+
})], CrumbNavigationElement.prototype, "caretEmbedded", void 0);
|
|
1094
|
+
__decorate([property({
|
|
1095
|
+
type: Boolean,
|
|
1096
|
+
reflect: true,
|
|
1097
|
+
attribute: `hideroot`
|
|
1098
|
+
})], CrumbNavigationElement.prototype, "hideRoot", void 0);
|
|
819
1099
|
CrumbNavigationElement = __decorate([safeCustomElement(`ixfx-crumb-navigation`)], CrumbNavigationElement);
|
|
820
1100
|
//#endregion
|
|
821
1101
|
export { CrumbNavigationElement };
|