Skip to content

Commit 4074e7e

Browse files
authored
refactor!: update confirm-dialog to not use dialog extension (#9736)
1 parent 0c53ae1 commit 4074e7e

File tree

11 files changed

+165
-208
lines changed

11 files changed

+165
-208
lines changed

packages/confirm-dialog/src/vaadin-confirm-dialog-mixin.d.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
66
import type { Constructor } from '@open-wc/dedupe-mixin';
7+
import type { OverlayClassMixinClass } from '@vaadin/component-base/src/overlay-class-mixin.js';
8+
import type { DialogSizeMixinClass } from '@vaadin/dialog/src/vaadin-dialog-size-mixin.js';
79

810
/*
911
* Fired when the `opened` property changes.
@@ -31,7 +33,7 @@ export type ConfirmDialogEventMap = ConfirmDialogCustomEventMap & HTMLElementEve
3133

3234
export declare function ConfirmDialogMixin<T extends Constructor<HTMLElement>>(
3335
base: T,
34-
): Constructor<ConfirmDialogMixinClass> & T;
36+
): Constructor<ConfirmDialogMixinClass> & Constructor<DialogSizeMixinClass> & Constructor<OverlayClassMixinClass> & T;
3537

3638
export declare class ConfirmDialogMixinClass {
3739
/**
@@ -121,24 +123,4 @@ export declare class ConfirmDialogMixinClass {
121123
* @attr {string} cancel-theme
122124
*/
123125
cancelTheme: string;
124-
125-
/**
126-
* A space-delimited list of CSS class names
127-
* to set on the underlying overlay element.
128-
*
129-
* @attr {string} overlay-class
130-
*/
131-
overlayClass: string;
132-
133-
/**
134-
* Set the width of the overlay.
135-
* If a unitless number is provided, pixels are assumed.
136-
*/
137-
width: string | null;
138-
139-
/**
140-
* Set the height of the overlay.
141-
* If a unitless number is provided, pixels are assumed.
142-
*/
143-
height: string | null;
144126
}

packages/confirm-dialog/src/vaadin-confirm-dialog-mixin.js

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
66
import { setAriaIDReference } from '@vaadin/a11y-base/src/aria-id-reference.js';
7+
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
78
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
89
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
10+
import { DialogSizeMixin } from '@vaadin/dialog/src/vaadin-dialog-size-mixin.js';
911

