@ixfx/components 0.5.17 → 0.5.18

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 (50) hide show
  1. package/bundle/index.d.ts +49 -1
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +311 -80
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.d.ts +1 -1
  6. package/dist/colour-picker.d.ts +1 -1
  7. package/dist/{crumb-navigation-DFqTzElw.js → crumb-navigation-DTwJ8468.js} +54 -80
  8. package/dist/crumb-navigation-DTwJ8468.js.map +1 -0
  9. package/dist/crumbs.d.ts +1 -1
  10. package/dist/crumbs.d.ts.map +1 -1
  11. package/dist/crumbs.js +1 -1
  12. package/dist/{icon-DpA9x2Ve.d.ts → icon-BUwP1CZ1.d.ts} +2 -2
  13. package/dist/icon-BUwP1CZ1.d.ts.map +1 -0
  14. package/dist/icons.d.ts +2 -2
  15. package/dist/{index-D_ftz_IT.d.ts → index-BKAlRgbq.d.ts} +2 -2
  16. package/dist/{index-D_ftz_IT.d.ts.map → index-BKAlRgbq.d.ts.map} +1 -1
  17. package/dist/{index-CoqtMSd9.d.ts → index-BUB5SICW.d.ts} +2 -2
  18. package/dist/{index-CoqtMSd9.d.ts.map → index-BUB5SICW.d.ts.map} +1 -1
  19. package/dist/{index-DfEkTGvT.d.ts → index-DkhBGHgF.d.ts} +3 -3
  20. package/dist/{index-DfEkTGvT.d.ts.map → index-DkhBGHgF.d.ts.map} +1 -1
  21. package/dist/{index-BtGFYfaK.d.ts → index-RqMh1i-O.d.ts} +2 -2
  22. package/dist/{index-BtGFYfaK.d.ts.map → index-RqMh1i-O.d.ts.map} +1 -1
  23. package/dist/index.d.ts +55 -9
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +257 -4
  26. package/dist/index.js.map +1 -1
  27. package/dist/{labelled-input-base-DiTme1JO.d.ts → labelled-input-base-Dp_9KP0G.d.ts} +2 -2
  28. package/dist/{labelled-input-base-DiTme1JO.d.ts.map → labelled-input-base-Dp_9KP0G.d.ts.map} +1 -1
  29. package/dist/labelled-radial-input.d.ts +2 -2
  30. package/dist/labelled-radial-input.d.ts.map +1 -1
  31. package/dist/labelled-range-input.d.ts +1 -1
  32. package/dist/{menu-B8gE2MSo.js → menu-CdwSe_XN.js} +2 -2
  33. package/dist/{menu-B8gE2MSo.js.map → menu-CdwSe_XN.js.map} +1 -1
  34. package/dist/{menu-item-DSyf9f_L.d.ts → menu-item-BG5w7fi4.d.ts} +4 -2
  35. package/dist/menu-item-BG5w7fi4.d.ts.map +1 -0
  36. package/dist/{menu-item-BYRvfyXK.js → menu-item-CrmUwIoJ.js} +7 -2
  37. package/dist/menu-item-CrmUwIoJ.js.map +1 -0
  38. package/dist/menu.d.ts +2 -2
  39. package/dist/menu.js +2 -2
  40. package/dist/panel.d.ts +1 -1
  41. package/dist/{tab-list-ih-0I0NE.d.ts → tab-list-CLqlPnX-.d.ts} +2 -2
  42. package/dist/{tab-list-ih-0I0NE.d.ts.map → tab-list-CLqlPnX-.d.ts.map} +1 -1
  43. package/dist/tabs.d.ts +1 -1
  44. package/docs-user/README.md +1 -0
  45. package/docs-user/select-horiz.md +114 -0
  46. package/package.json +1 -1
  47. package/dist/crumb-navigation-DFqTzElw.js.map +0 -1
  48. package/dist/icon-DpA9x2Ve.d.ts.map +0 -1
  49. package/dist/menu-item-BYRvfyXK.js.map +0 -1
  50. package/dist/menu-item-DSyf9f_L.d.ts.map +0 -1
