@fusion.dev/helix-headless 0.218.0 → 0.219.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 (74) hide show
  1. package/api.json +1 -1
  2. package/custom-elements.json +1 -1
  3. package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +13 -2
  4. package/dist/breadcrumbs/breadcrumb/breadcrumb.js +19 -9
  5. package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +16 -1
  6. package/dist/breadcrumbs/root/breadcrumbs-root.js +6 -0
  7. package/dist/button/root/button-root.d.ts +33 -0
  8. package/dist/button/root/button-root.js +13 -3
  9. package/dist/canvas/root/canvas-root.d.ts +11 -0
  10. package/dist/canvas/root/canvas-root.js +1 -0
  11. package/dist/chat/composer/chat-composer.d.ts +221 -6
  12. package/dist/chat/composer/chat-composer.js +249 -19
  13. package/dist/chat/message/chat-message.d.ts +7 -0
  14. package/dist/chat/message/chat-message.js +2 -1
  15. package/dist/chat/root/chat-root.d.ts +1 -0
  16. package/dist/chat/root/chat-root.js +1 -1
  17. package/dist/copy-button/root/copy-button-root.js +3 -3
  18. package/dist/device-screen/root/device-screen-root.d.ts +11 -0
  19. package/dist/device-screen/root/device-screen-root.js +22 -10
  20. package/dist/dialog/root/dialog-root.js +6 -1
  21. package/dist/drilldown/item/drilldown-item.js +1 -1
  22. package/dist/element-events.generated.js +1 -0
  23. package/dist/filter-input/root/filter-input-root.d.ts +4 -3
  24. package/dist/filter-input/root/filter-input-root.js +1 -20
  25. package/dist/graph/root/graph-root.d.ts +11 -0
  26. package/dist/graph/root/graph-root.js +4 -1
  27. package/dist/input/root/input-root.d.ts +6 -0
  28. package/dist/input/root/input-root.js +7 -0
  29. package/dist/lightbox/root/lightbox-root.d.ts +4 -1
  30. package/dist/lightbox/root/lightbox-root.js +10 -8
  31. package/dist/listbox/root/listbox-root.d.ts +21 -0
  32. package/dist/listbox/root/listbox-root.js +37 -2
  33. package/dist/log/group/log-group.d.ts +7 -1
  34. package/dist/log/group/log-group.js +14 -1
  35. package/dist/log/root/log-root.d.ts +13 -3
  36. package/dist/log/root/log-root.js +5 -2
  37. package/dist/map/root/map-root.d.ts +11 -0
  38. package/dist/map/root/map-root.js +28 -12
  39. package/dist/menu/root/menu-root.d.ts +8 -0
  40. package/dist/menu/root/menu-root.js +22 -1
  41. package/dist/menu/section/menu-section.d.ts +10 -0
  42. package/dist/menu/section/menu-section.js +10 -0
  43. package/dist/meter/index.d.ts +1 -0
  44. package/dist/meter/index.js +1 -0
  45. package/dist/meter/root/meter-root.d.ts +16 -1
  46. package/dist/meter/root/meter-root.js +27 -11
  47. package/dist/meter/segment/meter-segment.d.ts +74 -0
  48. package/dist/meter/segment/meter-segment.js +47 -0
  49. package/dist/scroll-area/root/scroll-area-root.d.ts +20 -3
  50. package/dist/scroll-area/root/scroll-area-root.js +23 -4
  51. package/dist/spatial-bar-chart/bars.d.ts +125 -5
  52. package/dist/spatial-bar-chart/bars.js +194 -17
  53. package/dist/spatial-bar-chart/root/spatial-bar-chart-root.d.ts +148 -6
  54. package/dist/spatial-bar-chart/root/spatial-bar-chart-root.js +285 -16
  55. package/dist/splitter/root/splitter-root.js +1 -0
  56. package/dist/tabs/root/tabs-root.d.ts +4 -0
  57. package/dist/tabs/tab/tab.d.ts +1 -0
  58. package/dist/tabs/tab/tab.js +2 -2
  59. package/dist/tag/root/tag-root.d.ts +1 -1
  60. package/dist/terminal/root/terminal-root.d.ts +11 -0
  61. package/dist/terminal/root/terminal-root.js +23 -10
  62. package/dist/toolbar/root/toolbar-root.d.ts +4 -1
  63. package/dist/tooltip/root/tooltip-root.d.ts +23 -1
  64. package/dist/tooltip/root/tooltip-root.js +28 -5
  65. package/dist/tour/root/tour-root.d.ts +1 -0
  66. package/dist/tour/root/tour-root.js +4 -1
  67. package/dist/tour/stop/tour-stop.js +1 -0
  68. package/examples.json +1 -1
  69. package/lint.json +1 -1
  70. package/package.json +5 -5
  71. package/types/jsx.d.ts +1373 -52
  72. package/types/svelte.d.ts +1 -0
  73. package/types/vue.d.ts +312 -17
  74. package/types/words.d.ts +9 -1
