@ixfx/components 0.5.17 → 0.5.19

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 (71) hide show
  1. package/bundle/index.d.ts +71 -8
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +563 -116
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +4 -2
  6. package/dist/ac-text.d.ts +1 -1
  7. package/dist/button.d.ts +1 -1
  8. package/dist/button.d.ts.map +1 -1
  9. package/dist/{colour-picker-DbypcEp6.js → colour-picker-37NyVenk.js} +2 -2
  10. package/dist/{colour-picker-DbypcEp6.js.map → colour-picker-37NyVenk.js.map} +1 -1
  11. package/dist/colour-picker.d.ts +1 -1
  12. package/dist/colour-picker.js +1 -1
  13. package/dist/{crumb-navigation-DFqTzElw.js → crumb-navigation-BrB0r14u.js} +169 -98
  14. package/dist/crumb-navigation-BrB0r14u.js.map +1 -0
  15. package/dist/crumbs.d.ts +3 -1
  16. package/dist/crumbs.d.ts.map +1 -1
  17. package/dist/crumbs.js +1 -1
  18. package/dist/{defaults-DcE8RQJc.js → defaults-BkWCPJFL.js} +7 -1
  19. package/dist/{defaults-DcE8RQJc.js.map → defaults-BkWCPJFL.js.map} +1 -1
  20. package/dist/{icon-DpA9x2Ve.d.ts → icon-BUwP1CZ1.d.ts} +2 -2
  21. package/dist/icon-BUwP1CZ1.d.ts.map +1 -0
  22. package/dist/icons.d.ts +2 -2
  23. package/dist/icons.js +1 -1
  24. package/dist/{index-D_ftz_IT.d.ts → index-BKAlRgbq.d.ts} +2 -2
  25. package/dist/{index-D_ftz_IT.d.ts.map → index-BKAlRgbq.d.ts.map} +1 -1
  26. package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +2 -2
  27. package/dist/{index-CoqtMSd9.d.ts.map → index-BUB5SICW.d.ts.map} +1 -1
  28. package/dist/{index-DfEkTGvT.d.ts → index-DkhBGHgF.d.ts} +3 -3
  29. package/dist/{index-DfEkTGvT.d.ts.map → index-DkhBGHgF.d.ts.map} +1 -1
  30. package/dist/{index-BtGFYfaK.d.ts → index-RqMh1i-O.d.ts} +2 -2
  31. package/dist/{index-BtGFYfaK.d.ts.map → index-RqMh1i-O.d.ts.map} +1 -1
  32. package/dist/index.d.ts +55 -9
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +288 -10
  35. package/dist/index.js.map +1 -1
  36. package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +2 -2
  37. package/dist/{labelled-input-base-DiTme1JO.d.ts.map → labelled-input-base-Dp_9KP0G.d.ts.map} +1 -1
  38. package/dist/labelled-radial-input.d.ts +2 -2
  39. package/dist/labelled-radial-input.d.ts.map +1 -1
  40. package/dist/labelled-range-input.d.ts +1 -1
  41. package/dist/{menu-B8gE2MSo.js → menu-CdwSe_XN.js} +2 -2
  42. package/dist/{menu-B8gE2MSo.js.map → menu-CdwSe_XN.js.map} +1 -1
  43. package/dist/{menu-item-DSyf9f_L.d.ts → menu-item-BG5w7fi4.d.ts} +4 -2
  44. package/dist/menu-item-BG5w7fi4.d.ts.map +1 -0
  45. package/dist/{menu-item-BYRvfyXK.js → menu-item-CrmUwIoJ.js} +7 -2
  46. package/dist/menu-item-CrmUwIoJ.js.map +1 -0
  47. package/dist/menu.d.ts +2 -2
  48. package/dist/menu.js +2 -2
  49. package/dist/panel.d.ts +1 -1
  50. package/dist/split-layout.d.ts +7 -1
  51. package/dist/split-layout.d.ts.map +1 -1
  52. package/dist/split-layout.js +84 -14
  53. package/dist/split-layout.js.map +1 -1
  54. package/dist/style.css +4 -2
  55. package/dist/{tab-list-ih-0I0NE.d.ts → tab-list-Beuh2nom.d.ts} +10 -3
  56. package/dist/tab-list-Beuh2nom.d.ts.map +1 -0
  57. package/dist/{tab-list-6W5CgXix.js → tab-list-mAoD6L0e.js} +20 -2
  58. package/dist/tab-list-mAoD6L0e.js.map +1 -0
  59. package/dist/tabs.d.ts +1 -1
  60. package/dist/tabs.js +1 -1
  61. package/docs-user/README.md +1 -0
  62. package/docs-user/crumbs.md +4 -0
  63. package/docs-user/select-horiz.md +114 -0
  64. package/docs-user/split-layout.md +29 -7
  65. package/package.json +3 -1
  66. package/dist/crumb-navigation-DFqTzElw.js.map +0 -1
  67. package/dist/icon-DpA9x2Ve.d.ts.map +0 -1
  68. package/dist/menu-item-BYRvfyXK.js.map +0 -1
  69. package/dist/menu-item-DSyf9f_L.d.ts.map +0 -1
  70. package/dist/tab-list-6W5CgXix.js.map +0 -1
  71. package/dist/tab-list-ih-0I0NE.d.ts.map +0 -1
