diff --git a/.nvmrc b/.nvmrc index 209e3ef4b624..9de2256827ae 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20 +lts/iron diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index aa84af365cbc..e662941010bb 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -12,11 +12,7 @@ module.exports.sourceMapURL = () => { }; // Files from NPM Packages that should not be imported -// eslint-disable-next-line unused-imports/no-unused-vars -module.exports.ignorePackages = ({ latestBuild }) => [ - // Part of yaml.js and only used for !!js functions that we don't use - require.resolve("esprima"), -]; +module.exports.ignorePackages = () => []; // Files from NPM packages that we should replace with empty file module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) => diff --git a/demo/src/html/index.html.template b/demo/src/html/index.html.template index 89236790afdb..c2be4e7cc39c 100644 --- a/demo/src/html/index.html.template +++ b/demo/src/html/index.html.template @@ -74,19 +74,9 @@
- - - + + +
diff --git a/gallery/src/pages/components/ha-chips.ts b/gallery/src/pages/components/ha-chips.ts index 43e2e7d6e8ae..677f0c7bf9c7 100644 --- a/gallery/src/pages/components/ha-chips.ts +++ b/gallery/src/pages/components/ha-chips.ts @@ -1,8 +1,10 @@ -import { css, html, LitElement, TemplateResult } from "lit"; +import { css, html, LitElement, TemplateResult, nothing } from "lit"; import { customElement } from "lit/decorators"; import "../../../../src/components/ha-card"; -import "../../../../src/components/ha-chip"; -import "../../../../src/components/ha-chip-set"; +import "../../../../src/components/chips/ha-chip-set"; +import "../../../../src/components/chips/ha-assist-chip"; +import "../../../../src/components/chips/ha-input-chip"; +import "../../../../src/components/chips/ha-filter-chip"; import "../../../../src/components/ha-svg-icon"; import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg"; @@ -10,10 +12,6 @@ const chips: { icon?: string; content?: string; }[] = [ - {}, - { - icon: mdiHomeAssistant, - }, { content: "Content", }, @@ -29,31 +27,73 @@ export class DemoHaChips extends LitElement { return html`
- ${chips.map( - (chip) => html` - - ${chip.icon - ? html` - ` - : ""} - ${chip.content} - - ` - )} -
-
- -
+

Action chip

+ + ${chips.map( + (chip) => html` + + ${chip.icon + ? html` + ` + : nothing} + + ` + )} + ${chips.map( + (chip) => html` + + ${chip.icon + ? html` + ` + : nothing} + + ` + )} + +

Filter chip

+ + ${chips.map( + (chip) => html` + + ${chip.icon + ? html` + ` + : nothing} + + ` + )} + ${chips.map( + (chip) => html` + + ${chip.icon + ? html` + ` + : nothing} + + ` + )} + +

Input chip