1012
/**
1113
* @polymerMixin
14+
* @mixes DialogSizeMixin
15+
* @mixes OverlayClassMixin
1216
*/
1317
export const ConfirmDialogMixin = (superClass) =>
14-
class ConfirmDialogMixinClass extends superClass {
18+
class ConfirmDialogMixinClass extends OverlayClassMixin(DialogSizeMixin(superClass)) {
1519
static get properties() {
1620
return {
1721
/**
@@ -154,32 +158,6 @@ export const ConfirmDialogMixin = (superClass) =>
154158
value: 'tertiary',
155159
},
156160

157-
/**
158-
* A space-delimited list of CSS class names
159-
* to set on the underlying overlay element.
160-
*
161-
* @attr {string} overlay-class
162-
*/
163-
overlayClass: {
164-
type: String,
165-
},
166-
167-
/**
168-
* Set the height of the overlay.
169-
* If a unitless number is provided, pixels are assumed.
170-
*/
171-
height: {
172-
type: String,
173-
},
174-
175-
/**
176-
* Set the width of the overlay.
177-
* If a unitless number is provided, pixels are assumed.
178-
*/
179-
width: {
180-
type: String,
181-
},
182-
183161
/**
184162
* A reference to the "Cancel" button which will be teleported to the overlay.
185163
* @private
@@ -213,15 +191,6 @@ export const ConfirmDialogMixin = (superClass) =>
213191
value: () => [],
214192
},
215193

216-
/**
217-
* A reference to the overlay element.
218-
* @private
219-
*/
220-
_overlayElement: {
221-
type: Object,
222-
sync: true,
223-
},
224-
225194
/**
226195
* A reference to the "Reject" button which will be teleported to the overlay.
227196
* @private
@@ -255,6 +224,29 @@ export const ConfirmDialogMixin = (superClass) =>
255224
return [this._headerNode, ...this._messageNodes, this._cancelButton, this._confirmButton, this._rejectButton];
256225
}
257226

227+
/** @protected */
228+
connectedCallback() {
229+
super.connectedCallback();
230+
// Restore opened state if overlay was opened when disconnecting
231+
if (this.__restoreOpened) {
232+
this.opened = true;
233+
}
234+
}
235+
236+
/** @protected */
237+
disconnectedCallback() {
238+
super.disconnectedCallback();
239+
// Automatically close the overlay when dialog is removed from DOM
240+
// Using a timeout to avoid toggling opened state, and dispatching change
241+
// events, when just moving the dialog in the DOM
242+
setTimeout(() => {
243+
if (!this.isConnected) {
244+
this.__restoreOpened = this.opened;
245+
this.opened = false;
246+
}
247+
});
248+
}
249+
258250
/** @protected */
259251
ready() {
260252
super.ready();
@@ -304,20 +296,10 @@ export const ConfirmDialogMixin = (superClass) =>
304296
});
305297
this.addController(this._confirmController);
306298

307-
this._overlayElement = this.$.dialog.$.overlay;
308-
309-
this._initOverlay(this._overlayElement);
299+
this._overlayElement = this.$.overlay;
310300
}
311301

312302
/** @protected */
313-
_initOverlay(overlay) {
314-
overlay.addEventListener('vaadin-overlay-escape-press', this._escPressed.bind(this));
315-
overlay.addEventListener('vaadin-overlay-open', () => this.__onDialogOpened());
316-
overlay.addEventListener('vaadin-overlay-closed', () => this.__onDialogClosed());
317-
overlay.setAttribute('role', 'alertdialog');
318-
}
319-
320-
/** @private */
321303
__onDialogOpened() {
322304
const overlay = this._overlayElement;
323305

@@ -332,7 +314,7 @@ export const ConfirmDialogMixin = (superClass) =>
332314
}
333315
}
334316

335-
/** @private */
317+
/** @protected */
336318
__onDialogClosed() {
337319
// Move nodes from the overlay back to the host.
338320
this.__slottedNodes.forEach((node) => {
@@ -425,13 +407,20 @@ export const ConfirmDialogMixin = (superClass) =>
425407
}
426408
}
427409

428-
/** @private */
429-
_escPressed(event) {
430-
if (!event.defaultPrevented) {
410+
/** @protected */
411+
_onOverlayEscapePress(event) {
412+
if (this.noCloseOnEsc) {
413+
event.preventDefault();
414+
} else {
431415
this.__cancel();
432416
}
433417
}
434418

419+
/** @protected */
420+
_onOverlayOutsideClick(event) {
421+
event.preventDefault();
422+
}
423+
435424
/** @private */
436425
__confirm() {
437426
this.dispatchEvent(new CustomEvent('confirm'));
@@ -450,11 +439,6 @@ export const ConfirmDialogMixin = (superClass) =>
450439
this.opened = false;
451440
}
452441

453-
/** @private */
454-
_getAriaLabel(header) {
455-
return header || 'confirmation';
456-
}
457-
458442
/**
459443
* Fired when the confirm dialog is closed.
460444
*

packages/confirm-dialog/src/vaadin-confirm-dialog-overlay.js

Lines changed: 1 addition & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,13 @@
33
* Copyright (c) 2018 - 2025 Vaadin Ltd.
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
6-
import { css, html, LitElement } from 'lit';
7-
import { ifDefined } from 'lit/directives/if-defined.js';
6+
import { html, LitElement } from 'lit';
87
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
98
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
10-
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
119
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
12-
import { DialogBaseMixin } from '@vaadin/dialog/src/vaadin-dialog-base-mixin.js';
13-
import { DialogSizeMixin } from '@vaadin/dialog/src/vaadin-dialog-size-mixin.js';
1410
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
1511
import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
1612
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
17-
import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
1813
import { confirmDialogOverlayStyles } from './styles/vaadin-confirm-dialog-overlay-core-styles.js';
1914

2015
/**
@@ -90,70 +85,3 @@ class ConfirmDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMi
9085
}
9186

9287
defineCustomElement(ConfirmDialogOverlay);
93-
94-
/**
95-
* An element used internally by `<vaadin-confirm-dialog>`. Not intended to be used separately.
96-
* @private
97-
*/
98-
class ConfirmDialogDialog extends DialogSizeMixin(
99-
DialogBaseMixin(OverlayClassMixin(ThemePropertyMixin(PolylitMixin(LitElement)))),
100-
) {
101-
static get is() {
102-
return 'vaadin-confirm-dialog-dialog';
103-
}
104-
105-
static get styles() {
106-
return css`
107-
:host {
108-
display: none;
109-
}
110-
`;
111-
}
112-
113-
static get properties() {
114-
return {
115-
/**
116-
* Set the `aria-label` attribute for assistive technologies like
117-
* screen readers. An empty string value for this property (the
118-
* default) means that the `aria-label` attribute is not present.
119-
*/
120-
ariaLabel: {
121-
type: String,
122-
value: '',
123-
},
124-
125-
cancelButtonVisible: {
126-
type: Boolean,
127-
},
128-
129-
rejectButtonVisible: {
130-
type: Boolean,
131-
},
132-
};
133-
}
134-
135-
/** @protected */
136-
render() {
137-
return html`
138-
<vaadin-confirm-dialog-overlay
139-
id="overlay"
140-
.owner="${this}"
141-
.opened="${this.opened}"
142-
@opened-changed="${this._onOverlayOpened}"
143-
@mousedown="${this._bringOverlayToFront}"
144-
@touchstart="${this._bringOverlayToFront}"
145-
theme="${ifDefined(this._theme)}"
146-
.modeless="${this.modeless}"
147-
.withBackdrop="${!this.modeless}"
148-
?resizable="${this.resizable}"
149-
aria-label="${this.ariaLabel}"
150-
.cancelButtonVisible="${this.cancelButtonVisible}"
151-
.rejectButtonVisible="${this.rejectButtonVisible}"
152-
restore-focus-on-close
153-
focus-trap
154-
></vaadin-confirm-dialog-overlay>
155-
`;
156-
}
157-
}
158-
159-
defineCustomElement(ConfirmDialogDialog);

packages/confirm-dialog/src/vaadin-confirm-dialog.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,24 @@ class ConfirmDialog extends ConfirmDialogMixin(ElementMixin(ThemePropertyMixin(P
8585
/** @protected */
8686
render() {
8787
return html`
88-
<vaadin-confirm-dialog-dialog
89-
id="dialog"
88+
<vaadin-confirm-dialog-overlay
89+
id="overlay"
90+
role="alertdialog"
91+
.owner="${this}"
9092
.opened="${this.opened}"
91-
.overlayClass="${this.overlayClass}"
93+
theme="${ifDefined(this._theme)}"
94+
.ariaLabel="${this.header || 'confirmation'}"
9295
.cancelButtonVisible="${this.cancelButtonVisible}"
9396
.rejectButtonVisible="${this.rejectButtonVisible}"
94-
aria-label="${this.header || 'confirmation'}"
95-
theme="${ifDefined(this._theme)}"
96-
no-close-on-outside-click
97-
.noCloseOnEsc="${this.noCloseOnEsc}"
98-
.height="${this.height}"
99-
.width="${this.width}"
97+
with-backdrop
98+
restore-focus-on-close
99+
focus-trap
100100
@opened-changed="${this._onOpenedChanged}"
101-
></vaadin-confirm-dialog-dialog>
101+
@vaadin-overlay-open="${this.__onDialogOpened}"
102+
@vaadin-overlay-closed="${this.__onDialogClosed}"
103+
@vaadin-overlay-outside-click="${this._onOverlayOutsideClick}"
104+
@vaadin-overlay-escape-press="${this._onOverlayEscapePress}"
105+
></vaadin-confirm-dialog-overlay>
102106
103107
<div hidden>
104108
<slot name="header"></slot>

0 commit comments

Comments
 (0)