@vaadin/popover 24.5.0-alpha1 → 24.5.0-alpha11

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.
@@ -4,18 +4,30 @@
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import './vaadin-popover-overlay.js';
7
- import { html, LitElement } from 'lit';
7
+ import { css, html, LitElement } from 'lit';
8
8
  import { ifDefined } from 'lit/directives/if-defined.js';
9
- import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
9
+ import {
10
+ getDeepActiveElement,
11
+ getFocusableElements,
12
+ isElementFocused,
13
+ isKeyboardActive,
14
+ } from '@vaadin/a11y-base/src/focus-utils.js';
10
15
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
11
16
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
12
17
  import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
13
18
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
14
19
  import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
20
+ import { isLastOverlay } from '@vaadin/overlay/src/vaadin-overlay-stack-mixin.js';
15
21
  import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
16
22
  import { PopoverPositionMixin } from './vaadin-popover-position-mixin.js';
17
23
  import { PopoverTargetMixin } from './vaadin-popover-target-mixin.js';
18
24
 
25
+ const DEFAULT_DELAY = 500;
26
+
27
+ let defaultFocusDelay = DEFAULT_DELAY;
28
+ let defaultHoverDelay = DEFAULT_DELAY;
29
+ let defaultHideDelay = DEFAULT_DELAY;
30
+
19
31
  /**
20
32
  * Controller for handling popover opened state.
21
33
  */