${chips.map( (chip) => html` - + ${chip.icon ? html` ` : ""} ${chip.content} - + + ` + )} + ${chips.map( + (chip) => html` + + ${chip.icon + ? html` + ` + : nothing} + ` )} @@ -68,12 +108,10 @@ export class DemoHaChips extends LitElement { max-width: 600px; margin: 24px auto; } - ha-chip { - margin-bottom: 4px; - } .card-content { display: flex; flex-direction: column; + align-items: flex-start; } `; } diff --git a/gallery/src/pages/components/ha-control-slider.ts b/gallery/src/pages/components/ha-control-slider.ts index 5faf01a1fc5d..efc61bb46146 100644 --- a/gallery/src/pages/components/ha-control-slider.ts +++ b/gallery/src/pages/components/ha-control-slider.ts @@ -9,6 +9,7 @@ const sliders: { id: string; label: string; mode?: "start" | "end" | "cursor"; + unit?: string; class?: string; }[] = [ { @@ -31,18 +32,21 @@ const sliders: { label: "Slider (start mode) and custom style", mode: "start", class: "custom", + unit: "mm", }, { id: "slider-end-custom", label: "Slider (end mode) and custom style", mode: "end", class: "custom", + unit: "mm", }, { id: "slider-cursor-custom", label: "Slider (cursor mode) and custom style", mode: "cursor", class: "custom", + unit: "mm", }, ]; @@ -93,6 +97,7 @@ export class DemoHaBarSlider extends LitElement { @value-changed=${this.handleValueChanged} @slider-moved=${this.handleSliderMoved} aria-labelledby=${id} + .tooltipUnit=${config.unit} >
@@ -114,6 +119,7 @@ export class DemoHaBarSlider extends LitElement { @value-changed=${this.handleValueChanged} @slider-moved=${this.handleSliderMoved} aria-label=${label} + .tooltipUnit=${config.unit} > `; diff --git a/gallery/src/pages/misc/entity-state.ts b/gallery/src/pages/misc/entity-state.ts index 9e62a6ae91d0..1ab1d7df159f 100644 --- a/gallery/src/pages/misc/entity-state.ts +++ b/gallery/src/pages/misc/entity-state.ts @@ -10,7 +10,6 @@ import { computeStateDisplay } from "../../../../src/common/entity/compute_state import "../../../../src/components/data-table/ha-data-table"; import type { DataTableColumnContainer } from "../../../../src/components/data-table/ha-data-table"; import "../../../../src/components/entity/state-badge"; -import "../../../../src/components/ha-chip"; import { provideHass } from "../../../../src/fake_data/provide_hass"; import { HomeAssistant } from "../../../../src/types"; diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index f602ad24d898..074b8e08daee 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -31,8 +31,8 @@ import { navigate } from "../../../../src/common/navigate"; import "../../../../src/components/buttons/ha-progress-button"; import "../../../../src/components/ha-alert"; import "../../../../src/components/ha-card"; -import "../../../../src/components/ha-chip"; -import "../../../../src/components/ha-chip-set"; +import "../../../../src/components/chips/ha-chip-set"; +import "../../../../src/components/chips/ha-assist-chip"; import "../../../../src/components/ha-markdown"; import "../../../../src/components/ha-settings-row"; import "../../../../src/components/ha-svg-icon"; @@ -78,6 +78,7 @@ import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-has import { hassioStyle } from "../../resources/hassio-style"; import "../../update-available/update-available-card"; import { addonArchIsSupported, extractChangelog } from "../../util/addon"; +import { capitalizeFirstLetter } from "../../../../src/common/string/capitalize-first-letter"; const STAGE_ICON = { stable: mdiCheckCircle, @@ -234,28 +235,32 @@ class HassioAddonInfo extends LitElement { ${this.addon.stage !== "stable" - ? html` - - - ${this.supervisor.localize( - `addon.dashboard.capability.stages.${this.addon.stage}` - )} - ` + + + + ` : ""} - = 6, yellow: [3, 4, 5].includes(Number(this.addon.rating)), @@ -263,138 +268,183 @@ class HassioAddonInfo extends LitElement { })} @click=${this._showMoreInfo} id="rating" + .label=${capitalizeFirstLetter( + this.supervisor.localize( + "addon.dashboard.capability.label.rating" + ) + )} > - - ${this.supervisor.localize( - "addon.dashboard.capability.label.rating" - )} - + ${this.addon.host_network ? html` - - ${this.supervisor.localize( - "addon.dashboard.capability.label.host" - )} - + ` : ""} ${this.addon.full_access ? html` - - ${this.supervisor.localize( - "addon.dashboard.capability.label.hardware" - )} - + ` : ""} ${this.addon.homeassistant_api ? html` - - ${this.supervisor.localize( - "addon.dashboard.capability.label.core" - )} - + ` : ""} ${this._computeHassioApi ? html` - + - ${this.supervisor.localize( - `addon.dashboard.capability.role.${this.addon.hassio_role}` - ) || this.addon.hassio_role} - + ` : ""} ${this.addon.docker_api ? html` - - - ${this.supervisor.localize( - "addon.dashboard.capability.label.docker" + + > + + ` : ""} ${this.addon.host_pid ? html` - - - ${this.supervisor.localize( - "addon.dashboard.capability.label.host_pid" + + > + + ` : ""} ${this.addon.apparmor !== "default" ? html` - - ${this.supervisor.localize( - "addon.dashboard.capability.label.apparmor" - )} - + ` : ""} ${this.addon.auth_api ? html` - - - ${this.supervisor.localize( - "addon.dashboard.capability.label.auth" + + > + + ` : ""} ${this.addon.ingress ? html` - + - ${this.supervisor.localize( - "addon.dashboard.capability.label.ingress" - )} - + ` : ""} ${this.addon.signed ? html` - - - ${this.supervisor.localize( - "addon.dashboard.capability.label.signed" + + > + + ` : ""} @@ -1185,23 +1235,35 @@ class HassioAddonInfo extends LitElement { .description a { color: var(--primary-color); } - ha-chip { - text-transform: capitalize; - --ha-chip-text-color: var(--text-primary-color); - --ha-chip-background-color: var(--primary-color); + ha-assist-chip { + --md-sys-color-primary: var(--text-primary-color); + --md-sys-color-on-surface: var(--text-primary-color); + --ha-assist-chip-filled-container-color: var(--primary-color); } .red { - --ha-chip-background-color: var(--label-badge-red, #df4c1e); + --ha-assist-chip-filled-container-color: var( + --label-badge-red, + #df4c1e + ); } .blue { - --ha-chip-background-color: var(--label-badge-blue, #039be5); + --ha-assist-chip-filled-container-color: var( + --label-badge-blue, + #039be5 + ); } .green { - --ha-chip-background-color: var(--label-badge-green, #0da035); + --ha-assist-chip-filled-container-color: var( + --label-badge-green, + #0da035 + ); } .yellow { - --ha-chip-background-color: var(--label-badge-yellow, #f4b400); + --ha-assist-chip-filled-container-color: var( + --label-badge-yellow, + #f4b400 + ); } .capabilities { margin-bottom: 16px; @@ -1260,9 +1322,6 @@ class HassioAddonInfo extends LitElement { } @media (max-width: 720px) { - ha-chip { - line-height: 36px; - } .addon-options { max-width: 100%; } diff --git a/package.json b/package.json index 8cbcba7de5a7..041381d794f1 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@codemirror/legacy-modes": "6.3.3", "@codemirror/search": "6.5.4", "@codemirror/state": "6.3.1", - "@codemirror/view": "6.21.4", + "@codemirror/view": "6.22.0", "@egjs/hammerjs": "2.0.17", "@formatjs/intl-datetimeformat": "6.11.1", "@formatjs/intl-displaynames": "6.6.1", @@ -53,7 +53,7 @@ "@lit-labs/context": "0.4.1", "@lit-labs/motion": "1.0.6", "@lit-labs/observers": "2.0.2", - "@lit-labs/virtualizer": "2.0.9", + "@lit-labs/virtualizer": "2.0.10", "@lrnwebcomponents/simple-tooltip": "7.0.18", "@material/chips": "=14.0.0-canary.53b3cad2f.0", "@material/data-table": "=14.0.0-canary.53b3cad2f.0", @@ -94,8 +94,8 @@ "@polymer/paper-toast": "3.0.1", "@polymer/polymer": "3.5.1", "@thomasloven/round-slider": "0.6.0", - "@vaadin/combo-box": "24.2.1", - "@vaadin/vaadin-themable-mixin": "24.2.1", + "@vaadin/combo-box": "24.2.2", + "@vaadin/vaadin-themable-mixin": "24.2.2", "@vibrant/color": "3.2.1-alpha.1", "@vibrant/core": "3.2.1-alpha.1", "@vibrant/quantizer-mmcq": "3.2.1-alpha.1", @@ -122,7 +122,7 @@ "leaflet-draw": "1.0.4", "lit": "2.8.0", "luxon": "3.4.3", - "marked": "9.1.3", + "marked": "9.1.5", "memoize-one": "6.0.0", "node-vibrant": "3.2.1-alpha.1", "proxy-polyfill": "0.3.2", @@ -141,7 +141,7 @@ "ua-parser-js": "1.0.37", "unfetch": "5.0.0", "vis-data": "7.1.7", - "vis-network": "9.1.8", + "vis-network": "9.1.9", "vue": "2.7.15", "vue2-daterange-picker": "0.6.8", "weekstart": "2.0.0", @@ -174,7 +174,6 @@ "@types/babel__plugin-transform-runtime": "7.9.4", "@types/chromecast-caf-receiver": "6.0.11", "@types/chromecast-caf-sender": "1.0.7", - "@types/esprima": "4.0.5", "@types/glob": "8.1.0", "@types/html-minifier-terser": "7.0.1", "@types/js-yaml": "4.0.8", @@ -196,7 +195,7 @@ "babel-plugin-template-html-minifier": "4.1.0", "chai": "4.3.10", "del": "7.1.0", - "eslint": "8.52.0", + "eslint": "8.53.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-typescript": "17.1.0", "eslint-config-prettier": "9.0.0", @@ -204,10 +203,9 @@ "eslint-plugin-disable": "2.0.3", "eslint-plugin-import": "2.29.0", "eslint-plugin-lit": "1.10.1", - "eslint-plugin-lit-a11y": "4.1.0", + "eslint-plugin-lit-a11y": "4.1.1", "eslint-plugin-unused-imports": "3.0.0", "eslint-plugin-wc": "2.0.4", - "esprima": "4.0.1", "fancy-log": "2.0.0", "fs-extra": "11.1.1", "glob": "10.3.10", @@ -236,7 +234,7 @@ "rollup-plugin-terser": "7.0.2", "rollup-plugin-visualizer": "5.9.2", "serve-handler": "6.1.5", - "sinon": "17.0.0", + "sinon": "17.0.1", "source-map-url": "0.4.1", "systemjs": "6.14.2", "tar": "6.2.0", diff --git a/public/static/icons/mask-icon.svg b/public/static/icons/mask-icon.svg index 66db74fcc819..0993bef4cc83 100644 --- a/public/static/icons/mask-icon.svg +++ b/public/static/icons/mask-icon.svg @@ -1,23 +1 @@ - - - - - - - + \ No newline at end of file diff --git a/renovate.json b/renovate.json index f6e9e56c4fb7..741ef2c4998c 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "configMigration": true, "extends": [ ":ignoreModulesAndTests", ":label(Dependencies)", @@ -10,7 +11,7 @@ "group:recommended", "npm:unpublishSafe" ], - "enabledManagers": ["npm"], + "enabledManagers": ["npm", "nvm"], "postUpdateOptions": ["yarnDedupeHighest"], "lockFileMaintenance": { "description": ["Run after patch releases but before next beta"], @@ -28,11 +29,22 @@ "matchPackageNames": ["vue"], "allowedVersions": "< 3" }, + { + "description": "Group MDI packages", + "groupName": "Material Design Icons", + "matchPackageNames": ["@mdi/js", "@mdi/svg"] + }, { "description": "Group tsparticles engine and presets", "groupName": "tsparticles", "matchPackageNames": ["tsparticles-engine"], "matchPackagePrefixes": ["tsparticles-preset-"] + }, + { + "description": "Group and temporarily disable WDS packages", + "groupName": "Web Dev Server", + "matchPackagePrefixes": ["@web/dev-server"], + "enabled": false } ] } diff --git a/src/common/translations/blank_before_unit.ts b/src/common/translations/blank_before_unit.ts new file mode 100644 index 000000000000..34fe8ab2d562 --- /dev/null +++ b/src/common/translations/blank_before_unit.ts @@ -0,0 +1,15 @@ +import { FrontendLocaleData } from "../../data/translation"; +import { blankBeforePercent } from "./blank_before_percent"; + +export const blankBeforeUnit = ( + unit: string, + localeOptions?: FrontendLocaleData +): string => { + if (unit === "°") { + return ""; + } + if (localeOptions && unit === "%") { + return blankBeforePercent(localeOptions); + } + return " "; +}; diff --git a/src/components/chips/ha-assist-chip.ts b/src/components/chips/ha-assist-chip.ts new file mode 100644 index 000000000000..98d03bb886d4 --- /dev/null +++ b/src/components/chips/ha-assist-chip.ts @@ -0,0 +1,53 @@ +import { MdAssistChip } from "@material/web/chips/assist-chip"; +import { css, html } from "lit"; +import { customElement, property } from "lit/decorators"; + +@customElement("ha-assist-chip") +export class HaAssistChip extends MdAssistChip { + @property({ type: Boolean, reflect: true }) filled = false; + + static override styles = [ + ...super.styles, + css` + :host { + --md-sys-color-primary: var(--primary-text-color); + --md-sys-color-on-surface: var(--primary-text-color); + --md-assist-chip-container-shape: 16px; + --md-assist-chip-outline-color: var(--outline-color); + --md-assist-chip-label-text-weight: 400; + --ha-assist-chip-filled-container-color: rgba( + var(--rgb-primary-text-color), + 0.15 + ); + } + /** Material 3 doesn't have a filled chip, so we have to make our own **/ + .filled { + display: flex; + pointer-events: none; + border-radius: inherit; + inset: 0; + position: absolute; + background-color: var(--ha-assist-chip-filled-container-color); + } + /** Set the size of mdc icons **/ + ::slotted([slot="icon"]) { + display: flex; + --mdc-icon-size: var(--md-input-chip-icon-size, 18px); + } + `, + ]; + + protected override renderOutline() { + if (this.filled) { + return html``; + } + + return super.renderOutline(); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-assist-chip": HaAssistChip; + } +} diff --git a/src/components/chips/ha-chip-set.ts b/src/components/chips/ha-chip-set.ts new file mode 100644 index 000000000000..e82b49eeaf16 --- /dev/null +++ b/src/components/chips/ha-chip-set.ts @@ -0,0 +1,11 @@ +import { MdChipSet } from "@material/web/chips/chip-set"; +import { customElement } from "lit/decorators"; + +@customElement("ha-chip-set") +export class HaChipSet extends MdChipSet {} + +declare global { + interface HTMLElementTagNameMap { + "ha-chip-set": HaChipSet; + } +} diff --git a/src/components/chips/ha-filter-chip.ts b/src/components/chips/ha-filter-chip.ts new file mode 100644 index 000000000000..accd3c5f2313 --- /dev/null +++ b/src/components/chips/ha-filter-chip.ts @@ -0,0 +1,41 @@ +import { MdFilterChip } from "@material/web/chips/filter-chip"; +import { css, html } from "lit"; +import { customElement, property } from "lit/decorators"; + +@customElement("ha-filter-chip") +export class HaFilterChip extends MdFilterChip { + @property({ type: Boolean, reflect: true, attribute: "no-leading-icon" }) + noLeadingIcon = false; + + static override styles = [ + ...super.styles, + css` + :host { + --md-sys-color-primary: var(--primary-text-color); + --md-sys-color-on-surface: var(--primary-text-color); + --md-sys-color-on-surface-variant: var(--primary-text-color); + --md-sys-color-on-secondary-container: var(--primary-text-color); + --md-filter-chip-container-shape: 16px; + --md-filter-chip-outline-color: var(--outline-color); + --md-filter-chip-selected-container-color: rgba( + var(--rgb-primary-text-color), + 0.15 + ); + } + `, + ]; + + protected renderLeadingIcon() { + if (this.noLeadingIcon) { + // eslint-disable-next-line lit/prefer-nothing + return html``; + } + return super.renderLeadingIcon(); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-filter-chip": HaFilterChip; + } +} diff --git a/src/components/chips/ha-input-chip.ts b/src/components/chips/ha-input-chip.ts new file mode 100644 index 000000000000..cdaa980351a0 --- /dev/null +++ b/src/components/chips/ha-input-chip.ts @@ -0,0 +1,35 @@ +import { MdInputChip } from "@material/web/chips/input-chip"; +import { css } from "lit"; +import { customElement } from "lit/decorators"; + +@customElement("ha-input-chip") +export class HaInputChip extends MdInputChip { + static override styles = [ + ...super.styles, + css` + :host { + --md-sys-color-primary: var(--primary-text-color); + --md-sys-color-on-surface: var(--primary-text-color); + --md-sys-color-on-surface-variant: var(--primary-text-color); + --md-sys-color-on-secondary-container: var(--primary-text-color); + --md-input-chip-container-shape: 16px; + --md-input-chip-outline-color: var(--outline-color); + --md-input-chip-selected-container-color: rgba( + var(--rgb-primary-text-color), + 0.15 + ); + } + /** Set the size of mdc icons **/ + ::slotted([slot="icon"]) { + display: flex; + --mdc-icon-size: var(--md-input-chip-icon-size, 18px); + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-input-chip": HaInputChip; + } +} diff --git a/src/components/ha-chip-set.ts b/src/components/ha-chip-set.ts deleted file mode 100644 index 699f1b0a730d..000000000000 --- a/src/components/ha-chip-set.ts +++ /dev/null @@ -1,38 +0,0 @@ -// @ts-ignore -import chipStyles from "@material/chips/dist/mdc.chips.min.css"; -import { - css, - CSSResultGroup, - html, - LitElement, - TemplateResult, - unsafeCSS, -} from "lit"; -import { customElement } from "lit/decorators"; - -@customElement("ha-chip-set") -export class HaChipSet extends LitElement { - protected render(): TemplateResult { - return html` -
- -
- `; - } - - static get styles(): CSSResultGroup { - return css` - ${unsafeCSS(chipStyles)} - - slot::slotted(ha-chip) { - margin: 4px 4px 4px 0; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-chip-set": HaChipSet; - } -} diff --git a/src/components/ha-chip.ts b/src/components/ha-chip.ts deleted file mode 100644 index fc427fd93d8d..000000000000 --- a/src/components/ha-chip.ts +++ /dev/null @@ -1,85 +0,0 @@ -// @ts-ignore -import chipStyles from "@material/chips/dist/mdc.chips.min.css"; -import { css, CSSResultGroup, html, LitElement, nothing, unsafeCSS } from "lit"; -import { customElement, property } from "lit/decorators"; - -@customElement("ha-chip") -export class HaChip extends LitElement { - @property({ type: Boolean }) public hasIcon = false; - - @property({ type: Boolean }) public hasTrailingIcon = false; - - @property({ type: Boolean }) public noText = false; - - protected render() { - return html` -
- ${this.hasIcon - ? html`
- -
` - : nothing} -
- - - - - - ${this.hasTrailingIcon - ? html`
- -
` - : nothing} -
- `; - } - - static get styles(): CSSResultGroup { - return css` - ${unsafeCSS(chipStyles)} - .mdc-chip { - background-color: var( - --ha-chip-background-color, - rgba(var(--rgb-primary-text-color), 0.15) - ); - color: var(--ha-chip-text-color, var(--primary-text-color)); - } - - .mdc-chip.no-text { - padding: 0 10px; - } - - .mdc-chip:hover { - color: var(--ha-chip-text-color, var(--primary-text-color)); - } - - .mdc-chip__icon--leading, - .mdc-chip__icon--trailing { - --mdc-icon-size: 18px; - line-height: 14px; - color: var(--ha-chip-icon-color, var(--ha-chip-text-color)); - } - .mdc-chip.mdc-chip--selected .mdc-chip__checkmark, - .mdc-chip .mdc-chip__icon--leading:not(.mdc-chip__icon--leading-hidden) { - margin-right: -4px; - margin-inline-start: -4px; - margin-inline-end: 4px; - direction: var(--direction); - } - - span[role="gridcell"] { - line-height: 14px; - } - - :host { - outline: none; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-chip": HaChip; - } -} diff --git a/src/components/ha-control-slider.ts b/src/components/ha-control-slider.ts index d323bf0a5514..76183d45378e 100644 --- a/src/components/ha-control-slider.ts +++ b/src/components/ha-control-slider.ts @@ -4,13 +4,17 @@ import { CSSResultGroup, html, LitElement, + nothing, PropertyValues, TemplateResult, } from "lit"; -import { customElement, property, query } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import { fireEvent } from "../common/dom/fire_event"; +import { FrontendLocaleData } from "../data/translation"; +import { formatNumber } from "../common/number/format_number"; +import { blankBeforeUnit } from "../common/translations/blank_before_unit"; declare global { interface HASSDomEvents { @@ -29,13 +33,21 @@ const A11Y_KEY_CODES = new Set([ "End", ]); +type TooltipPosition = "top" | "bottom" | "left" | "right"; + +type TooltipMode = "never" | "always" | "interaction"; + +type SliderMode = "start" | "end" | "cursor"; + @customElement("ha-control-slider") export class HaControlSlider extends LitElement { + @property({ attribute: false }) public locale?: FrontendLocaleData; + @property({ type: Boolean, reflect: true }) public disabled = false; @property() - public mode?: "start" | "end" | "cursor" = "start"; + public mode?: SliderMode = "start"; @property({ type: Boolean, reflect: true }) public vertical = false; @@ -46,6 +58,15 @@ export class HaControlSlider extends LitElement { @property({ type: Boolean, attribute: "inverted" }) public inverted = false; + @property({ attribute: "tooltip-position" }) + public tooltipPosition?: TooltipPosition; + + @property({ attribute: "tooltip-unit" }) + public tooltipUnit?: string; + + @property({ attribute: "tooltip-mode" }) + public tooltipMode: TooltipMode = "interaction"; + @property({ type: Number }) public value?: number; @@ -58,11 +79,14 @@ export class HaControlSlider extends LitElement { @property({ type: Number }) public max = 100; - private _mc?: HammerManager; - - @property({ type: Boolean, reflect: true }) + @state() public pressed = false; + @state() + public tooltipVisible = false; + + private _mc?: HammerManager; + valueToPercentage(value: number) { const percentage = (this.boundedValue(value) - this.min) / (this.max - this.min); @@ -98,6 +122,7 @@ export class HaControlSlider extends LitElement { if (changedProps.has("value")) { const valuenow = this.steppedValue(this.value ?? 0); this.setAttribute("aria-valuenow", valuenow.toString()); + this.setAttribute("aria-valuetext", this._formatValue(valuenow)); } if (changedProps.has("min")) { this.setAttribute("aria-valuemin", this.min.toString()); @@ -143,11 +168,13 @@ export class HaControlSlider extends LitElement { this._mc.on("panstart", () => { if (this.disabled) return; this.pressed = true; + this._showTooltip(); savedValue = this.value; }); this._mc.on("pancancel", () => { if (this.disabled) return; this.pressed = false; + this._hideTooltip(); this.value = savedValue; }); this._mc.on("panmove", (e) => { @@ -160,6 +187,7 @@ export class HaControlSlider extends LitElement { this._mc.on("panend", (e) => { if (this.disabled) return; this.pressed = false; + this._hideTooltip(); const percentage = this._getPercentageFromEvent(e); this.value = this.steppedValue(this.percentageToValue(percentage)); fireEvent(this, "slider-moved", { value: undefined }); @@ -191,6 +219,21 @@ export class HaControlSlider extends LitElement { return Math.max(this.step, (this.max - this.min) / 10); } + _showTooltip() { + if (this._tooltipTimeout != null) window.clearTimeout(this._tooltipTimeout); + this.tooltipVisible = true; + } + + _hideTooltip(delay?: number) { + if (!delay) { + this.tooltipVisible = false; + return; + } + this._tooltipTimeout = window.setTimeout(() => { + this.tooltipVisible = false; + }, delay); + } + _handleKeyDown(e: KeyboardEvent) { if (!A11Y_KEY_CODES.has(e.code)) return; e.preventDefault(); @@ -220,12 +263,16 @@ export class HaControlSlider extends LitElement { this.value = this.max; break; } + this._showTooltip(); fireEvent(this, "slider-moved", { value: this.value }); } + private _tooltipTimeout?: number; + _handleKeyUp(e: KeyboardEvent) { if (!A11Y_KEY_CODES.has(e.code)) return; e.preventDefault(); + this._hideTooltip(500); fireEvent(this, "value-changed", { value: this.value }); } @@ -242,36 +289,76 @@ export class HaControlSlider extends LitElement { return Math.max(Math.min(1, (x - offset) / total), 0); }; + private _formatValue(value: number) { + const formattedValue = formatNumber(value, this.locale); + + const formattedUnit = this.tooltipUnit + ? `${blankBeforeUnit(this.tooltipUnit, this.locale)}${this.tooltipUnit}` + : ""; + + return `${formattedValue}${formattedUnit}`; + } + + private _renderTooltip() { + if (this.tooltipMode === "never") return nothing; + + const position = this.tooltipPosition ?? (this.vertical ? "left" : "top"); + + const visible = + this.tooltipMode === "always" || + (this.tooltipVisible && this.tooltipMode === "interaction"); + + const value = this.steppedValue(this.value ?? 0); + + return html` + + `; + } + protected render(): TemplateResult { return html`
-
- - ${this.mode === "cursor" - ? this.value != null - ? html` +
+
+ + ${this.mode === "cursor" + ? this.value != null + ? html` +
+ ` + : null + : html`
- ` - : null - : html` -
- `} + `} +
+ ${this._renderTooltip()}
`; } @@ -285,6 +372,7 @@ export class HaControlSlider extends LitElement { --control-slider-background-opacity: 0.2; --control-slider-thickness: 40px; --control-slider-border-radius: 10px; + --control-slider-tooltip-font-size: 14px; height: var(--control-slider-thickness); width: 100%; border-radius: var(--control-slider-border-radius); @@ -298,6 +386,89 @@ export class HaControlSlider extends LitElement { width: var(--control-slider-thickness); height: 100%; } + .container { + position: relative; + height: 100%; + width: 100%; + --handle-size: 4px; + --handle-margin: calc(var(--control-slider-thickness) / 8); + } + .tooltip { + pointer-events: none; + user-select: none; + position: absolute; + background-color: var(--clear-background-color); + color: var(--primary-text-color); + font-size: var(--control-slider-tooltip-font-size); + border-radius: 0.8em; + padding: 0.2em 0.4em; + opacity: 0; + white-space: nowrap; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + transition: + opacity 180ms ease-in-out, + left 180ms ease-in-out, + bottom 180ms ease-in-out; + --handle-spacing: calc(2 * var(--handle-margin) + var(--handle-size)); + --slider-tooltip-margin: -4px; + --slider-tooltip-range: 100%; + --slider-tooltip-offset: 0px; + --slider-tooltip-position: calc( + min( + max( + var(--value) * var(--slider-tooltip-range) + + var(--slider-tooltip-offset), + 0% + ), + 100% + ) + ); + } + .tooltip.start { + --slider-tooltip-offset: calc(-0.5 * (var(--handle-spacing))); + } + .tooltip.end { + --slider-tooltip-offset: calc(0.5 * (var(--handle-spacing))); + } + .tooltip.cursor { + --slider-tooltip-range: calc(100% - var(--handle-spacing)); + --slider-tooltip-offset: calc(0.5 * (var(--handle-spacing))); + } + .tooltip.show-handle { + --slider-tooltip-range: calc(100% - var(--handle-spacing)); + --slider-tooltip-offset: calc(0.5 * (var(--handle-spacing))); + } + .tooltip.visible { + opacity: 1; + } + .tooltip.top { + transform: translate3d(-50%, -100%, 0); + top: var(--slider-tooltip-margin); + left: 50%; + } + .tooltip.bottom { + transform: translate3d(-50%, 100%, 0); + bottom: var(--slider-tooltip-margin); + left: 50%; + } + .tooltip.left { + transform: translate3d(-100%, 50%, 0); + bottom: 50%; + left: var(--slider-tooltip-margin); + } + .tooltip.right { + transform: translate3d(100%, 50%, 0); + bottom: 50%; + right: var(--slider-tooltip-margin); + } + :host(:not([vertical])) .tooltip.top, + :host(:not([vertical])) .tooltip.bottom { + left: var(--slider-tooltip-position); + } + :host([vertical]) .tooltip.right, + :host([vertical]) .tooltip.left { + bottom: var(--slider-tooltip-position); + } .slider { position: relative; height: 100%; @@ -328,8 +499,6 @@ export class HaControlSlider extends LitElement { } .slider .slider-track-bar { --border-radius: var(--control-slider-border-radius); - --handle-size: 4px; - --handle-margin: calc(var(--control-slider-thickness) / 8); --slider-size: 100%; position: absolute; height: 100%; @@ -432,7 +601,6 @@ export class HaControlSlider extends LitElement { .slider .slider-track-cursor { --cursor-size: calc(var(--control-slider-thickness) / 4); - --handle-size: 4px; position: absolute; background-color: white; border-radius: var(--handle-size); @@ -462,9 +630,11 @@ export class HaControlSlider extends LitElement { height: var(--handle-size); width: 50%; } - - :host([pressed]) .slider-track-bar, - :host([pressed]) .slider-track-cursor { + .pressed .tooltip { + transition: opacity 180ms ease-in-out; + } + .pressed .slider-track-bar, + .pressed .slider-track-cursor { transition: none; } :host(:disabled) .slider { diff --git a/src/components/ha-label.ts b/src/components/ha-label.ts new file mode 100644 index 000000000000..ffb4d0612649 --- /dev/null +++ b/src/components/ha-label.ts @@ -0,0 +1,60 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement } from "lit/decorators"; + +@customElement("ha-label") +class HaLabel extends LitElement { + protected render(): TemplateResult { + return html` + + + + + `; + } + + static get styles(): CSSResultGroup { + return [ + css` + :host { + --ha-label-text-color: var(--primary-text-color); + --ha-label-icon-color: var(--primary-text-color); + --ha-label-background-color: rgba( + var(--rgb-primary-text-color), + 0.15 + ); + } + .label { + display: inline-flex; + flex-direction: row; + align-items: center; + font-size: 12px; + font-weight: 500; + line-height: 16px; + letter-spacing: 0.1px; + vertical-align: middle; + height: 32px; + padding: 0 16px; + border-radius: 18px; + background-color: var(--ha-label-background-color); + color: var(--ha-label-text-color); + --mdc-icon-size: 18px; + } + ::slotted([slot="icon"]) { + margin-right: 8px; + margin-left: -8px; + display: flex; + color: var(--ha-label-icon-color); + } + span { + display: inline-flex; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-label": HaLabel; + } +} diff --git a/src/components/ha-logo-svg.ts b/src/components/ha-logo-svg.ts index 532c002c6704..1f34735ac6e2 100644 --- a/src/components/ha-logo-svg.ts +++ b/src/components/ha-logo-svg.ts @@ -4,18 +4,14 @@ import { customElement } from "lit/decorators"; @customElement("ha-logo-svg") export class HaLogoSvg extends LitElement { protected render(): TemplateResult { - return html` + return html` `; } diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts index b443013ff820..a20559f91bfe 100644 --- a/src/components/ha-selector/ha-selector-select.ts +++ b/src/components/ha-selector/ha-selector-select.ts @@ -1,5 +1,5 @@ import "@material/mwc-list/mwc-list-item"; -import { mdiClose, mdiDrag } from "@mdi/js"; +import { mdiDrag } from "@mdi/js"; import { LitElement, PropertyValues, css, html, nothing } from "lit"; import { customElement, property, query } from "lit/decorators"; import { repeat } from "lit/directives/repeat"; @@ -12,9 +12,9 @@ import type { SelectOption, SelectSelector } from "../../data/selector"; import { sortableStyles } from "../../resources/ha-sortable-style"; import { SortableInstance } from "../../resources/sortable"; import type { HomeAssistant } from "../../types"; +import "../chips/ha-chip-set"; +import "../chips/ha-input-chip"; import "../ha-checkbox"; -import "../ha-chip"; -import "../ha-chip-set"; import "../ha-combo-box"; import type { HaComboBox } from "../ha-combo-box"; import "../ha-formfield"; @@ -65,7 +65,7 @@ export class HaSelectSelector extends LitElement { { animation: 150, fallbackClass: "sortable-fallback", - draggable: "ha-chip", + draggable: "ha-input-chip", onChoose: (evt: SortableEvent) => { (evt.item as any).placeholder = document.createComment("sort-placeholder"); @@ -199,30 +199,31 @@ export class HaSelectSelector extends LitElement { ${repeat( value, (item) => item, - (item, idx) => html` - - ${this.selector.select?.reorder - ? html` - - ` - : nothing} - ${options.find((option) => option.value === item) - ?.label || item} - { + const label = + options.find((option) => option.value === item)?.label || + item; + return html` + - - ` + @remove=${this._removeItem} + .label=${label} + selected + > + ${this.selector.select?.reorder + ? html` + + ` + : nothing} + ${options.find((option) => option.value === item) + ?.label || item} + + `; + } )} ` @@ -354,6 +355,7 @@ export class HaSelectSelector extends LitElement { } private async _removeItem(ev) { + ev.stopPropagation(); const value: string[] = [...ensureArray(this.value!)]; value.splice(ev.target.idx, 1); @@ -431,6 +433,9 @@ export class HaSelectSelector extends LitElement { mwc-list-item[disabled] { --mdc-theme-text-primary-on-background: var(--disabled-text-color); } + ha-chip-set { + padding: 8px 0; + } `, ]; } diff --git a/src/components/media-player/ha-media-player-browse.ts b/src/components/media-player/ha-media-player-browse.ts index e5c895e74268..525befc13d90 100644 --- a/src/components/media-player/ha-media-player-browse.ts +++ b/src/components/media-player/ha-media-player-browse.ts @@ -899,6 +899,7 @@ export class HaMediaPlayerBrowse extends LitElement { overflow-y: auto; box-sizing: border-box; height: 100%; + position: relative; } /* HEADER */ diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index 6e18baeef085..3e6656d5d8fe 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -1090,6 +1090,12 @@ const tryDescribeCondition = ( }`; } + if (condition.condition === "template") { + return hass.localize( + `${conditionsTranslationBaseKey}.template.description.full` + ); + } + if (condition.condition === "trigger" && condition.id != null) { return hass.localize( `${conditionsTranslationBaseKey}.trigger.description.full`, diff --git a/src/data/calendar.ts b/src/data/calendar.ts index 178ef3544ece..85efa30686af 100644 --- a/src/data/calendar.ts +++ b/src/data/calendar.ts @@ -139,7 +139,8 @@ export const getCalendars = (hass: HomeAssistant): Calendar[] => .filter( (eid) => computeDomain(eid) === "calendar" && - !isUnavailableState(hass.states[eid].state) + !isUnavailableState(hass.states[eid].state) && + hass.entities[eid]?.hidden !== true ) .sort() .map((eid, idx) => ({ diff --git a/src/data/entity_attributes.ts b/src/data/entity_attributes.ts index db9c63e563a6..00e2e6d3dcfb 100644 --- a/src/data/entity_attributes.ts +++ b/src/data/entity_attributes.ts @@ -34,7 +34,7 @@ export const TEMPERATURE_ATTRIBUTES = new Set([ "max_temp", ]); -export const DOMAIN_ATTRIBUTES_UNITS: Record> = { +export const DOMAIN_ATTRIBUTES_UNITS = { climate: { humidity: "%", current_humidity: "%", @@ -74,4 +74,4 @@ export const DOMAIN_ATTRIBUTES_UNITS: Record> = { sensor: { battery_level: "%", }, -}; +} as const satisfies Record>; diff --git a/src/data/translation.ts b/src/data/translation.ts index bc8165578a99..e4824b0e636f 100644 --- a/src/data/translation.ts +++ b/src/data/translation.ts @@ -61,6 +61,7 @@ export type TranslationCategory = | "state" | "entity" | "entity_component" + | "exceptions" | "config" | "config_panel" | "options" diff --git a/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts b/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts index f0b1954f5581..c03f63f57e97 100644 --- a/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts +++ b/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts @@ -415,6 +415,7 @@ export class HaMoreInfoClimateTemperature extends LitElement { line-height: 64px; letter-spacing: -0.25px; margin: 0; + direction: ltr; } .temperature span { display: inline-flex; diff --git a/src/dialogs/more-info/components/cover/ha-more-info-cover-position.ts b/src/dialogs/more-info/components/cover/ha-more-info-cover-position.ts index e1dfeb91c541..ab13306eadd7 100644 --- a/src/dialogs/more-info/components/cover/ha-more-info-cover-position.ts +++ b/src/dialogs/more-info/components/cover/ha-more-info-cover-position.ts @@ -6,6 +6,7 @@ import { stateColorCss } from "../../../../common/entity/state_color"; import "../../../../components/ha-control-slider"; import { CoverEntity } from "../../../../data/cover"; import { UNAVAILABLE } from "../../../../data/entity"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes"; import { HomeAssistant } from "../../../../types"; @customElement("ha-more-info-cover-position") @@ -60,6 +61,8 @@ export class HaMoreInfoCoverPosition extends LitElement { "--control-slider-background": color, })} .disabled=${this.stateObj.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_position} + .locale=${this.hass.locale} > `; @@ -76,6 +79,7 @@ export class HaMoreInfoCoverPosition extends LitElement { --control-slider-color: var(--primary-color); --control-slider-background: var(--disabled-color); --control-slider-background-opacity: 0.2; + --control-slider-tooltip-font-size: 20px; } `; } diff --git a/src/dialogs/more-info/components/cover/ha-more-info-cover-tilt-position.ts b/src/dialogs/more-info/components/cover/ha-more-info-cover-tilt-position.ts index cf23456e86bd..d5c2113743ba 100644 --- a/src/dialogs/more-info/components/cover/ha-more-info-cover-tilt-position.ts +++ b/src/dialogs/more-info/components/cover/ha-more-info-cover-tilt-position.ts @@ -13,6 +13,7 @@ import { stateColorCss } from "../../../../common/entity/state_color"; import "../../../../components/ha-control-slider"; import { CoverEntity } from "../../../../data/cover"; import { UNAVAILABLE } from "../../../../data/entity"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes"; import { HomeAssistant } from "../../../../types"; export function generateTiltSliderTrackBackgroundGradient() { @@ -96,6 +97,8 @@ export class HaMoreInfoCoverTiltPosition extends LitElement { "--control-slider-background": color, })} .disabled=${this.stateObj.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_tilt_position} + .locale=${this.hass.locale} >
@@ -113,6 +116,7 @@ export class HaMoreInfoCoverTiltPosition extends LitElement { --control-slider-color: var(--primary-color); --control-slider-background: var(--disabled-color); --control-slider-background-opacity: 0.2; + --control-slider-tooltip-font-size: 20px; } .gradient { background: -webkit-linear-gradient(top, ${GRADIENT}); diff --git a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts index d1a641d6c5fc..7146131040db 100644 --- a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts +++ b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts @@ -8,6 +8,7 @@ import "../../../../components/ha-control-select"; import type { ControlSelectOption } from "../../../../components/ha-control-select"; import "../../../../components/ha-control-slider"; import { UNAVAILABLE } from "../../../../data/entity"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes"; import { computeFanSpeedCount, computeFanSpeedIcon, @@ -130,6 +131,8 @@ export class HaMoreInfoFanSpeed extends LitElement { "--control-slider-background": color, })} .disabled=${this.stateObj.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.fan.percentage} + .locale=${this.hass.locale} > `; @@ -146,6 +149,7 @@ export class HaMoreInfoFanSpeed extends LitElement { --control-slider-color: var(--primary-color); --control-slider-background: var(--disabled-color); --control-slider-background-opacity: 0.2; + --control-slider-tooltip-font-size: 20px; } ha-control-select { height: 45vh; diff --git a/src/dialogs/more-info/components/lights/ha-more-info-light-brightness.ts b/src/dialogs/more-info/components/lights/ha-more-info-light-brightness.ts index 8798250214aa..587df1047b38 100644 --- a/src/dialogs/more-info/components/lights/ha-more-info-light-brightness.ts +++ b/src/dialogs/more-info/components/lights/ha-more-info-light-brightness.ts @@ -77,6 +77,8 @@ export class HaMoreInfoLightBrightness extends LitElement { "--control-slider-background": color, })} .disabled=${this.stateObj.state === UNAVAILABLE} + .tooltipUnit=${"%"} + .locale=${this.hass.locale} > `; @@ -93,6 +95,7 @@ export class HaMoreInfoLightBrightness extends LitElement { --control-slider-color: var(--primary-color); --control-slider-background: var(--disabled-color); --control-slider-background-opacity: 0.2; + --control-slider-tooltip-font-size: 20px; } `; } diff --git a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts index 0331d24b3133..1f645e32c635 100644 --- a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts +++ b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts @@ -26,6 +26,7 @@ import { LightEntity, } from "../../../../data/light"; import { HomeAssistant } from "../../../../types"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../../data/entity_attributes"; declare global { interface HASSDomEvents { @@ -93,6 +94,8 @@ class LightColorTempPicker extends LitElement { "--gradient": gradient, })} .disabled=${this.stateObj.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.light.color_temp_kelvin} + .locale=${this.hass.locale} > `; @@ -193,6 +196,7 @@ class LightColorTempPicker extends LitElement { top, var(--gradient) ); + --control-slider-tooltip-font-size: 20px; --control-slider-background-opacity: 1; } `, diff --git a/src/dialogs/more-info/controls/more-info-climate.ts b/src/dialogs/more-info/controls/more-info-climate.ts index c1e4cb0999ef..173fe7905a7f 100644 --- a/src/dialogs/more-info/controls/more-info-climate.ts +++ b/src/dialogs/more-info/controls/more-info-climate.ts @@ -434,6 +434,7 @@ class MoreInfoClimate extends LitElement { font-size: 22px; font-weight: 500; line-height: 28px; + direction: ltr; } ha-select { width: 100%; diff --git a/src/dialogs/more-info/controls/more-info-cover.ts b/src/dialogs/more-info/controls/more-info-cover.ts index 02b2f2ec5a66..3c2881017e48 100644 --- a/src/dialogs/more-info/controls/more-info-cover.ts +++ b/src/dialogs/more-info/controls/more-info-cover.ts @@ -33,36 +33,12 @@ class MoreInfoCover extends LitElement { @property({ attribute: false }) public stateObj?: CoverEntity; - @state() private _livePosition?: number; - - @state() private _liveTilt?: number; - @state() private _mode?: Mode; private _setMode(ev) { this._mode = ev.currentTarget.mode; } - private _positionSliderMoved(ev) { - const value = (ev.detail as any).value; - if (isNaN(value)) return; - this._livePosition = value; - } - - private _positionValueChanged() { - this._livePosition = undefined; - } - - private _tiltSliderMoved(ev) { - const value = (ev.detail as any).value; - if (isNaN(value)) return; - this._liveTilt = value; - } - - private _tiltValueChanged() { - this._liveTilt = undefined; - } - protected willUpdate(changedProps: PropertyValues): void { super.willUpdate(changedProps); if (changedProps.has("stateObj") && this.stateObj) { @@ -77,20 +53,11 @@ class MoreInfoCover extends LitElement { } private get _stateOverride() { - const liveValue = this._livePosition ?? this._liveTilt; - - const forcedState = - liveValue != null ? (liveValue ? "open" : "closed") : undefined; - - const stateDisplay = this.hass.formatEntityState( - this.stateObj!, - forcedState - ); + const stateDisplay = this.hass.formatEntityState(this.stateObj!); const positionStateDisplay = computeCoverPositionStateDisplay( this.stateObj!, - this.hass, - liveValue + this.hass ); if (positionStateDisplay) { @@ -147,8 +114,6 @@ class MoreInfoCover extends LitElement { ` : nothing} @@ -157,8 +122,6 @@ class MoreInfoCover extends LitElement { ` : nothing} diff --git a/src/dialogs/more-info/controls/more-info-fan.ts b/src/dialogs/more-info/controls/more-info-fan.ts index 8c8f566cdcdb..f2028f577ca8 100644 --- a/src/dialogs/more-info/controls/more-info-fan.ts +++ b/src/dialogs/more-info/controls/more-info-fan.ts @@ -40,18 +40,6 @@ class MoreInfoFan extends LitElement { @state() public _presetMode?: string; - @state() private _liveSpeed?: number; - - private _speedSliderMoved(ev) { - const value = (ev.detail as any).value; - if (isNaN(value)) return; - this._liveSpeed = value; - } - - private _speedValueChanged() { - this._liveSpeed = undefined; - } - private _toggle = () => { const service = this.stateObj?.state === "on" ? "turn_off" : "turn_on"; forwardHaptic("light"); @@ -104,23 +92,14 @@ class MoreInfoFan extends LitElement { } private get _stateOverride() { - const liveValue = this._liveSpeed; - - const forcedState = - liveValue != null ? (liveValue ? "on" : "off") : undefined; - - const stateDisplay = this.hass.formatEntityState( - this.stateObj!, - forcedState - ); + const stateDisplay = this.hass.formatEntityState(this.stateObj!); const positionStateDisplay = computeFanSpeedStateDisplay( this.stateObj!, - this.hass, - liveValue + this.hass ); - if (positionStateDisplay && (stateActive(this.stateObj!) || liveValue)) { + if (positionStateDisplay && stateActive(this.stateObj!)) { return positionStateDisplay; } return stateDisplay; @@ -165,8 +144,6 @@ class MoreInfoFan extends LitElement { ` diff --git a/src/dialogs/more-info/controls/more-info-humidifier.ts b/src/dialogs/more-info/controls/more-info-humidifier.ts index d919753c86ba..25b8e60e0bcc 100644 --- a/src/dialogs/more-info/controls/more-info-humidifier.ts +++ b/src/dialogs/more-info/controls/more-info-humidifier.ts @@ -250,6 +250,7 @@ class MoreInfoHumidifier extends LitElement { font-size: 22px; font-weight: 500; line-height: 28px; + direction: ltr; } `, ]; diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts index 5d3800d651f1..63e07c722251 100644 --- a/src/dialogs/more-info/controls/more-info-light.ts +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -60,29 +60,10 @@ class MoreInfoLight extends LitElement { @state() private _effect?: string; - @state() private _selectedBrightness?: number; - - @state() private _colorTempPreview?: number; - @state() private _mainControl: MainControl = "brightness"; - private _brightnessChanged(ev) { - const value = (ev.detail as any).value; - if (isNaN(value)) return; - this._selectedBrightness = (value * 255) / 100; - } - - private _tempColorHovered(ev: CustomEvent) { - if (ev.detail && "color_temp_kelvin" in ev.detail) { - this._colorTempPreview = ev.detail.color_temp_kelvin; - } else { - this._colorTempPreview = undefined; - } - } - protected updated(changedProps: PropertyValues): void { if (changedProps.has("stateObj")) { - this._selectedBrightness = this.stateObj?.attributes.brightness; this._effect = this.stateObj?.attributes.effect; } } @@ -98,19 +79,8 @@ class MoreInfoLight extends LitElement { } private get _stateOverride() { - if (this._colorTempPreview) { - return this.hass.formatEntityAttributeValue( - this.stateObj!, - "color_temp_kelvin", - this._colorTempPreview - ); - } - if (this._selectedBrightness) { - return this.hass.formatEntityAttributeValue( - this.stateObj!, - "brightness", - this._selectedBrightness - ); + if (this.stateObj?.attributes.brightness) { + return this.hass.formatEntityAttributeValue(this.stateObj!, "brightness"); } return undefined; } @@ -168,7 +138,6 @@ class MoreInfoLight extends LitElement { ` @@ -187,7 +156,6 @@ class MoreInfoLight extends LitElement { ` diff --git a/src/dialogs/more-info/controls/more-info-water_heater.ts b/src/dialogs/more-info/controls/more-info-water_heater.ts index 99269b6e2c4b..3e0a77fa5cb5 100644 --- a/src/dialogs/more-info/controls/more-info-water_heater.ts +++ b/src/dialogs/more-info/controls/more-info-water_heater.ts @@ -243,6 +243,7 @@ class MoreInfoWaterHeater extends LitElement { font-size: 22px; font-weight: 500; line-height: 28px; + direction: ltr; } `, ]; diff --git a/src/dialogs/more-info/controls/more-info-weather.ts b/src/dialogs/more-info/controls/more-info-weather.ts index 5da649ae4f0e..7e1bd84c2b3e 100644 --- a/src/dialogs/more-info/controls/more-info-weather.ts +++ b/src/dialogs/more-info/controls/more-info-weather.ts @@ -356,6 +356,7 @@ class MoreInfoWeather extends LitElement { .templow { min-width: 48px; text-align: right; + direction: ltr; } .templow { diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts index 07d823858d1c..27c8336de9e6 100644 --- a/src/dialogs/quick-bar/ha-quick-bar.ts +++ b/src/dialogs/quick-bar/ha-quick-bar.ts @@ -27,7 +27,7 @@ import { fuzzyFilterSort, } from "../../common/string/filter/sequence-matching"; import { debounce } from "../../common/util/debounce"; -import "../../components/ha-chip"; +import "../../components/ha-label"; import "../../components/ha-circular-progress"; import "../../components/ha-icon-button"; import "../../components/ha-list-item"; @@ -326,19 +326,17 @@ export class QuickBar extends LitElement { hasMeta > - ${item.iconPath - ? html`` - : ""} - ${item.categoryText} + ? html` + + ` + : nothing} + ${item.categoryText} + ${item.primaryText} @@ -766,6 +764,7 @@ export class QuickBar extends LitElement { haStyleDialog, css` mwc-list { + position: relative; --mdc-list-vertical-padding: 0; } .heading { @@ -815,20 +814,20 @@ export class QuickBar extends LitElement { } .command-category { - --ha-chip-icon-color: #585858; - --ha-chip-text-color: #212121; + --ha-label-icon-color: #585858; + --ha-label-text-color: #212121; } .command-category.reload { - --ha-chip-background-color: #cddc39; + --ha-label-background-color: #cddc39; } .command-category.navigation { - --ha-chip-background-color: var(--light-primary-color); + --ha-label-background-color: var(--light-primary-color); } .command-category.server_control { - --ha-chip-background-color: var(--warning-color); + --ha-label-background-color: var(--warning-color); } span.command-text { diff --git a/src/html/authorize.html.template b/src/html/authorize.html.template index b5fd0259f474..2770e1a32a31 100644 --- a/src/html/authorize.html.template +++ b/src/html/authorize.html.template @@ -15,9 +15,6 @@ justify-content: center; height: 73px; } - .logomark { - fill: #F2F4F9; - } .wordmark { fill: #1D2126; } @@ -35,22 +32,10 @@
- - - - - - - - - - - - - - - - + + + +
diff --git a/src/html/index.html.template b/src/html/index.html.template index 183bc7e5614e..efcea2af68be 100644 --- a/src/html/index.html.template +++ b/src/html/index.html.template @@ -50,19 +50,9 @@
- - - + + +
diff --git a/src/panels/calendar/dialog-calendar-event-editor.ts b/src/panels/calendar/dialog-calendar-event-editor.ts index a7f885d11970..2cd0bb0f5d36 100644 --- a/src/panels/calendar/dialog-calendar-event-editor.ts +++ b/src/panels/calendar/dialog-calendar-event-editor.ts @@ -584,6 +584,10 @@ class DialogCalendarEventEditor extends LitElement { return [ haStyleDialog, css` + ha-dialog { + --mdc-dialog-min-width: min(600px, 95vw); + --mdc-dialog-max-width: min(600px, 95vw); + } state-info { line-height: 40px; } diff --git a/src/panels/calendar/ha-recurrence-rule-editor.ts b/src/panels/calendar/ha-recurrence-rule-editor.ts index 987b58ab2eb5..d7f19d0b671b 100644 --- a/src/panels/calendar/ha-recurrence-rule-editor.ts +++ b/src/panels/calendar/ha-recurrence-rule-editor.ts @@ -1,14 +1,14 @@ import type { SelectedDetail } from "@material/mwc-list"; import { formatInTimeZone, toDate } from "date-fns-tz"; -import { css, html, LitElement, PropertyValues, nothing } from "lit"; +import { LitElement, PropertyValues, css, html, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { classMap } from "lit/directives/class-map"; import type { Options, WeekdayStr } from "rrule"; import { ByWeekday, RRule, Weekday } from "rrule"; import { firstWeekdayIndex } from "../../common/datetime/first_weekday"; import { stopPropagation } from "../../common/dom/stop_propagation"; import { LocalizeKeys } from "../../common/translations/localize"; -import "../../components/ha-chip"; +import "../../components/chips/ha-chip-set"; +import "../../components/chips/ha-filter-chip"; import "../../components/ha-date-input"; import "../../components/ha-list-item"; import "../../components/ha-select"; @@ -16,17 +16,17 @@ import type { HaSelect } from "../../components/ha-select"; import "../../components/ha-textfield"; import { HomeAssistant } from "../../types"; import { + DEFAULT_COUNT, + MonthlyRepeatItem, + RepeatEnd, + RepeatFrequency, convertFrequency, convertRepeatFrequency, - DEFAULT_COUNT, getMonthdayRepeatFromRule, getMonthlyRepeatItems, getMonthlyRepeatWeekdayFromRule, getWeekday, getWeekdays, - MonthlyRepeatItem, - RepeatEnd, - RepeatFrequency, ruleByWeekDay, untilValue, } from "./recurrence"; @@ -240,22 +240,24 @@ export class RecurrenceRuleEditor extends LitElement { renderWeekly() { return html` ${this.renderInterval()} -
+ ${this._allWeekdays!.map( (item) => html` - ${this.hass.localize( + .label=${this.hass.localize( `ui.components.calendar.event.repeat.weekly.weekday.${ item.toLowerCase() as Lowercase }` - )} + ` )} -
+ `; } @@ -379,10 +381,10 @@ export class RecurrenceRuleEditor extends LitElement { private _onWeekdayToggle(e: MouseEvent) { const target = e.currentTarget as any; const value = target.value as WeekdayStr; - if (!target.classList.contains("active")) { - this._weekday.add(value); - } else { + if (this._weekday.has(value)) { this._weekday.delete(value); + } else { + this._weekday.add(value); } this.requestUpdate("_weekday"); } @@ -504,8 +506,6 @@ export class RecurrenceRuleEditor extends LitElement { margin-bottom: 16px; } .weekdays { - display: flex; - justify-content: space-between; margin-bottom: 16px; } ha-textfield:last-child, @@ -513,11 +513,6 @@ export class RecurrenceRuleEditor extends LitElement { .weekdays:last-child { margin-bottom: 0; } - - .active { - --ha-chip-background-color: var(--primary-color); - --ha-chip-text-color: var(--text-primary-color); - } `; } diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index c608b2008655..f68d0b78774c 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -27,7 +27,7 @@ import type { RowClickedEvent, } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-button-related-filter-menu"; -import "../../../components/ha-chip"; +import "../../../components/ha-label"; import "../../../components/ha-fab"; import "../../../components/ha-icon-button"; import "../../../components/ha-icon-overflow-menu"; @@ -202,11 +202,11 @@ class HaAutomationPicker extends LitElement { template: (automation) => automation.disabled ? html` - + ${this.hass.localize( "ui.panel.config.automation.picker.disabled" )} - + ` : "", }; diff --git a/src/panels/config/dashboard/ha-config-dashboard.ts b/src/panels/config/dashboard/ha-config-dashboard.ts index bbe63dcbbb95..9cd8a390ec2d 100644 --- a/src/panels/config/dashboard/ha-config-dashboard.ts +++ b/src/panels/config/dashboard/ha-config-dashboard.ts @@ -8,16 +8,17 @@ import { } from "@mdi/js"; import { HassEntities, UnsubscribeFunc } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, TemplateResult, + css, + html, } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; +import "../../../components/chips/ha-assist-chip"; import "../../../components/ha-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; @@ -34,9 +35,9 @@ import { subscribeRepairsIssueRegistry, } from "../../../data/repairs"; import { + UpdateEntity, checkForEntityUpdates, filterUpdateEntitiesWithInstall, - UpdateEntity, } from "../../../data/update"; import { showQuickBar } from "../../../dialogs/quick-bar/show-dialog-quick-bar"; import { showRestartDialog } from "../../../dialogs/restart/show-dialog-restart"; @@ -231,15 +232,17 @@ class HaConfigDashboard extends SubscribeMixin(LitElement) { > ${totalRepairIssues > repairsIssues.length ? html` - - ${this.hass.localize( + + > + ` : ""} ` @@ -257,15 +260,17 @@ class HaConfigDashboard extends SubscribeMixin(LitElement) { > ${totalUpdates > canInstallUpdates.length ? html` - - ${this.hass.localize( + + > + ` : ""} ` @@ -349,13 +354,8 @@ class HaConfigDashboard extends SubscribeMixin(LitElement) { text-decoration: none; color: var(--primary-text-color); } - a.button { - display: inline-block; - color: var(--primary-text-color); - padding: 6px 16px; + ha-assist-chip { margin: 8px 16px 16px 16px; - border-radius: 32px; - border: 1px solid var(--divider-color); } .title { font-size: 16px; diff --git a/src/panels/config/devices/device-detail/ha-device-automation-card.ts b/src/panels/config/devices/device-detail/ha-device-automation-card.ts index 7ea0ec102685..26ff027d77b3 100644 --- a/src/panels/config/devices/device-detail/ha-device-automation-card.ts +++ b/src/panels/config/devices/device-detail/ha-device-automation-card.ts @@ -1,8 +1,8 @@ import { css, html, LitElement, nothing } from "lit"; import { property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/ha-chip"; -import "../../../../components/ha-chip-set"; +import "../../../../components/chips/ha-assist-chip"; +import "../../../../components/chips/ha-chip-set"; import { showAutomationEditor } from "../../../../data/automation"; import { DeviceAction, @@ -77,17 +77,18 @@ export abstract class HaDeviceAutomationCard< ${automations.map( (automation, idx) => html` - - ${this._localizeDeviceAutomation( + .label=${this._localizeDeviceAutomation( this.hass, this.entityReg!, automation )} - + > + ` )} @@ -128,7 +129,10 @@ export abstract class HaDeviceAutomationCard< color: var(--primary-text-color); } .secondary { - --ha-chip-background-color: rgba(var(--rgb-primary-text-color), 0.07); + --ha-assist-chip-filled-container-color: rgba( + var(--rgb-primary-text-color), + 0.07 + ); } button.link { color: var(--primary-color); diff --git a/src/panels/config/integrations/dialog-add-integration.ts b/src/panels/config/integrations/dialog-add-integration.ts index 31a56fb4b51a..62e86a587410 100644 --- a/src/panels/config/integrations/dialog-add-integration.ts +++ b/src/panels/config/integrations/dialog-add-integration.ts @@ -678,6 +678,9 @@ class AddIntegrationDialog extends LitElement { justify-content: center; margin: 24px 0; } + mwc-list { + position: relative; + } lit-virtualizer { contain: size layout !important; } diff --git a/src/panels/config/users/dialog-user-detail.ts b/src/panels/config/users/dialog-user-detail.ts index def8e07fbd50..a448b6b4f665 100644 --- a/src/panels/config/users/dialog-user-detail.ts +++ b/src/panels/config/users/dialog-user-detail.ts @@ -1,14 +1,13 @@ -import "@material/mwc-button"; import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; +import "@material/mwc-button"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; -import "../../../components/ha-chip"; -import "../../../components/ha-chip-set"; import { createCloseHeading } from "../../../components/ha-dialog"; import "../../../components/ha-formfield"; import "../../../components/ha-help-tooltip"; +import "../../../components/ha-label"; import "../../../components/ha-svg-icon"; import "../../../components/ha-switch"; import "../../../components/ha-textfield"; @@ -76,16 +75,16 @@ class DialogUserDetail extends LitElement { ${badges.length === 0 ? "" : html` - +
${badges.map( ([icon, label]) => html` - + ${label} - + ` )} - +
`}
* { + margin: 4px 4px 4px 0; + } .state { background-color: rgba(var(--rgb-primary-text-color), 0.15); border-radius: 16px; diff --git a/src/panels/config/voice-assistants/dialog-expose-entity.ts b/src/panels/config/voice-assistants/dialog-expose-entity.ts index 97f94d90aee6..9f42f42d58a0 100644 --- a/src/panels/config/voice-assistants/dialog-expose-entity.ts +++ b/src/panels/config/voice-assistants/dialog-expose-entity.ts @@ -174,6 +174,9 @@ class DialogExposeEntity extends LitElement { --mdc-dialog-min-width: 500px; --mdc-dialog-max-width: 600px; } + mwc-list { + position: relative; + } lit-virtualizer { height: 500px; } diff --git a/src/panels/developer-tools/state/developer-tools-state.ts b/src/panels/developer-tools/state/developer-tools-state.ts index a47960a44288..d46074b7afc5 100644 --- a/src/panels/developer-tools/state/developer-tools-state.ts +++ b/src/panels/developer-tools/state/developer-tools-state.ts @@ -1,38 +1,39 @@ -import { addHours } from "date-fns/esm"; -import "@material/mwc-button"; import { mdiClipboardTextMultipleOutline, mdiInformationOutline, mdiRefresh, } from "@mdi/js"; -import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { addHours } from "date-fns/esm"; import { HassEntities, HassEntity, HassEntityAttributeBase, } from "home-assistant-js-websocket"; -import memoizeOne from "memoize-one"; import { dump } from "js-yaml"; +import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; +import { customElement, property, query, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; import { formatDateTimeWithSeconds } from "../../../common/datetime/format_date_time"; -import { computeRTL } from "../../../common/util/compute_rtl"; +import { storage } from "../../../common/decorators/storage"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { toggleAttribute } from "../../../common/dom/toggle_attribute"; import { escapeRegExp } from "../../../common/string/escape_regexp"; +import { computeRTL } from "../../../common/util/compute_rtl"; import { copyToClipboard } from "../../../common/util/copy-clipboard"; import "../../../components/entity/ha-entity-picker"; -import "../../../components/ha-yaml-editor"; +import "../../../components/ha-alert"; +import "../../../components/ha-button"; +import "../../../components/ha-checkbox"; +import "../../../components/ha-expansion-panel"; import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; -import "../../../components/ha-checkbox"; import "../../../components/ha-tip"; -import "../../../components/ha-alert"; +import "../../../components/ha-yaml-editor"; +import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import "../../../components/search-input"; -import "../../../components/ha-expansion-panel"; import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; -import { fireEvent } from "../../../common/dom/fire_event"; -import { toggleAttribute } from "../../../common/dom/toggle_attribute"; -import { storage } from "../../../common/decorators/storage"; @customElement("developer-tools-state") class HaPanelDevState extends LitElement { @@ -70,6 +71,8 @@ class HaPanelDevState extends LitElement { @property({ type: Boolean, reflect: true }) public rtl = false; + @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; + private _filteredEntities = memoizeOne( ( entityFilter: string, @@ -151,23 +154,22 @@ class HaPanelDevState extends LitElement { )}

- ${this.hass.localize( "ui.panel.developer-tools.tabs.states.set_state" - )} @@ -343,16 +345,26 @@ class HaPanelDevState extends LitElement { this._entity = entityState; this._state = entityState.state; this._stateAttributes = entityState.attributes; + this._updateEditor(); this._expanded = true; ev.preventDefault(); } + private _updateEditor() { + this._yamlEditor?.setValue(this._stateAttributes); + } + private _entityIdChanged(ev: CustomEvent) { this._entityId = ev.detail.value; + this._updateEntity(); + } + + private _updateEntity() { if (!this._entityId) { this._entity = undefined; this._state = ""; this._stateAttributes = {}; + this._updateEditor(); return; } const entityState = this.hass.states[this._entityId]; @@ -362,6 +374,7 @@ class HaPanelDevState extends LitElement { this._entity = entityState; this._state = entityState.state; this._stateAttributes = entityState.attributes; + this._updateEditor(); this._expanded = true; } @@ -415,6 +428,7 @@ class HaPanelDevState extends LitElement { }); return; } + this._updateEditor(); try { await this.hass.callApi("POST", "states/" + this._entityId, { state: this._state, diff --git a/src/panels/logbook/ha-panel-logbook.ts b/src/panels/logbook/ha-panel-logbook.ts index 9a93813793fd..d192b53edb65 100644 --- a/src/panels/logbook/ha-panel-logbook.ts +++ b/src/panels/logbook/ha-panel-logbook.ts @@ -240,7 +240,6 @@ export class HaPanelLogbook extends LitElement { margin-inline-start: initial; max-width: 100%; direction: var(--direction); - margin-bottom: -5px; } :host([narrow]) ha-date-range-picker { diff --git a/src/panels/lovelace/cards/hui-alarm-panel-card.ts b/src/panels/lovelace/cards/hui-alarm-panel-card.ts index 34585865c6bb..310203837d02 100644 --- a/src/panels/lovelace/cards/hui-alarm-panel-card.ts +++ b/src/panels/lovelace/cards/hui-alarm-panel-card.ts @@ -1,28 +1,29 @@ +import { HassEntity } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; -import { HassEntity } from "home-assistant-js-websocket"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; import { alarmPanelIcon } from "../../../common/entity/alarm_panel_icon"; import { stateColorCss } from "../../../common/entity/state_color"; +import { supportsFeature } from "../../../common/entity/supports-feature"; +import "../../../components/chips/ha-assist-chip"; import "../../../components/ha-card"; -import "../../../components/ha-chip"; import "../../../components/ha-textfield"; import type { HaTextField } from "../../../components/ha-textfield"; import { - callAlarmAction, - FORMAT_NUMBER, ALARM_MODES, AlarmMode, + FORMAT_NUMBER, + callAlarmAction, } from "../../../data/alarm_control_panel"; import { UNAVAILABLE } from "../../../data/entity"; import type { HomeAssistant } from "../../../types"; @@ -30,7 +31,6 @@ import { findEntities } from "../common/find-entities"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import type { LovelaceCard } from "../types"; import { AlarmPanelCardConfig, AlarmPanelCardConfigState } from "./types"; -import { supportsFeature } from "../../../common/entity/supports-feature"; const BUTTONS = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "clear"]; @@ -190,18 +190,18 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { ${this._config.name || stateObj.attributes.friendly_name || stateLabel} - - ${stateLabel} - +
${(stateObj.state === "disarmed" @@ -312,10 +312,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard { --alarm-state-color: var(--state-inactive-color); } - ha-chip { - --ha-chip-background-color: var(--alarm-state-color); + ha-assist-chip { + --ha-assist-chip-filled-container-color: var(--alarm-state-color); --primary-text-color: var(--text-primary-color); - line-height: initial; } .card-header { diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index c775a30984d0..8680b42cf006 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -350,7 +350,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return html` - ${this._shouldRenderRipple ? html`` : nothing}
+ > + ${this._shouldRenderRipple + ? html`` + : nothing} +
= numericState) + (condition.below == null || condition.below > numericState) ); } diff --git a/src/panels/lovelace/components/hui-buttons-base.ts b/src/panels/lovelace/components/hui-buttons-base.ts index 0e0e0c3ad0c9..ff04a931a42e 100644 --- a/src/panels/lovelace/components/hui-buttons-base.ts +++ b/src/panels/lovelace/components/hui-buttons-base.ts @@ -9,7 +9,8 @@ import { computeTooltip } from "../common/compute-tooltip"; import { actionHandler } from "../common/directives/action-handler-directive"; import { handleAction } from "../common/handle-action"; import { hasAction } from "../common/has-action"; -import "../../../components/ha-chip"; +import "../../../components/chips/ha-assist-chip"; +import "../../../components/chips/ha-chip-set"; import { haStyleScrollbar } from "../../../resources/styles"; @customElement("hui-buttons-base") @@ -20,7 +21,7 @@ export class HuiButtonsBase extends LitElement { protected render(): TemplateResult { return html` -
+ ${(this.configEntities || []).map((entityConf) => { const stateObj = this.hass.states[entityConf.entity]; @@ -31,7 +32,8 @@ export class HuiButtonsBase extends LitElement { : ""; return html` - ${entityConf.show_icon !== false ? html` @@ -56,11 +57,10 @@ export class HuiButtonsBase extends LitElement { > ` : ""} - ${name} - + `; })} -
+ `; } @@ -74,7 +74,7 @@ export class HuiButtonsBase extends LitElement { haStyleScrollbar, css` .ha-scrollbar { - padding: 8px; + padding: 12px; padding-top: var(--padding-top, 8px); padding-bottom: var(--padding-bottom, 8px); width: 100%; @@ -102,8 +102,9 @@ export class HuiButtonsBase extends LitElement { margin-left: -3px; margin-top: -3px; } - ha-chip { - padding: 4px; + ha-assist-chip state-badge { + margin-right: -4px; + --mdc-icon-size: 18px; } @media all and (max-width: 450px), all and (max-height: 500px) { .ha-scrollbar { diff --git a/src/panels/lovelace/tile-features/hui-cover-position-tile-feature.ts b/src/panels/lovelace/tile-features/hui-cover-position-tile-feature.ts index c613156cd30d..e4fe3a6ae31e 100644 --- a/src/panels/lovelace/tile-features/hui-cover-position-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-cover-position-tile-feature.ts @@ -13,6 +13,7 @@ import { UNAVAILABLE } from "../../../data/entity"; import { HomeAssistant } from "../../../types"; import { LovelaceTileFeature } from "../types"; import { CoverPositionTileFeatureConfig } from "./types"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes"; export const supportsCoverPositionTileFeature = (stateObj: HassEntity) => { const domain = computeDomain(stateObj.entity_id); @@ -93,6 +94,8 @@ class HuiCoverPositionTileFeature "current_position" )} .disabled=${this.stateObj!.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_position} + .locale=${this.hass.locale} >
`; diff --git a/src/panels/lovelace/tile-features/hui-cover-tilt-position-tile-feature.ts b/src/panels/lovelace/tile-features/hui-cover-tilt-position-tile-feature.ts index 00c5768dd437..7607527d0b09 100644 --- a/src/panels/lovelace/tile-features/hui-cover-tilt-position-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-cover-tilt-position-tile-feature.ts @@ -13,6 +13,7 @@ import { generateTiltSliderTrackBackgroundGradient } from "../../../dialogs/more import { HomeAssistant } from "../../../types"; import { LovelaceTileFeature } from "../types"; import { CoverTiltPositionTileFeatureConfig } from "./types"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes"; const GRADIENT = generateTiltSliderTrackBackgroundGradient(); @@ -92,6 +93,8 @@ class HuiCoverTiltPositionTileFeature "current_tilt_position" )} .disabled=${this.stateObj!.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.cover.current_tilt_position} + .locale=${this.hass.locale} >
diff --git a/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts b/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts index 8e6804d1f458..4b587fb71b7e 100644 --- a/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts @@ -23,6 +23,7 @@ import { import { HomeAssistant } from "../../../types"; import { LovelaceTileFeature } from "../types"; import { FanSpeedTileFeatureConfig } from "./types"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes"; export const supportsFanSpeedTileFeature = (stateObj: HassEntity) => { const domain = computeDomain(stateObj.entity_id); @@ -126,6 +127,8 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature { "percentage" )} .disabled=${this.stateObj!.state === UNAVAILABLE} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.fan.percentage} + .locale=${this.hass.locale} >
`; diff --git a/src/panels/lovelace/tile-features/hui-light-brightness-tile-feature.ts b/src/panels/lovelace/tile-features/hui-light-brightness-tile-feature.ts index 01d1e763cf99..a08bbf243033 100644 --- a/src/panels/lovelace/tile-features/hui-light-brightness-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-light-brightness-tile-feature.ts @@ -67,6 +67,8 @@ class HuiLightBrightnessTileFeature .disabled=${this.stateObj!.state === UNAVAILABLE} @value-changed=${this._valueChanged} .label=${this.hass.localize("ui.card.light.brightness")} + .tooltipUnit=${"%"} + .locale=${this.hass.locale} >
`; diff --git a/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts b/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts index 2c35e33eae75..7d641679d7e4 100644 --- a/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts @@ -11,6 +11,7 @@ import { computeDomain } from "../../../common/entity/compute_domain"; import { stateActive } from "../../../common/entity/state_active"; import "../../../components/ha-control-slider"; import { UNAVAILABLE } from "../../../data/entity"; +import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes"; import { LightColorMode, lightSupportsColorMode } from "../../../data/light"; import { generateColorTemperatureGradient } from "../../../dialogs/more-info/components/lights/light-color-temp-picker"; import { HomeAssistant } from "../../../types"; @@ -85,6 +86,8 @@ class HuiLightColorTempTileFeature style=${styleMap({ "--gradient": gradient, })} + .tooltipUnit=${DOMAIN_ATTRIBUTES_UNITS.light.color_temp_kelvin} + .locale=${this.hass.locale} >
`; diff --git a/src/resources/home-assistant-logo-svg.ts b/src/resources/home-assistant-logo-svg.ts index 9eeb6ee8560d..c37e6eb46c79 100644 --- a/src/resources/home-assistant-logo-svg.ts +++ b/src/resources/home-assistant-logo-svg.ts @@ -1,2 +1,2 @@ export const mdiHomeAssistant = - "m12.151 1.5882c-0.32617 1.292e-4 -0.65235 0.12907-0.89964 0.38672l-8.3848 8.7354c-0.061873 0.06443-0.12224 0.13674-0.18069 0.21539-1.018e-4 1.72e-4 -2.376e-4 1.72e-4 -3.31e-4 3.53e-4 -0.058394 0.07855-0.1147 0.16343-0.16842 0.25303-0.25934 0.43253-0.4552 0.97486-0.52317 1.4555-0.00255 0.018-0.00764 0.03695-0.00942 0.05478-0.012052 0.09874-0.018418 0.19443-0.018418 0.28568v7.959c0 0.72958 0.5729 1.3265 1.2731 1.3265h7.8313l-3.4484-3.593c-0.17739 0.06365-0.36671 0.09984-0.56362 0.09984-0.95908 0-1.7399-0.81359-1.7399-1.8129 0-0.99929 0.78085-1.8129 1.7399-1.8129 0.95908 0 1.7399 0.8136 1.7399 1.8129 0 0.20605-0.034883 0.40329-0.095985 0.58812l2.6847 2.7972v-10.248c-0.57715-0.29532-0.97606-0.91251-0.97606-1.6262 0-0.99929 0.78084-1.8129 1.7399-1.8129 0.95908 0 1.7399 0.81359 1.7399 1.8129 0 0.71366-0.39891 1.3309-0.97606 1.6262v7.187l2.6702-2.782c-0.05262-0.17333-0.08156-0.35738-0.08156-0.5484 0-0.9993 0.78084-1.8129 1.7399-1.8129 0.95908 0 1.7399 0.8136 1.7399 1.8129 0 0.99929-0.78084 1.8129-1.7399 1.8129-0.21219 0-0.41417-0.04152-0.60174-0.114l-3.7269 3.8831v2.7299h8.1479c0.61268 0 1.1279-0.45698 1.2471-1.06 0.01698-0.08588 0.02597-0.17475 0.02606-0.26565v-7.959c0-0.09119-0.0059-0.18679-0.01842-0.2855-0.06026-0.49355-0.26358-1.0617-0.53262-1.5105-0.05373-0.08961-0.11007-0.17449-0.16842-0.25304-8.5e-5 -1.81e-4 -2.55e-4 -1.81e-4 -3.4e-4 -3.53e-4 -0.05848-0.07864-0.11884-0.15094-0.18069-0.21539l-8.3848-8.7363c-0.2473-0.25768-0.57348-0.38663-0.89965-0.38675z"; + "m12.151 1.5882c-.3262 0-.6523.1291-.8996.3867l-8.3848 8.7354c-.0619.0644-.1223.1368-.1807.2154-.0588.0789-.1151.1638-.1688.2534-.2593.4325-.4552.9749-.5232 1.4555-.0026.018-.0076.0369-.0094.0548-.0121.0987-.0184.1944-.0184.2857v8.0124a1.2731 1.2731 0 001.2731 1.2731h7.8313l-3.4484-3.593a1.7399 1.7399 0 111.0803-1.125l2.6847 2.7972v-10.248a1.7399 1.7399 0 111.5276-0v7.187l2.6702-2.782a1.7399 1.7399 0 111.0566 1.1505l-3.7269 3.8831v2.7299h8.174a1.2471 1.2471 0 001.2471-1.2471v-8.0375c0-.0912-.0059-.1868-.0184-.2855-.0603-.4935-.2636-1.0617-.5326-1.5105-.0537-.0896-.1101-.1745-.1684-.253-.0588-.079-.1191-.1513-.181-.2158l-8.3848-8.7363c-.2473-.2577-.5735-.3866-.8995-.3864"; diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index c3cced5705c8..2ba9833bd69e 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -122,18 +122,27 @@ export const connectionMixin = >( } if (notifyOnError) { forwardHaptic("failure"); + const lokalize = await this.hass!.loadBackendTranslation( + "exceptions", + err.translation_domain + ); + const localizedErrorMessage = lokalize( + `component.${err.translation_domain}.exceptions.${err.translation_key}.message`, + err.translation_placeholders + ); const message = + localizedErrorMessage || (this as any).hass.localize( "ui.notification_toast.service_call_failed", "service", `${domain}/${service}` ) + - ` ${ - err.message || - (err.error?.code === ERR_CONNECTION_LOST - ? "connection lost" - : "unknown error") - }`; + ` ${ + err.message || + (err.error?.code === ERR_CONNECTION_LOST + ? "connection lost" + : "unknown error") + }`; fireEvent(this as any, "hass-notification", { message }); } throw err; diff --git a/src/translations/en.json b/src/translations/en.json index 4120fee79044..907445f5b42a 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2532,7 +2532,7 @@ "value_template": "Value template", "for": "For", "description": { - "full": "When a template triggers{hasDuration, select, \n true { for {duration}} \n other {}\n }" + "full": "When a template changes from false to true{hasDuration, select, \n true { for {duration}} \n other {}\n }" } }, "time": { @@ -2662,7 +2662,10 @@ }, "template": { "label": "[%key:ui::panel::config::automation::editor::triggers::type::template::label%]", - "value_template": "[%key:ui::panel::config::automation::editor::triggers::type::template::value_template%]" + "value_template": "[%key:ui::panel::config::automation::editor::triggers::type::template::value_template%]", + "description": { + "full": "Test if template renders a value equal to true" + } }, "time": { "type_value": "[%key:ui::panel::config::automation::editor::triggers::type::time::type_value%]", @@ -5676,7 +5679,7 @@ "hdmi_input": "HDMI input", "hdmi_switcher": "HDMI switcher", "volume": "Volume", - "total_tv_time": "Total TV Ttme", + "total_tv_time": "Total TV Time", "turn_tv_off": "Turn television off", "air": "Air" }, diff --git a/yarn.lock b/yarn.lock index e7dbab201cd8..82af266bb0af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1516,14 +1516,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:6.21.4, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0": - version: 6.21.4 - resolution: "@codemirror/view@npm:6.21.4" +"@codemirror/view@npm:6.22.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0": + version: 6.22.0 + resolution: "@codemirror/view@npm:6.22.0" dependencies: "@codemirror/state": "npm:^6.1.4" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: a1b8758ff3897dd3995e70a641290e1fc2f66a5a3fa9ed6053a2f1a72e2ddda1490078b354e018e1504562eec9ae219a4af2f3146c57a49f0ac14d10ab15cff2 + checksum: df9a41c13724d55b540d6c84ac81788f0bc03fcbdae6206c7ee80056906a6734413b7a8c500c6c793d9ef527f2ff5f2c7f1eec481de22e6e6139335deb627783 languageName: node linkType: hard @@ -1570,9 +1570,9 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.2": - version: 2.1.2 - resolution: "@eslint/eslintrc@npm:2.1.2" +"@eslint/eslintrc@npm:^2.1.3": + version: 2.1.3 + resolution: "@eslint/eslintrc@npm:2.1.3" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" @@ -1583,14 +1583,14 @@ __metadata: js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: fa25638f2666cac6810f98ee7d0f4b912f191806467c1b40d72bac759fffef0b3357f12a1869817286837b258e4de3517e0c7408520e156ca860fc53a1fbaed9 + checksum: 77b70a89232fe702c2f765b5b92970f5e4224b55363b923238b996c66fcd991504f40d3663c0543ae17d6c5049ab9b07ab90b65d7601e6f25e8bcd4caf69ac75 languageName: node linkType: hard -"@eslint/js@npm:8.52.0": - version: 8.52.0 - resolution: "@eslint/js@npm:8.52.0" - checksum: 86beff213d0ae4ced203a922b74e2cc4d767d109e7815f985bf648946ba072198977102e32afc9fa04f7825a6de83a831874f6b6675ba0c1d0743ade2dc2d53d +"@eslint/js@npm:8.53.0": + version: 8.53.0 + resolution: "@eslint/js@npm:8.53.0" + checksum: a372d55aa2bbe0d9399acc8de3c892dcfe507fd914d29fde6826ae54a13452619be626aa7eb70b1ec4d4da5302b6ed8e8ac9bf1f830003f15c0ad56c30b4f520 languageName: node linkType: hard @@ -2122,13 +2122,13 @@ __metadata: languageName: node linkType: hard -"@lit-labs/virtualizer@npm:2.0.9": - version: 2.0.9 - resolution: "@lit-labs/virtualizer@npm:2.0.9" +"@lit-labs/virtualizer@npm:2.0.10": + version: 2.0.10 + resolution: "@lit-labs/virtualizer@npm:2.0.10" dependencies: lit: "npm:^2 || ^3" tslib: "npm:^2.0.3" - checksum: d638997118b6757f47b6b5aab6eaa217fc0f9771af5008e79e136b5cd176fc490f055ea26ec3c851e1789b866e37e36827a5a34a86aee554c38d86982dc34205 + checksum: 30f08ee582809d6ef27b50c2cd799ebe362dcfd276ef511c0ebaf5707fd75152cb8705c4125c775a7ea943a76d7fa162f0300a33cf75d8aa701387a3ffa41d56 languageName: node linkType: hard @@ -4136,15 +4136,6 @@ __metadata: languageName: node linkType: hard -"@types/esprima@npm:4.0.5": - version: 4.0.5 - resolution: "@types/esprima@npm:4.0.5" - dependencies: - "@types/estree": "npm:*" - checksum: bb722d9833bdae19c915d3d0f5cba5320ac30806eea8c93af168ee1f9dfc0e924003cff0cacf3f625dc00e2639ed457ceb910e9d9b57e847e1459760f0cefce3 - languageName: node - linkType: hard - "@types/estree@npm:*, @types/estree@npm:^1.0.0": version: 1.0.3 resolution: "@types/estree@npm:1.0.3" @@ -4721,126 +4712,126 @@ __metadata: languageName: node linkType: hard -"@vaadin/a11y-base@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/a11y-base@npm:24.2.1" +"@vaadin/a11y-base@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/a11y-base@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.2.1" + "@vaadin/component-base": "npm:~24.2.2" lit: "npm:^2.0.0" - checksum: 3294f41e67f2a03818e15f7e3c6987f0d976dd1f5c66a55a9ca7ce32e0c19cc8b6d1bd475063e19af3a9125e4cfde070e382821936278e74742c01ba98caa893 + checksum: ff7b65ec107d70f09ceed7be895a22d3c72d37a745b96d1118b5788784de10fdc51f586c252635e93785fd09d0eada90cd41d8ce95563cad5a64d35cbed70341 languageName: node linkType: hard -"@vaadin/combo-box@npm:24.2.1": - version: 24.2.1 - resolution: "@vaadin/combo-box@npm:24.2.1" +"@vaadin/combo-box@npm:24.2.2": + version: 24.2.2 + resolution: "@vaadin/combo-box@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.2.1" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/field-base": "npm:~24.2.1" - "@vaadin/input-container": "npm:~24.2.1" - "@vaadin/item": "npm:~24.2.1" - "@vaadin/lit-renderer": "npm:~24.2.1" - "@vaadin/overlay": "npm:~24.2.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.2.1" - "@vaadin/vaadin-material-styles": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" - checksum: 447a090708240bbb9d8edd8143d549371c6bd59c98442fb841812654518428e493d56594607f618e4d5531c780d4a289f24b46fd083ece6650d0da56644c8225 + "@vaadin/a11y-base": "npm:~24.2.2" + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/field-base": "npm:~24.2.2" + "@vaadin/input-container": "npm:~24.2.2" + "@vaadin/item": "npm:~24.2.2" + "@vaadin/lit-renderer": "npm:~24.2.2" + "@vaadin/overlay": "npm:~24.2.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.2.2" + "@vaadin/vaadin-material-styles": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" + checksum: f24e9bd557ecc843d7e00f8e46653e4903d59530d6c84e1517d71e31860c4fe70472942e8b6c1114cdd6078fb69a919c69057d2ddc91452e8c4200a36772cbb4 languageName: node linkType: hard -"@vaadin/component-base@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/component-base@npm:24.2.1" +"@vaadin/component-base@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/component-base@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" "@vaadin/vaadin-development-mode-detector": "npm:^2.0.0" "@vaadin/vaadin-usage-statistics": "npm:^2.1.0" lit: "npm:^2.0.0" - checksum: ef156cee137eb57f1d969ccbe4f8ec0bac79b107e77315f771bbcc2eddd0f951fa874a8ea04561abbeaf5a309cf0dfdf34eeaf7f453f771eaed693e8a59f8651 + checksum: 940726eda470191bb15c531cb663a09a9136ffa608a07a5eca44d526c70ab8ef53953c191bfc8cdcfe3a21090a93c8fcfab00122eab5b7e9a11f0f1d065087c0 languageName: node linkType: hard -"@vaadin/field-base@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/field-base@npm:24.2.1" +"@vaadin/field-base@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/field-base@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.2.1" - "@vaadin/component-base": "npm:~24.2.1" + "@vaadin/a11y-base": "npm:~24.2.2" + "@vaadin/component-base": "npm:~24.2.2" lit: "npm:^2.0.0" - checksum: bf8a716ea273fd6dc5433e108c1d88a1922c6a94c8926b26d413b0e30c4dc69beb015dd029c7ef33bbb8cac5e6585bc113979e300d02d8cf774ffeda0da1eda2 + checksum: dbfc40ecaef91672865b9419710e35d4da14850cda2d12f4cf90fa3adcb2e9e0439635518fd0b91a83f5d852abd1d9f01298810a982fd59b2903371a0406edd5 languageName: node linkType: hard -"@vaadin/icon@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/icon@npm:24.2.1" +"@vaadin/icon@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/icon@npm:24.2.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" lit: "npm:^2.0.0" - checksum: a4d972a71801729933d99083a91d447b023accf4ae7107635ff82d496b0670e6314ccc7c9faf7c80e78cfe54ea8bc4e59ef4fadc9e0789e4868a0db9d065a49c + checksum: 2895eed759606b26bd51c694e90fd2de29f6e86c9b28088e2f51df995ba6cf822dbdc1dda90f63eac2e67ed656ba46f6981919bb69a3f1005d523d80561233ca languageName: node linkType: hard -"@vaadin/input-container@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/input-container@npm:24.2.1" +"@vaadin/input-container@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/input-container@npm:24.2.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.2.1" - "@vaadin/vaadin-material-styles": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" - checksum: 537b83fe050a75ba7d2f9f4e03679cb623ccfadc6ea7924500404d8fa9e563ea553b070c8dccd5d3ffe74b0840f0ae1b1a3c1b2ae0d0596e98942134aa4d3a2d + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.2.2" + "@vaadin/vaadin-material-styles": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" + checksum: 42385a0d060fc9d6f5d856cb7089d2170daab61813ea4e37195e42e53d136665fa5a51c1426bfdb0d470156fb41591a78ba08a0d53056233fe34d3ab22f6280c languageName: node linkType: hard -"@vaadin/item@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/item@npm:24.2.1" +"@vaadin/item@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/item@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.2.1" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.2.1" - "@vaadin/vaadin-material-styles": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" - checksum: 6ab646b2980f13fe6211db92b3f15461a2a0125c9d8019c75e484755c9b9cfc648ac10fee16db6ca7e7781e86a6d8dfd78e3fd20b6eaca2439c29bcafbced7cc + "@vaadin/a11y-base": "npm:~24.2.2" + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.2.2" + "@vaadin/vaadin-material-styles": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" + checksum: b6e4574e43d870d68286b8f64bae4028934a2c0fc56dcf9a485abedb4124b96f565c4dfe25fb0b3e84f9ba3063655636cdc2b20edb47efd9cc3c53ccc8733fba languageName: node linkType: hard -"@vaadin/lit-renderer@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/lit-renderer@npm:24.2.1" +"@vaadin/lit-renderer@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/lit-renderer@npm:24.2.2" dependencies: lit: "npm:^2.0.0" - checksum: e28849de273b31971fa769dacbfc694f14dd30ae49ce41467d84d76fe69fa69894661bfc3aabe9654d14532b8ccffc04f7560d57eae3e4e1058dace647419b69 + checksum: 4be7535e5642ce73a60db5b05956da67be3f569a5feca19f555d3ffd33ed163ffc86c972cc73f1441a511f7bb7a091c82a9372a36b89496a7bde56bf2822a981 languageName: node linkType: hard -"@vaadin/overlay@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/overlay@npm:24.2.1" +"@vaadin/overlay@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/overlay@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.2.1" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.2.1" - "@vaadin/vaadin-material-styles": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" - checksum: a9e8a2817200111fab9f3dbe0aa2a055be3a4b98d57b0c13e41005326c25dfa5bd812567a291dba3de46d2e8e168fceafeb0d64d7c1166675bf5dfbdb1f09f90 + "@vaadin/a11y-base": "npm:~24.2.2" + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.2.2" + "@vaadin/vaadin-material-styles": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" + checksum: c7e095566cf719d39f54d9ef50274c415503568e76f7f73d99aaeab9ea4eaad96ea1b9a2544b7107cc6a7413e0eb8348a43c9aaec465c7d7ab617df75ea7dcbb languageName: node linkType: hard @@ -4851,36 +4842,36 @@ __metadata: languageName: node linkType: hard -"@vaadin/vaadin-lumo-styles@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/vaadin-lumo-styles@npm:24.2.1" +"@vaadin/vaadin-lumo-styles@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/vaadin-lumo-styles@npm:24.2.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/icon": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" - checksum: c28c2524155b630aab6c3dcb678c1c7d2457fec529cfa2f8f975be67cd65cbafac52c3555e0de816c016addd7d4caf30ce6ff8bf40b4521fa5efdd406b1b7bf2 + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/icon": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" + checksum: 51ef76ca619a9c3c65bb192194816fa8fb35d35ed4ad5245f0308f45262355e7c752da2844ce27ad6e2c21985b88dcc26705816699d1d7a6ac861a04b97c3b25 languageName: node linkType: hard -"@vaadin/vaadin-material-styles@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/vaadin-material-styles@npm:24.2.1" +"@vaadin/vaadin-material-styles@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/vaadin-material-styles@npm:24.2.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.2.1" - checksum: 521322251705a8b108303b7b332098713a51bc99b4065f38bb621eb4ffaaf2f871f8521c65cc5e24918757273adfaa37265d658ae305cdc46a1612100ea3be5a + "@vaadin/component-base": "npm:~24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.2.2" + checksum: ea9f6ce5923cd982f97883f4adf1f1c9e83900cc77dd7c50806859c950b16b71fa922d104a4083052162a2dec324d5ad14212176586475ff196cd9e3bf3bf622 languageName: node linkType: hard -"@vaadin/vaadin-themable-mixin@npm:24.2.1, @vaadin/vaadin-themable-mixin@npm:~24.2.1": - version: 24.2.1 - resolution: "@vaadin/vaadin-themable-mixin@npm:24.2.1" +"@vaadin/vaadin-themable-mixin@npm:24.2.2, @vaadin/vaadin-themable-mixin@npm:~24.2.2": + version: 24.2.2 + resolution: "@vaadin/vaadin-themable-mixin@npm:24.2.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" lit: "npm:^2.0.0" - checksum: 4b3e0bea695dd0328c7e96685355bd34fc3daef8fd487357db81ccb6c693b45b34c3b66d1db4cd1e8c224f44e96e8275bd2fa71b67e6d6ea0edc924f501a9ba4 + checksum: 5916c7399683da7513052522f34434404a7914ea868ef4c0fc13ad5dda38fcb93d7ea1b5348f5e8ffe5d632220e6e2ec720ccff7f971cbb12c7e41714979871c languageName: node linkType: hard @@ -8048,16 +8039,16 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-lit-a11y@npm:4.1.0": - version: 4.1.0 - resolution: "eslint-plugin-lit-a11y@npm:4.1.0" +"eslint-plugin-lit-a11y@npm:4.1.1": + version: 4.1.1 + resolution: "eslint-plugin-lit-a11y@npm:4.1.1" dependencies: aria-query: "npm:^5.1.3" axe-core: "npm:^4.3.3" axobject-query: "npm:^2.2.0" dom5: "npm:^3.0.1" emoji-regex: "npm:^10.2.1" - eslint-plugin-lit: "npm:^1.6.0" + eslint-plugin-lit: "npm:^1.10.1" eslint-rule-extender: "npm:0.0.1" language-tags: "npm:^1.0.5" parse5: "npm:^7.1.2" @@ -8065,11 +8056,11 @@ __metadata: requireindex: "npm:~1.2.0" peerDependencies: eslint: ">= 5" - checksum: 41c5b3a216552ea89c715a53d9b1d4e4ec1d3a8652d53896c77ce84daae059bb54f4cc4bef1842a7503d6db9ba9cee8423ce93803fbf6c363f3a0d98dcc81f20 + checksum: f8d20e4e18ea9cf17c95546f878213d57f3eb9fd71a01ebae1b5d1689c0da7c35f0fe39137994717e600c3d12cfaa754ab3d4cdd854a6cf4d0a907ae898bc9a5 languageName: node linkType: hard -"eslint-plugin-lit@npm:1.10.1, eslint-plugin-lit@npm:^1.6.0": +"eslint-plugin-lit@npm:1.10.1, eslint-plugin-lit@npm:^1.10.1": version: 1.10.1 resolution: "eslint-plugin-lit@npm:1.10.1" dependencies: @@ -8150,14 +8141,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.52.0": - version: 8.52.0 - resolution: "eslint@npm:8.52.0" +"eslint@npm:8.53.0": + version: 8.53.0 + resolution: "eslint@npm:8.53.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.2" - "@eslint/js": "npm:8.52.0" + "@eslint/eslintrc": "npm:^2.1.3" + "@eslint/js": "npm:8.53.0" "@humanwhocodes/config-array": "npm:^0.11.13" "@humanwhocodes/module-importer": "npm:^1.0.1" "@nodelib/fs.walk": "npm:^1.2.8" @@ -8194,7 +8185,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 01784ab15351d749bc95446039ed7acd5124f7cc84acdbf98c7199272eae06212a8f3ea4a9b47e7cc54ab17ca094c3a664bbfc3002c7de27936220e278b5028a + checksum: e305a71ce2b9a8631b293266fe53e346c76f28bc8d004af33f10e537cf133db1fb87af3599376e70ed6e0f89a78be10c4f08ddd0c1c9c0c497cd143b4a270420 languageName: node linkType: hard @@ -8209,16 +8200,6 @@ __metadata: languageName: node linkType: hard -"esprima@npm:4.0.1": - version: 4.0.1 - resolution: "esprima@npm:4.0.1" - bin: - esparse: ./bin/esparse.js - esvalidate: ./bin/esvalidate.js - checksum: f1d3c622ad992421362294f7acf866aa9409fbad4eb2e8fa230bd33944ce371d32279667b242d8b8907ec2b6ad7353a717f3c0e60e748873a34a7905174bc0eb - languageName: node - linkType: hard - "esquery@npm:^1.4.2": version: 1.5.0 resolution: "esquery@npm:1.5.0" @@ -9635,7 +9616,7 @@ __metadata: "@codemirror/legacy-modes": "npm:6.3.3" "@codemirror/search": "npm:6.5.4" "@codemirror/state": "npm:6.3.1" - "@codemirror/view": "npm:6.21.4" + "@codemirror/view": "npm:6.22.0" "@egjs/hammerjs": "npm:2.0.17" "@formatjs/intl-datetimeformat": "npm:6.11.1" "@formatjs/intl-displaynames": "npm:6.6.1" @@ -9656,7 +9637,7 @@ __metadata: "@lit-labs/context": "npm:0.4.1" "@lit-labs/motion": "npm:1.0.6" "@lit-labs/observers": "npm:2.0.2" - "@lit-labs/virtualizer": "npm:2.0.9" + "@lit-labs/virtualizer": "npm:2.0.10" "@lokalise/node-api": "npm:12.0.0" "@lrnwebcomponents/simple-tooltip": "npm:7.0.18" "@material/chips": "npm:=14.0.0-canary.53b3cad2f.0" @@ -9710,7 +9691,6 @@ __metadata: "@types/babel__plugin-transform-runtime": "npm:7.9.4" "@types/chromecast-caf-receiver": "npm:6.0.11" "@types/chromecast-caf-sender": "npm:1.0.7" - "@types/esprima": "npm:4.0.5" "@types/glob": "npm:8.1.0" "@types/html-minifier-terser": "npm:7.0.1" "@types/js-yaml": "npm:4.0.8" @@ -9726,8 +9706,8 @@ __metadata: "@types/webspeechapi": "npm:0.0.29" "@typescript-eslint/eslint-plugin": "npm:6.9.1" "@typescript-eslint/parser": "npm:6.9.1" - "@vaadin/combo-box": "npm:24.2.1" - "@vaadin/vaadin-themable-mixin": "npm:24.2.1" + "@vaadin/combo-box": "npm:24.2.2" + "@vaadin/vaadin-themable-mixin": "npm:24.2.2" "@vibrant/color": "npm:3.2.1-alpha.1" "@vibrant/core": "npm:3.2.1-alpha.1" "@vibrant/quantizer-mmcq": "npm:3.2.1-alpha.1" @@ -9749,7 +9729,7 @@ __metadata: deep-clone-simple: "npm:1.1.1" deep-freeze: "npm:0.0.1" del: "npm:7.1.0" - eslint: "npm:8.52.0" + eslint: "npm:8.53.0" eslint-config-airbnb-base: "npm:15.0.0" eslint-config-airbnb-typescript: "npm:17.1.0" eslint-config-prettier: "npm:9.0.0" @@ -9757,10 +9737,9 @@ __metadata: eslint-plugin-disable: "npm:2.0.3" eslint-plugin-import: "npm:2.29.0" eslint-plugin-lit: "npm:1.10.1" - eslint-plugin-lit-a11y: "npm:4.1.0" + eslint-plugin-lit-a11y: "npm:4.1.1" eslint-plugin-unused-imports: "npm:3.0.0" eslint-plugin-wc: "npm:2.0.4" - esprima: "npm:4.0.1" fancy-log: "npm:2.0.0" fs-extra: "npm:11.1.1" fuse.js: "npm:7.0.0" @@ -9790,7 +9769,7 @@ __metadata: luxon: "npm:3.4.3" magic-string: "npm:0.30.5" map-stream: "npm:0.0.7" - marked: "npm:9.1.3" + marked: "npm:9.1.5" memoize-one: "npm:6.0.0" mocha: "npm:10.2.0" node-vibrant: "npm:3.2.1-alpha.1" @@ -9810,7 +9789,7 @@ __metadata: rollup-plugin-visualizer: "npm:5.9.2" rrule: "npm:2.7.2" serve-handler: "npm:6.1.5" - sinon: "npm:17.0.0" + sinon: "npm:17.0.1" sortablejs: "npm:1.15.0" source-map-url: "npm:0.4.1" stacktrace-js: "npm:2.0.2" @@ -9828,7 +9807,7 @@ __metadata: vinyl-buffer: "npm:1.0.1" vinyl-source-stream: "npm:2.0.0" vis-data: "npm:7.1.7" - vis-network: "npm:9.1.8" + vis-network: "npm:9.1.9" vue: "npm:2.7.15" vue2-daterange-picker: "npm:0.6.8" webpack: "npm:5.89.0" @@ -11781,12 +11760,12 @@ __metadata: languageName: node linkType: hard -"marked@npm:9.1.3": - version: 9.1.3 - resolution: "marked@npm:9.1.3" +"marked@npm:9.1.5": + version: 9.1.5 + resolution: "marked@npm:9.1.5" bin: marked: bin/marked.js - checksum: edfa85287dcd00d04221848d211f2d33376590dc91004d115b2e7646fb16408ce604224db42ce2245730f164c41892186053ccd7bbe1ce5d4dfc1edcf22e15ae + checksum: 308cacc0c2678d0cc79f33ede75bf73fde85302d447c0fc2df3e4d66343f1dda10297ea8bd0d990ecdeac1d15eb3565ca7cb4f224b3de8b6adb002dd6ca1acf8 languageName: node linkType: hard @@ -14387,9 +14366,9 @@ __metadata: languageName: node linkType: hard -"sinon@npm:17.0.0": - version: 17.0.0 - resolution: "sinon@npm:17.0.0" +"sinon@npm:17.0.1": + version: 17.0.1 + resolution: "sinon@npm:17.0.1" dependencies: "@sinonjs/commons": "npm:^3.0.0" "@sinonjs/fake-timers": "npm:^11.2.2" @@ -14397,7 +14376,7 @@ __metadata: diff: "npm:^5.1.0" nise: "npm:^5.1.5" supports-color: "npm:^7.2.0" - checksum: ffc1507a551acf15588b0420ba548274ffec2556211a2979df11476630a1d1769c6398ee4bcd56413c716c01c52fa4561e11761d24de57095728ad194e597893 + checksum: b34f1a97da0be3556ac686c6b649a566c2666eb7f50e75e754928c1c72c96d78f56e56a999227be794c3d9cdaed0bc78d11f38ab303d3079c5bcbcffc0f9c6d5 languageName: node linkType: hard @@ -16050,9 +16029,9 @@ __metadata: languageName: node linkType: hard -"vis-network@npm:9.1.8": - version: 9.1.8 - resolution: "vis-network@npm:9.1.8" +"vis-network@npm:9.1.9": + version: 9.1.9 + resolution: "vis-network@npm:9.1.9" peerDependencies: "@egjs/hammerjs": ^2.0.0 component-emitter: ^1.3.0 @@ -16060,7 +16039,7 @@ __metadata: uuid: ^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 vis-data: ^6.3.0 || ^7.0.0 vis-util: ^5.0.1 - checksum: ea46410d8f85258f25c18f03653cc6c6a5156fa1b079bf4a7cab4defbbe40ac102961a8dddaaf92639b15291472dc5f3d9e3bffbbc52e1be17a35169c0e62b87 + checksum: 929b2645ff62645d030e6a03f2f618d0e66c9a83782c4f6f3257160d48ea49fc06eb62403762b010eb07d137bee72a1bd62e5c58ebbfb9091dbb3ca1f8f1887d languageName: node linkType: hard