@@ -2,7 +2,7 @@ import { n as tickledStyles, r as TickledController, t as tickledItemStyles } fr
2
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-BYRvfyXK.js";
5
+ import "./menu-item-CrmUwIoJ.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, unsafeCSS } from "lit";
@@ -90,6 +90,8 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
90
90
  this.leadingCaret = false;
91
91
  this.caretEmbedded = true;
92
92
  this.hideRoot = false;
93
+ this.padEnding = false;
94
+ this.withUp = false;
93
95
  this.#previousSelectionKey = ``;
94
96
  this.#menuOpenedByKeyboard = false;
95
97
  this.#currentOpenTrigger = null;
@@ -127,7 +129,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
127
129
  const r = this.root;
128
130
  const sel = this.selectedNode;
129
131
  if (!r || !sel) break;
130
- const totalItems = (this.#findPath(r, sel) ?? [r]).length + (this.#hasChildOptions() ? 1 : 0);
132
+ const totalItems = this.#getTickledItems().length;
131
133
  const currentTickled = this.tickled.tickledId ?? -1;
132
134
  if (e.key === `ArrowLeft`) {
133
135
  if (currentTickled > 0) this.tickled.handleKeyboardNavigation(`previous`);
@@ -140,13 +142,13 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
140
142
  const r = this.root;
141
143
  const sel = this.selectedNode;
142
144
  if (!r || !sel) return;
143
- const totalItems = (this.#findPath(r, sel) ?? [r]).length + (this.#hasChildOptions() ? 1 : 0);
145
+ const totalItems = this.#getTickledItems().length;
144
146
  const currentTickled = this.tickled.tickledId ?? -1;
145
147
  switch (e.key) {
146
148
  case `ArrowRight`:
147
149
  e.preventDefault();
148
150
  if (currentTickled < totalItems - 1) this.tickled.handleKeyboardNavigation(`next`);
149
- else if (currentTickled === totalItems - 1) this.#shiftFocusToNarrowedText();
151
+ else if (currentTickled === totalItems - 1 && this.#canFocusSuggestions()) this.#shiftFocusToNarrowedText();
150
152
  break;
151
153
  case `ArrowLeft`:
152
154
  e.preventDefault();
@@ -166,8 +168,9 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
166
168
  }
167
169
  break;
168
170
  case `Enter`:
171
+ case ` `:
169
172
  e.preventDefault();
170
- this.#handleEnter();
173
+ this.#activateTickled();
171
174
  break;
172
175
  case `Escape`:
173
176
  e.preventDefault();
@@ -175,16 +178,12 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
175
178
  this.tickled.clearTickled();
176
179
  this.blur();
177
180
  break;
178
- case `Tab`: if (e.shiftKey) {
179
- e.preventDefault();
180
- this.#shiftFocusToPath();
181
- } else if (currentTickled === totalItems - 1) {
182
- e.preventDefault();
183
- this._menuOpen = false;
184
- this._focusOnNarrowedText = true;
185
- const narrowedText = this.shadowRoot?.querySelector(`ixfx-narrowed-text`);
186
- if (narrowedText) narrowedText.focus();
187
- }
181
+ case `Tab`:
182
+ if (e.shiftKey) break;
183
+ if (currentTickled === totalItems - 1 && this.#canFocusSuggestions()) {
184
+ e.preventDefault();
185
+ this.#shiftFocusToNarrowedText();
186
+ }
188
187
  }
189
188
  };
190
189
  this.#onNarrowedTextBlur = () => {
@@ -236,7 +235,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
236
235
  enabled: true
237
236
  });
