Compare commits

..

37 Commits

Author SHA1 Message Date
Bram Kragten
e98eb8de7f Add inital form data to hui-form-editor 2023-12-12 09:58:50 +01:00
renovate[bot]
12e6701ffa Update dependency marked to v11.0.1 (#19007) 2023-12-11 20:56:46 -05:00
karwosts
7167b66719 Don't leave empty arrays in the service control target (#18986) 2023-12-11 11:19:28 +01:00
dependabot[bot]
a52ba5fbd1 Bump actions/stale from 8.0.0 to 9.0.0 (#19004) 2023-12-11 08:06:47 +01:00
dependabot[bot]
22cf903656 Bump actions/setup-python from 4 to 5 (#19005) 2023-12-11 08:05:40 +01:00
dependabot[bot]
d77b657036 Bump actions/labeler from 4.3.0 to 5.0.0 (#19003) 2023-12-11 07:46:59 +01:00
renovate[bot]
4a3038c12c Update dependency hls.js to v1.4.13 (#18994) 2023-12-10 22:02:24 -05:00
renovate[bot]
3ac7cd5d4a Update dependency @codemirror/state to v6.3.3 (#18984) 2023-12-09 20:57:44 -05:00
renovate[bot]
58eddd2b42 Update dependency typescript to v5.3.3 (#18993) 2023-12-09 16:44:38 -05:00
renovate[bot]
d808da68bd Update dependency @lokalise/node-api to v12.1.0 (#18973) 2023-12-08 22:09:23 -05:00
renovate[bot]
2ed4d1efa0 Update dependency @braintree/sanitize-url to v7 (#18975) 2023-12-08 22:00:36 -05:00
Paul Bottein
fcb9e13a84 Bumped version to 20231208.2 2023-12-08 14:49:04 +01:00
Bram Kragten
3ada2f3279 Fix label when there is no target (#18969) 2023-12-08 13:38:01 +00:00
Paul Bottein
8d2d45ae4e Add dropdown style to hvac_modes feature (#18963) 2023-12-08 13:43:59 +01:00
Simon Lamon
c9e6963387 Fix todo url (#18954)
* Fix todo url

* Move searchParams

* Update src/panels/todo/ha-panel-todo.ts

* check if saved entity exists

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-12-08 13:35:57 +01:00
Paul Bottein
6d36b0e28c Hide climate mode control on default dashboard if there is only one hvac mode (#18964)
Hide hvac mode on default dashboard if there is only one hvac mode
2023-12-08 10:58:08 +00:00
Paul Bottein
61117bb34f Bumped version to 20231208.1 2023-12-08 10:30:33 +01:00
Simon Lamon
86a3c32844 Fix area in device picker (#18955)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-12-08 09:17:40 +00:00
Paul Bottein
b855b3e103 Format number attribute for media player (#18949) 2023-12-08 10:14:55 +01:00
renovate[bot]
80edeebab9 Update dependency chart.js to v4.4.1 (#18957) 2023-12-07 20:38:49 -05:00
renovate[bot]
f366e287b1 Update typescript-eslint monorepo to v6.13.2 (#18953) 2023-12-07 20:34:08 -05:00
renovate[bot]
9ce8684aba Update dependency lint-staged to v15.2.0 (#18930) 2023-12-07 20:32:47 -05:00
renovate[bot]
caa6ea531c Update dependency @types/luxon to v3.3.7 (#18956) 2023-12-07 20:28:26 -05:00
Paul Bottein
cca1183ee3 Revert "Remove card features for humidifier and climate on default dashboard" (#18944)
* Revert "Remove card features for humidifier and climate on default dashboard (#18747)"

This reverts commit 2afd2788e2.

* Rename humidifier feature
2023-12-07 16:53:07 +01:00
Paul Bottein
0f9c97aea0 Center login content for every screen size (#18943) 2023-12-07 13:45:05 +00:00
Paul Bottein
8d08aa8c79 Fix tile card interaction when border width is set to 0 (#18941) 2023-12-07 14:40:23 +01:00
renovate[bot]
eebcab435d Update dependency rollup-plugin-visualizer to v5.10.0 (#18936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-07 11:15:26 +01:00
Bram Kragten
76d3c6e237 Revert fetching config flow after subscribe for progress (#18939) 2023-12-07 09:31:34 +01:00
karwosts
a820ca1e90 Fix number selector display for 0 (#18927) 2023-12-06 17:03:44 +01:00
Paul Bottein
39260d172f Bumped version to 20231206.0 2023-12-06 14:23:09 +01:00
Paul Bottein
e646528b86 Fix empty classmap in state control (#18922)
* Fix empy classmap in state control

* Don't use class map
2023-12-06 14:22:32 +01:00
Bram Kragten
86726102fb Fix issues with circular progress (#18920) 2023-12-06 14:21:28 +01:00
Bram Kragten
1330558819 Force media player browser dialog re-layout after open animation (#18910) 2023-12-06 14:14:14 +01:00
Paul Bottein
b4ab0fc10b Reduce sensitivity of the circular slider on touch devices (#18921) 2023-12-06 14:13:19 +01:00
Paul Bottein
15becf9ef6 Add ellipsis to thermostat and humidifier card title (#18924) 2023-12-06 13:28:03 +01:00
Paul Bottein
ef3785ce9f Fix particles over alert in login screen (#18923) 2023-12-06 13:16:47 +01:00
renovate[bot]
134e13005d Update dependency eslint-config-prettier to v9.1.0 (#18909) 2023-12-05 18:18:46 -05:00
37 changed files with 631 additions and 361 deletions

View File

@@ -10,6 +10,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Apply labels
uses: actions/labeler@v4.3.0
uses: actions/labeler@v5.0.0
with:
sync-labels: true

View File

@@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@v4.1.1
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

View File

@@ -29,7 +29,7 @@ jobs:
uses: home-assistant/actions/helpers/verify-version@master
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 90 days stale policy
uses: actions/stale@v8.0.0
uses: actions/stale@v9.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 90

View File

@@ -26,13 +26,13 @@
"type": "module",
"dependencies": {
"@babel/runtime": "7.23.5",
"@braintree/sanitize-url": "6.0.4",
"@braintree/sanitize-url": "7.0.0",
"@codemirror/autocomplete": "6.11.1",
"@codemirror/commands": "6.3.2",
"@codemirror/language": "6.9.3",
"@codemirror/legacy-modes": "6.3.3",
"@codemirror/search": "6.5.5",
"@codemirror/state": "6.3.2",
"@codemirror/state": "6.3.3",
"@codemirror/view": "6.22.1",
"@egjs/hammerjs": "2.0.17",
"@formatjs/intl-datetimeformat": "6.12.0",
@@ -99,7 +99,7 @@
"@webcomponents/scoped-custom-element-registry": "0.0.9",
"@webcomponents/webcomponentsjs": "2.8.0",
"app-datepicker": "5.1.1",
"chart.js": "4.4.0",
"chart.js": "4.4.1",
"comlink": "4.4.1",
"core-js": "3.33.3",
"cropperjs": "1.6.1",
@@ -110,7 +110,7 @@
"element-internals-polyfill": "1.3.9",
"fuse.js": "7.0.0",
"google-timezones-json": "1.2.0",
"hls.js": "1.4.12",
"hls.js": "1.4.13",
"home-assistant-js-websocket": "9.1.0",
"idb-keyval": "6.2.1",
"intl-messageformat": "10.5.8",
@@ -119,7 +119,7 @@
"leaflet-draw": "1.0.4",
"lit": "2.8.0",
"luxon": "3.4.4",
"marked": "11.0.0",
"marked": "11.0.1",
"memoize-one": "6.0.0",
"node-vibrant": "3.2.1-alpha.1",
"proxy-polyfill": "0.3.2",
@@ -158,7 +158,7 @@
"@babel/preset-typescript": "7.23.3",
"@bundle-stats/plugin-webpack-filter": "4.8.3",
"@koa/cors": "4.0.0",
"@lokalise/node-api": "12.0.0",
"@lokalise/node-api": "12.1.0",
"@octokit/auth-oauth-device": "6.0.1",
"@octokit/plugin-retry": "6.0.1",
"@octokit/rest": "20.0.2",
@@ -176,7 +176,7 @@
"@types/js-yaml": "4.0.9",
"@types/leaflet": "1.9.8",
"@types/leaflet-draw": "1.0.11",
"@types/luxon": "3.3.6",
"@types/luxon": "3.3.7",
"@types/mocha": "10.0.6",
"@types/qrcode": "1.5.5",
"@types/serve-handler": "6.1.4",
@@ -184,8 +184,8 @@
"@types/tar": "6.1.10",
"@types/ua-parser-js": "0.7.39",
"@types/webspeechapi": "0.0.29",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"@typescript-eslint/eslint-plugin": "6.13.2",
"@typescript-eslint/parser": "6.13.2",
"@web/dev-server": "0.1.38",
"@web/dev-server-rollup": "0.4.1",
"babel-loader": "9.1.3",
@@ -195,7 +195,7 @@
"eslint": "8.55.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-airbnb-typescript": "17.1.0",
"eslint-config-prettier": "9.0.0",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-webpack": "0.13.8",
"eslint-plugin-disable": "2.0.3",
"eslint-plugin-import": "2.29.0",
@@ -216,7 +216,7 @@
"husky": "8.0.3",
"instant-mocha": "1.5.2",
"jszip": "3.10.1",
"lint-staged": "15.1.0",
"lint-staged": "15.2.0",
"lit-analyzer": "2.0.1",
"lodash.template": "4.5.0",
"magic-string": "0.30.5",
@@ -229,7 +229,7 @@
"rollup": "2.79.1",
"rollup-plugin-string": "3.0.0",
"rollup-plugin-terser": "7.0.2",
"rollup-plugin-visualizer": "5.9.3",
"rollup-plugin-visualizer": "5.10.0",
"serve-handler": "6.1.5",
"sinon": "17.0.1",
"source-map-url": "0.4.1",
@@ -237,7 +237,7 @@
"tar": "6.2.0",
"terser-webpack-plugin": "5.3.9",
"ts-lit-plugin": "2.0.1",
"typescript": "5.3.2",
"typescript": "5.3.3",
"vinyl-buffer": "1.0.1",
"vinyl-source-stream": "2.0.0",
"webpack": "5.89.0",

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20231205.0"
version = "20231208.2"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"

View File

@@ -63,6 +63,7 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
ha-authorize ha-alert {
display: block;
margin: 16px 0;
background-color: var(--primary-background-color, #fafafa);
}
</style>
<ha-alert alert-type="error"
@@ -93,6 +94,7 @@ export class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
ha-alert {
display: block;
margin: 16px 0;
background-color: var(--primary-background-color, #fafafa);
}
p {
font-size: 14px;

View File

@@ -1,5 +1,6 @@
import { HassConfig, HassEntity } from "home-assistant-js-websocket";
import {
DOMAIN_ATTRIBUTES_FORMATERS,
DOMAIN_ATTRIBUTES_UNITS,
TEMPERATURE_ATTRIBUTES,
} from "../../data/entity_attributes";
@@ -14,11 +15,10 @@ import { formatNumber } from "../number/format_number";
import { capitalizeFirstLetter } from "../string/capitalize-first-letter";
import { isDate } from "../string/is_date";
import { isTimestamp } from "../string/is_timestamp";
import { blankBeforePercent } from "../translations/blank_before_percent";
import { blankBeforeUnit } from "../translations/blank_before_unit";
import { LocalizeFunc } from "../translations/localize";
import { computeDomain } from "./compute_domain";
import { computeStateDomain } from "./compute_state_domain";
import { blankBeforeUnit } from "../translations/blank_before_unit";
export const computeAttributeValueDisplay = (
localize: LocalizeFunc,
@@ -39,19 +39,18 @@ export const computeAttributeValueDisplay = (
// Number value, return formatted number
if (typeof attributeValue === "number") {
const formattedValue = formatNumber(attributeValue, locale);
const domain = computeStateDomain(stateObj);
const formatter = DOMAIN_ATTRIBUTES_FORMATERS[domain]?.[attribute];
const formattedValue = formatter
? formatter(attributeValue, locale)
: formatNumber(attributeValue, locale);
let unit = DOMAIN_ATTRIBUTES_UNITS[domain]?.[attribute] as
| string
| undefined;
if (domain === "light" && attribute === "brightness") {
const percentage = Math.round((attributeValue / 255) * 100);
return `${percentage}${blankBeforePercent(locale)}%`;
}
if (domain === "weather") {
unit = getWeatherUnit(config, stateObj as WeatherEntity, attribute);
}

View File

@@ -10,7 +10,6 @@ import {
ScorableTextItem,
fuzzyFilterSort,
} from "../../common/string/filter/sequence-matching";
import { AreaRegistryEntry } from "../../data/area_registry";
import {
DeviceEntityDisplayLookup,
DeviceRegistryEntry,
@@ -102,7 +101,7 @@ export class HaDevicePicker extends LitElement {
private _getDevices = memoizeOne(
(
devices: DeviceRegistryEntry[],
areas: AreaRegistryEntry[],
areas: HomeAssistant["areas"],
entities: EntityRegistryDisplayEntry[],
includeDomains: this["includeDomains"],
excludeDomains: this["excludeDomains"],
@@ -133,8 +132,6 @@ export class HaDevicePicker extends LitElement {
deviceEntityLookup = getDeviceEntityDisplayLookup(entities);
}
const areaLookup = areas;
let inputDevices = devices.filter(
(device) => device.id === this.value || !device.disabled_by
);
@@ -224,8 +221,8 @@ export class HaDevicePicker extends LitElement {
id: device.id,
name: name,
area:
device.area_id && areaLookup[device.area_id]
? areaLookup[device.area_id].name
device.area_id && areas[device.area_id]
? areas[device.area_id].name
: this.hass.localize("ui.components.device-picker.no_area"),
strings: [name || ""],
};
@@ -267,7 +264,7 @@ export class HaDevicePicker extends LitElement {
this._init = true;
const devices = this._getDevices(
Object.values(this.hass.devices),
Object.values(this.hass.areas),
this.hass.areas,
Object.values(this.hass.entities),
this.includeDomains,
this.excludeDomains,

View File

@@ -2,6 +2,7 @@ import {
DIRECTION_ALL,
Manager,
Pan,
Press,
Tap,
TouchMouseInput,
} from "@egjs/hammerjs";
@@ -108,6 +109,9 @@ export class HaControlCircularSlider extends LitElement {
@property({ type: Number })
public max = 100;
@property({ type: Boolean, attribute: "prevent-interaction-on-scroll" })
public preventInteractionOnScroll?: boolean;
@state()
public _localValue?: number = this.value;
@@ -246,16 +250,62 @@ export class HaControlCircularSlider extends LitElement {
this._mc = new Manager(this._interaction, {
inputClass: TouchMouseInput,
});
const pressToActivate =
this.preventInteractionOnScroll && "ontouchstart" in window;
// If press to activate is true, a 60ms press is required to activate the slider
this._mc.add(
new Pan({
direction: DIRECTION_ALL,
enable: true,
threshold: 0,
new Press({
enable: pressToActivate,
pointers: 1,
time: 60,
})
);
const panRecognizer = new Pan({
direction: DIRECTION_ALL,
enable: !pressToActivate,
threshold: 0,
});
this._mc.add(panRecognizer);
this._mc.add(new Tap({ event: "singletap" }));
this._mc.on("press", (e) => {
e.srcEvent.stopPropagation();
e.srcEvent.preventDefault();
if (this.disabled || this.readonly) return;
const percentage = this._getPercentageFromEvent(e);
const raw = this._percentageToValue(percentage);
this._activeSlider = this._findActiveSlider(raw);
const bounded = this._boundedValue(raw);
this._setActiveValue(bounded);
const stepped = this._steppedValue(bounded);
if (this._activeSlider) {
fireEvent(this, `${this._activeSlider}-changing`, { value: stepped });
}
panRecognizer.set({ enable: true });
});
this._mc.on("pressup", (e) => {
e.srcEvent.stopPropagation();
e.srcEvent.preventDefault();
const percentage = this._getPercentageFromEvent(e);
const raw = this._percentageToValue(percentage);
const bounded = this._boundedValue(raw);
const stepped = this._steppedValue(bounded);
this._setActiveValue(stepped);
if (this._activeSlider) {
fireEvent(this, `${this._activeSlider}-changing`, {
value: undefined,
});
fireEvent(this, `${this._activeSlider}-changed`, { value: stepped });
}
this._activeSlider = undefined;
});
this._mc.on("pan", (e) => {
e.srcEvent.stopPropagation();
e.srcEvent.preventDefault();
@@ -271,6 +321,9 @@ export class HaControlCircularSlider extends LitElement {
this._mc.on("pancancel", () => {
if (this.disabled || this.readonly) return;
this._activeSlider = undefined;
if (pressToActivate) {
panRecognizer.set({ enable: false });
}
});
this._mc.on("panmove", (e) => {
if (this.disabled || this.readonly) return;
@@ -297,6 +350,9 @@ export class HaControlCircularSlider extends LitElement {
fireEvent(this, `${this._activeSlider}-changed`, { value: stepped });
}
this._activeSlider = undefined;
if (pressToActivate) {
panRecognizer.set({ enable: false });
}
});
this._mc.on("singletap", (e) => {
if (this.disabled || this.readonly) return;
@@ -315,6 +371,9 @@ export class HaControlCircularSlider extends LitElement {
this._lastSlider = this._activeSlider;
this.shadowRoot?.getElementById("#slider")?.focus();
this._activeSlider = undefined;
if (pressToActivate) {
panRecognizer.set({ enable: false });
}
});
}
}

View File

@@ -30,9 +30,9 @@ export class HaNumberSelector extends LitElement {
protected willUpdate(changedProps: PropertyValues) {
if (changedProps.has("value")) {
if (this.value !== Number(this._valueStr)) {
if (this._valueStr === "" || this.value !== Number(this._valueStr)) {
this._valueStr =
!this.value || isNaN(this.value) ? "" : this.value.toString();
this.value == null || isNaN(this.value) ? "" : this.value.toString();
}
}
}

View File

@@ -597,9 +597,9 @@ export class HaServiceControl extends LitElement {
);
}
target = {
entity_id: targetEntities,
device_id: targetDevices,
area_id: targetAreas,
...(targetEntities.length ? { entity_id: targetEntities } : {}),
...(targetDevices.length ? { device_id: targetDevices } : {}),
...(targetAreas.length ? { area_id: targetAreas } : {}),
};
}
}

View File

@@ -58,6 +58,7 @@ class DialogMediaPlayerBrowse extends LitElement {
this._navigateIds = undefined;
this._currentItem = undefined;
this._preferredLayout = "auto";
this.classList.remove("opened");
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -79,6 +80,7 @@ class DialogMediaPlayerBrowse extends LitElement {
)
: this._currentItem.title}
@closed=${this.closeDialog}
@opened=${this._dialogOpened}
>
<ha-dialog-header show-border slot="heading">
${this._navigateIds.length > 1
@@ -167,6 +169,10 @@ class DialogMediaPlayerBrowse extends LitElement {
`;
}
private _dialogOpened() {
this.classList.add("opened");
}
private async _handleMenuAction(ev: CustomEvent<ActionDetail>) {
switch (ev.detail.index) {
case 0:
@@ -217,10 +223,13 @@ class DialogMediaPlayerBrowse extends LitElement {
ha-media-player-browse {
--media-browser-max-height: calc(100vh - 65px);
height: calc(100vh - 65px);
direction: ltr;
}
:host(.opened) ha-media-player-browse {
height: calc(100vh - 65px);
}
@media (min-width: 800px) {
ha-dialog {
--mdc-dialog-max-width: 800px;
@@ -231,7 +240,6 @@ class DialogMediaPlayerBrowse extends LitElement {
ha-media-player-browse {
position: initial;
--media-browser-max-height: 100vh - 137px;
height: 100vh - 137px;
width: 700px;
}
}

View File

@@ -1,3 +1,6 @@
import { formatDuration } from "../common/datetime/duration";
import { FrontendLocaleData } from "./translation";
export const STATE_ATTRIBUTES = [
"entity_id",
"assumed_state",
@@ -64,6 +67,7 @@ export const DOMAIN_ATTRIBUTES_UNITS = {
color_temp_kelvin: "K",
min_color_temp_kelvin: "K",
max_color_temp_kelvin: "K",
brightness: "%",
},
sun: {
elevation: "°",
@@ -74,4 +78,22 @@ export const DOMAIN_ATTRIBUTES_UNITS = {
sensor: {
battery_level: "%",
},
media_player: {
volume_level: "%",
},
} as const satisfies Record<string, Record<string, string>>;
type Formatter = (value: number, locale: FrontendLocaleData) => string;
export const DOMAIN_ATTRIBUTES_FORMATERS: Record<
string,
Record<string, Formatter>
> = {
light: {
brightness: (value) => Math.round((value / 255) * 100).toString(),
},
media_player: {
volume_level: (value) => Math.round(value * 100).toString(),
media_duration: (value) => formatDuration(value.toString(), "s"),
},
};

View File

@@ -425,13 +425,6 @@ class DataEntryFlowDialog extends LitElement {
);
}
);
if (this._step?.flow_id) {
await this._unsubDataEntryFlowProgressed;
// fetch flow after we subscribe to the event, so we don't miss the first event
this._processStep(
this._params!.flowConfig.fetchFlow(this.hass, this._step.flow_id)
);
}
}
static get styles(): CSSResultGroup {

View File

@@ -103,8 +103,10 @@ class MoreInfoUpdate extends LitElement {
: ""}
${supportsFeature(this.stateObj!, UPDATE_SUPPORT_RELEASE_NOTES) &&
!this._error
? this._releaseNotes === undefined
? html`<ha-circular-progress indeterminate></ha-circular-progress>`
? !this._releaseNotes
? html`<div class="flex center">
<ha-circular-progress indeterminate></ha-circular-progress>
</div>`
: html`<hr />
<ha-faded>
<ha-markdown .content=${this._releaseNotes}></ha-markdown>
@@ -254,9 +256,10 @@ class MoreInfoUpdate extends LitElement {
a {
color: var(--primary-color);
}
ha-circular-progress {
width: 100%;
.flex.center {
display: flex;
justify-content: center;
align-items: center;
}
mwc-linear-progress {
margin-bottom: -8px;

View File

@@ -26,7 +26,8 @@
width: 100%;
max-width: 400px;
margin: 0 auto;
box-sizing: border-box;
padding: 0 16px;
box-sizing: content-box;
}
.header {
@@ -40,12 +41,6 @@
height: 56px;
width: 56px;
}
@media (max-width: 592px) {
.content {
margin: 0 16px;
}
}
</style>
</head>
<body>

View File

@@ -22,7 +22,8 @@
.content {
max-width: 560px;
margin: 0 auto;
box-sizing: border-box;
padding: 0 16px;
box-sizing: content-box;
}
.header {
@@ -36,12 +37,6 @@
height: 56px;
width: 56px;
}
@media (max-width: 592px) {
.content {
margin: 0 16px;
}
}
</style>
</head>
<body id="particles">

View File

@@ -449,7 +449,9 @@ class AddIntegrationDialog extends LitElement {
>
</lit-virtualizer>
</mwc-list>`
: html`<ha-circular-progress indeterminate></ha-circular-progress>`} `;
: html`<div class="flex center">
<ha-circular-progress indeterminate></ha-circular-progress>
</div>`} `;
}
private _keyFunction = (integration: IntegrationListItem) =>
@@ -682,10 +684,12 @@ class AddIntegrationDialog extends LitElement {
p > a {
color: var(--primary-color);
}
ha-circular-progress {
width: 100%;
.flex.center {
display: flex;
justify-content: center;
align-items: center;
}
ha-circular-progress {
margin: 24px 0;
}
mwc-list {

View File

@@ -236,7 +236,7 @@ class ZHAAddDevicesPage extends LitElement {
color: var(--error-color);
}
ha-circular-progress {
padding: 20px;
margin: 20px;
}
.searching {
margin-top: 20px;

View File

@@ -1,11 +1,15 @@
import { mdiThermostat } from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { customElement, property, query, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
import { stopPropagation } from "../../../common/dom/stop_propagation";
import { computeDomain } from "../../../common/entity/compute_domain";
import { stateColorCss } from "../../../common/entity/state_color";
import "../../../components/ha-control-select";
import "../../../components/ha-control-select-menu";
import type { ControlSelectOption } from "../../../components/ha-control-select";
import type { HaControlSelectMenu } from "../../../components/ha-control-select-menu";
import {
ClimateEntity,
compareClimateHvacModes,
@@ -35,6 +39,9 @@ class HuiClimateHvacModesCardFeature
@state() _currentHvacMode?: HvacMode;
@query("ha-control-select-menu", true)
private _haSelect?: HaControlSelectMenu;
static getStubConfig(
_,
stateObj?: HassEntity
@@ -66,8 +73,23 @@ class HuiClimateHvacModesCardFeature
}
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
if (this._haSelect && changedProps.has("hass")) {
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
if (
this.hass &&
this.hass.formatEntityAttributeValue !==
oldHass?.formatEntityAttributeValue
) {
this._haSelect.layoutOptions();
}
}
}
private async _valueChanged(ev: CustomEvent) {
const mode = (ev.detail as any).value as HvacMode;
const mode =
(ev.detail as any).value ?? ((ev.target as any).value as HvacMode);
if (mode === this.stateObj!.state) return;
@@ -111,6 +133,37 @@ class HuiClimateHvacModesCardFeature
path: computeHvacModeIcon(mode),
}));
if (this._config.style === "dropdown") {
return html`
<div class="container">
<ha-control-select-menu
show-arrow
hide-label
.label=${this.hass.localize("ui.card.climate.mode")}
.value=${this._currentHvacMode}
.disabled=${this.stateObj.state === UNAVAILABLE}
fixedMenuPosition
naturalMenuWidth
@selected=${this._valueChanged}
@closed=${stopPropagation}
>
<ha-svg-icon slot="icon" .path=${mdiThermostat}></ha-svg-icon>
${options.map(
(option) => html`
<ha-list-item .value=${option.value} graphic="icon">
<ha-svg-icon
slot="graphic"
.path=${option.path}
></ha-svg-icon>
${option.label}
</ha-list-item>
`
)}
</ha-control-select-menu>
</div>
`;
}
return html`
<div class="container">
<ha-control-select
@@ -131,6 +184,14 @@ class HuiClimateHvacModesCardFeature
static get styles() {
return css`
ha-control-select-menu {
box-sizing: border-box;
--control-select-menu-height: 40px;
--control-select-menu-border-radius: 10px;
line-height: 1.2;
display: block;
width: 100%;
}
ha-control-select {
--control-select-padding: 0;
--control-select-thickness: 40px;

View File

@@ -37,6 +37,7 @@ export interface AlarmModesCardFeatureConfig {
export interface ClimateHvacModesCardFeatureConfig {
type: "climate-hvac-modes";
style?: "dropdown" | "icons";
hvac_modes?: HvacMode[];
}

View File

@@ -127,6 +127,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
<ha-card>
<p class="title">${name}</p>
<ha-state-control-humidifier-humidity
prevent-interaction-on-scroll
show-current
.hass=${this.hass}
.stateObj=${stateObj}
@@ -168,11 +169,14 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
.title {
width: 100%;
font-size: 18px;
line-height: 24px;
padding: 12px 36px 16px 36px;
line-height: 36px;
padding: 8px 30px 8px 30px;
margin: 0;
text-align: center;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
ha-state-control-humidifier-humidity {
@@ -180,7 +184,6 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
max-width: 344px; /* 12px + 12px + 320px */
padding: 0 12px 12px 12px;
box-sizing: border-box;
--interaction-margin: 0px;
}
.more-info {

View File

@@ -59,7 +59,7 @@ export class HuiStartingCard extends LitElement implements LovelaceCard {
height: calc(100vh - var(--header-height));
}
ha-circular-progress {
padding-bottom: 20px;
margin-bottom: 20px;
}
.content {
height: 100%;

View File

@@ -119,6 +119,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
<ha-card>
<p class="title">${name}</p>
<ha-state-control-climate-temperature
prevent-interaction-on-scroll
show-current
.hass=${this.hass}
.stateObj=${stateObj}
@@ -160,11 +161,14 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
.title {
width: 100%;
font-size: 18px;
line-height: 24px;
padding: 12px 36px 16px 36px;
line-height: 36px;
padding: 8px 30px 8px 30px;
margin: 0;
text-align: center;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
ha-state-control-climate-temperature {
@@ -172,7 +176,6 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
max-width: 344px; /* 12px + 12px + 320px */
padding: 0 12px 12px 12px;
box-sizing: border-box;
--interaction-margin: 0px;
}
.more-info {

View File

@@ -310,24 +310,22 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
if (!stateObj) {
return html`
<ha-card>
<div class="tile">
<div class="content ${classMap(contentClasses)}">
<div class="icon-container">
<ha-tile-icon class="icon" .iconPath=${mdiHelp}></ha-tile-icon>
<ha-tile-badge
class="badge"
.iconPath=${mdiExclamationThick}
style=${styleMap({
"--tile-badge-background-color": `var(--red-color)`,
})}
></ha-tile-badge>
</div>
<ha-tile-info
class="info"
.primary=${entityId}
secondary=${this.hass.localize("ui.card.tile.not_found")}
></ha-tile-info>
<div class="content ${classMap(contentClasses)}">
<div class="icon-container">
<ha-tile-icon class="icon" .iconPath=${mdiHelp}></ha-tile-icon>
<ha-tile-badge
class="badge"
.iconPath=${mdiExclamationThick}
style=${styleMap({
"--tile-badge-background-color": `var(--red-color)`,
})}
></ha-tile-badge>
</div>
<ha-tile-info
class="info"
.primary=${entityId}
secondary=${this.hass.localize("ui.card.tile.not_found")}
></ha-tile-info>
</div>
</ha-card>
`;
@@ -359,73 +357,71 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
return html`
<ha-card style=${styleMap(style)} class=${classMap({ active })}>
<div class="tile">
<div
class="background"
@action=${this._handleAction}
.actionHandler=${actionHandler({
hasHold: hasAction(this._config!.hold_action),
hasDoubleClick: hasAction(this._config!.double_tap_action),
})}
role="button"
tabindex="0"
aria-labelledby="info"
@mousedown=${this.handleRippleActivate}
@mouseup=${this.handleRippleDeactivate}
@mouseenter=${this.handleRippleMouseEnter}
@mouseleave=${this.handleRippleMouseLeave}
@touchstart=${this.handleRippleActivate}
@touchend=${this.handleRippleDeactivate}
@touchcancel=${this.handleRippleDeactivate}
>
${this._shouldRenderRipple
? html`<mwc-ripple></mwc-ripple>`
: nothing}
</div>
<div class="content ${classMap(contentClasses)}">
<div
class="background"
@action=${this._handleAction}
.actionHandler=${actionHandler({
hasHold: hasAction(this._config!.hold_action),
hasDoubleClick: hasAction(this._config!.double_tap_action),
})}
class="icon-container"
role="button"
tabindex="0"
aria-labelledby="info"
@mousedown=${this.handleRippleActivate}
@mouseup=${this.handleRippleDeactivate}
@mouseenter=${this.handleRippleMouseEnter}
@mouseleave=${this.handleRippleMouseLeave}
@touchstart=${this.handleRippleActivate}
@touchend=${this.handleRippleDeactivate}
@touchcancel=${this.handleRippleDeactivate}
@action=${this._handleIconAction}
.actionHandler=${actionHandler()}
>
${this._shouldRenderRipple
? html`<mwc-ripple></mwc-ripple>`
${imageUrl
? html`
<ha-tile-image
class="icon"
.imageUrl=${imageUrl}
></ha-tile-image>
`
: html`
<ha-tile-icon
data-domain=${ifDefined(domain)}
data-state=${ifDefined(stateObj?.state)}
class="icon"
.icon=${icon}
.iconPath=${iconPath}
></ha-tile-icon>
`}
${badge
? html`
<ha-tile-badge
class="badge"
.icon=${badge.icon}
.iconPath=${badge.iconPath}
style=${styleMap({
"--tile-badge-background-color": badge.color,
})}
></ha-tile-badge>
`
: nothing}
</div>
<div class="content ${classMap(contentClasses)}">
<div
class="icon-container"
role="button"
tabindex="0"
@action=${this._handleIconAction}
.actionHandler=${actionHandler()}
>
${imageUrl
? html`
<ha-tile-image
class="icon"
.imageUrl=${imageUrl}
></ha-tile-image>
`
: html`
<ha-tile-icon
data-domain=${ifDefined(domain)}
data-state=${ifDefined(stateObj?.state)}
class="icon"
.icon=${icon}
.iconPath=${iconPath}
></ha-tile-icon>
`}
${badge
? html`
<ha-tile-badge
class="badge"
.icon=${badge.icon}
.iconPath=${badge.iconPath}
style=${styleMap({
"--tile-badge-background-color": badge.color,
})}
></ha-tile-badge>
`
: nothing}
</div>
<ha-tile-info
id="info"
class="info"
.primary=${name}
.secondary=${localizedState}
></ha-tile-info>
</div>
<ha-tile-info
id="info"
class="info"
.primary=${name}
.secondary=${localizedState}
></ha-tile-info>
</div>
<hui-card-features
.hass=${this.hass}
@@ -472,7 +468,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
bottom: 0;
right: 0;
border-radius: var(--ha-card-border-radius, 12px);
inset: calc(-1 * var(--ha-card-border-width, 1px));
margin: calc(-1 * var(--ha-card-border-width, 1px));
overflow: hidden;
}
.content {

View File

@@ -143,12 +143,26 @@ export const computeCards = (
const cardConfig: ThermostatCardConfig = {
type: "thermostat",
entity: entityId,
features:
(states[entityId]?.attributes?.hvac_modes?.length ?? 0) > 1
? [
{
type: "climate-hvac-modes",
hvac_modes: states[entityId]?.attributes?.hvac_modes,
},
]
: undefined,
};
cards.push(cardConfig);
} else if (domain === "humidifier") {
const cardConfig: HumidifierCardConfig = {
type: "humidifier",
entity: entityId,
features: [
{
type: "humidifier-toggle",
},
],
};
cards.push(cardConfig);
} else if (domain === "media_player") {

View File

@@ -4,6 +4,7 @@ import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../common/dom/fire_event";
import type { FormatEntityStateFunc } from "../../../../common/translations/entity-state";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import "../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../components/ha-form/types";
import { HVAC_MODES } from "../../../../data/climate";
@@ -30,8 +31,27 @@ export class HuiClimateHvacModesCardFeatureEditor
}
private _schema = memoizeOne(
(formatEntityState: FormatEntityStateFunc, stateObj?: HassEntity) =>
(
localize: LocalizeFunc,
formatEntityState: FormatEntityStateFunc,
stateObj?: HassEntity
) =>
[
{
name: "style",
selector: {
select: {
multiple: false,
mode: "list",
options: ["dropdown", "icons"].map((mode) => ({
value: mode,
label: localize(
`ui.panel.lovelace.editor.features.types.climate-preset-modes.style_list.${mode}`
),
})),
},
},
},
{
name: "hvac_modes",
selector: {
@@ -59,12 +79,22 @@ export class HuiClimateHvacModesCardFeatureEditor
? this.hass.states[this.context?.entity_id]
: undefined;
const schema = this._schema(this.hass.formatEntityState, stateObj);
const data: ClimateHvacModesCardFeatureConfig = {
style: "icons",
hvac_modes: [],
...this._config,
};
const schema = this._schema(
this.hass.localize,
this.hass.formatEntityState,
stateObj
);
return html`
<ha-form
.hass=${this.hass}
.data=${this._config}
.data=${data}
.schema=${schema}
.computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged}
@@ -81,13 +111,12 @@ export class HuiClimateHvacModesCardFeatureEditor
) => {
switch (schema.name) {
case "hvac_modes":
case "style":
return this.hass!.localize(
`ui.panel.lovelace.editor.features.types.climate-hvac-modes.${schema.name}`
);
default:
return this.hass!.localize(
`ui.panel.lovelace.editor.card.generic.${schema.name}`
);
return "";
}
};
}

View File

@@ -9,6 +9,7 @@ import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
import type { HomeAssistant } from "../../../../types";
import type { LovelaceGenericElementEditor } from "../../types";
import { configElementStyle } from "./config-elements-style";
import { computeInitialHaFormData } from "../../../../components/ha-form/compute-initial-ha-form-data";
@customElement("hui-form-editor")
export class HuiFormEditor
@@ -27,7 +28,7 @@ export class HuiFormEditor
public setConfig(config: LovelaceCardConfig): void {
this.assertConfig(config);
this._config = config;
this._config = { ...computeInitialHaFormData(this.schema), ...config };
}
protected render() {

View File

@@ -46,7 +46,10 @@ import { HuiErrorCard } from "../lovelace/cards/hui-error-card";
import { createCardElement } from "../lovelace/create-element/create-card-element";
import { LovelaceCard } from "../lovelace/types";
import { navigate } from "../../common/navigate";
import { createSearchParam } from "../../common/url/search-params";
import {
createSearchParam,
extractSearchParam,
} from "../../common/url/search-params";
import { constructUrlCurrentPath } from "../../common/url/construct-url";
@customElement("ha-panel-todo")
@@ -105,18 +108,21 @@ class PanelTodo extends LitElement {
if (!this.hasUpdated) {
this.hass.loadFragmentTranslation("lovelace");
const urlEntityId = extractSearchParam("entity_id");
if (urlEntityId) {
this._entityId = urlEntityId;
} else {
if (this._entityId && !(this._entityId in this.hass.states)) {
this._entityId = undefined;
}
if (!this._entityId) {
this._entityId = getTodoLists(this.hass)[0]?.entity_id;
}
}
}
if (!this.hasUpdated && !this._entityId) {
this._entityId = getTodoLists(this.hass)[0]?.entity_id;
} else if (!this.hasUpdated) {
this._setupTodoElement();
}
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (changedProperties.has("_entityId")) {
if (changedProperties.has("_entityId") || !this.hasUpdated) {
this._setupTodoElement();
}

View File

@@ -1,7 +1,6 @@
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { stateActive } from "../../common/entity/state_active";
import { domainStateColorProperties } from "../../common/entity/state_color";
@@ -30,6 +29,9 @@ export class HaStateControlClimateHumidity extends LitElement {
@property({ attribute: "show-current", type: Boolean })
public showCurrent?: boolean;
@property({ type: Boolean, attribute: "prevent-interaction-on-scroll" })
public preventInteractionOnScroll?: boolean;
@state() private _targetHumidity?: number;
private _sizeController = createStateControlCircularSliderController(this);
@@ -95,6 +97,12 @@ export class HaStateControlClimateHumidity extends LitElement {
`;
}
if (!this._targetHumidity) {
return html`
<p class="label">${this.hass.formatEntityState(this.stateObj)}</p>
`;
}
return html`
<p class="label">
${this.hass.localize("ui.card.climate.humidity_target")}
@@ -176,8 +184,8 @@ export class HaStateControlClimateHumidity extends LitElement {
const currentHumidity = this.stateObj.attributes.current_humidity;
const containerSizeClass = this._sizeController.value
? { [this._sizeController.value]: true }
: {};
? ` ${this._sizeController.value}`
: "";
if (
supportsTargetHumidity &&
@@ -186,12 +194,13 @@ export class HaStateControlClimateHumidity extends LitElement {
) {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.inactive=${!active}
.value=${this._targetHumidity}
.min=${this._min}
@@ -214,8 +223,9 @@ export class HaStateControlClimateHumidity extends LitElement {
}
return html`
<div class="container${classMap(containerSizeClass)}">
<div class="container${containerSizeClass}">
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.current=${this.stateObj.attributes.current_humidity}
.min=${this._min}
.max=${this._max}

View File

@@ -48,6 +48,9 @@ export class HaStateControlClimateTemperature extends LitElement {
@property({ attribute: "show-current", type: Boolean })
public showCurrent?: boolean;
@property({ type: Boolean, attribute: "prevent-interaction-on-scroll" })
public preventInteractionOnScroll?: boolean;
@state() private _targetTemperature: Partial<Record<Target, number>> = {};
@state() private _selectTargetTemperature: Target = "low";
@@ -161,14 +164,17 @@ export class HaStateControlClimateTemperature extends LitElement {
}
if (
!supportsFeature(
(!supportsFeature(
this.stateObj,
ClimateEntityFeature.TARGET_TEMPERATURE
) &&
!supportsFeature(
) ||
this._targetTemperature.value === null) &&
(!supportsFeature(
this.stateObj,
ClimateEntityFeature.TARGET_TEMPERATURE_RANGE
)
) ||
this._targetTemperature.low === null ||
this._targetTemperature.high === null)
) {
return html`
<p class="label">${this.hass.formatEntityState(this.stateObj)}</p>
@@ -291,8 +297,8 @@ export class HaStateControlClimateTemperature extends LitElement {
}
const containerSizeClass = this._sizeController.value
? { [this._sizeController.value]: true }
: {};
? ` ${this._sizeController.value}`
: "";
if (
supportsTargetTemperature &&
@@ -311,13 +317,14 @@ export class HaStateControlClimateTemperature extends LitElement {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
"--action-color": actionColor,
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.inactive=${!active}
.mode=${sliderMode}
.value=${this._targetTemperature.value}
@@ -349,7 +356,7 @@ export class HaStateControlClimateTemperature extends LitElement {
) {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--low-color": lowColor,
"--high-color": highColor,
@@ -357,6 +364,7 @@ export class HaStateControlClimateTemperature extends LitElement {
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.inactive=${!active}
dual
.low=${this._targetTemperature.low}
@@ -412,6 +420,7 @@ export class HaStateControlClimateTemperature extends LitElement {
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
mode="full"
.current=${this.stateObj.attributes.current_temperature}
.min=${this._min}

View File

@@ -1,7 +1,6 @@
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { stateActive } from "../../common/entity/state_active";
import { stateColorCss } from "../../common/entity/state_color";
@@ -32,6 +31,9 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@property({ attribute: "show-current", type: Boolean })
public showCurrent?: boolean = false;
@property({ type: Boolean, attribute: "prevent-interaction-on-scroll" })
public preventInteractionOnScroll?: boolean;
@state() private _targetHumidity?: number;
private _sizeController = createStateControlCircularSliderController(this);
@@ -108,7 +110,9 @@ export class HaStateControlHumidifierHumidity extends LitElement {
<p class="label">
${action && action !== "off" && action !== "idle"
? actionLabel
: this.hass.localize("ui.card.humidifier.target")}
: this._targetHumidity
? this.hass.localize("ui.card.humidifier.target")
: this.hass.formatEntityState(this.stateObj)}
</p>
`;
}
@@ -185,8 +189,8 @@ export class HaStateControlHumidifierHumidity extends LitElement {
const currentHumidity = this.stateObj.attributes.current_humidity;
const containerSizeClass = this._sizeController.value
? { [this._sizeController.value]: true }
: {};
? ` ${this._sizeController.value}`
: "";
if (targetHumidity != null && this.stateObj.state !== UNAVAILABLE) {
const inverted =
@@ -195,13 +199,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
"--action-color": actionColor,
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.inactive=${!active}
.mode=${inverted ? "end" : "start"}
.value=${targetHumidity}
@@ -226,12 +231,13 @@ export class HaStateControlHumidifierHumidity extends LitElement {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--action-color": actionColor,
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.current=${currentHumidity}
.min=${this._min}
.max=${this._max}

View File

@@ -121,10 +121,6 @@ export const stateControlCircularSliderStyle = css`
ha-control-circular-slider {
width: 100%;
--control-circular-slider-color: var(--state-color, var(--disabled-color));
--control-circular-slider-interaction-margin: var(
--interaction-margin,
12px
);
}
ha-control-circular-slider::after {
display: block;

View File

@@ -1,7 +1,6 @@
import { mdiMinus, mdiPlus } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { UNIT_F } from "../../common/const";
import { stateActive } from "../../common/entity/state_active";
@@ -33,6 +32,9 @@ export class HaStateControlWaterHeaterTemperature extends LitElement {
@property({ attribute: "show-current", type: Boolean })
public showCurrent?: boolean;
@property({ type: Boolean, attribute: "prevent-interaction-on-scroll" })
public preventInteractionOnScroll?: boolean;
@state() private _targetTemperature?: number;
private _sizeController = createStateControlCircularSliderController(this);
@@ -105,7 +107,8 @@ export class HaStateControlWaterHeaterTemperature extends LitElement {
!supportsFeature(
this.stateObj,
WaterHeaterEntityFeature.TARGET_TEMPERATURE
)
) ||
!this._targetTemperature
) {
return html`
<p class="label">${this.hass.formatEntityState(this.stateObj)}</p>
@@ -181,8 +184,8 @@ export class HaStateControlWaterHeaterTemperature extends LitElement {
const active = stateActive(this.stateObj);
const containerSizeClass = this._sizeController.value
? { [this._sizeController.value]: true }
: {};
? ` ${this._sizeController.value}`
: "";
if (
supportsTargetTemperature &&
@@ -191,12 +194,13 @@ export class HaStateControlWaterHeaterTemperature extends LitElement {
) {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
.inactive=${!active}
.value=${this._targetTemperature}
.min=${this._min}
@@ -221,12 +225,13 @@ export class HaStateControlWaterHeaterTemperature extends LitElement {
return html`
<div
class="container${classMap(containerSizeClass)}"
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
})}
>
<ha-control-circular-slider
.preventInteractionOnScroll=${this.preventInteractionOnScroll}
mode="full"
.current=${this.stateObj.attributes.current_temperature}
.min=${this._min}

View File

@@ -5280,7 +5280,12 @@
},
"climate-hvac-modes": {
"label": "Climate HVAC modes",
"hvac_modes": "HVAC modes"
"hvac_modes": "HVAC modes",
"style": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style%]",
"style_list": {
"dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]",
"icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]"
}
},
"climate-preset-modes": {
"label": "Climate preset modes",

350
yarn.lock
View File

@@ -1442,10 +1442,10 @@ __metadata:
languageName: node
linkType: hard
"@braintree/sanitize-url@npm:6.0.4":
version: 6.0.4
resolution: "@braintree/sanitize-url@npm:6.0.4"
checksum: 52de7e19df29039134e2f0fbe6d11dbc15423d18799dc5306fbc2c92d6a7bd0e6c3c079c09be99260647cc85c3ca910e2099d819965a1d8604d05e5d3f3bb358
"@braintree/sanitize-url@npm:7.0.0":
version: 7.0.0
resolution: "@braintree/sanitize-url@npm:7.0.0"
checksum: 670e218cf1dbda1ceeedbb06487f4178848c681f0612468574688e02dcddd54456e85f94bc4a531faf2caaf01e3dbe164b0ef57188f9df21a4d4d58db099f0a5
languageName: node
linkType: hard
@@ -1521,10 +1521,10 @@ __metadata:
languageName: node
linkType: hard
"@codemirror/state@npm:6.3.2, @codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.4, @codemirror/state@npm:^6.2.0":
version: 6.3.2
resolution: "@codemirror/state@npm:6.3.2"
checksum: 6f46d7b3bf85d86383b8bc693d424734be247e2a6c22eb8979a1bdcb807895a6c39e81c9da361e10b210716b1a143517fdc6154261e4981118b31ed7ac328d51
"@codemirror/state@npm:6.3.3, @codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.4, @codemirror/state@npm:^6.2.0":
version: 6.3.3
resolution: "@codemirror/state@npm:6.3.3"
checksum: c0db0fc943ed36925238242522a8f4b2a4e3ecc4489cc013ea6d32be2bc615ecd813c98ff6a4c8f8ec1179376e555ec93a07dc1f0d1751aae721b5b38f812c08
languageName: node
linkType: hard
@@ -2153,10 +2153,10 @@ __metadata:
languageName: node
linkType: hard
"@lokalise/node-api@npm:12.0.0":
version: 12.0.0
resolution: "@lokalise/node-api@npm:12.0.0"
checksum: 78ac0c0f4e5c9f68fc20e01998feab4f043d32a651bd75c7c1eb3bbede63be01a1b806ae1ab14b75402aa43a79f6842628d42172c89471975631d464d2807bcd
"@lokalise/node-api@npm:12.1.0":
version: 12.1.0
resolution: "@lokalise/node-api@npm:12.1.0"
checksum: 6a5fed900b2cf22fd716eaac2f69897383d6cc77f9ccdf53fb8f6b48069ebeed086c2d52e5fbd535b21234de0721639b596e2790cd633cda4fe3c6c29337b5be
languageName: node
linkType: hard
@@ -4322,10 +4322,10 @@ __metadata:
languageName: node
linkType: hard
"@types/luxon@npm:3.3.6":
version: 3.3.6
resolution: "@types/luxon@npm:3.3.6"
checksum: e44e9d856b69d6832572d136cc3ae9e859828be1bea076f78c3f5f3163ec52adfaecf3b2b4ed2b27139fd64e8baaeef7a1425051767b66bc46ea60356bbc1282
"@types/luxon@npm:3.3.7":
version: 3.3.7
resolution: "@types/luxon@npm:3.3.7"
checksum: 282ac72fd55da0c9d57f376ba9061ce83506cf6239c32259dacde0800964089f6183d2e449ef2ddd89b079fb8bfdffd7e5dbf187eb5c9f106aeaeca2aa60ed09
languageName: node
linkType: hard
@@ -4567,15 +4567,15 @@ __metadata:
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/eslint-plugin@npm:6.13.1"
"@typescript-eslint/eslint-plugin@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/eslint-plugin@npm:6.13.2"
dependencies:
"@eslint-community/regexpp": "npm:^4.5.1"
"@typescript-eslint/scope-manager": "npm:6.13.1"
"@typescript-eslint/type-utils": "npm:6.13.1"
"@typescript-eslint/utils": "npm:6.13.1"
"@typescript-eslint/visitor-keys": "npm:6.13.1"
"@typescript-eslint/scope-manager": "npm:6.13.2"
"@typescript-eslint/type-utils": "npm:6.13.2"
"@typescript-eslint/utils": "npm:6.13.2"
"@typescript-eslint/visitor-keys": "npm:6.13.2"
debug: "npm:^4.3.4"
graphemer: "npm:^1.4.0"
ignore: "npm:^5.2.4"
@@ -4588,44 +4588,44 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: cae42c77404d8e6c149d68aca75bb3ce83cff5de8713d82e87e93bafae2839f29d261bc75b68f315b6b23858a85ea2f22ed8468cf5c7331e8330f7cee2129522
checksum: e6665fc5de0ae2b7ada9150d3d119157521a04208b8da385a4c39538b9471871efe6eef272dbcee4c76f599e09453b6f7317f3b3b80d89291f6b2ace4125c51b
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/parser@npm:6.13.1"
"@typescript-eslint/parser@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/parser@npm:6.13.2"
dependencies:
"@typescript-eslint/scope-manager": "npm:6.13.1"
"@typescript-eslint/types": "npm:6.13.1"
"@typescript-eslint/typescript-estree": "npm:6.13.1"
"@typescript-eslint/visitor-keys": "npm:6.13.1"
"@typescript-eslint/scope-manager": "npm:6.13.2"
"@typescript-eslint/types": "npm:6.13.2"
"@typescript-eslint/typescript-estree": "npm:6.13.2"
"@typescript-eslint/visitor-keys": "npm:6.13.2"
debug: "npm:^4.3.4"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
checksum: cdc328d157a8b8a6babad88360451c177ea41666e2150f3822a474ed287a12336517dccf9f475f75a007d4aa622cb74f1442f17d17b87e19cc2c839784742351
checksum: a2b32d2ad1aa12ce31790e80e059fd5b0699265541f3799b58f2e5c8b40f2e21ac7010519802bc406f4b74c14a1f52081570fa6119b949f68392d0968628b3b8
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/scope-manager@npm:6.13.1"
"@typescript-eslint/scope-manager@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/scope-manager@npm:6.13.2"
dependencies:
"@typescript-eslint/types": "npm:6.13.1"
"@typescript-eslint/visitor-keys": "npm:6.13.1"
checksum: f728dbd995c58fadfc390411fe31b1b8a729b1c85ecf0ae2fe70f97f613298feab78c05bc180e03612f595b24cf0090476a0b8234c617b3edf1dae568342a7cf
"@typescript-eslint/types": "npm:6.13.2"
"@typescript-eslint/visitor-keys": "npm:6.13.2"
checksum: a6505cc73e90dfed3b9b03816213610f05be58548f468ce24c05ce49a3c6d029ef02233db51cff3b780aa8d040a0c7b3268ea28244c704932c9ee6ef82088509
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/type-utils@npm:6.13.1"
"@typescript-eslint/type-utils@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/type-utils@npm:6.13.2"
dependencies:
"@typescript-eslint/typescript-estree": "npm:6.13.1"
"@typescript-eslint/utils": "npm:6.13.1"
"@typescript-eslint/typescript-estree": "npm:6.13.2"
"@typescript-eslint/utils": "npm:6.13.2"
debug: "npm:^4.3.4"
ts-api-utils: "npm:^1.0.1"
peerDependencies:
@@ -4633,23 +4633,23 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: 484e5f74fc604b24687fe6426e650f40f679d62216ee5e45bf6d1f91edd60cd8deef747ca43f7dc3c22b2b76f030477603c82559e44c3f2fb5c8877a0c65aefa
checksum: c8de5ab94295980a378e4f22dd51dedb3838761969ad1a355386a801c9bc332837651747cdc2edf7f399c88d0bbd787d2233d09e14e4e2849fb01a57bd0cab00
languageName: node
linkType: hard
"@typescript-eslint/types@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/types@npm:6.13.1"
checksum: 350c7f847052f7c24629d41645c02be152c512f3e5c21a79f53c04821b1fff3019416b18d9b72e5ca5c3c5f62f210301f2bb69080b84e67fe83af27751a7af18
"@typescript-eslint/types@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/types@npm:6.13.2"
checksum: 3ed2622468b2c61bff0828a3675357b498360bada85740dd72e4ec3c80ee112bce8808d7688aa0104b9d0a655a30e2deb0fee69468474c7e046fc9285f549fe6
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/typescript-estree@npm:6.13.1"
"@typescript-eslint/typescript-estree@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/typescript-estree@npm:6.13.2"
dependencies:
"@typescript-eslint/types": "npm:6.13.1"
"@typescript-eslint/visitor-keys": "npm:6.13.1"
"@typescript-eslint/types": "npm:6.13.2"
"@typescript-eslint/visitor-keys": "npm:6.13.2"
debug: "npm:^4.3.4"
globby: "npm:^11.1.0"
is-glob: "npm:^4.0.3"
@@ -4658,34 +4658,34 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: 1df965c5b202664da1a4a1ffc51bda3d85e581d8c206cd4be63653e2558775104258f6071e1f35a269619ebfb81bd18ee74e3fcb724fed15d3a2577d0ee5a34f
checksum: 8fa1344228858fa8171a9660e11eb0d5ed88de2ada343bce4a02a957724ccbeb9b67da1083eada29247f444aeba6908a4145d1758b528d320928abbb4e48dca7
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/utils@npm:6.13.1"
"@typescript-eslint/utils@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/utils@npm:6.13.2"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0"
"@types/json-schema": "npm:^7.0.12"
"@types/semver": "npm:^7.5.0"
"@typescript-eslint/scope-manager": "npm:6.13.1"
"@typescript-eslint/types": "npm:6.13.1"
"@typescript-eslint/typescript-estree": "npm:6.13.1"
"@typescript-eslint/scope-manager": "npm:6.13.2"
"@typescript-eslint/types": "npm:6.13.2"
"@typescript-eslint/typescript-estree": "npm:6.13.2"
semver: "npm:^7.5.4"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
checksum: 6fab1122071c7a2da959dcf16cdd723a65bd8ba8e55af9cea11bb1707c4d047e94c3daaed2ab504cdbd2ca0d052f2a33de5290b28de0277ba00210569673ac9b
checksum: 934282b612e5f78423bc375122258c5aec65fcdf9c25fd0521e3984686d1e5b950500f093c5f1c21a267be164bc7025d8f629dcfaa60573ad98c6e3861092076
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:6.13.1":
version: 6.13.1
resolution: "@typescript-eslint/visitor-keys@npm:6.13.1"
"@typescript-eslint/visitor-keys@npm:6.13.2":
version: 6.13.2
resolution: "@typescript-eslint/visitor-keys@npm:6.13.2"
dependencies:
"@typescript-eslint/types": "npm:6.13.1"
"@typescript-eslint/types": "npm:6.13.2"
eslint-visitor-keys: "npm:^3.4.1"
checksum: 27ccc4bfe940e50b0977838356b7feda95b68754fa544a988588a159a2619eb04d07c67e55d16bfea1b0dc6184a7fb5daff1366b266c9f5fd19d72831dea6163
checksum: eb6f3a3fa4dae6003533eac41bd2a8181a0353f352640e92b619e353b4bd5a5cd4c076018cbdf4b1ba45b826be0c1d15293d87e956fc9a8aa2fb8d8aa04a7c98
languageName: node
linkType: hard
@@ -5480,12 +5480,12 @@ __metadata:
languageName: node
linkType: hard
"ansi-escapes@npm:^5.0.0":
version: 5.0.0
resolution: "ansi-escapes@npm:5.0.0"
"ansi-escapes@npm:^6.2.0":
version: 6.2.0
resolution: "ansi-escapes@npm:6.2.0"
dependencies:
type-fest: "npm:^1.0.2"
checksum: cbfb95f9f6d8a1ffc89f50fcda3313effae2d9ac2f357f89f626815b4d95fdc3f10f74e0887614ff850d01f805b7505eb1e7ebfdd26144bbfc26c5de08e19195
type-fest: "npm:^3.0.0"
checksum: 442f91b04650b35bc4815f47c20412d69ddbba5d4bf22f72ec03be352fca2de6819c7e3f4dfd17816ee4e0c6c965fe85e6f1b3f09683996a8d12fd366afd924e
languageName: node
linkType: hard
@@ -5555,7 +5555,7 @@ __metadata:
languageName: node
linkType: hard
"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0":
"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1":
version: 6.2.1
resolution: "ansi-styles@npm:6.2.1"
checksum: 70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32
@@ -6514,12 +6514,12 @@ __metadata:
languageName: node
linkType: hard
"chart.js@npm:4.4.0":
version: 4.4.0
resolution: "chart.js@npm:4.4.0"
"chart.js@npm:4.4.1":
version: 4.4.1
resolution: "chart.js@npm:4.4.1"
dependencies:
"@kurkle/color": "npm:^0.3.0"
checksum: 5d60ae67e2ad7ba1026531be3c965a83f4b4213146b131aa041fcac846bd98bdfc38aeadc0d19c58f3a3ef689fb6acc014b8687665d38d4776b38351bf991de1
checksum: bb58247349ed04b6a38c4c4b45d953d87dab40ecd70dd796da302cbcebf866dfc1ecf7bd32d95ecb44b89dccf9a4cfc6ff84f74ba69b024be9b5bd19b2930fbc
languageName: node
linkType: hard
@@ -6634,13 +6634,13 @@ __metadata:
languageName: node
linkType: hard
"cli-truncate@npm:^3.1.0":
version: 3.1.0
resolution: "cli-truncate@npm:3.1.0"
"cli-truncate@npm:^4.0.0":
version: 4.0.0
resolution: "cli-truncate@npm:4.0.0"
dependencies:
slice-ansi: "npm:^5.0.0"
string-width: "npm:^5.0.0"
checksum: c3243e41974445691c63f8b405df1d5a24049dc33d324fe448dc572e561a7b772ae982692900b1a5960901cc4fc7def25a629b9c69a4208ee89d12ab3332617a
string-width: "npm:^7.0.0"
checksum: d5149175fd25ca985731bdeec46a55ec237475cf74c1a5e103baea696aceb45e372ac4acbaabf1316f06bd62e348123060f8191ffadfeedebd2a70a2a7fb199d
languageName: node
linkType: hard
@@ -7612,7 +7612,7 @@ __metadata:
languageName: node
linkType: hard
"emoji-regex@npm:^10.2.1":
"emoji-regex@npm:^10.2.1, emoji-regex@npm:^10.3.0":
version: 10.3.0
resolution: "emoji-regex@npm:10.3.0"
checksum: b9b084ebe904f13bb4b66ee4c29fb41a7a4a1165adcc33c1ce8056c0194b882cc91ebdc782f1a779b5d7ea7375c5064643a7734893d7c657b44c5c6b9d7bf1e7
@@ -7927,14 +7927,14 @@ __metadata:
languageName: node
linkType: hard
"eslint-config-prettier@npm:9.0.0":
version: 9.0.0
resolution: "eslint-config-prettier@npm:9.0.0"
"eslint-config-prettier@npm:9.1.0":
version: 9.1.0
resolution: "eslint-config-prettier@npm:9.1.0"
peerDependencies:
eslint: ">=7.0.0"
bin:
eslint-config-prettier: bin/cli.js
checksum: 276b0b5b5b19066962a9ff3a16a553bdad28e1c0a2ea33a1d75d65c0428bb7b37f6e85ac111ebefcc9bdefb544385856dbe6eaeda5279c639e5549c113d27dda
checksum: 411e3b3b1c7aa04e3e0f20d561271b3b909014956c4dba51c878bf1a23dbb8c800a3be235c46c4732c70827276e540b6eed4636d9b09b444fd0a8e07f0fcd830
languageName: node
linkType: hard
@@ -9023,6 +9023,13 @@ __metadata:
languageName: node
linkType: hard
"get-east-asian-width@npm:^1.0.0":
version: 1.2.0
resolution: "get-east-asian-width@npm:1.2.0"
checksum: c9b280e7c7c67fb89fa17e867c4a9d1c9f1321aba2a9ee27bff37fb6ca9552bccda328c70a80c1f83a0e39ba1b7e3427e60f47823402d19e7a41b83417ec047a
languageName: node
linkType: hard
"get-func-name@npm:^2.0.1, get-func-name@npm:^2.0.2":
version: 2.0.2
resolution: "get-func-name@npm:2.0.2"
@@ -9573,10 +9580,10 @@ __metadata:
languageName: node
linkType: hard
"hls.js@npm:1.4.12":
version: 1.4.12
resolution: "hls.js@npm:1.4.12"
checksum: c27e968605abc0b65e2d102814c3a6bbcf139fed0c4800484afedf869a2101be2426aed374378c716baa7f2b84a58e2506d10d0ce2ff9e5f2809371a82147db0
"hls.js@npm:1.4.13":
version: 1.4.13
resolution: "hls.js@npm:1.4.13"
checksum: 8d54aaeaa6f396be85e0dde4fe6b6e6c0f8a60d821a581aa465ce63041a31bc553af154dd945b3da854a24e626cbd1e7667f7922452ccdab9e5f2984071f7aac
languageName: node
linkType: hard
@@ -9591,14 +9598,14 @@ __metadata:
"@babel/preset-env": "npm:7.23.5"
"@babel/preset-typescript": "npm:7.23.3"
"@babel/runtime": "npm:7.23.5"
"@braintree/sanitize-url": "npm:6.0.4"
"@braintree/sanitize-url": "npm:7.0.0"
"@bundle-stats/plugin-webpack-filter": "npm:4.8.3"
"@codemirror/autocomplete": "npm:6.11.1"
"@codemirror/commands": "npm:6.3.2"
"@codemirror/language": "npm:6.9.3"
"@codemirror/legacy-modes": "npm:6.3.3"
"@codemirror/search": "npm:6.5.5"
"@codemirror/state": "npm:6.3.2"
"@codemirror/state": "npm:6.3.3"
"@codemirror/view": "npm:6.22.1"
"@egjs/hammerjs": "npm:2.0.17"
"@formatjs/intl-datetimeformat": "npm:6.12.0"
@@ -9621,7 +9628,7 @@ __metadata:
"@lit-labs/motion": "npm:1.0.6"
"@lit-labs/observers": "npm:2.0.2"
"@lit-labs/virtualizer": "npm:2.0.11"
"@lokalise/node-api": "npm:12.0.0"
"@lokalise/node-api": "npm:12.1.0"
"@lrnwebcomponents/simple-tooltip": "npm:7.0.18"
"@material/chips": "npm:=14.0.0-canary.53b3cad2f.0"
"@material/data-table": "npm:=14.0.0-canary.53b3cad2f.0"
@@ -9675,7 +9682,7 @@ __metadata:
"@types/js-yaml": "npm:4.0.9"
"@types/leaflet": "npm:1.9.8"
"@types/leaflet-draw": "npm:1.0.11"
"@types/luxon": "npm:3.3.6"
"@types/luxon": "npm:3.3.7"
"@types/mocha": "npm:10.0.6"
"@types/qrcode": "npm:1.5.5"
"@types/serve-handler": "npm:6.1.4"
@@ -9683,8 +9690,8 @@ __metadata:
"@types/tar": "npm:6.1.10"
"@types/ua-parser-js": "npm:0.7.39"
"@types/webspeechapi": "npm:0.0.29"
"@typescript-eslint/eslint-plugin": "npm:6.13.1"
"@typescript-eslint/parser": "npm:6.13.1"
"@typescript-eslint/eslint-plugin": "npm:6.13.2"
"@typescript-eslint/parser": "npm:6.13.2"
"@vaadin/combo-box": "npm:24.2.5"
"@vaadin/vaadin-themable-mixin": "npm:24.2.5"
"@vibrant/color": "npm:3.2.1-alpha.1"
@@ -9699,7 +9706,7 @@ __metadata:
babel-loader: "npm:9.1.3"
babel-plugin-template-html-minifier: "npm:4.1.0"
chai: "npm:4.3.10"
chart.js: "npm:4.4.0"
chart.js: "npm:4.4.1"
comlink: "npm:4.4.1"
core-js: "npm:3.33.3"
cropperjs: "npm:1.6.1"
@@ -9712,7 +9719,7 @@ __metadata:
eslint: "npm:8.55.0"
eslint-config-airbnb-base: "npm:15.0.0"
eslint-config-airbnb-typescript: "npm:17.1.0"
eslint-config-prettier: "npm:9.0.0"
eslint-config-prettier: "npm:9.1.0"
eslint-import-resolver-webpack: "npm:0.13.8"
eslint-plugin-disable: "npm:2.0.3"
eslint-plugin-import: "npm:2.29.0"
@@ -9731,7 +9738,7 @@ __metadata:
gulp-merge-json: "npm:2.1.2"
gulp-rename: "npm:2.0.0"
gulp-zopfli-green: "npm:6.0.1"
hls.js: "npm:1.4.12"
hls.js: "npm:1.4.13"
home-assistant-js-websocket: "npm:9.1.0"
html-minifier-terser: "npm:7.2.0"
husky: "npm:8.0.3"
@@ -9742,14 +9749,14 @@ __metadata:
jszip: "npm:3.10.1"
leaflet: "npm:1.9.4"
leaflet-draw: "npm:1.0.4"
lint-staged: "npm:15.1.0"
lint-staged: "npm:15.2.0"
lit: "npm:2.8.0"
lit-analyzer: "npm:2.0.1"
lodash.template: "npm:4.5.0"
luxon: "npm:3.4.4"
magic-string: "npm:0.30.5"
map-stream: "npm:0.0.7"
marked: "npm:11.0.0"
marked: "npm:11.0.1"
memoize-one: "npm:6.0.0"
mocha: "npm:10.2.0"
node-vibrant: "npm:3.2.1-alpha.1"
@@ -9765,7 +9772,7 @@ __metadata:
rollup: "npm:2.79.1"
rollup-plugin-string: "npm:3.0.0"
rollup-plugin-terser: "npm:7.0.2"
rollup-plugin-visualizer: "npm:5.9.3"
rollup-plugin-visualizer: "npm:5.10.0"
rrule: "npm:2.8.1"
serve-handler: "npm:6.1.5"
sinon: "npm:17.0.1"
@@ -9780,7 +9787,7 @@ __metadata:
ts-lit-plugin: "npm:2.0.1"
tsparticles-engine: "npm:2.12.0"
tsparticles-preset-links: "npm:2.12.0"
typescript: "npm:5.3.2"
typescript: "npm:5.3.3"
ua-parser-js: "npm:1.0.37"
unfetch: "npm:5.0.0"
vinyl-buffer: "npm:1.0.1"
@@ -10494,6 +10501,15 @@ __metadata:
languageName: node
linkType: hard
"is-fullwidth-code-point@npm:^5.0.0":
version: 5.0.0
resolution: "is-fullwidth-code-point@npm:5.0.0"
dependencies:
get-east-asian-width: "npm:^1.0.0"
checksum: 8dfb2d2831b9e87983c136f5c335cd9d14c1402973e357a8ff057904612ed84b8cba196319fabedf9aefe4639e14fe3afe9d9966d1d006ebeb40fe1fed4babe5
languageName: node
linkType: hard
"is-function@npm:^1.0.1":
version: 1.0.2
resolution: "is-function@npm:1.0.2"
@@ -11332,44 +11348,44 @@ __metadata:
languageName: node
linkType: hard
"lilconfig@npm:2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
checksum: b1314a2e55319013d5e7d7d08be39015829d2764a1eaee130129545d40388499d81b1c31b0f9b3417d4db12775a88008b72ec33dd06e0184cf7503b32ca7cc0b
"lilconfig@npm:3.0.0":
version: 3.0.0
resolution: "lilconfig@npm:3.0.0"
checksum: 55f60f4f9f7b41358cc33875e3696919412683a35aec30c6c60c4f6ecb16fb6d11f7ac856b8458b9b82b21d5f4629649fbfca1de034e8d5b0cc7a70836266db6
languageName: node
linkType: hard
"lint-staged@npm:15.1.0":
version: 15.1.0
resolution: "lint-staged@npm:15.1.0"
"lint-staged@npm:15.2.0":
version: 15.2.0
resolution: "lint-staged@npm:15.2.0"
dependencies:
chalk: "npm:5.3.0"
commander: "npm:11.1.0"
debug: "npm:4.3.4"
execa: "npm:8.0.1"
lilconfig: "npm:2.1.0"
listr2: "npm:7.0.2"
lilconfig: "npm:3.0.0"
listr2: "npm:8.0.0"
micromatch: "npm:4.0.5"
pidtree: "npm:0.6.0"
string-argv: "npm:0.3.2"
yaml: "npm:2.3.4"
bin:
lint-staged: bin/lint-staged.js
checksum: 77aacab303ebab8ef6781833d35d82405b73f0e3e8f8c585cdd95b0e1f42a638a12e853d7ef6227a85d77ed2ba233f92b0499124696a6872569c508e04d25ce3
checksum: 2a20e9b15f7e7419e92a2014afb01feb58798341a4a56aa1b9c8570297681cf54919f645df3c221e4348fd262df38c1e711a245a645d477bf870841e27c604f2
languageName: node
linkType: hard
"listr2@npm:7.0.2":
version: 7.0.2
resolution: "listr2@npm:7.0.2"
"listr2@npm:8.0.0":
version: 8.0.0
resolution: "listr2@npm:8.0.0"
dependencies:
cli-truncate: "npm:^3.1.0"
cli-truncate: "npm:^4.0.0"
colorette: "npm:^2.0.20"
eventemitter3: "npm:^5.0.1"
log-update: "npm:^5.0.1"
log-update: "npm:^6.0.0"
rfdc: "npm:^1.3.0"
wrap-ansi: "npm:^8.1.0"
checksum: 42cda5764906f9d298e3b0b0a684e71a3737533b2aef66f361265a3b938c4bc8f49bcea91536a8daa956833658d14108469b00c565c8e93ce4079795f6a06e07
wrap-ansi: "npm:^9.0.0"
checksum: d5a53b6d5feaa3a45c3750ebf10d242d42f11741b890edf8de7d68a002c36f15d0683f25742a0eb055763f04c005210a5cd61ef6c24ebac099d597cb21b06f29
languageName: node
linkType: hard
@@ -11596,16 +11612,16 @@ __metadata:
languageName: node
linkType: hard
"log-update@npm:^5.0.1":
version: 5.0.1
resolution: "log-update@npm:5.0.1"
"log-update@npm:^6.0.0":
version: 6.0.0
resolution: "log-update@npm:6.0.0"
dependencies:
ansi-escapes: "npm:^5.0.0"
ansi-escapes: "npm:^6.2.0"
cli-cursor: "npm:^4.0.0"
slice-ansi: "npm:^5.0.0"
strip-ansi: "npm:^7.0.1"
wrap-ansi: "npm:^8.0.1"
checksum: 0e154e46744125b6d20c30289e90091794d58b83c2f01d7676da2afa2411c6ec2c3ee2c99753b9c6b896b9ee496a9a403a563330a2d5914a3bdb30e836f17cfb
slice-ansi: "npm:^7.0.0"
strip-ansi: "npm:^7.1.0"
wrap-ansi: "npm:^9.0.0"
checksum: b345f392c356087290918f1bdaae84ee38699c89c9274fafbb6f4cee2fe6f89f9737000111279a40e651fbe0e9c08803b0457c2a4800d8a405752804f73058a8
languageName: node
linkType: hard
@@ -11739,12 +11755,12 @@ __metadata:
languageName: node
linkType: hard
"marked@npm:11.0.0":
version: 11.0.0
resolution: "marked@npm:11.0.0"
"marked@npm:11.0.1":
version: 11.0.1
resolution: "marked@npm:11.0.1"
bin:
marked: bin/marked.js
checksum: bc533791a77a041291a92f91083482a95d59767c4adaf39c4aa3008400446e586933578065ceb4c66c340aed0fb13a61b489d7d88adfbecda7c8ed7bfcead102
checksum: a732d6d2ad1b74fc0e94eea266e87fe17777bce4f1c631230384b843c27bd03c18fce337a9effd97c893ef4583c19d8ddc1c965aa71b602375efb89de14d5e67
languageName: node
linkType: hard
@@ -13921,9 +13937,9 @@ __metadata:
languageName: node
linkType: hard
"rollup-plugin-visualizer@npm:5.9.3":
version: 5.9.3
resolution: "rollup-plugin-visualizer@npm:5.9.3"
"rollup-plugin-visualizer@npm:5.10.0":
version: 5.10.0
resolution: "rollup-plugin-visualizer@npm:5.10.0"
dependencies:
open: "npm:^8.4.0"
picomatch: "npm:^2.3.1"
@@ -13936,7 +13952,7 @@ __metadata:
optional: true
bin:
rollup-plugin-visualizer: dist/bin/cli.js
checksum: 569acbdf9401fb5e23456d889b1094e95a003331c63428732f94418eda59850fd74994587353f58c833a535cc24cdef56c06872996f76f98802ff22939ebbf0d
checksum: aa4ef8d2aae064b50a50168094db1337762d91bd0cd06206cfbc96a97adca45b7036dc1871eab7e70878111eeedb8164fe267f5cc56cd9eb4225ed71c8966aa6
languageName: node
linkType: hard
@@ -14376,6 +14392,16 @@ __metadata:
languageName: node
linkType: hard
"slice-ansi@npm:^7.0.0":
version: 7.1.0
resolution: "slice-ansi@npm:7.1.0"
dependencies:
ansi-styles: "npm:^6.2.1"
is-fullwidth-code-point: "npm:^5.0.0"
checksum: 10313dd3cf7a2e4b265f527b1684c7c568210b09743fd1bd74f2194715ed13ffba653dc93a5fa79e3b1711518b8990a732cb7143aa01ddafe626e99dfa6474b2
languageName: node
linkType: hard
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
@@ -14766,7 +14792,7 @@ __metadata:
languageName: node
linkType: hard
"string-width@npm:^5.0.0, string-width@npm:^5.0.1, string-width@npm:^5.1.2":
"string-width@npm:^5.0.1, string-width@npm:^5.1.2":
version: 5.1.2
resolution: "string-width@npm:5.1.2"
dependencies:
@@ -14777,6 +14803,17 @@ __metadata:
languageName: node
linkType: hard
"string-width@npm:^7.0.0":
version: 7.0.0
resolution: "string-width@npm:7.0.0"
dependencies:
emoji-regex: "npm:^10.3.0"
get-east-asian-width: "npm:^1.0.0"
strip-ansi: "npm:^7.1.0"
checksum: bc0de5700a2690895169fce447ec4ed44bc62de80312c2093d5606bfd48319bb88e48a99e97f269dff2bc9577448b91c26b3804c16e7d9b389699795e4655c3b
languageName: node
linkType: hard
"string.prototype.matchall@npm:^4.0.6":
version: 4.0.10
resolution: "string.prototype.matchall@npm:4.0.10"
@@ -14874,7 +14911,7 @@ __metadata:
languageName: node
linkType: hard
"strip-ansi@npm:^7.0.1":
"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0":
version: 7.1.0
resolution: "strip-ansi@npm:7.1.0"
dependencies:
@@ -15489,10 +15526,10 @@ __metadata:
languageName: node
linkType: hard
"type-fest@npm:^1.0.2":
version: 1.4.0
resolution: "type-fest@npm:1.4.0"
checksum: 89875c247564601c2650bacad5ff80b859007fbdb6c9e43713ae3ffa3f584552eea60f33711dd762e16496a1ab4debd409822627be14097d9a17e39c49db591a
"type-fest@npm:^3.0.0":
version: 3.13.1
resolution: "type-fest@npm:3.13.1"
checksum: 9a8a2359ada34c9b3affcaf3a8f73ee14c52779e89950db337ce66fb74c3399776c697c99f2532e9b16e10e61cfdba3b1c19daffb93b338b742f0acd0117ce12
languageName: node
linkType: hard
@@ -15574,13 +15611,13 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:5.3.2":
version: 5.3.2
resolution: "typescript@npm:5.3.2"
"typescript@npm:5.3.3":
version: 5.3.3
resolution: "typescript@npm:5.3.3"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 415e5fb6611f5713e460bad48039f00bcfdbde53a2f911727862d5aa9c5d5edd250059a419df382d8f031709e15a169c41eb62b6a401da5eec7ac0f4e359d6ac
checksum: 6e4e6a14a50c222b3d14d4ea2f729e79f972fa536ac1522b91202a9a65af3605c2928c4a790a4a50aa13694d461c479ba92cedaeb1e7b190aadaa4e4b96b8e18
languageName: node
linkType: hard
@@ -15594,13 +15631,13 @@ __metadata:
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A5.3.2#optional!builtin<compat/typescript>":
version: 5.3.2
resolution: "typescript@patch:typescript@npm%3A5.3.2#optional!builtin<compat/typescript>::version=5.3.2&hash=e012d7"
"typescript@patch:typescript@npm%3A5.3.3#optional!builtin<compat/typescript>":
version: 5.3.3
resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin<compat/typescript>::version=5.3.3&hash=e012d7"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 1b45cdfb577a78ae7a9a9d0b77a7b772142cb98ba05e4e5aefba7044a028ded885bcecef63166407a5986645cea816fe4986894336aacd5e791796ea79a6a7ed
checksum: c93786fcc9a70718ba1e3819bab56064ead5817004d1b8186f8ca66165f3a2d0100fee91fa64c840dcd45f994ca5d615d8e1f566d39a7470fc1e014dbb4cf15d
languageName: node
linkType: hard
@@ -16713,7 +16750,7 @@ __metadata:
languageName: node
linkType: hard
"wrap-ansi@npm:^8.0.1, wrap-ansi@npm:^8.1.0":
"wrap-ansi@npm:^8.1.0":
version: 8.1.0
resolution: "wrap-ansi@npm:8.1.0"
dependencies:
@@ -16724,6 +16761,17 @@ __metadata:
languageName: node
linkType: hard
"wrap-ansi@npm:^9.0.0":
version: 9.0.0
resolution: "wrap-ansi@npm:9.0.0"
dependencies:
ansi-styles: "npm:^6.2.1"
string-width: "npm:^7.0.0"
strip-ansi: "npm:^7.1.0"
checksum: b9d91564c091cf3978a7c18ca0f3e4d4606e83549dbe59cf76f5e77feefdd5ec91443155e8102630524d10a8c275efac8a7082c0f26fa43e6b989dc150d176ce
languageName: node
linkType: hard
"wrappy@npm:1":
version: 1.0.2
resolution: "wrappy@npm:1.0.2"