Compare commits

...

2 Commits

Author SHA1 Message Date
Pavilion Sahota
7b83e0f44c Implemented top bar fixed for climate lights and security panels 2026-02-13 10:55:36 +00:00
Pavilion Sahota
410df52a9a Refactored duplicate header styling 2026-02-13 10:55:13 +00:00
6 changed files with 139 additions and 369 deletions

View File

@@ -0,0 +1,51 @@
import { css } from "lit";
export const haTopAppBarFixedSharedStyles = css`
header {
padding-top: var(--safe-area-inset-top);
}
.mdc-top-app-bar__row {
height: var(--header-height);
border-bottom: var(--app-header-border-bottom);
}
.mdc-top-app-bar--fixed-adjust {
padding-top: calc(
var(--header-height, 0px) + var(--safe-area-inset-top, 0px)
);
padding-bottom: var(--safe-area-inset-bottom);
padding-right: var(--safe-area-inset-right);
}
:host([narrow]) .mdc-top-app-bar--fixed-adjust {
padding-left: var(--safe-area-inset-left);
}
.mdc-top-app-bar {
--mdc-typography-headline6-font-weight: var(--ha-font-weight-normal);
color: var(--app-header-text-color, var(--mdc-theme-on-primary, #fff));
background-color: var(
--app-header-background-color,
var(--mdc-theme-primary)
);
-webkit-backdrop-filter: var(--app-header-backdrop-filter, none);
backdrop-filter: var(--app-header-backdrop-filter, none);
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
transition:
width var(--ha-animation-duration-normal) ease,
padding-left var(--ha-animation-duration-normal) ease,
padding-right var(--ha-animation-duration-normal) ease;
}
:host([narrow]) .mdc-top-app-bar {
padding-left: var(--safe-area-inset-left);
}
@media (prefers-reduced-motion: reduce) {
.mdc-top-app-bar {
transition: none;
}
}
`;

View File

