@vaadin/confirm-dialog 22.0.2 → 23.0.0-alpha4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/confirm-dialog",
3
- "version": "22.0.2",
3
+ "version": "23.0.0-alpha4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "main": "vaadin-confirm-dialog.js",
20
20
  "module": "vaadin-confirm-dialog.js",
21
+ "type": "module",
21
22
  "files": [
22
23
  "src",
23
24
  "theme",
@@ -33,19 +34,19 @@
33
34
  ],
34
35
  "dependencies": {
35
36
  "@polymer/polymer": "^3.0.0",
36
- "@vaadin/button": "^22.0.2",
37
- "@vaadin/component-base": "^22.0.2",
38
- "@vaadin/dialog": "^22.0.2",
37
+ "@vaadin/button": "23.0.0-alpha4",
38
+ "@vaadin/component-base": "23.0.0-alpha4",
39
+ "@vaadin/dialog": "23.0.0-alpha4",
39
40
  "@vaadin/vaadin-license-checker": "^2.1.0",
40
- "@vaadin/vaadin-lumo-styles": "^22.0.2",
41
- "@vaadin/vaadin-material-styles": "^22.0.2",
42
- "@vaadin/vaadin-overlay": "^22.0.2",
43
- "@vaadin/vaadin-themable-mixin": "^22.0.2"
41
+ "@vaadin/vaadin-lumo-styles": "23.0.0-alpha4",
42
+ "@vaadin/vaadin-material-styles": "23.0.0-alpha4",
43
+ "@vaadin/vaadin-overlay": "23.0.0-alpha4",
44
+ "@vaadin/vaadin-themable-mixin": "23.0.0-alpha4"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@esm-bundle/chai": "^4.3.4",
47
48
  "@vaadin/testing-helpers": "^0.3.2",
48
49
  "sinon": "^9.2.1"
49
50
  },
50
- "gitHead": "df21370c4a655a38eac11f79686021ab3b0887ad"
51
+ "gitHead": "81e2deee5147bb7c1f4884760f4598613306f1fb"
51
52
  }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2018 - 2022 Vaadin Ltd.
4
+ * This program is available under Commercial Vaadin Developer License 4.0, available at https://vaadin.com/license/cvdl-4.0.
5
+ */
6
+ import { html } from '@polymer/polymer/lib/utils/html-tag.js';
7
+ import { Dialog, DialogOverlay } from '@vaadin/dialog/src/vaadin-dialog.js';
8
+ import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
9
+
10
+ registerStyles(
11
+ 'vaadin-confirm-dialog-overlay',
12
+ css`
13
+ :host {
14
+ --_vaadin-confirm-dialog-content-width: auto;
15
+ --_vaadin-confirm-dialog-content-height: auto;
16
+ }
17
+
18
+ [part='content'] {
19
+ width: var(--_vaadin-confirm-dialog-content-width);
20
+ display: flex;
21
+ flex-direction: column;
22
+ height: var(--_vaadin-confirm-dialog-content-height);
23
+ box-sizing: content-box;
24
+ }
25
+
26
+ [part='message'] {
27
+ margin-bottom: auto;
28
+ }
29
+ `,
30
+ { moduleId: 'vaadin-confirm-dialog-overlay-styles' }
31
+ );
32
+
33
+ let memoizedTemplate;
34
+
35
+ const dialogTemplate = html`
36
+ <div part="header">
37
+ <slot name="header"></slot>
38
+ </div>
39
+
40
+ <div part="message">
41
+ <slot></slot>
42
+ </div>
43
+
44
+ <div part="footer">
45
+ <div part="cancel-button">
46
+ <slot name="cancel-button"></slot>
47
+ </div>
48
+ <div part="reject-button">
49
+ <slot name="reject-button"></slot>
50
+ </div>
51
+ <div part="confirm-button">
52
+ <slot name="confirm-button"></slot>
53
+ </div>
54
+ </div>
55
+ `;
56
+
57
+ /**
58
+ * An extension of `<vaadin-dialog-overlay>` used internally by `<vaadin-confirm-dialog>`.
59
+ * Not intended to be used separately.
60
+ * @private
61
+ */
62
+ class ConfirmDialogOverlay extends DialogOverlay {
63
+ static get is() {
64
+ return 'vaadin-confirm-dialog-overlay';
65
+ }
66
+
67
+ static get template() {
68
+ if (!memoizedTemplate) {
69
+ memoizedTemplate = super.template.cloneNode(true);
70
+ const contentPart = memoizedTemplate.content.querySelector('[part="content"]');
71
+ const defaultSlot = contentPart.querySelector('slot:not([name])');
72
+ contentPart.removeChild(defaultSlot);
73
+ contentPart.appendChild(dialogTemplate.content.cloneNode(true));
74
+ }
75
+ return memoizedTemplate;
76
+ }
77
+
78
+ /**
79
+ * Override method inherited from `OverlayElement` to notify when overlay is closed.
80
+ * The `vaadin-overlay-close` event is not suitable, as it fires before closing.
81
+ * @protected
82
+ * @override
83
+ */
84
+ _finishClosing() {
85
+ super._finishClosing();
86
+
87
+ this.dispatchEvent(new CustomEvent('vaadin-confirm-dialog-close'));
88
+ }
89
+ }
90
+
91
+ customElements.define(ConfirmDialogOverlay.is, ConfirmDialogOverlay);
92
+
93
+ /**
94
+ * An extension of `<vaadin-dialog>` used internally by `<vaadin-confirm-dialog>`.
95
+ * Not intended to be used separately.
96
+ * @private
97
+ */
98
+ class ConfirmDialogDialog extends Dialog {
99
+ static get is() {
100
+ return 'vaadin-confirm-dialog-dialog';
101
+ }
102
+
103
+ /**
104
+ * Override template to provide custom overlay tag name.
105
+ */
106
+ static get template() {
107
+ return html`
108
+ <style>
109
+ :host {
110
+ display: none;
111
+ }
112
+ </style>
113
+
114
+ <vaadin-confirm-dialog-overlay
115
+ id="overlay"
116
+ on-opened-changed="_onOverlayOpened"
117
+ on-mousedown="_bringOverlayToFront"
118
+ on-touchstart="_bringOverlayToFront"
119
+ theme$="[[theme]]"
120
+ modeless="[[modeless]]"
121
+ with-backdrop="[[!modeless]]"
122
+ resizable$="[[resizable]]"
123
+ focus-trap
124
+ ></vaadin-confirm-dialog-overlay>
125
+ `;
126
+ }
127
+ }
128
+
129
+ customElements.define(ConfirmDialogDialog.is, ConfirmDialogDialog);
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 Vaadin Ltd.
3
+ * Copyright (c) 2018 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
7
- import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
7
+ import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
8
+ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
8
9
 