238
237
  });
239
- if (this.#hasChildOptions()) items.push({
238
+ if (this.#canFocusSuggestions()) items.push({
240
239
  id: pathNodes.length,
241
240
  enabled: true
242
241
  });
@@ -272,8 +271,8 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
272
271
  if (!r || !sel) return;
273
272
  const pathNodes = this.#findPath(r, sel) ?? [r];
274
273
  let el = null;
275
- if (index < pathNodes.length) el = this.shadowRoot?.querySelectorAll(`.crumb-segment`)[index] ?? null;
276
- else if (index === pathNodes.length) el = this.shadowRoot?.querySelector(`#child-options-trigger`) ?? null;
274
+ if (this.caretEmbedded && this.#canFocusSuggestions() && index === pathNodes.length) el = this.shadowRoot?.querySelector(`ixfx-narrowed-text`) ?? null;
275
+ else el = this.shadowRoot?.querySelectorAll(`.crumb-segment`)[index] ?? null;
277
276
  el?.scrollIntoView({
278
277
  inline: `nearest`,
279
278
  block: `nearest`,
@@ -286,6 +285,10 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
286
285
  const isPending = this.#pendingNode === s;
287
286
  return (s.children ?? []).length > 0 || isPending;
288
287
  }
288
+ /** True when the suggestions (narrowed-text) sub-part is renderable and focusable. */
289
+ #canFocusSuggestions() {
290
+ return this.showSuggestions && this.#hasChildOptions();
291
+ }
289
292
  #onFocus;
290
293
  #onBlur;
291
294
  #getHostContainer() {
@@ -298,26 +301,18 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
298
301
  const r = this.root;
299
302
  const sel = this.selectedNode;
300
303
  if (!r || !sel) return;
301
- if (currentTickled < (this.#findPath(r, sel) ?? [r]).length - 1) {
302
- const trigger = (this.shadowRoot?.querySelectorAll(`.crumb-segment`))?.[currentTickled]?.querySelector(`.caret ixfx-menu-trigger`);
303
- if (trigger) {
304
- this.#menuOpenedByKeyboard = true;
305
- this.#currentOpenTrigger = trigger;
306
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
307
- trigger.openMenu();
308
- this.#propagateInputModeToMenu();
309
- return;
310
- }
304
+ const pathNodes = this.#findPath(r, sel) ?? [r];
305
+ if (this.caretEmbedded && this.#canFocusSuggestions() && currentTickled === pathNodes.length) {
306
+ this.#shiftFocusToNarrowedText();
307
+ return;
311
308
  }
312
- if (this.#hasChildOptions()) {
313
- const trigger = this.shadowRoot?.querySelector(`#child-options-trigger`);
314
- if (trigger) {
315
- this.#menuOpenedByKeyboard = true;
316
- this.#currentOpenTrigger = trigger;
317
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
318
- trigger.openMenu();
319
- this.#propagateInputModeToMenu();
320
- }
309
+ const trigger = (this.shadowRoot?.querySelectorAll(`.crumb-segment`))?.[currentTickled]?.querySelector(`.caret ixfx-menu-trigger`);
310
+ if (trigger) {
311
+ this.#menuOpenedByKeyboard = true;
312
+ this.#currentOpenTrigger = trigger;
313
+ document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
314
+ trigger.openMenu();
315
+ this.#propagateInputModeToMenu();
321
316
  }
322
317
  }
323
318
  #propagateInputModeToMenu() {
@@ -330,40 +325,24 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
330
325
  #onMenuTriggerClose;
331
326
  #onMenuKeyNav;
332
327
  #onKeyDown;
333
- #handleEnter() {
328
+ /** Activates the currently tickled item, as if it had been clicked. */
329
+ #activateTickled() {
330
+ const currentTickled = this.tickled.tickledId;
331
+ if (currentTickled === void 0) return;
334
332
  const r = this.root;
335
333
  const sel = this.selectedNode;
336
334
  if (!r || !sel) return;
337
335
  const pathNodes = this.#findPath(r, sel) ?? [r];
338
- const hasChildOptions = this.#hasChildOptions();
339
- const currentTickled = this.tickled.tickledId ?? -1;
340
- if (currentTickled < pathNodes.length) {
341
- const node = pathNodes[currentTickled];
342
- this.#setSelected(node);
343
- this._menuOpen = false;
344
- this.dispatchEvent(new CustomEvent(`item-click`, {
345
- detail: {
346
- node,
347
- depth: currentTickled
348
- },
349
- bubbles: true,
350
- composed: true
351
- }));
352
- } else if (hasChildOptions && currentTickled === pathNodes.length) {
353
- this._menuOpen = true;
354
- this.#menuOpenedByKeyboard = true;
355
- const trigger = this.shadowRoot?.querySelector(`#child-options-trigger`);
356
- if (trigger) {
357
- this.#currentOpenTrigger = trigger;
358
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
359
- trigger.openMenu();
360
- this.#propagateInputModeToMenu();
361
- }
336
+ if (this.caretEmbedded && this.#canFocusSuggestions() && currentTickled === pathNodes.length) {
337
+ this.#shiftFocusToNarrowedText();
338
+ return;
362
339
  }
340
+ (this.shadowRoot?.querySelector(`.crumb-segment[data-segment-id="${currentTickled}"]`))?.click();
363
341
  }
364
342
  #shiftFocusToNarrowedText() {
365
343
  const narrowedText = this.shadowRoot?.querySelector(`ixfx-narrowed-text`);
366
344
  if (narrowedText) {
345
+ this._menuOpen = false;
367
346
  this._focusOnNarrowedText = true;
368
347
  narrowedText.focus();
369
348
  }
@@ -491,6 +470,24 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
491
470
  inline: `start`
492
471
  });
493
472
  }
