Skip to content

Commit 4c6cbf9

Browse files
committed
Safe area: containers and panels
This commit squashes the following development history: 1e78af3 - Restore, moved to #26969 d672d9f - Restore 53ee5fb - Restore 16b4eb9 - Restore 8d8b13f - Restore 62e1661 - Apply changes from #27003 f5ee79a - Fix 6067868 - Fix 766ed6a - Fix f76bd4f - Fix fabs 1879fd0 - Fix ea3ee6d - Add safe areas to ha-hanel-custom aa3384b - Add missing c9a7f76 - Fix 78351fd - Fix 59789d3 - Fix 1c7aabd - Remove eaf1373 - Fix 8481a93 - Fix fe7df1f - Remove 69f244f - Restore 2eb936b - Adjust b093506 - Fix c0504bb - Clean b0773d7 - Fix 4caa4a4 - make sure narrow is passed 8885f6b - Add safe areas to 2 pane fixed 62df70f - Clean a87e68d - FIx 5086be0 - Fix energy ac3478e - Fix 0f28098 - Restore b65ba3d - Restore b0e1ea6 - Restore 7bb78d1 - Fix 26c95df - Update 7369c79 - Remove b5f31da - Fix 40cfc43 - Set top level padding instead of individual panels 83b4972 - Restore 25db158 - Fix 8c9c398 - Set top level app bar padding instead of individual panels b7a1b27 - Remove 1e93687 - Device 1482502 - Integration page 98dc1bf - Fix 1c3de13 - Add a08bee4 - Remove 0d46243 - Area subpage 4bfd608 - Areas fix b5cbcda - Fix 9fb2720 - Add safe areas to script editor 7c3bc94 - Add safe areas to scene editor 1cf1b99 - Fix mobile for automation editors 4413bd4 - Add safe areas to automation editor 2e69533 - Add safe areas to blueprint editor 989776d - Add config section padding 6692b7c - Fix header row 22337b5 - Fix calendar 414e058 - Fix pane f09ae0e - Fix calendar fb5a984 - Fix pane 1daee18 - Todo fab 6f52cb4 - Todo content 9b317c5 - Media browser 0f8ca24 - Fix history panel cd78437 - Fix logbook b8d47ec - Fix d15e931 - Safe area: dashboard view container should only apply left safe area when in full view Summary of changes: - Add narrow property to top app bar components for conditional safe area padding - Update safe area inset calculations to use fallback values (0px) for better compatibility - Fix content height calculations to account for safe area insets - Apply safe area padding conditionally based on narrow state - Update FAB positioning to respect safe area insets - Ensure proper spacing and layout on mobile devices with notches/dynamic islands
1 parent c595392 commit 4c6cbf9

27 files changed

+269
-110
lines changed

src/components/ha-top-app-bar-fixed.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { TopAppBarFixedBase } from "@material/mwc-top-app-bar-fixed/mwc-top-app-bar-fixed-base";
22
import { styles } from "@material/mwc-top-app-bar/mwc-top-app-bar.css";
33
import { css } from "lit";
4-
import { customElement } from "lit/decorators";
4+
import { customElement, property } from "lit/decorators";
55