9
10
  /**
10
11
  * Fired when the `opened` property changes.
@@ -34,34 +35,44 @@ export type ConfirmDialogEventMap = HTMLElementEventMap & ConfirmDialogCustomEve
34
35
  *
35
36
  * ### Styling
36
37
  *
37
- * The following Shadow DOM parts are available for styling the dialog parts:
38
+ * The `<vaadin-confirm-dialog>` is not themable. Apply styles to `<vaadin-confirm-dialog-overlay>`
39
+ * component and use its shadow parts for styling.
40
+ * See [`<vaadin-overlay>`](#/elements/vaadin-overlay) for the overlay styling documentation.
38
41
  *
39
- * Part name | Description
40
- * -----------|---------------------------------------------------------|
41
- * `header` | Header of the confirmation dialog
42
- * `message` | Container for the message of the dialog
43
- * `footer` | Container for the buttons
42
+ * In addition to `<vaadin-overlay>` parts, the following parts are available for theming:
43
+ *
44
+ * Part name | Description
45
+ * -----------------|-------------------------------------------
46
+ * `header` | The header element wrapper
47
+ * `message` | The message element wrapper
48
+ * `footer` | The footer element that wraps the buttons
49
+ * `cancel-button` | The "Cancel" button wrapper
50
+ * `confirm-button` | The "Confirm" button wrapper
51
+ * `reject-button` | The "Reject" button wrapper
52
+ *
53
+ * Use `confirmTheme`, `cancelTheme` and `rejectTheme` properties to customize buttons theme.
54
+ * Also, the `theme` attribute value set on `<vaadin-confirm-dialog>` is propagated to the
55
+ * `<vaadin-confirm-dialog-overlay>` component.
44
56
  *
45
57
  * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
46
58
  *
47
59
  * ### Custom content
48
60
  *
49
- * The following parts are available for replacement:
61
+ * The following slots are available for providing custom content:
50
62
  *
51
63
  * Slot name | Description
52
- * ------------------|---------------------------------------------------------|
53
- * `header` | Header of the confirmation dialog
54
- * `message` | Container for the message of the dialog
55
- * `cancel-button` | Container for the Cancel button
56
- * `reject-button` | Container for the Reject button
57
- * `confirm-button` | Container for the Confirm button
64
+ * ------------------|---------------------------
65
+ * `header` | Slot for header element
66
+ * `cancel-button` | Slot for "Cancel" button
67
+ * `confirm-button` | Slot for "Confirm" button
68
+ * `reject-button` | Slot for "Reject" button
58
69
  *
59
70
  * @fires {Event} confirm - Fired when Confirm button was pressed.
60
71
  * @fires {Event} cancel - Fired when Cancel button or Escape key was pressed.
61
72
  * @fires {Event} reject - Fired when Reject button was pressed.
62
73
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
63
74
  */
