@vaadin/tooltip 23.3.0-alpha1

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.
@@ -0,0 +1,649 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2022 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import './vaadin-tooltip-overlay.js';
7
+ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
8
+ import { addValueToAttribute, removeValueFromAttribute } from '@vaadin/component-base/src/dom-utils.js';
9
+ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
10
+ import { isKeyboardActive } from '@vaadin/component-base/src/focus-utils.js';
11
+ import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
12
+ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
13
+
14
+ const DEFAULT_DELAY = 0;
15
+
16
+ let defaultFocusDelay = DEFAULT_DELAY;
17
+ let defaultHoverDelay = DEFAULT_DELAY;
18
+ let defaultHideDelay = DEFAULT_DELAY;
19
+
20
+ const closing = new Set();
21
+
22
+ let warmedUp = false;
23
+ let warmUpTimeout = null;
24
+ let cooldownTimeout = null;
25
+
26
+ /**
27
+ * `<vaadin-tooltip>` is a Web Component for creating tooltips.
28
+ *
29
+ * ```html
30
+ * <button id="confirm">Confirm</button>
31
+ * <vaadin-tooltip text="Click to save changes" for="confirm"></vaadin-tooltip>
32
+ * ```
33
+ *
34
+ * ### Styling
35
+ *
36
+ * `<vaadin-tooltip>` uses `<vaadin-tooltip-overlay>` internal
37
+ * themable component as the actual visible overlay.
38
+ *
39
+ * See [`<vaadin-overlay>`](#/elements/vaadin-overlay) documentation
40
+ * for `<vaadin-tooltip-overlay>` parts.
41
+ *
42
+ * The following state attributes are available for styling:
43
+ *
44
+ * Attribute | Description
45
+ * -----------------|----------------------------------------
46
+ * `position` | Reflects the `position` property value.
47
+ *
48
+ * Note: the `theme` attribute value set on `<vaadin-tooltip>` is
49
+ * propagated to the internal `<vaadin-tooltip-overlay>` component.
50
+ *
51
+ * ### Custom CSS Properties
52
+ *
53
+ * The following custom CSS properties are available on the `<vaadin-tooltip>` element:
54
+ *
55
+ * Custom CSS property | Description
56
+ * ---------------------------------|-------------
57
+ * `--vaadin-tooltip-offset-top` | Used as an offset when the tooltip is aligned vertically below the target
58
+ * `--vaadin-tooltip-offset-bottom` | Used as an offset when the tooltip is aligned vertically above the target
59
+ * `--vaadin-tooltip-offset-start` | Used as an offset when the tooltip is aligned horizontally after the target
60
+ * `--vaadin-tooltip-offset-end` | Used as an offset when the tooltip is aligned horizontally before the target
61
+ *
62
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
63
+ *
64
+ * @extends HTMLElement
65
+ * @mixes ElementMixin
66
+ * @mixes ThemePropertyMixin
67
+ */
68
+ class Tooltip extends ThemePropertyMixin(ElementMixin(PolymerElement)) {
69
+ static get is() {
70
+ return 'vaadin-tooltip';
71
+ }
72
+
73
+ static get template() {
74
+ return html`
75
+ <style>
76
+ :host {
77
+ display: none;
78
+ }
79
+ </style>
80
+ <vaadin-tooltip-overlay
81
+ id="[[_uniqueId]]"
82
+ role="tooltip"
83
+ renderer="[[_renderer]]"
84
+ theme$="[[_theme]]"
85
+ opened="[[__computeOpened(manual, opened, _autoOpened)]]"
86
+ position-target="[[target]]"
87
+ position="[[position]]"
88
+ no-horizontal-overlap$="[[__computeNoHorizontalOverlap(position)]]"
89
+ no-vertical-overlap$="[[__computeNoVerticalOverlap(position)]]"
90
+ horizontal-align="[[__computeHorizontalAlign(position)]]"
91
+ vertical-align="[[__computeVerticalAlign(position)]]"
92
+ modeless
93
+ ></vaadin-tooltip-overlay>
94
+ `;
95
+ }
96
+
97
+ static get properties() {
98
+ return {
99
+ /**
100
+ * Object with properties passed to `textGenerator`
101
+ * function to be used for generating tooltip text.
102
+ */
103
+ context: {
104
+ type: Object,
105
+ value: () => {
106
+ return {};
107
+ },
108
+ },
109
+
110
+ /**
111
+ * The delay in milliseconds before the tooltip
112
+ * is opened on focus, when not in manual mode.
113
+ * @attr {number} focus-delay
114
+ */
115
+ focusDelay: {
116
+ type: Number,
117
+ },
118
+
119
+ /**
120
+ * The id of the element used as a tooltip trigger.
121
+ * The element should be in the DOM by the time when
122
+ * the attribute is set, otherwise a warning is shown.
123
+ */
124
+ for: {
125
+ type: String,
126
+ observer: '__forChanged',
127
+ },
128
+
129
+ /**
130
+ * The delay in milliseconds before the tooltip
131
+ * is closed on losing hover, when not in manual mode.
132
+ * On blur, the tooltip is closed immediately.
133
+ * @attr {number} hide-delay
134
+ */
135
+ hideDelay: {
136
+ type: Number,
137
+ },
138
+
139
+ /**
140
+ * The delay in milliseconds before the tooltip
141
+ * is opened on hover, when not in manual mode.
142
+ * @attr {number} hover-delay
143
+ */
144
+ hoverDelay: {
145
+ type: Number,
146
+ },
147
+
148
+ /**
149
+ * When true, the tooltip is controlled programmatically
150
+ * instead of reacting to focus and mouse events.
151
+ */
152
+ manual: {
153
+ type: Boolean,
154
+ value: false,
155
+ },
156
+
157
+ /**
158
+ * When true, the tooltip is opened programmatically.
159
+ * Only works if `manual` is set to `true`.
160
+ */
161
+ opened: {
162
+ type: Boolean,
163
+ value: false,
164
+ },
165
+
166
+ /**
167
+ * Position of the tooltip with respect to its target.
168
+ * Supported values: `top-start`, `top`, `top-end`,
169
+ * `bottom-start`, `bottom`, `bottom-end`, `start-top`,
170
+ * `start`, `start-bottom`, `end-top`, `end`, `end-bottom`.
171
+ */
172
+ position: {
173
+ type: String,
174
+ value: 'bottom',
175
+ },
176
+
177
+ /**
178
+ * Function used to detect whether to show the tooltip based on a condition,
179
+ * called every time the tooltip is about to be shown on hover and focus.
180
+ * The function accepts a reference to the target element as a parameter.
181
+ * The tooltip is only shown when the function invocation returns `true`.
182
+ */
183
+ shouldShow: {
184
+ type: Object,
185
+ value: () => {
186
+ return (_target) => true;
187
+ },
188
+ },
189
+
190
+ /**
191
+ * Reference to the element used as a tooltip trigger.
192
+ * The target must be placed in the same shadow scope.
193
+ * Defaults to an element referenced with `for`.
194
+ */
195
+ target: {
196
+ type: Object,
197
+ observer: '__targetChanged',
198
+ },
199
+
200
+ /**
201
+ * String used as a tooltip content.
202
+ */
203
+ text: {
204
+ type: String,
205
+ observer: '__textChanged',
206
+ },
207
+
208
+ /**
209
+ * Function used to generate the tooltip content.
210
+ * When provided, it overrides the `text` property.
211
+ * Use the `context` property to provide argument
212
+ * that can be passed to the generator function.
213
+ */
214
+ textGenerator: {
215
+ type: Object,
216
+ },
217
+
218
+ /**
219
+ * Set to true when the overlay is opened using auto-added
220
+ * event listeners: mouseenter and focusin (keyboard only).
221
+ * @protected
222
+ */
223
+ _autoOpened: {
224
+ type: Boolean,
225
+ observer: '__autoOpenedChanged',
226
+ },
227
+
228
+ /** @protected */
229
+ _overlayElement: Object,
230
+
231
+ /** @private */
232
+ __isTargetHidden: {
233
+ type: Boolean,
234
+ value: false,
235
+ },
236
+ };
237
+ }
238
+
239
+ static get observers() {
240
+ return ['__textGeneratorChanged(_overlayElement, textGenerator, context)'];
241
+ }
242
+
243
+ /**
244
+ * Sets the default focus delay to be used by all tooltip instances,
245
+ * except for those that have focus delay configured using property.
246
+ *
247
+ * @param {number} delay
248
+ */
249
+ static setDefaultFocusDelay(focusDelay) {
250
+ defaultFocusDelay = focusDelay != null && focusDelay >= 0 ? focusDelay : DEFAULT_DELAY;
251
+ }
252
+
253
+ /**
254
+ * Sets the default hide delay to be used by all tooltip instances,
255
+ * except for those that have hide delay configured using property.
256
+ *
257
+ * @param {number} hideDelay
258
+ */
259
+ static setDefaultHideDelay(hideDelay) {
260
+ defaultHideDelay = hideDelay != null && hideDelay >= 0 ? hideDelay : DEFAULT_DELAY;
261
+ }
262
+
263
+ /**
264
+ * Sets the default hover delay to be used by all tooltip instances,
265
+ * except for those that have hover delay configured using property.
266
+ *
267
+ * @param {number} delay
268
+ */
269
+ static setDefaultHoverDelay(hoverDelay) {
270
+ defaultHoverDelay = hoverDelay != null && hoverDelay >= 0 ? hoverDelay : DEFAULT_DELAY;
271
+ }
272
+
273
+ constructor() {
274
+ super();
275
+
276
+ this._uniqueId = `vaadin-tooltip-${generateUniqueId()}`;
277
+ this._renderer = this.__tooltipRenderer.bind(this);
278
+
279
+ this.__onFocusin = this.__onFocusin.bind(this);
280
+ this.__onFocusout = this.__onFocusout.bind(this);
281
+ this.__onMouseDown = this.__onMouseDown.bind(this);
282
+ this.__onMouseEnter = this.__onMouseEnter.bind(this);
283
+ this.__onMouseLeave = this.__onMouseLeave.bind(this);
284
+ this.__onKeyDown = this.__onKeyDown.bind(this);
285
+
286
+ this.__targetVisibilityObserver = new IntersectionObserver(
287
+ ([entry]) => {
288
+ this.__onTargetVisibilityChange(entry.isIntersecting);
289
+ },
290
+ { threshold: 1 },
291
+ );
292
+ }
293
+
294
+ /** @protected */
295
+ ready() {
296
+ super.ready();
297
+
298
+ this._overlayElement = this.shadowRoot.querySelector('vaadin-tooltip-overlay');
299
+ this._overlayElement.owner = this;
300
+ }
301
+
302
+ /** @protected */
303
+ disconnectedCallback() {
304
+ super.disconnectedCallback();
305
+
306
+ if (this._autoOpened) {
307
+ this._close(true);
308
+ }
309
+ }
310
+
311
+ /** @private */
312
+ __computeHorizontalAlign(position) {
313
+ return ['top-end', 'bottom-end', 'start-top', 'start', 'start-bottom'].includes(position) ? 'end' : 'start';
314
+ }
315
+
316
+ /** @private */
317
+ __computeNoHorizontalOverlap(position) {
318
+ return ['start-top', 'start', 'start-bottom', 'end-top', 'end', 'end-bottom'].includes(position);
319
+ }
320
+
321
+ /** @private */
322
+ __computeNoVerticalOverlap(position) {
323
+ return ['top-start', 'top-end', 'top', 'bottom-start', 'bottom', 'bottom-end'].includes(position);
324
+ }
325
+
326
+ /** @private */
327
+ __computeVerticalAlign(position) {
328
+ return ['top-start', 'top-end', 'top', 'start-bottom', 'end-bottom'].includes(position) ? 'bottom' : 'top';
329
+ }
330
+
331
+ /** @private */
332
+ __computeOpened(manual, opened, autoOpened) {
333
+ return manual ? opened : autoOpened;
334
+ }
335
+
336
+ /** @private */
337
+ __tooltipRenderer(root) {
338
+ root.textContent = typeof this.textGenerator === 'function' ? this.textGenerator(this.context) : this.text;
339
+ }
340
+
341
+ /** @private */
342
+ __autoOpenedChanged(opened, oldOpened) {
343
+ if (opened) {
344
+ document.addEventListener('keydown', this.__onKeyDown, true);
345
+ } else if (oldOpened) {
346
+ document.removeEventListener('keydown', this.__onKeyDown, true);
347
+ }
348
+ }
349
+
350
+ /** @private */
351
+ __forChanged(forId) {
352
+ if (forId) {
353
+ const target = this.getRootNode().getElementById(forId);
354
+
355
+ if (target) {
356
+ this.target = target;
357
+ } else {
358
+ console.warn(`No element with id="${forId}" found to show tooltip.`);
359
+ }
360
+ }
361
+ }
362
+
363
+ /** @private */
364
+ __targetChanged(target, oldTarget) {
365
+ if (oldTarget) {
366
+ oldTarget.removeEventListener('mouseenter', this.__onMouseEnter);
367
+ oldTarget.removeEventListener('mouseleave', this.__onMouseLeave);
368
+ oldTarget.removeEventListener('focusin', this.__onFocusin);
369
+ oldTarget.removeEventListener('focusout', this.__onFocusout);
370
+ oldTarget.removeEventListener('mousedown', this.__onMouseDown);
371
+
372
+ this.__targetVisibilityObserver.unobserve(oldTarget);
373
+
374
+ removeValueFromAttribute(oldTarget, 'aria-describedby', this._uniqueId);
375
+ }
376
+
377
+ if (target) {
378
+ target.addEventListener('mouseenter', this.__onMouseEnter);
379
+ target.addEventListener('mouseleave', this.__onMouseLeave);
380
+ target.addEventListener('focusin', this.__onFocusin);
381
+ target.addEventListener('focusout', this.__onFocusout);
382
+ target.addEventListener('mousedown', this.__onMouseDown);
383
+
384
+ this.__targetVisibilityObserver.observe(target);
385
+
386
+ addValueToAttribute(target, 'aria-describedby', this._uniqueId);
387
+ }
388
+ }
389
+
390
+ /** @private */
391
+ __onFocusin(event) {
392
+ // Only open on keyboard focus.
393
+ if (!isKeyboardActive()) {
394
+ return;
395
+ }
396
+
397
+ // Do not re-open while focused if closed on Esc or mousedown.
398
+ if (this.target.contains(event.relatedTarget)) {
399
+ return;
400
+ }
401
+
402
+ if (typeof this.shouldShow === 'function' && this.shouldShow(this.target) !== true) {
403
+ return;
404
+ }
405
+
406
+ this.__focusInside = true;
407
+
408
+ if (!this.__isTargetHidden && (!this.__hoverInside || !this._autoOpened)) {
409
+ this._open({ focus: true });
410
+ }
411
+ }
412
+
413
+ /** @private */
414
+ __onFocusout(event) {
415
+ // Do not close when moving focus within a component.
416
+ if (this.target.contains(event.relatedTarget)) {
417
+ return;
418
+ }
419
+
420
+ this.__focusInside = false;
421
+
422
+ if (!this.__hoverInside) {
423
+ this._close(true);
424
+ }
425
+ }
426
+
427
+ /** @private */
428
+ __onKeyDown(event) {
429
+ if (event.key === 'Escape') {
430
+ event.stopPropagation();
431
+ this._close(true);
432
+ }
433
+ }
434
+
435
+ /** @private */
436
+ __onMouseDown() {
437
+ this._close(true);
438
+ }
439
+
440
+ /** @private */
441
+ __onMouseEnter() {
442
+ if (typeof this.shouldShow === 'function' && this.shouldShow(this.target) !== true) {
443
+ return;
444
+ }
445
+
446
+ if (this.__hoverInside) {
447
+ // Already hovering inside the element, do nothing.
448
+ return;
449
+ }
450
+
451
+ this.__hoverInside = true;
452
+
453
+ if (!this.__isTargetHidden && (!this.__focusInside || !this._autoOpened)) {
454
+ this._open({ hover: true });
455
+ }
456
+ }
457
+
458
+ /** @private */
459
+ __onMouseLeave() {
460
+ this.__hoverInside = false;
461
+
462
+ if (!this.__focusInside) {
463
+ this._close();
464
+ }
465
+ }
466
+
467
+ /** @private */
468
+ __onTargetVisibilityChange(isVisible) {
469
+ const oldHidden = this.__isTargetHidden;
470
+ this.__isTargetHidden = !isVisible;
471
+
472
+ // Open the overlay when the target becomes visible and has focus or hover.
473
+ if (oldHidden && isVisible && (this.__focusInside || this.__hoverInside)) {
474
+ this._open(true);
475
+ return;
476
+ }
477
+
478
+ // Close the overlay when the target is no longer fully visible.
479
+ if (!isVisible && this._autoOpened) {
480
+ this._close(true);
481
+ }
482
+ }
483
+
484
+ /**
485
+ * Schedule opening the tooltip.
486
+ * @param {boolean} immediate
487
+ * @protected
488
+ */
489
+ _open(options = { immediate: false }) {
490
+ const { immediate, hover, focus } = options;
491
+ const isHover = hover && this.__getHoverDelay() > 0;
492
+ const isFocus = focus && this.__getFocusDelay() > 0;
493
+
494
+ if (!immediate && (isHover || isFocus) && !this.__closeTimeout) {
495
+ this.__warmupTooltip(isFocus);
496
+ } else {
497
+ this.__showTooltip();
498
+ }
499
+ }
500
+
501
+ /**
502
+ * Schedule closing the tooltip.
503
+ * @param {boolean} immediate
504
+ * @protected
505
+ */
506
+ _close(immediate) {
507
+ if (!immediate && this.__getHideDelay() > 0) {
508
+ this.__scheduleClose();
509
+ } else {
510
+ this.__abortClose();
511
+ this._autoOpened = false;
512
+ }
513
+
514
+ this.__abortWarmUp();
515
+
516
+ if (warmedUp) {
517
+ // Re-start cooldown timer on each tooltip closing.
518
+ this.__abortCooldown();
519
+ this.__scheduleCooldown();
520
+ }
521
+ }
522
+
523
+ /** @private */
524
+ __getFocusDelay() {
525
+ return this.focusDelay != null && this.focusDelay > 0 ? this.focusDelay : defaultFocusDelay;
526
+ }
527
+
528
+ /** @private */
529
+ __getHoverDelay() {
530
+ return this.hoverDelay != null && this.hoverDelay > 0 ? this.hoverDelay : defaultHoverDelay;
531
+ }
532
+
533
+ /** @private */
534
+ __getHideDelay() {
535
+ return this.hideDelay != null && this.hideDelay > 0 ? this.hideDelay : defaultHideDelay;
536
+ }
537
+
538
+ /** @private */
539
+ __flushClosingTooltips() {
540
+ closing.forEach((tooltip) => {
541
+ tooltip._close(true);
542
+ closing.delete(tooltip);
543
+ });
544
+ }
545
+
546
+ /** @private */
547
+ __showTooltip() {
548
+ this.__abortClose();
549
+ this.__flushClosingTooltips();
550
+
551
+ this._autoOpened = true;
552
+ warmedUp = true;
553
+
554
+ // Abort previously scheduled timers.
555
+ this.__abortWarmUp();
556
+ this.__abortCooldown();
557
+ }
558
+
559
+ /** @private */
560
+ __warmupTooltip(isFocus) {
561
+ if (!this._autoOpened) {
562
+ // First tooltip is opened, warm up.
563
+ if (!warmedUp) {
564
+ this.__scheduleWarmUp(isFocus);
565
+ } else {
566
+ // Warmed up, show another tooltip.
567
+ this.__showTooltip();
568
+ }
569
+ }
570
+ }
571
+
572
+ /** @private */
573
+ __abortClose() {
574
+ if (this.__closeTimeout) {
575
+ clearTimeout(this.__closeTimeout);
576
+ this.__closeTimeout = null;
577
+ }
578
+ }
579
+
580
+ /** @private */
581
+ __abortCooldown() {
582
+ if (cooldownTimeout) {
583
+ clearTimeout(cooldownTimeout);
584
+ cooldownTimeout = null;
585
+ }
586
+ }
587
+
588
+ /** @private */
589
+ __abortWarmUp() {
590
+ if (warmUpTimeout) {
591
+ clearTimeout(warmUpTimeout);
592
+ warmUpTimeout = null;
593
+ }
594
+ }
595
+
596
+ /** @private */
597
+ __scheduleClose() {
598
+ if (this._autoOpened) {
599
+ closing.add(this);
600
+
601
+ this.__closeTimeout = setTimeout(() => {
602
+ closing.delete(this);
603
+ this.__closeTimeout = null;
604
+ this._autoOpened = false;
605
+ }, this.__getHideDelay());
606
+ }
607
+ }
608
+
609
+ /** @private */
610
+ __scheduleCooldown() {
611
+ cooldownTimeout = setTimeout(() => {
612
+ cooldownTimeout = null;
613
+ warmedUp = false;
614
+ }, this.__getHideDelay());
615
+ }
616
+
617
+ /** @private */
618
+ __scheduleWarmUp(isFocus) {
619
+ const delay = isFocus ? this.__getFocusDelay() : this.__getHoverDelay();
620
+ warmUpTimeout = setTimeout(() => {
621
+ warmUpTimeout = null;
622
+ warmedUp = true;
623
+ this.__showTooltip();
624
+ }, delay);
625
+ }
626
+
627
+ /** @private */
628
+ __textChanged(text, oldText) {
629
+ if (this._overlayElement && (text || oldText)) {
630
+ this._overlayElement.requestContentUpdate();
631
+ }
632
+ }
633
+
634
+ /** @private */
635
+ __textGeneratorChanged(overlayElement, textGenerator, context) {
636
+ if (overlayElement) {
637
+ if (textGenerator !== this.__oldTextGenerator || context !== this.__oldContext) {
638
+ overlayElement.requestContentUpdate();
639
+ }
640
+
641
+ this.__oldTextGenerator = textGenerator;
642
+ this.__oldContext = context;
643
+ }
644
+ }
645
+ }
646
+
647
+ customElements.define(Tooltip.is, Tooltip);
648
+
649
+ export { Tooltip };
@@ -0,0 +1,25 @@
1
+ import '@vaadin/vaadin-lumo-styles/color.js';
2
+ import '@vaadin/vaadin-lumo-styles/style.js';
3
+ import { overlay } from '@vaadin/vaadin-lumo-styles/mixins/overlay.js';
4
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
5
+
6
+ const tooltipOverlay = css`
7
+ :host {
8
+ --vaadin-tooltip-offset-top: var(--lumo-space-xs);
9
+ --vaadin-tooltip-offset-bottom: var(--lumo-space-xs);
10
+ --vaadin-tooltip-offset-start: var(--lumo-space-xs);
11
+ --vaadin-tooltip-offset-end: var(--lumo-space-xs);
12
+ }
13
+
14
+ [part='overlay'] {
15
+ background-color: var(--lumo-contrast);
16
+ color: var(--lumo-primary-contrast-color);
17
+ font-size: var(--lumo-font-size-xs);
18
+ }
19
+
20
+ [part='content'] {
21
+ padding: var(--lumo-space-xs) var(--lumo-space-s);
22
+ }
23
+ `;
24
+
25
+ registerStyles('vaadin-tooltip-overlay', [overlay, tooltipOverlay], { moduleId: 'lumo-tooltip-overlay' });
@@ -0,0 +1,3 @@
1
+ import '@vaadin/vaadin-overlay/theme/lumo/vaadin-overlay.js';
2
+ import './vaadin-tooltip-styles.js';
3
+ import '../../src/vaadin-tooltip.js';
@@ -0,0 +1,23 @@
1
+ import { overlay } from '@vaadin/vaadin-material-styles/mixins/overlay.js';
2
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
3
+
4
+ const tooltipOverlay = css`
5
+ :host {
6
+ --vaadin-tooltip-offset-top: 0.25rem;
7
+ --vaadin-tooltip-offset-bottom: 0.25rem;
8
+ --vaadin-tooltip-offset-start: 0.25rem;
9
+ --vaadin-tooltip-offset-end: 0.25rem;
10
+ }
11
+
12
+ [part='overlay'] {
13
+ background-color: rgba(97, 97, 97, 0.92);
14
+ color: #fff;
15
+ font-size: 0.6875rem;
16
+ }
17
+
18
+ [part='content'] {
19
+ padding: 0.25rem 0.5rem;
20
+ }
21
+ `;
22
+
23
+ registerStyles('vaadin-tooltip-overlay', [overlay, tooltipOverlay], { moduleId: 'material-tooltip-overlay' });
@@ -0,0 +1,3 @@
1
+ import '@vaadin/vaadin-overlay/theme/material/vaadin-overlay.js';
2
+ import './vaadin-tooltip-styles.js';
3
+ import '../../src/vaadin-tooltip.js';
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-tooltip.js';
@@ -0,0 +1,3 @@
1
+ import './theme/lumo/vaadin-tooltip.js';
2
+
3
+ export * from './src/vaadin-tooltip.js';