Add typography styles (#25171)

* Add typoghrapy styles

* Split styles

* Fix duplicated html

* remove unused paper vars

* Fix vars

* Add vars autocompletion extension

* Fix css syntax highlighting
pull/24788/merge
Wendelin 2025-04-28 15:04:47 +02:00 committed by GitHub
parent 9a52185e13
commit ca642d46cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 533 additions and 444 deletions

View File

@ -21,7 +21,8 @@
"esbenp.prettier-vscode",
"runem.lit-plugin",
"github.vscode-pull-request-github",
"eamodio.gitlens"
"eamodio.gitlens",
"yeion7.styled-global-variables-autocomplete"
],
"settings": {
"files.eol": "\n",

View File

@ -5,6 +5,7 @@
"runem.lit-plugin",
"github.vscode-pull-request-github",
"eamodio.gitlens",
"vitest.explorer"
"vitest.explorer",
"yeion7.styled-global-variables-autocomplete"
]
}

View File

@ -1,3 +1,3 @@
import "./layout/hc-connect";
import("../../../src/resources/ha-style");
import("../../../src/resources/append-ha-style");

View File

@ -109,7 +109,7 @@ export class HcMain extends HassElement {
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
import("./hc-lovelace");
import("../../../../src/resources/ha-style");
import("../../../../src/resources/append-ha-style");
window.addEventListener("location-changed", () => {
const panelPath = `/${this._urlPath || "lovelace"}/`;

View File

@ -1,4 +1,4 @@
import "./util/is_frontpage";
import "./ha-demo";
import("../../src/resources/ha-style");
import("../../src/resources/append-ha-style");

View File

@ -1,6 +1,6 @@
import "./hassio-main";
import("../../src/resources/ha-style");
import("../../src/resources/append-ha-style");
const styleEl = document.createElement("style");
styleEl.textContent = `

View File

@ -1,5 +1,6 @@
import type { ThemeVars } from "../../data/ws-themes";
import { darkStyles, derivedStyles } from "../../resources/styles-data";
import { darkColorVariables } from "../../resources/theme/color.globals";
import { derivedStyles } from "../../resources/theme/theme";
import type { HomeAssistant } from "../../types";
import {
hex2rgb,
@ -50,7 +51,7 @@ export const applyThemesOnElement = (
if (themeToApply && darkMode) {
cacheKey = `${cacheKey}__dark`;
themeRules = { ...darkStyles };
themeRules = { ...darkColorVariables };
}
if (themeToApply === "default") {

View File

@ -0,0 +1,45 @@
import type { CSSResult } from "lit";
const _extractCssVars = (
cssString: string,
condition: (string) => boolean = () => true
) => {
const variables: Record<string, string> = {};
cssString.split(";").forEach((rawLine) => {
const line = rawLine.substring(rawLine.indexOf("--")).trim();
if (line.startsWith("--") && condition(line)) {
const [name, value] = line.split(":").map((part) => part.trim());
variables[name.substring(2, name.length)] = value;
}
});
return variables;
};
export const extractVar = (css: CSSResult, varName: string) => {
const cssString = css.toString();
const search = `--${varName}:`;
const startIndex = cssString.indexOf(search);
if (startIndex === -1) {
return "";
}
const endIndex = cssString.indexOf(";", startIndex + search.length);
return cssString.substring(startIndex + search.length, endIndex).trim();
};
export const extractVars = (css: CSSResult) => {
const cssString = css.toString();
return _extractCssVars(cssString);
};
export const extractDerivedVars = (css: CSSResult) => {
const cssString = css.toString();
if (!cssString.includes("var(")) {
return {};
}
return _extractCssVars(cssString, (line) => line.includes("var("));
};

View File

@ -1,4 +1,4 @@
import "@webcomponents/scoped-custom-element-registry/scoped-custom-element-registry.min";
import "../layouts/home-assistant";
import("../resources/ha-style");
import("../resources/append-ha-style");

View File

@ -1,3 +1,3 @@
import "../auth/ha-authorize";
import("../resources/ha-style");
import("../resources/append-ha-style");

View File

@ -1,6 +1,6 @@
import "../onboarding/ha-onboarding";
import("../resources/ha-style");
import("../resources/append-ha-style");
declare global {
interface Window {

View File

@ -30,7 +30,7 @@ import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-
import { showRestartDialog } from "../../../dialogs/restart/show-dialog-restart";
import "../../../layouts/hass-subpage";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { DEFAULT_PRIMARY_COLOR } from "../../../resources/styles-data";
import { DefaultPrimaryColor } from "../../../resources/theme/color.globals";
import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types";
import { hardwareBrandsUrl } from "../../../util/brands-url";
@ -42,9 +42,9 @@ const DATASAMPLES = 60;
const DATA_SET_CONFIG: SeriesOption = {
type: "line",
color: DEFAULT_PRIMARY_COLOR,
color: DefaultPrimaryColor,
areaStyle: {
color: DEFAULT_PRIMARY_COLOR + "2B",
color: DefaultPrimaryColor + "2B",
},
symbolSize: 0,
lineStyle: {

View File

@ -12,9 +12,9 @@ import "../../components/ha-select";
import "../../components/ha-settings-row";
import "../../components/ha-textfield";
import {
DEFAULT_ACCENT_COLOR,
DEFAULT_PRIMARY_COLOR,
} from "../../resources/styles-data";
DefaultAccentColor,
DefaultPrimaryColor,
} from "../../resources/theme/color.globals";
import type { HomeAssistant } from "../../types";
import { documentationUrl } from "../../util/documentation-url";
@ -129,8 +129,7 @@ export class HaPickThemeRow extends LitElement {
${curTheme === HOME_ASSISTANT_THEME
? html`<div class="color-pickers">
<ha-textfield
.value=${themeSettings?.primaryColor ||
DEFAULT_PRIMARY_COLOR}
.value=${themeSettings?.primaryColor || DefaultPrimaryColor}
type="color"
.label=${this.hass.localize(
"ui.panel.profile.themes.primary_color"
@ -139,7 +138,7 @@ export class HaPickThemeRow extends LitElement {
@change=${this._handleColorChange}
></ha-textfield>
<ha-textfield
.value=${themeSettings?.accentColor || DEFAULT_ACCENT_COLOR}
.value=${themeSettings?.accentColor || DefaultAccentColor}
type="color"
.label=${this.hass.localize(
"ui.panel.profile.themes.accent_color"

View File

@ -0,0 +1,5 @@
import { themeStyles } from "./theme/theme";
const styleElement = document.createElement("style");
styleElement.textContent = themeStyles;
document.head.append(styleElement);

View File

@ -1,165 +0,0 @@
import { css, unsafeCSS } from "lit";
import { fontStyles } from "./roboto";
import {
DEFAULT_ACCENT_COLOR,
DEFAULT_PRIMARY_COLOR,
derivedStyles,
} from "./styles-data";
const mainStyles = css`
/*
Home Assistant default styles.
*/
html {
/* typography */
--ha-font-family-body: Roboto, Noto, sans-serif;
--ha-font-family-code: monospace;
--ha-font-family-longform: ui-sans-serif, system-ui, sans-serif;
font-size: 14px;
--ha-font-size-scale: 1;
--ha-font-weight-light: 300;
--ha-font-weight-normal: 400;
--ha-font-weight-semibold: 500;
--ha-font-weight-bold: 600;
--ha-line-height-condensed: 1.2;
--ha-line-height-normal: 1.6;
--ha-line-height-expanded: 2;
--ha-font-smoothing: antialiased;
height: 100vh;
/* text */
--primary-text-color: #212121;
--secondary-text-color: #727272;
--text-primary-color: #ffffff;
--text-light-primary-color: #212121;
--disabled-text-color: #bdbdbd;
/* main interface colors */
--primary-color: ${unsafeCSS(DEFAULT_PRIMARY_COLOR)};
--dark-primary-color: #0288d1;
--light-primary-color: #b3e5fc;
--accent-color: ${unsafeCSS(DEFAULT_ACCENT_COLOR)};
--divider-color: rgba(0, 0, 0, 0.12);
--outline-color: rgba(0, 0, 0, 0.12);
--outline-hover-color: rgba(0, 0, 0, 0.24);
--scrollbar-thumb-color: rgb(194, 194, 194);
--error-color: #db4437;
--warning-color: #ffa600;
--success-color: #43a047;
--info-color: #039be5;
/* backgrounds */
--card-background-color: #ffffff;
--primary-background-color: #fafafa;
--secondary-background-color: #e5e5e5; /* behind the cards on state */
--clear-background-color: #ffffff;
/* for header */
--header-height: 56px;
/* for label-badge */
--label-badge-grey: #9e9e9e;
/* states icon */
--state-icon-color: #44739e;
/* an error state is anything that would be considered an error */
/* --state-icon-error-color: #db4437; derived from error-color */
/* energy */
--energy-grid-consumption-color: #488fc2;
--energy-grid-return-color: #8353d1;
--energy-solar-color: #ff9800;
--energy-non-fossil-color: #0f9d58;
--energy-battery-out-color: #4db6ac;
--energy-battery-in-color: #f06292;
--energy-gas-color: #8e021b;
--energy-water-color: #00bcd4;
/* opacity for dark text on a light background */
--dark-divider-opacity: 0.12;
--dark-disabled-opacity: 0.38; /* or hint text or icon */
--dark-secondary-opacity: 0.54;
--dark-primary-opacity: 0.87;
/* opacity for light text on a dark background */
--light-divider-opacity: 0.12;
--light-disabled-opacity: 0.3; /* or hint text or icon */
--light-secondary-opacity: 0.7;
--light-primary-opacity: 1;
/* rgb */
--rgb-primary-color: 3, 169, 244;
--rgb-accent-color: 255, 152, 0;
--rgb-primary-text-color: 33, 33, 33;
--rgb-secondary-text-color: 114, 114, 114;
--rgb-text-primary-color: 255, 255, 255;
--rgb-card-background-color: 255, 255, 255;
/* color */
--disabled-color: #bdbdbd;
--red-color: #f44336;
--pink-color: #e91e63;
--purple-color: #926bc7;
--deep-purple-color: #6e41ab;
--indigo-color: #3f51b5;
--blue-color: #2196f3;
--light-blue-color: #03a9f4;
--cyan-color: #00bcd4;
--teal-color: #009688;
--green-color: #4caf50;
--light-green-color: #8bc34a;
--lime-color: #cddc39;
--yellow-color: #ffeb3b;
--amber-color: #ffc107;
--orange-color: #ff9800;
--deep-orange-color: #ff6f22;
--brown-color: #795548;
--light-grey-color: #bdbdbd;
--grey-color: #9e9e9e;
--dark-grey-color: #606060;
--blue-grey-color: #607d8b;
--black-color: #000000;
--white-color: #ffffff;
/* history colors */
--history-unavailable-color: transparent;
/* input components */
--input-idle-line-color: rgba(0, 0, 0, 0.42);
--input-hover-line-color: rgba(0, 0, 0, 0.87);
--input-disabled-line-color: rgba(0, 0, 0, 0.06);
--input-outlined-idle-border-color: rgba(0, 0, 0, 0.38);
--input-outlined-hover-border-color: rgba(0, 0, 0, 0.87);
--input-outlined-disabled-border-color: rgba(0, 0, 0, 0.06);
--input-fill-color: rgb(245, 245, 245);
--input-disabled-fill-color: rgb(250, 250, 250);
--input-ink-color: rgba(0, 0, 0, 0.87);
--input-label-ink-color: rgba(0, 0, 0, 0.6);
--input-disabled-ink-color: rgba(0, 0, 0, 0.37);
--input-dropdown-icon-color: rgba(0, 0, 0, 0.54);
direction: ltr;
--direction: ltr;
--float-start: left;
--float-end: right;
--margin-title-ltr: 0 0 0 24px;
--margin-title-rtl: 0 24px 0 0;
${unsafeCSS(
Object.entries(derivedStyles)
.map(([key, value]) => `--${key}: ${value};`)
.join("")
)}
}
`.toString();
const styleElement = document.createElement("style");
styleElement.textContent = [mainStyles, fontStyles].join("");
document.head.append(styleElement);

View File

@ -1,6 +1,6 @@
import { tsParticles } from "@tsparticles/engine";
import { loadLinksPreset } from "@tsparticles/preset-links";
import { DEFAULT_PRIMARY_COLOR } from "./styles-data";
import { DefaultPrimaryColor } from "./theme/color.globals";
loadLinksPreset(tsParticles).then(() => {
tsParticles.load({
@ -25,11 +25,11 @@ loadLinksPreset(tsParticles).then(() => {
},
particles: {
color: {
value: DEFAULT_PRIMARY_COLOR,
value: DefaultPrimaryColor,
},
links: {
color: {
value: DEFAULT_PRIMARY_COLOR,
value: DefaultPrimaryColor,
},
distance: 100,
enable: true,

View File

@ -121,4 +121,4 @@ export const fontStyles = css`
font-weight: 900;
font-style: italic;
}
`.toString();
`;

View File

@ -1,255 +0,0 @@
export const DEFAULT_PRIMARY_COLOR = "#03a9f4" as const;
export const DEFAULT_ACCENT_COLOR = "#ff9800" as const;
export const darkStyles = {
"primary-background-color": "#111111",
"card-background-color": "#1c1c1c",
"secondary-background-color": "#282828",
"clear-background-color": "#111111",
"primary-text-color": "#e1e1e1",
"secondary-text-color": "#9b9b9b",
"disabled-text-color": "#6f6f6f",
"app-header-text-color": "#e1e1e1",
"app-header-background-color": "#101e24",
"switch-unchecked-button-color": "#999999",
"switch-unchecked-track-color": "#9b9b9b",
"divider-color": "rgba(225, 225, 225, .12)",
"outline-color": "rgba(225, 225, 225, .12)",
"outline-hover-color": "rgba(225, 225, 225, .24)",
"mdc-ripple-color": "#AAAAAA",
"mdc-linear-progress-buffer-color": "rgba(255, 255, 255, 0.1)",
"input-idle-line-color": "rgba(255, 255, 255, 0.42)",
"input-hover-line-color": "rgba(255, 255, 255, 0.87)",
"input-disabled-line-color": "rgba(255, 255, 255, 0.06)",
"input-outlined-idle-border-color": "rgba(255, 255, 255, 0.38)",
"input-outlined-hover-border-color": "rgba(255, 255, 255, 0.87)",
"input-outlined-disabled-border-color": "rgba(255, 255, 255, 0.06)",
"input-fill-color": "rgba(255, 255, 255, 0.05)",
"input-disabled-fill-color": "rgba(255, 255, 255, 0.02)",
"input-ink-color": "rgba(255, 255, 255, 0.87)",
"input-label-ink-color": "rgba(255, 255, 255, 0.6)",
"input-disabled-ink-color": "rgba(255, 255, 255, 0.37)",
"input-dropdown-icon-color": "rgba(255, 255, 255, 0.54)",
"codemirror-keyword": "#C792EA",
"codemirror-operator": "#89DDFF",
"codemirror-variable": "#f07178",
"codemirror-variable-2": "#EEFFFF",
"codemirror-variable-3": "#DECB6B",
"codemirror-builtin": "#FFCB6B",
"codemirror-atom": "#F78C6C",
"codemirror-number": "#FF5370",
"codemirror-def": "#82AAFF",
"codemirror-string": "#C3E88D",
"codemirror-string-2": "#f07178",
"codemirror-comment": "#545454",
"codemirror-tag": "#FF5370",
"codemirror-meta": "#FFCB6B",
"codemirror-attribute": "#C792EA",
"codemirror-property": "#C792EA",
"codemirror-qualifier": "#DECB6B",
"codemirror-type": "#DECB6B",
"energy-grid-return-color": "#a280db",
"map-filter":
"invert(.9) hue-rotate(170deg) brightness(1.5) contrast(1.2) saturate(.3)",
"disabled-color": "#464646",
} as const;
export const derivedStyles = {
/* typography */
"ha-font-size-xs": "calc(10px * var(--ha-font-size-scale))",
"ha-font-size-s": "calc(12px * var(--ha-font-size-scale))",
"ha-font-size-m": "calc(14px * var(--ha-font-size-scale))",
"ha-font-size-l": "calc(16px * var(--ha-font-size-scale))",
"ha-font-size-xl": "calc(20px * var(--ha-font-size-scale))",
"ha-font-size-2xl": "calc(24px * var(--ha-font-size-scale))",
"ha-font-size-3xl": "calc(28px * var(--ha-font-size-scale))",
"ha-font-size-4xl": "calc(32px * var(--ha-font-size-scale))",
"ha-font-size-5xl": "calc(40px * var(--ha-font-size-scale))",
"ha-font-family-heading": "var(--ha-font-family-body)",
"ha-font-weight-body": "var(--ha-font-weight-normal)",
"ha-font-weight-heading": "var(--ha-font-weight-bold)",
"ha-font-weight-action": "var(--ha-font-weight-semibold)",
/* Vaadin typography */
"material-h6-font-size": "var(--ha-font-size-m)",
"material-small-font-size": "var(--ha-font-size-xs)",
"material-caption-font-size": "var(--ha-font-size-2xs)",
"material-button-font-size": "var(--ha-font-size-xs)",
/* for label-badge */
"label-badge-red": "var(--error-color)",
"label-badge-blue": "var(--info-color)",
"label-badge-green": "var(--success-color)",
"label-badge-yellow": "var(--warning-color)",
/* state color */
"state-active-color": "var(--amber-color)",
"state-inactive-color": "var(--grey-color)",
"state-unavailable-color":
"var(--state-icon-unavailable-color, var(--disabled-text-color))",
/* state domain colors */
"state-alarm_control_panel-armed_away-color": "var(--green-color)",
"state-alarm_control_panel-armed_custom_bypass-color": "var(--green-color)",
"state-alarm_control_panel-armed_home-color": "var(--green-color)",
"state-alarm_control_panel-armed_night-color": "var(--green-color)",
"state-alarm_control_panel-armed_vacation-color": "var(--green-color)",
"state-alarm_control_panel-arming-color": "var(--orange-color)",
"state-alarm_control_panel-disarming-color": "var(--orange-color)",
"state-alarm_control_panel-pending-color": "var(--orange-color)",
"state-alarm_control_panel-triggered-color": "var(--red-color)",
"state-alert-off-color": "var(--orange-color)",
"state-alert-on-color": "var(--red-color)",
"state-binary_sensor-active-color": "var(--amber-color)",
"state-binary_sensor-battery-on-color": "var(--red-color)",
"state-binary_sensor-carbon_monoxide-on-color": "var(--red-color)",
"state-binary_sensor-gas-on-color": "var(--red-color)",
"state-binary_sensor-heat-on-color": "var(--red-color)",
"state-binary_sensor-lock-on-color": "var(--red-color)",
"state-binary_sensor-moisture-on-color": "var(--red-color)",
"state-binary_sensor-problem-on-color": "var(--red-color)",
"state-binary_sensor-safety-on-color": "var(--red-color)",
"state-binary_sensor-smoke-on-color": "var(--red-color)",
"state-binary_sensor-sound-on-color": "var(--red-color)",
"state-binary_sensor-tamper-on-color": "var(--red-color)",
"state-climate-auto-color": "var(--green-color)",
"state-climate-cool-color": "var(--blue-color)",
"state-climate-dry-color": "var(--orange-color)",
"state-climate-fan_only-color": "var(--cyan-color)",
"state-climate-heat-color": "var(--deep-orange-color)",
"state-climate-heat-cool-color": "var(--amber-color)",
"state-cover-active-color": "var(--purple-color)",
"state-device_tracker-active-color": "var(--blue-color)",
"state-device_tracker-home-color": "var(--green-color)",
"state-fan-active-color": "var(--cyan-color)",
"state-humidifier-on-color": "var(--blue-color)",
"state-lawn_mower-error-color": "var(--red-color)",
"state-lawn_mower-mowing-color": "var(--teal-color)",
"state-light-active-color": "var(--amber-color)",
"state-lock-jammed-color": "var(--red-color)",
"state-lock-locked-color": "var(--green-color)",
"state-lock-locking-color": "var(--orange-color)",
"state-lock-unlocked-color": "var(--red-color)",
"state-lock-unlocking-color": "var(--orange-color)",
"state-lock-open-color": "var(--red-color)",
"state-lock-opening-color": "var(--orange-color)",
"state-media_player-active-color": "var(--light-blue-color)",
"state-person-active-color": "var(--blue-color)",
"state-person-home-color": "var(--green-color)",
"state-plant-active-color": "var(--red-color)",
"state-siren-active-color": "var(--red-color)",
"state-sun-above_horizon-color": "var(--amber-color)",
"state-sun-below_horizon-color": "var(--indigo-color)",
"state-switch-active-color": "var(--amber-color)",
"state-update-active-color": "var(--orange-color)",
"state-vacuum-active-color": "var(--teal-color)",
"state-valve-active-color": "var(--blue-color)",
"state-sensor-battery-high-color": "var(--green-color)",
"state-sensor-battery-low-color": "var(--red-color)",
"state-sensor-battery-medium-color": "var(--orange-color)",
"state-water_heater-eco-color": "var(--green-color)",
"state-water_heater-electric-color": "var(--orange-color)",
"state-water_heater-gas-color": "var(--orange-color)",
"state-water_heater-heat_pump-color": "var(--orange-color)",
"state-water_heater-high_demand-color": "var(--deep-orange-color)",
"state-water_heater-performance-color": "var(--deep-orange-color)",
/* history colors */
"history-unknown-color": "var(--dark-grey-color)",
"state-icon-error-color": "var(--error-state-color, var(--error-color))",
"sidebar-text-color": "var(--primary-text-color)",
"sidebar-background-color": "var(--card-background-color)",
"sidebar-selected-text-color": "var(--primary-color)",
"sidebar-selected-icon-color": "var(--primary-color)",
"sidebar-icon-color": "rgba(var(--rgb-primary-text-color), 0.6)",
"switch-checked-color": "var(--primary-color)",
"switch-checked-button-color":
"var(--switch-checked-color, var(--primary-background-color))",
"switch-checked-track-color": "var(--switch-checked-color, #000000)",
"switch-unchecked-button-color":
"var(--switch-unchecked-color, var(--primary-background-color))",
"switch-unchecked-track-color": "var(--switch-unchecked-color, #000000)",
"slider-color": "var(--primary-color)",
"slider-secondary-color": "var(--light-primary-color)",
"slider-track-color": "var(--scrollbar-thumb-color)",
"label-badge-background-color": "var(--card-background-color)",
"label-badge-text-color": "rgba(var(--rgb-primary-text-color), 0.8)",
"table-header-background-color": "var(--input-fill-color)",
"table-row-background-color": "var(--primary-background-color)",
"table-row-alternative-background-color": "var(--secondary-background-color)",
"data-table-background-color": "var(--card-background-color)",
"markdown-code-background-color": "var(--primary-background-color)",
// https://github.com/material-components/material-web/blob/master/docs/theming.md
"mdc-theme-primary": "var(--primary-color)",
"mdc-theme-secondary": "var(--accent-color)",
"mdc-theme-background": "var(--primary-background-color)",
"mdc-theme-surface": "var(--card-background-color)",
"mdc-theme-on-primary": "var(--text-primary-color)",
"mdc-theme-on-secondary": "var(--text-primary-color)",
"mdc-theme-on-surface": "var(--primary-text-color)",
"mdc-theme-text-disabled-on-light": "var(--disabled-text-color)",
"mdc-theme-text-primary-on-background": "var(--primary-text-color)",
"mdc-theme-text-secondary-on-background": "var(--secondary-text-color)",
"mdc-theme-text-hint-on-background": "var(--secondary-text-color)",
"mdc-theme-text-icon-on-background": "var(--secondary-text-color)",
"mdc-theme-error": "var(--error-color)",
"app-header-text-color": "var(--text-primary-color)",
"app-header-background-color": "var(--primary-color)",
"app-theme-color": "var(--app-header-background-color)",
"mdc-checkbox-unchecked-color": "rgba(var(--rgb-primary-text-color), 0.54)",
"mdc-checkbox-disabled-color": "var(--disabled-text-color)",
"mdc-radio-unchecked-color": "rgba(var(--rgb-primary-text-color), 0.54)",
"mdc-radio-disabled-color": "var(--disabled-text-color)",
"mdc-tab-text-label-color-default": "var(--primary-text-color)",
"mdc-button-disabled-ink-color": "var(--disabled-text-color)",
"mdc-button-outline-color": "var(--outline-color)",
"mdc-dialog-scroll-divider-color": "var(--divider-color)",
"mdc-dialog-heading-ink-color": "var(--primary-text-color)",
"mdc-dialog-content-ink-color": "var(--primary-text-color)",
"mdc-text-field-idle-line-color": "var(--input-idle-line-color)",
"mdc-text-field-hover-line-color": "var(--input-hover-line-color)",
"mdc-text-field-disabled-line-color": "var(--input-disabled-line-color)",
"mdc-text-field-outlined-idle-border-color":
"var(--input-outlined-idle-border-color)",
"mdc-text-field-outlined-hover-border-color":
"var(--input-outlined-hover-border-color)",
"mdc-text-field-outlined-disabled-border-color":
"var(--input-outlined-disabled-border-color)",
"mdc-text-field-fill-color": "var(--input-fill-color)",
"mdc-text-field-disabled-fill-color": "var(--input-disabled-fill-color)",
"mdc-text-field-ink-color": "var(--input-ink-color)",
"mdc-text-field-label-ink-color": "var(--input-label-ink-color)",
"mdc-text-field-disabled-ink-color": "var(--input-disabled-ink-color)",
"mdc-select-idle-line-color": "var(--input-idle-line-color)",
"mdc-select-hover-line-color": "var(--input-hover-line-color)",
"mdc-select-outlined-idle-border-color":
"var(--input-outlined-idle-border-color)",
"mdc-select-outlined-hover-border-color":
"var(--input-outlined-hover-border-color)",
"mdc-select-outlined-disabled-border-color":
"var(--input-outlined-disabled-border-color)",
"mdc-select-fill-color": "var(--input-fill-color)",
"mdc-select-disabled-fill-color": "var(--input-disabled-fill-color)",
"mdc-select-ink-color": "var(--input-ink-color)",
"mdc-select-label-ink-color": "var(--input-label-ink-color)",
"mdc-select-disabled-ink-color": "var(--input-disabled-ink-color)",
"mdc-select-dropdown-icon-color": "var(--input-dropdown-icon-color)",
"mdc-select-disabled-dropdown-icon-color": "var(--input-disabled-ink-color)",
"ha-assist-chip-filled-container-color":
"rgba(var(--rgb-primary-text-color),0.15)",
"ha-assist-chip-active-container-color":
"rgba(var(--rgb-primary-color),0.15)",
"chip-background-color": "rgba(var(--rgb-primary-text-color), 0.15)",
// Vaadin
"material-body-text-color": "var(--primary-text-color)",
"material-background-color": "var(--card-background-color)",
"material-secondary-background-color": "var(--secondary-background-color)",
"material-secondary-text-color": "var(--secondary-text-color)",
} as const;

View File

@ -0,0 +1,359 @@
import { css } from "lit";
import {
extractDerivedVars,
extractVar,
extractVars,
} from "../../common/style/derived-css-vars";
export const colorStyles = css`
html {
/* text */
--primary-text-color: #212121;
--secondary-text-color: #727272;
--text-primary-color: #ffffff;
--text-light-primary-color: #212121;
--disabled-text-color: #bdbdbd;
/* main interface colors */
--primary-color: #03a9f4;
--dark-primary-color: #0288d1;
--light-primary-color: #b3e5fc;
--accent-color: #ff9800;
--divider-color: rgba(0, 0, 0, 0.12);
--outline-color: rgba(0, 0, 0, 0.12);
--outline-hover-color: rgba(0, 0, 0, 0.24);
/* rgb */
--rgb-primary-color: 3, 169, 244;
--rgb-accent-color: 255, 152, 0;
--rgb-primary-text-color: 33, 33, 33;
--rgb-secondary-text-color: 114, 114, 114;
--rgb-text-primary-color: 255, 255, 255;
--rgb-card-background-color: 255, 255, 255;
--scrollbar-thumb-color: rgb(194, 194, 194);
--error-color: #db4437;
--warning-color: #ffa600;
--success-color: #43a047;
--info-color: #039be5;
/* backgrounds */
--card-background-color: #ffffff;
--primary-background-color: #fafafa;
--secondary-background-color: #e5e5e5; /* behind the cards on state */
--clear-background-color: #ffffff;
/* for label-badge */
--label-badge-grey: #9e9e9e;
/* states icon */
--state-icon-color: #44739e;
/* an error state is anything that would be considered an error */
/* --state-icon-error-color: #db4437; derived from error-color */
/* energy */
--energy-grid-consumption-color: #488fc2;
--energy-grid-return-color: #8353d1;
--energy-solar-color: #ff9800;
--energy-non-fossil-color: #0f9d58;
--energy-battery-out-color: #4db6ac;
--energy-battery-in-color: #f06292;
--energy-gas-color: #8e021b;
--energy-water-color: #00bcd4;
/* color */
--disabled-color: #bdbdbd;
--red-color: #f44336;
--pink-color: #e91e63;
--purple-color: #926bc7;
--deep-purple-color: #6e41ab;
--indigo-color: #3f51b5;
--blue-color: #2196f3;
--light-blue-color: #03a9f4;
--cyan-color: #00bcd4;
--teal-color: #009688;
--green-color: #4caf50;
--light-green-color: #8bc34a;
--lime-color: #cddc39;
--yellow-color: #ffeb3b;
--amber-color: #ffc107;
--orange-color: #ff9800;
--deep-orange-color: #ff6f22;
--brown-color: #795548;
--light-grey-color: #bdbdbd;
--grey-color: #9e9e9e;
--dark-grey-color: #606060;
--blue-grey-color: #607d8b;
--black-color: #000000;
--white-color: #ffffff;
/* history colors */
--history-unavailable-color: transparent;
/* input components */
--input-idle-line-color: rgba(0, 0, 0, 0.42);
--input-hover-line-color: rgba(0, 0, 0, 0.87);
--input-disabled-line-color: rgba(0, 0, 0, 0.06);
--input-outlined-idle-border-color: rgba(0, 0, 0, 0.38);
--input-outlined-hover-border-color: rgba(0, 0, 0, 0.87);
--input-outlined-disabled-border-color: rgba(0, 0, 0, 0.06);
--input-fill-color: rgb(245, 245, 245);
--input-disabled-fill-color: rgb(250, 250, 250);
--input-ink-color: rgba(0, 0, 0, 0.87);
--input-label-ink-color: rgba(0, 0, 0, 0.6);
--input-disabled-ink-color: rgba(0, 0, 0, 0.37);
--input-dropdown-icon-color: rgba(0, 0, 0, 0.54);
/* for label-badge */
--label-badge-red: var(--error-color);
--label-badge-blue: var(--info-color);
--label-badge-green: var(--success-color);
--label-badge-yellow: var(--warning-color);
/* state color */
--state-active-color: var(--amber-color);
--state-inactive-color: var(--grey-color);
--state-unavailable-color: var(
--state-icon-unavailable-color,
var(--disabled-text-color)
);
/* state domain colors */
--state-alarm_control_panel-armed_away-color: var(--green-color);
--state-alarm_control_panel-armed_custom_bypass-color: var(--green-color);
--state-alarm_control_panel-armed_home-color: var(--green-color);
--state-alarm_control_panel-armed_night-color: var(--green-color);
--state-alarm_control_panel-armed_vacation-color: var(--green-color);
--state-alarm_control_panel-arming-color: var(--orange-color);
--state-alarm_control_panel-disarming-color: var(--orange-color);
--state-alarm_control_panel-pending-color: var(--orange-color);
--state-alarm_control_panel-triggered-color: var(--red-color);
--state-alert-off-color: var(--orange-color);
--state-alert-on-color: var(--red-color);
--state-binary_sensor-active-color: var(--amber-color);
--state-binary_sensor-battery-on-color: var(--red-color);
--state-binary_sensor-carbon_monoxide-on-color: var(--red-color);
--state-binary_sensor-gas-on-color: var(--red-color);
--state-binary_sensor-heat-on-color: var(--red-color);
--state-binary_sensor-lock-on-color: var(--red-color);
--state-binary_sensor-moisture-on-color: var(--red-color);
--state-binary_sensor-problem-on-color: var(--red-color);
--state-binary_sensor-safety-on-color: var(--red-color);
--state-binary_sensor-smoke-on-color: var(--red-color);
--state-binary_sensor-sound-on-color: var(--red-color);
--state-binary_sensor-tamper-on-color: var(--red-color);
--state-climate-auto-color: var(--green-color);
--state-climate-cool-color: var(--blue-color);
--state-climate-dry-color: var(--orange-color);
--state-climate-fan_only-color: var(--cyan-color);
--state-climate-heat-color: var(--deep-orange-color);
--state-climate-heat-cool-color: var(--amber-color);
--state-cover-active-color: var(--purple-color);
--state-device_tracker-active-color: var(--blue-color);
--state-device_tracker-home-color: var(--green-color);
--state-fan-active-color: var(--cyan-color);
--state-humidifier-on-color: var(--blue-color);
--state-lawn_mower-error-color: var(--red-color);
--state-lawn_mower-mowing-color: var(--teal-color);
--state-light-active-color: var(--amber-color);
--state-lock-jammed-color: var(--red-color);
--state-lock-locked-color: var(--green-color);
--state-lock-locking-color: var(--orange-color);
--state-lock-unlocked-color: var(--red-color);
--state-lock-unlocking-color: var(--orange-color);
--state-lock-open-color: var(--red-color);
--state-lock-opening-color: var(--orange-color);
--state-media_player-active-color: var(--light-blue-color);
--state-person-active-color: var(--blue-color);
--state-person-home-color: var(--green-color);
--state-plant-active-color: var(--red-color);
--state-siren-active-color: var(--red-color);
--state-sun-above_horizon-color: var(--amber-color);
--state-sun-below_horizon-color: var(--indigo-color);
--state-switch-active-color: var(--amber-color);
--state-update-active-color: var(--orange-color);
--state-vacuum-active-color: var(--teal-color);
--state-valve-active-color: var(--blue-color);
--state-sensor-battery-high-color: var(--green-color);
--state-sensor-battery-low-color: var(--red-color);
--state-sensor-battery-medium-color: var(--orange-color);
--state-water_heater-eco-color: var(--green-color);
--state-water_heater-electric-color: var(--orange-color);
--state-water_heater-gas-color: var(--orange-color);
--state-water_heater-heat_pump-color: var(--orange-color);
--state-water_heater-high_demand-color: var(--deep-orange-color);
--state-water_heater-performance-color: var(--deep-orange-color);
/* history colors */
--history-unknown-color: var(--dark-grey-color);
--state-icon-error-color: var(--error-state-color, var(--error-color));
--sidebar-text-color: var(--primary-text-color);
--sidebar-background-color: var(--card-background-color);
--sidebar-selected-text-color: var(--primary-color);
--sidebar-selected-icon-color: var(--primary-color);
--sidebar-icon-color: rgba(var(--rgb-primary-text-color), 0.6);
--switch-checked-color: var(--primary-color);
--switch-checked-button-color: var(
--switch-checked-color,
var(--primary-background-color)
);
--switch-checked-track-color: var(--switch-checked-color, #000000);
--switch-unchecked-button-color: var(
--switch-unchecked-color,
var(--primary-background-color)
);
--switch-unchecked-track-color: var(--switch-unchecked-color, #000000);
--slider-color: var(--primary-color);
--slider-secondary-color: var(--light-primary-color);
--slider-track-color: var(--scrollbar-thumb-color);
--label-badge-background-color: var(--card-background-color);
--label-badge-text-color: rgba(var(--rgb-primary-text-color), 0.8);
--table-header-background-color: var(--input-fill-color);
--table-row-background-color: var(--primary-background-color);
--table-row-alternative-background-color: var(--secondary-background-color);
--data-table-background-color: var(--card-background-color);
--markdown-code-background-color: var(--primary-background-color);
/* https://github.com/material-components/material-web/blob/master/docs/theming.md */
--mdc-theme-primary: var(--primary-color);
--mdc-theme-secondary: var(--accent-color);
--mdc-theme-background: var(--primary-background-color);
--mdc-theme-surface: var(--card-background-color);
--mdc-theme-on-primary: var(--text-primary-color);
--mdc-theme-on-secondary: var(--text-primary-color);
--mdc-theme-on-surface: var(--primary-text-color);
--mdc-theme-text-disabled-on-light: var(--disabled-text-color);
--mdc-theme-text-primary-on-background: var(--primary-text-color);
--mdc-theme-text-secondary-on-background: var(--secondary-text-color);
--mdc-theme-text-hint-on-background: var(--secondary-text-color);
--mdc-theme-text-icon-on-background: var(--secondary-text-color);
--mdc-theme-error: var(--error-color);
--app-header-text-color: var(--text-primary-color);
--app-header-background-color: var(--primary-color);
--app-theme-color: var(--app-header-background-color);
--mdc-checkbox-unchecked-color: rgba(var(--rgb-primary-text-color), 0.54);
--mdc-checkbox-disabled-color: var(--disabled-text-color);
--mdc-radio-unchecked-color: rgba(var(--rgb-primary-text-color), 0.54);
--mdc-radio-disabled-color: var(--disabled-text-color);
--mdc-tab-text-label-color-default: var(--primary-text-color);
--mdc-button-disabled-ink-color: var(--disabled-text-color);
--mdc-button-outline-color: var(--outline-color);
--mdc-dialog-scroll-divider-color: var(--divider-color);
--mdc-dialog-heading-ink-color: var(--primary-text-color);
--mdc-dialog-content-ink-color: var(--primary-text-color);
--mdc-text-field-idle-line-color: var(--input-idle-line-color);
--mdc-text-field-hover-line-color: var(--input-hover-line-color);
--mdc-text-field-disabled-line-color: var(--input-disabled-line-color);
--mdc-text-field-outlined-idle-border-color: var(
--input-outlined-idle-border-color
);
--mdc-text-field-outlined-hover-border-color: var(
--input-outlined-hover-border-color
);
--mdc-text-field-outlined-disabled-border-color: var(
--input-outlined-disabled-border-color
);
--mdc-text-field-fill-color: var(--input-fill-color);
--mdc-text-field-disabled-fill-color: var(--input-disabled-fill-color);
--mdc-text-field-ink-color: var(--input-ink-color);
--mdc-text-field-label-ink-color: var(--input-label-ink-color);
--mdc-text-field-disabled-ink-color: var(--input-disabled-ink-color);
--mdc-select-idle-line-color: var(--input-idle-line-color);
--mdc-select-hover-line-color: var(--input-hover-line-color);
--mdc-select-outlined-idle-border-color: var(
--input-outlined-idle-border-color
);
--mdc-select-outlined-hover-border-color: var(
--input-outlined-hover-border-color
);
--mdc-select-outlined-disabled-border-color: var(
--input-outlined-disabled-border-color
);
--mdc-select-fill-color: var(--input-fill-color);
--mdc-select-disabled-fill-color: var(--input-disabled-fill-color);
--mdc-select-ink-color: var(--input-ink-color);
--mdc-select-label-ink-color: var(--input-label-ink-color);
--mdc-select-disabled-ink-color: var(--input-disabled-ink-color);
--mdc-select-dropdown-icon-color: var(--input-dropdown-icon-color);
--mdc-select-disabled-dropdown-icon-color: var(--input-disabled-ink-color);
--ha-assist-chip-filled-container-color: rgba(
var(--rgb-primary-text-color),
0.15
);
--ha-assist-chip-active-container-color: rgba(
var(--rgb-primary-color),
0.15
);
--chip-background-color: rgba(var(--rgb-primary-text-color), 0.15);
/* Vaadin */
--material-body-text-color: var(--primary-text-color);
--material-background-color: var(--card-background-color);
--material-secondary-background-color: var(--secondary-background-color);
--material-secondary-text-color: var(--secondary-text-color);
}
`;
const darkColorStyles = css`
--primary-background-color: #111111;
--card-background-color: #1c1c1c;
--secondary-background-color: #282828;
--clear-background-color: #111111;
--primary-text-color: #e1e1e1;
--secondary-text-color: #9b9b9b;
--disabled-text-color: #6f6f6f;
--app-header-text-color: #e1e1e1;
--app-header-background-color: #101e24;
--switch-unchecked-button-color: #999999;
--switch-unchecked-track-color: #9b9b9b;
--divider-color: rgba(225, 225, 225, 0.12);
--outline-color: rgba(225, 225, 225, 0.12);
--outline-hover-color: rgba(225, 225, 225, 0.24);
--mdc-ripple-color: #aaaaaa;
--mdc-linear-progress-buffer-color: rgba(255, 255, 255, 0.1);
--input-idle-line-color: rgba(255, 255, 255, 0.42);
--input-hover-line-color: rgba(255, 255, 255, 0.87);
--input-disabled-line-color: rgba(255, 255, 255, 0.06);
--input-outlined-idle-border-color: rgba(255, 255, 255, 0.38);
--input-outlined-hover-border-color: rgba(255, 255, 255, 0.87);
--input-outlined-disabled-border-color: rgba(255, 255, 255, 0.06);
--input-fill-color: rgba(255, 255, 255, 0.05);
--input-disabled-fill-color: rgba(255, 255, 255, 0.02);
--input-ink-color: rgba(255, 255, 255, 0.87);
--input-label-ink-color: rgba(255, 255, 255, 0.6);
--input-disabled-ink-color: rgba(255, 255, 255, 0.37);
--input-dropdown-icon-color: rgba(255, 255, 255, 0.54);
--codemirror-keyword: #c792ea;
--codemirror-operator: #89ddff;
--codemirror-variable: #f07178;
--codemirror-variable-2: #eeffff;
--codemirror-variable-3: #decb6b;
--codemirror-builtin: #ffcb6b;
--codemirror-atom: #f78c6c;
--codemirror-number: #ff5370;
--codemirror-def: #82aaff;
--codemirror-string: #c3e88d;
--codemirror-string-2: #f07178;
--codemirror-comment: #545454;
--codemirror-tag: #ff5370;
--codemirror-meta: #ffcb6b;
--codemirror-attribute: #c792ea;
--codemirror-property: #c792ea;
--codemirror-qualifier: #decb6b;
--codemirror-type: #decb6b;
--energy-grid-return-color: #a280db;
--map-filter: invert(0.9) hue-rotate(170deg) brightness(1.5) contrast(1.2)
saturate(0.3);
--disabled-color: #464646;
`;
export const colorDerivedVariables = extractDerivedVars(colorStyles);
export const darkColorVariables = extractVars(darkColorStyles);
export const DefaultPrimaryColor = extractVar(colorStyles, "primary-color");
export const DefaultAccentColor = extractVar(colorStyles, "accent-color");

View File

@ -0,0 +1,38 @@
import { css } from "lit";
import { extractDerivedVars } from "../../common/style/derived-css-vars";
export const mainStyles = css`
html {
height: 100vh;
/* for header */
--header-height: 56px;
/* opacity for dark text on a light background */
--dark-divider-opacity: 0.12;
--dark-disabled-opacity: 0.38; /* or hint text or icon */
--dark-secondary-opacity: 0.54;
--dark-primary-opacity: 0.87;
/* opacity for light text on a dark background */
--light-divider-opacity: 0.12;
--light-disabled-opacity: 0.3; /* or hint text or icon */
--light-secondary-opacity: 0.7;
--light-primary-opacity: 1;
direction: ltr;
--direction: ltr;
--float-start: left;
--float-end: right;
--margin-title-ltr: 0 0 0 24px;
--margin-title-rtl: 0 24px 0 0;
/* Vaadin typography */
--material-h6-font-size: var(--ha-font-size-m);
--material-small-font-size: var(--ha-font-size-xs);
--material-caption-font-size: var(--ha-font-size-2xs);
--material-button-font-size: var(--ha-font-size-xs);
}
`;
export const mainDerivedVariables = extractDerivedVars(mainStyles);

View File

@ -0,0 +1,20 @@
import { fontStyles } from "../roboto";
import { colorDerivedVariables, colorStyles } from "./color.globals";
import { mainDerivedVariables, mainStyles } from "./main.globals";
import {
typographyDerivedVariables,
typographyStyles,
} from "./typography.globals";
export const themeStyles = [
fontStyles.toString(),
mainStyles.toString(),
typographyStyles.toString(),
colorStyles.toString(),
].join("");
export const derivedStyles = {
...mainDerivedVariables,
...typographyDerivedVariables,
...colorDerivedVariables,
};

View File

@ -0,0 +1,40 @@
import { css } from "lit";
import { extractDerivedVars } from "../../common/style/derived-css-vars";
export const typographyStyles = css`
html {
--ha-font-family-body: Roboto, Noto, sans-serif;
--ha-font-family-code: monospace;
--ha-font-family-longform: ui-sans-serif, system-ui, sans-serif;
font-size: 14px;
--ha-font-size-scale: 1;
--ha-font-size-xs: calc(10px * var(--ha-font-size-scale));
--ha-font-size-s: calc(12px * var(--ha-font-size-scale));
--ha-font-size-m: calc(14px * var(--ha-font-size-scale));
--ha-font-size-l: calc(16px * var(--ha-font-size-scale));
--ha-font-size-xl: calc(20px * var(--ha-font-size-scale));
--ha-font-size-2xl: calc(24px * var(--ha-font-size-scale));
--ha-font-size-3xl: calc(28px * var(--ha-font-size-scale));
--ha-font-size-4xl: calc(32px * var(--ha-font-size-scale));
--ha-font-size-5xl: calc(40px * var(--ha-font-size-scale));
--ha-font-weight-light: 300;
--ha-font-weight-normal: 400;
--ha-font-weight-semibold: 500;
--ha-font-weight-bold: 600;
--ha-font-family-heading: var(--ha-font-family-body);
--ha-font-weight-body: var(--ha-font-weight-normal);
--ha-font-weight-heading: var(--ha-font-weight-bold);
--ha-font-weight-action: var(--ha-font-weight-semibold);
--ha-line-height-condensed: 1.2;
--ha-line-height-normal: 1.6;
--ha-line-height-expanded: 2;
--ha-font-smoothing: antialiased;
}
`;
export const typographyDerivedVariables = extractDerivedVars(typographyStyles);