@nanoporetech-digital/components 4.5.0 → 4.5.1

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 (40) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cjs/nano-datalist_3.cjs.entry.js +1 -1
  3. package/dist/cjs/nano-dialog.cjs.entry.js +1 -1
  4. package/dist/cjs/nano-icon-button_2.cjs.entry.js +15 -18
  5. package/dist/cjs/nano-icon-button_2.cjs.entry.js.map +1 -1
  6. package/dist/cjs/{slot-6c6864a6.js → slot-a448c1a7.js} +3 -5
  7. package/dist/cjs/slot-a448c1a7.js.map +1 -0
  8. package/dist/collection/components/tooltip/tooltip.js +17 -18
  9. package/dist/collection/components/tooltip/tooltip.js.map +1 -1
  10. package/dist/collection/utils/slot.js +2 -4
  11. package/dist/collection/utils/slot.js.map +1 -1
  12. package/dist/components/slot.js +2 -4
  13. package/dist/components/slot.js.map +1 -1
  14. package/dist/components/tooltip.js +15 -18
  15. package/dist/components/tooltip.js.map +1 -1
  16. package/dist/esm/nano-datalist_3.entry.js +1 -1
  17. package/dist/esm/nano-dialog.entry.js +1 -1
  18. package/dist/esm/nano-icon-button_2.entry.js +15 -18
  19. package/dist/esm/nano-icon-button_2.entry.js.map +1 -1
  20. package/dist/esm/{slot-c38a2b92.js → slot-a4f6e2af.js} +3 -5
  21. package/dist/esm/slot-a4f6e2af.js.map +1 -0
  22. package/dist/nano-components/nano-components.css +1 -1
  23. package/dist/nano-components/nano-components.esm.js +1 -1
  24. package/dist/nano-components/{p-6d068d65.entry.js → p-25cb3889.entry.js} +2 -2
  25. package/dist/nano-components/p-25cb3889.entry.js.map +1 -0
  26. package/dist/nano-components/{p-053eb1df.entry.js → p-27eb26ef.entry.js} +2 -2
  27. package/dist/nano-components/{p-ac0ac58f.entry.js → p-2ad0d9a3.entry.js} +2 -2
  28. package/dist/nano-components/p-58cf5446.js +5 -0
  29. package/dist/nano-components/p-58cf5446.js.map +1 -0
  30. package/dist/types/components/tooltip/tooltip.d.ts +2 -3
  31. package/docs-json.json +1 -1
  32. package/hydrate/index.js +27 -32
  33. package/package.json +2 -2
  34. package/dist/cjs/slot-6c6864a6.js.map +0 -1
  35. package/dist/esm/slot-c38a2b92.js.map +0 -1
  36. package/dist/nano-components/p-6d068d65.entry.js.map +0 -1
  37. package/dist/nano-components/p-b933f3c8.js +0 -5
  38. package/dist/nano-components/p-b933f3c8.js.map +0 -1
  39. /package/dist/nano-components/{p-053eb1df.entry.js.map → p-27eb26ef.entry.js.map} +0 -0
  40. /package/dist/nano-components/{p-ac0ac58f.entry.js.map → p-2ad0d9a3.entry.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.5.1](https://git.oxfordnanolabs.local/Digital/nano-components/compare/v4.5.0...v4.5.1) (2023-04-19)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **tooltip:** fixed a vue / ssr issue where (for a11y) elements were injected into lightDOM causing hydration mismatch errors ([493f57d](https://git.oxfordnanolabs.local/Digital/nano-components/commits/493f57dba362e5f068e9f0e4f469a1e2c54d7882))
12
+
13
+
14
+
15
+
16
+
6
17
  # [4.5.0](https://git.oxfordnanolabs.local/Digital/nano-components/compare/v4.4.1...v4.5.0) (2023-04-18)
7
18
 
8
19
 
@@ -9,7 +9,7 @@ const index = require('./index-71f899a7.js');
9
9
  const activeElement = require('./active-element-2f9bf0aa.js');
10
10
  const throttle = require('./throttle-f55496c8.js');
11
11
  const dom = require('./dom-7acf7afd.js');
12
- const slot = require('./slot-6c6864a6.js');
12
+ const slot = require('./slot-a448c1a7.js');
13
13
 
14
14
  const datalistCss = ":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}:host{--padding-top:var(--nano-spacing-small, 8px);--padding-bottom:var(--nano-spacing-small, 8px);--padding-start:var(--nano-spacing-xlarge, 24px);--padding-end:var(--nano-spacing-xlarge, 24px);--font-size:0.8em;--color:#b5aea7;color:var(--color)}.dlist--isfiltered ::slotted(*:not(nano-option):not([slot=no-result]):not([slot=list-top]):not([slot=list-bottom])){display:none !important}.dlist__dropdown{--min-width:100%;--overflow:auto}.dlist__status{clip:rect(1px, 1px, 1px, 1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);block-size:1px;inline-size:1px;margin:-1px;overflow:hidden;padding:0;position:absolute}.dlist__menu{--padding-top:inherit;--padding-bottom:inherit;--padding-start:inherit;--padding-end:inherit;--font-size:inherit}";
15
15
 
@@ -8,7 +8,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
8
8
  const index = require('./index-71f899a7.js');
9
9
  const modal = require('./modal-5884a6de.js');
10
10
  const scroll = require('./scroll-6a9bedb4.js');
11
- const slot = require('./slot-6c6864a6.js');
11
+ const slot = require('./slot-a448c1a7.js');
12
12
  const componentStore = require('./component-store-74d25f63.js');
13
13
  require('./tabbable-bdf10c84.js');
14
14
  require('./dom-7acf7afd.js');
@@ -57,7 +57,6 @@ IconButton.style = iconButtonCss;
57
57
 
58
58
  const tooltipCss = ":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}:host{--max-width:20rem;--hide-delay:0s;--hide-duration:0.125s;--hide-timing-function:ease;--show-delay:0.125s;--show-duration:0.125s;--show-timing-function:ease;display:contents}.tooltip{max-inline-size:var(--max-width);border-radius:var(--nano-tooltip-border-radius, var(--nano-border-radius-small, 2px));background-color:black;font-size:var(--nano-fontsize-small, 0.875rem);line-height:1.5;color:white;opacity:0;padding:var(--nano-tooltip-padding, var(--nano-spacing-xsmall, 4px) var(--nano-spacing-small, 8px));transform:translateY(10px) translateZ(0);transform-origin:bottom;transition:opacity, transform var(--hide-duration) var(--hide-timing-function) var(--hide-delay);white-space:normal}.tooltip-arrow{content:\"\";position:absolute;inline-size:0;block-size:0;color:black;transition:0.2s ease transform}.tooltip-positioner{position:absolute;z-index:var(--nano-layer-index-tooltip, 1000)}.tooltip-positioner[data-popper-placement^=top] .tooltip{transform-origin:bottom;transform:translateY(-10px) translateZ(0)}.tooltip-positioner[data-popper-placement^=bottom] .tooltip{transform-origin:top}.tooltip-positioner[data-popper-placement^=left] .tooltip{transform-origin:right}.tooltip-positioner[data-popper-placement^=right] .tooltip{transform-origin:left}.tooltip-positioner.popover-visible .tooltip{opacity:1;transform:none;transition-delay:var(--show-delay);transition-duration:var(--show-duration);transition-timing-function:var(--show-timing-function)}.tooltip-positioner[data-popper-placement^=bottom] .tooltip-arrow{inset-block-end:100%;inset-inline-start:calc(50% - 5px);-webkit-border-after:5px solid;border-block-end:5px solid;-webkit-border-start:5px solid transparent;border-inline-start:5px solid transparent;-webkit-border-end:5px solid transparent;border-inline-end:5px solid transparent}.tooltip-positioner[data-popper-placement=bottom-start] .tooltip-arrow{inset-inline-start:5px}.tooltip-positioner[data-popper-placement=bottom-end] .tooltip-arrow{inset-inline:auto 5px}.tooltip-positioner[data-popper-placement^=top] .tooltip-arrow{inset-block-start:100%;inset-inline-start:calc(50% - 5px);-webkit-border-before:5px solid;border-block-start:5px solid;-webkit-border-start:5px solid transparent;border-inline-start:5px solid transparent;-webkit-border-end:5px solid transparent;border-inline-end:5px solid transparent}.tooltip-positioner[data-popper-placement=top-start] .tooltip-arrow{inset-inline-start:5px}.tooltip-positioner[data-popper-placement=top-end] .tooltip-arrow{inset-inline:auto 5px}.tooltip-positioner[data-popper-placement^=left] .tooltip-arrow{inset-block-start:calc(50% - 5px);inset-inline-start:100%;-webkit-border-start:5px solid;border-inline-start:5px solid;-webkit-border-before:5px solid transparent;border-block-start:5px solid transparent;-webkit-border-after:5px solid transparent;border-block-end:5px solid transparent}.tooltip-positioner[data-popper-placement=left-start] .tooltip-arrow{inset-block-start:5px}.tooltip-positioner[data-popper-placement=left-end] .tooltip-arrow{inset-block:auto 5px}.tooltip-positioner[data-popper-placement^=right] .tooltip-arrow{inset-block-start:calc(50% - 5px);inset-inline-end:100%;-webkit-border-end:5px solid;border-inline-end:5px solid;-webkit-border-before:5px solid transparent;border-block-start:5px solid transparent;-webkit-border-after:5px solid transparent;border-block-end:5px solid transparent}.tooltip-positioner[data-popper-placement=right-start] .tooltip-arrow{inset-block-start:5px}.tooltip-positioner[data-popper-placement=right-end] .tooltip-arrow{inset-block:auto 5px}";
59
59
 
60
- let id = 0;
61
60
  const Tooltip = class {
62
61
  constructor(hostRef) {
63
62
  index.registerInstance(this, hostRef);
@@ -65,8 +64,8 @@ const Tooltip = class {
65
64
  this.nanoAfterShow = index.createEvent(this, "nanoAfterShow", 7);
66
65
  this.nanoHide = index.createEvent(this, "nanoHide", 7);
67
66
  this.nanoAfterHide = index.createEvent(this, "nanoAfterHide", 7);
68
- this.componentId = `tooltip-${++id}`;
69
67
  this.isVisible = false;
68
+ this.label = '';
70
69
  // Event Handlers
71
70
  this.handleBlur = () => {
72
71
  if (this.hasTrigger('focus')) {
@@ -103,15 +102,6 @@ const Tooltip = class {
103
102
  this.handleSlotChange = () => {
104
103
  this.target = this.getTarget();
105
104
  };
106
- this.handleTTSlotChange = () => {
107
- const contentDiv = this.host.querySelector(`[id="${this.componentId}"]`) ||
108
- this.defaultContent;
109
- Array.from(this.host.querySelectorAll('[slot="content"]'))
110
- .filter((elm) => elm !== contentDiv)
111
- .forEach((elm) => {
112
- contentDiv.appendChild(elm);
113
- });
114
- };
115
105
  this.content = '';
116
106
  this.placement = 'top';
117
107
  this.disabled = false;
@@ -126,11 +116,20 @@ const Tooltip = class {
126
116
  }
127
117
  set target(newTarget) {
128
118
  if (newTarget !== this._target && this._target) {
129
- this._target.removeAttribute('aria-describedby');
119
+ this._target.removeAttribute('aria-label');
130
120
  }
131
- newTarget.setAttribute('aria-describedby', this.componentId);
121
+ newTarget.setAttribute('aria-label', this.label);
132
122
  this._target = newTarget;
133
123
  }
124
+ setLabel() {
125
+ const contentSlotNodes = Array.from(this.host.querySelectorAll('[slot="content"]'));
126
+ const textContent = contentSlotNodes
127
+ .map((node) => node.textContent)
128
+ .join(' ')
129
+ .trim();
130
+ this.label = textContent || this.content;
131
+ this.target.setAttribute('aria-label', this.label);
132
+ }
134
133
  handleOpenChange() {
135
134
  this.open ? this.show() : this.hide();
136
135
  }
@@ -195,10 +194,7 @@ const Tooltip = class {
195
194
  this.target = this.getTarget();
196
195
  this.popover = new popover.Popover(this.target, this.tooltipPositioner);
197
196
  this.syncOptions();
198
- const ele = this.defaultContent;
199
- ele.slot = 'content';
200
- this.host.appendChild(ele);
201
- this.handleTTSlotChange();
197
+ this.setLabel();
202
198
  // Show on init if open
203
199
  this.tooltipPositioner.hidden = !this.open;
204
200
  if (this.open) {
@@ -215,10 +211,11 @@ const Tooltip = class {
215
211
  return (index.h(index.Host, { onKeyDown: this.handleKeyDown, onMouseOver: this.handleMouseOver, onMouseOut: this.handleMouseOut, onBlur: this.handleBlur, onFocus: this.handleFocus, onClick: this.handleClick }, index.h("slot", { onSlotchange: this.handleSlotChange }), index.h("div", { ref: (el) => (this.tooltipPositioner = el), class: "tooltip-positioner" }, index.h("div", { part: "base", ref: (el) => (this.tooltip = el), class: {
216
212
  tooltip: true,
217
213
  'tooltip--open': this.open,
218
- }, role: "tooltip", "aria-hidden": this.open ? 'false' : 'true' }, index.h("slot", { name: "content", onSlotchange: this.handleTTSlotChange }, index.h("div", { ref: (el) => (this.defaultContent = el), id: this.componentId }, this.content)), index.h("div", { class: "tooltip-arrow", "data-popper-arrow": true })))));
214
+ }, role: "tooltip", "aria-hidden": this.open ? 'false' : 'true' }, index.h("slot", { name: "content", onSlotchange: () => this.setLabel() }, this.content), index.h("div", { class: "tooltip-arrow", "data-popper-arrow": true })))));
219
215
  }
220
216
  get host() { return index.getElement(this); }
221
217
  static get watchers() { return {
218
+ "content": ["setLabel"],
222
219
  "open": ["handleOpenChange"]
223
220
  }; }
224
221
  };
@@ -1 +1 @@
1
- {"file":"nano-icon-button.nano-tooltip.entry.cjs.js","mappings":"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","names":["focusVisible","h","Popover","Host"],"sources":["./src/components/icon-button/icon-button.scss?tag=nano-icon-button&encapsulation=scoped","./src/components/icon-button/icon-button.tsx","./src/components/tooltip/tooltip.scss?tag=nano-tooltip&encapsulation=shadow","./src/components/tooltip/tooltip.tsx"],"sourcesContent":["@use 'sass:map';\n@use 'sass:list';\n\n@import '../../global/style/nano-theme/base';\n@import '../../global/style/nano-theme/colours';\n@import '../../global/style/nano-theme/form';\n\n:host {\n /**\n * @prop --border-radius: defaults to #{$border-radius-medium};\n * @prop --border-radius: defaults to #{$border-radius-medium};\n * @prop --color: defaults to #{map.get($colors, palegrey)};\n * @prop --active-color: defaults to #{map.get($colors, darkblue--faded)};\n * @prop --hover-color: defaults to #{map.get($colors, blue)};\n * @prop --background: defaults to transparent;\n * @prop --padding: defaults to #{$spacing-small};\n */\n display: inline-block;\n\n --border-radius: #{$border-radius-medium};\n --active-color: #{map.get($colors, darkblue--faded)};\n --hover-color: #{map.get($colors, blue)};\n --nano-color-base: var(--color, #{map.get($colors, mediumgrey)});\n --background: transparent;\n --padding: #{$spacing-small};\n}\n\n.icon-button {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n border: none;\n border-radius: var(--border-radius);\n background: var(--background);\n font-size: inherit;\n color: var(--color);\n padding: var(--padding);\n cursor: pointer;\n appearance: none;\n transition: box-shadow #{$transition-xfast} ease-in-out;\n\n &:hover:not(.icon-button--disabled),\n &:focus:not(.icon-button--disabled) {\n color: var(--hover-color);\n\n --nano-color-base: var(--hover-color);\n }\n\n &:active:not(.icon-button--disabled) {\n color: var(--active-color);\n\n --nano-color-base: var(--active-color);\n }\n\n &:focus {\n outline: none;\n }\n}\n\n.icon-button--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.focus-visible.icon-button:focus {\n box-shadow: #{$control-focus-style};\n}\n","import { Component, Prop, h, ComponentInterface, Method } from '@stencil/core';\nimport { focusVisible } from '../../utils/focus-visible';\n\n/** Icons buttons are simple, icon-only buttons that can be used for actions and in toolbars.\n *\n * @part base - the main control (either `<a />` or `<button />`)\n * @part icon - a `<nano-icon />` component\n */\n\n@Component({\n tag: 'nano-icon-button',\n styleUrl: 'icon-button.scss',\n scoped: true,\n})\nexport class IconButton implements ComponentInterface {\n private button: HTMLButtonElement;\n\n /** The name of the icon to draw. */\n @Prop() iconName?: string;\n\n /** An external URL of an SVG file. */\n @Prop() iconSrc?: string;\n\n /** The default behavior of the button. */\n @Prop({ reflect: true }) type: 'submit' | 'reset' | 'button' = 'button';\n\n /** The name of the button, submitted as a pair with the button’s value as part of the form data. */\n @Prop({ reflect: true }) name?: string;\n\n /** Defines the value associated with the button’s name when it’s submitted with the form data. */\n @Prop({ reflect: true }) value?: string;\n\n /** A description that gets read by screen readers and other assistive devices. For optimal accessibility, you should\n * always include a label that describes what the icon button does. */\n @Prop() label!: string;\n\n /** display the label as a `<nano-tooltip />` */\n @Prop() showTooltip: boolean = false;\n\n /** Set to true to disable the button. */\n @Prop({ reflect: true }) disabled = false;\n\n /** Contains a URL or a URL fragment that the hyperlink points to.\n * If this property is set, an anchor tag will be rendered. */\n @Prop() href: string | undefined;\n\n /** Specifies where to display the linked URL. Only applies when an `href` is provided.\n * Special keywords: `\"_blank\"`, `\"_self\"`, `\"_parent\"`, `\"_top\"`. */\n @Prop() target: string | undefined;\n\n /** Sets focus on the internal button */\n @Method()\n async setFocus() {\n this.button.focus();\n }\n\n componentDidLoad() {\n focusVisible.observe(this.button);\n }\n\n connectedCallback() {\n if (this.button) focusVisible.observe(this.button);\n }\n\n disconnectedCallback() {\n focusVisible.unobserve(this.button);\n }\n\n private content() {\n const TagType = this.href === undefined ? 'button' : ('a' as any);\n\n return (\n <TagType\n part=\"base\"\n ref={(el) => (this.button = el)}\n class={{\n 'icon-button': true,\n 'icon-button--disabled': this.disabled,\n }}\n aria-label={this.label}\n name={this.name}\n value={this.value}\n href={this.href || undefined}\n target={this.href && this.target ? this.target : undefined}\n type={!this.href && this.type ? this.type : undefined}\n >\n <nano-icon\n name={this.iconName}\n src={this.iconSrc}\n aria-hidden=\"true\"\n lazy={false}\n part=\"icon\"\n />\n </TagType>\n );\n }\n\n render() {\n if (this.showTooltip) {\n return <nano-tooltip content={this.label}>{this.content()}</nano-tooltip>;\n }\n return this.content();\n }\n}\n","@import '../../global/style/nano-theme/components';\n@import '../../global/style/nano-theme/layers';\n\n/**\n * @prop --hide-delay: The amount of time to wait before hiding the tooltip.\n * @prop --hide-duration: The amount of time the hide transition takes to complete.\n * @prop --hide-timing-function: The timing function (easing) to use for the hide transition.\n * @prop --max-width: The maximum width of the tooltip.\n * @prop --show-delay: The amount of time to wait before showing the tooltip.\n * @prop --show-duration: The amount of time the show transition takes to complete.\n * @prop --show-timing-function: The timing function (easing) to use for the show transition.\n */\n:host {\n --max-width: 20rem;\n --hide-delay: 0s;\n --hide-duration: 0.125s;\n --hide-timing-function: ease;\n --show-delay: 0.125s;\n --show-duration: 0.125s;\n --show-timing-function: ease;\n\n /* autoprefixer: ignore next */\n display: contents;\n}\n\n.tooltip {\n $self: &;\n\n max-inline-size: var(--max-width);\n border-radius: #{$tooltip-border-radius};\n background-color: black;\n font-size: #{$tooltip-fontsize};\n line-height: 1.5;\n color: white;\n opacity: 0;\n padding: #{$tooltip-padding};\n transform: translateY(10px) translateZ(0);\n transform-origin: bottom;\n transition: opacity, transform var(--hide-duration) var(--hide-timing-function) var(--hide-delay);\n white-space: normal;\n\n &-arrow {\n content: '';\n position: absolute;\n inline-size: 0;\n block-size: 0;\n color: black;\n transition: 0.2s ease transform;\n }\n\n &-positioner {\n position: absolute;\n z-index: #{$layer-index-tooltip};\n\n &[data-popper-placement^='top'] #{$self} {\n transform-origin: bottom;\n transform: translateY(-10px) translateZ(0);\n }\n\n &[data-popper-placement^='bottom'] #{$self} {\n transform-origin: top;\n }\n\n &[data-popper-placement^='left'] #{$self} {\n transform-origin: right;\n }\n\n &[data-popper-placement^='right'] #{$self} {\n transform-origin: left;\n }\n\n &.popover-visible #{$self} {\n opacity: 1;\n transform: none;\n transition-delay: var(--show-delay);\n transition-duration: var(--show-duration);\n transition-timing-function: var(--show-timing-function);\n }\n\n // Arrow + bottom\n &[data-popper-placement^='bottom'] #{$self}-arrow {\n inset-block-end: 100%;\n inset-inline-start: calc(50% - #{$tooltip-arrow-size});\n border-block-end: #{$tooltip-arrow-size} solid;\n border-inline-start: #{$tooltip-arrow-size} solid transparent;\n border-inline-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='bottom-start'] #{$self}-arrow {\n inset-inline-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='bottom-end'] #{$self}-arrow {\n inset-inline: auto #{$tooltip-arrow-offset};\n }\n\n // Arrow + top\n &[data-popper-placement^='top'] #{$self}-arrow {\n inset-block-start: 100%;\n inset-inline-start: calc(50% - #{$tooltip-arrow-size});\n border-block-start: #{$tooltip-arrow-size} solid;\n border-inline-start: #{$tooltip-arrow-size} solid transparent;\n border-inline-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='top-start'] #{$self}-arrow {\n inset-inline-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='top-end'] #{$self}-arrow {\n inset-inline: auto #{$tooltip-arrow-offset};\n }\n\n // Arrow + left\n &[data-popper-placement^='left'] #{$self}-arrow {\n inset-block-start: calc(50% - #{$tooltip-arrow-size});\n inset-inline-start: 100%;\n border-inline-start: #{$tooltip-arrow-size} solid;\n border-block-start: #{$tooltip-arrow-size} solid transparent;\n border-block-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='left-start'] #{$self}-arrow {\n inset-block-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='left-end'] #{$self}-arrow {\n inset-block: auto #{$tooltip-arrow-offset};\n }\n\n // Arrow + right\n &[data-popper-placement^='right'] #{$self}-arrow {\n inset-block-start: calc(50% - #{$tooltip-arrow-size});\n inset-inline-end: 100%;\n border-inline-end: #{$tooltip-arrow-size} solid;\n border-block-start: #{$tooltip-arrow-size} solid transparent;\n border-block-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='right-start'] #{$self}-arrow {\n inset-block-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='right-end'] #{$self}-arrow {\n inset-block: auto #{$tooltip-arrow-offset};\n }\n }\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n Watch,\n h,\n} from '@stencil/core';\nimport Popover from '../../utils/popover';\n\nlet id = 0;\n\n/**\n * Tooltips display additional information based on a specific action.\n * @slot - The tooltip's target element. Only the first element will be used as the target.\n * @slot content - The tooltip's content. Alternatively, you can use the content prop.\n */\n@Component({\n tag: 'nano-tooltip',\n styleUrl: 'tooltip.scss',\n shadow: true,\n})\nexport class Tooltip {\n private componentId = `tooltip-${++id}`;\n private isVisible = false;\n private popover: Popover;\n private tooltipPositioner: HTMLElement;\n private tooltip: any;\n private defaultContent: HTMLElement;\n\n private _target: HTMLElement;\n private get target() {\n return this._target;\n }\n private set target(newTarget) {\n if (newTarget !== this._target && this._target) {\n this._target.removeAttribute('aria-describedby');\n }\n newTarget.setAttribute('aria-describedby', this.componentId);\n this._target = newTarget;\n }\n\n @Element() host: HTMLNanoTooltipElement;\n\n /** The tooltip's content. Alternatively, you can use the content slot. */\n @Prop() content = '';\n\n /**\n * The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip\n * inside of the viewport.\n */\n @Prop() placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'top';\n\n /** Set to true to disable the tooltip so it won't show when triggered. */\n @Prop() disabled = false;\n\n /** The distance in pixels from which to offset the tooltip away from its target. */\n @Prop() distance = 10;\n\n /** Indicates whether or not the tooltip is open. You can use this in lieu of the show/hide methods. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /** The distance in pixels from which to offset the tooltip along its target. */\n @Prop() skidding = 0;\n\n /**\n * Enable this option to prevent the panel from being clipped when the component is placed inside a container with\n * `overflow: auto|scroll`.\n */\n @Prop() hoist = false;\n\n /**\n * Controls how the tooltip is activated. Possible options include `click`, `hover`, `focus`, and `manual`. Multiple\n * options can be passed by separating them with a space. When manual is used, the tooltip must be activated\n * programmatically.\n */\n @Prop() trigger: string = 'hover focus';\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n // Events\n\n /** Emitted when the tooltip begins to show. Calling `event.preventDefault()` will prevent it from being shown. */\n @Event() nanoShow: EventEmitter;\n\n /** Emitted after the tooltip has shown and all transitions are complete. */\n @Event() nanoAfterShow: EventEmitter;\n\n /** Emitted when the tooltip begins to hide. Calling `event.preventDefault()` will prevent it from being hidden. */\n @Event() nanoHide: EventEmitter;\n\n /** Emitted after the tooltip has hidden and all transitions are complete. */\n @Event() nanoAfterHide: EventEmitter;\n\n // Public methods\n\n /** Shows the tooltip. */\n @Method()\n async show() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (this.isVisible || this.disabled) {\n return;\n }\n const slShow = this.nanoShow.emit();\n if (slShow.defaultPrevented) {\n this.open = false;\n return;\n }\n\n this.isVisible = true;\n this.open = true;\n this.popover.show();\n }\n\n /** Hides the tooltip. */\n @Method()\n async hide() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (!this.isVisible) {\n return;\n }\n\n const slHide = this.nanoHide.emit();\n if (slHide.defaultPrevented) {\n this.open = true;\n return;\n }\n\n this.isVisible = false;\n this.open = false;\n this.popover.hide();\n }\n\n // Private methods\n\n private getTarget() {\n // Get the first child that isn't a <style> or content slot\n const target = [...Array.from(this.host.children)].find(\n (el) =>\n el.tagName.toLowerCase() !== 'style' &&\n el.getAttribute('slot') !== 'content'\n ) as HTMLElement;\n\n if (!target) {\n throw new Error('Invalid tooltip target: no child element was found.');\n }\n\n return target;\n }\n\n private hasTrigger(triggerType: string) {\n const triggers = this.trigger.split(' ');\n return triggers.includes(triggerType);\n }\n\n private syncOptions() {\n this.popover.setOptions({\n strategy: this.hoist ? 'fixed' : 'absolute',\n placement: this.placement,\n distance: this.distance,\n skidding: this.skidding,\n transitionElement: this.tooltip,\n onAfterHide: () => this.nanoAfterHide.emit(),\n onAfterShow: () => this.nanoAfterShow.emit(),\n });\n }\n\n // Event Handlers\n\n private handleBlur = () => {\n if (this.hasTrigger('focus')) {\n this.hide();\n }\n };\n\n private handleClick = () => {\n if (this.hasTrigger('click')) {\n this.open ? this.hide() : this.show();\n }\n };\n\n private handleFocus = () => {\n if (this.hasTrigger('focus')) {\n this.show();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Pressing escape when the target element has focus should dismiss the tooltip\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n }\n };\n\n private handleMouseOver = () => {\n if (this.hasTrigger('hover')) {\n this.show();\n }\n };\n\n private handleMouseOut = () => {\n if (this.hasTrigger('hover')) {\n this.hide();\n }\n };\n\n private handleSlotChange = () => {\n this.target = this.getTarget();\n };\n\n private handleTTSlotChange = () => {\n const contentDiv =\n this.host.querySelector(`[id=\"${this.componentId}\"]`) ||\n this.defaultContent;\n\n Array.from(this.host.querySelectorAll('[slot=\"content\"]'))\n .filter((elm) => elm !== contentDiv)\n .forEach((elm) => {\n contentDiv.appendChild(elm);\n });\n };\n\n // Stencil hooks\n\n componentDidLoad() {\n this.target = this.getTarget();\n this.popover = new Popover(this.target, this.tooltipPositioner);\n this.syncOptions();\n\n const ele = this.defaultContent;\n ele.slot = 'content';\n this.host.appendChild(ele);\n this.handleTTSlotChange();\n\n // Show on init if open\n this.tooltipPositioner.hidden = !this.open;\n if (this.open) {\n this.show();\n }\n }\n\n componentDidUpdate() {\n this.syncOptions();\n }\n\n disconnectedCallback() {\n this.popover.destroy();\n }\n\n render() {\n return (\n <Host\n onKeyDown={this.handleKeyDown}\n onMouseOver={this.handleMouseOver}\n onMouseOut={this.handleMouseOut}\n onBlur={this.handleBlur}\n onFocus={this.handleFocus}\n onClick={this.handleClick}\n >\n <slot onSlotchange={this.handleSlotChange} />\n <div\n ref={(el) => (this.tooltipPositioner = el)}\n class=\"tooltip-positioner\"\n >\n <div\n part=\"base\"\n ref={(el) => (this.tooltip = el)}\n class={{\n tooltip: true,\n 'tooltip--open': this.open,\n }}\n role=\"tooltip\"\n aria-hidden={this.open ? 'false' : 'true'}\n >\n <slot name=\"content\" onSlotchange={this.handleTTSlotChange}>\n <div\n ref={(el) => (this.defaultContent = el)}\n id={this.componentId}\n >\n {this.content}\n </div>\n </slot>\n <div class=\"tooltip-arrow\" data-popper-arrow></div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"version":3}
1
+ {"file":"nano-icon-button.nano-tooltip.entry.cjs.js","mappings":"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","names":["focusVisible","h","Popover","Host"],"sources":["./src/components/icon-button/icon-button.scss?tag=nano-icon-button&encapsulation=scoped","./src/components/icon-button/icon-button.tsx","./src/components/tooltip/tooltip.scss?tag=nano-tooltip&encapsulation=shadow","./src/components/tooltip/tooltip.tsx"],"sourcesContent":["@use 'sass:map';\n@use 'sass:list';\n\n@import '../../global/style/nano-theme/base';\n@import '../../global/style/nano-theme/colours';\n@import '../../global/style/nano-theme/form';\n\n:host {\n /**\n * @prop --border-radius: defaults to #{$border-radius-medium};\n * @prop --border-radius: defaults to #{$border-radius-medium};\n * @prop --color: defaults to #{map.get($colors, palegrey)};\n * @prop --active-color: defaults to #{map.get($colors, darkblue--faded)};\n * @prop --hover-color: defaults to #{map.get($colors, blue)};\n * @prop --background: defaults to transparent;\n * @prop --padding: defaults to #{$spacing-small};\n */\n display: inline-block;\n\n --border-radius: #{$border-radius-medium};\n --active-color: #{map.get($colors, darkblue--faded)};\n --hover-color: #{map.get($colors, blue)};\n --nano-color-base: var(--color, #{map.get($colors, mediumgrey)});\n --background: transparent;\n --padding: #{$spacing-small};\n}\n\n.icon-button {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n border: none;\n border-radius: var(--border-radius);\n background: var(--background);\n font-size: inherit;\n color: var(--color);\n padding: var(--padding);\n cursor: pointer;\n appearance: none;\n transition: box-shadow #{$transition-xfast} ease-in-out;\n\n &:hover:not(.icon-button--disabled),\n &:focus:not(.icon-button--disabled) {\n color: var(--hover-color);\n\n --nano-color-base: var(--hover-color);\n }\n\n &:active:not(.icon-button--disabled) {\n color: var(--active-color);\n\n --nano-color-base: var(--active-color);\n }\n\n &:focus {\n outline: none;\n }\n}\n\n.icon-button--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n pointer-events: none;\n}\n\n.focus-visible.icon-button:focus {\n box-shadow: #{$control-focus-style};\n}\n","import { Component, Prop, h, ComponentInterface, Method } from '@stencil/core';\nimport { focusVisible } from '../../utils/focus-visible';\n\n/** Icons buttons are simple, icon-only buttons that can be used for actions and in toolbars.\n *\n * @part base - the main control (either `<a />` or `<button />`)\n * @part icon - a `<nano-icon />` component\n */\n\n@Component({\n tag: 'nano-icon-button',\n styleUrl: 'icon-button.scss',\n scoped: true,\n})\nexport class IconButton implements ComponentInterface {\n private button: HTMLButtonElement;\n\n /** The name of the icon to draw. */\n @Prop() iconName?: string;\n\n /** An external URL of an SVG file. */\n @Prop() iconSrc?: string;\n\n /** The default behavior of the button. */\n @Prop({ reflect: true }) type: 'submit' | 'reset' | 'button' = 'button';\n\n /** The name of the button, submitted as a pair with the button’s value as part of the form data. */\n @Prop({ reflect: true }) name?: string;\n\n /** Defines the value associated with the button’s name when it’s submitted with the form data. */\n @Prop({ reflect: true }) value?: string;\n\n /** A description that gets read by screen readers and other assistive devices. For optimal accessibility, you should\n * always include a label that describes what the icon button does. */\n @Prop() label!: string;\n\n /** display the label as a `<nano-tooltip />` */\n @Prop() showTooltip: boolean = false;\n\n /** Set to true to disable the button. */\n @Prop({ reflect: true }) disabled = false;\n\n /** Contains a URL or a URL fragment that the hyperlink points to.\n * If this property is set, an anchor tag will be rendered. */\n @Prop() href: string | undefined;\n\n /** Specifies where to display the linked URL. Only applies when an `href` is provided.\n * Special keywords: `\"_blank\"`, `\"_self\"`, `\"_parent\"`, `\"_top\"`. */\n @Prop() target: string | undefined;\n\n /** Sets focus on the internal button */\n @Method()\n async setFocus() {\n this.button.focus();\n }\n\n componentDidLoad() {\n focusVisible.observe(this.button);\n }\n\n connectedCallback() {\n if (this.button) focusVisible.observe(this.button);\n }\n\n disconnectedCallback() {\n focusVisible.unobserve(this.button);\n }\n\n private content() {\n const TagType = this.href === undefined ? 'button' : ('a' as any);\n\n return (\n <TagType\n part=\"base\"\n ref={(el) => (this.button = el)}\n class={{\n 'icon-button': true,\n 'icon-button--disabled': this.disabled,\n }}\n aria-label={this.label}\n name={this.name}\n value={this.value}\n href={this.href || undefined}\n target={this.href && this.target ? this.target : undefined}\n type={!this.href && this.type ? this.type : undefined}\n >\n <nano-icon\n name={this.iconName}\n src={this.iconSrc}\n aria-hidden=\"true\"\n lazy={false}\n part=\"icon\"\n />\n </TagType>\n );\n }\n\n render() {\n if (this.showTooltip) {\n return <nano-tooltip content={this.label}>{this.content()}</nano-tooltip>;\n }\n return this.content();\n }\n}\n","@import '../../global/style/nano-theme/components';\n@import '../../global/style/nano-theme/layers';\n\n/**\n * @prop --hide-delay: The amount of time to wait before hiding the tooltip.\n * @prop --hide-duration: The amount of time the hide transition takes to complete.\n * @prop --hide-timing-function: The timing function (easing) to use for the hide transition.\n * @prop --max-width: The maximum width of the tooltip.\n * @prop --show-delay: The amount of time to wait before showing the tooltip.\n * @prop --show-duration: The amount of time the show transition takes to complete.\n * @prop --show-timing-function: The timing function (easing) to use for the show transition.\n */\n:host {\n --max-width: 20rem;\n --hide-delay: 0s;\n --hide-duration: 0.125s;\n --hide-timing-function: ease;\n --show-delay: 0.125s;\n --show-duration: 0.125s;\n --show-timing-function: ease;\n\n /* autoprefixer: ignore next */\n display: contents;\n}\n\n.tooltip {\n $self: &;\n\n max-inline-size: var(--max-width);\n border-radius: #{$tooltip-border-radius};\n background-color: black;\n font-size: #{$tooltip-fontsize};\n line-height: 1.5;\n color: white;\n opacity: 0;\n padding: #{$tooltip-padding};\n transform: translateY(10px) translateZ(0);\n transform-origin: bottom;\n transition: opacity, transform var(--hide-duration) var(--hide-timing-function) var(--hide-delay);\n white-space: normal;\n\n &-arrow {\n content: '';\n position: absolute;\n inline-size: 0;\n block-size: 0;\n color: black;\n transition: 0.2s ease transform;\n }\n\n &-positioner {\n position: absolute;\n z-index: #{$layer-index-tooltip};\n\n &[data-popper-placement^='top'] #{$self} {\n transform-origin: bottom;\n transform: translateY(-10px) translateZ(0);\n }\n\n &[data-popper-placement^='bottom'] #{$self} {\n transform-origin: top;\n }\n\n &[data-popper-placement^='left'] #{$self} {\n transform-origin: right;\n }\n\n &[data-popper-placement^='right'] #{$self} {\n transform-origin: left;\n }\n\n &.popover-visible #{$self} {\n opacity: 1;\n transform: none;\n transition-delay: var(--show-delay);\n transition-duration: var(--show-duration);\n transition-timing-function: var(--show-timing-function);\n }\n\n // Arrow + bottom\n &[data-popper-placement^='bottom'] #{$self}-arrow {\n inset-block-end: 100%;\n inset-inline-start: calc(50% - #{$tooltip-arrow-size});\n border-block-end: #{$tooltip-arrow-size} solid;\n border-inline-start: #{$tooltip-arrow-size} solid transparent;\n border-inline-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='bottom-start'] #{$self}-arrow {\n inset-inline-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='bottom-end'] #{$self}-arrow {\n inset-inline: auto #{$tooltip-arrow-offset};\n }\n\n // Arrow + top\n &[data-popper-placement^='top'] #{$self}-arrow {\n inset-block-start: 100%;\n inset-inline-start: calc(50% - #{$tooltip-arrow-size});\n border-block-start: #{$tooltip-arrow-size} solid;\n border-inline-start: #{$tooltip-arrow-size} solid transparent;\n border-inline-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='top-start'] #{$self}-arrow {\n inset-inline-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='top-end'] #{$self}-arrow {\n inset-inline: auto #{$tooltip-arrow-offset};\n }\n\n // Arrow + left\n &[data-popper-placement^='left'] #{$self}-arrow {\n inset-block-start: calc(50% - #{$tooltip-arrow-size});\n inset-inline-start: 100%;\n border-inline-start: #{$tooltip-arrow-size} solid;\n border-block-start: #{$tooltip-arrow-size} solid transparent;\n border-block-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='left-start'] #{$self}-arrow {\n inset-block-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='left-end'] #{$self}-arrow {\n inset-block: auto #{$tooltip-arrow-offset};\n }\n\n // Arrow + right\n &[data-popper-placement^='right'] #{$self}-arrow {\n inset-block-start: calc(50% - #{$tooltip-arrow-size});\n inset-inline-end: 100%;\n border-inline-end: #{$tooltip-arrow-size} solid;\n border-block-start: #{$tooltip-arrow-size} solid transparent;\n border-block-end: #{$tooltip-arrow-size} solid transparent;\n }\n\n &[data-popper-placement='right-start'] #{$self}-arrow {\n inset-block-start: #{$tooltip-arrow-offset};\n }\n\n &[data-popper-placement='right-end'] #{$self}-arrow {\n inset-block: auto #{$tooltip-arrow-offset};\n }\n }\n}\n","import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n Watch,\n h,\n} from '@stencil/core';\nimport Popover from '../../utils/popover';\n\n/**\n * Tooltips display additional information based on a specific action.\n * @slot - The tooltip's target element. Only the first element will be used as the target.\n * @slot content - The tooltip's content. Alternatively, you can use the content prop.\n */\n@Component({\n tag: 'nano-tooltip',\n styleUrl: 'tooltip.scss',\n shadow: true,\n})\nexport class Tooltip {\n private isVisible = false;\n private popover: Popover;\n private tooltipPositioner: HTMLElement;\n private tooltip: any;\n\n private _target: HTMLElement;\n private get target() {\n return this._target;\n }\n private set target(newTarget) {\n if (newTarget !== this._target && this._target) {\n this._target.removeAttribute('aria-label');\n }\n newTarget.setAttribute('aria-label', this.label);\n this._target = newTarget;\n }\n\n private label = '';\n\n @Element() host: HTMLNanoTooltipElement;\n\n /** The tooltip's content. Alternatively, you can use the content slot. */\n @Prop() content = '';\n\n @Watch('content')\n setLabel() {\n const contentSlotNodes = Array.from(\n this.host.querySelectorAll('[slot=\"content\"]')\n );\n const textContent = contentSlotNodes\n .map((node) => node.textContent)\n .join(' ')\n .trim();\n\n this.label = textContent || this.content;\n this.target.setAttribute('aria-label', this.label);\n }\n\n /**\n * The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip\n * inside of the viewport.\n */\n @Prop() placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'top';\n\n /** Set to true to disable the tooltip so it won't show when triggered. */\n @Prop() disabled = false;\n\n /** The distance in pixels from which to offset the tooltip away from its target. */\n @Prop() distance = 10;\n\n /** Indicates whether or not the tooltip is open. You can use this in lieu of the show/hide methods. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /** The distance in pixels from which to offset the tooltip along its target. */\n @Prop() skidding = 0;\n\n /**\n * Enable this option to prevent the panel from being clipped when the component is placed inside a container with\n * `overflow: auto|scroll`.\n */\n @Prop() hoist = false;\n\n /**\n * Controls how the tooltip is activated. Possible options include `click`, `hover`, `focus`, and `manual`. Multiple\n * options can be passed by separating them with a space. When manual is used, the tooltip must be activated\n * programmatically.\n */\n @Prop() trigger: string = 'hover focus';\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n // Events\n\n /** Emitted when the tooltip begins to show. Calling `event.preventDefault()` will prevent it from being shown. */\n @Event() nanoShow: EventEmitter;\n\n /** Emitted after the tooltip has shown and all transitions are complete. */\n @Event() nanoAfterShow: EventEmitter;\n\n /** Emitted when the tooltip begins to hide. Calling `event.preventDefault()` will prevent it from being hidden. */\n @Event() nanoHide: EventEmitter;\n\n /** Emitted after the tooltip has hidden and all transitions are complete. */\n @Event() nanoAfterHide: EventEmitter;\n\n // Public methods\n\n /** Shows the tooltip. */\n @Method()\n async show() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (this.isVisible || this.disabled) {\n return;\n }\n const slShow = this.nanoShow.emit();\n if (slShow.defaultPrevented) {\n this.open = false;\n return;\n }\n\n this.isVisible = true;\n this.open = true;\n this.popover.show();\n }\n\n /** Hides the tooltip. */\n @Method()\n async hide() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (!this.isVisible) {\n return;\n }\n\n const slHide = this.nanoHide.emit();\n if (slHide.defaultPrevented) {\n this.open = true;\n return;\n }\n\n this.isVisible = false;\n this.open = false;\n this.popover.hide();\n }\n\n // Private methods\n\n private getTarget() {\n // Get the first child that isn't a <style> or content slot\n const target = [...Array.from(this.host.children)].find(\n (el) =>\n el.tagName.toLowerCase() !== 'style' &&\n el.getAttribute('slot') !== 'content'\n ) as HTMLElement;\n\n if (!target) {\n throw new Error('Invalid tooltip target: no child element was found.');\n }\n\n return target;\n }\n\n private hasTrigger(triggerType: string) {\n const triggers = this.trigger.split(' ');\n return triggers.includes(triggerType);\n }\n\n private syncOptions() {\n this.popover.setOptions({\n strategy: this.hoist ? 'fixed' : 'absolute',\n placement: this.placement,\n distance: this.distance,\n skidding: this.skidding,\n transitionElement: this.tooltip,\n onAfterHide: () => this.nanoAfterHide.emit(),\n onAfterShow: () => this.nanoAfterShow.emit(),\n });\n }\n\n // Event Handlers\n\n private handleBlur = () => {\n if (this.hasTrigger('focus')) {\n this.hide();\n }\n };\n\n private handleClick = () => {\n if (this.hasTrigger('click')) {\n this.open ? this.hide() : this.show();\n }\n };\n\n private handleFocus = () => {\n if (this.hasTrigger('focus')) {\n this.show();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Pressing escape when the target element has focus should dismiss the tooltip\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n }\n };\n\n private handleMouseOver = () => {\n if (this.hasTrigger('hover')) {\n this.show();\n }\n };\n\n private handleMouseOut = () => {\n if (this.hasTrigger('hover')) {\n this.hide();\n }\n };\n\n private handleSlotChange = () => {\n this.target = this.getTarget();\n };\n\n // Stencil hooks\n\n componentDidLoad() {\n this.target = this.getTarget();\n this.popover = new Popover(this.target, this.tooltipPositioner);\n this.syncOptions();\n this.setLabel();\n\n // Show on init if open\n this.tooltipPositioner.hidden = !this.open;\n if (this.open) {\n this.show();\n }\n }\n\n componentDidUpdate() {\n this.syncOptions();\n }\n\n disconnectedCallback() {\n this.popover.destroy();\n }\n\n render() {\n return (\n <Host\n onKeyDown={this.handleKeyDown}\n onMouseOver={this.handleMouseOver}\n onMouseOut={this.handleMouseOut}\n onBlur={this.handleBlur}\n onFocus={this.handleFocus}\n onClick={this.handleClick}\n >\n <slot onSlotchange={this.handleSlotChange} />\n <div\n ref={(el) => (this.tooltipPositioner = el)}\n class=\"tooltip-positioner\"\n >\n <div\n part=\"base\"\n ref={(el) => (this.tooltip = el)}\n class={{\n tooltip: true,\n 'tooltip--open': this.open,\n }}\n role=\"tooltip\"\n aria-hidden={this.open ? 'false' : 'true'}\n >\n <slot name=\"content\" onSlotchange={() => this.setLabel()}>\n {this.content}\n </slot>\n <div class=\"tooltip-arrow\" data-popper-arrow></div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"version":3}
@@ -19,11 +19,9 @@ function getTextContent(slot) {
19
19
  const nodes = slot.assignedNodes({ flatten: true });
20
20
  let text = '';
21
21
  [...nodes].map((node) => {
22
- if (node.nodeType === Node.TEXT_NODE) {
23
- text += node.textContent;
24
- }
22
+ text += node.textContent + ' ';
25
23
  });
26
- return text;
24
+ return text.trim();
27
25
  }
28
26
  /**
29
27
  * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named
@@ -55,4 +53,4 @@ function hasSlot(el, name) {
55
53
  exports.getTextContent = getTextContent;
56
54
  exports.hasSlot = hasSlot;
57
55
 
58
- //# sourceMappingURL=slot-6c6864a6.js.map
56
+ //# sourceMappingURL=slot-a448c1a7.js.map
@@ -0,0 +1 @@
1
+ {"file":"slot-a448c1a7.js","mappings":";;;;;AAAA;;;;;;AAuBA;;;;;;SAMgB,cAAc,CAAC,IAAqB;EAClD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI;IAClB,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;GAChC,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED;;;;;;;SAOgB,OAAO,CAAC,EAAe,EAAE,IAAa;;EAEpD,IAAI,IAAI,EAAE;IACR,OAAO,EAAE,CAAC,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;GACtD;;EAGD,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI;IAC9C,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;MACtE,OAAO,IAAI,CAAC;KACb;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,MAAM,EAAE,GAAG,IAAmB,CAAC;MAC/B,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;QAC5B,OAAO,IAAI,CAAC;OACb;KACF;IAED,OAAO,KAAK,CAAC;GACd,CAAC,CAAC;AACL;;;;;","names":[],"sources":["./src/utils/slot.ts"],"sourcesContent":["/**\n * Given a slot, this function iterates over all of its assigned elements and text nodes and returns the concatenated\n * HTML as a string. This is useful because we can't use slot.innerHTML as an alternative.\n * @param slot\n * @returns a concatenated string from html and text nodes\n */\nexport function getInnerHTML(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let html = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n html += (node as HTMLElement).outerHTML;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n html += node.textContent;\n }\n });\n\n return html;\n}\n\n/**\n * Given a slot, this function iterates over all of its assigned text nodes and returns the concatenated text as a\n * string. This is useful because we can't use slot.textContent as an alternative.\n * @param slot\n * @returns a concatenated string of text\n */\nexport function getTextContent(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let text = '';\n\n [...nodes].map((node) => {\n text += node.textContent + ' ';\n });\n\n return text.trim();\n}\n\n/**\n * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named\n * slot, otherwise it will look for a \"default\" slot (e.g. a non-empty text node or an element with no slot attribute).\n * @param el\n * @param name\n * @returns boolean\n */\nexport function hasSlot(el: HTMLElement, name?: string) {\n // Look for a named slot\n if (name) {\n return el.querySelector(`[slot=\"${name}\"]`) !== null;\n }\n\n // Look for a default slot\n return [...Array.from(el.childNodes)].some((node) => {\n if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== '') {\n return true;\n }\n\n if (node.nodeType === node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (!el.hasAttribute('slot')) {\n return true;\n }\n }\n\n return false;\n });\n}\n"],"version":3}
@@ -3,7 +3,6 @@
3
3
  */
4
4
  import { Host, h, } from '@stencil/core';
5
5
  import Popover from '../../utils/popover';
6
- let id = 0;
7
6
  /**
8
7
  * Tooltips display additional information based on a specific action.
9
8
  * @slot - The tooltip's target element. Only the first element will be used as the target.
@@ -11,8 +10,8 @@ let id = 0;
11
10
  */
12
11
  export class Tooltip {
13
12
  constructor() {
14
- this.componentId = `tooltip-${++id}`;
15
13
  this.isVisible = false;
14
+ this.label = '';
16
15
  // Event Handlers
17
16
  this.handleBlur = () => {
18
17
  if (this.hasTrigger('focus')) {
@@ -49,15 +48,6 @@ export class Tooltip {
49
48
  this.handleSlotChange = () => {
50
49
  this.target = this.getTarget();
51
50
  };
52
- this.handleTTSlotChange = () => {
53
- const contentDiv = this.host.querySelector(`[id="${this.componentId}"]`) ||
54
- this.defaultContent;
55
- Array.from(this.host.querySelectorAll('[slot="content"]'))
56
- .filter((elm) => elm !== contentDiv)
57
- .forEach((elm) => {
58
- contentDiv.appendChild(elm);
59
- });
60
- };
61
51
  this.content = '';
62
52
  this.placement = 'top';
63
53
  this.disabled = false;
@@ -72,11 +62,20 @@ export class Tooltip {
72
62
  }
73
63
  set target(newTarget) {
74
64
  if (newTarget !== this._target && this._target) {
75
- this._target.removeAttribute('aria-describedby');
65
+ this._target.removeAttribute('aria-label');
76
66
  }
77
- newTarget.setAttribute('aria-describedby', this.componentId);
67
+ newTarget.setAttribute('aria-label', this.label);
78
68
  this._target = newTarget;
79
69
  }
70
+ setLabel() {
71
+ const contentSlotNodes = Array.from(this.host.querySelectorAll('[slot="content"]'));
72
+ const textContent = contentSlotNodes
73
+ .map((node) => node.textContent)
74
+ .join(' ')
75
+ .trim();
76
+ this.label = textContent || this.content;
77
+ this.target.setAttribute('aria-label', this.label);
78
+ }
80
79
  handleOpenChange() {
81
80
  this.open ? this.show() : this.hide();
82
81
  }
@@ -141,10 +140,7 @@ export class Tooltip {
141
140
  this.target = this.getTarget();
142
141
  this.popover = new Popover(this.target, this.tooltipPositioner);
143
142
  this.syncOptions();
144
- const ele = this.defaultContent;
145
- ele.slot = 'content';
146
- this.host.appendChild(ele);
147
- this.handleTTSlotChange();
143
+ this.setLabel();
148
144
  // Show on init if open
149
145
  this.tooltipPositioner.hidden = !this.open;
150
146
  if (this.open) {
@@ -161,7 +157,7 @@ export class Tooltip {
161
157
  return (h(Host, { onKeyDown: this.handleKeyDown, onMouseOver: this.handleMouseOver, onMouseOut: this.handleMouseOut, onBlur: this.handleBlur, onFocus: this.handleFocus, onClick: this.handleClick }, h("slot", { onSlotchange: this.handleSlotChange }), h("div", { ref: (el) => (this.tooltipPositioner = el), class: "tooltip-positioner" }, h("div", { part: "base", ref: (el) => (this.tooltip = el), class: {
162
158
  tooltip: true,
163
159
  'tooltip--open': this.open,
164
- }, role: "tooltip", "aria-hidden": this.open ? 'false' : 'true' }, h("slot", { name: "content", onSlotchange: this.handleTTSlotChange }, h("div", { ref: (el) => (this.defaultContent = el), id: this.componentId }, this.content)), h("div", { class: "tooltip-arrow", "data-popper-arrow": true })))));
160
+ }, role: "tooltip", "aria-hidden": this.open ? 'false' : 'true' }, h("slot", { name: "content", onSlotchange: () => this.setLabel() }, this.content), h("div", { class: "tooltip-arrow", "data-popper-arrow": true })))));
165
161
  }
166
162
  static get is() { return "nano-tooltip"; }
167
163
  static get encapsulation() { return "shadow"; }
@@ -441,6 +437,9 @@ export class Tooltip {
441
437
  static get elementRef() { return "host"; }
442
438
  static get watchers() {
443
439
  return [{
440
+ "propName": "content",
441
+ "methodName": "setLabel"
442
+ }, {
444
443
  "propName": "open",
445
444
  "methodName": "handleOpenChange"
446
445
  }];
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.js","sourceRoot":"","sources":["../../../src/components/tooltip/tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n Watch,\n h,\n} from '@stencil/core';\nimport Popover from '../../utils/popover';\n\nlet id = 0;\n\n/**\n * Tooltips display additional information based on a specific action.\n * @slot - The tooltip's target element. Only the first element will be used as the target.\n * @slot content - The tooltip's content. Alternatively, you can use the content prop.\n */\n@Component({\n tag: 'nano-tooltip',\n styleUrl: 'tooltip.scss',\n shadow: true,\n})\nexport class Tooltip {\n private componentId = `tooltip-${++id}`;\n private isVisible = false;\n private popover: Popover;\n private tooltipPositioner: HTMLElement;\n private tooltip: any;\n private defaultContent: HTMLElement;\n\n private _target: HTMLElement;\n private get target() {\n return this._target;\n }\n private set target(newTarget) {\n if (newTarget !== this._target && this._target) {\n this._target.removeAttribute('aria-describedby');\n }\n newTarget.setAttribute('aria-describedby', this.componentId);\n this._target = newTarget;\n }\n\n @Element() host: HTMLNanoTooltipElement;\n\n /** The tooltip's content. Alternatively, you can use the content slot. */\n @Prop() content = '';\n\n /**\n * The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip\n * inside of the viewport.\n */\n @Prop() placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'top';\n\n /** Set to true to disable the tooltip so it won't show when triggered. */\n @Prop() disabled = false;\n\n /** The distance in pixels from which to offset the tooltip away from its target. */\n @Prop() distance = 10;\n\n /** Indicates whether or not the tooltip is open. You can use this in lieu of the show/hide methods. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /** The distance in pixels from which to offset the tooltip along its target. */\n @Prop() skidding = 0;\n\n /**\n * Enable this option to prevent the panel from being clipped when the component is placed inside a container with\n * `overflow: auto|scroll`.\n */\n @Prop() hoist = false;\n\n /**\n * Controls how the tooltip is activated. Possible options include `click`, `hover`, `focus`, and `manual`. Multiple\n * options can be passed by separating them with a space. When manual is used, the tooltip must be activated\n * programmatically.\n */\n @Prop() trigger: string = 'hover focus';\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n // Events\n\n /** Emitted when the tooltip begins to show. Calling `event.preventDefault()` will prevent it from being shown. */\n @Event() nanoShow: EventEmitter;\n\n /** Emitted after the tooltip has shown and all transitions are complete. */\n @Event() nanoAfterShow: EventEmitter;\n\n /** Emitted when the tooltip begins to hide. Calling `event.preventDefault()` will prevent it from being hidden. */\n @Event() nanoHide: EventEmitter;\n\n /** Emitted after the tooltip has hidden and all transitions are complete. */\n @Event() nanoAfterHide: EventEmitter;\n\n // Public methods\n\n /** Shows the tooltip. */\n @Method()\n async show() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (this.isVisible || this.disabled) {\n return;\n }\n const slShow = this.nanoShow.emit();\n if (slShow.defaultPrevented) {\n this.open = false;\n return;\n }\n\n this.isVisible = true;\n this.open = true;\n this.popover.show();\n }\n\n /** Hides the tooltip. */\n @Method()\n async hide() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (!this.isVisible) {\n return;\n }\n\n const slHide = this.nanoHide.emit();\n if (slHide.defaultPrevented) {\n this.open = true;\n return;\n }\n\n this.isVisible = false;\n this.open = false;\n this.popover.hide();\n }\n\n // Private methods\n\n private getTarget() {\n // Get the first child that isn't a <style> or content slot\n const target = [...Array.from(this.host.children)].find(\n (el) =>\n el.tagName.toLowerCase() !== 'style' &&\n el.getAttribute('slot') !== 'content'\n ) as HTMLElement;\n\n if (!target) {\n throw new Error('Invalid tooltip target: no child element was found.');\n }\n\n return target;\n }\n\n private hasTrigger(triggerType: string) {\n const triggers = this.trigger.split(' ');\n return triggers.includes(triggerType);\n }\n\n private syncOptions() {\n this.popover.setOptions({\n strategy: this.hoist ? 'fixed' : 'absolute',\n placement: this.placement,\n distance: this.distance,\n skidding: this.skidding,\n transitionElement: this.tooltip,\n onAfterHide: () => this.nanoAfterHide.emit(),\n onAfterShow: () => this.nanoAfterShow.emit(),\n });\n }\n\n // Event Handlers\n\n private handleBlur = () => {\n if (this.hasTrigger('focus')) {\n this.hide();\n }\n };\n\n private handleClick = () => {\n if (this.hasTrigger('click')) {\n this.open ? this.hide() : this.show();\n }\n };\n\n private handleFocus = () => {\n if (this.hasTrigger('focus')) {\n this.show();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Pressing escape when the target element has focus should dismiss the tooltip\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n }\n };\n\n private handleMouseOver = () => {\n if (this.hasTrigger('hover')) {\n this.show();\n }\n };\n\n private handleMouseOut = () => {\n if (this.hasTrigger('hover')) {\n this.hide();\n }\n };\n\n private handleSlotChange = () => {\n this.target = this.getTarget();\n };\n\n private handleTTSlotChange = () => {\n const contentDiv =\n this.host.querySelector(`[id=\"${this.componentId}\"]`) ||\n this.defaultContent;\n\n Array.from(this.host.querySelectorAll('[slot=\"content\"]'))\n .filter((elm) => elm !== contentDiv)\n .forEach((elm) => {\n contentDiv.appendChild(elm);\n });\n };\n\n // Stencil hooks\n\n componentDidLoad() {\n this.target = this.getTarget();\n this.popover = new Popover(this.target, this.tooltipPositioner);\n this.syncOptions();\n\n const ele = this.defaultContent;\n ele.slot = 'content';\n this.host.appendChild(ele);\n this.handleTTSlotChange();\n\n // Show on init if open\n this.tooltipPositioner.hidden = !this.open;\n if (this.open) {\n this.show();\n }\n }\n\n componentDidUpdate() {\n this.syncOptions();\n }\n\n disconnectedCallback() {\n this.popover.destroy();\n }\n\n render() {\n return (\n <Host\n onKeyDown={this.handleKeyDown}\n onMouseOver={this.handleMouseOver}\n onMouseOut={this.handleMouseOut}\n onBlur={this.handleBlur}\n onFocus={this.handleFocus}\n onClick={this.handleClick}\n >\n <slot onSlotchange={this.handleSlotChange} />\n <div\n ref={(el) => (this.tooltipPositioner = el)}\n class=\"tooltip-positioner\"\n >\n <div\n part=\"base\"\n ref={(el) => (this.tooltip = el)}\n class={{\n tooltip: true,\n 'tooltip--open': this.open,\n }}\n role=\"tooltip\"\n aria-hidden={this.open ? 'false' : 'true'}\n >\n <slot name=\"content\" onSlotchange={this.handleTTSlotChange}>\n <div\n ref={(el) => (this.defaultContent = el)}\n id={this.componentId}\n >\n {this.content}\n </div>\n </slot>\n <div class=\"tooltip-arrow\" data-popper-arrow></div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"]}
1
+ {"version":3,"file":"tooltip.js","sourceRoot":"","sources":["../../../src/components/tooltip/tooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n Host,\n Method,\n Prop,\n Watch,\n h,\n} from '@stencil/core';\nimport Popover from '../../utils/popover';\n\n/**\n * Tooltips display additional information based on a specific action.\n * @slot - The tooltip's target element. Only the first element will be used as the target.\n * @slot content - The tooltip's content. Alternatively, you can use the content prop.\n */\n@Component({\n tag: 'nano-tooltip',\n styleUrl: 'tooltip.scss',\n shadow: true,\n})\nexport class Tooltip {\n private isVisible = false;\n private popover: Popover;\n private tooltipPositioner: HTMLElement;\n private tooltip: any;\n\n private _target: HTMLElement;\n private get target() {\n return this._target;\n }\n private set target(newTarget) {\n if (newTarget !== this._target && this._target) {\n this._target.removeAttribute('aria-label');\n }\n newTarget.setAttribute('aria-label', this.label);\n this._target = newTarget;\n }\n\n private label = '';\n\n @Element() host: HTMLNanoTooltipElement;\n\n /** The tooltip's content. Alternatively, you can use the content slot. */\n @Prop() content = '';\n\n @Watch('content')\n setLabel() {\n const contentSlotNodes = Array.from(\n this.host.querySelectorAll('[slot=\"content\"]')\n );\n const textContent = contentSlotNodes\n .map((node) => node.textContent)\n .join(' ')\n .trim();\n\n this.label = textContent || this.content;\n this.target.setAttribute('aria-label', this.label);\n }\n\n /**\n * The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip\n * inside of the viewport.\n */\n @Prop() placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'right'\n | 'right-start'\n | 'right-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'left-start'\n | 'left-end' = 'top';\n\n /** Set to true to disable the tooltip so it won't show when triggered. */\n @Prop() disabled = false;\n\n /** The distance in pixels from which to offset the tooltip away from its target. */\n @Prop() distance = 10;\n\n /** Indicates whether or not the tooltip is open. You can use this in lieu of the show/hide methods. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n /** The distance in pixels from which to offset the tooltip along its target. */\n @Prop() skidding = 0;\n\n /**\n * Enable this option to prevent the panel from being clipped when the component is placed inside a container with\n * `overflow: auto|scroll`.\n */\n @Prop() hoist = false;\n\n /**\n * Controls how the tooltip is activated. Possible options include `click`, `hover`, `focus`, and `manual`. Multiple\n * options can be passed by separating them with a space. When manual is used, the tooltip must be activated\n * programmatically.\n */\n @Prop() trigger: string = 'hover focus';\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n // Events\n\n /** Emitted when the tooltip begins to show. Calling `event.preventDefault()` will prevent it from being shown. */\n @Event() nanoShow: EventEmitter;\n\n /** Emitted after the tooltip has shown and all transitions are complete. */\n @Event() nanoAfterShow: EventEmitter;\n\n /** Emitted when the tooltip begins to hide. Calling `event.preventDefault()` will prevent it from being hidden. */\n @Event() nanoHide: EventEmitter;\n\n /** Emitted after the tooltip has hidden and all transitions are complete. */\n @Event() nanoAfterHide: EventEmitter;\n\n // Public methods\n\n /** Shows the tooltip. */\n @Method()\n async show() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (this.isVisible || this.disabled) {\n return;\n }\n const slShow = this.nanoShow.emit();\n if (slShow.defaultPrevented) {\n this.open = false;\n return;\n }\n\n this.isVisible = true;\n this.open = true;\n this.popover.show();\n }\n\n /** Hides the tooltip. */\n @Method()\n async hide() {\n // Prevent subsequent calls to the method, whether manually or triggered by the `open` watcher\n if (!this.isVisible) {\n return;\n }\n\n const slHide = this.nanoHide.emit();\n if (slHide.defaultPrevented) {\n this.open = true;\n return;\n }\n\n this.isVisible = false;\n this.open = false;\n this.popover.hide();\n }\n\n // Private methods\n\n private getTarget() {\n // Get the first child that isn't a <style> or content slot\n const target = [...Array.from(this.host.children)].find(\n (el) =>\n el.tagName.toLowerCase() !== 'style' &&\n el.getAttribute('slot') !== 'content'\n ) as HTMLElement;\n\n if (!target) {\n throw new Error('Invalid tooltip target: no child element was found.');\n }\n\n return target;\n }\n\n private hasTrigger(triggerType: string) {\n const triggers = this.trigger.split(' ');\n return triggers.includes(triggerType);\n }\n\n private syncOptions() {\n this.popover.setOptions({\n strategy: this.hoist ? 'fixed' : 'absolute',\n placement: this.placement,\n distance: this.distance,\n skidding: this.skidding,\n transitionElement: this.tooltip,\n onAfterHide: () => this.nanoAfterHide.emit(),\n onAfterShow: () => this.nanoAfterShow.emit(),\n });\n }\n\n // Event Handlers\n\n private handleBlur = () => {\n if (this.hasTrigger('focus')) {\n this.hide();\n }\n };\n\n private handleClick = () => {\n if (this.hasTrigger('click')) {\n this.open ? this.hide() : this.show();\n }\n };\n\n private handleFocus = () => {\n if (this.hasTrigger('focus')) {\n this.show();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n // Pressing escape when the target element has focus should dismiss the tooltip\n if (this.open && event.key === 'Escape') {\n event.stopPropagation();\n this.hide();\n }\n };\n\n private handleMouseOver = () => {\n if (this.hasTrigger('hover')) {\n this.show();\n }\n };\n\n private handleMouseOut = () => {\n if (this.hasTrigger('hover')) {\n this.hide();\n }\n };\n\n private handleSlotChange = () => {\n this.target = this.getTarget();\n };\n\n // Stencil hooks\n\n componentDidLoad() {\n this.target = this.getTarget();\n this.popover = new Popover(this.target, this.tooltipPositioner);\n this.syncOptions();\n this.setLabel();\n\n // Show on init if open\n this.tooltipPositioner.hidden = !this.open;\n if (this.open) {\n this.show();\n }\n }\n\n componentDidUpdate() {\n this.syncOptions();\n }\n\n disconnectedCallback() {\n this.popover.destroy();\n }\n\n render() {\n return (\n <Host\n onKeyDown={this.handleKeyDown}\n onMouseOver={this.handleMouseOver}\n onMouseOut={this.handleMouseOut}\n onBlur={this.handleBlur}\n onFocus={this.handleFocus}\n onClick={this.handleClick}\n >\n <slot onSlotchange={this.handleSlotChange} />\n <div\n ref={(el) => (this.tooltipPositioner = el)}\n class=\"tooltip-positioner\"\n >\n <div\n part=\"base\"\n ref={(el) => (this.tooltip = el)}\n class={{\n tooltip: true,\n 'tooltip--open': this.open,\n }}\n role=\"tooltip\"\n aria-hidden={this.open ? 'false' : 'true'}\n >\n <slot name=\"content\" onSlotchange={() => this.setLabel()}>\n {this.content}\n </slot>\n <div class=\"tooltip-arrow\" data-popper-arrow></div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"]}
@@ -30,11 +30,9 @@ export function getTextContent(slot) {
30
30
  const nodes = slot.assignedNodes({ flatten: true });
31
31
  let text = '';
32
32
  [...nodes].map((node) => {
33
- if (node.nodeType === Node.TEXT_NODE) {
34
- text += node.textContent;
35
- }
33
+ text += node.textContent + ' ';
36
34
  });
37
- return text;
35
+ return text.trim();
38
36
  }
39
37
  /**
40
38
  * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named
@@ -1 +1 @@
1
- {"version":3,"file":"slot.js","sourceRoot":"","sources":["../../src/utils/slot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAqB;EAChD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,IAAI,IAAK,IAAoB,CAAC,SAAS,CAAC;KACzC;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;MACpC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;KAC1B;EACH,CAAC,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAqB;EAClD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;MACpC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;KAC1B;EACH,CAAC,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,EAAe,EAAE,IAAa;EACpD,wBAAwB;EACxB,IAAI,IAAI,EAAE;IACR,OAAO,EAAE,CAAC,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;GACtD;EAED,0BAA0B;EAC1B,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IAClD,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;MACtE,OAAO,IAAI,CAAC;KACb;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,MAAM,EAAE,GAAG,IAAmB,CAAC;MAC/B,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;QAC5B,OAAO,IAAI,CAAC;OACb;KACF;IAED,OAAO,KAAK,CAAC;EACf,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Given a slot, this function iterates over all of its assigned elements and text nodes and returns the concatenated\n * HTML as a string. This is useful because we can't use slot.innerHTML as an alternative.\n * @param slot\n * @returns a concatenated string from html and text nodes\n */\nexport function getInnerHTML(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let html = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n html += (node as HTMLElement).outerHTML;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n html += node.textContent;\n }\n });\n\n return html;\n}\n\n/**\n * Given a slot, this function iterates over all of its assigned text nodes and returns the concatenated text as a\n * string. This is useful because we can't use slot.textContent as an alternative.\n * @param slot\n * @returns a concatenated string of text\n */\nexport function getTextContent(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let text = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent;\n }\n });\n\n return text;\n}\n\n/**\n * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named\n * slot, otherwise it will look for a \"default\" slot (e.g. a non-empty text node or an element with no slot attribute).\n * @param el\n * @param name\n * @returns boolean\n */\nexport function hasSlot(el: HTMLElement, name?: string) {\n // Look for a named slot\n if (name) {\n return el.querySelector(`[slot=\"${name}\"]`) !== null;\n }\n\n // Look for a default slot\n return [...Array.from(el.childNodes)].some((node) => {\n if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== '') {\n return true;\n }\n\n if (node.nodeType === node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (!el.hasAttribute('slot')) {\n return true;\n }\n }\n\n return false;\n });\n}\n"]}
1
+ {"version":3,"file":"slot.js","sourceRoot":"","sources":["../../src/utils/slot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAqB;EAChD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,IAAI,IAAK,IAAoB,CAAC,SAAS,CAAC;KACzC;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;MACpC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;KAC1B;EACH,CAAC,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAqB;EAClD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;IACtB,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;EACjC,CAAC,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,EAAe,EAAE,IAAa;EACpD,wBAAwB;EACxB,IAAI,IAAI,EAAE;IACR,OAAO,EAAE,CAAC,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;GACtD;EAED,0BAA0B;EAC1B,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IAClD,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;MACtE,OAAO,IAAI,CAAC;KACb;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,MAAM,EAAE,GAAG,IAAmB,CAAC;MAC/B,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;QAC5B,OAAO,IAAI,CAAC;OACb;KACF;IAED,OAAO,KAAK,CAAC;EACf,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Given a slot, this function iterates over all of its assigned elements and text nodes and returns the concatenated\n * HTML as a string. This is useful because we can't use slot.innerHTML as an alternative.\n * @param slot\n * @returns a concatenated string from html and text nodes\n */\nexport function getInnerHTML(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let html = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n html += (node as HTMLElement).outerHTML;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n html += node.textContent;\n }\n });\n\n return html;\n}\n\n/**\n * Given a slot, this function iterates over all of its assigned text nodes and returns the concatenated text as a\n * string. This is useful because we can't use slot.textContent as an alternative.\n * @param slot\n * @returns a concatenated string of text\n */\nexport function getTextContent(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let text = '';\n\n [...nodes].map((node) => {\n text += node.textContent + ' ';\n });\n\n return text.trim();\n}\n\n/**\n * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named\n * slot, otherwise it will look for a \"default\" slot (e.g. a non-empty text node or an element with no slot attribute).\n * @param el\n * @param name\n * @returns boolean\n */\nexport function hasSlot(el: HTMLElement, name?: string) {\n // Look for a named slot\n if (name) {\n return el.querySelector(`[slot=\"${name}\"]`) !== null;\n }\n\n // Look for a default slot\n return [...Array.from(el.childNodes)].some((node) => {\n if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== '') {\n return true;\n }\n\n if (node.nodeType === node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (!el.hasAttribute('slot')) {\n return true;\n }\n }\n\n return false;\n });\n}\n"]}
@@ -17,11 +17,9 @@ function getTextContent(slot) {
17
17
  const nodes = slot.assignedNodes({ flatten: true });
18
18
  let text = '';
19
19
  [...nodes].map((node) => {
20
- if (node.nodeType === Node.TEXT_NODE) {
21
- text += node.textContent;
22
- }
20
+ text += node.textContent + ' ';
23
21
  });
24
- return text;
22
+ return text.trim();
25
23
  }
26
24
  /**
27
25
  * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named
@@ -1 +1 @@
1
- {"file":"slot.js","mappings":";;;AAAA;;;;;;AAuBA;;;;;;SAMgB,cAAc,CAAC,IAAqB;EAClD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI;IAClB,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;MACpC,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;KAC1B;GACF,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;SAOgB,OAAO,CAAC,EAAe,EAAE,IAAa;;EAEpD,IAAI,IAAI,EAAE;IACR,OAAO,EAAE,CAAC,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;GACtD;;EAGD,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI;IAC9C,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;MACtE,OAAO,IAAI,CAAC;KACb;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,MAAM,EAAE,GAAG,IAAmB,CAAC;MAC/B,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;QAC5B,OAAO,IAAI,CAAC;OACb;KACF;IAED,OAAO,KAAK,CAAC;GACd,CAAC,CAAC;AACL;;;;","names":[],"sources":["./src/utils/slot.ts"],"sourcesContent":["/**\n * Given a slot, this function iterates over all of its assigned elements and text nodes and returns the concatenated\n * HTML as a string. This is useful because we can't use slot.innerHTML as an alternative.\n * @param slot\n * @returns a concatenated string from html and text nodes\n */\nexport function getInnerHTML(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let html = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n html += (node as HTMLElement).outerHTML;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n html += node.textContent;\n }\n });\n\n return html;\n}\n\n/**\n * Given a slot, this function iterates over all of its assigned text nodes and returns the concatenated text as a\n * string. This is useful because we can't use slot.textContent as an alternative.\n * @param slot\n * @returns a concatenated string of text\n */\nexport function getTextContent(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let text = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.TEXT_NODE) {\n text += node.textContent;\n }\n });\n\n return text;\n}\n\n/**\n * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named\n * slot, otherwise it will look for a \"default\" slot (e.g. a non-empty text node or an element with no slot attribute).\n * @param el\n * @param name\n * @returns boolean\n */\nexport function hasSlot(el: HTMLElement, name?: string) {\n // Look for a named slot\n if (name) {\n return el.querySelector(`[slot=\"${name}\"]`) !== null;\n }\n\n // Look for a default slot\n return [...Array.from(el.childNodes)].some((node) => {\n if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== '') {\n return true;\n }\n\n if (node.nodeType === node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (!el.hasAttribute('slot')) {\n return true;\n }\n }\n\n return false;\n });\n}\n"],"version":3}
1
+ {"file":"slot.js","mappings":";;;AAAA;;;;;;AAuBA;;;;;;SAMgB,cAAc,CAAC,IAAqB;EAClD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;EACpD,IAAI,IAAI,GAAG,EAAE,CAAC;EAEd,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI;IAClB,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;GAChC,CAAC,CAAC;EAEH,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED;;;;;;;SAOgB,OAAO,CAAC,EAAe,EAAE,IAAa;;EAEpD,IAAI,IAAI,EAAE;IACR,OAAO,EAAE,CAAC,aAAa,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;GACtD;;EAGD,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI;IAC9C,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;MACtE,OAAO,IAAI,CAAC;KACb;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;MACvC,MAAM,EAAE,GAAG,IAAmB,CAAC;MAC/B,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;QAC5B,OAAO,IAAI,CAAC;OACb;KACF;IAED,OAAO,KAAK,CAAC;GACd,CAAC,CAAC;AACL;;;;","names":[],"sources":["./src/utils/slot.ts"],"sourcesContent":["/**\n * Given a slot, this function iterates over all of its assigned elements and text nodes and returns the concatenated\n * HTML as a string. This is useful because we can't use slot.innerHTML as an alternative.\n * @param slot\n * @returns a concatenated string from html and text nodes\n */\nexport function getInnerHTML(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let html = '';\n\n [...nodes].map((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n html += (node as HTMLElement).outerHTML;\n }\n\n if (node.nodeType === Node.TEXT_NODE) {\n html += node.textContent;\n }\n });\n\n return html;\n}\n\n/**\n * Given a slot, this function iterates over all of its assigned text nodes and returns the concatenated text as a\n * string. This is useful because we can't use slot.textContent as an alternative.\n * @param slot\n * @returns a concatenated string of text\n */\nexport function getTextContent(slot: HTMLSlotElement): string {\n const nodes = slot.assignedNodes({ flatten: true });\n let text = '';\n\n [...nodes].map((node) => {\n text += node.textContent + ' ';\n });\n\n return text.trim();\n}\n\n/**\n * Determines whether an element has a slot. If name is specified, the function will look for a corresponding named\n * slot, otherwise it will look for a \"default\" slot (e.g. a non-empty text node or an element with no slot attribute).\n * @param el\n * @param name\n * @returns boolean\n */\nexport function hasSlot(el: HTMLElement, name?: string) {\n // Look for a named slot\n if (name) {\n return el.querySelector(`[slot=\"${name}\"]`) !== null;\n }\n\n // Look for a default slot\n return [...Array.from(el.childNodes)].some((node) => {\n if (node.nodeType === node.TEXT_NODE && node.textContent.trim() !== '') {\n return true;\n }\n\n if (node.nodeType === node.ELEMENT_NODE) {\n const el = node as HTMLElement;\n if (!el.hasAttribute('slot')) {\n return true;\n }\n }\n\n return false;\n });\n}\n"],"version":3}
@@ -6,7 +6,6 @@ import { P as Popover } from './popover.js';
6
6
 
7
7
  const tooltipCss = ":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}:host{--max-width:20rem;--hide-delay:0s;--hide-duration:0.125s;--hide-timing-function:ease;--show-delay:0.125s;--show-duration:0.125s;--show-timing-function:ease;display:contents}.tooltip{max-inline-size:var(--max-width);border-radius:var(--nano-tooltip-border-radius, var(--nano-border-radius-small, 2px));background-color:black;font-size:var(--nano-fontsize-small, 0.875rem);line-height:1.5;color:white;opacity:0;padding:var(--nano-tooltip-padding, var(--nano-spacing-xsmall, 4px) var(--nano-spacing-small, 8px));transform:translateY(10px) translateZ(0);transform-origin:bottom;transition:opacity, transform var(--hide-duration) var(--hide-timing-function) var(--hide-delay);white-space:normal}.tooltip-arrow{content:\"\";position:absolute;inline-size:0;block-size:0;color:black;transition:0.2s ease transform}.tooltip-positioner{position:absolute;z-index:var(--nano-layer-index-tooltip, 1000)}.tooltip-positioner[data-popper-placement^=top] .tooltip{transform-origin:bottom;transform:translateY(-10px) translateZ(0)}.tooltip-positioner[data-popper-placement^=bottom] .tooltip{transform-origin:top}.tooltip-positioner[data-popper-placement^=left] .tooltip{transform-origin:right}.tooltip-positioner[data-popper-placement^=right] .tooltip{transform-origin:left}.tooltip-positioner.popover-visible .tooltip{opacity:1;transform:none;transition-delay:var(--show-delay);transition-duration:var(--show-duration);transition-timing-function:var(--show-timing-function)}.tooltip-positioner[data-popper-placement^=bottom] .tooltip-arrow{inset-block-end:100%;inset-inline-start:calc(50% - 5px);-webkit-border-after:5px solid;border-block-end:5px solid;-webkit-border-start:5px solid transparent;border-inline-start:5px solid transparent;-webkit-border-end:5px solid transparent;border-inline-end:5px solid transparent}.tooltip-positioner[data-popper-placement=bottom-start] .tooltip-arrow{inset-inline-start:5px}.tooltip-positioner[data-popper-placement=bottom-end] .tooltip-arrow{inset-inline:auto 5px}.tooltip-positioner[data-popper-placement^=top] .tooltip-arrow{inset-block-start:100%;inset-inline-start:calc(50% - 5px);-webkit-border-before:5px solid;border-block-start:5px solid;-webkit-border-start:5px solid transparent;border-inline-start:5px solid transparent;-webkit-border-end:5px solid transparent;border-inline-end:5px solid transparent}.tooltip-positioner[data-popper-placement=top-start] .tooltip-arrow{inset-inline-start:5px}.tooltip-positioner[data-popper-placement=top-end] .tooltip-arrow{inset-inline:auto 5px}.tooltip-positioner[data-popper-placement^=left] .tooltip-arrow{inset-block-start:calc(50% - 5px);inset-inline-start:100%;-webkit-border-start:5px solid;border-inline-start:5px solid;-webkit-border-before:5px solid transparent;border-block-start:5px solid transparent;-webkit-border-after:5px solid transparent;border-block-end:5px solid transparent}.tooltip-positioner[data-popper-placement=left-start] .tooltip-arrow{inset-block-start:5px}.tooltip-positioner[data-popper-placement=left-end] .tooltip-arrow{inset-block:auto 5px}.tooltip-positioner[data-popper-placement^=right] .tooltip-arrow{inset-block-start:calc(50% - 5px);inset-inline-end:100%;-webkit-border-end:5px solid;border-inline-end:5px solid;-webkit-border-before:5px solid transparent;border-block-start:5px solid transparent;-webkit-border-after:5px solid transparent;border-block-end:5px solid transparent}.tooltip-positioner[data-popper-placement=right-start] .tooltip-arrow{inset-block-start:5px}.tooltip-positioner[data-popper-placement=right-end] .tooltip-arrow{inset-block:auto 5px}";
8
8
 
9
- let id = 0;
10
9
  const Tooltip = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
11
10
  constructor() {
12
11
  super();
@@ -16,8 +15,8 @@ const Tooltip = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
16
15
  this.nanoAfterShow = createEvent(this, "nanoAfterShow", 7);
17
16
  this.nanoHide = createEvent(this, "nanoHide", 7);
18
17
  this.nanoAfterHide = createEvent(this, "nanoAfterHide", 7);
19
- this.componentId = `tooltip-${++id}`;
20
18
  this.isVisible = false;
19
+ this.label = '';
21
20
  // Event Handlers
22
21
  this.handleBlur = () => {
23
22
  if (this.hasTrigger('focus')) {
@@ -54,15 +53,6 @@ const Tooltip = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
54
53
  this.handleSlotChange = () => {
55
54
  this.target = this.getTarget();
56
55
  };
57
- this.handleTTSlotChange = () => {
58
- const contentDiv = this.host.querySelector(`[id="${this.componentId}"]`) ||
59
- this.defaultContent;
60
- Array.from(this.host.querySelectorAll('[slot="content"]'))
61
- .filter((elm) => elm !== contentDiv)
62
- .forEach((elm) => {
63
- contentDiv.appendChild(elm);
64
- });
65
- };
66
56
  this.content = '';
67
57
  this.placement = 'top';
68
58
  this.disabled = false;
@@ -77,11 +67,20 @@ const Tooltip = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
77
67
  }
78
68
  set target(newTarget) {
79
69
  if (newTarget !== this._target && this._target) {
80
- this._target.removeAttribute('aria-describedby');
70
+ this._target.removeAttribute('aria-label');
81
71
  }
82
- newTarget.setAttribute('aria-describedby', this.componentId);
72
+ newTarget.setAttribute('aria-label', this.label);
83
73
  this._target = newTarget;
84
74
  }
75
+ setLabel() {
76
+ const contentSlotNodes = Array.from(this.host.querySelectorAll('[slot="content"]'));
77
+ const textContent = contentSlotNodes
78
+ .map((node) => node.textContent)
79
+ .join(' ')
80
+ .trim();
81
+ this.label = textContent || this.content;
82
+ this.target.setAttribute('aria-label', this.label);
83
+ }
85
84
  handleOpenChange() {
86
85
  this.open ? this.show() : this.hide();
87
86
  }
@@ -146,10 +145,7 @@ const Tooltip = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
146
145
  this.target = this.getTarget();
147
146
  this.popover = new Popover(this.target, this.tooltipPositioner);
148
147
  this.syncOptions();
149
- const ele = this.defaultContent;
150
- ele.slot = 'content';
151
- this.host.appendChild(ele);
152
- this.handleTTSlotChange();
148
+ this.setLabel();
153
149
  // Show on init if open
154
150
  this.tooltipPositioner.hidden = !this.open;
155
151
  if (this.open) {
@@ -166,10 +162,11 @@ const Tooltip = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
166
162
  return (h(Host, { onKeyDown: this.handleKeyDown, onMouseOver: this.handleMouseOver, onMouseOut: this.handleMouseOut, onBlur: this.handleBlur, onFocus: this.handleFocus, onClick: this.handleClick }, h("slot", { onSlotchange: this.handleSlotChange }), h("div", { ref: (el) => (this.tooltipPositioner = el), class: "tooltip-positioner" }, h("div", { part: "base", ref: (el) => (this.tooltip = el), class: {
167
163
  tooltip: true,
168
164
  'tooltip--open': this.open,
169
- }, role: "tooltip", "aria-hidden": this.open ? 'false' : 'true' }, h("slot", { name: "content", onSlotchange: this.handleTTSlotChange }, h("div", { ref: (el) => (this.defaultContent = el), id: this.componentId }, this.content)), h("div", { class: "tooltip-arrow", "data-popper-arrow": true })))));
165
+ }, role: "tooltip", "aria-hidden": this.open ? 'false' : 'true' }, h("slot", { name: "content", onSlotchange: () => this.setLabel() }, this.content), h("div", { class: "tooltip-arrow", "data-popper-arrow": true })))));
170
166
  }
171
167
  get host() { return this; }
172
168
  static get watchers() { return {
169
+ "content": ["setLabel"],
173
170
  "open": ["handleOpenChange"]
174
171
  }; }
175
172
  static get style() { return tooltipCss; }