64
- declare class ConfirmDialog extends ElementMixin(ThemableMixin(HTMLElement)) {
75
+ declare class ConfirmDialog extends SlotMixin(ElementMixin(ThemePropertyMixin(HTMLElement))) {
65
76
  /**
66
77
  * True if the overlay is currently displayed.
67
78
  */
@@ -1,14 +1,15 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2018 - 2021 Vaadin Ltd
3
+ * Copyright (c) 2018 - 2022 Vaadin Ltd.
4
4
  * This program is available under Commercial Vaadin Developer License 4.0, available at https://vaadin.com/license/cvdl-4.0.
5
5
  */
6
6
  import '@vaadin/vaadin-license-checker/vaadin-license-checker.js';
7
- import '@vaadin/button/src/vaadin-button.js';
8
- import '@vaadin/dialog/src/vaadin-dialog.js';
7
+ import './vaadin-confirm-dialog-overlay.js';
8
+ import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
9
9
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
10
10
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
- import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
11
+ import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
12
+ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
12
13
 
13
14
  /**
14
15
  * `<vaadin-confirm-dialog>` is a Web Component for showing alerts and asking for user confirmation.
@@ -21,27 +22,37 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
21
22
  *
22
23
  * ### Styling
23
24
  *
24
- * The following Shadow DOM parts are available for styling the dialog parts:
25
+ * The `<vaadin-confirm-dialog>` is not themable. Apply styles to `<vaadin-confirm-dialog-overlay>`
26
+ * component and use its shadow parts for styling.
27
+ * See [`<vaadin-overlay>`](#/elements/vaadin-overlay) for the overlay styling documentation.
25
28
  *
26
- * Part name | Description
27
- * -----------|---------------------------------------------------------|
28
- * `header` | Header of the confirmation dialog
29
- * `message` | Container for the message of the dialog
30
- * `footer` | Container for the buttons
29
+ * In addition to `<vaadin-overlay>` parts, the following parts are available for theming:
30
+ *
31
+ * Part name | Description
32
+ * -----------------|-------------------------------------------
33
+ * `header` | The header element wrapper
34
+ * `message` | The message element wrapper
35
+ * `footer` | The footer element that wraps the buttons
36
+ * `cancel-button` | The "Cancel" button wrapper
37
+ * `confirm-button` | The "Confirm" button wrapper
38
+ * `reject-button` | The "Reject" button wrapper
39
+ *
40
+ * Use `confirmTheme`, `cancelTheme` and `rejectTheme` properties to customize buttons theme.
41
+ * Also, the `theme` attribute value set on `<vaadin-confirm-dialog>` is propagated to the
42
+ * `<vaadin-confirm-dialog-overlay>` component.
31
43
  *
32
44
  * See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
33
45
  *
34
46
  * ### Custom content
35
47
  *
36
- * The following parts are available for replacement:
48
+ * The following slots are available for providing custom content:
37
49
  *
38
50
  * Slot name | Description
39
- * ------------------|---------------------------------------------------------|
40
- * `header` | Header of the confirmation dialog
41
- * `message` | Container for the message of the dialog
42
- * `cancel-button` | Container for the Cancel button
43
- * `reject-button` | Container for the Reject button
44
- * `confirm-button` | Container for the Confirm button
51
+ * ------------------|---------------------------
52
+ * `header` | Slot for header element
53
+ * `cancel-button` | Slot for "Cancel" button
54
+ * `confirm-button` | Slot for "Confirm" button
55
+ * `reject-button` | Slot for "Reject" button
45
56
  *
46
57
  * @fires {Event} confirm - Fired when Confirm button was pressed.
47
58
  * @fires {Event} cancel - Fired when Cancel button or Escape key was pressed.
@@ -49,80 +60,39 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
49
60
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
50
61
  *
51
62
  * @extends HTMLElement
63
+ * @mixes SlotMixin
52
64
  * @mixes ElementMixin
53
- * @mixes ThemableMixin
65
+ * @mixes ThemePropertyMixin
54
66
  */
55
- class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
67
+ class ConfirmDialog extends SlotMixin(ElementMixin(ThemePropertyMixin(PolymerElement))) {
56
68
  static get template() {
57
69
  return html`
58
70
  <style>
59
71
  :host {
60
72
  display: none;
61
- --_vaadin-confirm-dialog-content-width: auto;
62
- --_vaadin-confirm-dialog-content-height: auto;
63
- --_vaadin-confirm-dialog-footer-height: auto;
73
+ }
74
+
75
+ [hidden] {
76
+ display: none !important;
64
77
  }
65
78
  </style>
66
79
 
67
- <vaadin-dialog
80
+ <vaadin-confirm-dialog-dialog
68
81
  id="dialog"
69
82
  opened="{{opened}}"
70
83
  aria-label="[[_getAriaLabel(header)]]"
71
- theme$="_vaadin-confirm-dialog-dialog-overlay-theme [[theme]]"
84
+ theme$="[[theme]]"
72
85
  no-close-on-outside-click
73
86
  no-close-on-esc="[[noCloseOnEsc]]"
74
- ></vaadin-dialog>
75
-
76
- <template id="dialogTemplate">
77
- <div id="content">
78
- <div part="header">
79
- <slot name="header">
80
- <h3 class="header">[[header]]</h3>
81
- </slot>
82
- </div>
83
-
84
- <div part="message" id="message">
85
- <slot></slot>
86
- [[message]]
87
- </div>
88
- </div>
89
-
90
- <div part="footer">
91
- <div class="cancel-button">
92
- <slot name="cancel-button">
93
- <vaadin-button
94
- id="cancel"
95
- theme$="[[cancelTheme]]"
96
- on-click="_cancel"
97
- hidden$="[[!cancel]]"
98
- aria-describedby="message"
99
- >
100
- [[cancelText]]
101
- </vaadin-button>
102
- </slot>
103
- </div>
104
- <div class="reject-button">
105
- <slot name="reject-button">
106
- <vaadin-button
107
- id="reject"
108
- theme$="[[rejectTheme]]"
109
- on-click="_reject"
110
- hidden$="[[!reject]]"
111
- aria-describedby="message"
112
- >
113
- [[rejectText]]
114
- </vaadin-button>
115
- </slot>
116
- </div>
117
- <div class="confirm-button">
118
- <slot name="confirm-button">
119
- <vaadin-button id="confirm" theme$="[[confirmTheme]]" on-click="_confirm" aria-describedby="message">
120
- [[confirmText]]
121
- </vaadin-button>
122
- </slot>
123
- </div>
124
- </div>
125
- </template>
87
+ ></vaadin-confirm-dialog-dialog>
88
+
89
+ <div hidden>
90
+ <slot name="header"></slot>
91
+ <slot></slot>
92
+ <slot name="cancel-button"></slot>
93
+ <slot name="reject-button"></slot>
94
+ <slot name="confirm-button"></slot>
95
+ </div>
126
96
  `;
127
97
  }
128
98
 
@@ -139,8 +109,7 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
139
109
  opened: {
140
110
  type: Boolean,
141
111
  value: false,
142
- notify: true,
143
- observer: '_openedChanged'
112
+ notify: true
144
113
  },
145
114
 
146
115
  /**
@@ -156,7 +125,8 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
156
125
  * Set the message or confirmation question.
157
126
  */
158
127
  message: {
159
- type: String
128
+ type: String,
129
+ value: ''
160
130
  },
161
131
 
162
132
  /**
@@ -249,9 +219,47 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
249
219
  value: 'tertiary'
250
220
  },
251
221
 
252
- /** @private */
222
+ /**
223
+ * A reference to the "Cancel" button which will be teleported to the overlay.
224
+ * @private
225
+ */
226
+ _cancelButton: {
227
+ type: HTMLElement,
228
+ observer: '_cancelButtonChanged'
229
+ },
230
+
231
+ /**
232
+ * A reference to the "Confirm" button which will be teleported to the overlay.
233
+ * @private
234
+ */
253
235
  _confirmButton: {
254
- type: Element
236
+ type: HTMLElement,
237
+ observer: '_confirmButtonChanged'
238
+ },
239
+
240
+ /**
241
+ * A reference to the "header" node which will be teleported to the overlay.
242
+ * @private
243
+ */
244
+ _headerNode: {
245
+ type: HTMLElement
246
+ },
247
+
248
+ /**
249
+ * A reference to the message which will be placed in the overlay default slot.
250
+ * @private
251
+ */
252
+ _messageNode: {
253
+ type: HTMLElement
254
+ },
255
+
256
+ /**
257
+ * A reference to the "Reject" button which will be teleported to the overlay.
258
+ * @private
259
+ */
260
+ _rejectButton: {
261
+ type: HTMLElement,
262
+ observer: '_rejectButtonChanged'
255
263
  }
256
264
  };
257
265
  }
@@ -268,11 +276,70 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
268
276
  }
