Replace paper item in sidebar (#24883)

* replace paper item in sidebar

* make items same height as before

* remove polymer refs

* fix user badge

* replace removed styles (and remove unused)
This commit is contained in:
Bram Kragten 2025-04-10 18:32:38 +02:00 committed by GitHub
parent 7383e3247b
commit 21b3177f95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 314 additions and 767 deletions

View File

@ -1,34 +0,0 @@
diff --git a/lib/legacy/class.js b/lib/legacy/class.js
index aee2511be1cd9bf900ee552bc98190c1631c57c0..f2f499d68bf52034cac9c28307c99e8ce6b8417d 100644
--- a/lib/legacy/class.js
+++ b/lib/legacy/class.js
@@ -304,17 +304,23 @@ function GenerateClassFromInfo(info, Base, behaviors) {
// only proceed if the generated class' prototype has not been registered.
const generatedProto = PolymerGenerated.prototype;
if (!generatedProto.hasOwnProperty(JSCompiler_renameProperty('__hasRegisterFinished', generatedProto))) {
- generatedProto.__hasRegisterFinished = true;
+ // make sure legacy lifecycle is called on the *element*'s prototype
+ // and not the generated class prototype; if the element has been
+ // extended, these are *not* the same.
+ const proto = Object.getPrototypeOf(this);
+ // Only set flag when generated prototype itself is registered,
+ // as this element may be extended from, and needs to run `registered`
+ // on all behaviors on the subclass as well.
+ if (proto === generatedProto) {
+ generatedProto.__hasRegisterFinished = true;
+ }
// ensure superclass is registered first.
super._registered();
// copy properties onto the generated class lazily if we're optimizing,
- if (legacyOptimizations) {
+ if (legacyOptimizations && !Object.hasOwnProperty(generatedProto, '__hasCopiedProperties')) {
+ generatedProto.__hasCopiedProperties = true;
copyPropertiesToProto(generatedProto);
}
- // make sure legacy lifecycle is called on the *element*'s prototype
- // and not the generated class prototype; if the element has been
- // extended, these are *not* the same.
- const proto = Object.getPrototypeOf(this);
let list = lifecycle.beforeRegister;
if (list) {
for (let i=0; i < list.length; i++) {

View File

@ -2,7 +2,7 @@ import defineProvider from "@babel/helper-define-polyfill-provider";
import { join } from "node:path";
import paths from "../paths.cjs";
const POLYFILL_DIR = join(paths.polymer_dir, "src/resources/polyfills");
const POLYFILL_DIR = join(paths.root_dir, "src/resources/polyfills");
// List of polyfill keys with supported browser targets for the functionality
const polyfillSupport = {

View File

@ -20,22 +20,16 @@ module.exports.ignorePackages = () => [];
// Files from NPM packages that we should replace with empty file
module.exports.emptyPackages = ({ isHassioBuild }) =>
[
// Contains all color definitions for all material color sets.
// We don't use it
require.resolve("@polymer/paper-styles/color.js"),
require.resolve("@polymer/paper-styles/default-theme.js"),
// Loads stuff from a CDN
require.resolve("@polymer/font-roboto/roboto.js"),
require.resolve("@vaadin/vaadin-material-styles/typography.js"),
require.resolve("@vaadin/vaadin-material-styles/font-icons.js"),
// Icons in supervisor conflict with icons in HA so we don't load.
isHassioBuild &&
require.resolve(
path.resolve(paths.polymer_dir, "src/components/ha-icon.ts")
path.resolve(paths.root_dir, "src/components/ha-icon.ts")
),
isHassioBuild &&
require.resolve(
path.resolve(paths.polymer_dir, "src/components/ha-icon-picker.ts")
path.resolve(paths.root_dir, "src/components/ha-icon-picker.ts")
),
].filter(Boolean);
@ -50,7 +44,8 @@ module.exports.definedVars = ({ isProdBuild, latestBuild, defineOverlay }) => ({
__HASS_URL__: `\`${
"HASS_URL" in process.env
? process.env.HASS_URL
: "${location.protocol}//${location.host}"
: // eslint-disable-next-line no-template-curly-in-string
"${location.protocol}//${location.host}"
}\``,
"process.env.NODE_ENV": JSON.stringify(
isProdBuild ? "production" : "development"
@ -164,7 +159,7 @@ module.exports.babelOptions = ({
],
],
exclude: [
path.join(paths.polymer_dir, "src/resources/polyfills"),
path.join(paths.root_dir, "src/resources/polyfills"),
...[
"@formatjs/(?:ecma402-abstract|intl-\\w+)",
"@lit-labs/virtualizer/polyfills",

View File

@ -21,7 +21,7 @@ module.exports = {
},
version() {
const version = fs
.readFileSync(path.resolve(paths.polymer_dir, "pyproject.toml"), "utf8")
.readFileSync(path.resolve(paths.root_dir, "pyproject.toml"), "utf8")
.match(/version\W+=\W"(\d{8}\.\d(?:\.dev)?)"/);
if (!version) {
throw Error("Version not found");

View File

@ -169,14 +169,14 @@ const APP_PAGE_ENTRIES = {
gulp.task(
"gen-pages-app-dev",
genPagesDevTask(APP_PAGE_ENTRIES, paths.polymer_dir, paths.app_output_root)
genPagesDevTask(APP_PAGE_ENTRIES, paths.root_dir, paths.app_output_root)
);
gulp.task(
"gen-pages-app-prod",
genPagesProdTask(
APP_PAGE_ENTRIES,
paths.polymer_dir,
paths.root_dir,
paths.app_output_root,
paths.app_output_latest,
paths.app_output_es5

View File

@ -6,8 +6,8 @@ import path from "path";
import paths from "../paths.cjs";
const npmPath = (...parts) =>
path.resolve(paths.polymer_dir, "node_modules", ...parts);
const polyPath = (...parts) => path.resolve(paths.polymer_dir, ...parts);
path.resolve(paths.root_dir, "node_modules", ...parts);
const polyPath = (...parts) => path.resolve(paths.root_dir, ...parts);
const copyFileDir = (fromFile, toDir) =>
fs.copySync(fromFile, path.join(toDir, path.basename(fromFile)));

View File

@ -4,7 +4,7 @@ import gulp from "gulp";
import { join, resolve } from "node:path";
import paths from "../paths.cjs";
const formatjsDir = join(paths.polymer_dir, "node_modules", "@formatjs");
const formatjsDir = join(paths.root_dir, "node_modules", "@formatjs");
const outDir = join(paths.build_dir, "locale-data");
const INTL_POLYFILLS = {

View File

@ -1,7 +1,7 @@
const path = require("path");
module.exports = {
polymer_dir: path.resolve(__dirname, ".."),
root_dir: path.resolve(__dirname, ".."),
build_dir: path.resolve(__dirname, "../build"),
app_output_root: path.resolve(__dirname, "../hass_frontend"),

View File

@ -161,7 +161,7 @@ const createRspackConfig = ({
}),
new rspack.NormalModuleReplacementPlugin(
new RegExp(bundle.emptyPackages({ isHassioBuild }).join("|")),
path.resolve(paths.polymer_dir, "src/util/empty.js")
path.resolve(paths.root_dir, "src/util/empty.js")
),
!isProdBuild && new LogStartCompilePlugin(),
isProdBuild &&

View File

@ -42,7 +42,6 @@ export default tseslint.config(
__VERSION__: false,
__STATIC_PATH__: false,
__SUPERVISOR__: false,
Polymer: true,
},
parser: tseslint.parser,

View File

@ -1,9 +1,6 @@
import "./hassio-main";
import("../../src/resources/ha-style");
import("@polymer/polymer/lib/utils/settings").then(
({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false)
);
const styleEl = document.createElement("style");
styleEl.textContent = `

View File

@ -84,9 +84,6 @@
"@material/web": "2.3.0",
"@mdi/js": "7.4.47",
"@mdi/svg": "7.4.47",
"@polymer/paper-item": "3.0.1",
"@polymer/paper-listbox": "3.0.1",
"@polymer/polymer": "3.5.2",
"@replit/codemirror-indentation-markers": "6.5.3",
"@shoelace-style/shoelace": "2.20.1",
"@thomasloven/round-slider": "0.6.0",
@ -231,9 +228,7 @@
"webpackbar": "7.0.0",
"workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"
},
"_comment": "Polymer 3.2 contained a bug, fixed in https://github.com/Polymer/polymer/pull/5569, add as patch",
"resolutions": {
"@polymer/polymer": "patch:@polymer/polymer@3.5.2#./.yarn/patches/@polymer/polymer/pr-5569.patch",
"@material/mwc-button@^0.25.3": "^0.27.0",
"lit": "2.8.0",
"lit-html": "2.8.0",

View File

@ -134,10 +134,7 @@ export const applyThemesOnElement = (
element.__themes = { cacheKey, keys: newTheme?.keys };
// Set and/or reset styles
if (element.updateStyles) {
// Use updateStyles() method of Polymer elements
element.updateStyles(styles);
} else if (window.ShadyCSS) {
if (window.ShadyCSS) {
// Use ShadyCSS if available
window.ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ element, styles);
} else {

View File

@ -17,15 +17,16 @@ import {
mdiTooltipAccount,
mdiViewDashboard,
} from "@mdi/js";
import "@polymer/paper-item/paper-icon-item";
import type { PaperIconItemElement } from "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { CSSResult, CSSResultGroup, PropertyValues } from "lit";
import { LitElement, css, html, nothing } from "lit";
import { customElement, eventOptions, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import {
customElement,
eventOptions,
property,
state,
query,
} from "lit/decorators";
import memoizeOne from "memoize-one";
import { storage } from "../common/decorators/storage";
import { fireEvent } from "../common/dom/fire_event";
@ -48,7 +49,9 @@ import "./ha-menu-button";
import "./ha-sortable";
import "./ha-svg-icon";
import "./user/ha-user-badge";
import { preventDefault } from "../common/dom/prevent_default";
import "./ha-md-list";
import "./ha-md-list-item";
import type { HaMdListItem } from "./ha-md-list-item";
const SHOW_AFTER_SPACER = ["config", "developer-tools"];
@ -221,6 +224,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
})
private _hiddenPanels: string[] = [];
@query(".tooltip") private _tooltip!: HTMLDivElement;
public hassSubscribe(): UnsubscribeFunc[] {
return this.hass.user?.is_admin
? [
@ -238,13 +243,18 @@ class HaSidebar extends SubscribeMixin(LitElement) {
return nothing;
}
// Show the supervisor as being part of configuration
const selectedPanel = this.route.path?.startsWith("/hassio/")
? "config"
: this.hass.panelUrl;
// prettier-ignore
return html`
${this._renderHeader()}
${this._renderAllPanels()}
${this._renderAllPanels(selectedPanel)}
${this._renderDivider()}
${this._renderNotifications()}
${this._renderUserItem()}
${this._renderUserItem(selectedPanel)}
<div disabled class="bottom-spacer"></div>
<div class="tooltip"></div>
`;
@ -314,9 +324,11 @@ class HaSidebar extends SubscribeMixin(LitElement) {
return;
}
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
if (
this.hass &&
changedProps.get("hass")?.connected === false &&
oldHass?.connected === false &&
this.hass.connected === true
) {
this._subscribePersistentNotifications();
@ -327,9 +339,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
if (!SUPPORT_SCROLL_IF_NEEDED) {
return;
}
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
if (!oldHass || oldHass.panelUrl !== this.hass.panelUrl) {
const selectedEl = this.shadowRoot!.querySelector(".iron-selected");
if (oldHass?.panelUrl !== this.hass.panelUrl) {
const selectedEl = this.shadowRoot!.querySelector(".selected");
if (selectedEl) {
// @ts-ignore
selectedEl.scrollIntoViewIfNeeded();
@ -381,7 +392,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
</div>`;
}
private _renderAllPanels() {
private _renderAllPanels(selectedPanel: string) {
const [beforeSpacer, afterSpacer] = computePanels(
this.hass.panels,
this.hass.defaultPanel,
@ -390,34 +401,26 @@ class HaSidebar extends SubscribeMixin(LitElement) {
this.hass.locale
);
// Show the supervisor as being part of configuration
const selectedPanel = this.route.path?.startsWith("/hassio/")
? "config"
: this.hass.panelUrl;
// prettier-ignore
return html`
<paper-listbox
attr-for-selected="data-panel"
<ha-md-list
class="ha-scrollbar"
.selected=${selectedPanel}
@focusin=${this._listboxFocusIn}
@focusout=${this._listboxFocusOut}
@scroll=${this._listboxScroll}
@keydown=${this._listboxKeydown}
@iron-activate=${preventDefault}
>
${this.editMode
? this._renderPanelsEdit(beforeSpacer)
: this._renderPanels(beforeSpacer)}
? this._renderPanelsEdit(beforeSpacer, selectedPanel)
: this._renderPanels(beforeSpacer, selectedPanel)}
${this._renderSpacer()}
${this._renderPanels(afterSpacer)}
${this._renderPanels(afterSpacer, selectedPanel)}
${this._renderExternalConfiguration()}
</paper-listbox>
</ha-md-list>
`;
}
private _renderPanels(panels: PanelInfo[]) {
private _renderPanels(panels: PanelInfo[], selectedPanel: string) {
return panels.map((panel) =>
this._renderPanel(
panel.url_path,
@ -429,7 +432,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
? PANEL_ICONS.lovelace
: panel.url_path in PANEL_ICONS
? PANEL_ICONS[panel.url_path]
: undefined
: undefined,
selectedPanel
)
);
}
@ -437,30 +441,24 @@ class HaSidebar extends SubscribeMixin(LitElement) {
private _renderPanel(
urlPath: string,
title: string | null,
icon?: string | null,
iconPath?: string | null
icon: string | null | undefined,
iconPath: string | null | undefined,
selectedPanel: string
) {
return urlPath === "config"
? this._renderConfiguration(title)
? this._renderConfiguration(title, selectedPanel)
: html`
<a
role="option"
aria-selected=${urlPath === this.hass.panelUrl}
href=${`/${urlPath}`}
data-panel=${urlPath}
tabindex="-1"
<ha-md-list-item
.href=${this.editMode ? undefined : `/${urlPath}`}
type="link"
class=${selectedPanel === urlPath ? "selected" : ""}
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
>
<paper-icon-item>
${iconPath
? html`<ha-svg-icon
slot="item-icon"
.path=${iconPath}
></ha-svg-icon>`
: html`<ha-icon slot="item-icon" .icon=${icon}></ha-icon>`}
<span class="item-text">${title}</span>
</paper-icon-item>
? html`<ha-svg-icon slot="start" .path=${iconPath}></ha-svg-icon>`
: html`<ha-icon slot="start" .icon=${icon}></ha-icon>`}
<span class="item-text" slot="headline">${title}</span>
${this.editMode
? html`<ha-icon-button
.label=${this.hass.localize("ui.sidebar.hide_panel")}
@ -468,9 +466,10 @@ class HaSidebar extends SubscribeMixin(LitElement) {
class="hide-panel"
.panel=${urlPath}
@click=${this._hidePanel}
slot="end"
></ha-icon-button>`
: ""}
</a>
: nothing}
</ha-md-list-item>
`;
}
@ -493,14 +492,10 @@ class HaSidebar extends SubscribeMixin(LitElement) {
this._panelOrder = panelOrder;
}
private _renderPanelsEdit(beforeSpacer: PanelInfo[]) {
private _renderPanelsEdit(beforeSpacer: PanelInfo[], selectedPanel: string) {
return html`
<ha-sortable
handle-selector="paper-icon-item"
.disabled=${!this.editMode}
@item-moved=${this._panelMoved}
>
<div class="reorder-list">${this._renderPanels(beforeSpacer)}</div>
<ha-sortable .disabled=${!this.editMode} @item-moved=${this._panelMoved}
><div>${this._renderPanels(beforeSpacer, selectedPanel)}</div>
</ha-sortable>
${this._renderSpacer()}${this._renderHiddenPanels()}
`;
@ -513,26 +508,24 @@ class HaSidebar extends SubscribeMixin(LitElement) {
if (!panel) {
return "";
}
return html`<paper-icon-item
return html`<ha-md-list-item
@click=${this._unhidePanel}
class="hidden-panel"
.panel=${url}
type="button"
>
${panel.url_path === this.hass.defaultPanel && !panel.icon
? html`<ha-svg-icon
slot="item-icon"
slot="start"
.path=${PANEL_ICONS.lovelace}
></ha-svg-icon>`
: panel.url_path in PANEL_ICONS
? html`<ha-svg-icon
slot="item-icon"
slot="start"
.path=${PANEL_ICONS[panel.url_path]}
></ha-svg-icon>`
: html`<ha-icon
slot="item-icon"
.icon=${panel.icon}
></ha-icon>`}
<span class="item-text"
: html`<ha-icon slot="start" .icon=${panel.icon}></ha-icon>`}
<span class="item-text" slot="headline"
>${panel.url_path === this.hass.defaultPanel
? this.hass.localize("panel.states")
: this.hass.localize(`panel.${panel.title}`) ||
@ -542,8 +535,9 @@ class HaSidebar extends SubscribeMixin(LitElement) {
.label=${this.hass.localize("ui.sidebar.show_panel")}
.path=${mdiPlus}
class="show-panel"
slot="end"
></ha-icon-button>
</paper-icon-item>`;
</ha-md-list-item>`;
})}
${this._renderSpacer()}`
: ""}`;
@ -557,41 +551,34 @@ class HaSidebar extends SubscribeMixin(LitElement) {
return html`<div class="spacer" disabled></div>`;
}
private _renderConfiguration(title: string | null) {
return html`<a
class="configuration-container"
role="option"
aria-selected=${this.hass.panelUrl === "config"}
private _renderConfiguration(title: string | null, selectedPanel: string) {
return html`
<ha-md-list-item
class="configuration${selectedPanel === "config" ? " selected" : ""}"
type="button"
href="/config"
data-panel="config"
tabindex="-1"
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
>
<paper-icon-item
class="configuration"
role="option"
aria-selected=${this.hass.panelUrl === "config"}
>
<ha-svg-icon slot="item-icon" .path=${mdiCog}></ha-svg-icon>
<ha-svg-icon slot="start" .path=${mdiCog}></ha-svg-icon>
${!this.alwaysExpand &&
(this._updatesCount > 0 || this._issuesCount > 0)
? html`
<span class="configuration-badge" slot="item-icon">
<span class="badge" slot="start">
${this._updatesCount + this._issuesCount}
</span>
`
: ""}
<span class="item-text">${title}</span>
<span class="item-text" slot="headline">${title}</span>
${this.alwaysExpand && (this._updatesCount > 0 || this._issuesCount > 0)
? html`
<span class="configuration-badge"
<span class="badge" slot="end"
>${this._updatesCount + this._issuesCount}</span
>
`
: ""}
</paper-icon-item>
</a>`;
</ha-md-list-item>
`;
}
private _renderNotifications() {
@ -599,91 +586,67 @@ class HaSidebar extends SubscribeMixin(LitElement) {
? this._notifications.length
: 0;
return html`<div
class="notifications-container"
return html`
<ha-md-list-item
class="notifications"
@click=${this._handleShowNotificationDrawer}
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
type="button"
>
<paper-icon-item
class="notifications"
role="option"
aria-selected="false"
@click=${this._handleShowNotificationDrawer}
>
<ha-svg-icon slot="item-icon" .path=${mdiBell}></ha-svg-icon>
<ha-svg-icon slot="start" .path=${mdiBell}></ha-svg-icon>
${!this.alwaysExpand && notificationCount > 0
? html`
<span class="notification-badge" slot="item-icon">
${notificationCount}
</span>
<span class="badge" slot="start"> ${notificationCount} </span>
`
: ""}
<span class="item-text">
${this.hass.localize("ui.notification_drawer.title")}
</span>
<span class="item-text" slot="headline"
>${this.hass.localize("ui.notification_drawer.title")}</span
>
${this.alwaysExpand && notificationCount > 0
? html` <span class="notification-badge">${notificationCount}</span> `
? html`<span class="badge" slot="end">${notificationCount}</span>`
: ""}
</paper-icon-item>
</div>`;
</ha-md-list-item>
`;
}
private _renderUserItem() {
return html`<a
class=${classMap({
profile: true,
// Mimic behavior that paper-listbox provides
"iron-selected": this.hass.panelUrl === "profile",
})}
private _renderUserItem(selectedPanel: string) {
return html`
<ha-md-list-item
href="/profile"
data-panel="panel"
tabindex="-1"
role="option"
aria-selected=${this.hass.panelUrl === "profile"}
aria-label=${this.hass.localize("panel.profile")}
type="link"
class="user ${selectedPanel === "profile" ? " selected" : ""}"
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
>
<paper-icon-item>
<ha-user-badge
slot="item-icon"
slot="start"
.user=${this.hass.user}
.hass=${this.hass}
></ha-user-badge>
<span class="item-text">
${this.hass.user ? this.hass.user.name : ""}
</span>
</paper-icon-item>
</a>`;
<span class="item-text" slot="headline"
>${this.hass.user ? this.hass.user.name : ""}</span
>
</ha-md-list-item>
`;
}
private _renderExternalConfiguration() {
return html`${!this.hass.user?.is_admin &&
this.hass.auth.external?.config.hasSettingsScreen
? html`
<a
role="option"
aria-label=${this.hass.localize(
"ui.sidebar.external_app_configuration"
)}
href="#external-app-configuration"
tabindex="-1"
aria-selected="false"
<ha-md-list-item
@click=${this._handleExternalAppConfiguration}
type="button"
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
>
<paper-icon-item>
<ha-svg-icon
slot="item-icon"
.path=${mdiCellphoneCog}
></ha-svg-icon>
<span class="item-text">
<ha-svg-icon slot="start" .path=${mdiCellphoneCog}></ha-svg-icon>
<span class="item-text" slot="headline">
${this.hass.localize("ui.sidebar.external_app_configuration")}
</span>
</paper-icon-item>
</a>
</ha-md-list-item>
`
: ""}`;
}
@ -695,10 +658,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
});
}
private get _tooltip() {
return this.shadowRoot!.querySelector(".tooltip")! as HTMLDivElement;
}
private _handleAction(ev: CustomEvent<ActionHandlerDetail>) {
if (ev.detail.action !== "hold") {
return;
@ -761,7 +720,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
clearTimeout(this._mouseLeaveTimeout);
this._mouseLeaveTimeout = undefined;
}
this._showTooltip(ev.currentTarget as PaperIconItemElement);
this._showTooltip(ev.currentTarget as HaMdListItem);
}
private _itemMouseLeave() {
@ -774,10 +733,10 @@ class HaSidebar extends SubscribeMixin(LitElement) {
}
private _listboxFocusIn(ev) {
if (this.alwaysExpand || ev.target.nodeName !== "A") {
if (this.alwaysExpand || ev.target.localName !== "ha-md-list-item") {
return;
}
this._showTooltip(ev.target.querySelector("paper-icon-item"));
this._showTooltip(ev.target);
}
private _listboxFocusOut() {
@ -801,22 +760,25 @@ class HaSidebar extends SubscribeMixin(LitElement) {
this._recentKeydownActiveUntil = new Date().getTime() + 100;
}
private _showTooltip(item: PaperIconItemElement) {
private _showTooltip(item: HaMdListItem) {
if (this._tooltipHideTimeout) {
clearTimeout(this._tooltipHideTimeout);
this._tooltipHideTimeout = undefined;
}
const tooltip = this._tooltip;
const listbox = this.shadowRoot!.querySelector("paper-listbox")!;
const listbox = this.shadowRoot!.querySelector("ha-md-list")!;
let top = item.offsetTop + 11;
if (listbox.contains(item)) {
top += listbox.offsetTop;
top -= listbox.scrollTop;
}
tooltip.innerHTML = item.querySelector(".item-text")!.innerHTML;
tooltip.innerText = (
item.querySelector(".item-text") as HTMLElement
).innerText;
tooltip.style.display = "block";
tooltip.style.position = "fixed";
tooltip.style.top = `${top}px`;
tooltip.style.left = `${item.offsetLeft + item.clientWidth + 4}px`;
tooltip.style.left = `${item.offsetLeft + item.clientWidth + 8}px`;
}
private _hideTooltip() {
@ -905,12 +867,11 @@ class HaSidebar extends SubscribeMixin(LitElement) {
.menu mwc-button {
width: 100%;
}
.reorder-list,
.hidden-panel {
display: none;
}
paper-listbox {
ha-md-list {
padding: 4px 0;
display: flex;
flex-direction: column;
@ -922,90 +883,62 @@ class HaSidebar extends SubscribeMixin(LitElement) {
overflow-x: hidden;
background: none;
margin-left: env(safe-area-inset-left);
margin-inline-start: env(safe-area-inset-left);
margin-inline-end: initial;
}
a {
text-decoration: none;
color: var(--sidebar-text-color);
font-weight: 500;
font-size: 14px;
position: relative;
display: block;
outline: 0;
}
paper-icon-item {
ha-md-list-item {
box-sizing: border-box;
margin: 4px;
padding-left: 12px;
padding-inline-start: 12px;
padding-inline-end: initial;
border-radius: 4px;
--paper-item-min-height: 40px;
height: 40px;
--md-list-item-one-line-container-height: 40px;
width: 48px;
position: relative;
--md-list-item-label-text-color: var(--sidebar-text-color);
--md-list-item-leading-space: 12px;
--md-list-item-trailing-space: 12px;
--md-list-item-leading-icon-size: 24px;
}
:host([expanded]) paper-icon-item {
:host([expanded]) ha-md-list-item {
width: 248px;
}
ha-icon[slot="item-icon"],
ha-svg-icon[slot="item-icon"] {
color: var(--sidebar-icon-color);
ha-md-list-item.selected {
--md-list-item-label-text-color: var(--sidebar-selected-icon-color);
--md-ripple-hover-color: var(--sidebar-selected-icon-color);
}
.iron-selected paper-icon-item::before,
a:not(.iron-selected):focus::before {
ha-md-list-item.selected::before {
border-radius: 4px;
position: absolute;
top: 0;
right: 2px;
right: 0;
bottom: 0;
left: 2px;
left: 0;
pointer-events: none;
content: "";
transition: opacity 15ms linear;
will-change: opacity;
}
.iron-selected paper-icon-item::before {
background-color: var(--sidebar-selected-icon-color);
opacity: 0.12;
}
a:not(.iron-selected):focus::before {
background-color: currentColor;
opacity: var(--dark-divider-opacity);
margin: 4px 8px;
}
.iron-selected paper-icon-item:focus::before,
.iron-selected:focus paper-icon-item::before {
opacity: 0.2;
}
.iron-selected paper-icon-item[pressed]:before {
opacity: 0.37;
ha-icon[slot="start"],
ha-svg-icon[slot="start"] {
flex-shrink: 0;
color: var(--sidebar-icon-color);
}
paper-icon-item span {
color: var(--sidebar-text-color);
font-weight: 500;
font-size: 14px;
}
a.iron-selected paper-icon-item ha-icon,
a.iron-selected paper-icon-item ha-svg-icon {
ha-md-list-item.selected ha-svg-icon[slot="start"],
ha-md-list-item.selected ha-icon[slot="start"] {
color: var(--sidebar-selected-icon-color);
}
a.iron-selected .item-text {
color: var(--sidebar-selected-text-color);
}
paper-icon-item .item-text {
ha-md-list-item .item-text {
display: none;
max-width: calc(100% - 56px);
font-weight: 500;
font-size: 14px;
}
:host([expanded]) paper-icon-item .item-text {
:host([expanded]) ha-md-list-item .item-text {
display: block;
}
@ -1019,60 +952,38 @@ class HaSidebar extends SubscribeMixin(LitElement) {
height: 1px;
background-color: var(--divider-color);
}
.notifications-container,
.configuration-container {
.badge {
display: flex;
margin-left: env(safe-area-inset-left);
margin-inline-start: env(safe-area-inset-left);
margin-inline-end: initial;
}
.notifications {
cursor: pointer;
}
.notifications .item-text,
.configuration .item-text {
flex: 1;
}
.profile {
margin-left: env(safe-area-inset-left);
margin-inline-start: env(safe-area-inset-left);
margin-inline-end: initial;
}
.profile paper-icon-item {
padding-left: 4px;
padding-inline-start: 4px;
padding-inline-end: auto;
}
.profile .item-text {
margin-left: 8px;
margin-inline-start: 8px;
margin-inline-end: initial;
}
.notification-badge,
.configuration-badge {
position: absolute;
left: calc(var(--app-drawer-width, 248px) - 42px);
inset-inline-start: calc(var(--app-drawer-width, 248px) - 42px);
inset-inline-end: initial;
min-width: 20px;
box-sizing: border-box;
border-radius: 50%;
justify-content: center;
align-items: center;
min-width: 8px;
border-radius: 10px;
font-weight: 400;
line-height: normal;
background-color: var(--accent-color);
line-height: 20px;
text-align: center;
padding: 0px 2px;
padding: 2px 6px;
color: var(--text-accent-color, var(--text-primary-color));
}
ha-svg-icon + .notification-badge,
ha-svg-icon + .configuration-badge {
ha-svg-icon + .badge {
position: absolute;
bottom: 14px;
top: 4px;
left: 26px;
inset-inline-start: 26px;
inset-inline-end: initial;
border-radius: 10px;
font-size: 0.65em;
line-height: 2;
padding: 0 4px;
}
ha-md-list-item.user {
--md-list-item-leading-icon-size: 40px;
--md-list-item-bottom-space: 12px;
--md-list-item-leading-space: 4px;
--md-list-item-trailing-space: 4px;
}
ha-user-badge {
flex-shrink: 0;
}
.spacer {
@ -1088,19 +999,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
white-space: nowrap;
}
.dev-tools {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 8px;
width: 256px;
box-sizing: border-box;
}
.dev-tools a {
color: var(--sidebar-icon-color);
}
.tooltip {
display: none;
position: absolute;

View File

@ -84,21 +84,24 @@ class UserBadge extends LitElement {
static styles = css`
:host {
display: contents;
}
.picture {
display: block;
width: 40px;
height: 40px;
}
.picture {
width: 100%;
height: 100%;
background-size: cover;
border-radius: 50%;
}
.initials {
display: inline-block;
display: inline-flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 40px;
line-height: 40px;
width: 100%;
height: 100%;
border-radius: 50%;
text-align: center;
background-color: var(--light-primary-color);
text-decoration: none;
color: var(--text-light-primary-color, var(--primary-text-color));

View File

@ -20,6 +20,7 @@ import type {
import { fetchStatistics, getStatisticMetadata } from "../../data/recorder";
import { getSensorNumericDeviceClasses } from "../../data/sensor";
import type { HomeAssistant } from "../../types";
import { haStyle } from "../../resources/styles";
declare global {
interface HASSDomEvents {
@ -58,9 +59,9 @@ export class MoreInfoHistory extends LitElement {
return html`${isComponentLoaded(this.hass, "history")
? html`<div class="header">
<div class="title">
<h2>
${this.hass.localize("ui.dialogs.more_info_control.history")}
</div>
</h2>
${__DEMO__
? nothing
: html`<a href=${this._showMoreHref}
@ -231,7 +232,9 @@ export class MoreInfoHistory extends LitElement {
this._setRedrawTimer();
}
static styles = css`
static styles = [
haStyle,
css`
.header {
display: flex;
flex-direction: row;
@ -243,15 +246,11 @@ export class MoreInfoHistory extends LitElement {
a:visited {
color: var(--primary-color);
}
.title {
font-family: var(--paper-font-title_-_font-family);
-webkit-font-smoothing: var(--paper-font-title_-_-webkit-font-smoothing);
font-size: var(--paper-font-subhead_-_font-size);
font-weight: var(--paper-font-title_-_font-weight);
letter-spacing: var(--paper-font-title_-_letter-spacing);
line-height: var(--paper-font-title_-_line-height);
h2 {
margin: 0;
}
`;
`,
];
}
declare global {

View File

@ -7,6 +7,7 @@ import { isComponentLoaded } from "../../common/config/is_component_loaded";
import { createSearchParam } from "../../common/url/search-params";
import "../../panels/logbook/ha-logbook";
import type { HomeAssistant } from "../../types";
import { haStyle } from "../../resources/styles";
@customElement("ha-more-info-logbook")
export class MoreInfoLogbook extends LitElement {
@ -32,9 +33,7 @@ export class MoreInfoLogbook extends LitElement {
return html`
<div class="header">
<div class="title">
${this.hass.localize("ui.dialogs.more_info_control.logbook")}
</div>
<h2>${this.hass.localize("ui.dialogs.more_info_control.logbook")}</h2>
<a href=${this._showMoreHref}
>${this.hass.localize("ui.dialogs.more_info_control.show_more")}</a
>
@ -68,6 +67,7 @@ export class MoreInfoLogbook extends LitElement {
static get styles() {
return [
haStyle,
css`
ha-logbook {
--logbook-max-height: 250px;
@ -88,15 +88,8 @@ export class MoreInfoLogbook extends LitElement {
a:visited {
color: var(--primary-color);
}
.title {
font-family: var(--paper-font-title_-_font-family);
-webkit-font-smoothing: var(
--paper-font-title_-_-webkit-font-smoothing
);
font-size: var(--paper-font-subhead_-_font-size);
font-weight: var(--paper-font-title_-_font-weight);
letter-spacing: var(--paper-font-title_-_letter-spacing);
line-height: var(--paper-font-title_-_line-height);
h2 {
margin: 0;
}
`,
];

View File

@ -25,15 +25,14 @@ export class HuiNotificationItemTemplate extends LitElement {
}
ha-card .header {
/* start paper-font-headline style */
font-family: "Roboto", "Noto", sans-serif;
-webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
text-rendering: optimizeLegibility;
font-size: 24px;
font-weight: 400;
letter-spacing: -0.012em;
line-height: 32px;
/* end paper-font-headline style */
font-family: var(--paper-font-headline_-_font-family);
-webkit-font-smoothing: var(
--paper-font-headline_-_-webkit-font-smoothing
);
font-size: var(--paper-font-headline_-_font-size);
font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height);
color: var(--primary-text-color);
padding: 16px 16px 0;

View File

@ -2,9 +2,3 @@ import "@webcomponents/scoped-custom-element-registry/scoped-custom-element-regi
import "../layouts/home-assistant";
import("../resources/ha-style");
import("@polymer/polymer/lib/utils/settings").then(
({ setCancelSyntheticClickEvents, setPassiveTouchGestures }) => {
setCancelSyntheticClickEvents(false);
setPassiveTouchGestures(true);
}
);

View File

@ -1,6 +1,3 @@
import "../auth/ha-authorize";
import("../resources/ha-style");
import("@polymer/polymer/lib/utils/settings").then(
({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false)
);

View File

@ -10,10 +10,6 @@ import { createCustomPanelElement } from "../util/custom-panel/create-custom-pan
import { loadCustomPanel } from "../util/custom-panel/load-custom-panel";
import { setCustomPanelProperties } from "../util/custom-panel/set-custom-panel-properties";
import("@polymer/polymer/lib/utils/settings").then(
({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false)
);
declare global {
interface Window {
loadES5Adapter: () => Promise<unknown>;

View File

@ -1,9 +1,6 @@
import "../onboarding/ha-onboarding";
import("../resources/ha-style");
import("@polymer/polymer/lib/utils/settings").then(
({ setCancelSyntheticClickEvents }) => setCancelSyntheticClickEvents(false)
);
declare global {
interface Window {

View File

@ -7,7 +7,6 @@
script.src = src;
return document.head.appendChild(script);
}
window.polymerSkipLoadingFontRoboto = true;
if (!("attachShadow" in Element.prototype)) {
_ls("/static/polyfills/webcomponents-bundle.js", true);
_ls("/static/polyfills/lit-polyfill-support.js", true);

View File

@ -92,11 +92,11 @@ class HaPanelDevEvent extends LitElement {
</div>
<div>
<div class="header">
<h2>
${this.hass.localize(
"ui.panel.developer-tools.tabs.events.active_listeners"
)}
</div>
</h2>
<events-list
@event-selected=${this._eventSelected}
.hass=${this.hass}
@ -160,7 +160,6 @@ class HaPanelDevEvent extends LitElement {
-ms-user-select: initial;
-webkit-user-select: initial;
-moz-user-select: initial;
@apply --paper-font-body1;
display: block;
}
@ -180,10 +179,6 @@ class HaPanelDevEvent extends LitElement {
display: block;
}
.header {
@apply --paper-font-title;
}
event-subscribe-card {
display: block;
margin-top: 16px;

View File

@ -323,7 +323,8 @@ ${type === "object"
}
.rendered {
@apply --paper-font-code1;
font-family: "Roboto Mono", "Consolas", "Menlo", monospace;
-webkit-font-smoothing: antialiased;
clear: both;
white-space: pre-wrap;
background-color: var(--secondary-background-color);

View File

@ -200,11 +200,9 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
}
.footer {
/* start paper-font-common-nowrap style */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* end paper-font-common-nowrap style */
position: absolute;
left: 0;

View File

@ -178,14 +178,14 @@ class HuiPlantStatusCard extends LitElement implements LovelaceCard {
}
.header {
/* start paper-font-headline style */
font-family: "Roboto", "Noto", sans-serif;
-webkit-font-smoothing: antialiased; /* OS X subpixel AA bleed bug */
text-rendering: optimizeLegibility;
font-size: 24px;
font-weight: 400;
letter-spacing: -0.012em;
/* end paper-font-headline style */
font-family: var(--paper-font-headline_-_font-family);
-webkit-font-smoothing: var(
--paper-font-headline_-_-webkit-font-smoothing
);
font-size: var(--paper-font-headline_-_font-size);
font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height);
line-height: 40px;
padding: 8px 16px;

View File

@ -1,7 +1,7 @@
import { css } from "lit";
export const sidebarEditStyle = css`
.reorder-list a:nth-of-type(2n) paper-icon-item {
ha-sortable ha-md-list-item:nth-child(2n) {
animation-name: keyframes1;
animation-iteration-count: infinite;
transform-origin: 50% 10%;
@ -9,7 +9,7 @@ export const sidebarEditStyle = css`
animation-duration: 0.25s;
}
.reorder-list a:nth-of-type(2n-1) paper-icon-item {
ha-sortable ha-md-list-item:nth-child(2n-1) {
animation-name: keyframes2;
animation-iteration-count: infinite;
animation-direction: alternate;
@ -18,14 +18,9 @@ export const sidebarEditStyle = css`
animation-duration: 0.33s;
}
.reorder-list a {
ha-sortable ha-md-list-item {
height: 48px;
display: flex;
}
.reorder-list {
outline: none;
display: block !important;
cursor: grab;
}
.hidden-panel {
@ -59,19 +54,7 @@ export const sidebarEditStyle = css`
.show-panel,
.hide-panel {
display: none;
position: absolute;
top: 0;
right: 4px;
inset-inline-end: 4px;
inset-inline-start: initial;
--mdc-icon-button-size: 40px;
}
.hide-panel {
top: 4px;
right: 8px;
inset-inline-end: 8px;
inset-inline-start: initial;
--mdc-icon-button-size: 24px;
}
:host([expanded]) .hide-panel {
@ -79,12 +62,12 @@ export const sidebarEditStyle = css`
}
:host([expanded]) .show-panel {
display: inline-flex;
display: block;
}
paper-icon-item.hidden-panel,
paper-icon-item.hidden-panel span,
paper-icon-item.hidden-panel ha-icon[slot="item-icon"] {
ha-md-list-item.hidden-panel,
ha-md-list-item.hidden-panel span,
ha-md-list-item.hidden-panel ha-icon[slot="start"] {
color: var(--secondary-text-color);
cursor: pointer;
}

View File

@ -9,10 +9,6 @@ import {
const mainStyles = css`
/*
Home Assistant default styles.
In Polymer 2.0, default styles should to be set on the html selector.
(Setting all default styles only on body breaks shadyCSS polyfill.)
See: https://github.com/home-assistant/home-assistant-polymer/pull/901
*/
html {
font-size: 14px;
@ -213,221 +209,74 @@ const mainStyles = css`
--material-caption-font-size: 0.75rem;
--material-button-font-size: 0.875rem;
/* Paper shadow */
--shadow-transition: {
transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
};
--shadow-none: {
box-shadow: none;
};
/* from http://codepen.io/shyndman/pen/c5394ddf2e8b2a5c9185904b57421cdb */
--shadow-elevation-2dp: {
box-shadow:
0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 1px 5px 0 rgba(0, 0, 0, 0.12),
0 3px 1px -2px rgba(0, 0, 0, 0.2);
};
--shadow-elevation-3dp: {
box-shadow:
0 3px 4px 0 rgba(0, 0, 0, 0.14),
0 1px 8px 0 rgba(0, 0, 0, 0.12),
0 3px 3px -2px rgba(0, 0, 0, 0.4);
};
--shadow-elevation-4dp: {
box-shadow:
0 4px 5px 0 rgba(0, 0, 0, 0.14),
0 1px 10px 0 rgba(0, 0, 0, 0.12),
0 2px 4px -1px rgba(0, 0, 0, 0.4);
};
--shadow-elevation-6dp: {
box-shadow:
0 6px 10px 0 rgba(0, 0, 0, 0.14),
0 1px 18px 0 rgba(0, 0, 0, 0.12),
0 3px 5px -1px rgba(0, 0, 0, 0.4);
};
--shadow-elevation-8dp: {
box-shadow:
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12),
0 5px 5px -3px rgba(0, 0, 0, 0.4);
};
--shadow-elevation-12dp: {
box-shadow:
0 12px 16px 1px rgba(0, 0, 0, 0.14),
0 4px 22px 3px rgba(0, 0, 0, 0.12),
0 6px 7px -4px rgba(0, 0, 0, 0.4);
};
--shadow-elevation-16dp: {
box-shadow:
0 16px 24px 2px rgba(0, 0, 0, 0.14),
0 6px 30px 5px rgba(0, 0, 0, 0.12),
0 8px 10px -5px rgba(0, 0, 0, 0.4);
};
--shadow-elevation-24dp: {
box-shadow:
0 24px 38px 3px rgba(0, 0, 0, 0.14),
0 9px 46px 8px rgba(0, 0, 0, 0.12),
0 11px 15px -7px rgba(0, 0, 0, 0.4);
};
/* Paper typography Styles */
--paper-font-common-base: {
font-family: "Roboto", "Noto", sans-serif;
-webkit-font-smoothing: antialiased;
};
--paper-font-common-base_-_font-family: Roboto, Noto, sans-serif;
--paper-font-common-base_-_-webkit-font-smoothing: antialiased;
--paper-font-common-code_-_font-family:
"Roboto Mono", Consolas, Menlo, monospace;
--paper-font-common-code_-_-webkit-font-smoothing: antialiased;
--paper-font-common-nowrap_-_white-space: nowrap;
--paper-font-common-nowrap_-_overflow: hidden;
--paper-font-common-nowrap_-_text-overflow: ellipsis;
--paper-font-common-code: {
font-family: "Roboto Mono", "Consolas", "Menlo", monospace;
-webkit-font-smoothing: antialiased;
};
--paper-font-display1_-_font-family: var(
--paper-font-common-base_-_font-family
);
--paper-font-display1_-_-webkit-font-smoothing: var(
--paper-font-common-base_-_-webkit-font-smoothing
);
--paper-font-display1_-_font-size: 34px;
--paper-font-display1_-_font-weight: 400;
--paper-font-display1_-_letter-spacing: -0.01em;
--paper-font-display1_-_line-height: 40px;
--paper-font-common-expensive-kerning: {
text-rendering: optimizeLegibility;
};
--paper-font-headline_-_font-family: var(
--paper-font-common-base_-_font-family
);
--paper-font-headline_-_-webkit-font-smoothing: var(
--paper-font-common-base_-_-webkit-font-smoothing
);
--paper-font-headline_-_font-size: 24px;
--paper-font-headline_-_font-weight: 400;
--paper-font-headline_-_letter-spacing: -0.012em;
--paper-font-headline_-_line-height: 32px;
--paper-font-common-nowrap: {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
};
--paper-font-title_-_font-family: var(
--paper-font-common-base_-_font-family
);
--paper-font-title_-_-webkit-font-smoothing: var(
--paper-font-common-base_-_-webkit-font-smoothing
);
--paper-font-title_-_white-space: var(
--paper-font-common-nowrap_-_white-space
);
--paper-font-title_-_overflow: var(--paper-font-common-nowrap_-_overflow);
--paper-font-title_-_text-overflow: var(
--paper-font-common-nowrap_-_text-overflow
);
--paper-font-title_-_font-size: 20px;
--paper-font-title_-_font-weight: 500;
--paper-font-title_-_line-height: 28px;
/* Material Font Styles */
--paper-font-subhead_-_font-family: var(
--paper-font-common-base_-_font-family
);
--paper-font-subhead_-_-webkit-font-smoothing: var(
--paper-font-common-base_-_-webkit-font-smoothing
);
--paper-font-subhead_-_font-size: 16px;
--paper-font-subhead_-_font-weight: 400;
--paper-font-subhead_-_line-height: 24px;
--paper-font-display4: {
@apply --paper-font-common-base;
@apply --paper-font-common-nowrap;
font-size: 112px;
font-weight: 300;
letter-spacing: -0.044em;
line-height: 120px;
};
--paper-font-display3: {
@apply --paper-font-common-base;
@apply --paper-font-common-nowrap;
font-size: 56px;
font-weight: 400;
letter-spacing: -0.026em;
line-height: 60px;
};
--paper-font-display2: {
@apply --paper-font-common-base;
font-size: 45px;
font-weight: 400;
letter-spacing: -0.018em;
line-height: 48px;
};
--paper-font-display1: {
@apply --paper-font-common-base;
font-size: 34px;
font-weight: 400;
letter-spacing: -0.01em;
line-height: 40px;
};
--paper-font-headline: {
@apply --paper-font-common-base;
font-size: 24px;
font-weight: 400;
letter-spacing: -0.012em;
line-height: 32px;
};
--paper-font-title: {
@apply --paper-font-common-base;
@apply --paper-font-common-nowrap;
font-size: 20px;
font-weight: 500;
line-height: 28px;
};
--paper-font-subhead: {
@apply --paper-font-common-base;
font-size: 16px;
font-weight: 400;
line-height: 24px;
};
--paper-font-body2: {
@apply --paper-font-common-base;
font-size: 14px;
font-weight: 500;
line-height: 24px;
};
--paper-font-body1: {
@apply --paper-font-common-base;
font-size: 14px;
font-weight: 400;
line-height: 20px;
};
--paper-font-caption: {
@apply --paper-font-common-base;
@apply --paper-font-common-nowrap;
font-size: 12px;
font-weight: 400;
letter-spacing: 0.011em;
line-height: 20px;
};
--paper-font-menu: {
@apply --paper-font-common-base;
@apply --paper-font-common-nowrap;
font-size: 13px;
font-weight: 500;
line-height: 24px;
};
--paper-font-button: {
@apply --paper-font-common-base;
@apply --paper-font-common-nowrap;
font-size: 14px;
font-weight: 500;
letter-spacing: 0.018em;
line-height: 24px;
text-transform: uppercase;
};
--paper-font-code2: {
@apply --paper-font-common-code;
font-size: 14px;
font-weight: 700;
line-height: 20px;
};
--paper-font-code1: {
@apply --paper-font-common-code;
font-size: 14px;
font-weight: 500;
line-height: 20px;
};
--paper-font-body1_-_font-family: var(
--paper-font-common-base_-_font-family
);
--paper-font-body1_-_-webkit-font-smoothing: var(
--paper-font-common-base_-_-webkit-font-smoothing
);
--paper-font-body1_-_font-size: 14px;
--paper-font-body1_-_font-weight: 400;
--paper-font-body1_-_line-height: 20px;
direction: ltr;
--direction: ltr;

View File

@ -487,6 +487,6 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
}
};
// Load selected translation into memory immediately so it is ready when Polymer
// Load selected translation into memory immediately so it is ready when the app
// initializes.
getTranslation(null, getLocalLanguage());

View File

@ -7,7 +7,7 @@ const BASE_URL = `${__STATIC_PATH__}translations`;
const STORAGE = window.localStorage || {};
// Store loaded translations in memory so translations are available immediately
// when DOM is created in Polymer. Even a cache lookup creates noticeable latency.
// when DOM is created. Even a cache lookup creates noticeable latency.
const translations = {};
async function fetchTranslation(fingerprint: string) {

105
yarn.lock
View File

@ -3619,98 +3619,7 @@ __metadata:
languageName: node
linkType: hard
"@polymer/font-roboto@npm:^3.0.1":
version: 3.0.2
resolution: "@polymer/font-roboto@npm:3.0.2"
checksum: 10/6f487bc1df5636437592c1f75115816818f72327284518539c2fee71ea932f6fc47c45c2e03281f40a8e873a3541ed732d2f5c4b8365cc2baa5029a4945e9194
languageName: node
linkType: hard
"@polymer/iron-a11y-keys-behavior@npm:^3.0.0-pre.26":
version: 3.0.1
resolution: "@polymer/iron-a11y-keys-behavior@npm:3.0.1"
dependencies:
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/f3160b6663eb34925d33b84482e1b7775082985bf1798ccbbbcd769a723d34e7aad1b97b443d79f0d5201aa4fb15f4fe16ac002ac236d2166f2821f39ddfb59a
languageName: node
linkType: hard
"@polymer/iron-behaviors@npm:^3.0.0-pre.26":
version: 3.0.1
resolution: "@polymer/iron-behaviors@npm:3.0.1"
dependencies:
"@polymer/iron-a11y-keys-behavior": "npm:^3.0.0-pre.26"
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/ee8a7874cdd0e66f16e3a7282d9063fecb3e2e2a5b69911fb3cb219c57433a7f289a98c3b14f7d1a5087845ad5b8b5744abdae668fa9926ae8f13d5c8a049ebf
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"
dependencies:
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/0cddf0d4ca4c2475060cef9a8249ffa92a27bfd881d7463fc4bd94be09de6b93ac79d716fcc47df20863c2c789e186ae724a2500331060d4b34eec3492fc504d
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"
dependencies:
"@polymer/iron-a11y-keys-behavior": "npm:^3.0.0-pre.26"
"@polymer/iron-flex-layout": "npm:^3.0.0-pre.26"
"@polymer/iron-selector": "npm:^3.0.0-pre.26"
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/5674e42bb61711c5ebda0e1580136c2bcf6bdbce5fb1c7d1c7d2a9723d19ae5a1104402c4469a9d27e7e4a12e08e2da9755e4cbc2806a2ded9bb73ec706e825c
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"
dependencies:
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/1b3c8e8dd979d357abb7db738a3212b2b81f6a408a223490e57e759409e7acce09d152753c5e6364453d179af1797b4be284d750aed6145df271e4ab125928c1
languageName: node
linkType: hard
"@polymer/paper-item@npm:3.0.1":
version: 3.0.1
resolution: "@polymer/paper-item@npm:3.0.1"
dependencies:
"@polymer/iron-behaviors": "npm:^3.0.0-pre.26"
"@polymer/iron-flex-layout": "npm:^3.0.0-pre.26"
"@polymer/paper-styles": "npm:^3.0.0-pre.26"
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/1057bfc0d76df7eae08a51d60ee1733297718a2ee42273788ca49d03dcce39b7b4e98e51e45aae225d4de881c816dfbb1b94c342a4833c62c7600d04dc055477
languageName: node
linkType: hard
"@polymer/paper-listbox@npm:3.0.1":
version: 3.0.1
resolution: "@polymer/paper-listbox@npm:3.0.1"
dependencies:
"@polymer/iron-behaviors": "npm:^3.0.0-pre.26"
"@polymer/iron-menu-behavior": "npm:^3.0.0-pre.26"
"@polymer/paper-styles": "npm:^3.0.0-pre.26"
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/c9ee9324cdb258b53f302b7f5a8b631a8b334ded5c11963af040c0d5d6182092759be4edb0ca5155cb9b6481105692a12589484add83e2a0ed7782e6fa45534b
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"
dependencies:
"@polymer/font-roboto": "npm:^3.0.1"
"@polymer/iron-flex-layout": "npm:^3.0.0-pre.26"
"@polymer/polymer": "npm:^3.0.0"
checksum: 10/ee1ab8e2b1d3898f007c18921b6c3e549608e9fb7bb880014ae8a42b6255b08e67bfa646edb69d33b60a0a05bf0936b6b229198cb7ca6df181c09dc0fe7b41c7
languageName: node
linkType: hard
"@polymer/polymer@npm:3.5.2":
"@polymer/polymer@npm:^3.0.0":
version: 3.5.2
resolution: "@polymer/polymer@npm:3.5.2"
dependencies:
@ -3719,15 +3628,6 @@ __metadata:
languageName: node
linkType: hard
"@polymer/polymer@patch:@polymer/polymer@3.5.2#./.yarn/patches/@polymer/polymer/pr-5569.patch::locator=home-assistant-frontend%40workspace%3A.":
version: 3.5.2
resolution: "@polymer/polymer@patch:@polymer/polymer@npm%3A3.5.2#./.yarn/patches/@polymer/polymer/pr-5569.patch::version=3.5.2&hash=0f00db&locator=home-assistant-frontend%40workspace%3A."
dependencies:
"@webcomponents/shadycss": "npm:^1.9.1"
checksum: 10/5f610f979eed3b42f3d8d09c60797872b5418846baff1bc48f93d7cc13889fe78d85b0f24bcf9d7fcd9007910d144015162496295685533afe06f494d9c7cf74
languageName: node
linkType: hard
"@reallyland/esm@npm:^0.0.1":
version: 0.0.1
resolution: "@reallyland/esm@npm:0.0.1"
@ -9514,9 +9414,6 @@ __metadata:
"@octokit/auth-oauth-device": "npm:7.1.4"
"@octokit/plugin-retry": "npm:7.2.0"
"@octokit/rest": "npm:21.1.1"
"@polymer/paper-item": "npm:3.0.1"
"@polymer/paper-listbox": "npm:3.0.1"
"@polymer/polymer": "npm:3.5.2"
"@replit/codemirror-indentation-markers": "npm:6.5.3"
"@rsdoctor/rspack-plugin": "npm:1.0.1"
"@rspack/cli": "npm:1.3.2"