@vaadin/app-layout 22.0.1 → 23.0.0-alpha3
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/app-layout",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "23.0.0-alpha3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -32,19 +32,18 @@
|
|
|
32
32
|
"polymer"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@polymer/iron-resizable-behavior": "^3.0.0",
|
|
36
35
|
"@polymer/polymer": "^3.0.0",
|
|
37
|
-
"@vaadin/button": "
|
|
38
|
-
"@vaadin/component-base": "
|
|
39
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
40
|
-
"@vaadin/vaadin-material-styles": "
|
|
41
|
-
"@vaadin/vaadin-themable-mixin": "
|
|
36
|
+
"@vaadin/button": "23.0.0-alpha3",
|
|
37
|
+
"@vaadin/component-base": "23.0.0-alpha3",
|
|
38
|
+
"@vaadin/vaadin-lumo-styles": "23.0.0-alpha3",
|
|
39
|
+
"@vaadin/vaadin-material-styles": "23.0.0-alpha3",
|
|
40
|
+
"@vaadin/vaadin-themable-mixin": "23.0.0-alpha3"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@esm-bundle/chai": "^4.3.4",
|
|
45
|
-
"@vaadin/tabs": "
|
|
44
|
+
"@vaadin/tabs": "23.0.0-alpha3",
|
|
46
45
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
47
46
|
"sinon": "^9.2.1"
|
|
48
47
|
},
|
|
49
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "490037919a9e054cc002c1b3be0c94a1603e1a44"
|
|
50
49
|
}
|
package/src/detect-ios-navbar.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c)
|
|
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 { isIOS } from '@vaadin/component-base/src/browser-utils.js';
|
|
7
7
|
|
|
8
|
-
export
|
|
8
|
+
export function _detectIosNavbar() {
|
|
9
9
|
/* c8 ignore next 11 */
|
|
10
10
|
if (isIOS) {
|
|
11
11
|
const innerHeight = window.innerHeight;
|
|
@@ -18,7 +18,7 @@ export const _detectIosNavbar = function () {
|
|
|
18
18
|
document.documentElement.style.setProperty('--vaadin-viewport-offset-bottom', '');
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
}
|
|
21
|
+
}
|
|
22
22
|
|
|
23
23
|
_detectIosNavbar();
|
|
24
24
|
window.addEventListener('resize', _detectIosNavbar);
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c)
|
|
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
|
+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
6
7
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
7
8
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
9
|
|
|
10
|
+
export interface AppLayoutI18n {
|
|
11
|
+
drawer: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
9
14
|
/**
|
|
10
15
|
* Fired when the `drawerOpened` property changes.
|
|
11
16
|
*/
|
|
@@ -118,7 +123,29 @@ export type AppLayoutEventMap = HTMLElementEventMap & AppLayoutCustomEventMap;
|
|
|
118
123
|
* @fires {CustomEvent} overlay-changed - Fired when the `overlay` property changes.
|
|
119
124
|
* @fires {CustomEvent} primary-section-changed - Fired when the `primarySection` property changes.
|
|
120
125
|
*/
|
|
121
|
-
declare class AppLayout extends ElementMixin(ThemableMixin(HTMLElement)) {
|
|
126
|
+
declare class AppLayout extends ElementMixin(ThemableMixin(ControllerMixin(HTMLElement))) {
|
|
127
|
+
/**
|
|
128
|
+
* The object used to localize this component.
|
|
129
|
+
* To change the default localization, replace the entire
|
|
130
|
+
* `i18n` object with a custom one.
|
|
131
|
+
*
|
|
132
|
+
* To update individual properties, extend the existing i18n object as follows:
|
|
133
|
+
* ```js
|
|
134
|
+
* appLayout.i18n = {
|
|
135
|
+
* ...appLayout.i18n,
|
|
136
|
+
* drawer: 'Drawer'
|
|
137
|
+
* }
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* The object has the following structure and default values:
|
|
141
|
+
* ```
|
|
142
|
+
* {
|
|
143
|
+
* drawer: 'Drawer'
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
i18n: AppLayoutI18n;
|
|
148
|
+
|
|
122
149
|
/**
|
|
123
150
|
* Defines whether navbar or drawer will come first visually.
|
|
124
151
|
* - By default (`primary-section="navbar"`), the navbar takes the full available width and moves the drawer down.
|
package/src/vaadin-app-layout.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c)
|
|
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 './safe-area-inset.js';
|
|
7
7
|
import './detect-ios-navbar.js';
|
|
8
|
-
import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
|
|
9
|
-
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
|
|
10
8
|
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
|
11
9
|
import { afterNextRender, beforeNextRender } from '@polymer/polymer/lib/utils/render-status.js';
|
|
12
10
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
11
|
+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
13
12
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
13
|
+
import { FocusTrapController } from '@vaadin/component-base/src/focus-trap-controller.js';
|
|
14
14
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {import('./vaadin-app-layout.js').AppLayoutI18n} AppLayoutI18n
|
|
18
|
+
*/
|
|
19
|
+
|
|
16
20
|
/**
|
|
17
21
|
* `<vaadin-app-layout>` is a Web Component providing a quick and easy way to get a common application layout structure done.
|
|
18
22
|
*
|
|
@@ -103,8 +107,9 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
103
107
|
* @extends HTMLElement
|
|
104
108
|
* @mixes ElementMixin
|
|
105
109
|
* @mixes ThemableMixin
|
|
110
|
+
* @mixes ControllerMixin
|
|
106
111
|
*/
|
|
107
|
-
class AppLayout extends ElementMixin(ThemableMixin(
|
|
112
|
+
class AppLayout extends ElementMixin(ThemableMixin(ControllerMixin(PolymerElement))) {
|
|
108
113
|
static get template() {
|
|
109
114
|
return html`
|
|
110
115
|
<style>
|
|
@@ -199,16 +204,20 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
199
204
|
right: auto;
|
|
200
205
|
bottom: var(--vaadin-app-layout-navbar-offset-bottom, var(--vaadin-viewport-offset-bottom, 0));
|
|
201
206
|
left: var(--vaadin-app-layout-navbar-offset-left, 0);
|
|
202
|
-
transition: transform var(--vaadin-app-layout-transition);
|
|
207
|
+
transition: transform var(--vaadin-app-layout-transition), visibility var(--vaadin-app-layout-transition);
|
|
203
208
|
transform: translateX(-100%);
|
|
204
209
|
max-width: 90%;
|
|
205
210
|
width: 16em;
|
|
206
211
|
box-sizing: border-box;
|
|
207
212
|
padding: var(--safe-area-inset-top) 0 var(--safe-area-inset-bottom) var(--safe-area-inset-left);
|
|
208
213
|
outline: none;
|
|
214
|
+
/* The drawer should be inaccessible by the tabbing navigation when it is closed. */
|
|
215
|
+
visibility: hidden;
|
|
209
216
|
}
|
|
210
217
|
|
|
211
218
|
:host([drawer-opened]) [part='drawer'] {
|
|
219
|
+
/* The drawer should be accessible by the tabbing navigation when it is opened. */
|
|
220
|
+
visibility: visible;
|
|
212
221
|
transform: translateX(0%);
|
|
213
222
|
touch-action: manipulation;
|
|
214
223
|
}
|
|
@@ -285,7 +294,7 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
285
294
|
<slot name="navbar"></slot>
|
|
286
295
|
</div>
|
|
287
296
|
<div part="backdrop" on-click="_close" on-touchstart="_close"></div>
|
|
288
|
-
<div part="drawer" id="drawer">
|
|
297
|
+
<div part="drawer" id="drawer" on-keydown="__onDrawerKeyDown">
|
|
289
298
|
<slot name="drawer" id="drawerSlot"></slot>
|
|
290
299
|
</div>
|
|
291
300
|
<div content>
|
|
@@ -304,6 +313,39 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
304
313
|
|
|
305
314
|
static get properties() {
|
|
306
315
|
return {
|
|
316
|
+
/**
|
|
317
|
+
* The object used to localize this component.
|
|
318
|
+
* To change the default localization, replace the entire
|
|
319
|
+
* `i18n` object with a custom one.
|
|
320
|
+
*
|
|
321
|
+
* To update individual properties, extend the existing i18n object as follows:
|
|
322
|
+
* ```js
|
|
323
|
+
* appLayout.i18n = {
|
|
324
|
+
* ...appLayout.i18n,
|
|
325
|
+
* drawer: 'Drawer'
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* The object has the following structure and default values:
|
|
330
|
+
* ```
|
|
331
|
+
* {
|
|
332
|
+
* drawer: 'Drawer'
|
|
333
|
+
* }
|
|
334
|
+
* ```
|
|
335
|
+
*
|
|
336
|
+
* @type {AppLayoutI18n}
|
|
337
|
+
* @default {English/US}
|
|
338
|
+
*/
|
|
339
|
+
i18n: {
|
|
340
|
+
type: Object,
|
|
341
|
+
observer: '__i18nChanged',
|
|
342
|
+
value: () => {
|
|
343
|
+
return {
|
|
344
|
+
drawer: 'Drawer'
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
|
|
307
349
|
/**
|
|
308
350
|
* Defines whether navbar or drawer will come first visually.
|
|
309
351
|
* - By default (`primary-section="navbar"`), the navbar takes the full available width and moves the drawer down.
|
|
@@ -316,7 +358,7 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
316
358
|
value: 'navbar',
|
|
317
359
|
notify: true,
|
|
318
360
|
reflectToAttribute: true,
|
|
319
|
-
observer: '
|
|
361
|
+
observer: '__primarySectionChanged'
|
|
320
362
|
},
|
|
321
363
|
|
|
322
364
|
/**
|
|
@@ -332,7 +374,7 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
332
374
|
notify: true,
|
|
333
375
|
value: true,
|
|
334
376
|
reflectToAttribute: true,
|
|
335
|
-
observer: '
|
|
377
|
+
observer: '__drawerOpenedChanged'
|
|
336
378
|
},
|
|
337
379
|
|
|
338
380
|
/**
|
|
@@ -369,6 +411,9 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
369
411
|
this.__boundResizeListener = this._resize.bind(this);
|
|
370
412
|
this.__drawerToggleClickListener = this._drawerToggleClick.bind(this);
|
|
371
413
|
this.__closeOverlayDrawerListener = this.__closeOverlayDrawer.bind(this);
|
|
414
|
+
this.__trapFocusInDrawer = this.__trapFocusInDrawer.bind(this);
|
|
415
|
+
this.__releaseFocusFromDrawer = this.__releaseFocusFromDrawer.bind(this);
|
|
416
|
+
this.__focusTrapController = new FocusTrapController(this);
|
|
372
417
|
}
|
|
373
418
|
|
|
374
419
|
/** @protected */
|
|
@@ -402,6 +447,12 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
402
447
|
window.addEventListener('close-overlay-drawer', this.__closeOverlayDrawerListener);
|
|
403
448
|
}
|
|
404
449
|
|
|
450
|
+
/** @protected */
|
|
451
|
+
ready() {
|
|
452
|
+
super.ready();
|
|
453
|
+
this.addController(this.__focusTrapController);
|
|
454
|
+
}
|
|
455
|
+
|
|
405
456
|
/** @protected */
|
|
406
457
|
disconnectedCallback() {
|
|
407
458
|
super.disconnectedCallback();
|
|
@@ -421,29 +472,55 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
421
472
|
window.dispatchEvent(new CustomEvent('close-overlay-drawer'));
|
|
422
473
|
}
|
|
423
474
|
|
|
424
|
-
/**
|
|
425
|
-
|
|
426
|
-
|
|
475
|
+
/**
|
|
476
|
+
* A callback for the `primarySection` property observer.
|
|
477
|
+
*
|
|
478
|
+
* Ensures the property is set to its default value `navbar`
|
|
479
|
+
* whenever the new value is not one of the valid values: `navbar`, `drawer`.
|
|
480
|
+
*
|
|
481
|
+
* @param {string} value
|
|
482
|
+
* @private
|
|
483
|
+
*/
|
|
484
|
+
__primarySectionChanged(value) {
|
|
485
|
+
const isValid = ['navbar', 'drawer'].includes(value);
|
|
427
486
|
if (!isValid) {
|
|
428
487
|
this.set('primarySection', 'navbar');
|
|
429
488
|
}
|
|
430
489
|
}
|
|
431
490
|
|
|
432
|
-
/**
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
491
|
+
/**
|
|
492
|
+
* A callback for the `drawerOpened` property observer.
|
|
493
|
+
*
|
|
494
|
+
* When the drawer opens, the method ensures the drawer has a proper height and sets focus on it.
|
|
495
|
+
* As long as the drawer is open, the focus is trapped within the drawer.
|
|
496
|
+
*
|
|
497
|
+
* When the drawer closes, the method releases focus from the drawer, setting focus on the drawer toggle.
|
|
498
|
+
*
|
|
499
|
+
* @param {boolean} drawerOpened
|
|
500
|
+
* @param {boolean} oldDrawerOpened
|
|
501
|
+
* @private
|
|
502
|
+
*/
|
|
503
|
+
__drawerOpenedChanged(drawerOpened, oldDrawerOpened) {
|
|
438
504
|
if (this.overlay) {
|
|
439
|
-
if (
|
|
440
|
-
drawer.setAttribute('tabindex', 0);
|
|
441
|
-
drawer.focus();
|
|
505
|
+
if (drawerOpened) {
|
|
442
506
|
this._updateDrawerHeight();
|
|
507
|
+
this.__trapFocusInDrawer();
|
|
508
|
+
} else if (oldDrawerOpened) {
|
|
509
|
+
this.__releaseFocusFromDrawer();
|
|
443
510
|
}
|
|
444
511
|
}
|
|
512
|
+
}
|
|
445
513
|
|
|
446
|
-
|
|
514
|
+
/**
|
|
515
|
+
* A callback for the `i18n` property observer.
|
|
516
|
+
*
|
|
517
|
+
* The method ensures the drawer has ARIA attributes updated
|
|
518
|
+
* once the `i18n` property changes.
|
|
519
|
+
*
|
|
520
|
+
* @private
|
|
521
|
+
*/
|
|
522
|
+
__i18nChanged() {
|
|
523
|
+
this.__updateDrawerAriaAttributes();
|
|
447
524
|
}
|
|
448
525
|
|
|
449
526
|
/** @protected */
|
|
@@ -500,8 +577,6 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
500
577
|
const drawerRect = drawer.getBoundingClientRect();
|
|
501
578
|
|
|
502
579
|
this.style.setProperty('--_vaadin-app-layout-drawer-offset-size', drawerRect.width + 'px');
|
|
503
|
-
|
|
504
|
-
this.notifyResize();
|
|
505
580
|
}
|
|
506
581
|
|
|
507
582
|
/** @protected */
|
|
@@ -513,8 +588,7 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
513
588
|
|
|
514
589
|
/** @protected */
|
|
515
590
|
_updateOverlayMode() {
|
|
516
|
-
const overlay = this._getCustomPropertyValue('--vaadin-app-layout-drawer-overlay')
|
|
517
|
-
const drawer = this.$.drawer;
|
|
591
|
+
const overlay = this._getCustomPropertyValue('--vaadin-app-layout-drawer-overlay') === 'true';
|
|
518
592
|
|
|
519
593
|
if (!this.overlay && overlay) {
|
|
520
594
|
// Changed from not overlay to overlay
|
|
@@ -524,28 +598,105 @@ class AppLayout extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizable
|
|
|
524
598
|
|
|
525
599
|
this._setOverlay(overlay);
|
|
526
600
|
|
|
601
|
+
if (!this.overlay && this._drawerStateSaved) {
|
|
602
|
+
this.drawerOpened = this._drawerStateSaved;
|
|
603
|
+
this._drawerStateSaved = null;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
this._updateDrawerHeight();
|
|
607
|
+
this.__updateDrawerAriaAttributes();
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Updates ARIA attributes on the drawer depending on the drawer mode.
|
|
612
|
+
*
|
|
613
|
+
* - In the overlay mode, the method marks the drawer with ARIA attributes as a dialog
|
|
614
|
+
* labelled with the `i18n.drawer` property.
|
|
615
|
+
* - In the normal mode, the method removes the ARIA attributes that has been set for the overlay mode.
|
|
616
|
+
*
|
|
617
|
+
* @private
|
|
618
|
+
*/
|
|
619
|
+
__updateDrawerAriaAttributes() {
|
|
620
|
+
const drawer = this.$.drawer;
|
|
527
621
|
if (this.overlay) {
|
|
528
622
|
drawer.setAttribute('role', 'dialog');
|
|
529
623
|
drawer.setAttribute('aria-modal', 'true');
|
|
530
|
-
drawer.setAttribute('aria-label',
|
|
624
|
+
drawer.setAttribute('aria-label', this.i18n.drawer);
|
|
531
625
|
} else {
|
|
532
|
-
if (this._drawerStateSaved) {
|
|
533
|
-
this.drawerOpened = this._drawerStateSaved;
|
|
534
|
-
this._drawerStateSaved = null;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
626
|
drawer.removeAttribute('role');
|
|
538
627
|
drawer.removeAttribute('aria-modal');
|
|
539
628
|
drawer.removeAttribute('aria-label');
|
|
540
629
|
}
|
|
630
|
+
}
|
|
541
631
|
|
|
542
|
-
|
|
632
|
+
/**
|
|
633
|
+
* Returns a promise that resolves when the drawer opening/closing CSS transition ends.
|
|
634
|
+
*
|
|
635
|
+
* The method relies on the `--vaadin-app-layout-transition` CSS variable to detect whether
|
|
636
|
+
* the drawer has a CSS transition that needs to be awaited. If the CSS variable equals `none`,
|
|
637
|
+
* the promise resolves immediately.
|
|
638
|
+
*
|
|
639
|
+
* @return {Promise}
|
|
640
|
+
* @private
|
|
641
|
+
*/
|
|
642
|
+
__drawerTransitionComplete() {
|
|
643
|
+
return new Promise((resolve) => {
|
|
644
|
+
if (this._getCustomPropertyValue('--vaadin-app-layout-transition') === 'none') {
|
|
645
|
+
resolve();
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
543
648
|
|
|
544
|
-
|
|
545
|
-
|
|
649
|
+
this.$.drawer.addEventListener('transitionend', resolve, { once: true });
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/** @private */
|
|
654
|
+
async __trapFocusInDrawer() {
|
|
655
|
+
// Wait for the drawer CSS transition before focusing the drawer
|
|
656
|
+
// in order for VoiceOver to have a proper outline.
|
|
657
|
+
await this.__drawerTransitionComplete();
|
|
658
|
+
|
|
659
|
+
if (!this.drawerOpened) {
|
|
660
|
+
// The drawer has been closed during the CSS transition.
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
this.$.drawer.setAttribute('tabindex', '0');
|
|
665
|
+
this.__focusTrapController.trapFocus(this.$.drawer);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/** @private */
|
|
669
|
+
async __releaseFocusFromDrawer() {
|
|
670
|
+
// Wait for the drawer CSS transition in order to restore focus to the toggle
|
|
671
|
+
// only after `visibility` becomes `hidden`, that is, the drawer becomes inaccessible by the tabbing navigation.
|
|
672
|
+
await this.__drawerTransitionComplete();
|
|
673
|
+
|
|
674
|
+
if (this.drawerOpened) {
|
|
675
|
+
// The drawer has been opened during the CSS transition.
|
|
676
|
+
return;
|
|
546
677
|
}
|
|
547
678
|
|
|
548
|
-
|
|
679
|
+
this.__focusTrapController.releaseFocus();
|
|
680
|
+
this.$.drawer.removeAttribute('tabindex');
|
|
681
|
+
|
|
682
|
+
// Move focus to the drawer toggle when closing the drawer.
|
|
683
|
+
const toggle = this.querySelector('vaadin-drawer-toggle');
|
|
684
|
+
if (toggle) {
|
|
685
|
+
toggle.focus();
|
|
686
|
+
toggle.setAttribute('focus-ring', 'focus');
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Closes the drawer on Escape press if it has been opened in the overlay mode.
|
|
692
|
+
*
|
|
693
|
+
* @param {KeyboardEvent} event
|
|
694
|
+
* @private
|
|
695
|
+
*/
|
|
696
|
+
__onDrawerKeyDown(event) {
|
|
697
|
+
if (event.key === 'Escape' && this.overlay) {
|
|
698
|
+
this.drawerOpened = false;
|
|
699
|
+
}
|
|
549
700
|
}
|
|
550
701
|
|
|
551
702
|
/** @private */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* Copyright (c)
|
|
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 { html } from '@polymer/polymer/lib/utils/html-tag.js';
|