269
277
  }
270
278
 
279
+ static get observers() {
280
+ return [
281
+ '__updateConfirmButton(_confirmButton, confirmText, confirmTheme)',
282
+ '__updateCancelButton(_cancelButton, cancelText, cancelTheme, cancel)',
283
+ '__updateHeaderNode(_headerNode, header)',
284
+ '__updateMessageNode(_messageNode, message)',
285
+ '__updateRejectButton(_rejectButton, rejectText, rejectTheme, reject)'
286
+ ];
287
+ }
288
+
289
+ /** @protected */
290
+ get slots() {
291
+ // NOTE: order in which slots are listed matches the template.
292
+ return {
293
+ ...super.slots,
294
+ header: () => {
295
+ const h3 = document.createElement('h3');
296
+ this.__defaultHeader = h3;
297
+ return h3;
298
+ },
299
+ '': () => {
300
+ const div = document.createElement('div');
301
+ this.__defaultMessage = div;
302
+ return div;
303
+ },
304
+ 'cancel-button': () => {
305
+ const button = document.createElement('vaadin-button');
306
+ button.setAttribute('theme', this.cancelTheme);
307
+ button.textContent = this.cancelText;
308
+ return button;
309
+ },
310
+ 'reject-button': () => {
311
+ const button = document.createElement('vaadin-button');
312
+ button.setAttribute('theme', this.rejectTheme);
313
+ button.textContent = this.rejectText;
314
+ return button;
315
+ },
316
+ 'confirm-button': () => {
317
+ return document.createElement('vaadin-button');
318
+ }
319
+ };
320
+ }
321
+
322
+ constructor() {
323
+ super();
324
+ this.__slottedNodes = [];
325
+ this._observer = new FlattenedNodesObserver(this, (info) => {
326
+ this.__onDomChange(info.addedNodes);
327
+ });
328
+ }
329
+
271
330
  /** @protected */
