Skip to content

Commit 485c08c

Browse files
authored
fix: app-layout and master-detail-layout safe area insets (#10483)
1 parent a8ea254 commit 485c08c

File tree

9 files changed

+161
-66
lines changed

9 files changed

+161
-66
lines changed

dev/aura.html

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6+
<meta name="mobile-web-app-capable" content="yes" />
7+
<meta name="apple-mobile-web-app-capable" content="yes" />
8+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
79
<title>Aura</title>
810
<link rel="stylesheet" href="../packages/aura/aura.css" />
911
<link rel="stylesheet" href="./aura/aura-view.css" />
@@ -30,6 +32,7 @@
3032
import '@vaadin/date-time-picker';
3133
import '@vaadin/grid';
3234
import '@vaadin/grid/src/vaadin-grid-selection-column.js';
35+
import '@vaadin/horizontal-layout';
3336
import '@vaadin/icon';
3437
import '@vaadin/master-detail-layout';
3538
import '@vaadin/menu-bar';
@@ -274,17 +277,13 @@
274277

275278
<style>
276279
html {
280+
height: calc(100% + env(safe-area-inset-top, 0px));
277281
--icon-rotate-ccw: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>');
278282
}
279283

280-
html,
281-
body,
282-
vaadin-app-layout {
284+
body {
283285
margin: 0;
284286
height: 100%;
285-
}
286-
287-
body {
288287
transition: none !important;
289288
}
290289

@@ -515,7 +514,7 @@ <h1>Dashboard</h1>
515514
<mdl-back-button></mdl-back-button>
516515
<h1>Components</h1>
517516
</header>
518-
<vaadin-scroller theme="overflow-indicator-top">
517+
<vaadin-scroller theme="overflow-indicators">
519518
<style>
520519
.components-view {
521520
container-type: inline-size;
@@ -809,6 +808,10 @@ <h5>Sizes</h5>
809808
</div>
810809
</div>
811810
</vaadin-scroller>
811+
<footer style="display: flex; justify-content: space-between">
812+
<span theme="small">20 components</span>
813+
<vaadin-button theme="small">Browse…</vaadin-button>
814+
</footer>
812815
</main>
813816
</vaadin-master-detail-layout>
814817
</vaadin-app-layout>

dev/aura/aura-view.css

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
.aura-view {
22
display: flex;
33
flex-direction: column;
4-
height: 100%;
4+
box-sizing: border-box;
5+
margin-block: calc(var(--safe-area-inset-top) * -1) calc(var(--safe-area-inset-bottom) * -1);
6+
padding-block: var(--safe-area-inset-top) var(--safe-area-inset-bottom);
7+
height: calc(100% + var(--safe-area-inset-top) + var(--safe-area-inset-bottom));
58
}
69

7-
.aura-view > :not(header, footer) {
10+
.aura-view > :not(header, footer, .aura-view-header, .aura-view-footer) {
811
flex: 1;
912
}
1013

1114
.aura-view > vaadin-scroller {
12-
padding-inline: var(--vaadin-padding-m);
15+
--vaadin-scroller-padding-inline: var(--vaadin-padding-m);
16+
}
17+
18+
.aura-view:not(:has(header, .aura-view-header)) > vaadin-scroller {
19+
padding-top: var(--safe-area-inset-top);
20+
}
21+
22+
.aura-view:not(:has(footer, .aura-view-footer)) > vaadin-scroller {
23+
padding-bottom: var(--safe-area-inset-bottom);
1324
}
1425

1526
.aura-view > :is(header, footer),
@@ -19,6 +30,30 @@
1930
align-items: center;
2031
}
2132

33+
.aura-view > header,
34+
.aura-view-header,
35+
.aura-view[slot='navbar'] > footer,
36+
.aura-view-footer[slot='navbar'] {
37+
padding-top: max(var(--vaadin-padding-m), var(--safe-area-inset-top));
38+
}
39+
40+
.aura-view[slot='navbar'] > :is(header, footer),
41+
:is(.aura-view-header, .aura-view-footer)[slot='navbar'],
42+
.aura-view[slot='drawer'] > header,
43+
.aura-view-header[slot='drawer'] {
44+
margin-top: calc(var(--safe-area-inset-top) * -1);
45+
}
46+
47+
.aura-view:not([slot='navbar']) > footer,
48+
.aura-view-footer:not([slot='navbar']) {
49+
padding-bottom: max(var(--vaadin-padding-m), var(--safe-area-inset-bottom));
50+
}
51+
52+
.aura-view[slot='drawer'] > footer,
53+
.aura-view-footer[slot='drawer'] {
54+
margin-bottom: calc(var(--safe-area-inset-bottom) * -1);
55+
}
56+
2257
:is(.aura-view > header, .aura-view-header) :is(h1, h2, h3, h4, h5, h6, .aura-view-heading) {
2358
margin: 0;
2459
padding-block: round(var(--vaadin-padding-s) / 1.4 + var(--vaadin-button-border-width, 1px), 1px);
@@ -37,7 +72,7 @@
3772
}
3873
}
3974

40-
vaadin-app-layout:is([drawer-opened], :has(> [slot='navbar'] vaadin-drawer-toggle))
75+
vaadin-app-layout:is([drawer-opened]:not([overlay]), :has(> [slot='navbar'] vaadin-drawer-toggle))
4176
:is(.aura-view > header, .aura-view-header)
4277
vaadin-drawer-toggle:not([theme~='permanent']),
4378
vaadin-master-detail-layout:not([drawer], [stack]) [slot='detail'].aura-view > header mdl-back-button,

packages/app-layout/src/safe-area-inset.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

packages/app-layout/src/styles/vaadin-app-layout-base-styles.js

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,18 @@ export const appLayoutStyles = css`
1717
--vaadin-app-layout-touch-optimized: false;
1818
--vaadin-app-layout-navbar-offset-top: var(--_vaadin-app-layout-navbar-offset-size);
1919
--vaadin-app-layout-navbar-offset-bottom: var(--_vaadin-app-layout-navbar-offset-size-bottom);
20-
padding-block: var(--vaadin-app-layout-navbar-offset-top) var(--vaadin-app-layout-navbar-offset-bottom);
21-
padding-inline-start: var(--vaadin-app-layout-navbar-offset-left);
20+
padding-top: max(var(--vaadin-app-layout-navbar-offset-top), var(--safe-area-inset-top));
21+
padding-bottom: max(var(--vaadin-app-layout-navbar-offset-bottom), var(--safe-area-inset-bottom));
22+
}
23+
24+
:host(:dir(ltr)) [content] {
25+
padding-left: max(var(--vaadin-app-layout-drawer-offset-left), var(--safe-area-inset-left));
26+
padding-right: var(--safe-area-inset-right);
27+
}
28+
29+
:host(:dir(rtl)) [content] {
30+
padding-left: var(--safe-area-inset-left);
31+
padding-right: max(var(--vaadin-app-layout-drawer-offset-left), var(--safe-area-inset-right));
2232
}
2333
2434
:host([hidden]),
@@ -37,8 +47,7 @@ export const appLayoutStyles = css`
3747
}
3848
3949
:host([overlay]) {
40-
--vaadin-app-layout-drawer-offset-left: 0;
41-
--vaadin-app-layout-navbar-offset-left: 0;
50+
--vaadin-app-layout-drawer-offset-left: 0px;
4251
}
4352
4453
:host(:not([no-scroll])) [content] {
@@ -47,6 +56,7 @@ export const appLayoutStyles = css`
4756
4857
[content] {
4958
height: 100%;
59+
transition: inherit;
5060
}
5161
5262
@media (pointer: coarse) and (max-width: 800px) and (min-height: 500px) {
@@ -110,7 +120,7 @@ export const appLayoutStyles = css`
110120
max-width: 90%;
111121
width: var(--_vaadin-app-layout-drawer-width);
112122
box-sizing: border-box;
113-
padding: var(--safe-area-inset-top) 0 var(--safe-area-inset-bottom) var(--safe-area-inset-left);
123+
padding-block: var(--safe-area-inset-top) var(--safe-area-inset-bottom);
114124
outline: none;
115125
/* The drawer should be inaccessible by the tabbing navigation when it is closed. */
116126
visibility: hidden;
@@ -119,6 +129,29 @@ export const appLayoutStyles = css`
119129
background: var(--vaadin-app-layout-drawer-background, transparent);
120130
}
121131
132+
[part='drawer']:dir(ltr) {
133+
padding-left: var(--safe-area-inset-left);
134+
}
135+
136+
[part='drawer']:dir(rtl) {
137+
padding-right: var(--safe-area-inset-right);
138+
}
139+
140+
:host([has-navbar]:not([overlay])) [part='drawer'],
141+
:host([has-navbar]) [content] {
142+
--safe-area-inset-top: 0px;
143+
}
144+
145+
:host([has-drawer]:not([overlay])[drawer-opened]) [content] {
146+
&:dir(ltr) {
147+
--safe-area-inset-left: 0px;
148+
}
149+
150+
&:dir(rtl) {
151+
--safe-area-inset-right: 0px;
152+
}
153+
}
154+
122155
:host([drawer-opened]) [part='drawer'] {
123156
/* The drawer should be accessible by the tabbing navigation when it is opened. */
124157
visibility: visible;
@@ -168,10 +201,6 @@ export const appLayoutStyles = css`
168201
transform: translateX(0%);
169202
}
170203
171-
:host([drawer-opened]:not([overlay])) {
172-
padding-inline-start: var(--vaadin-app-layout-drawer-offset-left);
173-
}
174-
175204
@media (max-width: 800px), (max-height: 600px) {
176205
:host {
177206
--vaadin-app-layout-drawer-overlay: true;

packages/app-layout/src/vaadin-app-layout.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
66
import './detect-ios-navbar.js';
7-
import './safe-area-inset.js';
87
import { html, LitElement } from 'lit';
98
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
109
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';

packages/app-layout/test/app-layout.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,14 @@ describe('vaadin-app-layout', () => {
311311
drawerContent.style.width = '200px';
312312
await nextResize(layout);
313313
await nextRender();
314-
const initialOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-inline-start'));
314+
const content = layout.shadowRoot.querySelector('[content]');
315+
const initialOffset = parseInt(getComputedStyle(content).getPropertyValue('padding-left'));
315316
expect(initialOffset).to.equal(200);
316317
// Decrease drawer content size and measure decrease
317318
drawerContent.style.width = '100px';
318319
await nextResize(layout);
319320
await nextRender();
320-
const updatedOffset = parseInt(getComputedStyle(layout).getPropertyValue('padding-inline-start'));
321+
const updatedOffset = parseInt(getComputedStyle(content).getPropertyValue('padding-left'));
321322
expect(updatedOffset).to.equal(100);
322323
});
323324
});

packages/aura/src/components/app-layout.css

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
--aura-app-layout-inset: 1.5vmin;
44
--aura-app-layout-radius: var(--vaadin-radius-l);
55
--_aura-mdl-border: 1px;
6-
--vaadin-app-layout-navbar-padding-top: 0;
7-
--vaadin-app-layout-navbar-padding-bottom: 0;
8-
--vaadin-app-layout-navbar-padding-inline-start: 0;
9-
--vaadin-app-layout-navbar-padding-inline-end: 0;
6+
/* Use px to ensure calc/min/max work */
7+
--vaadin-app-layout-navbar-padding-top: 0px;
8+
--vaadin-app-layout-navbar-padding-bottom: 0px;
9+
--vaadin-app-layout-navbar-padding-inline-start: 0px;
10+
--vaadin-app-layout-navbar-padding-inline-end: 0px;
1011
}
1112

