Skip to content

Commit 8c529b8

Browse files
authored
refactor: set aria-modal and tabindex on the confirm-dialog (#9980)
1 parent d5b6b0a commit 8c529b8

File tree

9 files changed

+68
-10
lines changed

9 files changed

+68
-10
lines changed

dev/confirm-dialog.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
</script>
1313
</head>
1414
<body>
15-
<vaadin-button class="short">Short Message</vaadin-button>
16-
<vaadin-button class="long">Long Message</vaadin-button>
15+
<section>
16+
<h3>Examples</h3>
17+
<vaadin-button class="short">Short Message</vaadin-button>
18+
<vaadin-button class="long">Long Message</vaadin-button>
19+
</section>
1720

1821
<vaadin-confirm-dialog class="short" header="Save Changes" confirm-text="Save" cancel-button-visible>
1922
Save or not?

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ export const ConfirmDialogMixin = (superClass) =>
246246
super.ready();
247247

248248
this.role = 'alertdialog';
249+
this.setAttribute('aria-modal', 'true');
250+
this.setAttribute('tabindex', '0');
249251

250252
this._headerController = new SlotController(this, 'header', 'h3', {
251253
initializer: (node) => {

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class ConfirmDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMi
4949
render() {
5050
return html`
5151
<div part="backdrop" id="backdrop" ?hidden="${!this.withBackdrop}"></div>
52-
<div part="overlay" id="overlay" tabindex="0">
52+
<div part="overlay" id="overlay">
5353
<header part="header"><slot name="header"></slot></header>
5454
<div part="content" id="content">
5555
<div part="message"><slot></slot></div>
@@ -98,6 +98,24 @@ class ConfirmDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMi
9898
get _modalRoot() {
9999
return this.owner;
100100
}
101+
102+
/**
103+
* Override method from OverlayFocusMixin to use owner as focus trap root
104+
* @protected
105+
* @override
106+
*/
107+
get _focusTrapRoot() {
108+
return this.owner;
109+
}
110+
111+
/**
112+
* Override method from OverlayFocusMixin to not set `aria-hidden`
113+
* @protected
114+
* @override
115+
*/
116+
get _useAriaHidden() {
117+
return false;
118+
}
101119
}
102120

103121
defineCustomElement(ConfirmDialogOverlay);

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,18 @@ class ConfirmDialog extends ConfirmDialogMixin(ElementMixin(ThemePropertyMixin(P
7575
:host([opened]),
7676
:host([opening]),
7777
:host([closing]) {
78-
display: contents !important;
78+
display: block !important;
79+
position: absolute;
7980
}
8081
8182
:host,
8283
:host([hidden]) {
8384
display: none !important;
8485
}
86+
87+
:host(:focus) ::part(overlay) {
88+
outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
89+
}
8590
`;
8691
}
8792

packages/confirm-dialog/test/confirm-dialog.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,15 @@ describe('vaadin-confirm-dialog', () => {
3636
});
3737

3838
['opened', 'opening', 'closing'].forEach((state) => {
39-
it(`should use display: contents when ${state} attribute is set`, () => {
39+
it(`should use display: block when ${state} attribute is set`, () => {
4040
confirm.setAttribute(state, '');
41-
expect(getComputedStyle(confirm).display).to.equal('contents');
41+
expect(getComputedStyle(confirm).display).to.equal('block');
4242
});
4343
});
4444

4545
it('should use display: none when hidden while opened', async () => {
4646
confirm.opened = true;
47+
await oneEvent(confirm.$.overlay, 'vaadin-overlay-open');
4748
confirm.hidden = true;
4849
await nextRender();
4950
expect(getComputedStyle(confirm).display).to.equal('none');

packages/confirm-dialog/test/dom/__snapshots__/confirm-dialog.test.snap.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ snapshots["vaadin-confirm-dialog host"] =
55
`<vaadin-confirm-dialog
66
aria-description="Do you want to save or discard the changes?"
77
aria-label="Unsaved changes"
8+
aria-modal="true"
89
header="Unsaved changes"
910
opened=""
1011
role="alertdialog"
12+
tabindex="0"
1113
with-backdrop=""
1214
>
1315
Do you want to save or discard the changes?
@@ -131,7 +133,6 @@ snapshots["vaadin-confirm-dialog overlay"] =
131133
<div
132134
id="overlay"
133135
part="overlay"
134-
tabindex="0"
135136
>
136137
<header part="header">
137138
<slot name="header">

packages/crud/test/dom/__snapshots__/crud.test.snap.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ snapshots["vaadin-crud host default"] =
99
<vaadin-confirm-dialog
1010
aria-description="There are unsaved changes to this item."
1111
aria-label="Discard changes"
12+
aria-modal="true"
1213
cancel-button-visible=""
1314
confirm-theme="primary"
1415
role="alertdialog"
1516
slot="confirm-cancel"
17+
tabindex="0"
1618
with-backdrop=""
1719
>
1820
<h3 slot="header">
@@ -50,10 +52,12 @@ snapshots["vaadin-crud host default"] =
5052
<vaadin-confirm-dialog
5153
aria-description="Are you sure you want to delete this item? This action cannot be undone."
5254
aria-label="Delete item"
55+
aria-modal="true"
5356
cancel-button-visible=""
5457
confirm-theme="primary error"
5558
role="alertdialog"
5659
slot="confirm-delete"
60+
tabindex="0"
5761
with-backdrop=""
5862
>
5963
<h3 slot="header">

packages/overlay/src/vaadin-overlay-focus-mixin.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,34 @@ export const OverlayFocusMixin = (superClass) =>
8080
return this;
8181
}
8282

83+
/**
84+
* Override to specify another element used as a focus trap root,
85+
* e.g. the overlay's owner element, rather than overlay part.
86+
* @protected
87+
*/
88+
get _focusTrapRoot() {
89+
return this.$.overlay;
90+
}
91+
92+
/**
93+
* Override not use a controller for setting `aria-hidden` on
94+
* elements outside the overlay, e.g. when using `aria-modal`.
95+
* @protected
96+
*/
97+
_useAriaHidden() {
98+
return true;
99+
}
100+
83101
/**
84102
* Release focus and restore focus after the overlay is closed.
85103
*
86104
* @protected
87105
*/
88106
_resetFocus() {
89107
if (this.focusTrap) {
90-
this.__ariaModalController.close();
108+
if (this._useAriaHidden) {
109+
this.__ariaModalController.close();
110+
}
91111
this.__focusTrapController.releaseFocus();
92112
}
93113

@@ -115,8 +135,10 @@ export const OverlayFocusMixin = (superClass) =>
115135
*/
116136
_trapFocus() {
117137
if (this.focusTrap) {
118-
this.__ariaModalController.showModal();
119-
this.__focusTrapController.trapFocus(this.$.overlay);
138+
if (this._useAriaHidden) {
139+
this.__ariaModalController.showModal();
140+
}
141+
this.__focusTrapController.trapFocus(this._focusTrapRoot);
120142
}
121143
}
122144

packages/rich-text-editor/test/dom/__snapshots__/rich-text-editor.test.snap.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ snapshots["vaadin-rich-text-editor host"] =
66
<vaadin-confirm-dialog
77
aria-description=""
88
aria-label="Link address"
9+
aria-modal="true"
910
cancel-button-visible=""
1011
reject-theme="error"
1112
role="alertdialog"
1213
slot="link-dialog"
14+
tabindex="0"
1315
with-backdrop=""
1416
>
1517
<vaadin-text-field style="width: 100%;">

0 commit comments

Comments
 (0)