diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index 72d1d24912..086b0bfdba 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -736,8 +736,7 @@ class HaSidebar extends LitElement { border-left: 1px solid var(--divider-color); } .menu { - box-sizing: border-box; - height: 65px; + height: var(--header-height); display: flex; padding: 0 8.5px; border-bottom: 1px solid transparent; @@ -794,7 +793,10 @@ class HaSidebar extends LitElement { display: flex; flex-direction: column; box-sizing: border-box; - height: calc(100% - 196px - env(safe-area-inset-bottom)); + height: calc(100% - var(--header-height) - 132px); + height: calc( + 100% - var(--header-height) - 132px - env(safe-area-inset-bottom) + ); overflow-x: hidden; background: none; margin-left: env(safe-area-inset-left); diff --git a/src/components/ha-tabs.ts b/src/components/ha-tabs.ts index 33338c4a93..b6dc45dcf1 100644 --- a/src/components/ha-tabs.ts +++ b/src/components/ha-tabs.ts @@ -34,14 +34,17 @@ export class HaTabs extends PaperTabs { superStyle!.appendChild( document.createTextNode(` + :host { + padding-top: .5px; + } .not-visible { display: none; } - :host > paper-icon-button:first-of-type { - padding-left: 0; - } paper-icon-button { - margin: 0 -8px 0 0; + width: 24px; + height: 48px; + padding: 0; + margin: 0; } `) ); @@ -85,7 +88,7 @@ export class HaTabs extends PaperTabs { if (this._lastLeftHiddenState !== this._leftHidden) { this._lastLeftHiddenState = this._leftHidden; - this.$.tabsContainer.scrollLeft += this._leftHidden ? -46 : 46; + this.$.tabsContainer.scrollLeft += this._leftHidden ? -23 : 23; } } } diff --git a/src/dialogs/notifications/notification-drawer.js b/src/dialogs/notifications/notification-drawer.js index 865c77b942..0ad149e9f0 100644 --- a/src/dialogs/notifications/notification-drawer.js +++ b/src/dialogs/notifications/notification-drawer.js @@ -40,7 +40,7 @@ export class HuiNotificationDrawer extends EventsMixin( padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); padding-bottom: env(safe-area-inset-bottom); - height: calc(100% - 65px); + height: calc(100% - 1px - var(--header-height)); box-sizing: border-box; background-color: var(--primary-background-color); color: var(--primary-text-color); diff --git a/src/layouts/hass-error-screen.ts b/src/layouts/hass-error-screen.ts index 8776184498..962e812de5 100644 --- a/src/layouts/hass-error-screen.ts +++ b/src/layouts/hass-error-screen.ts @@ -64,7 +64,7 @@ class HassErrorScreen extends LitElement { } .content { color: var(--primary-text-color); - height: calc(100% - 64px); + height: calc(100% - var(--header-height)); display: flex; align-items: center; justify-content: center; diff --git a/src/layouts/hass-loading-screen.ts b/src/layouts/hass-loading-screen.ts index f0b01c96b1..e3917e581f 100644 --- a/src/layouts/hass-loading-screen.ts +++ b/src/layouts/hass-loading-screen.ts @@ -80,7 +80,7 @@ class HassLoadingScreen extends LitElement { pointer-events: auto; } .content { - height: calc(100% - 64px); + height: calc(100% - var(--header-height)); display: flex; align-items: center; justify-content: center; diff --git a/src/layouts/hass-subpage.ts b/src/layouts/hass-subpage.ts index ee7a5529aa..72afdffa1c 100644 --- a/src/layouts/hass-subpage.ts +++ b/src/layouts/hass-subpage.ts @@ -97,7 +97,7 @@ class HassSubpage extends LitElement { .content { position: relative; width: 100%; - height: calc(100% - 65px); + height: calc(100% - 1px - var(--header-height)); overflow-y: auto; overflow: auto; -webkit-overflow-scrolling: touch; diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index 2785eac9d8..9af3dd8317 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -227,7 +227,7 @@ export class HaTabsSubpageDataTable extends LitElement { --data-table-border-width: 0; } :host(:not([narrow])) ha-data-table { - height: calc(100vh - 65px); + height: calc(100vh - 1px - var(--header-height)); display: block; } .table-header { diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index c110a02836..24b5ca9f9a 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -278,9 +278,10 @@ class HassTabsSubpage extends LitElement { ); margin-left: env(safe-area-inset-left); margin-right: env(safe-area-inset-right); - height: calc(100% - 65px); - height: calc(100% - 65px - env(safe-area-inset-bottom)); - overflow-y: auto; + height: calc(100% - 1px - var(--header-height)); + height: calc( + 100% - 1px - var(--header-height) - env(safe-area-inset-bottom) + ); overflow: auto; -webkit-overflow-scrolling: touch; } diff --git a/src/panels/calendar/ha-panel-calendar.ts b/src/panels/calendar/ha-panel-calendar.ts index 58aefd8146..692194b06f 100644 --- a/src/panels/calendar/ha-panel-calendar.ts +++ b/src/panels/calendar/ha-panel-calendar.ts @@ -179,7 +179,7 @@ class PanelCalendar extends LitElement { } :host(:not([narrow])) .content { - height: calc(100vh - 64px); + height: calc(100vh - var(--header-height); } .calendar-list { diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts index 1ab567785a..85ffc4a26a 100644 --- a/src/panels/config/entities/ha-config-entities.ts +++ b/src/panels/config/entities/ha-config-entities.ts @@ -834,7 +834,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) { --data-table-border-width: 0; } :host(:not([narrow])) ha-data-table { - height: calc(100vh - 65px); + height: calc(100vh - 1px - var(--header-height)); display: block; } ha-button-menu { diff --git a/src/panels/iframe/ha-panel-iframe.js b/src/panels/iframe/ha-panel-iframe.js index b7ebf03359..28d220de25 100644 --- a/src/panels/iframe/ha-panel-iframe.js +++ b/src/panels/iframe/ha-panel-iframe.js @@ -13,7 +13,7 @@ class HaPanelIframe extends PolymerElement { border: 0; width: 100%; position: absolute; - height: calc(100% - 64px); + height: calc(100% - var(--header-height)); background-color: var(--primary-background-color); } diff --git a/src/panels/lovelace/cards/hui-starting-card.ts b/src/panels/lovelace/cards/hui-starting-card.ts index 668cbce764..883cca483c 100644 --- a/src/panels/lovelace/cards/hui-starting-card.ts +++ b/src/panels/lovelace/cards/hui-starting-card.ts @@ -57,7 +57,7 @@ export class HuiStartingCard extends LitElement implements LovelaceCard { return css` :host { display: block; - height: calc(100vh - 64px); + height: calc(100vh - var(--header-height)); } ha-circular-progress { padding-bottom: 20px; diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index f789e3303e..740c5a7afb 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -3,11 +3,15 @@ import "@material/mwc-list/mwc-list-item"; import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item"; import { mdiClose, + mdiCog, mdiDotsVertical, + mdiHelp, mdiHelpCircle, mdiMicrophone, mdiPencil, mdiPlus, + mdiRefresh, + mdiShape, } from "@mdi/js"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-scroll-effects/effects/waterfall"; @@ -21,6 +25,7 @@ import { LitElement, property, PropertyValues, + query, TemplateResult, } from "lit-element"; import { classMap } from "lit-html/directives/class-map"; @@ -51,6 +56,7 @@ import { } from "../../dialogs/generic/show-dialog-box"; import { showVoiceCommandDialog } from "../../dialogs/voice-command-dialog/show-ha-voice-command-dialog"; import "../../layouts/ha-app-layout"; +import type { haAppLayout } from "../../layouts/ha-app-layout"; import { haStyle } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; import { documentationUrl } from "../../util/documentation-url"; @@ -72,6 +78,8 @@ class HUIRoot extends LitElement { @internalProperty() private _curView?: number | "hass-unused-entities"; + @query("ha-app-layout", true) private _appLayout!: haAppLayout; + private _viewCache?: { [viewId: string]: HUIView }; private _debouncedConfigChanged: () => void; @@ -187,11 +195,50 @@ class HUIRoot extends LitElement { .hass=${this.hass} .narrow=${this.narrow} > -
${this.config.title || "Home Assistant"}
- ${this._conversation(this.hass.config.components) + ${this.lovelace!.config.views.length > 1 + ? html` + + ${this.lovelace!.config.views.map( + (view) => html` + e.user === this.hass!.user!.id + )) || + view.visible === false) + ), + })}" + > + ${view.icon + ? html` + + ` + : view.title || "Unnamed view"} + + ` + )} + + ` + : html`
${this.config.title}
`} + ${!this.narrow && + this._conversation(this.hass.config.components) ? html` @@ -210,27 +257,63 @@ class HUIRoot extends LitElement { > + ${this.narrow && + this._conversation(this.hass.config.components) + ? html` + + ${this.hass!.localize( + "ui.panel.lovelace.menu.start_conversation" + )} + + + ` + : ""} ${this._yamlMode ? html` - ${this.hass!.localize( - "ui.panel.lovelace.menu.refresh" - )} + ${this.hass!.localize( + "ui.panel.lovelace.menu.refresh" + )} + - ${this.hass!.localize( - "ui.panel.lovelace.unused_entities.title" - )} + ${this.hass!.localize( + "ui.panel.lovelace.unused_entities.title" + )} + ` : ""} @@ -238,6 +321,7 @@ class HUIRoot extends LitElement { ?.mode === "yaml" ? html` ` : ""} ${this.hass!.user?.is_admin && !this.hass!.config.safe_mode ? html` ` : ""} @@ -270,17 +363,22 @@ class HUIRoot extends LitElement { target="_blank" > ${this.hass!.localize("ui.panel.lovelace.menu.help")} + `} - ${this.lovelace!.config.views.length > 1 || this._editMode + ${this._editMode ? html`
-
+
`; } @@ -443,10 +534,7 @@ class HUIRoot extends LitElement { if (!oldLovelace || oldLovelace.editMode !== this.lovelace!.editMode) { const views = this.config && this.config.views; - // Adjust for higher header - if (!views || views.length < 2) { - fireEvent(this, "iron-resize"); - } + fireEvent(this, "iron-resize"); // Leave unused entities when leaving edit mode if ( @@ -643,12 +731,6 @@ class HUIRoot extends LitElement { unusedEntities.lovelace = this.lovelace!; unusedEntities.narrow = this.narrow; }); - if (this.config.background) { - unusedEntities.style.setProperty( - "--lovelace-background", - this.config.background - ); - } root.appendChild(unusedEntities); return; } @@ -675,7 +757,12 @@ class HUIRoot extends LitElement { const configBackground = viewConfig.background || this.config.background; if (configBackground) { - view.style.setProperty("--lovelace-background", configBackground); + this._appLayout.style.setProperty( + "--lovelace-background", + configBackground + ); + } else { + this._appLayout.style.removeProperty("--lovelace-background"); } root.appendChild(view); @@ -697,13 +784,19 @@ class HUIRoot extends LitElement { ha-app-layout { min-height: 100%; + background: var(--lovelace-background); } ha-tabs { - margin-left: max(env(safe-area-inset-left), 24px); - margin-right: max(env(safe-area-inset-right), 24px); + width: 100%; + height: 100%; + margin-left: 4px; --paper-tabs-selection-bar-color: var(--text-primary-color, #fff); text-transform: uppercase; } + .edit-mode ha-tabs { + margin-left: max(env(safe-area-inset-left), 24px); + margin-right: max(env(safe-area-inset-right), 24px); + } .edit-mode { background-color: var(--dark-color, #455a64); color: var(--text-dark-color); @@ -738,7 +831,7 @@ class HUIRoot extends LitElement { color: var(--error-color); } #view { - min-height: calc(100vh - 112px); + min-height: calc(100vh - var(--header-height)); /** * Since we only set min-height, if child nodes need percentage * heights they must use absolute positioning so we need relative @@ -761,9 +854,6 @@ class HUIRoot extends LitElement { flex: 1 1 100%; max-width: 100%; } - #view.tabs-hidden { - min-height: calc(100vh - 64px); - } .hide-tab { display: none; } diff --git a/src/panels/lovelace/views/hui-masonry-view.ts b/src/panels/lovelace/views/hui-masonry-view.ts index 2f0f3320b7..00555cd6b1 100644 --- a/src/panels/lovelace/views/hui-masonry-view.ts +++ b/src/panels/lovelace/views/hui-masonry-view.ts @@ -260,7 +260,6 @@ export class MasonryView extends LitElement implements LovelaceViewElement { return css` :host { display: block; - background: var(--lovelace-background); padding-top: 4px; height: 100%; box-sizing: border-box; diff --git a/src/panels/lovelace/views/hui-panel-view.ts b/src/panels/lovelace/views/hui-panel-view.ts index 2a5fac507b..2b9c5ae1e0 100644 --- a/src/panels/lovelace/views/hui-panel-view.ts +++ b/src/panels/lovelace/views/hui-panel-view.ts @@ -131,7 +131,6 @@ export class PanelView extends LitElement implements LovelaceViewElement { return css` :host { display: block; - background: var(--lovelace-background); height: 100%; } diff --git a/src/panels/mailbox/ha-dialog-show-audio-message.js b/src/panels/mailbox/ha-dialog-show-audio-message.js index d288138881..790d3b4ab6 100644 --- a/src/panels/mailbox/ha-dialog-show-audio-message.js +++ b/src/panels/mailbox/ha-dialog-show-audio-message.js @@ -21,7 +21,7 @@ class HaDialogShowAudioMessage extends LocalizeMixin(PolymerElement) { ha-paper-dialog { margin: 0; width: 100%; - max-height: calc(100% - 64px); + max-height: calc(100% - var(--header-height)); position: fixed !important; bottom: 0px; diff --git a/src/panels/map/ha-panel-map.js b/src/panels/map/ha-panel-map.js index a3c2d5103b..f6b299526a 100644 --- a/src/panels/map/ha-panel-map.js +++ b/src/panels/map/ha-panel-map.js @@ -25,7 +25,7 @@ class HaPanelMap extends LocalizeMixin(PolymerElement) { return html`