@@ -2,6 +2,7 @@ import { TopAppBarFixedBase } from "@material/mwc-top-app-bar-fixed/mwc-top-app-
import { styles } from "@material/mwc-top-app-bar/mwc-top-app-bar.css";
import { css } from "lit";
import { customElement, property } from "lit/decorators";
import { haTopAppBarFixedSharedStyles } from "./ha-top-app-bar-fixed-shared-styles";
@customElement("ha-top-app-bar-fixed")
export class HaTopAppBarFixed extends TopAppBarFixedBase {
@@ -9,46 +10,8 @@ export class HaTopAppBarFixed extends TopAppBarFixedBase {
static override styles = [
styles,
haTopAppBarFixedSharedStyles,
css`
header {
padding-top: var(--safe-area-inset-top);
}
.mdc-top-app-bar__row {
height: var(--header-height);
border-bottom: var(--app-header-border-bottom);
}
.mdc-top-app-bar--fixed-adjust {
padding-top: calc(
var(--header-height, 0px) + var(--safe-area-inset-top, 0px)
);
padding-bottom: var(--safe-area-inset-bottom);
padding-right: var(--safe-area-inset-right);
}
:host([narrow]) .mdc-top-app-bar--fixed-adjust {
padding-left: var(--safe-area-inset-left);
}
.mdc-top-app-bar {
--mdc-typography-headline6-font-weight: var(--ha-font-weight-normal);
color: var(--app-header-text-color, var(--mdc-theme-on-primary, #fff));
background-color: var(
--app-header-background-color,
var(--mdc-theme-primary)
);
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
transition:
width var(--ha-animation-duration-normal) ease,
padding-left var(--ha-animation-duration-normal) ease,
padding-right var(--ha-animation-duration-normal) ease;
}
:host([narrow]) .mdc-top-app-bar {
padding-left: var(--safe-area-inset-left);
}
@media (prefers-reduced-motion: reduce) {
.mdc-top-app-bar {
transition: none;
}
}
.mdc-top-app-bar__title {
font-size: var(--ha-font-size-xl);
padding-inline-start: var(--ha-space-6);

View File

@@ -11,6 +11,7 @@ import { property, query, customElement } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styles } from "@material/mwc-top-app-bar/mwc-top-app-bar.css";
import { haStyleScrollbar } from "../resources/styles";
import { haTopAppBarFixedSharedStyles } from "./ha-top-app-bar-fixed-shared-styles";
export const passiveEventOptionsIfSupported = supportsPassiveEventListener
? { passive: true }
@@ -245,24 +246,8 @@ export class TopAppBarBaseBase extends BaseElement {
static override styles = [
styles,
haStyleScrollbar,
haTopAppBarFixedSharedStyles,
css`
header {
padding-top: var(--safe-area-inset-top);
}
.mdc-top-app-bar__row {
height: var(--header-height);
border-bottom: var(--app-header-border-bottom);
}
.mdc-top-app-bar--fixed-adjust {
padding-top: calc(
var(--header-height, 0px) + var(--safe-area-inset-top, 0px)
);
padding-bottom: var(--safe-area-inset-bottom);
padding-right: var(--safe-area-inset-right);
}
:host([narrow]) .mdc-top-app-bar--fixed-adjust {
padding-left: var(--safe-area-inset-left);
}
.shadow-container {
position: absolute;
top: calc(-1 * var(--header-height));
@@ -279,28 +264,6 @@ export class TopAppBarBaseBase extends BaseElement {
0px 1px 10px 0px rgba(0, 0, 0, 0.12)
);
}
.mdc-top-app-bar {
--mdc-typography-headline6-font-weight: var(--ha-font-weight-normal);
color: var(--app-header-text-color, var(--mdc-theme-on-primary, #fff));
background-color: var(
--app-header-background-color,
var(--mdc-theme-primary)
);
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
transition:
width var(--ha-animation-duration-normal) ease,
padding-left var(--ha-animation-duration-normal) ease,
padding-right var(--ha-animation-duration-normal) ease;
}
:host([narrow]) .mdc-top-app-bar {
padding-left: var(--safe-area-inset-left);
}
@media (prefers-reduced-motion: reduce) {
.mdc-top-app-bar {
transition: none;
}
}
.mdc-top-app-bar--pane.mdc-top-app-bar--fixed-scrolled {
box-shadow: none;
}

View File

@@ -1,12 +1,12 @@
import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { goBack } from "../../common/navigate";
import { debounce } from "../../common/util/debounce";
import { deepEqual } from "../../common/util/deep-equal";
import "../../components/ha-icon-button-arrow-prev";
import "../../components/ha-menu-button";
import "../../components/ha-top-app-bar-fixed";
import type { LovelaceStrategyViewConfig } from "../../data/lovelace/config/view";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
@@ -96,29 +96,23 @@ class PanelClimate extends LitElement {
protected render() {
return html`
<div class="header ${classMap({ narrow: this.narrow })}">
<div class="toolbar">
${
this._searchParms.has("historyBack")
? html`
<ha-icon-button-arrow-prev
@click=${this._back}
slot="navigationIcon"
></ha-icon-button-arrow-prev>
`
: html`
<ha-menu-button
slot="navigationIcon"
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
`
}
<div class="main-title">${this.hass.localize("panel.climate")}</div>
</div>
</div>
${
this._lovelace
<ha-top-app-bar-fixed .narrow=${this.narrow}>
${this._searchParms.has("historyBack")
? html`
<ha-icon-button-arrow-prev
@click=${this._back}
slot="navigationIcon"
></ha-icon-button-arrow-prev>
`
: html`
<ha-menu-button
slot="navigationIcon"
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
`}
<div slot="title">${this.hass.localize("panel.climate")}</div>
${this._lovelace
? html`
<hui-view-container .hass=${this.hass}>
<hui-view-background .hass=${this.hass}> </hui-view-background>
@@ -127,12 +121,11 @@ class PanelClimate extends LitElement {
.narrow=${this.narrow}
.lovelace=${this._lovelace}
.index=${this._viewIndex}
></hui-view
></hui-view-container>
></hui-view>
</hui-view-container>
`
: nothing
}
</hui-view-container>
: nothing}
</ha-top-app-bar-fixed>
`;
}
@@ -173,78 +166,16 @@ class PanelClimate extends LitElement {
-webkit-user-select: none;
-moz-user-select: none;
}
.header {
background-color: var(--app-header-background-color);
color: var(--app-header-text-color, white);
position: fixed;
top: 0;
width: calc(
var(--mdc-top-app-bar-width, 100%) - var(
--safe-area-inset-right,
0px
)
);
padding-top: var(--safe-area-inset-top);
z-index: 4;
display: flex;
flex-direction: row;
-webkit-backdrop-filter: var(--app-header-backdrop-filter, none);
backdrop-filter: var(--app-header-backdrop-filter, none);
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
}
:host([narrow]) .header {
width: calc(
var(--mdc-top-app-bar-width, 100%) - var(
--safe-area-inset-left,
0px
) - var(--safe-area-inset-right, 0px)
);
padding-left: var(--safe-area-inset-left);
}
:host([scrolled]) .header {
box-shadow: var(
--mdc-top-app-bar-fixed-box-shadow,
0px 2px 4px -1px rgba(0, 0, 0, 0.2),
0px 4px 5px 0px rgba(0, 0, 0, 0.14),
0px 1px 10px 0px rgba(0, 0, 0, 0.12)
);
}
.toolbar {
height: var(--header-height);
display: flex;
flex: 1;
align-items: center;
font-size: var(--ha-font-size-xl);
padding: 0px 12px;
font-weight: var(--ha-font-weight-normal);
box-sizing: border-box;
border-bottom: var(--app-header-border-bottom, none);
}
:host([narrow]) .toolbar {
padding: 0 4px;
}
.main-title {
margin-inline-start: var(--ha-space-6);
line-height: var(--ha-line-height-normal);
flex-grow: 1;
}
.narrow .main-title {
margin-inline-start: var(--ha-space-2);
}
hui-view-container {
position: relative;
display: flex;
min-height: 100vh;
min-height: calc(
100vh - var(--header-height, 0px) - var(
--safe-area-inset-top,
0px
) - var(--safe-area-inset-bottom, 0px)
);
box-sizing: border-box;
padding-top: calc(var(--header-height) + var(--safe-area-inset-top));
padding-right: var(--safe-area-inset-right);
padding-inline-end: var(--safe-area-inset-right);
padding-bottom: var(--safe-area-inset-bottom);
}
:host([narrow]) hui-view-container {
padding-left: var(--safe-area-inset-left);
padding-inline-start: var(--safe-area-inset-left);
}
hui-view {
flex: 1 1 100%;

View File

@@ -1,12 +1,12 @@
import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { goBack } from "../../common/navigate";
import { debounce } from "../../common/util/debounce";
import { deepEqual } from "../../common/util/deep-equal";
import "../../components/ha-icon-button-arrow-prev";
import "../../components/ha-menu-button";
import "../../components/ha-top-app-bar-fixed";
import type { LovelaceStrategyViewConfig } from "../../data/lovelace/config/view";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
@@ -96,29 +96,23 @@ class PanelLight extends LitElement {
protected render() {
return html`
<div class="header ${classMap({ narrow: this.narrow })}">
<div class="toolbar">
${
this._searchParms.has("historyBack")
? html`
<ha-icon-button-arrow-prev
@click=${this._back}
slot="navigationIcon"
></ha-icon-button-arrow-prev>
`
: html`
<ha-menu-button
slot="navigationIcon"
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
`
}
<div class="main-title">${this.hass.localize("panel.light")}</div>
</div>
</div>
${
this._lovelace
<ha-top-app-bar-fixed .narrow=${this.narrow}>
${this._searchParms.has("historyBack")
? html`
<ha-icon-button-arrow-prev
@click=${this._back}
slot="navigationIcon"
></ha-icon-button-arrow-prev>
`
: html`
<ha-menu-button
slot="navigationIcon"
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
`}
<div slot="title">${this.hass.localize("panel.light")}</div>
${this._lovelace
? html`
<hui-view-container .hass=${this.hass}>
<hui-view-background .hass=${this.hass}> </hui-view-background>
@@ -127,12 +121,11 @@ class PanelLight extends LitElement {
.narrow=${this.narrow}
.lovelace=${this._lovelace}
.index=${this._viewIndex}
></hui-view
></hui-view-container>
></hui-view>
</hui-view-container>
`
: nothing
}
</hui-view-container>
: nothing}
</ha-top-app-bar-fixed>
`;
}
@@ -173,78 +166,16 @@ class PanelLight extends LitElement {
-webkit-user-select: none;
-moz-user-select: none;
}
.header {
background-color: var(--app-header-background-color);
color: var(--app-header-text-color, white);
position: fixed;
top: 0;
width: calc(
var(--mdc-top-app-bar-width, 100%) - var(
--safe-area-inset-right,
0px
)
);
padding-top: var(--safe-area-inset-top);
z-index: 4;
display: flex;
flex-direction: row;
-webkit-backdrop-filter: var(--app-header-backdrop-filter, none);
backdrop-filter: var(--app-header-backdrop-filter, none);
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
}
:host([narrow]) .header {
width: calc(
var(--mdc-top-app-bar-width, 100%) - var(
--safe-area-inset-left,
0px
) - var(--safe-area-inset-right, 0px)
);
padding-left: var(--safe-area-inset-left);
}
:host([scrolled]) .header {
box-shadow: var(
--mdc-top-app-bar-fixed-box-shadow,
0px 2px 4px -1px rgba(0, 0, 0, 0.2),
0px 4px 5px 0px rgba(0, 0, 0, 0.14),
0px 1px 10px 0px rgba(0, 0, 0, 0.12)
);
}
.toolbar {
height: var(--header-height);
display: flex;
flex: 1;
align-items: center;
font-size: var(--ha-font-size-xl);
padding: 0px 12px;
font-weight: var(--ha-font-weight-normal);
box-sizing: border-box;
border-bottom: var(--app-header-border-bottom, none);
}
:host([narrow]) .toolbar {
padding: 0 4px;
}
.main-title {
margin-inline-start: var(--ha-space-6);
line-height: var(--ha-line-height-normal);
flex-grow: 1;
}
.narrow .main-title {
margin-inline-start: var(--ha-space-2);
}
hui-view-container {
position: relative;
display: flex;
min-height: 100vh;
min-height: calc(
100vh - var(--header-height, 0px) - var(
--safe-area-inset-top,
0px
) - var(--safe-area-inset-bottom, 0px)
);
box-sizing: border-box;
padding-top: calc(var(--header-height) + var(--safe-area-inset-top));
padding-right: var(--safe-area-inset-right);
padding-inline-end: var(--safe-area-inset-right);
padding-bottom: var(--safe-area-inset-bottom);
}
:host([narrow]) hui-view-container {
padding-left: var(--safe-area-inset-left);
padding-inline-start: var(--safe-area-inset-left);
}
hui-view {
flex: 1 1 100%;

View File

@@ -1,12 +1,12 @@
import type { CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { goBack } from "../../common/navigate";
import { debounce } from "../../common/util/debounce";
import { deepEqual } from "../../common/util/deep-equal";
import "../../components/ha-icon-button-arrow-prev";
import "../../components/ha-menu-button";
import "../../components/ha-top-app-bar-fixed";
import type { LovelaceStrategyViewConfig } from "../../data/lovelace/config/view";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
@@ -96,29 +96,23 @@ class PanelSecurity extends LitElement {
protected render() {
return html`
<div class="header ${classMap({ narrow: this.narrow })}">
<div class="toolbar">
${
this._searchParms.has("historyBack")
? html`
<ha-icon-button-arrow-prev
@click=${this._back}
slot="navigationIcon"
></ha-icon-button-arrow-prev>
`
: html`
<ha-menu-button
slot="navigationIcon"
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
`
}
<div class="main-title">${this.hass.localize("panel.security")}</div>
</div>
</div>
${
this._lovelace
<ha-top-app-bar-fixed .narrow=${this.narrow}>
${this._searchParms.has("historyBack")
? html`
<ha-icon-button-arrow-prev
@click=${this._back}
slot="navigationIcon"
></ha-icon-button-arrow-prev>
`
: html`
<ha-menu-button
slot="navigationIcon"
.hass=${this.hass}
.narrow=${this.narrow}
></ha-menu-button>
`}
<div slot="title">${this.hass.localize("panel.security")}</div>
${this._lovelace
? html`
<hui-view-container .hass=${this.hass}>
<hui-view-background .hass=${this.hass}> </hui-view-background>
@@ -127,12 +121,11 @@ class PanelSecurity extends LitElement {
.narrow=${this.narrow}
.lovelace=${this._lovelace}
.index=${this._viewIndex}
></hui-view
></hui-view-container>
></hui-view>
</hui-view-container>
`
: nothing
}
</hui-view-container>
: nothing}
</ha-top-app-bar-fixed>
`;
}
@@ -173,78 +166,16 @@ class PanelSecurity extends LitElement {
-webkit-user-select: none;
-moz-user-select: none;
}
.header {
background-color: var(--app-header-background-color);
color: var(--app-header-text-color, white);
position: fixed;
top: 0;
width: calc(
var(--mdc-top-app-bar-width, 100%) - var(
--safe-area-inset-right,
0px
)
);
padding-top: var(--safe-area-inset-top);
z-index: 4;
display: flex;
flex-direction: row;
-webkit-backdrop-filter: var(--app-header-backdrop-filter, none);
backdrop-filter: var(--app-header-backdrop-filter, none);
padding-top: var(--safe-area-inset-top);
padding-right: var(--safe-area-inset-right);
}
:host([narrow]) .header {
width: calc(
var(--mdc-top-app-bar-width, 100%) - var(
--safe-area-inset-left,
0px
) - var(--safe-area-inset-right, 0px)
);
padding-left: var(--safe-area-inset-left);
}
:host([scrolled]) .header {
box-shadow: var(
--mdc-top-app-bar-fixed-box-shadow,
0px 2px 4px -1px rgba(0, 0, 0, 0.2),
0px 4px 5px 0px rgba(0, 0, 0, 0.14),
0px 1px 10px 0px rgba(0, 0, 0, 0.12)
);
}
.toolbar {
height: var(--header-height);
display: flex;
flex: 1;
align-items: center;
font-size: var(--ha-font-size-xl);
padding: 0px 12px;
font-weight: var(--ha-font-weight-normal);
box-sizing: border-box;
border-bottom: var(--app-header-border-bottom, none);
}
:host([narrow]) .toolbar {
padding: 0 4px;
}
.main-title {
margin-inline-start: var(--ha-space-6);
line-height: var(--ha-line-height-normal);
flex-grow: 1;
}
.narrow .main-title {
margin-inline-start: var(--ha-space-2);
}
hui-view-container {
position: relative;
display: flex;
min-height: 100vh;
min-height: calc(
100vh - var(--header-height, 0px) - var(
--safe-area-inset-top,
0px
) - var(--safe-area-inset-bottom, 0px)
);
box-sizing: border-box;
padding-top: calc(var(--header-height) + var(--safe-area-inset-top));
padding-right: var(--safe-area-inset-right);
padding-inline-end: var(--safe-area-inset-right);
padding-bottom: var(--safe-area-inset-bottom);
}
:host([narrow]) hui-view-container {
padding-left: var(--safe-area-inset-left);
padding-inline-start: var(--safe-area-inset-left);
}
hui-view {
flex: 1 1 100%;