package/bundle/index.js CHANGED
@@ -3843,6 +3843,7 @@ let MenuTrigger = class MenuTrigger extends i {
3843
3843
  this.mode = `trigger`;
3844
3844
  this.label = `⋮`;
3845
3845
  this.placement = `bottom-start`;
3846
+ this.tabStop = true;
3846
3847
  this._isOpen = false;
3847
3848
  this._hasMenu = false;
3848
3849
  this._hasTriggerSlot = false;
@@ -4105,7 +4106,7 @@ let MenuTrigger = class MenuTrigger extends i {
4105
4106
  @click=${this._handleTriggerClick}
4106
4107
  @contextmenu=${this._handleContextMenu}
4107
4108
  >
4108
- ${showButton ? b`<button class="trigger-btn" part="base">${this.label}</button>` : null}
4109
+ ${showButton ? b`<button class="trigger-btn" part="base" tabindex=${this.tabStop ? `0` : `-1`}>${this.label}</button>` : null}
4109
4110
  <slot name="trigger" @slotchange=${this._handleTriggerSlotChange}></slot>
4110
4111
  </div>
4111
4112
  <div
@@ -4123,6 +4124,10 @@ __decorate([property({ type: String })], MenuTrigger.prototype, "label", void 0)
4123
4124
  __decorate([property({ attribute: false })], MenuTrigger.prototype, "registry", void 0);
4124
4125
  __decorate([property({ attribute: false })], MenuTrigger.prototype, "keyboardManager", void 0);
4125
4126
  __decorate([property({ type: String })], MenuTrigger.prototype, "placement", void 0);
4127
+ __decorate([property({
4128
+ type: Boolean,
4129
+ attribute: `tab-stop`
4130
+ })], MenuTrigger.prototype, "tabStop", void 0);
4126
4131
  __decorate([state()], MenuTrigger.prototype, "_isOpen", void 0);
4127
4132
  __decorate([state()], MenuTrigger.prototype, "_hasMenu", void 0);
4128
4133
  __decorate([state()], MenuTrigger.prototype, "_hasTriggerSlot", void 0);
@@ -7137,7 +7142,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7137
7142
  const r = this.root;
7138
7143
  const sel = this.selectedNode;
7139
7144
  if (!r || !sel) break;
7140
- const totalItems = (this.#findPath(r, sel) ?? [r]).length + (this.#hasChildOptions() ? 1 : 0);
7145
+ const totalItems = this.#getTickledItems().length;
7141
7146
  const currentTickled = this.tickled.tickledId ?? -1;
7142
7147
  if (e.key === `ArrowLeft`) {
7143
7148
  if (currentTickled > 0) this.tickled.handleKeyboardNavigation(`previous`);
@@ -7150,13 +7155,13 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7150
7155
  const r = this.root;
7151
7156
  const sel = this.selectedNode;
7152
7157
  if (!r || !sel) return;
7153
- const totalItems = (this.#findPath(r, sel) ?? [r]).length + (this.#hasChildOptions() ? 1 : 0);
7158
+ const totalItems = this.#getTickledItems().length;
7154
7159
  const currentTickled = this.tickled.tickledId ?? -1;
7155
7160
  switch (e.key) {
7156
7161
  case `ArrowRight`:
7157
7162
  e.preventDefault();
7158
7163
  if (currentTickled < totalItems - 1) this.tickled.handleKeyboardNavigation(`next`);
7159
- else if (currentTickled === totalItems - 1) this.#shiftFocusToNarrowedText();
7164
+ else if (currentTickled === totalItems - 1 && this.#canFocusSuggestions()) this.#shiftFocusToNarrowedText();
7160
7165
  break;
7161
7166
  case `ArrowLeft`:
7162
7167
  e.preventDefault();
@@ -7176,8 +7181,9 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7176
7181
  }
7177
7182
  break;
7178
7183
  case `Enter`:
7184
+ case ` `:
7179
7185
  e.preventDefault();
7180
- this.#handleEnter();
7186
+ this.#activateTickled();
7181
7187
  break;
7182
7188
  case `Escape`:
7183
7189
  e.preventDefault();
@@ -7185,16 +7191,12 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7185
7191
  this.tickled.clearTickled();
7186
7192
  this.blur();
7187
7193
  break;
7188
- case `Tab`: if (e.shiftKey) {
7189
- e.preventDefault();
7190
- this.#shiftFocusToPath();
7191
- } else if (currentTickled === totalItems - 1) {
7192
- e.preventDefault();
7193
- this._menuOpen = false;
7194
- this._focusOnNarrowedText = true;
7195
- const narrowedText = this.shadowRoot?.querySelector(`ixfx-narrowed-text`);
7196
- if (narrowedText) narrowedText.focus();
7197
- }
7194
+ case `Tab`:
7195
+ if (e.shiftKey) break;
7196
+ if (currentTickled === totalItems - 1 && this.#canFocusSuggestions()) {
7197
+ e.preventDefault();
7198
+ this.#shiftFocusToNarrowedText();
7199
+ }
7198
7200
  }
7199
7201
  };
7200
7202
  this.#onNarrowedTextBlur = () => {
@@ -7246,7 +7248,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7246
7248
  enabled: true
7247
7249
  });
7248
7250
  });