473
+ #updateTrailingWidth() {
474
+ if (!this.padEnding || !this.shadowRoot) return;
475
+ const hostContainer = this.shadowRoot.querySelector(`.host-container`);
476
+ const trailing = this.shadowRoot.querySelector(`.trailing`);
477
+ if (!hostContainer || !trailing) return;
478
+ const segments = this.shadowRoot.querySelectorAll(`.crumb-segment`);
479
+ const lastSegment = segments[segments.length - 1];
480
+ if (!lastSegment) return;
481
+ const containerWidth = hostContainer.getBoundingClientRect().width;
482
+ const itemWidth = lastSegment.getBoundingClientRect().width;
483
+ if (itemWidth < containerWidth) {
484
+ trailing.style.width = `${containerWidth - itemWidth - 5}px`;
485
+ requestAnimationFrame(() => {
486
+ if (hostContainer.scrollWidth <= hostContainer.clientWidth) hostContainer.style.setProperty(`--scroll-fade-x-start`, `0px`, `important`);
487
+ else hostContainer.style.removeProperty(`--scroll-fade-x-start`);
488
+ });
489
+ } else trailing.style.width = ``;
490
+ }
494
491
  #setSelected(node) {
495
492
  const previous = this.selectedNode;
496
493
  if (previous) this.#previousSelectionKey = previous.item?.key ?? ``;
@@ -498,11 +495,14 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
498
495
  const previousSet = previous ? /* @__PURE__ */ new Set([previous]) : /* @__PURE__ */ new Set();
