@vaadin/dialog 24.2.0-alpha4 → 24.2.0-dev.538d07bdf
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/package.json +15 -11
- package/src/lit/renderer-directives.d.ts +2 -2
- package/src/vaadin-dialog-base-mixin.d.ts +34 -0
- package/src/vaadin-dialog-base-mixin.js +123 -0
- package/src/vaadin-dialog-draggable-mixin.js +4 -1
- package/src/vaadin-dialog-overlay-mixin.d.ts +56 -0
- package/src/vaadin-dialog-overlay-mixin.js +257 -0
- package/src/vaadin-dialog-overlay.d.ts +5 -27
- package/src/vaadin-dialog-overlay.js +27 -361
- package/src/vaadin-dialog-renderer-mixin.d.ts +68 -0
- package/src/vaadin-dialog-renderer-mixin.js +84 -0
- package/src/vaadin-dialog-resizable-mixin.js +4 -102
- package/src/vaadin-dialog-styles.d.ts +10 -0
- package/src/vaadin-dialog-styles.js +181 -0
- package/src/vaadin-dialog.d.ts +6 -79
- package/src/vaadin-dialog.js +9 -168
- package/theme/lumo/vaadin-dialog-styles.js +2 -0
- package/theme/material/vaadin-dialog-styles.js +2 -0
- package/web-types.json +0 -243
- package/web-types.lit.json +0 -118
|
@@ -3,379 +3,45 @@
|
|
|
3
3
|
* Copyright (c) 2017 - 2023 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
|
+
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
|
|
8
|
+
import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
|
|
9
|
+
import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
10
|
+
import { DialogOverlayMixin } from './vaadin-dialog-overlay-mixin.js';
|
|
11
|
+
import { dialogOverlay, resizableOverlay } from './vaadin-dialog-styles.js';
|
|
8
12
|
|
|
9
|
-
registerStyles(
|
|
10
|
-
'vaadin-dialog-overlay',
|
|
11
|
-
|
|
12
|
-
[part='header'],
|
|
13
|
-
[part='header-content'],
|
|
14
|
-
[part='footer'] {
|
|
15
|
-
display: flex;
|
|
16
|
-
align-items: center;
|
|
17
|
-
flex-wrap: wrap;
|
|
18
|
-
flex: none;
|
|
19
|
-
pointer-events: none;
|
|
20
|
-
z-index: 1;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
[part='header'] {
|
|
24
|
-
flex-wrap: nowrap;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
::slotted([slot='header-content']),
|
|
28
|
-
::slotted([slot='title']),
|
|
29
|
-
::slotted([slot='footer']) {
|
|
30
|
-
display: contents;
|
|
31
|
-
pointer-events: auto;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
::slotted([slot='title']) {
|
|
35
|
-
font: inherit !important;
|
|
36
|
-
overflow-wrap: anywhere;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
[part='header-content'] {
|
|
40
|
-
flex: 1;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
:host([has-title]) [part='header-content'],
|
|
44
|
-
[part='footer'] {
|
|
45
|
-
justify-content: flex-end;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
:host(:not([has-title]):not([has-header])) [part='header'],
|
|
49
|
-
:host(:not([has-header])) [part='header-content'],
|
|
50
|
-
:host(:not([has-title])) [part='title'],
|
|
51
|
-
:host(:not([has-footer])) [part='footer'] {
|
|
52
|
-
display: none !important;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
:host(:is([has-title], [has-header], [has-footer])) [part='content'] {
|
|
56
|
-
height: auto;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@media (min-height: 320px) {
|
|
60
|
-
:host(:is([has-title], [has-header], [has-footer])) .resizer-container {
|
|
61
|
-
overflow: hidden;
|
|
62
|
-
display: flex;
|
|
63
|
-
flex-direction: column;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
:host(:is([has-title], [has-header], [has-footer])) [part='content'] {
|
|
67
|
-
flex: 1;
|
|
68
|
-
overflow: auto;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/*
|
|
73
|
-
NOTE(platosha): Make some min-width to prevent collapsing of the content
|
|
74
|
-
taking the parent width, e. g., <vaadin-grid> and such.
|
|
75
|
-
*/
|
|
76
|
-
[part='content'] {
|
|
77
|
-
min-width: 12em; /* matches the default <vaadin-text-field> width */
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
:host([has-bounds-set]) [part='overlay'] {
|
|
81
|
-
max-width: none;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@media (forced-colors: active) {
|
|
85
|
-
[part='overlay'] {
|
|
86
|
-
outline: 3px solid !important;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
`,
|
|
90
|
-
{ moduleId: 'vaadin-dialog-overlay-styles' },
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
let memoizedTemplate;
|
|
13
|
+
registerStyles('vaadin-dialog-overlay', [overlayStyles, dialogOverlay, resizableOverlay], {
|
|
14
|
+
moduleId: 'vaadin-dialog-overlay-styles',
|
|
15
|
+
});
|
|
94
16
|
|
|
95
17
|
/**
|
|
96
18
|
* An element used internally by `<vaadin-dialog>`. Not intended to be used separately.
|
|
97
19
|
*
|
|
98
|
-
* @extends
|
|
20
|
+
* @extends HTMLElement
|
|
21
|
+
* @mixes DialogOverlayMixin
|
|
22
|
+
* @mixes DirMixin
|
|
23
|
+
* @mixes ThemableMixin
|
|
99
24
|
* @private
|
|
100
25
|
*/
|
|
101
|
-
export class DialogOverlay extends
|
|
26
|
+
export class DialogOverlay extends DialogOverlayMixin(DirMixin(ThemableMixin(PolymerElement))) {
|
|
102
27
|
static get is() {
|
|
103
28
|
return 'vaadin-dialog-overlay';
|
|
104
29
|
}
|
|
105
30
|
|
|
106
31
|
static get template() {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const titleContainer = document.createElement('div');
|
|
122
|
-
titleContainer.setAttribute('part', 'title');
|
|
123
|
-
headerContainer.appendChild(titleContainer);
|
|
124
|
-
|
|
125
|
-
const titleSlot = document.createElement('slot');
|
|
126
|
-
titleSlot.setAttribute('name', 'title');
|
|
127
|
-
titleContainer.appendChild(titleSlot);
|
|
128
|
-
|
|
129
|
-
const headerContentContainer = document.createElement('div');
|
|
130
|
-
headerContentContainer.setAttribute('part', 'header-content');
|
|
131
|
-
headerContainer.appendChild(headerContentContainer);
|
|
132
|
-
|
|
133
|
-
const headerSlot = document.createElement('slot');
|
|
134
|
-
headerSlot.setAttribute('name', 'header-content');
|
|
135
|
-
headerContentContainer.appendChild(headerSlot);
|
|
136
|
-
|
|
137
|
-
const footerContainer = document.createElement('footer');
|
|
138
|
-
footerContainer.setAttribute('part', 'footer');
|
|
139
|
-
resizerContainer.appendChild(footerContainer);
|
|
140
|
-
|
|
141
|
-
const footerSlot = document.createElement('slot');
|
|
142
|
-
footerSlot.setAttribute('name', 'footer');
|
|
143
|
-
footerContainer.appendChild(footerSlot);
|
|
144
|
-
}
|
|
145
|
-
return memoizedTemplate;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
static get observers() {
|
|
149
|
-
return [
|
|
150
|
-
'_headerFooterRendererChange(headerRenderer, footerRenderer, opened)',
|
|
151
|
-
'_headerTitleChanged(headerTitle, opened)',
|
|
152
|
-
];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
static get properties() {
|
|
156
|
-
return {
|
|
157
|
-
modeless: Boolean,
|
|
158
|
-
|
|
159
|
-
withBackdrop: Boolean,
|
|
160
|
-
|
|
161
|
-
headerTitle: String,
|
|
162
|
-
|
|
163
|
-
headerRenderer: Function,
|
|
164
|
-
|
|
165
|
-
footerRenderer: Function,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** @protected */
|
|
170
|
-
ready() {
|
|
171
|
-
super.ready();
|
|
172
|
-
|
|
173
|
-
// Update overflow attribute on resize
|
|
174
|
-
this.__resizeObserver = new ResizeObserver(() => {
|
|
175
|
-
this.__updateOverflow();
|
|
176
|
-
});
|
|
177
|
-
this.__resizeObserver.observe(this.$.resizerContainer);
|
|
178
|
-
|
|
179
|
-
// Update overflow attribute on scroll
|
|
180
|
-
this.$.content.addEventListener('scroll', () => {
|
|
181
|
-
this.__updateOverflow();
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/** @private */
|
|
186
|
-
__createContainer(slot) {
|
|
187
|
-
const container = document.createElement('div');
|
|
188
|
-
container.setAttribute('slot', slot);
|
|
189
|
-
return container;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/** @private */
|
|
193
|
-
__clearContainer(container) {
|
|
194
|
-
container.innerHTML = '';
|
|
195
|
-
// Whenever a Lit-based renderer is used, it assigns a Lit part to the node it was rendered into.
|
|
196
|
-
// When clearing the rendered content, this part needs to be manually disposed of.
|
|
197
|
-
// Otherwise, using a Lit-based renderer on the same node will throw an exception or render nothing afterward.
|
|
198
|
-
delete container._$litPart$;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/** @private */
|
|
202
|
-
__initContainer(container, slot) {
|
|
203
|
-
if (container) {
|
|
204
|
-
// Reset existing container in case if a new renderer is set.
|
|
205
|
-
this.__clearContainer(container);
|
|
206
|
-
} else {
|
|
207
|
-
// Create the container, but wait to append it until requestContentUpdate is called.
|
|
208
|
-
container = this.__createContainer(slot);
|
|
209
|
-
}
|
|
210
|
-
return container;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/** @private */
|
|
214
|
-
_headerFooterRendererChange(headerRenderer, footerRenderer, opened) {
|
|
215
|
-
const headerRendererChanged = this.__oldHeaderRenderer !== headerRenderer;
|
|
216
|
-
this.__oldHeaderRenderer = headerRenderer;
|
|
217
|
-
|
|
218
|
-
const footerRendererChanged = this.__oldFooterRenderer !== footerRenderer;
|
|
219
|
-
this.__oldFooterRenderer = footerRenderer;
|
|
220
|
-
|
|
221
|
-
const openedChanged = this._oldOpenedFooterHeader !== opened;
|
|
222
|
-
this._oldOpenedFooterHeader = opened;
|
|
223
|
-
|
|
224
|
-
// Set attributes here to update styles before detecting content overflow
|
|
225
|
-
this.toggleAttribute('has-header', !!headerRenderer);
|
|
226
|
-
this.toggleAttribute('has-footer', !!footerRenderer);
|
|
227
|
-
|
|
228
|
-
if (headerRendererChanged) {
|
|
229
|
-
if (headerRenderer) {
|
|
230
|
-
this.headerContainer = this.__initContainer(this.headerContainer, 'header-content');
|
|
231
|
-
} else if (this.headerContainer) {
|
|
232
|
-
this.headerContainer.remove();
|
|
233
|
-
this.headerContainer = null;
|
|
234
|
-
this.__updateOverflow();
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (footerRendererChanged) {
|
|
239
|
-
if (footerRenderer) {
|
|
240
|
-
this.footerContainer = this.__initContainer(this.footerContainer, 'footer');
|
|
241
|
-
} else if (this.footerContainer) {
|
|
242
|
-
this.footerContainer.remove();
|
|
243
|
-
this.footerContainer = null;
|
|
244
|
-
this.__updateOverflow();
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (
|
|
249
|
-
(headerRenderer && (headerRendererChanged || openedChanged)) ||
|
|
250
|
-
(footerRenderer && (footerRendererChanged || openedChanged))
|
|
251
|
-
) {
|
|
252
|
-
if (opened) {
|
|
253
|
-
this.requestContentUpdate();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/** @private */
|
|
259
|
-
_headerTitleChanged(headerTitle, opened) {
|
|
260
|
-
this.toggleAttribute('has-title', !!headerTitle);
|
|
261
|
-
|
|
262
|
-
if (opened && (headerTitle || this._oldHeaderTitle)) {
|
|
263
|
-
this.requestContentUpdate();
|
|
264
|
-
}
|
|
265
|
-
this._oldHeaderTitle = headerTitle;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/** @private */
|
|
269
|
-
_headerTitleRenderer() {
|
|
270
|
-
if (this.headerTitle) {
|
|
271
|
-
if (!this.headerTitleElement) {
|
|
272
|
-
this.headerTitleElement = document.createElement('h2');
|
|
273
|
-
this.headerTitleElement.setAttribute('slot', 'title');
|
|
274
|
-
this.headerTitleElement.classList.add('draggable');
|
|
275
|
-
}
|
|
276
|
-
this.appendChild(this.headerTitleElement);
|
|
277
|
-
this.headerTitleElement.textContent = this.headerTitle;
|
|
278
|
-
} else if (this.headerTitleElement) {
|
|
279
|
-
this.headerTitleElement.remove();
|
|
280
|
-
this.headerTitleElement = null;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* @override
|
|
286
|
-
*/
|
|
287
|
-
requestContentUpdate() {
|
|
288
|
-
super.requestContentUpdate();
|
|
289
|
-
|
|
290
|
-
if (this.headerContainer) {
|
|
291
|
-
// If a new renderer has been set, make sure to reattach the container
|
|
292
|
-
if (!this.headerContainer.parentElement) {
|
|
293
|
-
this.appendChild(this.headerContainer);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (this.headerRenderer) {
|
|
297
|
-
// Only call header renderer after the container has been initialized
|
|
298
|
-
this.headerRenderer.call(this.owner, this.headerContainer, this.owner);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (this.footerContainer) {
|
|
303
|
-
// If a new renderer has been set, make sure to reattach the container
|
|
304
|
-
if (!this.footerContainer.parentElement) {
|
|
305
|
-
this.appendChild(this.footerContainer);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (this.footerRenderer) {
|
|
309
|
-
// Only call header renderer after the container has been initialized
|
|
310
|
-
this.footerRenderer.call(this.owner, this.footerContainer, this.owner);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
this._headerTitleRenderer();
|
|
315
|
-
|
|
316
|
-
this.__updateOverflow();
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Updates the coordinates of the overlay.
|
|
321
|
-
* @param {!DialogOverlayBoundsParam} bounds
|
|
322
|
-
*/
|
|
323
|
-
setBounds(bounds) {
|
|
324
|
-
const overlay = this.$.overlay;
|
|
325
|
-
const parsedBounds = { ...bounds };
|
|
326
|
-
|
|
327
|
-
if (overlay.style.position !== 'absolute') {
|
|
328
|
-
overlay.style.position = 'absolute';
|
|
329
|
-
this.setAttribute('has-bounds-set', '');
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
Object.keys(parsedBounds).forEach((arg) => {
|
|
333
|
-
if (typeof parsedBounds[arg] === 'number') {
|
|
334
|
-
parsedBounds[arg] = `${parsedBounds[arg]}px`;
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
Object.assign(overlay.style, parsedBounds);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Retrieves the coordinates of the overlay.
|
|
343
|
-
* @return {!DialogOverlayBounds}
|
|
344
|
-
*/
|
|
345
|
-
getBounds() {
|
|
346
|
-
const overlayBounds = this.$.overlay.getBoundingClientRect();
|
|
347
|
-
const containerBounds = this.getBoundingClientRect();
|
|
348
|
-
const top = overlayBounds.top - containerBounds.top;
|
|
349
|
-
const left = overlayBounds.left - containerBounds.left;
|
|
350
|
-
const width = overlayBounds.width;
|
|
351
|
-
const height = overlayBounds.height;
|
|
352
|
-
return { top, left, width, height };
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/** @private */
|
|
356
|
-
__updateOverflow() {
|
|
357
|
-
let overflow = '';
|
|
358
|
-
|
|
359
|
-
// Only set "overflow" attribute if the dialog has a header, title or footer.
|
|
360
|
-
// Check for state attributes as extending components might not use renderers.
|
|
361
|
-
if (this.hasAttribute('has-header') || this.hasAttribute('has-footer') || this.headerTitle) {
|
|
362
|
-
const content = this.$.content;
|
|
363
|
-
|
|
364
|
-
if (content.scrollTop > 0) {
|
|
365
|
-
overflow += ' top';
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
if (content.scrollTop < content.scrollHeight - content.clientHeight) {
|
|
369
|
-
overflow += ' bottom';
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const value = overflow.trim();
|
|
374
|
-
if (value.length > 0 && this.getAttribute('overflow') !== value) {
|
|
375
|
-
this.setAttribute('overflow', value);
|
|
376
|
-
} else if (value.length === 0 && this.hasAttribute('overflow')) {
|
|
377
|
-
this.removeAttribute('overflow');
|
|
378
|
-
}
|
|
32
|
+
return html`
|
|
33
|
+
<div id="backdrop" part="backdrop" hidden$="[[!withBackdrop]]"></div>
|
|
34
|
+
<div part="overlay" id="overlay" tabindex="0">
|
|
35
|
+
<section id="resizerContainer" class="resizer-container">
|
|
36
|
+
<header part="header">
|
|
37
|
+
<div part="title"><slot name="title"></slot></div>
|
|
38
|
+
<div part="header-content"><slot name="header-content"></slot></div>
|
|
39
|
+
</header>
|
|
40
|
+
<div part="content" id="content"><slot></slot></div>
|
|
41
|
+
<footer part="footer"><slot name="footer"></slot></footer>
|
|
42
|
+
</section>
|
|
43
|
+
</div>
|
|
44
|
+
`;
|
|
379
45
|
}
|
|
380
46
|
}
|
|
381
47
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
import type { DialogRenderer } from './vaadin-dialog.js';
|
|
8
|
+
|
|
9
|
+
export declare function DialogRendererMixin<T extends Constructor<HTMLElement>>(
|
|
10
|
+
base: T,
|
|
11
|
+
): Constructor<DialogRendererMixinClass> & T;
|
|
12
|
+
|
|
13
|
+
export declare class DialogRendererMixinClass {
|
|
14
|
+
/**
|
|
15
|
+
* Custom function for rendering the content of the dialog.
|
|
16
|
+
* Receives two arguments:
|
|
17
|
+
*
|
|
18
|
+
* - `root` The root container DOM element. Append your content to it.
|
|
19
|
+
* - `dialog` The reference to the `<vaadin-dialog>` element.
|
|
20
|
+
*/
|
|
21
|
+
renderer: DialogRenderer | null | undefined;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* String used for rendering a dialog title.
|
|
25
|
+
*
|
|
26
|
+
* If both `headerTitle` and `headerRenderer` are defined, the title
|
|
27
|
+
* and the elements created by the renderer will be placed next to
|
|
28
|
+
* each other, with the title coming first.
|
|
29
|
+
*
|
|
30
|
+
* When `headerTitle` is set, the attribute `has-title` is added to the overlay element.
|
|
31
|
+
* @attr {string} header-title
|
|
32
|
+
*/
|
|
33
|
+
headerTitle: string | null | undefined;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Custom function for rendering the dialog header.
|
|
37
|
+
* Receives two arguments:
|
|
38
|
+
*
|
|
39
|
+
* - `root` The root container DOM element. Append your content to it.
|
|
40
|
+
* - `dialog` The reference to the `<vaadin-dialog>` element.
|
|
41
|
+
*
|
|
42
|
+
* If both `headerTitle` and `headerRenderer` are defined, the title
|
|
43
|
+
* and the elements created by the renderer will be placed next to
|
|
44
|
+
* each other, with the title coming first.
|
|
45
|
+
*
|
|
46
|
+
* When `headerRenderer` is set, the attribute `has-header` is added to the overlay element.
|
|
47
|
+
*/
|
|
48
|
+
headerRenderer: DialogRenderer | null | undefined;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Custom function for rendering the dialog footer.
|
|
52
|
+
* Receives two arguments:
|
|
53
|
+
*
|
|
54
|
+
* - `root` The root container DOM element. Append your content to it.
|
|
55
|
+
* - `dialog` The reference to the `<vaadin-dialog>` element.
|
|
56
|
+
*
|
|
57
|
+
* When `footerRenderer` is set, the attribute `has-footer` is added to the overlay element.
|
|
58
|
+
*/
|
|
59
|
+
footerRenderer: DialogRenderer | null | undefined;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* While performing the update, it invokes the renderer passed in the `renderer` property,
|
|
63
|
+
* as well as `headerRender` and `footerRenderer` properties, if these are defined.
|
|
64
|
+
*
|
|
65
|
+
* It is not guaranteed that the update happens immediately (synchronously) after it is requested.
|
|
66
|
+
*/
|
|
67
|
+
requestContentUpdate(): void;
|
|
68
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2017 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @polymerMixin
|
|
9
|
+
*/
|
|
10
|
+
export const DialogRendererMixin = (superClass) =>
|
|
11
|
+
class DialogRendererMixin extends superClass {
|
|
12
|
+
static get properties() {
|
|
13
|
+
return {
|
|
14
|
+
/**
|
|
15
|
+
* Custom function for rendering the content of the dialog.
|
|
16
|
+
* Receives two arguments:
|
|
17
|
+
*
|
|
18
|
+
* - `root` The root container DOM element. Append your content to it.
|
|
19
|
+
* - `dialog` The reference to the `<vaadin-dialog>` element.
|
|
20
|
+
* @type {DialogRenderer | undefined}
|
|
21
|
+
*/
|
|
22
|
+
renderer: {
|
|
23
|
+
type: Object,
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* String used for rendering a dialog title.
|
|
28
|
+
*
|
|
29
|
+
* If both `headerTitle` and `headerRenderer` are defined, the title
|
|
30
|
+
* and the elements created by the renderer will be placed next to
|
|
31
|
+
* each other, with the title coming first.
|
|
32
|
+
*
|
|
33
|
+
* When `headerTitle` is set, the attribute `has-title` is added to the overlay element.
|
|
34
|
+
* @attr {string} header-title
|
|
35
|
+
*/
|
|
36
|
+
headerTitle: String,
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Custom function for rendering the dialog header.
|
|
40
|
+
* Receives two arguments:
|
|
41
|
+
*
|
|
42
|
+
* - `root` The root container DOM element. Append your content to it.
|
|
43
|
+
* - `dialog` The reference to the `<vaadin-dialog>` element.
|
|
44
|
+
*
|
|
45
|
+
* If both `headerTitle` and `headerRenderer` are defined, the title
|
|
46
|
+
* and the elements created by the renderer will be placed next to
|
|
47
|
+
* each other, with the title coming first.
|
|
48
|
+
*
|
|
49
|
+
* When `headerRenderer` is set, the attribute `has-header` is added to the overlay element.
|
|
50
|
+
* @type {DialogRenderer | undefined}
|
|
51
|
+
*/
|
|
52
|
+
headerRenderer: {
|
|
53
|
+
type: Object,
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Custom function for rendering the dialog footer.
|
|
58
|
+
* Receives two arguments:
|
|
59
|
+
*
|
|
60
|
+
* - `root` The root container DOM element. Append your content to it.
|
|
61
|
+
* - `dialog` The reference to the `<vaadin-dialog>` element.
|
|
62
|
+
*
|
|
63
|
+
* When `footerRenderer` is set, the attribute `has-footer` is added to the overlay element.
|
|
64
|
+
* @type {DialogRenderer | undefined}
|
|
65
|
+
*/
|
|
66
|
+
footerRenderer: {
|
|
67
|
+
type: Object,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Requests an update for the content of the dialog.
|
|
74
|
+
* While performing the update, it invokes the renderer passed in the `renderer` property,
|
|
75
|
+
* as well as `headerRender` and `footerRenderer` properties, if these are defined.
|
|
76
|
+
*
|
|
77
|
+
* It is not guaranteed that the update happens immediately (synchronously) after it is requested.
|
|
78
|
+
*/
|
|
79
|
+
requestContentUpdate() {
|
|
80
|
+
if (this._overlayElement) {
|
|
81
|
+
this._overlayElement.requestContentUpdate();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
@@ -3,108 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2017 - 2023 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
7
6
|
import { eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
|
|
8
|
-
|
|
9
|
-
registerStyles(
|
|
10
|
-
'vaadin-dialog-overlay',
|
|
11
|
-
css`
|
|
12
|
-
[part='overlay'] {
|
|
13
|
-
position: relative;
|
|
14
|
-
overflow: visible;
|
|
15
|
-
max-height: 100%;
|
|
16
|
-
display: flex;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
[part='content'] {
|
|
20
|
-
box-sizing: border-box;
|
|
21
|
-
height: 100%;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.resizer-container {
|
|
25
|
-
overflow: auto;
|
|
26
|
-
flex-grow: 1;
|
|
27
|
-
border-radius: inherit; /* prevent child elements being drawn outside part=overlay */
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
[part='overlay'][style] .resizer-container {
|
|
31
|
-
min-height: 100%;
|
|
32
|
-
width: 100%;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
:host(:not([resizable])) .resizer {
|
|
36
|
-
display: none;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
:host([resizable]) [part='title'] {
|
|
40
|
-
cursor: move;
|
|
41
|
-
-webkit-user-select: none;
|
|
42
|
-
user-select: none;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.resizer {
|
|
46
|
-
position: absolute;
|
|
47
|
-
height: 16px;
|
|
48
|
-
width: 16px;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.resizer.edge {
|
|
52
|
-
height: 8px;
|
|
53
|
-
width: 8px;
|
|
54
|
-
inset: -4px;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.resizer.edge.n {
|
|
58
|
-
width: auto;
|
|
59
|
-
bottom: auto;
|
|
60
|
-
cursor: ns-resize;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.resizer.ne {
|
|
64
|
-
top: -4px;
|
|
65
|
-
right: -4px;
|
|
66
|
-
cursor: nesw-resize;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.resizer.edge.e {
|
|
70
|
-
height: auto;
|
|
71
|
-
left: auto;
|
|
72
|
-
cursor: ew-resize;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
.resizer.se {
|
|
76
|
-
bottom: -4px;
|
|
77
|
-
right: -4px;
|
|
78
|
-
cursor: nwse-resize;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.resizer.edge.s {
|
|
82
|
-
width: auto;
|
|
83
|
-
top: auto;
|
|
84
|
-
cursor: ns-resize;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
.resizer.sw {
|
|
88
|
-
bottom: -4px;
|
|
89
|
-
left: -4px;
|
|
90
|
-
cursor: nesw-resize;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.resizer.edge.w {
|
|
94
|
-
height: auto;
|
|
95
|
-
right: auto;
|
|
96
|
-
cursor: ew-resize;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.resizer.nw {
|
|
100
|
-
top: -4px;
|
|
101
|
-
left: -4px;
|
|
102
|
-
cursor: nwse-resize;
|
|
103
|
-
}
|
|
104
|
-
`,
|
|
105
|
-
{ moduleId: 'vaadin-dialog-resizable-overlay-styles' },
|
|
106
|
-
);
|
|
107
|
-
|
|
108
7
|
/**
|
|
109
8
|
* @polymerMixin
|
|
110
9
|
*/
|
|
@@ -125,11 +24,14 @@ export const DialogResizableMixin = (superClass) =>
|
|
|
125
24
|
}
|
|
126
25
|
|
|
127
26
|
/** @protected */
|
|
128
|
-
ready() {
|
|
27
|
+
async ready() {
|
|
129
28
|
super.ready();
|
|
130
29
|
this._originalBounds = {};
|
|
131
30
|
this._originalMouseCoords = {};
|
|
132
31
|
this._resizeListeners = { start: {}, resize: {}, stop: {} };
|
|
32
|
+
|
|
33
|
+
// Wait for overlay render
|
|
34
|
+
await new Promise(requestAnimationFrame);
|
|
133
35
|
this._addResizeListeners();
|
|
134
36
|
}
|
|
135
37
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 - 2023 Vaadin Ltd..
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { CSSResult } from 'lit';
|
|
7
|
+
|
|
8
|
+
export const dialogOverlay: CSSResult;
|
|
9
|
+
|
|
10
|
+
export const resizableOverlay: CSSResult;
|