7249
- if (this.#hasChildOptions()) items.push({
7251
+ if (this.#canFocusSuggestions()) items.push({
7250
7252
  id: pathNodes.length,
7251
7253
  enabled: true
7252
7254
  });
@@ -7282,8 +7284,8 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7282
7284
  if (!r || !sel) return;
7283
7285
  const pathNodes = this.#findPath(r, sel) ?? [r];
7284
7286
  let el = null;
7285
- if (index < pathNodes.length) el = this.shadowRoot?.querySelectorAll(`.crumb-segment`)[index] ?? null;
7286
- else if (index === pathNodes.length) el = this.shadowRoot?.querySelector(`#child-options-trigger`) ?? null;
7287
+ if (this.caretEmbedded && this.#canFocusSuggestions() && index === pathNodes.length) el = this.shadowRoot?.querySelector(`ixfx-narrowed-text`) ?? null;
7288
+ else el = this.shadowRoot?.querySelectorAll(`.crumb-segment`)[index] ?? null;
7287
7289
  el?.scrollIntoView({
7288
7290
  inline: `nearest`,
7289
7291
  block: `nearest`,
@@ -7296,6 +7298,10 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7296
7298
  const isPending = this.#pendingNode === s;
7297
7299
  return (s.children ?? []).length > 0 || isPending;
7298
7300
  }
7301
+ /** True when the suggestions (narrowed-text) sub-part is renderable and focusable. */
7302
+ #canFocusSuggestions() {
7303
+ return this.showSuggestions && this.#hasChildOptions();
7304
+ }
7299
7305
  #onFocus;
7300
7306
  #onBlur;
7301
7307
  #getHostContainer() {
@@ -7308,26 +7314,18 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7308
7314
  const r = this.root;
7309
7315
  const sel = this.selectedNode;
7310
7316
  if (!r || !sel) return;
7311
- if (currentTickled < (this.#findPath(r, sel) ?? [r]).length - 1) {
7312
- const trigger = (this.shadowRoot?.querySelectorAll(`.crumb-segment`))?.[currentTickled]?.querySelector(`.caret ixfx-menu-trigger`);
7313
- if (trigger) {
7314
- this.#menuOpenedByKeyboard = true;
7315
- this.#currentOpenTrigger = trigger;
7316
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
7317
- trigger.openMenu();
7318
- this.#propagateInputModeToMenu();
7319
- return;
7320
- }
7317
+ const pathNodes = this.#findPath(r, sel) ?? [r];
7318
+ if (this.caretEmbedded && this.#canFocusSuggestions() && currentTickled === pathNodes.length) {
7319
+ this.#shiftFocusToNarrowedText();
7320
+ return;
7321
7321
  }
7322
- if (this.#hasChildOptions()) {
7323
- const trigger = this.shadowRoot?.querySelector(`#child-options-trigger`);
7324
- if (trigger) {
7325
- this.#menuOpenedByKeyboard = true;
7326
- this.#currentOpenTrigger = trigger;
7327
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
7328
- trigger.openMenu();
7329
- this.#propagateInputModeToMenu();
7330
- }
7322
+ const trigger = (this.shadowRoot?.querySelectorAll(`.crumb-segment`))?.[currentTickled]?.querySelector(`.caret ixfx-menu-trigger`);
7323
+ if (trigger) {
7324
+ this.#menuOpenedByKeyboard = true;
7325
+ this.#currentOpenTrigger = trigger;
7326
+ document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
7327
+ trigger.openMenu();
7328
+ this.#propagateInputModeToMenu();
7331
7329
  }
7332
7330
  }
7333
7331
  #propagateInputModeToMenu() {
@@ -7340,40 +7338,24 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7340
7338
  #onMenuTriggerClose;
7341
7339
  #onMenuKeyNav;
7342
7340
  #onKeyDown;
7343
- #handleEnter() {
7341
+ /** Activates the currently tickled item, as if it had been clicked. */
7342
+ #activateTickled() {
7343
+ const currentTickled = this.tickled.tickledId;
7344
+ if (currentTickled === void 0) return;
7344
7345
  const r = this.root;
7345
7346
  const sel = this.selectedNode;
7346
7347
  if (!r || !sel) return;
7347
7348
  const pathNodes = this.#findPath(r, sel) ?? [r];
7348
- const hasChildOptions = this.#hasChildOptions();
7349
- const currentTickled = this.tickled.tickledId ?? -1;
7350
- if (currentTickled < pathNodes.length) {
7351
- const node = pathNodes[currentTickled];
7352
- this.#setSelected(node);
7353
- this._menuOpen = false;
7354
- this.dispatchEvent(new CustomEvent(`item-click`, {
7355
- detail: {
7356
- node,
7357
- depth: currentTickled
7358
- },
7359
- bubbles: true,
7360
- composed: true
7361
- }));
7362
- } else if (hasChildOptions && currentTickled === pathNodes.length) {
7363
- this._menuOpen = true;
7364
- this.#menuOpenedByKeyboard = true;
7365
- const trigger = this.shadowRoot?.querySelector(`#child-options-trigger`);
7366
- if (trigger) {
7367
- this.#currentOpenTrigger = trigger;
7368
- document.addEventListener(`keydown`, this.#onMenuKeyNav, { capture: true });
7369
- trigger.openMenu();
7370
- this.#propagateInputModeToMenu();
7371
- }
7349
+ if (this.caretEmbedded && this.#canFocusSuggestions() && currentTickled === pathNodes.length) {
7350
+ this.#shiftFocusToNarrowedText();
7351
+ return;
7372
7352
  }
7353
+ (this.shadowRoot?.querySelector(`.crumb-segment[data-segment-id="${currentTickled}"]`))?.click();
7373
7354
  }
7374
7355
  #shiftFocusToNarrowedText() {
7375
7356
  const narrowedText = this.shadowRoot?.querySelector(`ixfx-narrowed-text`);
7376
7357
  if (narrowedText) {
7358
+ this._menuOpen = false;
7377
7359
  this._focusOnNarrowedText = true;
7378
7360
  narrowedText.focus();
7379
7361
  }
@@ -7508,7 +7490,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7508
7490
  const previousSet = previous ? /* @__PURE__ */ new Set([previous]) : /* @__PURE__ */ new Set();
7509
7491
  this.selectedNode = node;
7510
7492
  this._selectedNodes = /* @__PURE__ */ new Set([node]);
7511
- if (this.leadingCaret && this.root) {
7493
+ if (this.root) {
7512
7494
  const path = this.#findPath(this.root, node);
7513
7495
  if (path) {
7514
7496
  const depth = this.hideRoot && path.length > 1 ? path.length - 2 : path.length - 1;
@@ -7529,7 +7511,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7529
7511
  #onLabelClick(node, depth) {
7530
7512
  this._openIdx = -1;
7531
7513
  this.#setSelected(node);
7532
- if (this.leadingCaret) this.#scrollSegmentIntoView(depth);
7514
+ this.#scrollSegmentIntoView(depth);
7533
7515
  this.dispatchEvent(new CustomEvent(`item-click`, {
7534
7516
  detail: {
7535
7517
  node,
@@ -7720,7 +7702,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7720
7702
  ${showLeadingCaret ? b`
7721
7703
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
7722
7704
  ${isPending ? b`<span class="loading-spinner"></span>` : b`
7723
- <ixfx-menu-trigger mode="trigger" label="›" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7705
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7724
7706
  <ixfx-menu-container slot="menu">
7725
7707
  ${siblingMenuItems}
7726
7708
  </ixfx-menu-container>
@@ -7732,7 +7714,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7732
7714
  ${showTrailingCaret ? b`
7733
7715
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
7734
7716
  ${isPending ? b`<span class="loading-spinner"></span>` : b`
7735
- <ixfx-menu-trigger mode="trigger" label="›" placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7717
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7736
7718
  <ixfx-menu-container slot="menu">
7737
7719
  ${childMenuItems}
7738
7720
  </ixfx-menu-container>
@@ -7754,7 +7736,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7754
7736
  >
7755
7737
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
7756
7738
  ${isPending ? b`<span class="loading-spinner"></span>` : b`
7757
- <ixfx-menu-trigger mode="trigger" label="›" placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7739
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} placement="right-start" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7758
7740
  <ixfx-menu-container slot="menu">
7759
7741
  ${siblingMenuItems}
7760
7742
  </ixfx-menu-container>
@@ -7789,7 +7771,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7789
7771
  >
7790
7772
  <span class="caret ${isOpen ? `open` : ``} ${isPending ? `pending` : ``}">
7791
7773
  ${isPending ? b`<span class="loading-spinner"></span>` : b`
7792
- <ixfx-menu-trigger mode="trigger" label="›" @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7774
+ <ixfx-menu-trigger mode="trigger" label="›" .tabStop=${false} @menu-command=${(e) => this.#onSegmentMenuCommand(e, node, i)}>
7793
7775
  <ixfx-menu-container slot="menu">
7794
7776
  ${childMenuItems}
7795
7777
  </ixfx-menu-container>
@@ -7897,7 +7879,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7897
7879
  --crumb-item-text-tickled: var(--item-text-tickled);
7898
7880
  --crumb-item-border: var(--item-border);
7899
7881
  --crumb-item-border-tickled: var(--item-border-tickled);
7900
- --crumb-item-padding: var(--item-padding, var(--space-xs));
7882
+ --crumb-item-padding: var(--space-s, 2px);
7901
7883
  --crumb-item-border-radius: var(--item-border-radius);
7902
7884
  --crumb-item-gap: var(--item-gap, var(--space-xs));
7903
7885
  --crumb-separator: var(--surface-muted-text);
@@ -7906,11 +7888,10 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7906
7888
  width: 100%;
7907
7889
  }
7908
7890
 
7909
- :host(.focused) {
7910
- outline: none;
7911
- }
7912
-
7913
- :host(:focus-within) .host-container {
7891
+ /* Outline goes on :host, not .host-container: .host-container carries the
7892
+ * scroll-fade mask-image, and CSS masks clip everything painted outside
7893
+ * the masked box - including an outline, which paints outside the border edge. */
7894
+ :host(:focus-within) {
7914
7895
  outline: 2px solid var(--accent);
7915
7896
  outline-offset: 2px;
7916
7897
  }
@@ -7944,6 +7925,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7944
7925
  background: var(--crumb-item-bg);
7945
7926
  border: var(--crumb-item-border);
7946
7927
  border-radius: var(--crumb-item-border-radius);
7928
+ padding:0;
7947
7929
  }
7948
7930
 
7949
7931
  .crumb-segment.leading-caret {
@@ -7972,6 +7954,7 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7972
7954
  }
7973
7955
 
7974
7956
  .label {
7957
+ padding: var(--crumb-item-padding);
7975
7958
  cursor: pointer;
7976
7959
  white-space: nowrap;
7977
7960
  color: inherit;
@@ -7992,15 +7975,12 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
7992
7975
  }
7993
7976
 
7994
7977
  .crumb-segment ixfx-menu-trigger {
7995
- --ixfx-button-padding: var(--space-xs) 8px;
7978
+ --ixfx-button-padding: var(--space-s, 2px);
7996
7979
  }
7997
7980
 
7998
7981
  .caret {
7999
7982
  position: relative;
8000
7983
  cursor: pointer;
8001
- padding: var(--crumb-item-padding);
8002
- margin-left: var(--crumb-item-gap);
8003
- margin-right: var(--crumb-item-gap);
8004
7984
  color: var(--crumb-separator);
8005
7985
  display: inline-flex;
8006
7986
  align-items: center;
@@ -8027,7 +8007,6 @@ let CrumbNavigationElement = class CrumbNavigationElement extends i {
8027
8007
  background: none;
8028
8008
  border: none;
8029
8009
  color: inherit;
8030
- padding: 0;
8031
8010
  cursor: pointer;
8032
8011
  font-size: inherit;
8033
8012
  line-height: 1;
@@ -21661,6 +21640,258 @@ __decorate([property({ type: Number })], RangeElement.prototype, "value", null);
21661
21640
  __decorate([property({ type: Number })], RangeElement.prototype, "step", void 0);
21662
21641
  RangeElement = __decorate([safeCustomElement(`ixfx-range`)], RangeElement);
21663
21642
  //#endregion
21643
+ //#region src/select-horiz/select-horiz.ts
21644
+ let SelectHorizElement = class SelectHorizElement extends WheelNudgeMixin(i) {
21645
+ constructor(..._args) {
21646
+ super(..._args);
21647
+ this._selectedIndex = -1;
21648
+ this._slottedItems = [];
21649
+ this.tickled = new TickledController(this, {
21650
+ getItems: () => this._slottedItems.map((_, i) => ({
21651
+ id: i,
21652
+ enabled: true
21653
+ })),
21654
+ onStateChange: () => this._syncTickled()
21655
+ });
21656
+ this._onSlotChange = () => {
21657
+ this._slottedItems = Array.from(this.shadowRoot?.querySelector(`slot`)?.assignedElements() ?? []);
21658
+ const declaredIndex = this._slottedItems.findIndex((item) => item.hasAttribute(`selected`));
21659
+ let resolvedIndex = declaredIndex >= 0 ? declaredIndex : this._selectedIndex;
21660
+ if (resolvedIndex >= this._slottedItems.length) resolvedIndex = this._slottedItems.length - 1;
21661
+ if (resolvedIndex < 0 && this._slottedItems.length > 0) resolvedIndex = 0;
21662
+ this.selectedIndex = resolvedIndex;
21663
+ };
21664
+ this._syncTickled = () => {
21665
+ this._slottedItems.forEach((item, i) => {
21666
+ const isTickled = this.tickled.isTickled(i);
21667
+ item.classList.toggle(`tickled`, isTickled);
21668
+ item.tabIndex = isTickled && this.tickled.inputMode === `keyboard` ? 0 : -1;
21669
+ });
21670
+ };
21671
+ this._findSlottedItem = (target) => {
21672
+ let el = target instanceof Element ? target : null;
21673
+ while (el) {
21674
+ if (this._slottedItems.includes(el)) return el;
21675
+ el = el.parentElement;
21676
+ }
21677
+ };
21678
+ this._handlePointerOver = (e) => {
21679
+ const item = this._findSlottedItem(e.target);
21680
+ if (item) this.tickled.handlePointerEnter(this._slottedItems.indexOf(item));
21681
+ };
21682
+ this._handleKeyDown = (e) => {
21683
+ if (e.key === `ArrowLeft`) {
21684
+ e.preventDefault();
21685
+ this.tickled.handleKeyboardNavigation(`previous`);
21686
+ this._applyTickledSelection();
21687
+ } else if (e.key === `ArrowRight`) {
21688
+ e.preventDefault();
21689
+ this.tickled.handleKeyboardNavigation(`next`);
21690
+ this._applyTickledSelection();
21691
+ } else if (e.key === `Home`) {
21692
+ e.preventDefault();
21693
+ this.tickled.handleKeyboardNavigation(`first`);
21694
+ this._applyTickledSelection();
21695
+ } else if (e.key === `End`) {
21696
+ e.preventDefault();
21697
+ this.tickled.handleKeyboardNavigation(`last`);
21698
+ this._applyTickledSelection();
21699
+ }
21700
+ };
21701
+ this._applyTickledSelection = () => {
21702
+ const id = this.tickled.tickledId;
21703
+ if (id !== void 0 && id !== this._selectedIndex) this.selectedIndex = id;
21704
+ };
21705
+ this._wheelCooldown = false;
21706
+ this._handleClick = (e) => {
21707
+ e.currentTarget.focus();
21708
+ const item = this._findSlottedItem(e.target);
21709
+ const index = item ? this._slottedItems.indexOf(item) : -1;
21710
+ if (index >= 0 && index !== this._selectedIndex) this.selectedIndex = index;
21711
+ };
21712
+ this._updateSelectedAttribute = () => {
21713
+ this._slottedItems.forEach((item, i) => {
21714
+ if (i === this._selectedIndex) item.setAttribute(`selected`, ``);
21715
+ else item.removeAttribute(`selected`);
21716
+ });
21717
+ };
21718
+ this._scrollSelectedIntoView = () => {
21719
+ const item = this._slottedItems[this._selectedIndex];
21720
+ if (item) item.scrollIntoView({
21721
+ inline: `center`,
21722
+ behavior: `smooth`
21723
+ });
21724
+ };
21725
+ this._emitChange = () => {
21726
+ this.dispatchEvent(new CustomEvent(`change`, {
21727
+ detail: {
21728
+ selectedIndex: this._selectedIndex,
21729
+ selectedItem: this.selectedItem,
21730
+ selectedValue: this.selectedValue
21731
+ },
21732
+ bubbles: true,
21733
+ composed: true
21734
+ }));
21735
+ };
21736
+ }
21737
+ static {
21738
+ this.styles = [
21739
+ themeFallbacks,
21740
+ tickledStyles,
21741
+ tickledItemStyles,
21742
+ scrollFadeStyles(`x`),
21743
+ i$3`
21744
+ :host {
21745
+ --select-horiz-item-width: 80%;
21746
+ --select-horiz-gap: var(--space-s);
21747
+ --select-horiz-bg: var(--surface-3);
21748
+ --select-horiz-border: var(--border);
21749
+ --select-horiz-radius: var(--radius-l);
21750
+ display: flex;
21751
+ width: 100%;
21752
+ background: var(--select-horiz-bg);
21753
+ border: var(--select-horiz-border);
21754
+ border-radius: var(--select-horiz-radius);
21755
+ }
21756
+
21757
+ /* Edge fade (the scroll-fade-x class, see ../styles/scroll-fade.ts) must sit on
21758
+ * the element that actually scrolls - its mask is sized to this element's own
21759
+ * box, and content overflowing a *different*, non-scrolling ancestor gets the
21760
+ * mask tiled across it instead of fading correctly. */
21761
+ .items {
21762
+ display: flex;
21763
+ align-items: center;
21764
+ gap: var(--select-horiz-gap);
21765
+ padding: var(--space-xs) var(--scroll-fade-width, 30px);
21766
+ width: 100%;
21767
+ min-height: 48px;
21768
+ overflow-x: scroll;
21769
+ overflow-y: hidden;
21770
+ scrollbar-width: none;
21771
+ scroll-snap-type: x mandatory;
21772
+ -webkit-overflow-scrolling: touch;
21773
+ cursor: grab;
21774
+
21775
+ box-sizing: border-box;
21776
+ }
21777
+
21778
+ .items:focus-within {
21779
+ cursor: default;
21780
+ }
21781
+
21782
+ .spacer {
21783
+ flex: 0 0 var(--select-horiz-spacer-width, 10%);
21784
+ pointer-events: none;
21785
+ user-select: none;
21786
+ }
21787
+
21788
+ ::slotted(*) {
21789
+ flex: 0 0 var(--select-horiz-item-width);
21790
+ scroll-snap-align: center;
21791
+ user-select: none;
21792
+ min-height: 100%;
21793
+ box-sizing: border-box;
21794
+ transition: opacity var(--transition), background var(--transition), border-color var(--transition), color var(--transition);
21795
+ background: var(--item-bg);
21796
+ border: var(--item-border);
21797
+ border-radius: var(--item-border-radius);
21798
+ padding: var(--item-padding);
21799
+ display: grid;
21800
+ align-content: center;
21801
+ justify-content: center;
21802
+ }
21803
+
21804
+ ::slotted(.tickled) {
21805
+ background: var(--item-bg-tickled);
21806
+ border-color: var(--item-border-tickled);
21807
+ color: var(--item-text-tickled);
21808
+ }
21809
+
21810
+ ::slotted([selected]) {
21811
+ background: var(--item-bg-selected);
21812
+ border-color: var(--item-border-selected);
21813
+ color: var(--item-text-selected);
21814
+ }
21815
+
21816
+ ::slotted([selected].tickled) {
21817
+ background: var(--item-bg-selected-tickled);
21818
+ outline: 2px dashed var(--surface-3);
21819
+ outline-offset: -2px;
21820
+ }
21821
+
21822
+ ::-webkit-scrollbar {
21823
+ display: none;
21824
+ }
21825
+ `
21826
+ ];
21827
+ }
21828
+ get selectedIndex() {
21829
+ return this._selectedIndex;
21830
+ }
21831
+ set selectedIndex(value) {
21832
+ const oldValue = this._selectedIndex;
21833
+ if (value < -1 || this._slottedItems.length > 0 && value >= this._slottedItems.length) return;
21834
+ this._selectedIndex = value;
21835
+ this._updateSelectedAttribute();
21836
+ this._scrollSelectedIntoView();
21837
+ this.tickled.setTickled(value === -1 ? void 0 : value);
21838
+ if (oldValue !== value) this._emitChange();
21839
+ }
21840
+ get selectedValue() {
21841
+ return this._slottedItems[this._selectedIndex]?.getAttribute(`value`) ?? null;
21842
+ }
21843
+ set selectedValue(value) {
21844
+ if (value === null) return;
21845
+ const index = this._slottedItems.findIndex((item) => item.getAttribute(`value`) === value);
21846
+ if (index >= 0) this.selectedIndex = index;
21847
+ }
21848
+ get selectedItem() {
21849
+ return this._slottedItems[this._selectedIndex] ?? null;
21850
+ }
21851
+ get items() {
21852
+ return this._slottedItems;
21853
+ }
21854
+ render() {
21855
+ return b`
21856
+ <div
21857
+ class="items scroll-fade-x"
21858
+ tabindex="0"
21859
+ data-input-mode=${this.tickled.inputMode}
21860
+ @pointerover=${this._handlePointerOver}
21861
+ @pointerleave=${(e) => this.tickled.handlePointerLeave(e)}
21862
+ @keydown=${this._handleKeyDown}
21863
+ @click=${this._handleClick}
21864
+ >
21865
+ <div class="spacer"></div>
21866
+ <slot @slotchange=${this._onSlotChange}></slot>
21867
+ <div class="spacer"></div>
21868
+ </div>
21869
+ `;
21870
+ }
21871
+ willUpdate(changed) {
21872
+ super.willUpdate(changed);
21873
+ this.setAttribute(`data-input-mode`, this.tickled.inputMode);
21874
+ }
21875
+ _applyWheelDelta(direction, _event) {
21876
+ if (this._wheelCooldown) return;
21877
+ this._wheelCooldown = true;
21878
+ this.tickled.handleKeyboardNavigation(direction === 1 ? `next` : `previous`);
21879
+ this._applyTickledSelection();
21880
+ setTimeout(() => {
21881
+ this._wheelCooldown = false;
21882
+ }, 250);
21883
+ }
21884
+ };
21885
+ __decorate([state()], SelectHorizElement.prototype, "_selectedIndex", void 0);
21886
+ __decorate([state()], SelectHorizElement.prototype, "_slottedItems", void 0);
21887
+ __decorate([property({
21888
+ type: Number,
21889
+ reflect: true,
21890
+ attribute: `selected-index`
21891
+ })], SelectHorizElement.prototype, "selectedIndex", null);
21892
+ __decorate([property({ type: String })], SelectHorizElement.prototype, "selectedValue", null);
21893
+ SelectHorizElement = __decorate([safeCustomElement(`ixfx-select-horiz`)], SelectHorizElement);
21894
+ //#endregion
21664
21895
  //#region src/selecthorizontal.ts
21665
21896
  let SelectHorizontalElement = class SelectHorizontalElement extends i {
21666
21897
  constructor(..._args) {
@@ -28401,6 +28632,6 @@ function init() {
28401
28632
  console.log(`Init`);
28402
28633
  }
28403
28634
  //#endregion
28404
- export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizontalElement, SliderInputElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
28635
+ export { AcTextElement, AcTokenElement, ButtonElement, Checkbox, ColourPicker, ColourPickerPopup, CrumbNavigationElement, CrumbPathController, CrumbPathElement, DataController, DataDisplayComponent, EditableLabel, EditableNumber, FormElement, FormGroupElement, FormPartElement, GroupedItemListerElement, ICON_CARET_RIGHT, ICON_CHECK, ICON_CHEVRON_DOWN, ICON_CLOSE, IncrSearchTreeController as IncrSearchMillerController, IncrSearchTreeController, IxfxHexEditorElement, IxfxIconElement, IxfxTimelineElement, LabelledRadialInput, LabelledRangeInput, LedElement, menu_exports as Menu, MillerBaseElement, MillerListElement, MillerTreeController, NarrowedTextElement, NotificationManager, NotificationPillElement, PanelElement, PanelGroupElement, PlotDataSeries, PlotHistogram, PlotMultiAxis, PlotSingleAxis, PlotXyAxis, PolarPad, RadialInputElement, RadioGroup, RangeElement, RangeInput, RangeMultiElement, SelectHorizElement, SelectHorizontalElement, SliderInputElement, SnackbarElement, SnapContainer, SplitButton, SplitLayoutElement, SwipeElement, TabController, TabListElement, TabListItemElement, TabPanelElement, TabPanelsElement, TimelineController, TimelineTrackTabElement, TooltipElement, TransitoryLabelElement, TreeBaseElement, TreeController, TreeDataModel, TreeListElement, VerticalListElement, XyPad, applyAgeModification, applyHighlights, attachTimelineInteractions, buildHighlightTargets, clearHighlights, collectDataResult, computeColour, createAcCompletionProvider, createElementIncrSearch, createFuzzySearch, createIncrSearch, createPillRenderer, createTreeListAdapter, createVerticalListAdapter, getIcon, hasIcon, iconBus, init, monitorIndeterminate, parseColourScaleAttr, readBaseColour, registerIcon, resolveCssVars, resolveGrid, svgToDataUri, timelineStyles };
28405
28636
 
28406
28637
  //# sourceMappingURL=index.js.map