66
@customElement("ha-top-app-bar-fixed")
77
export class HaTopAppBarFixed extends TopAppBarFixedBase {
8+
@property({ type: Boolean, reflect: true }) public narrow = false;
9+
810
static override styles = [
911
styles,
1012
css`
@@ -13,12 +15,17 @@ export class HaTopAppBarFixed extends TopAppBarFixedBase {
1315
}
1416
.mdc-top-app-bar__row {
1517
height: var(--header-height);
16-
padding-left: var(--safe-area-content-inset-left);
17-
padding-right: var(--safe-area-content-inset-right);
1818
border-bottom: var(--app-header-border-bottom);
1919
}
2020
.mdc-top-app-bar--fixed-adjust {
21-
padding-top: calc(var(--safe-area-inset-top) + var(--header-height));
21+
padding-top: calc(
22+
var(--header-height, 0px) + var(--safe-area-inset-top, 0px)
23+
);
24+
padding-bottom: var(--safe-area-inset-bottom);
25+
padding-right: var(--safe-area-inset-right);
26+
}
27+
:host([narrow]) .mdc-top-app-bar--fixed-adjust {
28+
padding-left: var(--safe-area-inset-left);
2229
}
2330
.mdc-top-app-bar {
2431
--mdc-typography-headline6-font-weight: var(--ha-font-weight-normal);
@@ -28,9 +35,11 @@ export class HaTopAppBarFixed extends TopAppBarFixedBase {
2835
var(--mdc-theme-primary)
2936
);
3037
padding-top: var(--safe-area-inset-top);
31-
padding-left: var(--safe-area-inset-left);
3238
padding-right: var(--safe-area-inset-right);
3339
}
40+
:host([narrow]) .mdc-top-app-bar {
41+
padding-left: var(--safe-area-inset-left);
42+
}
3443
.mdc-top-app-bar__title {
3544
font-size: var(--ha-font-size-xl);
3645
padding-inline-start: 24px;

src/components/ha-two-pane-top-app-bar-fixed.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ export class TopAppBarBaseBase extends BaseElement {
3232

3333
protected _scrollTarget!: HTMLElement | Window;
3434

35+
@property({ type: Boolean, reflect: true }) public narrow = false;
36+
3537
@property({ attribute: "center-title", type: Boolean }) centerTitle = false;
3638

3739
@property({ type: Boolean, reflect: true }) prominent = false;
@@ -252,7 +254,14 @@ export class TopAppBarBaseBase extends BaseElement {
252254
border-bottom: var(--app-header-border-bottom);
253255
}
254256
.mdc-top-app-bar--fixed-adjust {
255-
padding-top: calc(var(--safe-area-inset-top) + var(--header-height));
257+
padding-top: calc(
258+
var(--header-height, 0px) + var(--safe-area-inset-top, 0px)
259+
);
260+
padding-bottom: var(--safe-area-inset-bottom);
261+
padding-right: var(--safe-area-inset-right);
262+
}
263+
:host([narrow]) .mdc-top-app-bar--fixed-adjust {
264+
padding-left: var(--safe-area-inset-left);
256265
}
257266
.shadow-container {
258267
position: absolute;
@@ -278,9 +287,11 @@ export class TopAppBarBaseBase extends BaseElement {
278287
var(--mdc-theme-primary)
279288
);
280289
padding-top: var(--safe-area-inset-top);
281-
padding-left: var(--safe-area-inset-left);
282290
padding-right: var(--safe-area-inset-right);
283291
}
292+
:host([narrow]) .mdc-top-app-bar {
293+
padding-left: var(--safe-area-inset-left);
294+
}
284295
.mdc-top-app-bar--pane.mdc-top-app-bar--fixed-scrolled {
285296
box-shadow: none;
286297
}
@@ -294,7 +305,12 @@ export class TopAppBarBaseBase extends BaseElement {
294305
}
295306
div.mdc-top-app-bar--pane {
296307
display: flex;
297-
height: calc(100vh - var(--header-height));
308+
height: calc(
309+
100vh - var(--header-height, 0px) - var(
310+
--safe-area-inset-top,
311+
0px
312+
) - var(--safe-area-inset-bottom, 0px)
313+
);
298314
}
299315
.pane {
300316
border-right: 1px solid var(--divider-color);

src/layouts/hass-subpage.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,32 +147,49 @@ class HassSubpage extends LitElement {
147147
148148
.content {
149149
position: relative;
150-
width: 100%;
151-
height: calc(100% - 1px - var(--header-height));
150+
width: calc(100% - var(--safe-area-inset-right, 0px));
151+
height: calc(
152+
100% -
153+
1px - var(--header-height, 0px) - var(
154+
--safe-area-inset-top,
155+
0px
156+
) - var(--safe-area-inset-bottom, 0px)
157+
);
158+
margin-bottom: var(--safe-area-inset-bottom);
159+
margin-right: var(--safe-area-inset-right);
152160
overflow-y: auto;
153161
overflow: auto;
154162
-webkit-overflow-scrolling: touch;
155163
}
164+
:host([narrow]) .content {
165+
width: calc(
166+
100% - var(--safe-area-inset-left, 0px) - var(
167+
--safe-area-inset-right,
168+
0px
169+
)
170+
);
171+
margin-left: var(--safe-area-inset-left);
172+
}
156173
157174
#fab {
158175
position: absolute;
159-
right: calc(16px + var(--safe-area-inset-right));
160-
inset-inline-end: calc(16px + var(--safe-area-inset-right));
176+
right: calc(16px + var(--safe-area-inset-right, 0px));
177+
inset-inline-end: calc(16px + var(--safe-area-inset-right, 0px));
161178
inset-inline-start: initial;
162-
bottom: calc(16px + var(--safe-area-inset-bottom));
179+
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
163180
z-index: 1;
164181
display: flex;
165182
flex-wrap: wrap;
166183
justify-content: flex-end;
167184
gap: 8px;
168185
}
169186
:host([narrow]) #fab.tabs {
170-
bottom: calc(84px + var(--safe-area-inset-bottom));
187+
bottom: calc(84px + var(--safe-area-inset-bottom, 0px));
171188
}
172189
#fab[is-wide] {
173-
bottom: 24px;
174-
right: 24px;
175-
inset-inline-end: 24px;
190+
bottom: calc(24px + var(--safe-area-inset-bottom, 0px));
191+
right: calc(24px + var(--safe-area-inset-right, 0px));
192+
inset-inline-end: calc(24px + var(--safe-area-inset-right, 0px));
176193
inset-inline-start: initial;
177194
}
178195
`,

src/layouts/hass-tabs-subpage-data-table.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,12 +704,24 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) {
704704
}
705705
:host(:not([narrow])) ha-data-table,
706706
.pane {
707-
height: calc(100vh - 1px - var(--header-height));
707+
height: calc(
708+
100vh -
709+
1px - var(--header-height, 0px) - var(
710+
--safe-area-inset-top,
711+
0px
712+
) - var(--safe-area-inset-bottom, 0px)
713+
);
708714
display: block;
709715
}
710716
711717
.pane-content {
712-
height: calc(100vh - 1px - var(--header-height) - var(--header-height));
718+
height: calc(
719+
100vh -
720+
1px - var(--header-height, 0px) - var(--header-height, 0px) - var(
721+
--safe-area-inset-top,
722+
0px
723+
) - var(--safe-area-inset-bottom, 0px)
724+
);
713725
display: flex;
714726
flex-direction: column;
715727
}

src/layouts/hass-tabs-subpage.ts

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,9 @@ class HassTabsSubpage extends LitElement {
172172
? html`<div id="tabbar" class="bottom-bar">${tabs}</div>`
173173
: ""}
174174
</div>
175-
<div class="container">
175+
<div
176+
class=${classMap({ container: true, tabs: showTabs && this.narrow })}
177+
>
176178
${this.pane
177179
? html`<div class="pane">
178180
<div class="shadow-container"></div>
@@ -225,11 +227,9 @@ class HassTabsSubpage extends LitElement {
225227
226228
.container {
227229
display: flex;
228-
height: calc(100% - var(--header-height));
229-
}
230-
231-
:host([narrow]) .container {
232-
height: 100%;
230+
height: calc(
231+
100% - var(--header-height, 0px) - var(--safe-area-inset-top, 0px)
232+
);
233233
}
234234
235235
ha-menu-button {
@@ -240,26 +240,28 @@ class HassTabsSubpage extends LitElement {
240240
241241
.toolbar {
242242
font-size: var(--ha-font-size-xl);
243-
height: calc(var(--header-height) + var(--safe-area-inset-top));
243+
height: calc(
244+
var(--header-height, 0px) + var(--safe-area-inset-top, 0px)
245+
);
244246
padding-top: var(--safe-area-inset-top);
245247
padding-right: var(--safe-area-inset-right);
246-
padding-left: var(--safe-area-inset-left);
247248
background-color: var(--sidebar-background-color);
248249
font-weight: var(--ha-font-weight-normal);
249250
border-bottom: 1px solid var(--divider-color);
250251
box-sizing: border-box;
251252
}
253+
:host([narrow]) .toolbar {
254+
padding-left: var(--safe-area-inset-left);
255+
}
252256
.toolbar-content {
253257
padding: 8px 12px;
254258
display: flex;
255259
align-items: center;
256260
height: 100%;
257261
box-sizing: border-box;
258262
}
259-
@media (max-width: 599px) {
260-
.toolbar-content {
261-
padding: 4px;
262-
}
263+
:host([narrow]) .toolbar-content {
264+
padding: 4px;
263265
}
264266
.toolbar a {
265267
color: var(--sidebar-text-color);
@@ -323,53 +325,46 @@ class HassTabsSubpage extends LitElement {
323325
324326
.content {
325327
position: relative;
326-
width: calc(
327-
100% - var(--safe-area-inset-left) - var(--safe-area-inset-right)
328-
);
329-
margin-left: var(--safe-area-inset-left);
328+
width: 100%;
330329
margin-right: var(--safe-area-inset-right);
331-
margin-inline-start: var(--safe-area-inset-left);
332330
margin-inline-end: var(--safe-area-inset-right);
331+
margin-bottom: var(--safe-area-inset-bottom);
333332
overflow: auto;
334333
-webkit-overflow-scrolling: touch;
335334
}
336-
337335
:host([narrow]) .content {
338-
height: calc(100% - var(--header-height));
339-
height: calc(
340-
100% - var(--header-height) - var(--safe-area-inset-bottom)
341-
);
336+
margin-left: var(--safe-area-inset-left);
337+
margin-inline-start: var(--safe-area-inset-left);
342338
}
343-
344339
:host([narrow]) .content.tabs {
345-
height: calc(100% - 2 * var(--header-height));
346-
height: calc(
347-
100% - 2 * var(--header-height) - var(--safe-area-inset-bottom)
340+
/* Bottom bar reuses header height */
341+
margin-bottom: calc(
342+
var(--header-height, 0px) + var(--safe-area-inset-bottom, 0px)
348343
);
349344
}
350345
351346
.content .fab-bottom-space {
352-
height: calc(64px + var(--safe-area-inset-bottom));
347+
height: calc(64px + var(--safe-area-inset-bottom, 0px));
353348
}
354349
355350
:host([narrow]) .content.tabs .fab-bottom-space {
356-
height: calc(80px + var(--safe-area-inset-bottom));
351+
height: calc(80px + var(--safe-area-inset-bottom, 0px));
357352
}
358353
359354
#fab {
360355
position: fixed;
361-
right: calc(16px + var(--safe-area-inset-right));
356+
right: calc(16px + var(--safe-area-inset-right, 0px));
362357
inset-inline-end: calc(16px + var(--safe-area-inset-right));
363358
inset-inline-start: initial;
364-
bottom: calc(16px + var(--safe-area-inset-bottom));
359+
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
365360
z-index: 1;
366361
display: flex;
367362
flex-wrap: wrap;
368363
justify-content: flex-end;
369364
gap: 8px;
370365
}
371366
:host([narrow]) #fab.tabs {
372-
bottom: calc(84px + var(--safe-area-inset-bottom));
367+
bottom: calc(84px + var(--safe-area-inset-bottom, 0px));
373368
}
374369
#fab[is-wide] {
375370
bottom: 24px;

src/panels/calendar/ha-panel-calendar.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ class PanelCalendar extends LitElement {
114114
);
115115
const showPane = this._showPaneController.value ?? !this.narrow;
116116
return html`
117-
<ha-two-pane-top-app-bar-fixed .pane=${showPane} footer>
117+
<ha-two-pane-top-app-bar-fixed
118+
.pane=${showPane}
119+
footer
120+
.narrow=${this.narrow}
121+
>
118122
<ha-menu-button
119123
slot="navigationIcon"
120124
.hass=${this.hass}
@@ -294,10 +298,15 @@ class PanelCalendar extends LitElement {
294298
display: block;
295299
}
296300
ha-full-calendar {
297-
height: calc(100vh - var(--header-height));
298301
--calendar-header-padding: 12px;
299302
--calendar-border-radius: 0;
300303
--calendar-border-width: 1px 0;
304+
height: calc(
305+
100vh - var(--header-height, 0px) - var(
306+
--safe-area-inset-top,
307+
0px
308+
) - var(--safe-area-inset-bottom, 0px)
309+
);
301310
}
302311
ha-button-menu ha-button {
303312
--ha-font-size-m: var(--ha-font-size-l);

src/panels/config/automation/blueprint-automation-editor.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,25 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor {
9494
:host {
9595
position: relative;
9696
height: 100%;
97-
min-height: calc(100vh - 85px);
98-
min-height: calc(100dvh - 85px);
97+
min-height: calc(
98+
100vh -
99+
134px - var(--safe-area-inset-top, 0px) - var(
100+
--safe-area-inset-bottom,
101+
0px
102+
)
103+
);
104+
min-height: calc(
105+
100dvh -
106+
134px - var(--safe-area-inset-top, 0px) - var(
107+
--safe-area-inset-bottom,
108+
0px
109+
)
110+
);
99111
}
100112
ha-fab {
101113
position: fixed;
114+
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
115+
right: calc(16px + var(--safe-area-inset-right, 0px));
102116
}
103117
`,
104118
];

src/panels/config/automation/ha-automation-editor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,12 +1214,12 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
12141214
}
12151215
ha-fab {
12161216
position: fixed;
1217-
right: 16px;
1217+
right: calc(16px + var(--safe-area-inset-right, 0px));
12181218
bottom: calc(-80px - var(--safe-area-inset-bottom));
12191219
transition: bottom 0.3s;
12201220
}
12211221
ha-fab.dirty {
1222-
bottom: 16px;
1222+
bottom: calc(16px + var(--safe-area-inset-bottom, 0px));
12231223
}
12241224
`,
12251225
];

0 commit comments

Comments
 (0)