mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-16 22:06:34 +00:00
Header styling & paper-tabs improvements (#7238)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
d2dd1a43dd
commit
ce80285f8d
@ -98,8 +98,8 @@ class HaMenuButton extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.style.visibility =
|
this.style.display =
|
||||||
newNarrow || this._alwaysVisible ? "initial" : "hidden";
|
newNarrow || this._alwaysVisible ? "initial" : "none";
|
||||||
|
|
||||||
if (!newNarrow) {
|
if (!newNarrow) {
|
||||||
this._hasNotifications = false;
|
this._hasNotifications = false;
|
||||||
|
97
src/components/ha-tabs.ts
Normal file
97
src/components/ha-tabs.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import "@polymer/paper-tabs/paper-tabs";
|
||||||
|
import type { PaperIconButtonElement } from "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
import type { PaperTabElement } from "@polymer/paper-tabs/paper-tab";
|
||||||
|
import type { PaperTabsElement } from "@polymer/paper-tabs/paper-tabs";
|
||||||
|
import { customElement } from "lit-element";
|
||||||
|
import { Constructor } from "../types";
|
||||||
|
|
||||||
|
const PaperTabs = customElements.get("paper-tabs") as Constructor<
|
||||||
|
PaperTabsElement
|
||||||
|
>;
|
||||||
|
|
||||||
|
let subTemplate: HTMLTemplateElement;
|
||||||
|
|
||||||
|
@customElement("ha-tabs")
|
||||||
|
export class HaTabs extends PaperTabs {
|
||||||
|
private _firstTabWidth = 0;
|
||||||
|
|
||||||
|
private _lastTabWidth = 0;
|
||||||
|
|
||||||
|
private _lastLeftHiddenState = false;
|
||||||
|
|
||||||
|
static get template(): HTMLTemplateElement {
|
||||||
|
if (!subTemplate) {
|
||||||
|
subTemplate = (PaperTabs as any).template.cloneNode(true);
|
||||||
|
|
||||||
|
const superStyle = subTemplate.content.querySelector("style");
|
||||||
|
|
||||||
|
// Add "noink" attribute for scroll buttons to disable animation.
|
||||||
|
subTemplate.content
|
||||||
|
.querySelectorAll("paper-icon-button")
|
||||||
|
.forEach((arrow: PaperIconButtonElement) => {
|
||||||
|
arrow.setAttribute("noink", "");
|
||||||
|
});
|
||||||
|
|
||||||
|
superStyle!.appendChild(
|
||||||
|
document.createTextNode(`
|
||||||
|
.not-visible {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:host > paper-icon-button:first-of-type {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
paper-icon-button {
|
||||||
|
margin: 0 -8px 0 0;
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return subTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get first and last tab's width for _affectScroll
|
||||||
|
public _tabChanged(tab: PaperTabElement, old: PaperTabElement): void {
|
||||||
|
super._tabChanged(tab, old);
|
||||||
|
const tabs = this.querySelectorAll("paper-tab:not(.hide-tab)");
|
||||||
|
if (tabs.length > 0) {
|
||||||
|
this._firstTabWidth = tabs[0].clientWidth;
|
||||||
|
this._lastTabWidth = tabs[tabs.length - 1].clientWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll active tab into view if needed.
|
||||||
|
const selected = this.querySelector(".iron-selected");
|
||||||
|
if (selected) {
|
||||||
|
selected.scrollIntoView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify _affectScroll so that when the scroll arrows appear
|
||||||
|
* while scrolling and the tab container shrinks we can counteract
|
||||||
|
* the jump in tab position so that the scroll still appears smooth.
|
||||||
|
*/
|
||||||
|
public _affectScroll(dx: number): void {
|
||||||
|
if (this._firstTabWidth === 0 || this._lastTabWidth === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$.tabsContainer.scrollLeft += dx;
|
||||||
|
|
||||||
|
const scrollLeft = this.$.tabsContainer.scrollLeft;
|
||||||
|
|
||||||
|
this._leftHidden = scrollLeft - this._firstTabWidth < 0;
|
||||||
|
this._rightHidden =
|
||||||
|
scrollLeft + this._lastTabWidth > this._tabContainerScrollSize;
|
||||||
|
|
||||||
|
if (this._lastLeftHiddenState !== this._leftHidden) {
|
||||||
|
this._lastLeftHiddenState = this._leftHidden;
|
||||||
|
this.$.tabsContainer.scrollLeft += this._leftHidden ? -46 : 46;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-tabs": HaTabs;
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
|
|||||||
import "../../layouts/ha-app-layout";
|
import "../../layouts/ha-app-layout";
|
||||||
import "../../components/ha-icon-button";
|
import "../../components/ha-icon-button";
|
||||||
import "@polymer/paper-tabs/paper-tab";
|
import "@polymer/paper-tabs/paper-tab";
|
||||||
import "@polymer/paper-tabs/paper-tabs";
|
import "../../components/ha-tabs";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResultArray,
|
CSSResultArray,
|
||||||
@ -44,7 +44,7 @@ class PanelDeveloperTools extends LitElement {
|
|||||||
></ha-menu-button>
|
></ha-menu-button>
|
||||||
<div main-title>${this.hass.localize("panel.developer_tools")}</div>
|
<div main-title>${this.hass.localize("panel.developer_tools")}</div>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
<paper-tabs
|
<ha-tabs
|
||||||
scrollable
|
scrollable
|
||||||
attr-for-selected="page-name"
|
attr-for-selected="page-name"
|
||||||
.selected=${page}
|
.selected=${page}
|
||||||
@ -70,7 +70,7 @@ class PanelDeveloperTools extends LitElement {
|
|||||||
"ui.panel.developer-tools.tabs.events.title"
|
"ui.panel.developer-tools.tabs.events.title"
|
||||||
)}
|
)}
|
||||||
</paper-tab>
|
</paper-tab>
|
||||||
</paper-tabs>
|
</ha-tabs>
|
||||||
</app-header>
|
</app-header>
|
||||||
<developer-tools-router
|
<developer-tools-router
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
@ -106,8 +106,9 @@ class PanelDeveloperTools extends LitElement {
|
|||||||
display: block;
|
display: block;
|
||||||
height: calc(100vh - 112px);
|
height: calc(100vh - 112px);
|
||||||
}
|
}
|
||||||
paper-tabs {
|
ha-tabs {
|
||||||
margin-left: 12px;
|
margin-left: max(env(safe-area-inset-left), 24px);
|
||||||
|
margin-right: max(env(safe-area-inset-right), 24px);
|
||||||
--paper-tabs-selection-bar-color: #fff;
|
--paper-tabs-selection-bar-color: #fff;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import "@polymer/app-layout/app-header/app-header";
|
|||||||
import "@polymer/app-layout/app-scroll-effects/effects/waterfall";
|
import "@polymer/app-layout/app-scroll-effects/effects/waterfall";
|
||||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||||
import "@polymer/paper-tabs/paper-tab";
|
import "@polymer/paper-tabs/paper-tab";
|
||||||
import "@polymer/paper-tabs/paper-tabs";
|
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
@ -40,6 +39,7 @@ import "../../components/ha-icon-button-arrow-next";
|
|||||||
import "../../components/ha-icon-button-arrow-prev";
|
import "../../components/ha-icon-button-arrow-prev";
|
||||||
import "../../components/ha-menu-button";
|
import "../../components/ha-menu-button";
|
||||||
import "../../components/ha-svg-icon";
|
import "../../components/ha-svg-icon";
|
||||||
|
import "../../components/ha-tabs";
|
||||||
import type {
|
import type {
|
||||||
LovelaceConfig,
|
LovelaceConfig,
|
||||||
LovelacePanelConfig,
|
LovelacePanelConfig,
|
||||||
@ -283,7 +283,7 @@ class HUIRoot extends LitElement {
|
|||||||
${this.lovelace!.config.views.length > 1 || this._editMode
|
${this.lovelace!.config.views.length > 1 || this._editMode
|
||||||
? html`
|
? html`
|
||||||
<div sticky>
|
<div sticky>
|
||||||
<paper-tabs
|
<ha-tabs
|
||||||
scrollable
|
scrollable
|
||||||
.selected="${this._curView}"
|
.selected="${this._curView}"
|
||||||
@iron-activate="${this._handleViewSelected}"
|
@iron-activate="${this._handleViewSelected}"
|
||||||
@ -363,7 +363,7 @@ class HUIRoot extends LitElement {
|
|||||||
</mwc-icon-button>
|
</mwc-icon-button>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</paper-tabs>
|
</ha-tabs>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@ -698,9 +698,9 @@ class HUIRoot extends LitElement {
|
|||||||
ha-app-layout {
|
ha-app-layout {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
}
|
}
|
||||||
paper-tabs {
|
ha-tabs {
|
||||||
margin-left: max(env(safe-area-inset-left), 12px);
|
margin-left: max(env(safe-area-inset-left), 24px);
|
||||||
margin-right: env(safe-area-inset-right);
|
margin-right: max(env(safe-area-inset-right), 24px);
|
||||||
--paper-tabs-selection-bar-color: var(--text-primary-color, #fff);
|
--paper-tabs-selection-bar-color: var(--text-primary-color, #fff);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import "@polymer/paper-input/paper-textarea";
|
|||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-item/paper-item-body";
|
import "@polymer/paper-item/paper-item-body";
|
||||||
import "@polymer/paper-tabs/paper-tab";
|
import "@polymer/paper-tabs/paper-tab";
|
||||||
import "@polymer/paper-tabs/paper-tabs";
|
import "../../components/ha-tabs";
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
/* eslint-plugin-disable lit */
|
/* eslint-plugin-disable lit */
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
@ -46,6 +46,13 @@ class HaPanelMailbox extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ha-tabs {
|
||||||
|
margin-left: max(env(safe-area-inset-left), 24px);
|
||||||
|
margin-right: max(env(safe-area-inset-right), 24px);
|
||||||
|
--paper-tabs-selection-bar-color: #fff;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
.empty {
|
.empty {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
@ -86,7 +93,7 @@ class HaPanelMailbox extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
<div main-title>[[localize('panel.mailbox')]]</div>
|
<div main-title>[[localize('panel.mailbox')]]</div>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
<div sticky hidden$="[[areTabsHidden(platforms)]]">
|
<div sticky hidden$="[[areTabsHidden(platforms)]]">
|
||||||
<paper-tabs
|
<ha-tabs
|
||||||
scrollable
|
scrollable
|
||||||
selected="[[_currentPlatform]]"
|
selected="[[_currentPlatform]]"
|
||||||
on-iron-activate="handlePlatformSelected"
|
on-iron-activate="handlePlatformSelected"
|
||||||
@ -96,7 +103,7 @@ class HaPanelMailbox extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
[[getPlatformName(item)]]
|
[[getPlatformName(item)]]
|
||||||
</paper-tab>
|
</paper-tab>
|
||||||
</template>
|
</template>
|
||||||
</paper-tabs>
|
</ha-tabs>
|
||||||
</div>
|
</div>
|
||||||
</app-header>
|
</app-header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -110,10 +110,12 @@ export const haStyle = css`
|
|||||||
color: var(--app-header-text-color, white);
|
color: var(--app-header-text-color, white);
|
||||||
}
|
}
|
||||||
|
|
||||||
app-toolbar ha-menu-button + [main-title],
|
app-toolbar [main-title] {
|
||||||
app-toolbar ha-icon-button-arrow-prev + [main-title],
|
margin-left: 20px;
|
||||||
app-toolbar ha-icon-button + [main-title] {
|
}
|
||||||
margin-left: 24px;
|
|
||||||
|
ha-menu-button {
|
||||||
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user