@@ -34,17 +46,20 @@ class PopoverOpenedStateController {
34
46
 
35
47
  /** @private */
36
48
  get __focusDelay() {
37
- return this.host.focusDelay || 0;
49
+ const popover = this.host;
50
+ return popover.focusDelay != null && popover.focusDelay >= 0 ? popover.focusDelay : defaultFocusDelay;
38
51
  }
39
52
 
40
53
  /** @private */
41
54
  get __hoverDelay() {
42
- return this.host.hoverDelay || 0;
55
+ const popover = this.host;
56
+ return popover.hoverDelay != null && popover.hoverDelay >= 0 ? popover.hoverDelay : defaultHoverDelay;
43
57
  }
44
58
 
45
59
  /** @private */
46
60
  get __hideDelay() {
47
- return this.host.hideDelay || 0;
61
+ const popover = this.host;
62
+ return popover.hideDelay != null && popover.hideDelay >= 0 ? popover.hideDelay : defaultHideDelay;
48
63
  }
49
64
 
50
65
  /**
@@ -130,12 +145,49 @@ class PopoverOpenedStateController {
130
145
  * Unlike `<vaadin-tooltip>`, the popover supports rich content
131
146
  * that can be provided by using `renderer` function.
132
147
  *
148
+ * ### Styling
149
+ *
150
+ * `<vaadin-popover>` uses `<vaadin-popover-overlay>` internal
151
+ * themable component as the actual visible overlay.
152
+ *
153
+ * See [`<vaadin-overlay>`](#/elements/vaadin-overlay) documentation
154
+ * for `<vaadin-popover-overlay>` parts.
155
+ *
156
+ * In addition to `<vaadin-overlay>` parts, the following parts are available for styling:
157
+ *
158
+ * Part name | Description
159
+ * -----------------|-------------------------------------------
160
+ * `arrow` | Optional arrow pointing to the target when using `theme="arrow"`
161
+ *
162
+ * The following state attributes are available for styling:
163
+ *
164
+ * Attribute | Description
165
+ * -----------------|----------------------------------------
166
+ * `position` | Reflects the `position` property value.
167
+ *
168
+ * Note: the `theme` attribute value set on `<vaadin-popover>` is
169
+ * propagated to the internal `<vaadin-popover-overlay>` component.
170
+ *
171
+ * ### Custom CSS Properties
172
+ *
173
+ * The following custom CSS properties are available on the `<vaadin-popover>` element:
174
+ *
175
+ * Custom CSS property | Description
176
+ * ---------------------------------|-------------
177
+ * `--vaadin-popover-offset-top` | Used as an offset when the popover is aligned vertically below the target
178
+ * `--vaadin-popover-offset-bottom` | Used as an offset when the popover is aligned vertically above the target
179
+ * `--vaadin-popover-offset-start` | Used as an offset when the popover is aligned horizontally after the target
180
+ * `--vaadin-popover-offset-end` | Used as an offset when the popover is aligned horizontally before the target
181
+ *
182
+ * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
183
+ *
133
184
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
185
+ * @fires {CustomEvent} closed - Fired when the popover is closed.
134
186
  *
135
187
  * @customElement
136
188
  * @extends HTMLElement
137
189
  * @mixes ElementMixin
138
- * @mixes ElementMixin
190
+ * @mixes OverlayClassMixin
139
191
  * @mixes PopoverPositionMixin
140
192
  * @mixes PopoverTargetMixin
141
193
  * @mixes ThemePropertyMixin
@@ -147,6 +199,14 @@ class Popover extends PopoverPositionMixin(
147
199
  return 'vaadin-popover';
148
200
  }
149
201
 
202
+ static get styles() {
203
+ return css`
204
+ :host {
205
+ display: none !important;
206
+ }
207
+ `;
208
+ }
209
+
150
210
  static get properties() {
151
211
  return {
152
212
  /**
@@ -167,6 +227,14 @@ class Popover extends PopoverPositionMixin(
167
227
  type: String,
168
228
  },
169
229
 
230
+ /**
231
+ * When true, the popover content automatically receives focus after
232
+ * it is opened. Modal popovers use this behavior by default.
233
+ */
234
+ autofocus: {
235
+ type: Boolean,
236
+ },
237
+
170
238
  /**
171
239
  * Height to be set on the overlay content.
172
240
  *
@@ -188,6 +256,9 @@ class Popover extends PopoverPositionMixin(
188
256
  /**
189
257
  * The delay in milliseconds before the popover is opened
190
258
  * on focus when the corresponding trigger is used.
259
+ *
260
+ * When not specified, the global default (500ms) is used.
261
+ *
191
262
  * @attr {number} focus-delay
192
263
  */
193
264
  focusDelay: {
@@ -198,6 +269,9 @@ class Popover extends PopoverPositionMixin(
198
269
  * The delay in milliseconds before the popover is closed
199
270
  * on losing hover, when the corresponding trigger is used.
200
271
  * On blur, the popover is closed immediately.
272
+ *
273
+ * When not specified, the global default (500ms) is used.
274
+ *
201
275
  * @attr {number} hide-delay
202
276
  */
203
277
  hideDelay: {
@@ -207,6 +281,9 @@ class Popover extends PopoverPositionMixin(
207
281
  /**
208
282
  * The delay in milliseconds before the popover is opened
209
283
  * on hover when the corresponding trigger is used.
284
+ *
285
+ * When not specified, the global default (500ms) is used.
286
+ *
210
287
  * @attr {number} hover-delay
211
288
  */
212
289
  hoverDelay: {
@@ -334,6 +411,36 @@ class Popover extends PopoverPositionMixin(
334
411
  ];
335
412
  }
336
413
 
414
+ /**
415
+ * Sets the default focus delay to be used by all popover instances,
416
+ * except for those that have focus delay configured using property.
417
+ *
418
+ * @param {number} delay
419
+ */
420
+ static setDefaultFocusDelay(focusDelay) {
421
+ defaultFocusDelay = focusDelay != null && focusDelay >= 0 ? focusDelay : DEFAULT_DELAY;
422
+ }
423
+
424
+ /**
425
+ * Sets the default hide delay to be used by all popover instances,
426
+ * except for those that have hide delay configured using property.
427
+ *
428
+ * @param {number} hideDelay
429
+ */
430
+ static setDefaultHideDelay(hideDelay) {
431
+ defaultHideDelay = hideDelay != null && hideDelay >= 0 ? hideDelay : DEFAULT_DELAY;
432
+ }
433
+
434
+ /**
435
+ * Sets the default hover delay to be used by all popover instances,
436
+ * except for those that have hover delay configured using property.
437
+ *
438
+ * @param {number} delay
439
+ */
440
+ static setDefaultHoverDelay(hoverDelay) {
441
+ defaultHoverDelay = hoverDelay != null && hoverDelay >= 0 ? hoverDelay : DEFAULT_DELAY;
442
+ }
443
+
337
444
  constructor() {
338
445
  super();
339
446
 
@@ -342,7 +449,6 @@ class Popover extends PopoverPositionMixin(
342
449
  this.__onGlobalClick = this.__onGlobalClick.bind(this);
343
450
  this.__onGlobalKeyDown = this.__onGlobalKeyDown.bind(this);
344
451
  this.__onTargetClick = this.__onTargetClick.bind(this);
345
- this.__onTargetKeydown = this.__onTargetKeydown.bind(this);
346
452
  this.__onTargetFocusIn = this.__onTargetFocusIn.bind(this);
347
453
  this.__onTargetFocusOut = this.__onTargetFocusOut.bind(this);
348
454
  this.__onTargetMouseEnter = this.__onTargetMouseEnter.bind(this);
@@ -374,6 +480,7 @@ class Popover extends PopoverPositionMixin(
374
480
  ?no-vertical-overlap="${this.__computeNoVerticalOverlap(effectivePosition)}"
375
481
  .horizontalAlign="${this.__computeHorizontalAlign(effectivePosition)}"
376
482
  .verticalAlign="${this.__computeVerticalAlign(effectivePosition)}"
483
+ @mousedown="${this.__onOverlayMouseDown}"
377
484
  @mouseenter="${this.__onOverlayMouseEnter}"
378
485
  @mouseleave="${this.__onOverlayMouseLeave}"
379
486
  @focusin="${this.__onOverlayFocusIn}"
@@ -383,6 +490,7 @@ class Popover extends PopoverPositionMixin(
383
490
  .restoreFocusNode="${this.target}"
384
491
  @vaadin-overlay-escape-press="${this.__onEscapePress}"
385
492
  @vaadin-overlay-outside-click="${this.__onOutsideClick}"
493
+ @vaadin-overlay-open="${this.__onOverlayOpened}"
386
494
  @vaadin-overlay-closed="${this.__onOverlayClosed}"
387
495
  ></vaadin-popover-overlay>
388
496
  `;
@@ -413,14 +521,14 @@ class Popover extends PopoverPositionMixin(
413
521
  connectedCallback() {
414
522
  super.connectedCallback();
415
523
 
416
- document.addEventListener('click', this.__onGlobalClick, true);
524
+ document.documentElement.addEventListener('click', this.__onGlobalClick, true);
417
525
  }
418
526
 
419
527
  /** @protected */
420
528
  disconnectedCallback() {
421
529
  super.disconnectedCallback();
422
530
 
423
- document.removeEventListener('click', this.__onGlobalClick, true);
531
+ document.documentElement.removeEventListener('click', this.__onGlobalClick, true);
424
532
 
425
533
  this._openedStateController.close(true);
426
534
  }
@@ -432,7 +540,6 @@ class Popover extends PopoverPositionMixin(
432
540
  */
433
541
  _addTargetListeners(target) {
434
542
  target.addEventListener('click', this.__onTargetClick);
435
- target.addEventListener('keydown', this.__onTargetKeydown);
436
543
  target.addEventListener('mouseenter', this.__onTargetMouseEnter);
437
544
  target.addEventListener('mouseleave', this.__onTargetMouseLeave);
438
545
  target.addEventListener('focusin', this.__onTargetFocusIn);
@@ -446,7 +553,6 @@ class Popover extends PopoverPositionMixin(
446
553
  */
447
554
  _removeTargetListeners(target) {
448
555
  target.removeEventListener('click', this.__onTargetClick);
449
- target.removeEventListener('keydown', this.__onTargetKeydown);
450
556
  target.removeEventListener('mouseenter', this.__onTargetMouseEnter);
451
557
  target.removeEventListener('mouseleave', this.__onTargetMouseLeave);
452
558
  target.removeEventListener('focusin', this.__onTargetFocusIn);
@@ -500,7 +606,8 @@ class Popover extends PopoverPositionMixin(
500
606
  !this.__isManual &&
501
607
  !this.modal &&
502
608
  !event.composedPath().some((el) => el === this._overlayElement || el === this.target) &&
503
- !this.noCloseOnOutsideClick
609
+ !this.noCloseOnOutsideClick &&
610
+ isLastOverlay(this._overlayElement)
504
611
  ) {
505
612
  this._openedStateController.close(true);
506
613
  }
@@ -526,19 +633,104 @@ class Popover extends PopoverPositionMixin(
526
633
  * @private
527
634
  */
528
635
  __onGlobalKeyDown(event) {
529
- if (event.key === 'Escape' && !this.modal && !this.noCloseOnEsc && this.opened && !this.__isManual) {
636
+ // Modal popover uses overlay logic for Esc key and focus trap.
637
+ if (this.modal) {
638
+ return;
639
+ }
640
+
641
+ if (
642
+ event.key === 'Escape' &&
643
+ !this.noCloseOnEsc &&
644
+ this.opened &&
645
+ !this.__isManual &&
646
+ isLastOverlay(this._overlayElement)
647
+ ) {
530
648
  // Prevent closing parent overlay (e.g. dialog)
531
649
  event.stopPropagation();
532
650
  this._openedStateController.close(true);
533
651
  }
652
+
653
+ // Include popover content in the Tab order after the target.
654
+ if (event.key === 'Tab') {
655
+ if (event.shiftKey) {
656
+ this.__onGlobalShiftTab(event);
657
+ } else {
658
+ this.__onGlobalTab(event);
659
+ }
660
+ }
534
661
  }
535
662
 
536
663
  /** @private */
537
- __onTargetKeydown(event) {
538
- // Prevent restoring focus after target blur on Tab key
539
- if (event.key === 'Tab' && this.__shouldRestoreFocus) {
664
+ __onGlobalTab(event) {
665
+ const overlayPart = this._overlayElement.$.overlay;
666
+
667
+ // Move focus to the popover content on target element Tab
668
+ if (this.target && isElementFocused(this.target)) {
669
+ event.preventDefault();
670
+ overlayPart.focus();
671
+ return;
672
+ }
673
+
674
+ // Move focus to the next element after target on content Tab
675
+ const lastFocusable = this.__getLastFocusable(overlayPart);
676
+ if (lastFocusable && isElementFocused(lastFocusable)) {
677
+ const focusable = this.__getNextBodyFocusable(this.target);
678
+ if (focusable && focusable !== overlayPart) {
679
+ event.preventDefault();
680
+ focusable.focus();
681
+ return;
682
+ }
683
+ }
684
+
685
+ // Prevent focusing the popover content on previous element Tab
686
+ const activeElement = getDeepActiveElement();
687
+ const nextFocusable = this.__getNextBodyFocusable(activeElement);
688
+ if (nextFocusable === overlayPart && lastFocusable) {
689
+ // Move focus to the last overlay focusable and do NOT prevent keydown
690
+ // to move focus outside the popover content (e.g. to the URL bar).
691
+ lastFocusable.focus();
692
+ }
693
+ }
694
+
695
+ /** @private */
696
+ __onGlobalShiftTab(event) {
697
+ const overlayPart = this._overlayElement.$.overlay;
698
+
699
+ // Prevent restoring focus after target blur on Shift + Tab
700
+ if (this.target && isElementFocused(this.target) && this.__shouldRestoreFocus) {
540
701
  this.__shouldRestoreFocus = false;
702
+ return;
541
703
  }
704
+
705
+ // Move focus back to the target on overlay content Shift + Tab
706
+ if (this.target && isElementFocused(overlayPart)) {
707
+ event.preventDefault();
708
+ this.target.focus();
709
+ return;
710
+ }
711
+
712
+ // Move focus back to the popover on next element Shift + Tab
713
+ const nextFocusable = this.__getNextBodyFocusable(this.target);
714
+ if (nextFocusable && isElementFocused(nextFocusable)) {
715
+ const lastFocusable = this.__getLastFocusable(overlayPart);
716
+ if (lastFocusable) {
717
+ event.preventDefault();
718
+ lastFocusable.focus();
719
+ }
720
+ }
721
+ }
722
+
723
+ /** @private */
724
+ __getNextBodyFocusable(target) {
725
+ const focusables = getFocusableElements(document.body);
726
+ const idx = focusables.findIndex((el) => el === target);
727
+ return focusables[idx + 1];
728
+ }
729
+
730
+ /** @private */
731
+ __getLastFocusable(container) {
732
+ const focusables = getFocusableElements(container);
733
+ return focusables.pop();
542
734
  }
543
735
 
544
736
  /** @private */
@@ -563,7 +755,14 @@ class Popover extends PopoverPositionMixin(
563
755
 
564
756
  /** @private */
565
757
  __onTargetFocusOut(event) {
566
- if (this._overlayElement.contains(event.relatedTarget)) {
758
+ // Do not close the popover on overlay focusout if it's not the last one.
759
+ // This covers the case when focus moves to the nested popover opened
760
+ // without focusing parent popover overlay (e.g. using hover trigger).
761
+ if (!isLastOverlay(this._overlayElement)) {
762
+ return;
763
+ }
764
+
765
+ if ((this.__hasTrigger('focus') && this.__mouseDownInside) || this._overlayElement.contains(event.relatedTarget)) {
567
766
  return;
568
767
  }
569
768
 
@@ -585,6 +784,12 @@ class Popover extends PopoverPositionMixin(
585
784
 
586
785
  /** @private */
587
786
  __onTargetMouseLeave(event) {
787
+ // Do not close the popover on target focusout if the overlay is not the last one.
788
+ // This happens e.g. when opening the nested popover that uses non-modal overlay.
789
+ if (!isLastOverlay(this._overlayElement)) {
790
+ return;
791
+ }
792
+
588
793
  if (this._overlayElement.contains(event.relatedTarget)) {
589
794
  return;
590
795
  }
@@ -605,13 +810,40 @@ class Popover extends PopoverPositionMixin(
605
810
 
606
811
  /** @private */
607
812
  __onOverlayFocusOut(event) {
608
- if (event.relatedTarget === this.target || this._overlayElement.contains(event.relatedTarget)) {
813
+ // Do not close the popover on overlay focusout if it's not the last one.
814
+ // This covers the following cases of nested overlay based components:
815
+ // 1. Moving focus to the nested overlay (e.g. vaadin-select, vaadin-menu-bar)
816
+ // 2. Closing not focused nested overlay on outside (e.g. vaadin-combo-box)
817
+ if (!isLastOverlay(this._overlayElement)) {
818
+ return;
819
+ }
820
+
821
+ if (
822
+ (this.__hasTrigger('focus') && this.__mouseDownInside) ||
823
+ event.relatedTarget === this.target ||
824
+ this._overlayElement.contains(event.relatedTarget)
825
+ ) {
609
826
  return;
610
827
  }
611
828
 
612
829
  this.__handleFocusout();
613
830
  }
614
831
 
832
+ /** @private */
833
+ __onOverlayMouseDown() {
834
+ if (this.__hasTrigger('focus')) {
835
+ this.__mouseDownInside = true;
836
+
837
+ document.addEventListener(
838
+ 'mouseup',
839
+ () => {
840
+ this.__mouseDownInside = false;
841
+ },
842
+ { once: true },
843
+ );
844
+ }
845
+ }
846
+
615
847
  /** @private */
616
848
  __onOverlayMouseEnter() {
617
849
  this.__hoverInside = true;
@@ -624,6 +856,13 @@ class Popover extends PopoverPositionMixin(
624
856
 
625
857
  /** @private */
626
858
  __onOverlayMouseLeave(event) {
859
+ // Do not close the popover on overlay focusout if it's not the last one.
860
+ // This happens when opening the nested component that uses "modal" overlay
861
+ // setting `pointer-events: none` on the body (combo-box, date-picker etc).
862
+ if (!isLastOverlay(this._overlayElement)) {
863
+ return;
864
+ }
865
+
627
866
  if (event.relatedTarget === this.target) {
628
867
  return;
629
868
  }
@@ -662,6 +901,13 @@ class Popover extends PopoverPositionMixin(
662
901
  this.opened = event.detail.value;
663
902
  }
664
903
 
904
+ /** @private */
905
+ __onOverlayOpened() {
906
+ if (this.autofocus && !this.modal) {
907
+ this._overlayElement.$.overlay.focus();
908
+ }
909
+ }
910
+
665
911
  /** @private */
666
912
  __onOverlayClosed() {
667
913
  // Reset restoring focus state after a timeout to make sure focus was restored
@@ -676,6 +922,8 @@ class Popover extends PopoverPositionMixin(
676
922
  if (this.modal && this.target.style.pointerEvents) {
677
923
  this.target.style.pointerEvents = '';
678
924
  }
925
+
926
+ this.dispatchEvent(new CustomEvent('closed'));
679
927
  }
680
928
 
681
929
  /**
@@ -732,6 +980,12 @@ class Popover extends PopoverPositionMixin(
732
980
  this.__updateDimension(overlay, 'width', width);
733
981
  }
734
982
  }
983
+
984
+ /**
985
+ * Fired when the popover is closed.
986
+ *
987
+ * @event closed
988
+ */
735
989
  }
736
990
 
737
991
  defineCustomElement(Popover);
@@ -1,3 +1,4 @@
1
1
  import '@vaadin/vaadin-lumo-styles/color.js';
2
+ import '@vaadin/vaadin-lumo-styles/spacing.js';
2
3
  import '@vaadin/vaadin-lumo-styles/style.js';
3
4
  import '@vaadin/vaadin-lumo-styles/typography.js';
@@ -1,4 +1,5 @@
1
1
  import '@vaadin/vaadin-lumo-styles/color.js';
2
+ import '@vaadin/vaadin-lumo-styles/spacing.js';
2
3
  import '@vaadin/vaadin-lumo-styles/style.js';
3
4
  import '@vaadin/vaadin-lumo-styles/typography.js';
4
5
  import { overlay } from '@vaadin/vaadin-lumo-styles/mixins/overlay.js';
@@ -6,15 +7,105 @@ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themab
6
7
 
7
8
  const popoverOverlay = css`
8
9
  :host {
9
- --vaadin-popover-offset-top: var(--lumo-space-xs);
10
- --vaadin-popover-offset-bottom: var(--lumo-space-xs);
11
- --vaadin-popover-offset-start: var(--lumo-space-xs);
12
- --vaadin-popover-offset-end: var(--lumo-space-xs);
10
+ --vaadin-popover-offset-top: var(--_vaadin-popover-default-offset);
11
+ --vaadin-popover-offset-bottom: var(--_vaadin-popover-default-offset);
12
+ --vaadin-popover-offset-start: var(--_vaadin-popover-default-offset);
13
+ --vaadin-popover-offset-end: var(--_vaadin-popover-default-offset);
14
+ --vaadin-popover-arrow-size: 0.5rem;
15
+ --_vaadin-popover-default-offset: var(--lumo-space-xs);
16
+ }
17
+
18
+ [part='overlay'] {
19
+ outline: none;
13
20
  }
14
21
 
15
22
  [part='content'] {
16
23
  padding: var(--lumo-space-xs) var(--lumo-space-s);
17
24
  }
25
+
26
+ :host([theme~='no-padding']) [part='content'] {
27
+ padding: 0;
28
+ }
29
+
30
+ :host([theme~='arrow']) {
31
+ --_vaadin-popover-default-offset: calc(var(--lumo-space-s) + var(--vaadin-popover-arrow-size) / 2);
32
+ }
33
+
34
+ /* top / bottom position */
35
+ :host([theme~='arrow'][position^='top']) [part='arrow'],
36
+ :host([theme~='arrow'][position^='bottom']) [part='arrow'] {
37
+ border-left: var(--vaadin-popover-arrow-size) solid transparent;
38
+ border-right: var(--vaadin-popover-arrow-size) solid transparent;
39
+ }
40
+
41
+ :host([theme~='arrow'][position^='bottom'][bottom-aligned]) [part='arrow'],
42
+ :host([theme~='arrow'][position^='top'][bottom-aligned]) [part='arrow'] {
43
+ bottom: calc(var(--vaadin-popover-arrow-size) * -1);
44
+ border-top: var(--vaadin-popover-arrow-size) solid var(--lumo-base-color);
45
+ filter: drop-shadow(0 2px 1px var(--lumo-shade-10pct));
46
+ }
47
+
48
+ :host([theme~='arrow'][position^='bottom'][top-aligned]) [part='arrow'],
49
+ :host([theme~='arrow'][position^='top'][top-aligned]) [part='arrow'] {
50
+ top: calc(var(--vaadin-popover-arrow-size) * -1);
51
+ border-bottom: var(--vaadin-popover-arrow-size) solid var(--lumo-base-color);
52
+ filter: drop-shadow(0 -2px 1px var(--lumo-shade-10pct));
53
+ }
54
+
55
+ :host([theme~='arrow'][position^='bottom'][start-aligned]) [part='arrow'],
56
+ :host([theme~='arrow'][position^='top'][start-aligned]) [part='arrow'] {
57
+ transform: translateX(-50%);
58
+ inset-inline-start: 1.5rem;
59
+ }
60
+
61
+ :host([theme~='arrow'][position^='bottom'][end-aligned]) [part='arrow'],
62
+ :host([theme~='arrow'][position^='top'][end-aligned]) [part='arrow'] {
63
+ transform: translateX(50%);
64
+ inset-inline-end: 1.5rem;
65
+ }
66
+
67
+ :host([theme~='arrow'][position^='bottom'][arrow-centered]) [part='arrow'],
68
+ :host([theme~='arrow'][position^='top'][arrow-centered]) [part='arrow'] {
69
+ transform: translateX(-50%);
70
+ inset-inline-start: 50%;
71
+ }
72
+
73
+ /* start / end position */
74
+ :host([theme~='arrow'][position^='start']) [part='arrow'],
75
+ :host([theme~='arrow'][position^='end']) [part='arrow'] {
76
+ border-top: var(--vaadin-popover-arrow-size) solid transparent;
77
+ border-bottom: var(--vaadin-popover-arrow-size) solid transparent;
78
+ }
79
+
80
+ :host([theme~='arrow'][position^='start'][start-aligned]) [part='arrow'],
81
+ :host([theme~='arrow'][position^='end'][start-aligned]) [part='arrow'] {
82
+ inset-inline-start: calc(var(--vaadin-popover-arrow-size) * -1);
83
+ border-right: var(--vaadin-popover-arrow-size) solid var(--lumo-base-color);
84
+ filter: drop-shadow(-2px 0 1px var(--lumo-shade-10pct));
85
+ }
86
+
87
+ :host([theme~='arrow'][position^='start'][end-aligned]) [part='arrow'],
88
+ :host([theme~='arrow'][position^='end'][end-aligned]) [part='arrow'] {
89
+ inset-inline-end: calc(var(--vaadin-popover-arrow-size) * -1);
90
+ border-left: var(--vaadin-popover-arrow-size) solid var(--lumo-base-color);
91
+ filter: drop-shadow(2px 0 1px var(--lumo-shade-10pct));
92
+ }
93
+
94
+ :host([theme~='arrow'][position^='start'][top-aligned]) [part='arrow'],
95
+ :host([theme~='arrow'][position^='end'][top-aligned]) [part='arrow'] {
96
+ top: 0.5rem;
97
+ }
98
+
99
+ :host([theme~='arrow'][position='start'][top-aligned]) [part='arrow'],
100
+ :host([theme~='arrow'][position='end'][top-aligned]) [part='arrow'] {
101
+ top: 50%;
102
+ transform: translateY(-50%);
103
+ }
104
+
105
+ :host([theme~='arrow'][position^='start'][bottom-aligned]) [part='arrow'],
106
+ :host([theme~='arrow'][position^='end'][bottom-aligned]) [part='arrow'] {
107
+ bottom: 0.5rem;
108
+ }
18
109
  `;
19
110
 
20
111
  registerStyles('vaadin-popover-overlay', [overlay, popoverOverlay], { moduleId: 'lumo-popover-overlay' });
@@ -1 +1 @@
1
- export {};
1
+ import '@vaadin/vaadin-material-styles/color.js';