1213
/* Aligned with App Layout overlay breakpoint */
@@ -24,15 +25,11 @@ vaadin-app-layout {
2425
padding-top: calc(var(--aura-app-layout-inset) + var(--_vaadin-app-layout-navbar-offset-size));
2526
}
2627

27-
vaadin-app-layout[overlay] {
28-
&::part(navbar),
29-
&::part(drawer) {
30-
--vaadin-app-layout-navbar-background: var(--aura-surface);
31-
--vaadin-app-layout-drawer-background: var(--aura-surface);
32-
--aura-surface-opacity: var(--aura-overlay-surface-opacity);
33-
-webkit-backdrop-filter: var(--aura-overlay-backdrop-filter);
34-
backdrop-filter: var(--aura-overlay-backdrop-filter);
35-
}
28+
vaadin-app-layout[overlay]::part(drawer) {
29+
--vaadin-app-layout-drawer-background: var(--aura-surface);
30+
--aura-surface-opacity: var(--aura-overlay-surface-opacity);
31+
-webkit-backdrop-filter: var(--aura-overlay-backdrop-filter);
32+
backdrop-filter: var(--aura-overlay-backdrop-filter);
3633
}
3734

3835
vaadin-app-layout:is([overlay], :not([drawer-opened])) {
@@ -41,10 +38,9 @@ vaadin-app-layout:is([overlay], :not([drawer-opened])) {
4138

4239
vaadin-app-layout::part(navbar) {
4340
justify-content: space-between;
44-
}
45-
46-
vaadin-app-layout:not([overlay])::part(navbar) {
4741
--vaadin-app-layout-navbar-background: transparent;
42+
-webkit-backdrop-filter: blur(20px);
43+
backdrop-filter: blur(20px);
4844
}
4945

5046
vaadin-app-layout:not([overlay])::part(drawer) {
@@ -53,16 +49,18 @@ vaadin-app-layout:not([overlay])::part(drawer) {
5349
}
5450

5551
vaadin-app-layout > vaadin-scroller[slot='drawer'] {
56-
padding-inline: var(--vaadin-padding-m);
52+
--vaadin-scroller-padding-inline: var(--vaadin-padding-m);
5753
scrollbar-width: thin;
5854
}
5955

6056
vaadin-app-layout > vaadin-scroller:nth-child(1 of [slot='drawer']) {
61-
padding-top: var(--vaadin-padding-s);
57+
/* TODO would need a dedicated padding-top property */
58+
--vaadin-scroller-padding-block: var(--vaadin-padding-s);
6259
}
6360

6461
vaadin-app-layout > vaadin-scroller:nth-last-child(1 of [slot='drawer']) {
65-
padding-bottom: var(--vaadin-padding-s);
62+
/* TODO would need a dedicated padding-bottom property */
63+
--vaadin-scroller-padding-block: var(--vaadin-padding-s);
6664
}
6765

6866
vaadin-app-layout > :nth-child(1 of :not([slot])):nth-last-child(1 of :not([slot])) {
@@ -80,6 +78,32 @@ vaadin-app-layout > :nth-child(1 of :not([slot])):nth-last-child(1 of :not([slot
8078
}
8179

8280
vaadin-app-layout > vaadin-master-detail-layout:nth-child(1 of :not([slot])):nth-last-child(1 of :not([slot])) {
81+
margin-inline: calc(var(--safe-area-inset-left) * -1) calc(var(--safe-area-inset-right) * -1);
82+
padding-inline: var(--safe-area-inset-left) var(--safe-area-inset-right);
83+
max-width: calc(100% + var(--safe-area-inset-left) + var(--safe-area-inset-right));
84+
margin-block: calc(var(--safe-area-inset-top) * -1) calc(var(--safe-area-inset-bottom) * -1);
85+
padding-block: var(--safe-area-inset-top) var(--safe-area-inset-bottom);
86+
height: calc(100% + var(--safe-area-inset-top) + var(--safe-area-inset-bottom));
87+
max-height: calc(100% + var(--safe-area-inset-top) + var(--safe-area-inset-bottom));
88+
89+
&::part(detail) {
90+
padding-top: var(--safe-area-inset-top);
91+
padding-bottom: var(--safe-area-inset-bottom);
92+
}
93+
94+
&:dir(ltr)::part(detail) {
95+
padding-right: var(--safe-area-inset-right);
96+
}
97+
98+
&:dir(rtl)::part(detail) {
99+
padding-left: var(--safe-area-inset-left);
100+
}
101+
102+
&[stack]::part(detail) {
103+
padding-left: var(--safe-area-inset-left);
104+
padding-right: var(--safe-area-inset-right);
105+
}
106+
83107
& > vaadin-master-detail-layout,
84108
&:not([drawer])::part(detail) {
85109
border-start-end-radius: var(--_app-layout-radius);
@@ -99,7 +123,7 @@ vaadin-app-layout[has-navbar][has-drawer] {
99123
padding-top: var(--_vaadin-app-layout-navbar-offset-size);
100124

101125
&::part(drawer) {
102-
padding-top: 0;
126+
padding-top: var(--safe-area-inset-top);
103127
}
104128
}
105129

packages/component-base/src/styles/style-props.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)