Replace paper tabs by shoelace tabs (#24909)
parent
a6c9702ab2
commit
430e47c0fc
|
@ -182,6 +182,7 @@ module.exports.babelOptions = ({
|
|||
include: /\/node_modules\//,
|
||||
exclude: [
|
||||
"element-internals-polyfill",
|
||||
"@shoelace-style",
|
||||
"@?lit(?:-labs|-element|-html)?",
|
||||
].map((p) => new RegExp(`/node_modules/${p}/`)),
|
||||
},
|
||||
|
|
|
@ -3,7 +3,6 @@ export const demoThemeJimpower = () => ({
|
|||
"paper-item-icon-color": "var(--primary-text-color)",
|
||||
"primary-color": "#5294E2",
|
||||
"label-badge-red": "var(--accent-color)",
|
||||
"paper-tabs-selection-bar-color": "green",
|
||||
"light-primary-color": "var(--accent-color)",
|
||||
"primary-background-color": "#383C45",
|
||||
"primary-text-color": "#FFFFFF",
|
||||
|
|
|
@ -4,7 +4,6 @@ export const demoThemeKernehed = () => ({
|
|||
"paper-item-icon-color": "var(--primary-text-color)",
|
||||
"primary-color": "#2980b9",
|
||||
"label-badge-red": "var(--accent-color)",
|
||||
"paper-tabs-selection-bar-color": "green",
|
||||
"primary-text-color": "#FFFFFF",
|
||||
"light-primary-color": "var(--accent-color)",
|
||||
"primary-background-color": "#222222",
|
||||
|
|
|
@ -86,7 +86,6 @@
|
|||
"@mdi/svg": "7.4.47",
|
||||
"@polymer/paper-item": "3.0.1",
|
||||
"@polymer/paper-listbox": "3.0.1",
|
||||
"@polymer/paper-tabs": "3.1.0",
|
||||
"@polymer/polymer": "3.5.2",
|
||||
"@replit/codemirror-indentation-markers": "6.5.3",
|
||||
"@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;
|
||||
}
|
||||
}
|
|
@ -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 "@polymer/paper-tabs/paper-tab";
|
||||
import "@polymer/paper-tabs/paper-tabs";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
|
@ -10,6 +8,7 @@ import "../../components/ha-menu-button";
|
|||
import "../../components/ha-button-menu";
|
||||
import "../../components/ha-icon-button";
|
||||
import "../../components/ha-list-item";
|
||||
import "../../components/sl-tab-group";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../types";
|
||||
import "./developer-tools-router";
|
||||
|
@ -51,36 +50,37 @@ class PanelDeveloperTools extends LitElement {
|
|||
</ha-list-item>
|
||||
</ha-button-menu>
|
||||
</div>
|
||||
<paper-tabs
|
||||
scrollable
|
||||
attr-for-selected="page-name"
|
||||
.selected=${page}
|
||||
@selected-changed=${this._handlePageSelected}
|
||||
>
|
||||
<paper-tab page-name="yaml">
|
||||
<sl-tab-group @sl-tab-show=${this._handlePageSelected}>
|
||||
<sl-tab slot="nav" panel="yaml" .active=${page === "yaml"}>
|
||||
${this.hass.localize("ui.panel.developer-tools.tabs.yaml.title")}
|
||||
</paper-tab>
|
||||
<paper-tab page-name="state">
|
||||
</sl-tab>
|
||||
<sl-tab slot="nav" panel="state" .active=${page === "state"}>
|
||||
${this.hass.localize("ui.panel.developer-tools.tabs.states.title")}
|
||||
</paper-tab>
|
||||
<paper-tab page-name="action">
|
||||
</sl-tab>
|
||||
<sl-tab slot="nav" panel="action" .active=${page === "action"}>
|
||||
${this.hass.localize("ui.panel.developer-tools.tabs.actions.title")}
|
||||
</paper-tab>
|
||||
<paper-tab page-name="template">
|
||||
</sl-tab>
|
||||
<sl-tab slot="nav" panel="template" .active=${page === "template"}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.templates.title"
|
||||
)}
|
||||
</paper-tab>
|
||||
<paper-tab page-name="event">
|
||||
</sl-tab>
|
||||
<sl-tab slot="nav" panel="event" .active=${page === "event"}>
|
||||
${this.hass.localize("ui.panel.developer-tools.tabs.events.title")}
|
||||
</paper-tab>
|
||||
<paper-tab page-name="statistics">
|
||||
</sl-tab>
|
||||
<sl-tab
|
||||
slot="nav"
|
||||
panel="statistics"
|
||||
.active=${page === "statistics"}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.statistics.title"
|
||||
)}
|
||||
</paper-tab>
|
||||
<paper-tab page-name="assist">Assist</paper-tab>
|
||||
</paper-tabs>
|
||||
</sl-tab>
|
||||
<sl-tab slot="nav" panel="assist" .active=${page === "assist"}
|
||||
>Assist</sl-tab
|
||||
>
|
||||
</sl-tab-group>
|
||||
</div>
|
||||
<developer-tools-router
|
||||
.route=${this.route}
|
||||
|
@ -90,8 +90,11 @@ class PanelDeveloperTools extends LitElement {
|
|||
`;
|
||||
}
|
||||
|
||||
private _handlePageSelected(ev) {
|
||||
const newPage = ev.detail.value;
|
||||
private _handlePageSelected(ev: CustomEvent<{ name: string }>) {
|
||||
const newPage = ev.detail.name;
|
||||
if (!newPage) {
|
||||
return;
|
||||
}
|
||||
if (newPage !== this._page) {
|
||||
navigate(`/developer-tools/${newPage}`);
|
||||
} else {
|
||||
|
@ -161,16 +164,10 @@ class PanelDeveloperTools extends LitElement {
|
|||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
paper-tabs {
|
||||
margin-left: max(env(safe-area-inset-left), 24px);
|
||||
margin-right: max(env(safe-area-inset-right), 24px);
|
||||
margin-inline-start: max(env(safe-area-inset-left), 24px);
|
||||
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;
|
||||
sl-tab-group {
|
||||
--ha-tab-active-text-color: var(--text-primary-color);
|
||||
--ha-tab-track-color: var(--app-header-background-color);
|
||||
--ha-tab-indicator-color: var(--text-primary-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
|
|
@ -6,12 +6,11 @@ import {
|
|||
mdiListBoxOutline,
|
||||
mdiPlus,
|
||||
} from "@mdi/js";
|
||||
import "@polymer/paper-tabs";
|
||||
import "@polymer/paper-tabs/paper-tab";
|
||||
import deepClone from "deep-clone-simple";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { keyed } from "lit/directives/keyed";
|
||||
import {
|
||||
any,
|
||||
array,
|
||||
|
@ -21,17 +20,17 @@ import {
|
|||
optional,
|
||||
string,
|
||||
} 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 {
|
||||
HaFormSchema,
|
||||
SchemaUnion,
|
||||
} 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-arrow-prev";
|
||||
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 { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
|
@ -124,24 +123,18 @@ export class HuiStackCardEditor
|
|||
></ha-form>
|
||||
<div class="card-config">
|
||||
<div class="toolbar">
|
||||
<paper-tabs
|
||||
.selected=${selected}
|
||||
scrollable
|
||||
@iron-activate=${this._handleSelectedCard}
|
||||
>
|
||||
<sl-tab-group @sl-tab-show=${this._handleSelectedCard}>
|
||||
${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>
|
||||
<paper-tabs
|
||||
id="add-card"
|
||||
.selected=${selected === numcards ? "0" : undefined}
|
||||
@iron-activate=${this._handleSelectedCard}
|
||||
>
|
||||
<paper-tab>
|
||||
<ha-svg-icon .path=${mdiPlus}></ha-svg-icon>
|
||||
</paper-tab>
|
||||
</paper-tabs>
|
||||
</sl-tab-group>
|
||||
<ha-icon-button
|
||||
@click=${this._handleAddCard}
|
||||
.path=${mdiPlus}
|
||||
></ha-icon-button>
|
||||
</div>
|
||||
|
||||
<div id="editor">
|
||||
|
@ -234,14 +227,16 @@ export class HuiStackCardEditor
|
|||
return this._keys.get(key)!;
|
||||
}
|
||||
|
||||
protected _handleSelectedCard(ev) {
|
||||
if (ev.target.id === "add-card") {
|
||||
protected async _handleAddCard() {
|
||||
this._selectedCard = this._config!.cards.length;
|
||||
return;
|
||||
await this.updateComplete;
|
||||
this.renderRoot.querySelector("sl-tab-group")!.syncIndicator();
|
||||
}
|
||||
|
||||
protected _handleSelectedCard(ev) {
|
||||
this._setMode(true);
|
||||
this._guiModeAvailable = true;
|
||||
this._selectedCard = parseInt(ev.detail.selected, 10);
|
||||
this._selectedCard = parseInt(ev.detail.name, 10);
|
||||
}
|
||||
|
||||
protected _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
|
||||
|
@ -344,17 +339,13 @@ export class HuiStackCardEditor
|
|||
css`
|
||||
.toolbar {
|
||||
display: flex;
|
||||
--paper-tabs-selection-bar-color: var(--primary-color);
|
||||
--paper-tab-ink: var(--primary-color);
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
paper-tabs {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
sl-tab-group {
|
||||
flex-grow: 1;
|
||||
}
|
||||
#add-card {
|
||||
max-width: 32px;
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
--ha-tab-track-color: var(--card-background-color);
|
||||
}
|
||||
|
||||
#card-options {
|
||||
|
|
|
@ -15,10 +15,8 @@ import {
|
|||
mdiShape,
|
||||
mdiViewDashboard,
|
||||
} from "@mdi/js";
|
||||
import "@polymer/paper-tabs/paper-tab";
|
||||
import "@polymer/paper-tabs/paper-tabs";
|
||||
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 { classMap } from "lit/directives/class-map";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
|
@ -34,7 +32,6 @@ import {
|
|||
extractSearchParamsObject,
|
||||
removeSearchParam,
|
||||
} from "../../common/url/search-params";
|
||||
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
||||
import { debounce } from "../../common/util/debounce";
|
||||
import { afterNextRender } from "../../common/util/render-status";
|
||||
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-menu-button";
|
||||
import "../../components/ha-svg-icon";
|
||||
import "../../components/ha-tabs";
|
||||
import "../../components/sl-tab-group";
|
||||
import type { LovelacePanelConfig } from "../../data/lovelace";
|
||||
import type { LovelaceConfig } 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 type { Lovelace } from "./types";
|
||||
import "./views/hui-view";
|
||||
import "./views/hui-view-container";
|
||||
import type { HUIView } from "./views/hui-view";
|
||||
import "./views/hui-view-background";
|
||||
import "./views/hui-view-container";
|
||||
import { showShortcutsDialog } from "../../dialogs/shortcuts/show-shortcuts-dialog";
|
||||
|
||||
@customElement("hui-root")
|
||||
|
@ -302,6 +299,77 @@ class HUIRoot extends LitElement {
|
|||
|
||||
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`
|
||||
<div
|
||||
class=${classMap({
|
||||
|
@ -345,44 +413,7 @@ class HUIRoot extends LitElement {
|
|||
${curViewConfig?.subview
|
||||
? html`<div class="main-title">${curViewConfig.title}</div>`
|
||||
: views.filter((view) => !view.subview).length > 1
|
||||
? html`
|
||||
<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>
|
||||
`
|
||||
? tabs
|
||||
: html`
|
||||
<div class="main-title">
|
||||
${views[0]?.title ?? dashboardTitle}
|
||||
|
@ -392,81 +423,10 @@ class HUIRoot extends LitElement {
|
|||
`}
|
||||
</div>
|
||||
${this._editMode
|
||||
? html`
|
||||
<paper-tabs
|
||||
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(
|
||||
!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
|
||||
? html`
|
||||
? html`<div class="edit-tab-bar">
|
||||
${tabs}
|
||||
<ha-icon-button
|
||||
slot="nav"
|
||||
id="add-view"
|
||||
@click=${this._addView}
|
||||
.label=${this.hass!.localize(
|
||||
|
@ -474,11 +434,8 @@ class HUIRoot extends LitElement {
|
|||
)}
|
||||
.path=${mdiPlus}
|
||||
></ha-icon-button>
|
||||
`
|
||||
: ""}
|
||||
</paper-tabs>
|
||||
`
|
||||
: ""}
|
||||
</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
<hui-view-container
|
||||
.hass=${this.hass}
|
||||
|
@ -949,7 +906,7 @@ class HUIRoot extends LitElement {
|
|||
|
||||
private _handleViewSelected(ev) {
|
||||
ev.preventDefault();
|
||||
const viewIndex = ev.detail.selected as number;
|
||||
const viewIndex = Number(ev.detail.name);
|
||||
if (viewIndex !== this._curView) {
|
||||
const path = this.config.views[viewIndex].path || viewIndex;
|
||||
this._navigateToView(path);
|
||||
|
@ -1082,46 +1039,95 @@ class HUIRoot extends LitElement {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
ha-tabs {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 4px;
|
||||
margin-inline-start: 4px;
|
||||
margin-inline-end: initial;
|
||||
}
|
||||
ha-tabs,
|
||||
paper-tabs {
|
||||
--paper-tabs-selection-bar-color: var(
|
||||
sl-tab-group {
|
||||
--ha-tab-indicator-color: var(
|
||||
--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] {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.edit-mode paper-tabs {
|
||||
background-color: var(--app-header-edit-background-color, #455a64);
|
||||
.edit-tab-bar {
|
||||
display: flex;
|
||||
}
|
||||
.edit-mode sl-tab-group {
|
||||
flex-grow: 0;
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
color: var(--accent-color);
|
||||
padding-left: 8px;
|
||||
padding-inline-start: 8px;
|
||||
padding: 0 8px;
|
||||
vertical-align: middle;
|
||||
--mdc-theme-text-disabled-on-light: var(--disabled-text-color);
|
||||
direction: var(--direction);
|
||||
}
|
||||
.edit-icon:last-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
.edit-icon.view {
|
||||
display: none;
|
||||
}
|
||||
#add-view {
|
||||
position: absolute;
|
||||
height: 44px;
|
||||
}
|
||||
#add-view ha-svg-icon {
|
||||
background-color: var(--accent-color);
|
||||
border-radius: 4px;
|
||||
|
|
122
yarn.lock
122
yarn.lock
|
@ -3645,17 +3645,6 @@ __metadata:
|
|||
languageName: node
|
||||
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":
|
||||
version: 3.0.1
|
||||
resolution: "@polymer/iron-flex-layout@npm:3.0.1"
|
||||
|
@ -3665,36 +3654,6 @@ __metadata:
|
|||
languageName: node
|
||||
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":
|
||||
version: 3.0.2
|
||||
resolution: "@polymer/iron-menu-behavior@npm:3.0.2"
|
||||
|
@ -3707,24 +3666,6 @@ __metadata:
|
|||
languageName: node
|
||||
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":
|
||||
version: 3.0.1
|
||||
resolution: "@polymer/iron-selector@npm:3.0.1"
|
||||
|
@ -3734,40 +3675,6 @@ __metadata:
|
|||
languageName: node
|
||||
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":
|
||||
version: 3.0.1
|
||||
resolution: "@polymer/paper-item@npm:3.0.1"
|
||||
|
@ -3792,16 +3699,6 @@ __metadata:
|
|||
languageName: node
|
||||
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":
|
||||
version: 3.0.1
|
||||
resolution: "@polymer/paper-styles@npm:3.0.1"
|
||||
|
@ -3813,24 +3710,6 @@ __metadata:
|
|||
languageName: node
|
||||
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":
|
||||
version: 3.5.2
|
||||
resolution: "@polymer/polymer@npm:3.5.2"
|
||||
|
@ -9637,7 +9516,6 @@ __metadata:
|
|||
"@octokit/rest": "npm:21.1.1"
|
||||
"@polymer/paper-item": "npm:3.0.1"
|
||||
"@polymer/paper-listbox": "npm:3.0.1"
|
||||
"@polymer/paper-tabs": "npm:3.1.0"
|
||||
"@polymer/polymer": "npm:3.5.2"
|
||||
"@replit/codemirror-indentation-markers": "npm:6.5.3"
|
||||
"@rsdoctor/rspack-plugin": "npm:1.0.1"
|
||||
|
|
Loading…
Reference in New Issue