272
331
  ready() {
273
332
  super.ready();
274
333
 
275
- this.$.dialog.$.overlay.addEventListener('vaadin-overlay-escape-press', this._escPressed.bind(this));
334
+ this.__boundCancel = this._cancel.bind(this);
335
+ this.__boundConfirm = this._confirm.bind(this);
336
+ this.__boundReject = this._reject.bind(this);
337
+
338
+ this._overlayElement = this.$.dialog.$.overlay;
339
+ this._overlayElement.addEventListener('vaadin-overlay-escape-press', this._escPressed.bind(this));
340
+ this._overlayElement.addEventListener('vaadin-overlay-open', () => this.__onDialogOpened());
341
+ this._overlayElement.addEventListener('vaadin-confirm-dialog-close', () => this.__onDialogClosed());
342
+
276
343
  if (this._dimensions) {
277
344
  Object.keys(this._dimensions).forEach((name) => {
278
345
  this._setDimension(name, this._dimensions[name]);
@@ -280,61 +347,126 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
280
347
  }
281
348
  }
282
349
 
283
- /**
284
- * @param {string} name
285
- * @param {?string} oldValue
286
- * @param {?string} newValue
287
- * @protected
288
- */
289
- attributeChangedCallback(name, oldValue, newValue) {
290
- super.attributeChangedCallback(name, oldValue, newValue);
291
- if (name === 'dir') {
292
- const value = newValue === 'rtl';
293
- this.__isRTL = value;
294
- this.opened && this.__toggleContentRTL(value);
350
+ /** @private */
351
+ __onDialogOpened() {
352
+ const overlay = this._overlayElement;
353
+
354
+ // Teleport slotted nodes to the overlay element.
355
+ this.__slottedNodes.forEach((node) => {
356
+ overlay.appendChild(node);
357
+ });
358
+
359
+ const confirmButton = overlay.querySelector('[slot="confirm-button"]');
360
+ if (confirmButton) {
361
+ confirmButton.focus();
295
362
  }
296
363
  }
297
364
 
298
365
  /** @private */
299
- __toggleContentRTL(rtl) {
300
- const contentBlock = this.$.dialog.$.overlay.content.querySelector('#content');
301
- const footerBlock = this.$.dialog.$.overlay.content.querySelector('[part=footer]');
302
- if (rtl) {
303
- contentBlock.setAttribute('dir', 'rtl');
304
- footerBlock.setAttribute('dir', 'rtl');
305
- } else {
306
- contentBlock.removeAttribute('dir');
307
- footerBlock.removeAttribute('dir');
308
- }
366
+ __onDialogClosed() {
367
+ const nodes = this.__slottedNodes;
368
+
369
+ // Reset the list of nodes, it will be re-created.
370
+ this.__slottedNodes = [];
371
+
372
+ // Move nodes from the overlay back to the host.
373
+ nodes.forEach((node) => {
374
+ this.appendChild(node);
375
+ });
376
+ }
377
+
378
+ /** @private */
379
+ __onDomChange(addedNodes) {
380
+ // TODO: restore default element when a corresponding slotted element is removed.
381
+ // Consider creating a controller to reuse custom helper logic from FieldMixin.
382
+ addedNodes.forEach((node) => {
383
+ this.__slottedNodes.push(node);
384
+
385
+ const isElementNode = node.nodeType == Node.ELEMENT_NODE;
386
+ const slotName = isElementNode ? node.getAttribute('slot') : '';
387
+
388
+ // Handle named slots (header and buttons).
389
+ if (slotName) {
390
+ if (slotName.indexOf('button') >= 0) {
391
+ const [button] = slotName.split('-');
392
+ this[`_${button}Button`] = node;
393
+ } else if (slotName == 'header') {
394
+ this._headerNode = node;
395
+ }
396
+ } else {
397
+ const isNotEmptyText = node.nodeType == Node.TEXT_NODE && node.textContent.trim() !== '';
398
+ // Handle default slot (message element).
399
+ if (isNotEmptyText || (isElementNode && node.slot === '')) {
400
+ this._messageNode = node;
401
+ }
402
+ }
403
+ });
404
+ }
405
+
406
+ /** @private */
407
+ _cancelButtonChanged(button, oldButton) {
408
+ this.__setupSlottedButton(button, oldButton, this.__boundCancel);
409
+ }
410
+
411
+ /** @private */
412
+ _confirmButtonChanged(button, oldButton) {
413
+ this.__setupSlottedButton(button, oldButton, this.__boundConfirm);
309
414
  }
310
415
 
311
416
  /** @private */
312
- _openedChanged() {
313
- if (!this.opened) {
314
- return;
417
+ _rejectButtonChanged(button, oldButton) {
418
+ this.__setupSlottedButton(button, oldButton, this.__boundReject);
419
+ }
420
+
421
+ /** @private */
422
+ __setupSlottedButton(slottedButton, currentButton, clickListener) {
423
+ if (currentButton && currentButton.parentElement) {
424
+ currentButton.remove();
315
425
  }
316
426
 
317
- // TODO: A temporary hack as far as `vaadin-dialog` doesn't support the Polymer Template API anymore.
318
- this.$.dialog.$.overlay.template = this.$.dialogTemplate;
427
+ slottedButton.addEventListener('click', clickListener);
428
+ }
319
429
 
320
- const overlay = this.$.dialog.$.overlay;
430
+ /** @private */
431
+ __updateCancelButton(button, cancelText, cancelTheme, showCancel) {
432
+ if (button) {
433
+ button.textContent = cancelText;
434
+ button.setAttribute('theme', cancelTheme);
435
+ button.toggleAttribute('hidden', !showCancel);
436
+ }
437
+ }
321
438
 
322
- Array.from(this.childNodes).forEach((c) => {
323
- const newChild = overlay.$.content.appendChild(c);
324
- if (newChild.getAttribute && newChild.getAttribute('slot') == 'confirm-button' && newChild.focus) {
325
- this._confirmButton = newChild;
326
- }
327
- });
439
+ /** @private */
440
+ __updateConfirmButton(button, confirmText, confirmTheme) {
441
+ if (button) {
442
+ button.textContent = confirmText;
443
+ button.setAttribute('theme', confirmTheme);
444
+ }
445
+ }
328
446
 
329
- this.__toggleContentRTL(this.__isRTL);
447
+ /** @private */
448
+ __updateHeaderNode(headerNode, header) {
449
+ // Only update text content for the default header node.
450
+ if (headerNode && headerNode === this.__defaultHeader) {
451
+ headerNode.textContent = header;
452
+ }
453
+ }
330
454
 
331
- requestAnimationFrame(() => {
332
- const confirmButton = this._confirmButton || overlay.content.querySelector('#confirm');
333
- confirmButton.focus();
455
+ /** @private */
456
+ __updateMessageNode(messageNode, message) {
457
+ // Only update text content for the default message node.
458
+ if (messageNode && messageNode === this.__defaultMessage) {
459
+ messageNode.textContent = message;
460
+ }
461
+ }
334
462
 
335
- const { height } = getComputedStyle(overlay.content.querySelector('[part=footer]'));
336
- this.$.dialog.$.overlay.style.setProperty('--_vaadin-confirm-dialog-footer-height', height);
337
- });
463
+ /** @private */
464
+ __updateRejectButton(button, rejectText, rejectTheme, showReject) {
465
+ if (button) {
466
+ button.textContent = rejectText;
467
+ button.setAttribute('theme', rejectTheme);
468
+ button.toggleAttribute('hidden', !showReject);
469
+ }
338
470
  }
339
471
 
340
472
  /** @private */
@@ -379,7 +511,7 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
379
511
 
380
512
  /** @private */
381
513
  _setDimensionIfAttached(name, value) {
382
- if (this.$ && this.$.dialog) {
514
+ if (this._overlayElement) {
383
515
  this._setDimension(name, value);
384
516
  } else {
385
517
  this._dimensions = this._dimensions || {};
@@ -389,7 +521,7 @@ class ConfirmDialog extends ElementMixin(ThemableMixin(PolymerElement)) {
389
521
 
390
522
  /** @private */
391
523
  _setDimension(name, value) {
392
- this.$.dialog.$.overlay.style.setProperty(`--_vaadin-confirm-dialog-content-${name}`, value);
524
+ this._overlayElement.style.setProperty(`--_vaadin-confirm-dialog-content-${name}`, value);
393
525
  }
394
526
 
395
527
  /**
@@ -3,30 +3,10 @@ import '@vaadin/vaadin-lumo-styles/spacing.js';
3
3
  import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
4
4
 
5
5
  registerStyles(
6
- 'vaadin-dialog-overlay',
6
+ 'vaadin-confirm-dialog-overlay',
7
7
  css`
8
- :host([theme~='_vaadin-confirm-dialog-dialog-overlay-theme']) [part='content'] {
9
- height: auto;
10
- box-sizing: content-box;
11
- }
12
- `,
13
- { moduleId: 'lumo-confirm-dialog-overlay' }
14
- );
15
-
16
- registerStyles(
17
- 'vaadin-confirm-dialog',
18
- css`
19
- #content {
20
- height: calc(
21
- var(--_vaadin-confirm-dialog-content-height) - var(--_vaadin-confirm-dialog-footer-height) - var(--lumo-space-s)
22
- );
23
- width: var(--_vaadin-confirm-dialog-content-width);
24
- }
25
-
26
- [part='header'],
27
- .header {
28
- margin-top: var(--lumo-space-s);
29
- margin-bottom: var(--lumo-space-m);
8
+ [part='header'] ::slotted(h3) {
9
+ margin-top: 0 !important;
30
10
  }
31
11
 
32
12
  [part='message'] {
@@ -45,33 +25,20 @@ registerStyles(
45
25
  background-color: var(--lumo-contrast-5pct);
46
26
  }
47
27
 
48
- [part='footer'] div {
28
+ [part='footer'] > * {
49
29
  margin-top: var(--lumo-space-s);
50
30
  margin-bottom: var(--lumo-space-s);
51
31
  }
52
32
 
53
- vaadin-button[theme~='tertiary'] {
33
+ ::slotted([slot$='button'][theme~='tertiary']) {
54
34
  padding-left: var(--lumo-space-s);
55
35
  padding-right: var(--lumo-space-s);
56
36
  }
57
37
 
58
- .cancel-button {
38
+ [part='cancel-button'] {
59
39
  flex-grow: 1;
60
40
  }
61
41
 
62
- :not([dir='rtl']) > .cancel-button {
63
- margin-left: calc(var(--lumo-space-s) * -1);
64
- }
65
-
66
- :not([dir='rtl']) > .confirm-button {
67
- margin-right: calc(var(--lumo-space-s) * -1);
68
- }
69
-
70
- :not([dir='rtl']) > .reject-button,
71
- :not([dir='rtl']) > .confirm-button {
72
- margin-left: var(--lumo-space-s);
73
- }
74
-
75
42
  @media (max-width: 360px) {
76
43
  [part='footer'] {
77
44
  flex-direction: column-reverse;
@@ -81,35 +48,48 @@ registerStyles(
81
48
  margin: var(--lumo-space-xs) calc(var(--lumo-space-l) / -2) calc(var(--lumo-space-xs) * -1);
82
49
  }
83
50
 
84
- [part='footer'] vaadin-button,
85
- [part='footer'] ::slotted(*) {
51
+ ::slotted([slot$='button']) {
86
52
  width: 100%;
87
53
  margin-top: var(--lumo-space-xs);
88
54
  margin-bottom: var(--lumo-space-xs);
89
55
  }
90
56
 
91
- [part='footer'] .confirm-button {
57
+ [part='confirm-button'] {
92
58
  margin-top: var(--lumo-space-s);
93
59
  }
94
60
 
95
- [part='footer'] .cancel-button {
61
+ [part='cancel-button'] {
96
62
  margin-bottom: var(--lumo-space-s);
97
63
  }
98
64
  }
99
65
 
100
- /* RTL specific styles */
101
- [dir='rtl'] > .cancel-button {
66
+ /* LTR styles */
67
+ :host(:not([dir='rtl'])) [part='cancel-button'] {
68
+ margin-left: calc(var(--lumo-space-s) * -1);
69
+ }
70
+
71
+ :host(:not([dir='rtl'])) [part='confirm-button'] {
102
72
  margin-right: calc(var(--lumo-space-s) * -1);
73
+ margin-left: var(--lumo-space-s);
103
74
  }
104
75
 
105
- [dir='rtl'] > .confirm-button {
76
+ :host(:not([dir='rtl'])) [part='reject-button'] {
77
+ margin-left: var(--lumo-space-s);
78
+ }
79
+
80
+ /* RTL styles */
81
+ :host([dir='rtl']) [part='cancel-button'] {
82
+ margin-right: calc(var(--lumo-space-s) * -1);
83
+ }
84
+
85
+ :host([dir='rtl']) [part='confirm-button'] {
86
+ margin-right: var(--lumo-space-s);
106
87
  margin-left: calc(var(--lumo-space-s) * -1);
107
88
  }
108
89
 
109
- [dir='rtl'] > .reject-button,
110
- [dir='rtl'] > .confirm-button {
90
+ :host([dir='rtl']) [part='reject-button'] {
111
91
  margin-right: var(--lumo-space-s);
112
92
  }
113
93
  `,
114
- { moduleId: 'lumo-confirm-dialog' }
94
+ { moduleId: 'lumo-confirm-dialog-overlay' }
115
95
  );
@@ -1,29 +1,20 @@
1
1
  import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
2
2
 
3
3
  registerStyles(
4
- 'vaadin-dialog-overlay',
4
+ 'vaadin-confirm-dialog-overlay',
5
5
  css`
6
- :host([theme~='_vaadin-confirm-dialog-dialog-overlay-theme']) [part='overlay'] {
6
+ [part='overlay'] {
7
7
  max-width: 100%;
8
8
  min-width: 0;
9
9
  }
10
10
 
11
- :host([theme~='_vaadin-confirm-dialog-dialog-overlay-theme']) [part='content'] {
11
+ [part='content'] {
12
12
  padding: 8px 24px;
13
13
  min-width: 0;
14
- height: auto;
15
- box-sizing: content-box;
16
14
  }
17
- `,
18
- { moduleId: 'material-confirm-dialog-overlay' }
19
- );
20
15
 
21
- registerStyles(
22
- 'vaadin-confirm-dialog',
23
- css`
24
- #content {
25
- height: calc(var(--_vaadin-confirm-dialog-content-height) - var(--_vaadin-confirm-dialog-footer-height) - 39px);
26
- width: var(--_vaadin-confirm-dialog-content-width);
16
+ [part='header'] ::slotted(h3) {
17
+ margin-top: 0.75em !important;
27
18
  }
28
19
 
29
20
  [part='message'] {
@@ -40,50 +31,44 @@ registerStyles(
40
31
  margin-right: -16px;
41
32
  }
42
33
 
43
- [part='footer']:not([dir='rtl']) div:nth-child(-n + 2) vaadin-button,
44
- [part='footer']:not([dir='rtl']) div:nth-child(-n + 2) ::slotted(*) {
34
+ /* LTR styles */
35
+ :host(:not([dir='rtl'])) ::slotted([slot$='button']:not([slot^='confirm'])) {
45
36
  margin-right: 8px;
46
37
  }
47
38
 
39
+ /* RTL styles */
40
+ :host([dir='rtl']) [part='message'] {
41
+ margin-left: 24px;
42
+ margin-right: 0;
43
+ }
44
+
45
+ :host([dir='rtl']) [part='footer'] {
46
+ margin-left: -16px;
47
+ margin-right: 0;
48
+ }
49
+
50
+ :host([dir='rtl']) ::slotted([slot$='button']:not([slot^='confirm'])) {
51
+ margin-left: 8px;
52
+ }
53
+
48
54
  @media (max-width: 360px) {
49
55
  [part='footer'] {
50
56
  flex-direction: column-reverse;
51
57
  align-items: flex-end;
52
58
  }
53
59
 
54
- [part='footer'] div:nth-child(-n + 2) vaadin-button,
55
- [part='footer'] div:nth-child(-n + 2) ::slotted(*) {
60
+ ::slotted([slot$='button']:not([slot^='confirm'])) {
56
61
  margin-top: 8px;
57
- margin-right: 0;
58
62
  }
59
63
 
60
- [part='footer'] div:nth-last-child(1) vaadin-button,
61
- [part='footer'] div:nth-last-child(1) ::slotted(*) {
62
- margin-top: 8px;
64
+ :host(:not([dir='rtl'])) ::slotted([slot$='button']:not([slot^='confirm'])) {
65
+ margin-right: 0;
63
66
  }
64
67
 
65
- /* RTL specific styles */
66
- [part='footer'][dir='rtl'] div:nth-child(-n + 2) vaadin-button,
67
- [part='footer'][dir='rtl'] div:nth-child(-n + 2) ::slotted(*) {
68
+ :host([dir='rtl']) ::slotted([slot$='button']:not([slot^='confirm'])) {
68
69
  margin-left: 0;
69
70
  }
70
71
  }
71
-
72
- /* RTL specific styles */
73
- [dir='rtl'] > [part='message'] {
74
- margin-left: 24px;
75
- margin-right: 0;
76
- }
77
-
78
- [part='footer'][dir='rtl'] {
79
- margin-left: -16px;
80
- margin-right: 0;
81
- }
82
-
83
- [part='footer'][dir='rtl'] div:nth-child(-n + 2) vaadin-button,
84
- [part='footer'][dir='rtl'] div:nth-child(-n + 2) ::slotted(*) {
85
- margin-left: 8px;
86
- }
87
72
  `,
88
- { moduleId: 'material-confirm-dialog' }
73
+ { moduleId: 'material-confirm-dialog-overlay' }
89
74
  );