mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 07:16:39 +00:00
Replace paper tabs by shoelace tabs (#24909)
This commit is contained in:
parent
a6c9702ab2
commit
430e47c0fc
@ -182,6 +182,7 @@ module.exports.babelOptions = ({
|
|||||||
include: /\/node_modules\//,
|
include: /\/node_modules\//,
|
||||||
exclude: [
|
exclude: [
|
||||||
"element-internals-polyfill",
|
"element-internals-polyfill",
|
||||||
|
"@shoelace-style",
|
||||||
"@?lit(?:-labs|-element|-html)?",
|
"@?lit(?:-labs|-element|-html)?",
|
||||||
].map((p) => new RegExp(`/node_modules/${p}/`)),
|
].map((p) => new RegExp(`/node_modules/${p}/`)),
|
||||||
},
|
},
|
||||||
|
@ -3,7 +3,6 @@ export const demoThemeJimpower = () => ({
|
|||||||
"paper-item-icon-color": "var(--primary-text-color)",
|
"paper-item-icon-color": "var(--primary-text-color)",
|
||||||
"primary-color": "#5294E2",
|
"primary-color": "#5294E2",
|
||||||
"label-badge-red": "var(--accent-color)",
|
"label-badge-red": "var(--accent-color)",
|
||||||
"paper-tabs-selection-bar-color": "green",
|
|
||||||
"light-primary-color": "var(--accent-color)",
|
"light-primary-color": "var(--accent-color)",
|
||||||
"primary-background-color": "#383C45",
|
"primary-background-color": "#383C45",
|
||||||
"primary-text-color": "#FFFFFF",
|
"primary-text-color": "#FFFFFF",
|
||||||
|
@ -4,7 +4,6 @@ export const demoThemeKernehed = () => ({
|
|||||||
"paper-item-icon-color": "var(--primary-text-color)",
|
"paper-item-icon-color": "var(--primary-text-color)",
|
||||||
"primary-color": "#2980b9",
|
"primary-color": "#2980b9",
|
||||||
"label-badge-red": "var(--accent-color)",
|
"label-badge-red": "var(--accent-color)",
|
||||||
"paper-tabs-selection-bar-color": "green",
|
|
||||||
"primary-text-color": "#FFFFFF",
|
"primary-text-color": "#FFFFFF",
|
||||||
"light-primary-color": "var(--accent-color)",
|
"light-primary-color": "var(--accent-color)",
|
||||||
"primary-background-color": "#222222",
|
"primary-background-color": "#222222",
|
||||||
|
@ -86,7 +86,6 @@
|
|||||||
"@mdi/svg": "7.4.47",
|
"@mdi/svg": "7.4.47",
|
||||||
"@polymer/paper-item": "3.0.1",
|
"@polymer/paper-item": "3.0.1",
|
||||||
"@polymer/paper-listbox": "3.0.1",
|
"@polymer/paper-listbox": "3.0.1",
|
||||||
"@polymer/paper-tabs": "3.1.0",
|
|
||||||
"@polymer/polymer": "3.5.2",
|
"@polymer/polymer": "3.5.2",
|
||||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||||
"@shoelace-style/shoelace": "2.20.1",
|
"@shoelace-style/shoelace": "2.20.1",
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import type { PaperIconButtonElement } from "@polymer/paper-icon-button/paper-icon-button";
|
|
||||||
import type { PaperTabElement } from "@polymer/paper-tabs/paper-tab";
|
|
||||||
import "@polymer/paper-tabs/paper-tabs";
|
|
||||||
import type { PaperTabsElement } from "@polymer/paper-tabs/paper-tabs";
|
|
||||||
import { customElement } from "lit/decorators";
|
|
||||||
import type { Constructor } from "../types";
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
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;
|
|
||||||
|
|
||||||
private _lastRightHiddenState = 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(`
|
|
||||||
#selectionBar {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.not-visible {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
paper-icon-button {
|
|
||||||
width: 24px;
|
|
||||||
height: 48px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return subTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get first and last tab's width for _affectScroll
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
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();
|
|
||||||
this._affectScroll(0); // Ensure scroll arrows match scroll position
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
public _affectScroll(dx: number): void {
|
|
||||||
if (this._firstTabWidth === 0 || this._lastTabWidth === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$.tabsContainer.scrollLeft += dx;
|
|
||||||
|
|
||||||
const scrollLeft = this.$.tabsContainer.scrollLeft;
|
|
||||||
const dirRTL = this.dir === "rtl";
|
|
||||||
|
|
||||||
const boolCondition1 = Math.abs(scrollLeft) < this._firstTabWidth;
|
|
||||||
const boolCondition2 =
|
|
||||||
Math.abs(scrollLeft) + this._lastTabWidth > this._tabContainerScrollSize;
|
|
||||||
|
|
||||||
this._leftHidden = !dirRTL ? boolCondition1 : boolCondition2;
|
|
||||||
this._rightHidden = !dirRTL ? boolCondition2 : boolCondition1;
|
|
||||||
|
|
||||||
if (!dirRTL) {
|
|
||||||
if (this._lastLeftHiddenState !== this._leftHidden) {
|
|
||||||
this._lastLeftHiddenState = this._leftHidden;
|
|
||||||
this.$.tabsContainer.scrollLeft += this._leftHidden ? -23 : 23;
|
|
||||||
}
|
|
||||||
} else if (this._lastRightHiddenState !== this._rightHidden) {
|
|
||||||
this._lastRightHiddenState = this._rightHidden;
|
|
||||||
this.$.tabsContainer.scrollLeft -= this._rightHidden ? -23 : 23;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"ha-tabs": HaTabs;
|
|
||||||
}
|
|
||||||
}
|
|
159
src/components/sl-tab-group.ts
Normal file
159
src/components/sl-tab-group.ts
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
import TabGroup from "@shoelace-style/shoelace/dist/components/tab-group/tab-group.component";
|
||||||
|
import TabGroupStyles from "@shoelace-style/shoelace/dist/components/tab-group/tab-group.styles";
|
||||||
|
import "@shoelace-style/shoelace/dist/components/tab/tab";
|
||||||
|
import type { PropertyValues } from "lit";
|
||||||
|
import { css } from "lit";
|
||||||
|
import { customElement, query } from "lit/decorators";
|
||||||
|
|
||||||
|
@customElement("sl-tab-group")
|
||||||
|
// @ts-ignore
|
||||||
|
export class HaSlTabGroup extends TabGroup {
|
||||||
|
private _mouseIsDown = false;
|
||||||
|
|
||||||
|
private _scrolled = false;
|
||||||
|
|
||||||
|
private _mouseReleasedAt?: number;
|
||||||
|
|
||||||
|
private _scrollStartX = 0;
|
||||||
|
|
||||||
|
private _scrollLeft = 0;
|
||||||
|
|
||||||
|
@query(".tab-group__nav", true) private _scrollContainer?: HTMLElement;
|
||||||
|
|
||||||
|
public disconnectedCallback(): void {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
window.removeEventListener("mousemove", this._mouseMove);
|
||||||
|
}
|
||||||
|
|
||||||
|
override setAriaLabels() {
|
||||||
|
// Override the method to prevent setting aria-labels, as we don't use panels
|
||||||
|
// and don't want to set aria-labels for the tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
override getAllPanels() {
|
||||||
|
// Override the method to prevent querying for panels
|
||||||
|
// and return an empty array instead
|
||||||
|
// as we don't use panels
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override firstUpdated(_changedProperties: PropertyValues): void {
|
||||||
|
super.firstUpdated(_changedProperties);
|
||||||
|
|
||||||
|
const scrollContainer = this._scrollContainer;
|
||||||
|
|
||||||
|
if (scrollContainer) {
|
||||||
|
scrollContainer.addEventListener("mousedown", this._mouseDown);
|
||||||
|
scrollContainer.addEventListener("mouseup", this._mouseUp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
protected override handleClick(event: MouseEvent) {
|
||||||
|
if (
|
||||||
|
this._mouseReleasedAt &&
|
||||||
|
new Date().getTime() - this._mouseReleasedAt < 100
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
super.handleClick(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _mouseDown = (event: MouseEvent) => {
|
||||||
|
const scrollContainer = this._scrollContainer;
|
||||||
|
|
||||||
|
if (!scrollContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._scrollStartX = event.pageX - scrollContainer.offsetLeft;
|
||||||
|
this._scrollLeft = scrollContainer.scrollLeft;
|
||||||
|
this._mouseIsDown = true;
|
||||||
|
this._scrolled = false;
|
||||||
|
|
||||||
|
window.addEventListener("mousemove", this._mouseMove);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _mouseUp = () => {
|
||||||
|
this._mouseIsDown = false;
|
||||||
|
if (this._scrolled) {
|
||||||
|
this._mouseReleasedAt = new Date().getTime();
|
||||||
|
}
|
||||||
|
window.removeEventListener("mousemove", this._mouseMove);
|
||||||
|
};
|
||||||
|
|
||||||
|
private _mouseMove = (event: MouseEvent) => {
|
||||||
|
if (!this._mouseIsDown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollContainer = this._scrollContainer;
|
||||||
|
|
||||||
|
if (!scrollContainer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const x = event.pageX - scrollContainer.offsetLeft;
|
||||||
|
const scroll = x - this._scrollStartX;
|
||||||
|
|
||||||
|
if (!this._scrolled) {
|
||||||
|
this._scrolled = Math.abs(scroll) > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollContainer.scrollLeft = this._scrollLeft - scroll;
|
||||||
|
};
|
||||||
|
|
||||||
|
static override styles = [
|
||||||
|
TabGroupStyles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
--sl-spacing-3x-small: 0.125rem;
|
||||||
|
--sl-spacing-2x-small: 0.25rem;
|
||||||
|
--sl-spacing-x-small: 0.5rem;
|
||||||
|
--sl-spacing-small: 0.75rem;
|
||||||
|
--sl-spacing-medium: 1rem;
|
||||||
|
--sl-spacing-large: 1.25rem;
|
||||||
|
--sl-spacing-x-large: 1.75rem;
|
||||||
|
--sl-spacing-2x-large: 2.25rem;
|
||||||
|
--sl-spacing-3x-large: 3rem;
|
||||||
|
--sl-spacing-4x-large: 4.5rem;
|
||||||
|
|
||||||
|
--sl-transition-x-slow: 1000ms;
|
||||||
|
--sl-transition-slow: 500ms;
|
||||||
|
--sl-transition-medium: 250ms;
|
||||||
|
--sl-transition-fast: 150ms;
|
||||||
|
--sl-transition-x-fast: 50ms;
|
||||||
|
--transition-speed: var(--sl-transition-fast);
|
||||||
|
--sl-border-radius-small: 0.1875rem;
|
||||||
|
--sl-border-radius-medium: 0.25rem;
|
||||||
|
--sl-border-radius-large: 0.5rem;
|
||||||
|
--sl-border-radius-x-large: 1rem;
|
||||||
|
--sl-border-radius-circle: 50%;
|
||||||
|
--sl-border-radius-pill: 9999px;
|
||||||
|
|
||||||
|
--sl-color-neutral-600: inherit;
|
||||||
|
|
||||||
|
--sl-font-weight-semibold: 500;
|
||||||
|
--sl-font-size-small: 14px;
|
||||||
|
|
||||||
|
--sl-color-primary-600: var(
|
||||||
|
--ha-tab-active-text-color,
|
||||||
|
var(--primary-color)
|
||||||
|
);
|
||||||
|
--track-color: var(--ha-tab-track-color, var(--divider-color));
|
||||||
|
--indicator-color: var(--ha-tab-indicator-color, var(--primary-color));
|
||||||
|
}
|
||||||
|
::slotted(sl-tab:not([active])) {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
// @ts-ignore
|
||||||
|
"sl-tab-group": HaSlTabGroup;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,4 @@
|
|||||||
import { mdiDotsVertical } from "@mdi/js";
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
import "@polymer/paper-tabs/paper-tab";
|
|
||||||
import "@polymer/paper-tabs/paper-tabs";
|
|
||||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
@ -10,6 +8,7 @@ import "../../components/ha-menu-button";
|
|||||||
import "../../components/ha-button-menu";
|
import "../../components/ha-button-menu";
|
||||||
import "../../components/ha-icon-button";
|
import "../../components/ha-icon-button";
|
||||||
import "../../components/ha-list-item";
|
import "../../components/ha-list-item";
|
||||||
|
import "../../components/sl-tab-group";
|
||||||
import { haStyle } from "../../resources/styles";
|
import { haStyle } from "../../resources/styles";
|
||||||
import type { HomeAssistant, Route } from "../../types";
|
import type { HomeAssistant, Route } from "../../types";
|
||||||
import "./developer-tools-router";
|
import "./developer-tools-router";
|
||||||
@ -51,36 +50,37 @@ class PanelDeveloperTools extends LitElement {
|
|||||||
</ha-list-item>
|
</ha-list-item>
|
||||||
</ha-button-menu>
|
</ha-button-menu>
|
||||||
</div>
|
</div>
|
||||||
<paper-tabs
|
<sl-tab-group @sl-tab-show=${this._handlePageSelected}>
|
||||||
scrollable
|
<sl-tab slot="nav" panel="yaml" .active=${page === "yaml"}>
|
||||||
attr-for-selected="page-name"
|
|
||||||
.selected=${page}
|
|
||||||
@selected-changed=${this._handlePageSelected}
|
|
||||||
>
|
|
||||||
<paper-tab page-name="yaml">
|
|
||||||
${this.hass.localize("ui.panel.developer-tools.tabs.yaml.title")}
|
${this.hass.localize("ui.panel.developer-tools.tabs.yaml.title")}
|
||||||
</paper-tab>
|
</sl-tab>
|
||||||
<paper-tab page-name="state">
|
<sl-tab slot="nav" panel="state" .active=${page === "state"}>
|
||||||
${this.hass.localize("ui.panel.developer-tools.tabs.states.title")}
|
${this.hass.localize("ui.panel.developer-tools.tabs.states.title")}
|
||||||
</paper-tab>
|
</sl-tab>
|
||||||
<paper-tab page-name="action">
|
<sl-tab slot="nav" panel="action" .active=${page === "action"}>
|
||||||
${this.hass.localize("ui.panel.developer-tools.tabs.actions.title")}
|
${this.hass.localize("ui.panel.developer-tools.tabs.actions.title")}
|
||||||
</paper-tab>
|
</sl-tab>
|
||||||
<paper-tab page-name="template">
|
<sl-tab slot="nav" panel="template" .active=${page === "template"}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.developer-tools.tabs.templates.title"
|
"ui.panel.developer-tools.tabs.templates.title"
|
||||||
)}
|
)}
|
||||||
</paper-tab>
|
</sl-tab>
|
||||||
<paper-tab page-name="event">
|
<sl-tab slot="nav" panel="event" .active=${page === "event"}>
|
||||||
${this.hass.localize("ui.panel.developer-tools.tabs.events.title")}
|
${this.hass.localize("ui.panel.developer-tools.tabs.events.title")}
|
||||||
</paper-tab>
|
</sl-tab>
|
||||||
<paper-tab page-name="statistics">
|
<sl-tab
|
||||||
|
slot="nav"
|
||||||
|
panel="statistics"
|
||||||
|
.active=${page === "statistics"}
|
||||||
|
>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.developer-tools.tabs.statistics.title"
|
"ui.panel.developer-tools.tabs.statistics.title"
|
||||||
)}
|
)}
|
||||||
</paper-tab>
|
</sl-tab>
|
||||||
<paper-tab page-name="assist">Assist</paper-tab>
|
<sl-tab slot="nav" panel="assist" .active=${page === "assist"}
|
||||||
</paper-tabs>
|
>Assist</sl-tab
|
||||||
|
>
|
||||||
|
</sl-tab-group>
|
||||||
</div>
|
</div>
|
||||||
<developer-tools-router
|
<developer-tools-router
|
||||||
.route=${this.route}
|
.route=${this.route}
|
||||||
@ -90,8 +90,11 @@ class PanelDeveloperTools extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handlePageSelected(ev) {
|
private _handlePageSelected(ev: CustomEvent<{ name: string }>) {
|
||||||
const newPage = ev.detail.value;
|
const newPage = ev.detail.name;
|
||||||
|
if (!newPage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (newPage !== this._page) {
|
if (newPage !== this._page) {
|
||||||
navigate(`/developer-tools/${newPage}`);
|
navigate(`/developer-tools/${newPage}`);
|
||||||
} else {
|
} else {
|
||||||
@ -161,16 +164,10 @@ class PanelDeveloperTools extends LitElement {
|
|||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
paper-tabs {
|
sl-tab-group {
|
||||||
margin-left: max(env(safe-area-inset-left), 24px);
|
--ha-tab-active-text-color: var(--text-primary-color);
|
||||||
margin-right: max(env(safe-area-inset-right), 24px);
|
--ha-tab-track-color: var(--app-header-background-color);
|
||||||
margin-inline-start: max(env(safe-area-inset-left), 24px);
|
--ha-tab-indicator-color: var(--text-primary-color);
|
||||||
margin-inline-end: max(env(safe-area-inset-right), 24px);
|
|
||||||
--paper-tabs-selection-bar-color: var(
|
|
||||||
--app-header-selection-bar-color,
|
|
||||||
var(--app-header-text-color, #fff)
|
|
||||||
);
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
|
@ -6,12 +6,11 @@ import {
|
|||||||
mdiListBoxOutline,
|
mdiListBoxOutline,
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import "@polymer/paper-tabs";
|
|
||||||
import "@polymer/paper-tabs/paper-tab";
|
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import type { CSSResultGroup } from "lit";
|
import type { CSSResultGroup } from "lit";
|
||||||
import { LitElement, css, html, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { keyed } from "lit/directives/keyed";
|
||||||
import {
|
import {
|
||||||
any,
|
any,
|
||||||
array,
|
array,
|
||||||
@ -21,17 +20,17 @@ import {
|
|||||||
optional,
|
optional,
|
||||||
string,
|
string,
|
||||||
} from "superstruct";
|
} from "superstruct";
|
||||||
import { keyed } from "lit/directives/keyed";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
|
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import type {
|
import type {
|
||||||
HaFormSchema,
|
HaFormSchema,
|
||||||
SchemaUnion,
|
SchemaUnion,
|
||||||
} from "../../../../components/ha-form/types";
|
} from "../../../../components/ha-form/types";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
|
||||||
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
|
||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-icon-button";
|
||||||
import "../../../../components/ha-icon-button-arrow-prev";
|
|
||||||
import "../../../../components/ha-icon-button-arrow-next";
|
import "../../../../components/ha-icon-button-arrow-next";
|
||||||
|
import "../../../../components/ha-icon-button-arrow-prev";
|
||||||
|
import "../../../../components/sl-tab-group";
|
||||||
import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
import type { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
||||||
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
@ -124,24 +123,18 @@ export class HuiStackCardEditor
|
|||||||
></ha-form>
|
></ha-form>
|
||||||
<div class="card-config">
|
<div class="card-config">
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<paper-tabs
|
<sl-tab-group @sl-tab-show=${this._handleSelectedCard}>
|
||||||
.selected=${selected}
|
|
||||||
scrollable
|
|
||||||
@iron-activate=${this._handleSelectedCard}
|
|
||||||
>
|
|
||||||
${this._config.cards.map(
|
${this._config.cards.map(
|
||||||
(_card, i) => html` <paper-tab> ${i + 1} </paper-tab> `
|
(_card, i) =>
|
||||||
|
html`<sl-tab slot="nav" .panel=${i} .active=${i === selected}>
|
||||||
|
${i + 1}
|
||||||
|
</sl-tab>`
|
||||||
)}
|
)}
|
||||||
</paper-tabs>
|
</sl-tab-group>
|
||||||
<paper-tabs
|
<ha-icon-button
|
||||||
id="add-card"
|
@click=${this._handleAddCard}
|
||||||
.selected=${selected === numcards ? "0" : undefined}
|
.path=${mdiPlus}
|
||||||
@iron-activate=${this._handleSelectedCard}
|
></ha-icon-button>
|
||||||
>
|
|
||||||
<paper-tab>
|
|
||||||
<ha-svg-icon .path=${mdiPlus}></ha-svg-icon>
|
|
||||||
</paper-tab>
|
|
||||||
</paper-tabs>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="editor">
|
<div id="editor">
|
||||||
@ -234,14 +227,16 @@ export class HuiStackCardEditor
|
|||||||
return this._keys.get(key)!;
|
return this._keys.get(key)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async _handleAddCard() {
|
||||||
|
this._selectedCard = this._config!.cards.length;
|
||||||
|
await this.updateComplete;
|
||||||
|
this.renderRoot.querySelector("sl-tab-group")!.syncIndicator();
|
||||||
|
}
|
||||||
|
|
||||||
protected _handleSelectedCard(ev) {
|
protected _handleSelectedCard(ev) {
|
||||||
if (ev.target.id === "add-card") {
|
|
||||||
this._selectedCard = this._config!.cards.length;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._setMode(true);
|
this._setMode(true);
|
||||||
this._guiModeAvailable = true;
|
this._guiModeAvailable = true;
|
||||||
this._selectedCard = parseInt(ev.detail.selected, 10);
|
this._selectedCard = parseInt(ev.detail.name, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
|
protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
|
||||||
@ -344,17 +339,13 @@ export class HuiStackCardEditor
|
|||||||
css`
|
css`
|
||||||
.toolbar {
|
.toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
--paper-tabs-selection-bar-color: var(--primary-color);
|
justify-content: space-between;
|
||||||
--paper-tab-ink: var(--primary-color);
|
align-items: center;
|
||||||
}
|
}
|
||||||
paper-tabs {
|
sl-tab-group {
|
||||||
display: flex;
|
|
||||||
font-size: 14px;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
min-width: 0;
|
||||||
#add-card {
|
--ha-tab-track-color: var(--card-background-color);
|
||||||
max-width: 32px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#card-options {
|
#card-options {
|
||||||
|
@ -15,10 +15,8 @@ import {
|
|||||||
mdiShape,
|
mdiShape,
|
||||||
mdiViewDashboard,
|
mdiViewDashboard,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import "@polymer/paper-tabs/paper-tab";
|
|
||||||
import "@polymer/paper-tabs/paper-tabs";
|
|
||||||
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { ifDefined } from "lit/directives/if-defined";
|
import { ifDefined } from "lit/directives/if-defined";
|
||||||
@ -34,7 +32,6 @@ import {
|
|||||||
extractSearchParamsObject,
|
extractSearchParamsObject,
|
||||||
removeSearchParam,
|
removeSearchParam,
|
||||||
} from "../../common/url/search-params";
|
} from "../../common/url/search-params";
|
||||||
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
|
||||||
import { debounce } from "../../common/util/debounce";
|
import { debounce } from "../../common/util/debounce";
|
||||||
import { afterNextRender } from "../../common/util/render-status";
|
import { afterNextRender } from "../../common/util/render-status";
|
||||||
import "../../components/ha-button-menu";
|
import "../../components/ha-button-menu";
|
||||||
@ -44,7 +41,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 "../../components/sl-tab-group";
|
||||||
import type { LovelacePanelConfig } from "../../data/lovelace";
|
import type { LovelacePanelConfig } from "../../data/lovelace";
|
||||||
import type { LovelaceConfig } from "../../data/lovelace/config/types";
|
import type { LovelaceConfig } from "../../data/lovelace/config/types";
|
||||||
import { isStrategyDashboard } from "../../data/lovelace/config/types";
|
import { isStrategyDashboard } from "../../data/lovelace/config/types";
|
||||||
@ -76,9 +73,9 @@ import { getLovelaceStrategy } from "./strategies/get-strategy";
|
|||||||
import { isLegacyStrategyConfig } from "./strategies/legacy-strategy";
|
import { isLegacyStrategyConfig } from "./strategies/legacy-strategy";
|
||||||
import type { Lovelace } from "./types";
|
import type { Lovelace } from "./types";
|
||||||
import "./views/hui-view";
|
import "./views/hui-view";
|
||||||
import "./views/hui-view-container";
|
|
||||||
import type { HUIView } from "./views/hui-view";
|
import type { HUIView } from "./views/hui-view";
|
||||||
import "./views/hui-view-background";
|
import "./views/hui-view-background";
|
||||||
|
import "./views/hui-view-container";
|
||||||
import { showShortcutsDialog } from "../../dialogs/shortcuts/show-shortcuts-dialog";
|
import { showShortcutsDialog } from "../../dialogs/shortcuts/show-shortcuts-dialog";
|
||||||
|
|
||||||
@customElement("hui-root")
|
@customElement("hui-root")
|
||||||
@ -302,6 +299,77 @@ class HUIRoot extends LitElement {
|
|||||||
|
|
||||||
const background = curViewConfig?.background || this.config.background;
|
const background = curViewConfig?.background || this.config.background;
|
||||||
|
|
||||||
|
const tabs = html`<sl-tab-group @sl-tab-show=${this._handleViewSelected}>
|
||||||
|
${views.map(
|
||||||
|
(view, index) => html`
|
||||||
|
<sl-tab
|
||||||
|
slot="nav"
|
||||||
|
panel=${index}
|
||||||
|
.active=${this._curView === index}
|
||||||
|
aria-label=${ifDefined(view.title)}
|
||||||
|
class=${classMap({
|
||||||
|
icon: Boolean(view.icon),
|
||||||
|
"hide-tab": Boolean(
|
||||||
|
!this._editMode &&
|
||||||
|
view.visible !== undefined &&
|
||||||
|
((Array.isArray(view.visible) &&
|
||||||
|
!view.visible.some(
|
||||||
|
(e) => e.user === this.hass!.user?.id
|
||||||
|
)) ||
|
||||||
|
view.visible === false)
|
||||||
|
),
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
${this._editMode
|
||||||
|
? html`
|
||||||
|
<ha-icon-button-arrow-prev
|
||||||
|
.hass=${this.hass}
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_view.move_left"
|
||||||
|
)}
|
||||||
|
class="edit-icon view"
|
||||||
|
@click=${this._moveViewLeft}
|
||||||
|
.disabled=${this._curView === 0}
|
||||||
|
></ha-icon-button-arrow-prev>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
${view.icon
|
||||||
|
? html`
|
||||||
|
<ha-icon
|
||||||
|
class=${classMap({
|
||||||
|
"child-view-icon": Boolean(view.subview),
|
||||||
|
})}
|
||||||
|
title=${ifDefined(view.title)}
|
||||||
|
.icon=${view.icon}
|
||||||
|
></ha-icon>
|
||||||
|
`
|
||||||
|
: view.title || "Unnamed view"}
|
||||||
|
${this._editMode
|
||||||
|
? html`
|
||||||
|
<ha-icon-button
|
||||||
|
.title=${this.hass!.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_view.edit"
|
||||||
|
)}
|
||||||
|
class="edit-icon view"
|
||||||
|
.path=${mdiPencil}
|
||||||
|
@click=${this._editView}
|
||||||
|
></ha-icon-button>
|
||||||
|
<ha-icon-button-arrow-next
|
||||||
|
.hass=${this.hass}
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_view.move_right"
|
||||||
|
)}
|
||||||
|
class="edit-icon view"
|
||||||
|
@click=${this._moveViewRight}
|
||||||
|
.disabled=${(this._curView! as number) + 1 === views.length}
|
||||||
|
></ha-icon-button-arrow-next>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
</sl-tab>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</sl-tab-group>`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
@ -345,44 +413,7 @@ class HUIRoot extends LitElement {
|
|||||||
${curViewConfig?.subview
|
${curViewConfig?.subview
|
||||||
? html`<div class="main-title">${curViewConfig.title}</div>`
|
? html`<div class="main-title">${curViewConfig.title}</div>`
|
||||||
: views.filter((view) => !view.subview).length > 1
|
: views.filter((view) => !view.subview).length > 1
|
||||||
? html`
|
? tabs
|
||||||
<ha-tabs
|
|
||||||
slot="title"
|
|
||||||
scrollable
|
|
||||||
.selected=${this._curView}
|
|
||||||
@iron-activate=${this._handleViewSelected}
|
|
||||||
dir=${computeRTLDirection(this.hass!)}
|
|
||||||
>
|
|
||||||
${views.map(
|
|
||||||
(view) => html`
|
|
||||||
<paper-tab
|
|
||||||
aria-label=${ifDefined(view.title)}
|
|
||||||
class=${classMap({
|
|
||||||
"hide-tab": Boolean(
|
|
||||||
view.subview ||
|
|
||||||
(view.visible !== undefined &&
|
|
||||||
((Array.isArray(view.visible) &&
|
|
||||||
!view.visible.some(
|
|
||||||
(e) =>
|
|
||||||
e.user === this.hass!.user?.id
|
|
||||||
)) ||
|
|
||||||
view.visible === false))
|
|
||||||
),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
${view.icon
|
|
||||||
? html`
|
|
||||||
<ha-icon
|
|
||||||
title=${ifDefined(view.title)}
|
|
||||||
.icon=${view.icon}
|
|
||||||
></ha-icon>
|
|
||||||
`
|
|
||||||
: view.title || "Unnamed view"}
|
|
||||||
</paper-tab>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</ha-tabs>
|
|
||||||
`
|
|
||||||
: html`
|
: html`
|
||||||
<div class="main-title">
|
<div class="main-title">
|
||||||
${views[0]?.title ?? dashboardTitle}
|
${views[0]?.title ?? dashboardTitle}
|
||||||
@ -392,93 +423,19 @@ class HUIRoot extends LitElement {
|
|||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
${this._editMode
|
${this._editMode
|
||||||
? html`
|
? html`<div class="edit-tab-bar">
|
||||||
<paper-tabs
|
${tabs}
|
||||||
scrollable
|
<ha-icon-button
|
||||||
.selected=${this._curView}
|
slot="nav"
|
||||||
@iron-activate=${this._handleViewSelected}
|
id="add-view"
|
||||||
dir=${computeRTLDirection(this.hass!)}
|
@click=${this._addView}
|
||||||
>
|
.label=${this.hass!.localize(
|
||||||
${views.map(
|
"ui.panel.lovelace.editor.edit_view.add"
|
||||||
(view) => html`
|
|
||||||
<paper-tab
|
|
||||||
aria-label=${ifDefined(view.title)}
|
|
||||||
class=${classMap({
|
|
||||||
"hide-tab": Boolean(
|
|
||||||
!this._editMode &&
|
|
||||||
view.visible !== undefined &&
|
|
||||||
((Array.isArray(view.visible) &&
|
|
||||||
!view.visible.some(
|
|
||||||
(e) => e.user === this.hass!.user?.id
|
|
||||||
)) ||
|
|
||||||
view.visible === false)
|
|
||||||
),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
${this._editMode
|
|
||||||
? html`
|
|
||||||
<ha-icon-button-arrow-prev
|
|
||||||
.hass=${this.hass}
|
|
||||||
.label=${this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.editor.edit_view.move_left"
|
|
||||||
)}
|
|
||||||
class="edit-icon view"
|
|
||||||
@click=${this._moveViewLeft}
|
|
||||||
?disabled=${this._curView === 0}
|
|
||||||
></ha-icon-button-arrow-prev>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
${view.icon
|
|
||||||
? html`
|
|
||||||
<ha-icon
|
|
||||||
class=${classMap({
|
|
||||||
"child-view-icon": Boolean(view.subview),
|
|
||||||
})}
|
|
||||||
title=${ifDefined(view.title)}
|
|
||||||
.icon=${view.icon}
|
|
||||||
></ha-icon>
|
|
||||||
`
|
|
||||||
: view.title || "Unnamed view"}
|
|
||||||
${this._editMode
|
|
||||||
? html`
|
|
||||||
<ha-svg-icon
|
|
||||||
title=${this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.editor.edit_view.edit"
|
|
||||||
)}
|
|
||||||
class="edit-icon view"
|
|
||||||
.path=${mdiPencil}
|
|
||||||
@click=${this._editView}
|
|
||||||
></ha-svg-icon>
|
|
||||||
<ha-icon-button-arrow-next
|
|
||||||
.hass=${this.hass}
|
|
||||||
.label=${this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.editor.edit_view.move_right"
|
|
||||||
)}
|
|
||||||
class="edit-icon view"
|
|
||||||
@click=${this._moveViewRight}
|
|
||||||
?disabled=${(this._curView! as number) + 1 ===
|
|
||||||
views.length}
|
|
||||||
></ha-icon-button-arrow-next>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</paper-tab>
|
|
||||||
`
|
|
||||||
)}
|
)}
|
||||||
${this._editMode
|
.path=${mdiPlus}
|
||||||
? html`
|
></ha-icon-button>
|
||||||
<ha-icon-button
|
</div>`
|
||||||
id="add-view"
|
: nothing}
|
||||||
@click=${this._addView}
|
|
||||||
.label=${this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.editor.edit_view.add"
|
|
||||||
)}
|
|
||||||
.path=${mdiPlus}
|
|
||||||
></ha-icon-button>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</paper-tabs>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
<hui-view-container
|
<hui-view-container
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -949,7 +906,7 @@ class HUIRoot extends LitElement {
|
|||||||
|
|
||||||
private _handleViewSelected(ev) {
|
private _handleViewSelected(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const viewIndex = ev.detail.selected as number;
|
const viewIndex = Number(ev.detail.name);
|
||||||
if (viewIndex !== this._curView) {
|
if (viewIndex !== this._curView) {
|
||||||
const path = this.config.views[viewIndex].path || viewIndex;
|
const path = this.config.views[viewIndex].path || viewIndex;
|
||||||
this._navigateToView(path);
|
this._navigateToView(path);
|
||||||
@ -1082,46 +1039,95 @@ class HUIRoot extends LitElement {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
ha-tabs {
|
sl-tab-group {
|
||||||
width: 100%;
|
--ha-tab-indicator-color: var(
|
||||||
height: 100%;
|
|
||||||
margin-left: 4px;
|
|
||||||
margin-inline-start: 4px;
|
|
||||||
margin-inline-end: initial;
|
|
||||||
}
|
|
||||||
ha-tabs,
|
|
||||||
paper-tabs {
|
|
||||||
--paper-tabs-selection-bar-color: var(
|
|
||||||
--app-header-selection-bar-color,
|
--app-header-selection-bar-color,
|
||||||
var(--app-header-text-color, #fff)
|
var(--app-header-text-color, white)
|
||||||
|
);
|
||||||
|
--ha-tab-active-text-color: var(--app-header-text-color, white);
|
||||||
|
--ha-tab-track-color: transparent;
|
||||||
|
align-self: flex-end;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
sl-tab-group::part(nav) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
sl-tab-group::part(scroll-button) {
|
||||||
|
background-color: var(--app-header-background-color);
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
var(--app-header-background-color),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
sl-tab-group::part(scroll-button--end) {
|
||||||
|
background: linear-gradient(
|
||||||
|
270deg,
|
||||||
|
var(--app-header-background-color),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.edit-mode sl-tab-group::part(scroll-button) {
|
||||||
|
background-color: var(--app-header-edit-background-color, #455a64);
|
||||||
|
background: linear-gradient(
|
||||||
|
90deg,
|
||||||
|
var(--app-header-edit-background-color, #455a64),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.edit-mode sl-tab-group::part(scroll-button--end) {
|
||||||
|
background: linear-gradient(
|
||||||
|
270deg,
|
||||||
|
var(--app-header-edit-background-color, #455a64),
|
||||||
|
transparent
|
||||||
);
|
);
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
}
|
||||||
.edit-mode div[main-title] {
|
.edit-mode div[main-title] {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
.edit-mode paper-tabs {
|
.edit-tab-bar {
|
||||||
background-color: var(--app-header-edit-background-color, #455a64);
|
display: flex;
|
||||||
|
}
|
||||||
|
.edit-mode sl-tab-group {
|
||||||
|
flex-grow: 0;
|
||||||
color: var(--app-header-edit-text-color, #fff);
|
color: var(--app-header-edit-text-color, #fff);
|
||||||
}
|
}
|
||||||
paper-tab.iron-selected .edit-icon {
|
.edit-mode sl-tab {
|
||||||
|
height: 54px;
|
||||||
|
}
|
||||||
|
sl-tab {
|
||||||
|
height: calc(var(--header-height, 56px) - 2px);
|
||||||
|
}
|
||||||
|
sl-tab[aria-selected="true"] .edit-icon {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
sl-tab::part(base) {
|
||||||
|
padding-top: calc((var(--header-height) - 20px) / 2);
|
||||||
|
padding-bottom: calc((var(--header-height) - 20px) / 2 - 2px);
|
||||||
|
}
|
||||||
|
sl-tab.icon::part(base) {
|
||||||
|
padding-top: calc((var(--header-height) - 20px) / 2 - 2px);
|
||||||
|
padding-bottom: calc((var(--header-height) - 20px) / 2 - 4px);
|
||||||
|
}
|
||||||
|
.edit-mode sl-tab[aria-selected="true"]::part(base) {
|
||||||
|
padding: 4px 0 2px 0;
|
||||||
|
}
|
||||||
.edit-icon {
|
.edit-icon {
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
padding-left: 8px;
|
padding: 0 8px;
|
||||||
padding-inline-start: 8px;
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
--mdc-theme-text-disabled-on-light: var(--disabled-text-color);
|
--mdc-theme-text-disabled-on-light: var(--disabled-text-color);
|
||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
}
|
}
|
||||||
|
.edit-icon:last-child {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
.edit-icon.view {
|
.edit-icon.view {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#add-view {
|
|
||||||
position: absolute;
|
|
||||||
height: 44px;
|
|
||||||
}
|
|
||||||
#add-view ha-svg-icon {
|
#add-view ha-svg-icon {
|
||||||
background-color: var(--accent-color);
|
background-color: var(--accent-color);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
122
yarn.lock
122
yarn.lock
@ -3645,17 +3645,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@polymer/iron-checked-element-behavior@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-checked-element-behavior@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-form-element-behavior": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-validatable-behavior": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/2e8b09bb417d13e7c9862e7bb882b486b0b8df56b25f7b551bf671b87606c3a3629b6451695d94eade0d468c8d5723a152d8255ccd94ff354a14cb7ffe4e60b5
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/iron-flex-layout@npm:^3.0.0-pre.26":
|
"@polymer/iron-flex-layout@npm:^3.0.0-pre.26":
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
resolution: "@polymer/iron-flex-layout@npm:3.0.1"
|
resolution: "@polymer/iron-flex-layout@npm:3.0.1"
|
||||||
@ -3665,36 +3654,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@polymer/iron-form-element-behavior@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-form-element-behavior@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/b48f2ae7e29e7762f53c316e006a67ab53f61f9f5b631fd459169889f5b77194766d7d546ffbd2dbd68a0bbe717a26df5e3f8045e7a60dbae05817231c689ed6
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/iron-icon@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-icon@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-flex-layout": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-meta": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/6bea3e965e9b61ed1d3567064e01c6f0e4586a79afe4354b53ef2dffe8b7157e120dc1b83c43df27a7cf27170b2fffbe9d4da4abf6afcdcc9dd7f8b7913bcd60
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/iron-iconset-svg@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-iconset-svg@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-meta": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/22dbad29ef88f0087ee6b5aa95fe45f65190c9ee8274cd3558ee9527e04269b2736d2f0c6eb151b3eb39dc5275c63b3197fe50fbc56fd855295b1fe44114b6ed
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/iron-menu-behavior@npm:^3.0.0-pre.26":
|
"@polymer/iron-menu-behavior@npm:^3.0.0-pre.26":
|
||||||
version: 3.0.2
|
version: 3.0.2
|
||||||
resolution: "@polymer/iron-menu-behavior@npm:3.0.2"
|
resolution: "@polymer/iron-menu-behavior@npm:3.0.2"
|
||||||
@ -3707,24 +3666,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@polymer/iron-meta@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-meta@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/3b4c3f51d60a28f6c54b6bd0f4dfe92ab0ec208701d00a30aefeacf889015d7670a9c9e050024466b59360a15282351f5e02c128f7a6f00189a4aa6bc2546436
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/iron-resizable-behavior@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-resizable-behavior@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/9b4ccdb1602758b9fa05398b7046e7a164ea971e147a81d22e81183d60d697766ba384d9154a5e620cc28d8a4914ae229823d8368b2307c40c749045cab1e27f
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/iron-selector@npm:^3.0.0-pre.26":
|
"@polymer/iron-selector@npm:^3.0.0-pre.26":
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
resolution: "@polymer/iron-selector@npm:3.0.1"
|
resolution: "@polymer/iron-selector@npm:3.0.1"
|
||||||
@ -3734,40 +3675,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@polymer/iron-validatable-behavior@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/iron-validatable-behavior@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-meta": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/d2a88a1f20c04daf1c09a4b95719b2991242f1d83a065bc91f2713c7e6d1d13cf139d7847427f17f2fd31a7ed1f7a95b07a5628c02a3ea111f83f86582fa29a9
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/paper-behaviors@npm:^3.0.0-pre.27":
|
|
||||||
version: 3.0.1
|
|
||||||
resolution: "@polymer/paper-behaviors@npm:3.0.1"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-behaviors": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-checked-element-behavior": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/paper-ripple": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/70e054943c9c37bad903ab591fc92d4a27668ae5025639997d886e8182c81663f59094eaaa9e0900a8f12e6dd825a361afdecc5873cc02561b214305ce4b05f8
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/paper-icon-button@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.2
|
|
||||||
resolution: "@polymer/paper-icon-button@npm:3.0.2"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-icon": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/paper-behaviors": "npm:^3.0.0-pre.27"
|
|
||||||
"@polymer/paper-styles": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/f6e763186538b9adcace8941e2b8405ad1bb9b34059073cf05131f43c1ab3af02b6d9e168a07a645a6186b690ef9e0c4283e4df2521bdb3ea99bc6d23bd14e4d
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/paper-item@npm:3.0.1":
|
"@polymer/paper-item@npm:3.0.1":
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
resolution: "@polymer/paper-item@npm:3.0.1"
|
resolution: "@polymer/paper-item@npm:3.0.1"
|
||||||
@ -3792,16 +3699,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@polymer/paper-ripple@npm:^3.0.0-pre.26":
|
|
||||||
version: 3.0.2
|
|
||||||
resolution: "@polymer/paper-ripple@npm:3.0.2"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-a11y-keys-behavior": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/db2b8e237e175a7b02fa6bed35750f41d80c7885d4a938006272198e6326af85837e265af0e3ab53b38818c47270bb2b8b15a5355f9ce9dd4dc4106d78d64a53
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/paper-styles@npm:^3.0.0-pre.26":
|
"@polymer/paper-styles@npm:^3.0.0-pre.26":
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
resolution: "@polymer/paper-styles@npm:3.0.1"
|
resolution: "@polymer/paper-styles@npm:3.0.1"
|
||||||
@ -3813,24 +3710,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@polymer/paper-tabs@npm:3.1.0":
|
|
||||||
version: 3.1.0
|
|
||||||
resolution: "@polymer/paper-tabs@npm:3.1.0"
|
|
||||||
dependencies:
|
|
||||||
"@polymer/iron-behaviors": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-flex-layout": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-icon": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-iconset-svg": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-menu-behavior": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/iron-resizable-behavior": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/paper-behaviors": "npm:^3.0.0-pre.27"
|
|
||||||
"@polymer/paper-icon-button": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/paper-styles": "npm:^3.0.0-pre.26"
|
|
||||||
"@polymer/polymer": "npm:^3.0.0"
|
|
||||||
checksum: 10/a12accadfd9a8029dbf48663625c79b0d3a83fff63f3b0e84bd7d4ce2b44c327f703bdbfad0f3f7fc7c84f6d895d788fcc9cdca49b0630d80fb0d7a1c9585499
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@polymer/polymer@npm:3.5.2":
|
"@polymer/polymer@npm:3.5.2":
|
||||||
version: 3.5.2
|
version: 3.5.2
|
||||||
resolution: "@polymer/polymer@npm:3.5.2"
|
resolution: "@polymer/polymer@npm:3.5.2"
|
||||||
@ -9637,7 +9516,6 @@ __metadata:
|
|||||||
"@octokit/rest": "npm:21.1.1"
|
"@octokit/rest": "npm:21.1.1"
|
||||||
"@polymer/paper-item": "npm:3.0.1"
|
"@polymer/paper-item": "npm:3.0.1"
|
||||||
"@polymer/paper-listbox": "npm:3.0.1"
|
"@polymer/paper-listbox": "npm:3.0.1"
|
||||||
"@polymer/paper-tabs": "npm:3.1.0"
|
|
||||||
"@polymer/polymer": "npm:3.5.2"
|
"@polymer/polymer": "npm:3.5.2"
|
||||||
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
||||||
"@rsdoctor/rspack-plugin": "npm:1.0.1"
|
"@rsdoctor/rspack-plugin": "npm:1.0.1"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user