499
496
  this.selectedNode = node;
500
497
  this._selectedNodes = /* @__PURE__ */ new Set([node]);
501
- if (this.leadingCaret && this.root) {
498
+ if (this.root) {
502
499
  const path = this.#findPath(this.root, node);
503
500
  if (path) {
504
501
  const depth = this.hideRoot && path.length > 1 ? path.length - 2 : path.length - 1;
505
502
  requestAnimationFrame(() => {
503
+ this.#updateTrailingWidth();
504
+ const hostContainer = this.#getHostContainer();
505
+ if (hostContainer) hostContainer.scrollLeft = 0;
506
506
  this.#scrollSegmentIntoView(depth);
507
507
  });
508
508
  }
@@ -519,7 +519,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
519
519
  #onLabelClick(node, depth) {
520
520
  this._openIdx = -1;
521
521
  this.#setSelected(node);
522
- if (this.leadingCaret) this.#scrollSegmentIntoView(depth);
522
+ this.#scrollSegmentIntoView(depth);
523
523
  this.dispatchEvent(new CustomEvent(`item-click`, {
524
524
  detail: {
525
525
  node,
@@ -633,6 +633,15 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
633
633
  composed: true
634
634
  }));
635
635
  }
636
+ #onUpClick() {
637
+ const r = this.root;
638
+ const sel = this.selectedNode;
639
+ if (!r || !sel) return;
640
+ const path = this.#findPath(r, sel);
641
+ if (!path || path.length <= 1) return;
642
+ const parent = path[path.length - 2];
643
+ this.#setSelected(parent);
644
+ }
636
645
  /** Navigate to a node by key path. Returns false if any key is not found in already-loaded children. */
637
646
  navigateTo(keys) {
638
647
  if (!this.root?.children) return false;
@@ -680,6 +689,9 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
680
689
  let pathNodes = this.#findPath(r, sel) ?? [r];
681
690
  if (this.hideRoot && pathNodes.length > 1) pathNodes = pathNodes.slice(1);
682
691
  this.#hasChildOptions();
692
+ const isAtRoot = (() => {
693
+ return (this.#findPath(r, sel) ?? [r]).length <= 1;
694
+ })();
683
695
  const parts = [];
684
696
  let segmentId = 0;
685
697
  pathNodes.forEach((node, i) => {
@@ -710,7 +722,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
710
722
  ${showLeadingCaret ? html`
711
723
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
712
724
  ${isPending ? html`<span class="loading-spinner"></span>` : html`
713
- <ixfx-menu-trigger mode="trigger" label="›" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
725
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
714
726
  <ixfx-menu-container slot="menu">
715
727
  ${siblingMenuItems}
716
728
  </ixfx-menu-container>
@@ -722,7 +734,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
722
734
  ${showTrailingCaret ? html`
723
735
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
724
736
  ${isPending ? html`<span class="loading-spinner"></span>` : html`
725
- <ixfx-menu-trigger mode="trigger" label="›" placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
737
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
726
738
  <ixfx-menu-container slot="menu">
727
739
  ${childMenuItems}
728
740
  </ixfx-menu-container>
@@ -744,7 +756,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
744
756
  >
745
757
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
746
758
  ${isPending ? html`<span class="loading-spinner"></span>` : html`
747
- <ixfx-menu-trigger mode="trigger" label="›" placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
759
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
748
760
  <ixfx-menu-container slot="menu">
749
761
  ${siblingMenuItems}
750
762
  </ixfx-menu-container>
@@ -779,7 +791,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
779
791
  >
780
792
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
781
793
  ${isPending ? html`<span class="loading-spinner"></span>` : html`
782
- <ixfx-menu-trigger mode="trigger" label="›" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
794
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
783
795
  <ixfx-menu-container slot="menu">
784
796
  ${childMenuItems}
785
797
  </ixfx-menu-container>
@@ -793,18 +805,29 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
793
805
  }
794
806
  });
795
807
  return html`
796
- <div
797
- class="host-container scroll-fade-x"
798
- tabindex="0"
799
- @focus=${this.#onFocus}
800
- @blur=${this.#onBlur}
801
- @keydown=${this.#onKeyDown}
802
- @click=${this.#onHostClick}
803
- @menu-trigger-close=${this.#onMenuTriggerClose}
804
- @mouseout=${(e) => this.tickled.handlePointerLeave(e)}
805
- >
806
- <div class="parts"
807
- @mouseover=${(e) => {
808
+ <div class="crumb-wrapper">
809
+ ${this.withUp ? html`
810
+ <button
811
+ class="up-button"
812
+ ?disabled=${isAtRoot}
813
+ aria-label="Go up one level"
814
+ @click=${this.#onUpClick}
815
+ >
816
+ <ixfx-icon name="folder-up"></ixfx-icon>
817
+ </button>
818
+ ` : nothing}
819
+ <div
820
+ class="host-container scroll-fade-x"
821
+ tabindex="0"
822
+ @focus=${this.#onFocus}
823
+ @blur=${this.#onBlur}
824
+ @keydown=${this.#onKeyDown}
825
+ @click=${this.#onHostClick}
826
+ @menu-trigger-close=${this.#onMenuTriggerClose}
827
+ @mouseout=${(e) => this.tickled.handlePointerLeave(e)}
828
+ >
829
+ <div class="parts"
830
+ @mouseover=${(e) => {
808
831
  if (this.#isWheelScrolling) return;
809
832
  const target = e.target;
810
833
  if (!(target instanceof HTMLElement)) return;
@@ -825,8 +848,9 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
825
848
  composed: true
826
849
  }));
827
850
  }}
828
- >${parts}<div class="trailing"></div></div>
829
- ${this.showSuggestions ? this.#renderChildOptions() : nothing}
851
+ >${parts}${this.padEnding ? html`<div class="trailing"></div>` : nothing}</div>
852
+ ${this.showSuggestions ? this.#renderChildOptions() : nothing}
853
+ </div>
830
854
  </div>
831
855
  `;
832
856
  }
@@ -887,7 +911,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
887
911
  --crumb-item-text-tickled: var(--item-text-tickled);
888
912
  --crumb-item-border: var(--item-border);
889
913
  --crumb-item-border-tickled: var(--item-border-tickled);
890
- --crumb-item-padding: var(--item-padding, var(--space-xs));
914
+ --crumb-item-padding: var(--space-s, 2px);
891
915
  --crumb-item-border-radius: var(--item-border-radius);
892
916
  --crumb-item-gap: var(--item-gap, var(--space-xs));
893
917
  --crumb-separator: var(--surface-muted-text);
@@ -896,24 +920,65 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
896
920
  width: 100%;
897
921
  }
898
922
 
899
- :host(.focused) {
900
- outline: none;
901
- }
902
-
903
- :host(:focus-within) .host-container {
923
+ /* Outline goes on :host, not .host-container: .host-container carries the
924
+ * scroll-fade mask-image, and CSS masks clip everything painted outside
925
+ * the masked box - including an outline, which paints outside the border edge. */
926
+ :host(:focus-within) {
904
927
  outline: 2px solid var(--accent);
905
928
  outline-offset: 2px;
906
929
  }
907
930
 
931
+ .crumb-wrapper {
932
+ display: flex;
933
+ align-items: center;
934
+ gap: var(--crumb-item-gap);
935
+ width: 100%;
936
+ }
937
+
938
+ .up-button {
939
+ display: inline-flex;
940
+ align-items: center;
941
+ justify-content: center;
942
+ flex-shrink: 0;
943
+ background: var(--crumb-item-bg);
944
+ border: var(--crumb-item-border);
945
+ border-radius: var(--crumb-item-border-radius);
946
+ padding: var(--crumb-item-padding);
947
+ cursor: pointer;
948
+ color: inherit;
949
+ }
950
+
951
+ .up-button:disabled {
952
+ opacity: 0.5;
953
+ cursor: not-allowed;
954
+ }
955
+
956
+ .up-button:hover:not(:disabled) {
957
+ background: var(--crumb-item-bg-tickled);
958
+ border-color: var(--crumb-item-border-tickled);
959
+ }
960
+
961
+ .up-button ixfx-icon {
962
+ width: 1em;
963
+ height: 1em;
964
+ pointer-events: none;
965
+ }
966
+
908
967
  /* Edge fade (shows/hides based on scroll position) comes from the
909
968
  * shared .scroll-fade-x class - see ../styles/scroll-fade.ts */
910
969
  .host-container {
911
970
  display: flex;
912
- width: 100%;
971
+ flex: 1;
972
+ min-width: 0;
913
973
  outline: none;
914
974
  overflow: scroll;
915
975
  scroll-snap-type: x mandatory;
916
976
  scrollbar-width: none;
977
+ overscroll-behavior: none;
978
+ }
979
+
980
+ .host-container::-webkit-scrollbar {
981
+ display: none;
917
982
  }
918
983
 
919
984
  .parts {
@@ -922,9 +987,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
922
987
  }
923
988
 
924
989
  .trailing {
925
- flex: 1;
926
- min-width: 1em;
927
- cursor: pointer;
990
+ flex-shrink: 0;
928
991
  }
929
992
 
930
993
  .crumb-segment {
@@ -934,6 +997,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
934
997
  background: var(--crumb-item-bg);
935
998
  border: var(--crumb-item-border);
936
999
  border-radius: var(--crumb-item-border-radius);
1000
+ padding:0;
937
1001
  }
938
1002
 
939
1003
  .crumb-segment.leading-caret {
@@ -962,6 +1026,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
962
1026
  }
963
1027
 
964
1028
  .label {
1029
+ padding: var(--crumb-item-padding);
965
1030
  cursor: pointer;
966
1031
  white-space: nowrap;
967
1032
  color: inherit;
@@ -982,15 +1047,12 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
982
1047
  }
983
1048
 
984
1049
  .crumb-segment ixfx-menu-trigger {
985
- --ixfx-button-padding: var(--space-xs) 8px;
1050
+ --ixfx-button-padding: var(--space-s, 2px);
986
1051
  }
987
1052
 
988
1053
  .caret {
989
1054
  position: relative;
990
1055
  cursor: pointer;
991
- padding: var(--crumb-item-padding);
992
- margin-left: var(--crumb-item-gap);
993
- margin-right: var(--crumb-item-gap);
994
1056
  color: var(--crumb-separator);
995
1057
  display: inline-flex;
996
1058
  align-items: center;
@@ -1017,7 +1079,6 @@ let CrumbNavigationElement = class CrumbNavigationElement extends LitElement {
1017
1079
  background: none;
1018
1080
  border: none;
1019
1081
  color: inherit;
1020
- padding: 0;
1021
1082
  cursor: pointer;
1022
1083
  font-size: inherit;
1023
1084
  line-height: 1;
@@ -1142,8 +1203,18 @@ __decorate([property({
1142
1203
  reflect: true,
1143
1204
  attribute: `hide-root`
1144
1205
  })], CrumbNavigationElement.prototype, "hideRoot", void 0);
1206
+ __decorate([property({
1207
+ type: Boolean,
1208
+ reflect: true,
1209
+ attribute: `pad-ending`
1210
+ })], CrumbNavigationElement.prototype, "padEnding", void 0);
1211
+ __decorate([property({
1212
+ type: Boolean,
1213
+ reflect: true,
1214
+ attribute: `with-up`
1215
+ })], CrumbNavigationElement.prototype, "withUp", void 0);
1145
1216
  CrumbNavigationElement = __decorate([safeCustomElement(`ixfx-crumb-navigation`)], CrumbNavigationElement);
1146
1217
  //#endregion
1147
1218
  export { scrollFadeStyles as n, CrumbNavigationElement as t };
1148
1219
 
1149
- //# sourceMappingURL=crumb-navigation-DFqTzElw.js.map
1220
+ //# sourceMappingURL=crumb-navigation-BrB0r14u.js.map