@vaadin/popover 24.8.4 → 25.0.0-alpha10
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.
- package/README.md +0 -23
- package/package.json +13 -12
- package/src/styles/vaadin-popover-overlay-base-styles.d.ts +8 -0
- package/src/styles/vaadin-popover-overlay-base-styles.js +210 -0
- package/src/styles/vaadin-popover-overlay-core-styles.d.ts +8 -0
- package/src/styles/vaadin-popover-overlay-core-styles.js +74 -0
- package/src/vaadin-popover-overlay-mixin.js +0 -52
- package/src/vaadin-popover-overlay.js +39 -71
- package/src/vaadin-popover.d.ts +12 -20
- package/src/vaadin-popover.js +83 -65
- package/theme/lumo/vaadin-popover-styles.js +3 -7
- package/web-types.json +36 -14
- package/web-types.lit.json +15 -8
- package/theme/material/vaadin-popover-styles.d.ts +0 -1
- package/theme/material/vaadin-popover-styles.js +0 -108
- package/theme/material/vaadin-popover.d.ts +0 -2
- package/theme/material/vaadin-popover.js +0 -2
package/README.md
CHANGED
|
@@ -20,29 +20,6 @@ Once installed, import the component in your application:
|
|
|
20
20
|
import '@vaadin/popover';
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
## Themes
|
|
24
|
-
|
|
25
|
-
Vaadin components come with two built-in [themes](https://vaadin.com/docs/latest/styling), Lumo and Material.
|
|
26
|
-
The [main entrypoint](https://github.com/vaadin/web-components/blob/main/packages/popover/vaadin-popover.js) of the package uses Lumo theme.
|
|
27
|
-
|
|
28
|
-
To use the Material theme, import the component from the `theme/material` folder:
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
import '@vaadin/popover/theme/material/vaadin-popover.js';
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
You can also import the Lumo version of the component explicitly:
|
|
35
|
-
|
|
36
|
-
```js
|
|
37
|
-
import '@vaadin/popover/theme/lumo/vaadin-popover.js';
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Finally, you can import the un-themed component from the `src` folder to get a minimal starting point:
|
|
41
|
-
|
|
42
|
-
```js
|
|
43
|
-
import '@vaadin/popover/src/vaadin-popover.js';
|
|
44
|
-
```
|
|
45
|
-
|
|
46
23
|
## Contributing
|
|
47
24
|
|
|
48
25
|
Read the [contributing guide](https://vaadin.com/docs/latest/contributing) to learn about our development process, how to propose bugfixes and improvements, and how to test your changes to Vaadin components.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/popover",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "25.0.0-alpha10",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"lit.d.ts",
|
|
24
24
|
"lit.js",
|
|
25
25
|
"src",
|
|
26
|
+
"!src/styles/*-base-styles.d.ts",
|
|
27
|
+
"!src/styles/*-base-styles.js",
|
|
26
28
|
"theme",
|
|
27
29
|
"vaadin-*.d.ts",
|
|
28
30
|
"vaadin-*.js",
|
|
@@ -37,24 +39,23 @@
|
|
|
37
39
|
],
|
|
38
40
|
"dependencies": {
|
|
39
41
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
40
|
-
"@vaadin/a11y-base": "
|
|
41
|
-
"@vaadin/component-base": "
|
|
42
|
-
"@vaadin/lit-renderer": "
|
|
43
|
-
"@vaadin/overlay": "
|
|
44
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
45
|
-
"@vaadin/vaadin-
|
|
46
|
-
"@vaadin/vaadin-themable-mixin": "~24.8.4",
|
|
42
|
+
"@vaadin/a11y-base": "25.0.0-alpha10",
|
|
43
|
+
"@vaadin/component-base": "25.0.0-alpha10",
|
|
44
|
+
"@vaadin/lit-renderer": "25.0.0-alpha10",
|
|
45
|
+
"@vaadin/overlay": "25.0.0-alpha10",
|
|
46
|
+
"@vaadin/vaadin-lumo-styles": "25.0.0-alpha10",
|
|
47
|
+
"@vaadin/vaadin-themable-mixin": "25.0.0-alpha10",
|
|
47
48
|
"lit": "^3.0.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@vaadin/chai-plugins": "
|
|
51
|
-
"@vaadin/test-runner-commands": "
|
|
52
|
-
"@vaadin/testing-helpers": "^
|
|
51
|
+
"@vaadin/chai-plugins": "25.0.0-alpha10",
|
|
52
|
+
"@vaadin/test-runner-commands": "25.0.0-alpha10",
|
|
53
|
+
"@vaadin/testing-helpers": "^2.0.0",
|
|
53
54
|
"sinon": "^18.0.0"
|
|
54
55
|
},
|
|
55
56
|
"web-types": [
|
|
56
57
|
"web-types.json",
|
|
57
58
|
"web-types.lit.json"
|
|
58
59
|
],
|
|
59
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "6cc6c94079e805fa5b2f0af4dbf3b2a7485e57d0"
|
|
60
61
|
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2024 - 2025 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { css } from 'lit';
|
|
7
|
+
import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-base-styles.js';
|
|
8
|
+
|
|
9
|
+
const popoverOverlay = css`
|
|
10
|
+
:host {
|
|
11
|
+
--_arrow-size: var(--vaadin-popover-arrow-size, 8px);
|
|
12
|
+
--_default-offset: 4px;
|
|
13
|
+
--_rtl-multiplier: 1;
|
|
14
|
+
--_border-width: var(--vaadin-popover-border-width, var(--vaadin-overlay-border-width, 1px));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
[part='overlay']:focus-visible {
|
|
18
|
+
outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:host([dir='rtl']) {
|
|
22
|
+
--_rtl-multiplier: -1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:host([modeless][with-backdrop]) [part='backdrop'] {
|
|
26
|
+
pointer-events: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:host([position^='top'][top-aligned]) [part='overlay'],
|
|
30
|
+
:host([position^='bottom'][top-aligned]) [part='overlay'] {
|
|
31
|
+
margin-top: var(--vaadin-popover-offset-top, var(--_default-offset));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
[part='overlay'] {
|
|
35
|
+
position: relative;
|
|
36
|
+
overflow: visible;
|
|
37
|
+
max-height: 100%;
|
|
38
|
+
border: var(--_border-width) solid
|
|
39
|
+
var(--vaadin-popover-border-color, var(--vaadin-overlay-border-color, var(--vaadin-border-color)));
|
|
40
|
+
background: var(--vaadin-popover-background, var(--vaadin-overlay-background, var(--vaadin-background-color)));
|
|
41
|
+
box-shadow: var(--vaadin-popover-box-shadow, var(--vaadin-overlay-box-shadow, 0 8px 24px -4px rgba(0, 0, 0, 0.3)));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[part='content'] {
|
|
45
|
+
overflow: auto;
|
|
46
|
+
overscroll-behavior: contain;
|
|
47
|
+
box-sizing: border-box;
|
|
48
|
+
max-height: 100%;
|
|
49
|
+
padding: var(--vaadin-popover-padding, var(--vaadin-padding));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:host([theme~='no-padding']) [part='content'] {
|
|
53
|
+
padding: 0 !important;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Increase the area of the popover so the pointer can go from the target directly to it. */
|
|
57
|
+
[part='overlay']::before {
|
|
58
|
+
position: absolute;
|
|
59
|
+
content: '';
|
|
60
|
+
inset-block: calc(var(--vaadin-popover-offset-top, var(--_default-offset)) * -1)
|
|
61
|
+
calc(var(--vaadin-popover-offset-bottom, var(--_default-offset)) * -1);
|
|
62
|
+
inset-inline: calc(var(--vaadin-popover-offset-start, var(--_default-offset)) * -1)
|
|
63
|
+
calc(var(--vaadin-popover-offset-end, var(--_default-offset)) * -1);
|
|
64
|
+
z-index: -1;
|
|
65
|
+
pointer-events: auto;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
:host([position^='top'][bottom-aligned]) [part='overlay'],
|
|
69
|
+
:host([position^='bottom'][bottom-aligned]) [part='overlay'] {
|
|
70
|
+
margin-bottom: var(--vaadin-popover-offset-bottom, var(--_default-offset));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
:host([position^='start'][start-aligned]) [part='overlay'],
|
|
74
|
+
:host([position^='end'][start-aligned]) [part='overlay'] {
|
|
75
|
+
margin-inline-start: var(--vaadin-popover-offset-start, var(--_default-offset));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:host([position^='start'][end-aligned]) [part='overlay'],
|
|
79
|
+
:host([position^='end'][end-aligned]) [part='overlay'] {
|
|
80
|
+
margin-inline-end: var(--vaadin-popover-offset-end, var(--_default-offset));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
[part='arrow'] {
|
|
84
|
+
display: none;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:host([theme~='arrow']) {
|
|
88
|
+
--_default-offset: calc(4px + var(--_arrow-size) / 2);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:host([theme~='arrow']) [part='arrow'] {
|
|
92
|
+
display: block;
|
|
93
|
+
position: absolute;
|
|
94
|
+
background: inherit;
|
|
95
|
+
border: inherit;
|
|
96
|
+
border-start-start-radius: var(--vaadin-popover-arrow-border-radius, 0);
|
|
97
|
+
outline: inherit;
|
|
98
|
+
box-shadow: inherit;
|
|
99
|
+
width: var(--_arrow-size);
|
|
100
|
+
height: var(--_arrow-size);
|
|
101
|
+
rotate: 45deg;
|
|
102
|
+
--o: 20px; /* clip-path outset, how far outward it extends to reveal the outline and box shadow */
|
|
103
|
+
--b: var(--_border-width);
|
|
104
|
+
/* We need this elaborate clip-path to allow the arrow bg and border to cover
|
|
105
|
+
the overlay border but prevent the outline and box-shadow from covering it */
|
|
106
|
+
clip-path: polygon(
|
|
107
|
+
calc(var(--o) * -1) calc(var(--o) * -1),
|
|
108
|
+
calc(100% + var(--o) - var(--b)) calc(var(--o) * -1),
|
|
109
|
+
calc(100% - var(--b) * 1.4) 0,
|
|
110
|
+
100% 0,
|
|
111
|
+
calc(100% - var(--b)) var(--b),
|
|
112
|
+
calc(100% - var(--b)) calc(var(--b) + var(--ff, 0px)),
|
|
113
|
+
calc(var(--b) + var(--ff, 0px)) calc(100% - var(--b)),
|
|
114
|
+
calc(var(--b)) calc(100% - var(--b)),
|
|
115
|
+
0 100%,
|
|
116
|
+
0 calc(100% - var(--b) * 1.4),
|
|
117
|
+
calc(var(--o) * -1) calc(100% + var(--o) - var(--b))
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* Firefox renders a blurry edge for a diagonal clip-path + rotation,
|
|
122
|
+
so we need to extend the clip-path slightly further on the diagonal */
|
|
123
|
+
@supports (-moz-appearance: none) {
|
|
124
|
+
:host([theme~='arrow']) [part='arrow'] {
|
|
125
|
+
--ff: 1px;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* bottom / top */
|
|
130
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[start-aligned]) [part='arrow'] {
|
|
131
|
+
inset-inline-start: calc(var(--_arrow-size) * 2);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[end-aligned]) [part='arrow'] {
|
|
135
|
+
inset-inline-end: calc(var(--_arrow-size) * 2);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[arrow-centered]) [part='arrow'] {
|
|
139
|
+
inset-inline-start: 50%;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* bottom */
|
|
143
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[top-aligned]) [part='arrow'] {
|
|
144
|
+
top: 0;
|
|
145
|
+
translate: calc(-50% * var(--_rtl-multiplier)) -50%;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[end-aligned][top-aligned]) [part='arrow'] {
|
|
149
|
+
translate: calc(50% * var(--_rtl-multiplier)) -50%;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* top */
|
|
153
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[bottom-aligned]) [part='arrow'] {
|
|
154
|
+
bottom: 0;
|
|
155
|
+
rotate: 225deg;
|
|
156
|
+
translate: calc(-50% * var(--_rtl-multiplier)) 50%;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
:host([theme~='arrow']:is([position^='bottom'], [position^='top'])[end-aligned][bottom-aligned]) [part='arrow'] {
|
|
160
|
+
translate: calc(50% * var(--_rtl-multiplier)) 50%;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* start / end */
|
|
164
|
+
:host([theme~='arrow']:is([position^='start'], [position^='end'])[top-aligned]) [part='arrow'] {
|
|
165
|
+
rotate: -45deg;
|
|
166
|
+
top: calc(var(--_arrow-size) * 2);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
:host([theme~='arrow']:is([position^='start'], [position^='end'])[bottom-aligned]) [part='arrow'] {
|
|
170
|
+
rotate: -45deg;
|
|
171
|
+
bottom: calc(var(--_arrow-size) * 2);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
:host([theme~='arrow']:is([position='start'], [position='end'])[top-aligned]) [part='arrow'] {
|
|
175
|
+
top: 50%;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
:host([dir='rtl'][theme~='arrow']:is([position^='start'], [position^='end'])) [part='arrow'] {
|
|
179
|
+
scale: -1;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* end */
|
|
183
|
+
:host([theme~='arrow']:is([position^='start'], [position^='end'])[start-aligned]) [part='arrow'] {
|
|
184
|
+
inset-inline-start: 0;
|
|
185
|
+
translate: calc(-50% * var(--_rtl-multiplier)) -50%;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
:host([theme~='arrow']:is([position^='start'], [position^='end'])[start-aligned][bottom-aligned]) [part='arrow'] {
|
|
189
|
+
translate: calc(-50% * var(--_rtl-multiplier)) 50%;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* start */
|
|
193
|
+
:host([theme~='arrow']:is([position^='start'], [position^='end'])[end-aligned]) [part='arrow'] {
|
|
194
|
+
rotate: 135deg;
|
|
195
|
+
inset-inline-end: 0;
|
|
196
|
+
translate: calc(50% * var(--_rtl-multiplier)) -50%;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
:host([theme~='arrow']:is([position^='start'], [position^='end'])[end-aligned][bottom-aligned]) [part='arrow'] {
|
|
200
|
+
translate: calc(50% * var(--_rtl-multiplier)) 50%;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@media (forced-colors: active) {
|
|
204
|
+
:host {
|
|
205
|
+
--_border-width: 3px;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
`;
|
|
209
|
+
|
|
210
|
+
export const popoverOverlayStyles = [overlayStyles, popoverOverlay];
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2024 - 2025 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { css } from 'lit';
|
|
7
|
+
import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-core-styles.js';
|
|
8
|
+
|
|
9
|
+
const popoverOverlay = css`
|
|
10
|
+
:host {
|
|
11
|
+
--_default-offset: 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:host([modeless][with-backdrop]) [part='backdrop'] {
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:host([position^='top'][top-aligned]) [part='overlay'],
|
|
19
|
+
:host([position^='bottom'][top-aligned]) [part='overlay'] {
|
|
20
|
+
margin-top: var(--vaadin-popover-offset-top, var(--_default-offset));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[part='overlay'] {
|
|
24
|
+
position: relative;
|
|
25
|
+
overflow: visible;
|
|
26
|
+
max-height: 100%;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
[part='content'] {
|
|
30
|
+
overflow: auto;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
max-height: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Increase the area of the popover so the pointer can go from the target directly to it. */
|
|
36
|
+
[part='overlay']::before {
|
|
37
|
+
position: absolute;
|
|
38
|
+
content: '';
|
|
39
|
+
inset-block: calc(var(--vaadin-popover-offset-top, var(--_default-offset)) * -1)
|
|
40
|
+
calc(var(--vaadin-popover-offset-bottom, var(--_default-offset)) * -1);
|
|
41
|
+
inset-inline: calc(var(--vaadin-popover-offset-start, var(--_default-offset)) * -1)
|
|
42
|
+
calc(var(--vaadin-popover-offset-end, var(--_default-offset)) * -1);
|
|
43
|
+
z-index: -1;
|
|
44
|
+
pointer-events: auto;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:host([position^='top'][bottom-aligned]) [part='overlay'],
|
|
48
|
+
:host([position^='bottom'][bottom-aligned]) [part='overlay'] {
|
|
49
|
+
margin-bottom: var(--vaadin-popover-offset-bottom, var(--_default-offset));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:host([position^='start'][start-aligned]) [part='overlay'],
|
|
53
|
+
:host([position^='end'][start-aligned]) [part='overlay'] {
|
|
54
|
+
margin-inline-start: var(--vaadin-popover-offset-start, var(--_default-offset));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
:host([position^='start'][end-aligned]) [part='overlay'],
|
|
58
|
+
:host([position^='end'][end-aligned]) [part='overlay'] {
|
|
59
|
+
margin-inline-end: var(--vaadin-popover-offset-end, var(--_default-offset));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[part='arrow'] {
|
|
63
|
+
display: none;
|
|
64
|
+
position: absolute;
|
|
65
|
+
height: 0;
|
|
66
|
+
width: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:host([theme~='arrow']) [part='arrow'] {
|
|
70
|
+
display: block;
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
export const popoverOverlayStyles = [overlayStyles, popoverOverlay];
|
|
@@ -5,26 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
|
|
7
7
|
import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
|
|
8
|
-
import { setNestedOverlay } from '@vaadin/overlay/src/vaadin-overlay-stack-mixin.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Returns the closest parent overlay for given node, if any.
|
|
12
|
-
* @param {HTMLElement} node
|
|
13
|
-
* @return {HTMLElement}
|
|
14
|
-
*/
|
|
15
|
-
const getClosestOverlay = (node) => {
|
|
16
|
-
let n = node;
|
|
17
|
-
|
|
18
|
-
while (n && n !== node.ownerDocument) {
|
|
19
|
-
n = n.parentNode || n.host;
|
|
20
|
-
|
|
21
|
-
if (n && n._hasOverlayStackMixin) {
|
|
22
|
-
return n;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return null;
|
|
27
|
-
};
|
|
28
8
|
|
|
29
9
|
/**
|
|
30
10
|
* A mixin providing common popover overlay functionality.
|
|
@@ -44,19 +24,6 @@ export const PopoverOverlayMixin = (superClass) =>
|
|
|
44
24
|
};
|
|
45
25
|
}
|
|
46
26
|
|
|
47
|
-
static get observers() {
|
|
48
|
-
return ['__openedOrTargetChanged(opened, positionTarget)'];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Tag name prefix used by custom properties.
|
|
53
|
-
* @protected
|
|
54
|
-
* @return {string}
|
|
55
|
-
*/
|
|
56
|
-
get _tagNamePrefix() {
|
|
57
|
-
return 'vaadin-popover';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
27
|
/**
|
|
61
28
|
* @protected
|
|
62
29
|
* @override
|
|
@@ -68,15 +35,6 @@ export const PopoverOverlayMixin = (superClass) =>
|
|
|
68
35
|
return;
|
|
69
36
|
}
|
|
70
37
|
|
|
71
|
-
// Copy custom properties from the owner
|
|
72
|
-
if (this.owner) {
|
|
73
|
-
const style = getComputedStyle(this.owner);
|
|
74
|
-
['top', 'bottom', 'start', 'end'].forEach((prop) => {
|
|
75
|
-
const propertyName = `--${this._tagNamePrefix}-offset-${prop}`;
|
|
76
|
-
this.style.setProperty(propertyName, style.getPropertyValue(propertyName));
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
38
|
this.removeAttribute('arrow-centered');
|
|
81
39
|
|
|
82
40
|
// Center the overlay horizontally
|
|
@@ -114,14 +72,4 @@ export const PopoverOverlayMixin = (superClass) =>
|
|
|
114
72
|
this.style.top = `${overlayRect.top + offset}px`;
|
|
115
73
|
}
|
|
116
74
|
}
|
|
117
|
-
|
|
118
|
-
/** @private */
|
|
119
|
-
__openedOrTargetChanged(opened, target) {
|
|
120
|
-
if (target) {
|
|
121
|
-
const parent = getClosestOverlay(target);
|
|
122
|
-
if (parent) {
|
|
123
|
-
setNestedOverlay(parent, opened ? this : null);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
75
|
};
|
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* Copyright (c) 2024 - 2025 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { html, LitElement } from 'lit';
|
|
7
|
+
import { isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js';
|
|
7
8
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
8
9
|
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
9
10
|
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
|
|
10
|
-
import {
|
|
11
|
+
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
|
|
11
12
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
13
|
+
import { popoverOverlayStyles } from './styles/vaadin-popover-overlay-core-styles.js';
|
|
12
14
|
import { PopoverOverlayMixin } from './vaadin-popover-overlay-mixin.js';
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -21,80 +23,15 @@ import { PopoverOverlayMixin } from './vaadin-popover-overlay-mixin.js';
|
|
|
21
23
|
* @mixes ThemableMixin
|
|
22
24
|
* @private
|
|
23
25
|
*/
|
|
24
|
-
class PopoverOverlay extends PopoverOverlayMixin(
|
|
26
|
+
class PopoverOverlay extends PopoverOverlayMixin(
|
|
27
|
+
DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement)))),
|
|
28
|
+
) {
|
|
25
29
|
static get is() {
|
|
26
30
|
return 'vaadin-popover-overlay';
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
static get styles() {
|
|
30
|
-
return
|
|
31
|
-
overlayStyles,
|
|
32
|
-
css`
|
|
33
|
-
:host {
|
|
34
|
-
--_vaadin-popover-content-width: auto;
|
|
35
|
-
--_vaadin-popover-content-height: auto;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
:host([modeless][with-backdrop]) [part='backdrop'] {
|
|
39
|
-
pointer-events: none;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
:host([position^='top'][top-aligned]) [part='overlay'],
|
|
43
|
-
:host([position^='bottom'][top-aligned]) [part='overlay'] {
|
|
44
|
-
margin-top: var(--vaadin-popover-offset-top, 0);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
[part='overlay'] {
|
|
48
|
-
position: relative;
|
|
49
|
-
overflow: visible;
|
|
50
|
-
max-height: 100%;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
[part='content'] {
|
|
54
|
-
overflow: auto;
|
|
55
|
-
box-sizing: border-box;
|
|
56
|
-
max-height: 100%;
|
|
57
|
-
width: var(--_vaadin-popover-content-width);
|
|
58
|
-
height: var(--_vaadin-popover-content-height);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/* Increase the area of the popover so the pointer can go from the target directly to it. */
|
|
62
|
-
[part='overlay']::before {
|
|
63
|
-
position: absolute;
|
|
64
|
-
content: '';
|
|
65
|
-
inset-block: calc(var(--vaadin-popover-offset-top, 0) * -1) calc(var(--vaadin-popover-offset-bottom, 0) * -1);
|
|
66
|
-
inset-inline: calc(var(--vaadin-popover-offset-start, 0) * -1) calc(var(--vaadin-popover-offset-end, 0) * -1);
|
|
67
|
-
z-index: -1;
|
|
68
|
-
pointer-events: auto;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
:host([position^='top'][bottom-aligned]) [part='overlay'],
|
|
72
|
-
:host([position^='bottom'][bottom-aligned]) [part='overlay'] {
|
|
73
|
-
margin-bottom: var(--vaadin-popover-offset-bottom, 0);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
:host([position^='start'][start-aligned]) [part='overlay'],
|
|
77
|
-
:host([position^='end'][start-aligned]) [part='overlay'] {
|
|
78
|
-
margin-inline-start: var(--vaadin-popover-offset-start, 0);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
:host([position^='start'][end-aligned]) [part='overlay'],
|
|
82
|
-
:host([position^='end'][end-aligned]) [part='overlay'] {
|
|
83
|
-
margin-inline-end: var(--vaadin-popover-offset-end, 0);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
[part='arrow'] {
|
|
87
|
-
display: none;
|
|
88
|
-
position: absolute;
|
|
89
|
-
height: 0;
|
|
90
|
-
width: 0;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
:host([theme~='arrow']) [part='arrow'] {
|
|
94
|
-
display: block;
|
|
95
|
-
}
|
|
96
|
-
`,
|
|
97
|
-
];
|
|
34
|
+
return popoverOverlayStyles;
|
|
98
35
|
}
|
|
99
36
|
|
|
100
37
|
/** @protected */
|
|
@@ -107,6 +44,37 @@ class PopoverOverlay extends PopoverOverlayMixin(DirMixin(ThemableMixin(PolylitM
|
|
|
107
44
|
</div>
|
|
108
45
|
`;
|
|
109
46
|
}
|
|
47
|
+
|
|
48
|
+
/** @protected */
|
|
49
|
+
updated(props) {
|
|
50
|
+
super.updated(props);
|
|
51
|
+
|
|
52
|
+
if (props.has('restoreFocusNode') && this.opened) {
|
|
53
|
+
// Save focus to be restored when target is set while opened
|
|
54
|
+
if (this.restoreFocusNode && isElementFocused(this.restoreFocusNode.focusElement || this.restoreFocusNode)) {
|
|
55
|
+
this.__focusRestorationController.saveFocus();
|
|
56
|
+
} else if (!this.restoreFocusNode) {
|
|
57
|
+
// Do not restore focus when target is cleared while opened
|
|
58
|
+
this.__focusRestorationController.focusNode = null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @override
|
|
65
|
+
* @protected
|
|
66
|
+
*/
|
|
67
|
+
get _contentRoot() {
|
|
68
|
+
return this.owner;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @override
|
|
73
|
+
* @protected
|
|
74
|
+
*/
|
|
75
|
+
get _modalRoot() {
|
|
76
|
+
return this.owner;
|
|
77
|
+
}
|
|
110
78
|
}
|
|
111
79
|
|
|
112
80
|
defineCustomElement(PopoverOverlay);
|
package/src/vaadin-popover.d.ts
CHANGED
|
@@ -37,16 +37,13 @@ export type PopoverEventMap = HTMLElementEventMap & PopoverCustomEventMap;
|
|
|
37
37
|
*
|
|
38
38
|
* ### Styling
|
|
39
39
|
*
|
|
40
|
-
*
|
|
41
|
-
* themable component as the actual visible overlay.
|
|
42
|
-
*
|
|
43
|
-
* See [`<vaadin-overlay>`](#/elements/vaadin-overlay) documentation
|
|
44
|
-
* for `<vaadin-popover-overlay>` parts.
|
|
45
|
-
*
|
|
46
|
-
* In addition to `<vaadin-overlay>` parts, the following parts are available for styling:
|
|
40
|
+
* The following shadow DOM parts are available for styling:
|
|
47
41
|
*
|
|
48
42
|
* Part name | Description
|
|
49
43
|
* -----------------|-------------------------------------------
|
|
44
|
+
* `backdrop` | Backdrop of the overlay
|
|
45
|
+
* `overlay` | The overlay container
|
|
46
|
+
* `content` | The overlay content
|
|
50
47
|
* `arrow` | Optional arrow pointing to the target when using `theme="arrow"`
|
|
51
48
|
*
|
|
52
49
|
* The following state attributes are available for styling:
|
|
@@ -55,9 +52,6 @@ export type PopoverEventMap = HTMLElementEventMap & PopoverCustomEventMap;
|
|
|
55
52
|
* -----------------|----------------------------------------
|
|
56
53
|
* `position` | Reflects the `position` property value.
|
|
57
54
|
*
|
|
58
|
-
* Note: the `theme` attribute value set on `<vaadin-popover>` is
|
|
59
|
-
* propagated to the internal `<vaadin-popover-overlay>` component.
|
|
60
|
-
*
|
|
61
55
|
* ### Custom CSS Properties
|
|
62
56
|
*
|
|
63
57
|
* The following custom CSS properties are available on the `<vaadin-popover>` element:
|
|
@@ -96,14 +90,14 @@ declare class Popover extends PopoverPositionMixin(
|
|
|
96
90
|
static setDefaultHoverDelay(hoverDelay: number): void;
|
|
97
91
|
|
|
98
92
|
/**
|
|
99
|
-
* String used to label the
|
|
93
|
+
* String used to label the popover to screen reader users.
|
|
100
94
|
*
|
|
101
95
|
* @attr {string} accessible-name
|
|
102
96
|
*/
|
|
103
97
|
accessibleName: string | null | undefined;
|
|
104
98
|
|
|
105
99
|
/**
|
|
106
|
-
* Id of the element used as label of the
|
|
100
|
+
* Id of the element used as label of the popover to screen reader users.
|
|
107
101
|
*
|
|
108
102
|
* @attr {string} accessible-name-ref
|
|
109
103
|
*/
|
|
@@ -116,18 +110,16 @@ declare class Popover extends PopoverPositionMixin(
|
|
|
116
110
|
autofocus: boolean;
|
|
117
111
|
|
|
118
112
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* @attr {string} content-height
|
|
113
|
+
* Set the height of the overlay.
|
|
114
|
+
* If a unitless number is provided, pixels are assumed.
|
|
122
115
|
*/
|
|
123
|
-
|
|
116
|
+
height: string | null;
|
|
124
117
|
|
|
125
118
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* @attr {string} content-width
|
|
119
|
+
* Set the width of the overlay.
|
|
120
|
+
* If a unitless number is provided, pixels are assumed.
|
|
129
121
|
*/
|
|
130
|
-
|
|
122
|
+
width: string | null;
|
|
131
123
|
|
|
132
124
|
/**
|
|
133
125
|
* The delay in milliseconds before the popover is opened
|