Skip to content

Commit ca07d6f

Browse files
authored
refactor!: update confirm dialog overlay to use native popover (#9776)
1 parent d8fccce commit ca07d6f

File tree

11 files changed

+260
-206
lines changed

11 files changed

+260
-206
lines changed

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

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const ConfirmDialogMixin = (superClass) =>
3737
*/
3838
opened: {
3939
type: Boolean,
40+
reflectToAttribute: true,
4041
value: false,
4142
notify: true,
4243
sync: true,
@@ -207,7 +208,7 @@ export const ConfirmDialogMixin = (superClass) =>
207208
'__updateHeaderNode(_headerNode, header)',
208209
'__updateMessageNodes(_messageNodes, message)',
209210
'__updateRejectButton(_rejectButton, rejectText, rejectTheme, rejectButtonVisible)',
210-
'__accessibleDescriptionRefChanged(_overlayElement, _messageNodes, accessibleDescriptionRef)',
211+
'__accessibleDescriptionRefChanged(_messageNodes, accessibleDescriptionRef)',
211212
];
212213
}
213214

@@ -250,6 +251,8 @@ export const ConfirmDialogMixin = (superClass) =>
250251
ready() {
251252
super.ready();
252253

254+
this.role = 'alertdialog';
255+
253256
this._headerController = new SlotController(this, 'header', 'h3', {
254257
initializer: (node) => {
255258
this._headerNode = node;
@@ -293,46 +296,43 @@ export const ConfirmDialogMixin = (superClass) =>
293296
}
294297

295298
/** @protected */
296-
__onDialogOpened() {
297-
const overlay = this._overlayElement;
299+
updated(props) {
300+
super.updated(props);
298301

299-
// Teleport slotted nodes to the overlay element.
300-
this.__slottedNodes.forEach((node) => {
301-
overlay.appendChild(node);
302-
});
302+
if (props.has('header')) {
303+
this.ariaLabel = this.header || 'confirmation';
304+
}
305+
}
303306

304-
const confirmButton = overlay.querySelector('[slot="confirm-button"]');
305-
if (confirmButton) {
306-
confirmButton.focus();
307+
/** @protected */
308+
__onDialogOpened() {
309+
if (this._confirmButton) {
310+
this._confirmButton.focus();
307311
}
308312
}
309313

310314
/** @protected */
311315
__onDialogClosed() {
312-
// Move nodes from the overlay back to the host.
313-
this.__slottedNodes.forEach((node) => {
314-
this.appendChild(node);
315-
});
316316
this.dispatchEvent(new CustomEvent('closed'));
317317
}
318318

319319
/** @private */
320-
__accessibleDescriptionRefChanged(overlay, messageNodes, accessibleDescriptionRef) {
321-
if (!overlay || !messageNodes) {
320+
__accessibleDescriptionRefChanged(messageNodes, accessibleDescriptionRef) {
321+
if (!messageNodes) {
322322
return;
323323
}
324324

325325
if (accessibleDescriptionRef) {
326-
overlay.removeAttribute('aria-description');
327-
setAriaIDReference(overlay, 'aria-describedby', {
326+
this.removeAttribute('aria-description');
327+
setAriaIDReference(this, 'aria-describedby', {
328328
newId: accessibleDescriptionRef,
329329
oldId: this.__oldAccessibleDescriptionRef,
330330
fromUser: true,
331331
});
332332
} else {
333-
overlay.removeAttribute('aria-describedby');
333+
this.removeAttribute('aria-describedby');
334334
const ariaDescription = messageNodes.map((node) => node.textContent.trim()).join(' ');
335-
overlay.setAttribute('aria-description', ariaDescription);
335+
this.setAttribute('aria-description', ariaDescription);
336336
}
337337

338338
this.__oldAccessibleDescriptionRef = accessibleDescriptionRef;

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,40 @@ class ConfirmDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMi
8282
this.setAttribute('has-header', '');
8383
this.setAttribute('has-footer', '');
8484
}
85+
86+
/**
87+
* @protected
88+
* @override
89+
*/
90+
_attachOverlay() {
91+
this.showPopover();
92+
}
93+
94+
/**
95+
* @protected
96+
* @override
97+
*/
98+
_detachOverlay() {
99+
this.hidePopover();
100+
}
101+
102+
/**
103+
* Override method from OverlayFocusMixin to use owner as content root
104+
* @protected
105+
* @override
106+
*/
107+
get _contentRoot() {
108+
return this.owner;
109+
}
110+
111+
/**
112+
* Override method from OverlayFocusMixin to use owner as modal root
113+
* @protected
114+
* @override
115+
*/
116+
get _modalRoot() {
117+
return this.owner;
118+
}
85119
}
86120

87121
defineCustomElement(ConfirmDialogOverlay);

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@ export * from './vaadin-confirm-dialog-mixin.js';
2020
*
2121
* ### Styling
2222
*
23-
* The `<vaadin-confirm-dialog>` is not themable. Apply styles to `<vaadin-confirm-dialog-overlay>`
24-
* component and use its shadow parts for styling.
25-
* See [`<vaadin-overlay>`](#/elements/vaadin-overlay) for the overlay styling documentation.
26-
*
27-
* In addition to `<vaadin-overlay>` parts, the following parts are available for theming:
23+
* The following shadow DOM parts are available for styling:
2824
*
2925
* Part name | Description
3026
* -----------------|-------------------------------------------
27+
* `backdrop` | Backdrop of the overlay
28+
* `overlay` | The overlay container
29+
* `content` | The overlay content
3130
* `header` | The header element wrapper
3231
* `message` | The message element wrapper
3332
* `footer` | The footer element that wraps the buttons
@@ -36,8 +35,6 @@ export * from './vaadin-confirm-dialog-mixin.js';
3635
* `reject-button` | The "Reject" button wrapper
3736
*
3837
* Use `confirmTheme`, `cancelTheme` and `rejectTheme` properties to customize buttons theme.
39-
* Also, the `theme` attribute value set on `<vaadin-confirm-dialog>` is propagated to the
40-
* `<vaadin-confirm-dialog-overlay>` component.
4138
*
4239
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
4340
*

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ import { ConfirmDialogMixin } from './vaadin-confirm-dialog-mixin.js';
2424
*
2525
* ### Styling
2626
*
27-
* The `<vaadin-confirm-dialog>` is not themable. Apply styles to `<vaadin-confirm-dialog-overlay>`
28-
* component and use its shadow parts for styling.
29-
* See [`<vaadin-overlay>`](#/elements/vaadin-overlay) for the overlay styling documentation.
30-
*
31-
* In addition to `<vaadin-overlay>` parts, the following parts are available for theming:
27+
* The following shadow DOM parts are available for styling:
3228
*
3329
* Part name | Description
3430
* -----------------|-------------------------------------------
31+
* `backdrop` | Backdrop of the overlay
32+
* `overlay` | The overlay container
33+
* `content` | The overlay content
3534
* `header` | The header element wrapper
3635
* `message` | The message element wrapper
3736
* `footer` | The footer element that wraps the buttons
@@ -40,8 +39,6 @@ import { ConfirmDialogMixin } from './vaadin-confirm-dialog-mixin.js';
4039
* `reject-button` | The "Reject" button wrapper
4140
*
4241
* Use `confirmTheme`, `cancelTheme` and `rejectTheme` properties to customize buttons theme.
43-
* Also, the `theme` attribute value set on `<vaadin-confirm-dialog>` is propagated to the
44-
* `<vaadin-confirm-dialog-overlay>` component.
4542
*
4643
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
4744
*
@@ -79,6 +76,12 @@ class ConfirmDialog extends ConfirmDialogMixin(ElementMixin(ThemePropertyMixin(P
7976
[hidden] {
8077
display: none !important;
8178
}
79+
80+
:host([opened]),
81+
:host([opening]),
82+
:host([closing]) {
83+
display: contents !important;
84+
}
8285
`;
8386
}
8487

@@ -87,30 +90,28 @@ class ConfirmDialog extends ConfirmDialogMixin(ElementMixin(ThemePropertyMixin(P
8790
return html`
8891
<vaadin-confirm-dialog-overlay
8992
id="overlay"
90-
role="alertdialog"
93+
popover="manual"
9194
.owner="${this}"
9295
.opened="${this.opened}"
9396
theme="${ifDefined(this._theme)}"
94-
.ariaLabel="${this.header || 'confirmation'}"
9597
.cancelButtonVisible="${this.cancelButtonVisible}"
9698
.rejectButtonVisible="${this.rejectButtonVisible}"
9799
with-backdrop
98100
restore-focus-on-close
99101
focus-trap
102+
exportparts="backdrop, overlay, header, content, message, footer, cancel-button, confirm-button, reject-button"
100103
@opened-changed="${this._onOpenedChanged}"
101104
@vaadin-overlay-open="${this.__onDialogOpened}"
102105
@vaadin-overlay-closed="${this.__onDialogClosed}"
103106
@vaadin-overlay-outside-click="${this._onOverlayOutsideClick}"
104107
@vaadin-overlay-escape-press="${this._onOverlayEscapePress}"
105-
></vaadin-confirm-dialog-overlay>
106-
107-
<div hidden>
108-
<slot name="header"></slot>
108+
>
109+
<slot name="header" slot="header"></slot>
109110
<slot></slot>
110-
<slot name="cancel-button"></slot>
111-
<slot name="reject-button"></slot>
112-
<slot name="confirm-button"></slot>
113-
</div>
111+
<slot name="cancel-button" slot="cancel-button"></slot>
112+
<slot name="reject-button" slot="reject-button"></slot>
113+
<slot name="confirm-button" slot="confirm-button"></slot>
114+
</vaadin-confirm-dialog-overlay>
114115
`;
115116
}
116117

0 commit comments

Comments
 (0)