@@ -88,7 +88,7 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinDismissible(MixinSele
88
88
  @click=${this.handleLinkClick}
89
89
  @keydown=${this.handleKeydown}
90
90
  >
91
- <slot></slot>${this.renderDismiss()}
91
+ <slot part="label"></slot>${this.renderDismiss()}
92
92
  </a>`;
93
93
  }
94
94
  return html `<button
@@ -102,7 +102,7 @@ let HelixHeadlessTab = class HelixHeadlessTab extends MixinDismissible(MixinSele
102
102
  @click=${() => this.select()}
103
103
  @keydown=${this.handleKeydown}
104
104
  >
105
- <slot></slot>${this.renderDismiss()}
105
+ <slot part="label"></slot>${this.renderDismiss()}
106
106
  </button>`;
107
107
  }
108
108
  };
@@ -42,7 +42,7 @@ declare const HelixHeadlessTag_base: (new (...args: any[]) => import("@fusion.de
42
42
  *
43
43
  * @slot - The tag's label.
44
44
  * @slot dismiss-icon - Replaces the glyph on the remove button.
45
- * @slot start - The category the label belongs to, shown before it in a heavier weight.
45
+ * @slot start - The category the label belongs to, shown before it in a heavier weight, or an icon.
46
46
  *
47
47
  * @event {HelixDismissEvent} helix-dismiss - The remove button was pressed. The tag does not remove itself, so remove it in response. Cancelable.
48
48
  *
@@ -2,6 +2,7 @@ import { HelixElement, type TerminalResizeDetail } from '@fusion.dev/helix-core'
2
2
  import { nothing, type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../button/index.js';
4
4
  import '../../icon-button/index.js';
5
+ import '../../tooltip/index.js';
5
6
  import '../../toolbar/index.js';
6
7
  /** How a search through a terminal's output moves. */
7
8
  export interface TerminalFindOptions {
@@ -240,6 +241,16 @@ export interface TerminalSink {
240
241
  * @csspart restart-spinner - The ring the Restart button turns while it is pending.
241
242
  * @csspart restart-text - The Restart button's label.
242
243
  * @csspart status - The line under the terminal that says the process exited, or that Tab moves focus.
244
+ * @csspart tooltip-arrow - The arrow of the tooltip that names each button, forwarded from `Tooltip`.
245
+ * @csspart tooltip-arrow-bottom - The arrow while the bubble is below its button, on the bubble's top edge. Set together with `tooltip-arrow`.
246
+ * @csspart tooltip-arrow-left - The arrow while the bubble is left of its button, on the bubble's right edge. Set together with `tooltip-arrow`.
247
+ * @csspart tooltip-arrow-right - The arrow while the bubble is right of its button, on the bubble's left edge. Set together with `tooltip-arrow`.
248
+ * @csspart tooltip-arrow-top - The arrow while the bubble is above its button, on the bubble's bottom edge. Set together with `tooltip-arrow`.
249
+ * @csspart tooltip-surface - The bubble of the tooltip that names each button, forwarded from `Tooltip`.
250
+ * @csspart tooltip-surface-bottom - The bubble while it is below its button. Set together with `tooltip-surface`.
251
+ * @csspart tooltip-surface-left - The bubble while it is left of its button. Set together with `tooltip-surface`.
252
+ * @csspart tooltip-surface-right - The bubble while it is right of its button. Set together with `tooltip-surface`.
253
+ * @csspart tooltip-surface-top - The bubble while it is above its button. Set together with `tooltip-surface`.
243
254
  * @csspart viewport - The box the terminal is drawn in.
244
255
  *
245
256
  * @cssproperty --terminal-active-match-background-color - The ground of the current match of a search.
@@ -8,6 +8,7 @@ import { live } from 'lit/directives/live.js';
8
8
  import { html } from 'lit/static-html.js';
9
9
  import '../../button/index.js';
10
10
  import '../../icon-button/index.js';
11
+ import '../../tooltip/index.js';
11
12
  import '../../toolbar/index.js';
12
13
  import { isTab, shortcutOf, spokenChord } from '../keys.js';
13
14
  const readable = (source) => {
@@ -457,11 +458,13 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
457
458
  renderControls() {
458
459
  const toolbar = this.tag('toolbar');
459
460
  const button = this.tag('icon-button');
461
+ const tip = this.tag('tooltip');
460
462
  return html `<${toolbar} part="controls" exportparts="toolbar: controls-toolbar" label=${this.controlsLabel}>
461
463
  <slot name="actions" part="actions" @slotchange=${this.handleActions}></slot>
462
464
  ${this.draws('find')
463
465
  ? html `<${button}
464
466
  part="find"
467
+ id="find"
465
468
  exportparts="button: find-button, live: find-live, spinner: find-spinner, text: find-text"
466
469
  .expanded=${this.findOpen}
467
470
  label=${this.findLabel}
@@ -469,11 +472,12 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
469
472
  @helix-press=${stopPress}
470
473
  >
471
474
  <slot name="find-icon">${drawIcon(magnifyingGlass)}</slot>
472
- </${button}>`
475
+ </${button}><${tip} for="find" content=${this.findLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
473
476
  : nothing}
474
477
  ${this.draws('copy')
475
478
  ? html `<${button}
476
479
  part="copy"
480
+ id="copy"
477
481
  exportparts="button: copy-button, live: copy-live, spinner: copy-spinner, text: copy-text"
478
482
  ?disabled=${!this.anySelected}
479
483
  label=${this.copyLabel}
@@ -481,22 +485,24 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
481
485
  @helix-press=${stopPress}
482
486
  >
483
487
  <slot name="copy-icon">${drawIcon(copy)}</slot>
484
- </${button}>`
488
+ </${button}><${tip} for="copy" content=${this.copyLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
485
489
  : nothing}
486
490
  ${this.draws('clear')
487
491
  ? html `<${button}
488
492
  part="clear"
493
+ id="clear"
489
494
  exportparts="button: clear-button, live: clear-live, spinner: clear-spinner, text: clear-text"
490
495
  label=${this.clearLabel}
491
496
  @click=${() => this.clear()}
492
497
  @helix-press=${stopPress}
493
498
  >
494
499
  <slot name="clear-icon">${drawIcon(broom)}</slot>
495
- </${button}>`
500
+ </${button}><${tip} for="clear" content=${this.clearLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
496
501
  : nothing}
497
502
  ${this.draws('fullscreen')
498
503
  ? html `<${button}
499
504
  part="fullscreen"
505
+ id="fullscreen"
500
506
  exportparts="button: fullscreen-button, live: fullscreen-live, spinner: fullscreen-spinner, text: fullscreen-text"
501
507
  aria-pressed=${this.filled ? 'true' : 'false'}
502
508
  label=${this.fullscreenLabel}
@@ -504,7 +510,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
504
510
  @helix-press=${stopPress}
505
511
  >
506
512
  <slot name="fullscreen-icon">${drawIcon(cornersOut)}</slot>
507
- </${button}>`
513
+ </${button}><${tip} for="fullscreen" content=${this.fullscreenLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>`
508
514
  : nothing}
509
515
  </${toolbar}>`;
510
516
  }
@@ -514,6 +520,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
514
520
  }
515
521
  const toolbar = this.tag('toolbar');
516
522
  const button = this.tag('icon-button');
523
+ const tip = this.tag('tooltip');
517
524
  return html `<div part="find-bar" role="search" aria-label=${this.findLabel} ?hidden=${!this.findOpen}>
518
525
  <input
519
526
  part="find-field"
@@ -530,6 +537,7 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
530
537
  <${toolbar} part="find-controls" exportparts="toolbar: find-controls-toolbar" label=${this.findControlsLabel}>
531
538
  <${button}
532
539
  part="find-match-case"
540
+ id="find-match-case"
533
541
  exportparts="button: find-match-case-button, live: find-match-case-live, spinner: find-match-case-spinner, text: find-match-case-text"
534
542
  aria-pressed=${this.findMatchCase ? 'true' : 'false'}
535
543
  label=${this.findMatchCaseLabel}
@@ -537,9 +545,10 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
537
545
  @helix-press=${stopPress}
538
546
  >
539
547
  <slot name="find-match-case-icon">${drawIcon(textAa)}</slot>
540
- </${button}>
548
+ </${button}><${tip} for="find-match-case" content=${this.findMatchCaseLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
541
549
  <${button}
542
550
  part="find-whole-word"
551
+ id="find-whole-word"
543
552
  exportparts="button: find-whole-word-button, live: find-whole-word-live, spinner: find-whole-word-spinner, text: find-whole-word-text"
544
553
  aria-pressed=${this.findWholeWord ? 'true' : 'false'}
545
554
  label=${this.findWholeWordLabel}
@@ -547,9 +556,10 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
547
556
  @helix-press=${stopPress}
548
557
  >
549
558
  <slot name="find-whole-word-icon">${drawIcon(textAUnderline)}</slot>
550
- </${button}>
559
+ </${button}><${tip} for="find-whole-word" content=${this.findWholeWordLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
551
560
  <${button}
552
561
  part="find-regex"
562
+ id="find-regex"
553
563
  exportparts="button: find-regex-button, live: find-regex-live, spinner: find-regex-spinner, text: find-regex-text"
554
564
  aria-pressed=${this.findRegex ? 'true' : 'false'}
555
565
  label=${this.findRegexLabel}
@@ -557,10 +567,11 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
557
567
  @helix-press=${stopPress}
558
568
  >
559
569
  <slot name="find-regex-icon">${drawIcon(asterisk)}</slot>
560
- </${button}>
570
+ </${button}><${tip} for="find-regex" content=${this.findRegexLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
561
571
  <slot name="find-actions" part="find-actions"></slot>
562
572
  <${button}
563
573
  part="find-previous"
574
+ id="find-previous"
564
575
  exportparts="button: find-previous-button, live: find-previous-live, spinner: find-previous-spinner, text: find-previous-text"
565
576
  ?disabled=${!this.matchCount}
566
577
  label=${this.findPreviousLabel}
@@ -568,9 +579,10 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
568
579
  @helix-press=${stopPress}
569
580
  >
570
581
  <slot name="find-previous-icon">${drawIcon(caretUp)}</slot>
571
- </${button}>
582
+ </${button}><${tip} for="find-previous" content=${this.findPreviousLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
572
583
  <${button}
573
584
  part="find-next"
585
+ id="find-next"
574
586
  exportparts="button: find-next-button, live: find-next-live, spinner: find-next-spinner, text: find-next-text"
575
587
  ?disabled=${!this.matchCount}
576
588
  label=${this.findNextLabel}
@@ -578,16 +590,17 @@ let HelixHeadlessTerminal = class HelixHeadlessTerminal extends HelixElement {
578
590
  @helix-press=${stopPress}
579
591
  >
580
592
  <slot name="find-next-icon">${drawIcon(caretDown)}</slot>
581
- </${button}>
593
+ </${button}><${tip} for="find-next" content=${this.findNextLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
582
594
  <${button}
583
595
  part="find-close"
596
+ id="find-close"
584
597
  exportparts="button: find-close-button, live: find-close-live, spinner: find-close-spinner, text: find-close-text"
585
598
  label=${this.findCloseLabel}
586
599
  @click=${() => this.closeFind()}
587
600
  @helix-press=${stopPress}
588
601
  >
589
602
  <slot name="find-close-icon">${drawIcon(x)}</slot>
590
- </${button}>
603
+ </${button}><${tip} for="find-close" content=${this.findCloseLabel} exportparts="arrow: tooltip-arrow, arrow-bottom: tooltip-arrow-bottom, arrow-left: tooltip-arrow-left, arrow-right: tooltip-arrow-right, arrow-top: tooltip-arrow-top, surface: tooltip-surface, surface-bottom: tooltip-surface-bottom, surface-left: tooltip-surface-left, surface-right: tooltip-surface-right, surface-top: tooltip-surface-top"></${tip}>
591
604
  </${toolbar}>
592
605
  </div>`;
593
606
  }
@@ -10,7 +10,10 @@ import { type PropertyValues, type TemplateResult } from 'lit';
10
10
  * The toolbar is one tab stop, and the arrow keys move between its controls, so
11
11
  * three toolbars take three presses of Tab to pass. Any element the browser can
12
12
  * focus counts as a control, including your own elements. A child that takes no
13
- * focus, such as a divider, is skipped. A menu is reached at its trigger.
13
+ * focus, such as a divider, is skipped. A menu is reached at its trigger. A
14
+ * disabled control is skipped too, except a Button with
15
+ * `focusable-when-disabled`, which the arrows still reach so its tooltip can
16
+ * say why it is disabled.
14
17
  *
15
18
  * A Divider in the toolbar is a separator across the toolbar's axis, as React
16
19
  * Aria's is: vertical in a horizontal toolbar and horizontal in a vertical
@@ -1,5 +1,5 @@
1
1
  import { HelixElement, OpenPhaseController, type Placement } from '@fusion.dev/helix-core';
2
- import { type PropertyValues, type TemplateResult } from 'lit';
2
+ import { type CSSResultGroup, type PropertyValues, type TemplateResult } from 'lit';
3
3
  declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & typeof HelixElement;
4
4
  /**
5
5
  * @summary A short text that appears next to an element on hover and focus.
@@ -85,6 +85,7 @@ declare const HelixHeadlessTooltip_base: (new (...args: any[]) => import("@fusio
85
85
  * @cssstate placed-top - While the bubble sits above its trigger.
86
86
  */
87
87
  export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
88
+ static styles: CSSResultGroup;
88
89
  /**
89
90
  * The text shown in the bubble.
90
91
  *
@@ -314,6 +315,12 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
314
315
  * every control turns the scan into a series of pauses.
315
316
  */
316
317
  private readonly showLater;
318
+ /**
319
+ * Shows for a pointer or for focus, unless a menu or popover is open that
320
+ * the tooltip is not inside. `show()` and `open` are the consumer's own and
321
+ * are not refused.
322
+ */
323
+ private showForReader;
317
324
  /**
318
325
  * The pointer reached the bubble, in the `for` form.
319
326
  *
@@ -442,6 +449,21 @@ export declare class HelixHeadlessTooltip extends HelixHeadlessTooltip_base {
442
449
  * renders as its name, then the trigger's text.
443
450
  */
444
451
  private triggerSays;
452
+ /**
453
+ * A menu or popover opened outside the tooltip, so the tooltip yields to it.
454
+ *
455
+ * **A tooltip outside an open panel sits over the panel the reader is
456
+ * using.** A menu opened from the keyboard, or from a control beside the
457
+ * trigger while the pointer is still on it, is opened with no `click` on the
458
+ * trigger and no `pointerleave`, so neither takes the bubble down. Opening a
459
+ * menu by its keys from a trigger inside the tooltip also moves focus into
460
+ * the menu, and that `focusin` showed the bubble again. A pointer or focus
461
+ * does not show the bubble while such a panel is open, and this closes one
462
+ * they hold up as the panel opens. A bubble the consumer opened with `show()`
463
+ * or `open` holds nothing and stays.
464
+ */
465
+ private readonly yieldTo;
466
+ private stopYielding;
445
467
  connectedCallback(): void;
446
468
  disconnectedCallback(): void;
447
469
  protected firstUpdated(changed: PropertyValues): void;
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from "tslib";
2
- import { anchorElement, arrowReach, customElement, elementById, focusTarget, HelixElement, hostAria, linkDescription, MixinControllerOpen, numberConverter, OpenPhaseController, onUnlessFalse, PopoverController, reportRuntime, sideOf, timeConverter, unlinkDescription, } from '@fusion.dev/helix-core';
3
- import { html } from 'lit';
2
+ import { anchorElement, arrowReach, customElement, elementById, focusTarget, HelixElement, hintInside, hintMayShow, hostAria, linkDescription, MixinControllerOpen, numberConverter, OpenPhaseController, onPanelOpen, onUnlessFalse, PopoverController, reportRuntime, sideOf, timeConverter, unlinkDescription, } from '@fusion.dev/helix-core';
3
+ import { css, html } from 'lit';
4
4
  import { property, state } from 'lit/decorators.js';
5
5
  const GENERIC = new Set(['div', 'p', 'section', 'span']);
6
6
  const WARMTH = Symbol.for('fusion.helix.tooltip.warmth');
@@ -28,6 +28,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
28
28
  anchor: () => this.trigger,
29
29
  arrow: () => this.partNamed('arrow'),
30
30
  boundary: () => [this, this.named],
31
+ hints: 'keep',
31
32
  offset: () => this.offset + arrowReach(this.partNamed('arrow')),
32
33
  onDismiss: () => {
33
34
  this.holds.clear();
@@ -65,10 +66,10 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
65
66
  const warm = warmth();
66
67
  const others = [...warm.showing].some((one) => one !== this);
67
68
  if (others || performance.now() - warm.hidAt < this.skipDelay) {
68
- this.show();
69
+ this.showForReader();
69
70
  return;
70
71
  }
71
- this.timer = setTimeout(() => this.show(), this.delay);
72
+ this.timer = setTimeout(() => this.showForReader(), this.delay);
72
73
  };
73
74
  this.holdOnBubble = () => {
74
75
  if (!this.hoverable) {
@@ -97,7 +98,7 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
97
98
  return;
98
99
  }
99
100
  this.holds.add('focus');
100
- this.show();
101
+ this.showForReader();
101
102
  };
102
103
  this.releaseFocus = () => {
103
104
  this.holds.delete('focus');
@@ -115,7 +116,18 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
115
116
  this.link(true, event.type === 'focusin' && first instanceof Element ? first : undefined);
116
117
  };
117
118
  this.audited = false;
119
+ this.yieldTo = (surface) => {
120
+ if (this.open && this.holds.size > 0 && !hintInside(surface, this)) {
121
+ this.holds.clear();
122
+ this.hide();
123
+ }
124
+ };
125
+ }
126
+ static { this.styles = css `
127
+ :host {
128
+ display: contents;
118
129
  }
130
+ `; }
119
131
  get trigger() {
120
132
  const named = this.named;
121
133
  if (named) {
@@ -180,6 +192,11 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
180
192
  }
181
193
  this.bubbleLayer.hide();
182
194
  }
195
+ showForReader() {
196
+ if (hintMayShow(this)) {
197
+ this.show();
198
+ }
199
+ }
183
200
  release() {
184
201
  if (this.holds.size === 0) {
185
202
  this.hide();
@@ -277,6 +294,9 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
277
294
  });
278
295
  return;
279
296
  }
297
+ if (this.triggerSays(this.describedText)) {
298
+ return;
299
+ }
280
300
  reportRuntime({
281
301
  kind: 'unlinked-trigger',
282
302
  message: `<${this.localName} for="${this.for}"> is not read out with its trigger. The link is ` +
@@ -294,12 +314,15 @@ let HelixHeadlessTooltip = class HelixHeadlessTooltip extends MixinControllerOpe
294
314
  }
295
315
  connectedCallback() {
296
316
  super.connectedCallback();
317
+ this.stopYielding ??= onPanelOpen(this.yieldTo);
297
318
  if (this.hasUpdated) {
298
319
  this.bind();
299
320
  }
300
321
  }
301
322
  disconnectedCallback() {
302
323
  super.disconnectedCallback();
324
+ this.stopYielding?.();
325
+ this.stopYielding = undefined;
303
326
  this.unbind();
304
327
  this.holds.clear();
305
328
  clearTimeout(this.timer);
@@ -306,6 +306,7 @@ export declare class HelixHeadlessTour extends HelixHeadlessTour_base {
306
306
  private light;
307
307
  /** Keeps `sizer` on the lit target, and on nothing once there is none. */
308
308
  private watch;
309
+ private readonly handleSlotChange;
309
310
  protected render(): TemplateResult;
310
311
  }
311
312
  declare global {
@@ -75,6 +75,9 @@ let HelixHeadlessTour = class HelixHeadlessTour extends MixinControllerOpen(Heli
75
75
  };
76
76
  this.followed = false;
77
77
  this.veiled = false;
78
+ this.handleSlotChange = () => {
79
+ this.requestUpdate();
80
+ };
78
81
  }
79
82
  static { this.words = 'helix-tour'; }
80
83
  get index() {
@@ -415,7 +418,7 @@ let HelixHeadlessTour = class HelixHeadlessTour extends MixinControllerOpen(Heli
415
418
  aria-hidden="true"
416
419
  style=${`left: ${spot.left}px; top: ${spot.top}px; block-size: ${spot.height}px; inline-size: ${spot.width}px; --tour-spotlight-x: ${spot.left}px; --tour-spotlight-y: ${spot.top}px; --tour-spotlight-width: ${spot.width}px; --tour-spotlight-height: ${spot.height}px`}
417
420
  ></div>`}
418
- <slot></slot>`;
421
+ <slot @slotchange=${this.handleSlotChange}></slot>`;
419
422
  }
420
423
  };
421
424
  __decorate([
@@ -31,6 +31,7 @@ let HelixHeadlessTourStop = class HelixHeadlessTourStop extends HelixElement {
31
31
  this.floating = new PopoverController(this, {
32
32
  anchor: () => this.target,
33
33
  arrow: () => this.partNamed('arrow'),
34
+ hints: 'keep',
34
35
  offset: () => {
35
36
  const tour = this.parentElement;
36
37
  return (tour?.spotlightPadding ?? 0) + arrowReach(this.partNamed('arrow'));