Compare commits

..

14 Commits

Author SHA1 Message Date
renovate[bot]
bd46c358fb Update dependency @codemirror/commands to v6.10.1 (#28642)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 10:59:12 +00:00
renovate[bot]
30b8ea1ae8 Update dependency @rspack/core to v1.6.8 (#28643)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 11:53:48 +01:00
renovate[bot]
a24dacf50d Update formatjs monorepo (#28641)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 11:53:03 +01:00
renovate[bot]
7cbd07e33e Update dependency vite-tsconfig-paths to v6.0.2 (#28640)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 08:57:07 +01:00
renovate[bot]
c72ad83532 Lock file maintenance (#28621)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-19 19:11:00 +00:00
renovate[bot]
f2aba45dfe Update formatjs monorepo (major) (#28619)
* Update formatjs monorepo

* Add compiler paths

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
2025-12-19 18:58:38 +00:00
Bram Kragten
639c2ce077 Add choose selector (#28624)
* Add choose selector

* add support for translation

* pass required

* Add to gallery
2025-12-19 19:52:31 +01:00
renovate[bot]
1bddc02ae0 Update dependency @formatjs/intl-durationformat to v0.8.1 (#28617)
* Update dependency @formatjs/intl-durationformat to v0.8.1

* Add compiler path for polyfill

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
2025-12-19 18:33:11 +00:00
Simon
ebea5176e2 Add npmMinimalAgeGate to .yarnrc.yml (#28638) 2025-12-19 17:53:57 +00:00
Petar Petrov
39f550cf9f Fix datetime handling in energy charts (#28345)
* Fix datetime handling in energy charts

* PR comment

* Add detailedDailyData parameter to getSuggestedMax and update getCommonOptions

* refactor

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2025-12-19 18:47:18 +01:00
Paul Bottein
cdcbd00a92 Remove ha-space-0 (#28635)
* Remove ha-space-0

* Update src/components/ha-sidebar.ts

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Fix variable inside calc

* Replace for variables

---------

Co-authored-by: Aidan Timson <aidan@timmo.dev>
2025-12-19 17:12:28 +01:00
renovate[bot]
86cd0e81ad Update vitest monorepo to v4.0.16 (#28636)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-19 15:56:52 +00:00
Aidan Timson
6efe444af3 Use space tokens in more info dialog area (#28627)
Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
2025-12-19 16:12:32 +01:00
Wendelin
09c9665b2f Remove ha-combo-box and vaadin dependencies (#28632) 2025-12-19 15:11:17 +01:00
83 changed files with 1429 additions and 1825 deletions

View File

@@ -1,3 +0,0 @@
issue_enrichment:
auto_enrich:
enabled: false

View File

@@ -154,7 +154,7 @@ try {
- **Use CSS custom properties**: Leverage the theme system - **Use CSS custom properties**: Leverage the theme system
- **Use spacing tokens**: Prefer `--ha-space-*` tokens over hardcoded values for consistent spacing - **Use spacing tokens**: Prefer `--ha-space-*` tokens over hardcoded values for consistent spacing
- Spacing scale: `--ha-space-0` (0px) through `--ha-space-20` (80px) in 4px increments - Spacing scale: `--ha-space-1` (4px) through `--ha-space-20` (80px) in 4px increments
- Defined in `src/resources/theme/core.globals.ts` - Defined in `src/resources/theme/core.globals.ts`
- Common values: `--ha-space-2` (8px), `--ha-space-4` (16px), `--ha-space-8` (32px) - Common values: `--ha-space-2` (8px), `--ha-space-4` (16px), `--ha-space-8` (32px)
- **Mobile-first responsive**: Design for mobile, enhance for desktop - **Mobile-first responsive**: Design for mobile, enhance for desktop

View File

@@ -1,5 +1,7 @@
compressionLevel: mixed compressionLevel: mixed
npmMinimalAgeGate: "3d"
defaultSemverRangePrefix: "" defaultSemverRangePrefix: ""
enableGlobalCache: false enableGlobalCache: false

View File

@@ -20,8 +20,6 @@ module.exports.ignorePackages = () => [];
// Files from NPM packages that we should replace with empty file // Files from NPM packages that we should replace with empty file
module.exports.emptyPackages = ({ isHassioBuild, isLandingPageBuild }) => module.exports.emptyPackages = ({ isHassioBuild, isLandingPageBuild }) =>
[ [
require.resolve("@vaadin/vaadin-material-styles/typography.js"),
require.resolve("@vaadin/vaadin-material-styles/font-icons.js"),
// Icons in supervisor conflict with icons in HA so we don't load. // Icons in supervisor conflict with icons in HA so we don't load.
(isHassioBuild || isLandingPageBuild) && (isHassioBuild || isLandingPageBuild) &&
require.resolve( require.resolve(

View File

@@ -168,12 +168,16 @@ const createRspackConfig = ({
); );
}, },
}), }),
new rspack.NormalModuleReplacementPlugin( bundle.emptyPackages({ isHassioBuild, isLandingPageBuild }).length
new RegExp( ? new rspack.NormalModuleReplacementPlugin(
bundle.emptyPackages({ isHassioBuild, isLandingPageBuild }).join("|") new RegExp(
), bundle
path.resolve(paths.root_dir, "src/util/empty.js") .emptyPackages({ isHassioBuild, isLandingPageBuild })
), .join("|")
),
path.resolve(paths.root_dir, "src/util/empty.js")
)
: false,
!isProdBuild && new LogStartCompilePlugin(), !isProdBuild && new LogStartCompilePlugin(),
isProdBuild && isProdBuild &&
new StatsWriterPlugin({ new StatsWriterPlugin({
@@ -217,6 +221,42 @@ const createRspackConfig = ({
"@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver.js", "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver.js",
"@lit-labs/observers/resize-controller": "@lit-labs/observers/resize-controller":
"@lit-labs/observers/resize-controller.js", "@lit-labs/observers/resize-controller.js",
"@formatjs/intl-durationformat/should-polyfill$":
"@formatjs/intl-durationformat/should-polyfill.js",
"@formatjs/intl-durationformat/polyfill-force$":
"@formatjs/intl-durationformat/polyfill-force.js",
"@formatjs/intl-datetimeformat/should-polyfill":
"@formatjs/intl-datetimeformat/should-polyfill.js",
"@formatjs/intl-datetimeformat/polyfill-force":
"@formatjs/intl-datetimeformat/polyfill-force.js",
"@formatjs/intl-displaynames/should-polyfill":
"@formatjs/intl-displaynames/should-polyfill.js",
"@formatjs/intl-displaynames/polyfill-force":
"@formatjs/intl-displaynames/polyfill-force.js",
"@formatjs/intl-getcanonicallocales/should-polyfill":
"@formatjs/intl-getcanonicallocales/should-polyfill.js",
"@formatjs/intl-getcanonicallocales/polyfill-force":
"@formatjs/intl-getcanonicallocales/polyfill-force.js",
"@formatjs/intl-listformat/should-polyfill":
"@formatjs/intl-listformat/should-polyfill.js",
"@formatjs/intl-listformat/polyfill-force":
"@formatjs/intl-listformat/polyfill-force.js",
"@formatjs/intl-locale/should-polyfill":
"@formatjs/intl-locale/should-polyfill.js",
"@formatjs/intl-locale/polyfill-force":
"@formatjs/intl-locale/polyfill-force.js",
"@formatjs/intl-numberformat/should-polyfill":
"@formatjs/intl-numberformat/should-polyfill.js",
"@formatjs/intl-numberformat/polyfill-force":
"@formatjs/intl-numberformat/polyfill-force.js",
"@formatjs/intl-pluralrules/should-polyfill":
"@formatjs/intl-pluralrules/should-polyfill.js",
"@formatjs/intl-pluralrules/polyfill-force":
"@formatjs/intl-pluralrules/polyfill-force.js",
"@formatjs/intl-relativetimeformat/should-polyfill":
"@formatjs/intl-relativetimeformat/should-polyfill.js",
"@formatjs/intl-relativetimeformat/polyfill-force":
"@formatjs/intl-relativetimeformat/polyfill-force.js",
}, },
}, },
output: { output: {

View File

@@ -40,6 +40,9 @@ const ENTITIES = [
getEntity("switch", "coffee", "off", { getEntity("switch", "coffee", "off", {
friendly_name: "Coffee", friendly_name: "Coffee",
}), }),
getEntity("number", "number", 5, {
friendly_name: "Number",
}),
]; ];
const DEVICES: DeviceRegistryEntry[] = [ const DEVICES: DeviceRegistryEntry[] = [
@@ -377,6 +380,33 @@ const SCHEMAS: {
name: "Constant", name: "Constant",
selector: { constant: { value: true, label: "Yes!" } }, selector: { constant: { value: true, label: "Yes!" } },
}, },
choose: {
name: "Choose",
selector: {
choose: {
choices: {
number: {
selector: {
number: {
min: 0,
max: 100,
step: 0.1,
},
},
},
entity: {
selector: {
entity: {
filter: {
domain: "number",
},
},
},
},
},
},
},
},
}, },
}, },
{ {

View File

@@ -29,7 +29,7 @@
"@babel/runtime": "7.28.4", "@babel/runtime": "7.28.4",
"@braintree/sanitize-url": "7.1.1", "@braintree/sanitize-url": "7.1.1",
"@codemirror/autocomplete": "6.20.0", "@codemirror/autocomplete": "6.20.0",
"@codemirror/commands": "6.10.0", "@codemirror/commands": "6.10.1",
"@codemirror/language": "6.11.3", "@codemirror/language": "6.11.3",
"@codemirror/legacy-modes": "6.5.2", "@codemirror/legacy-modes": "6.5.2",
"@codemirror/search": "6.5.11", "@codemirror/search": "6.5.11",
@@ -37,15 +37,15 @@
"@codemirror/view": "6.39.4", "@codemirror/view": "6.39.4",
"@date-fns/tz": "1.4.1", "@date-fns/tz": "1.4.1",
"@egjs/hammerjs": "2.0.17", "@egjs/hammerjs": "2.0.17",
"@formatjs/intl-datetimeformat": "6.18.2", "@formatjs/intl-datetimeformat": "7.0.2",
"@formatjs/intl-displaynames": "6.8.13", "@formatjs/intl-displaynames": "7.0.2",
"@formatjs/intl-durationformat": "0.7.6", "@formatjs/intl-durationformat": "0.8.2",
"@formatjs/intl-getcanonicallocales": "2.5.6", "@formatjs/intl-getcanonicallocales": "3.0.2",
"@formatjs/intl-listformat": "7.7.13", "@formatjs/intl-listformat": "8.0.2",
"@formatjs/intl-locale": "4.2.13", "@formatjs/intl-locale": "5.0.2",
"@formatjs/intl-numberformat": "8.15.6", "@formatjs/intl-numberformat": "9.0.3",
"@formatjs/intl-pluralrules": "5.4.6", "@formatjs/intl-pluralrules": "6.0.2",
"@formatjs/intl-relativetimeformat": "11.4.13", "@formatjs/intl-relativetimeformat": "12.0.3",
"@fullcalendar/core": "6.1.19", "@fullcalendar/core": "6.1.19",
"@fullcalendar/daygrid": "6.1.19", "@fullcalendar/daygrid": "6.1.19",
"@fullcalendar/interaction": "6.1.19", "@fullcalendar/interaction": "6.1.19",
@@ -89,8 +89,6 @@
"@thomasloven/round-slider": "0.6.0", "@thomasloven/round-slider": "0.6.0",
"@tsparticles/engine": "3.9.1", "@tsparticles/engine": "3.9.1",
"@tsparticles/preset-links": "3.2.0", "@tsparticles/preset-links": "3.2.0",
"@vaadin/combo-box": "24.9.6",
"@vaadin/vaadin-themable-mixin": "24.9.6",
"@vibrant/color": "4.0.0", "@vibrant/color": "4.0.0",
"@vue/web-component-wrapper": "1.3.0", "@vue/web-component-wrapper": "1.3.0",
"@webcomponents/scoped-custom-element-registry": "0.0.10", "@webcomponents/scoped-custom-element-registry": "0.0.10",
@@ -114,7 +112,7 @@
"hls.js": "1.6.15", "hls.js": "1.6.15",
"home-assistant-js-websocket": "9.6.0", "home-assistant-js-websocket": "9.6.0",
"idb-keyval": "6.2.2", "idb-keyval": "6.2.2",
"intl-messageformat": "10.7.18", "intl-messageformat": "11.0.2",
"js-yaml": "4.1.1", "js-yaml": "4.1.1",
"leaflet": "1.9.4", "leaflet": "1.9.4",
"leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch", "leaflet-draw": "patch:leaflet-draw@npm%3A1.0.4#./.yarn/patches/leaflet-draw-npm-1.0.4-0ca0ebcf65.patch",
@@ -158,7 +156,7 @@
"@octokit/plugin-retry": "8.0.3", "@octokit/plugin-retry": "8.0.3",
"@octokit/rest": "22.0.1", "@octokit/rest": "22.0.1",
"@rsdoctor/rspack-plugin": "1.3.16", "@rsdoctor/rspack-plugin": "1.3.16",
"@rspack/core": "1.6.7", "@rspack/core": "1.6.8",
"@rspack/dev-server": "1.1.4", "@rspack/dev-server": "1.1.4",
"@types/babel__plugin-transform-runtime": "7.9.5", "@types/babel__plugin-transform-runtime": "7.9.5",
"@types/chromecast-caf-receiver": "6.0.25", "@types/chromecast-caf-receiver": "6.0.25",
@@ -178,7 +176,7 @@
"@types/tar": "6.1.13", "@types/tar": "6.1.13",
"@types/ua-parser-js": "0.7.39", "@types/ua-parser-js": "0.7.39",
"@types/webspeechapi": "0.0.29", "@types/webspeechapi": "0.0.29",
"@vitest/coverage-v8": "4.0.15", "@vitest/coverage-v8": "4.0.16",
"babel-loader": "10.0.0", "babel-loader": "10.0.0",
"babel-plugin-template-html-minifier": "4.1.0", "babel-plugin-template-html-minifier": "4.1.0",
"browserslist-useragent-regexp": "4.1.3", "browserslist-useragent-regexp": "4.1.3",
@@ -218,8 +216,8 @@
"ts-lit-plugin": "2.0.2", "ts-lit-plugin": "2.0.2",
"typescript": "5.9.3", "typescript": "5.9.3",
"typescript-eslint": "8.50.0", "typescript-eslint": "8.50.0",
"vite-tsconfig-paths": "6.0.1", "vite-tsconfig-paths": "6.0.2",
"vitest": "4.0.15", "vitest": "4.0.16",
"webpack-stats-plugin": "1.1.3", "webpack-stats-plugin": "1.1.3",
"webpackbar": "7.0.0", "webpackbar": "7.0.0",
"workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch" "workbox-build": "patch:workbox-build@npm%3A7.1.1#~/.yarn/patches/workbox-build-npm-7.1.1-a854f3faae.patch"

View File

@@ -1,4 +1,4 @@
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import type { HassEntity } from "home-assistant-js-websocket"; import type { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, nothing, type PropertyValues } from "lit"; import { html, LitElement, nothing, type PropertyValues } from "lit";
import { customElement, property, query, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
@@ -162,7 +162,7 @@ export class HaDevicePicker extends LitElement {
} }
); );
private _rowRenderer: ComboBoxLitRenderer<DevicePickerItem> = (item) => html` private _rowRenderer: RenderItemFunction<DevicePickerItem> = (item) => html`
<ha-combo-box-item type="button"> <ha-combo-box-item type="button">
${item.domain ${item.domain
? html` ? html`

View File

@@ -1,5 +1,5 @@
import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import { mdiPlus, mdiShape } from "@mdi/js"; import { mdiPlus, mdiShape } from "@mdi/js";
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { html, LitElement, nothing, type PropertyValues } from "lit"; import { html, LitElement, nothing, type PropertyValues } from "lit";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, query } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
@@ -172,9 +172,9 @@ export class HaEntityPicker extends LitElement {
return this.showEntityId || this.hass.userData?.showEntityIdPicker; return this.showEntityId || this.hass.userData?.showEntityIdPicker;
} }
private _rowRenderer: ComboBoxLitRenderer<EntityComboBoxItem> = ( private _rowRenderer: RenderItemFunction<EntityComboBoxItem> = (
item, item,
{ index } index
) => { ) => {
const showEntityId = this._showEntityId; const showEntityId = this._showEntityId;

View File

@@ -1,5 +1,5 @@
import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import { mdiChartLine, mdiHelpCircle, mdiShape } from "@mdi/js"; import { mdiChartLine, mdiHelpCircle, mdiShape } from "@mdi/js";
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import type { HassEntity } from "home-assistant-js-websocket"; import type { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, nothing, type PropertyValues } from "lit"; import { html, LitElement, nothing, type PropertyValues } from "lit";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, query } from "lit/decorators";
@@ -424,9 +424,9 @@ export class HaStatisticPicker extends LitElement {
}; };
} }
private _rowRenderer: ComboBoxLitRenderer<StatisticComboBoxItem> = ( private _rowRenderer: RenderItemFunction<StatisticComboBoxItem> = (
item, item,
{ index } index
) => { ) => {
const showEntityId = this.hass.userData?.showEntityIdPicker; const showEntityId = this.hass.userData?.showEntityIdPicker;
return html` return html`

View File

@@ -175,7 +175,7 @@ export class HaAutomationRow extends LitElement {
::slotted([slot="header"]) { ::slotted([slot="header"]) {
flex: 1; flex: 1;
overflow-wrap: anywhere; overflow-wrap: anywhere;
margin: var(--ha-space-0) var(--ha-space-3); margin: 0 var(--ha-space-3);
} }
.icons { .icons {
display: flex; display: flex;

View File

@@ -241,7 +241,7 @@ export class HaBottomSheet extends ScrollableFadeMixin(LitElement) {
} }
slot[name="footer"] { slot[name="footer"] {
display: block; display: block;
padding: var(--ha-space-0); padding: 0;
} }
::slotted([slot="footer"]) { ::slotted([slot="footer"]) {
display: flex; display: flex;

View File

@@ -46,14 +46,14 @@ export class HaCard extends LitElement {
line-height: var(--ha-line-height-expanded); line-height: var(--ha-line-height-expanded);
padding: var(--ha-space-3) var(--ha-space-4) var(--ha-space-4); padding: var(--ha-space-3) var(--ha-space-4) var(--ha-space-4);
display: block; display: block;
margin-block-start: var(--ha-space-0); margin-block-start: 0;
margin-block-end: var(--ha-space-0); margin-block-end: 0;
font-weight: var(--ha-font-weight-normal); font-weight: var(--ha-font-weight-normal);
} }
:host ::slotted(.card-content:not(:first-child)), :host ::slotted(.card-content:not(:first-child)),
slot:not(:first-child)::slotted(.card-content) { slot:not(:first-child)::slotted(.card-content) {
padding-top: var(--ha-space-0); padding-top: 0;
margin-top: calc(var(--ha-space-2) * -1); margin-top: calc(var(--ha-space-2) * -1);
} }

View File

@@ -1,433 +0,0 @@
import { mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js";
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { comboBoxRenderer } from "@vaadin/combo-box/lit";
import "@vaadin/combo-box/theme/material/vaadin-combo-box-light";
import type {
ComboBoxDataProvider,
ComboBoxLight,
ComboBoxLightFilterChangedEvent,
ComboBoxLightOpenedChangedEvent,
ComboBoxLightValueChangedEvent,
} from "@vaadin/combo-box/vaadin-combo-box-light";
import { registerStyles } from "@vaadin/vaadin-themable-mixin/register-styles";
import type { TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { fireEvent } from "../common/dom/fire_event";
import type { HomeAssistant } from "../types";
import "./ha-combo-box-item";
import "./ha-combo-box-textfield";
import "./ha-icon-button";
import "./ha-input-helper-text";
import "./ha-textfield";
import type { HaTextField } from "./ha-textfield";
registerStyles(
"vaadin-combo-box-item",
css`
:host {
padding: 0 !important;
}
:host([focused]:not([disabled])) {
background-color: rgba(var(--rgb-primary-text-color, 0, 0, 0), 0.12);
}
:host([selected]:not([disabled])) {
background-color: transparent;
color: var(--mdc-theme-primary);
--mdc-ripple-color: var(--mdc-theme-primary);
--mdc-theme-text-primary-on-background: var(--mdc-theme-primary);
}
:host([selected]:not([disabled])):before {
background-color: var(--mdc-theme-primary);
opacity: 0.12;
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
:host([selected][focused]:not([disabled])):before {
opacity: 0.24;
}
:host(:hover:not([disabled])) {
background-color: transparent;
}
[part="content"] {
width: 100%;
}
[part="checkmark"] {
display: none;
}
`
);
@customElement("ha-combo-box")
export class HaComboBox extends LitElement {
@property({ attribute: false }) public hass?: HomeAssistant;
@property() public label?: string;
@property() public value?: string;
@property() public placeholder?: string;
@property({ attribute: false }) public validationMessage?: string;
@property() public helper?: string;
@property({ attribute: "error-message" }) public errorMessage?: string;
@property({ type: Boolean }) public invalid = false;
@property({ type: Boolean }) public icon = false;
@property({ attribute: false }) public items?: any[];
@property({ attribute: false }) public filteredItems?: any[];
@property({ attribute: false })
public dataProvider?: ComboBoxDataProvider<any>;
@property({ attribute: "allow-custom-value", type: Boolean })
public allowCustomValue = false;
@property({ attribute: "item-value-path" }) public itemValuePath = "value";
@property({ attribute: "item-label-path" }) public itemLabelPath = "label";
@property({ attribute: "item-id-path" }) public itemIdPath?: string;
@property({ attribute: false }) public renderer?: ComboBoxLitRenderer<any>;
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public required = false;
@property({ type: Boolean, reflect: true }) public opened = false;
@property({ type: Boolean, attribute: "hide-clear-icon" })
public hideClearIcon = false;
@property({ type: Boolean, attribute: "clear-initial-value" })
public clearInitialValue = false;
@query("vaadin-combo-box-light", true) private _comboBox!: ComboBoxLight;
@query("ha-combo-box-textfield", true) private _inputElement!: HaTextField;
@state({ type: Boolean }) private _forceBlankValue = false;
private _overlayMutationObserver?: MutationObserver;
private _bodyMutationObserver?: MutationObserver;
public async open() {
await this.updateComplete;
this._comboBox?.open();
}
public async focus() {
await this.updateComplete;
await this._inputElement?.updateComplete;
this._inputElement?.focus();
}
public disconnectedCallback() {
super.disconnectedCallback();
if (this._overlayMutationObserver) {
this._overlayMutationObserver.disconnect();
this._overlayMutationObserver = undefined;
}
if (this._bodyMutationObserver) {
this._bodyMutationObserver.disconnect();
this._bodyMutationObserver = undefined;
}
}
public get selectedItem() {
return this._comboBox.selectedItem;
}
public setInputValue(value: string) {
this._comboBox.value = value;
}
public setTextFieldValue(value: string) {
this._inputElement.value = value;
}
protected render(): TemplateResult {
return html`
<!-- @ts-ignore Tag definition is not included in theme folder -->
<vaadin-combo-box-light
.itemValuePath=${this.itemValuePath}
.itemIdPath=${this.itemIdPath}
.itemLabelPath=${this.itemLabelPath}
.items=${this.items}
.value=${this.value || ""}
.filteredItems=${this.filteredItems}
.dataProvider=${this.dataProvider}
.allowCustomValue=${this.allowCustomValue}
.disabled=${this.disabled}
.required=${this.required}
${comboBoxRenderer(this.renderer || this._defaultRowRenderer)}
@opened-changed=${this._openedChanged}
@filter-changed=${this._filterChanged}
@value-changed=${this._valueChanged}
attr-for-value="value"
>
<ha-combo-box-textfield
label=${ifDefined(this.label)}
placeholder=${ifDefined(this.placeholder)}
?disabled=${this.disabled}
?required=${this.required}
validationMessage=${ifDefined(this.validationMessage)}
.errorMessage=${this.errorMessage}
class="input"
autocapitalize="none"
autocomplete="off"
.autocorrect=${false}
input-spellcheck="false"
.suffix=${html`<div
style="width: 28px;"
role="none presentation"
></div>`}
.icon=${this.icon}
.invalid=${this.invalid}
.forceBlankValue=${this._forceBlankValue}
>
<slot name="icon" slot="leadingIcon"></slot>
</ha-combo-box-textfield>
${this.value && !this.hideClearIcon
? html`<ha-svg-icon
role="button"
tabindex="-1"
aria-label=${ifDefined(this.hass?.localize("ui.common.clear"))}
class=${`clear-button ${this.label ? "" : "no-label"}`}
.path=${mdiClose}
?disabled=${this.disabled}
@click=${this._clearValue}
></ha-svg-icon>`
: ""}
<ha-svg-icon
role="button"
tabindex="-1"
aria-label=${ifDefined(this.label)}
aria-expanded=${this.opened ? "true" : "false"}
class=${`toggle-button ${this.label ? "" : "no-label"}`}
.path=${this.opened ? mdiMenuUp : mdiMenuDown}
?disabled=${this.disabled}
@click=${this._toggleOpen}
></ha-svg-icon>
</vaadin-combo-box-light>
${this._renderHelper()}
`;
}
private _renderHelper() {
return this.helper
? html`<ha-input-helper-text .disabled=${this.disabled}
>${this.helper}</ha-input-helper-text
>`
: "";
}
private _defaultRowRenderer: ComboBoxLitRenderer<
string | Record<string, any>
> = (item) => html`
<ha-combo-box-item type="button">
${this.itemLabelPath ? item[this.itemLabelPath] : item}
</ha-combo-box-item>
`;
private _clearValue(ev: Event) {
ev.stopPropagation();
fireEvent(this, "value-changed", { value: undefined });
}
private _toggleOpen(ev: Event) {
if (this.opened) {
this._comboBox?.close();
ev.stopPropagation();
} else {
this._comboBox?.inputElement.focus();
}
}
private _openedChanged(ev: ComboBoxLightOpenedChangedEvent) {
ev.stopPropagation();
const opened = ev.detail.value;
// delay this so we can handle click event for toggle button before setting _opened
setTimeout(() => {
this.opened = opened;
fireEvent(this, "opened-changed", { value: ev.detail.value });
}, 0);
if (this.clearInitialValue) {
this.setTextFieldValue("");
if (opened) {
// Wait 100ms to be sure vaddin-combo-box-light already tried to set the value
setTimeout(() => {
this._forceBlankValue = false;
}, 100);
} else {
this._forceBlankValue = true;
}
}
if (opened) {
const overlay = document.querySelector<HTMLElement>(
"vaadin-combo-box-overlay"
);
if (overlay) {
this._removeInert(overlay);
}
this._observeBody();
} else {
this._bodyMutationObserver?.disconnect();
this._bodyMutationObserver = undefined;
}
}
private _observeBody() {
if ("MutationObserver" in window && !this._bodyMutationObserver) {
this._bodyMutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeName === "VAADIN-COMBO-BOX-OVERLAY") {
this._removeInert(node as HTMLElement);
}
});
mutation.removedNodes.forEach((node) => {
if (node.nodeName === "VAADIN-COMBO-BOX-OVERLAY") {
this._overlayMutationObserver?.disconnect();
this._overlayMutationObserver = undefined;
}
});
});
});
this._bodyMutationObserver.observe(document.body, {
childList: true,
});
}
}
private _removeInert(overlay: HTMLElement) {
if (overlay.inert) {
overlay.inert = false;
this._overlayMutationObserver?.disconnect();
this._overlayMutationObserver = undefined;
return;
}
if ("MutationObserver" in window && !this._overlayMutationObserver) {
this._overlayMutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === "inert") {
const target = mutation.target as HTMLElement;
if (target.inert) {
this._overlayMutationObserver?.disconnect();
this._overlayMutationObserver = undefined;
target.inert = false;
}
}
});
});
this._overlayMutationObserver.observe(overlay, {
attributes: true,
});
}
}
private _filterChanged(ev: ComboBoxLightFilterChangedEvent) {
ev.stopPropagation();
fireEvent(this, "filter-changed", { value: ev.detail.value });
}
private _valueChanged(ev: ComboBoxLightValueChangedEvent) {
ev.stopPropagation();
if (!this.allowCustomValue) {
// @ts-ignore
this._comboBox._closeOnBlurIsPrevented = true;
}
if (!this.opened) {
return;
}
const newValue = ev.detail.value;
if (newValue !== this.value) {
fireEvent(this, "value-changed", { value: newValue || undefined });
}
}
static styles = css`
:host {
display: block;
width: 100%;
}
vaadin-combo-box-light {
position: relative;
}
ha-combo-box-textfield {
width: 100%;
}
ha-combo-box-textfield > ha-icon-button {
--mdc-icon-button-size: 24px;
padding: 2px;
color: var(--secondary-text-color);
}
ha-svg-icon {
color: var(--input-dropdown-icon-color);
position: absolute;
cursor: pointer;
}
.toggle-button {
right: 12px;
top: -10px;
inset-inline-start: initial;
inset-inline-end: 12px;
direction: var(--direction);
}
:host([opened]) .toggle-button {
color: var(--primary-color);
}
.toggle-button[disabled],
.clear-button[disabled] {
color: var(--disabled-text-color);
pointer-events: none;
}
.toggle-button.no-label {
top: -3px;
}
.clear-button {
--mdc-icon-size: 20px;
top: -7px;
right: 36px;
inset-inline-start: initial;
inset-inline-end: 36px;
direction: var(--direction);
}
.clear-button.no-label {
top: 0;
}
ha-input-helper-text {
margin-top: 4px;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-combo-box": HaComboBox;
}
}
declare global {
interface HASSDomEvents {
"filter-changed": { value: string };
"opened-changed": { value: boolean };
}
}

View File

@@ -101,14 +101,13 @@ export class HaDialog extends DialogBase {
} }
.mdc-dialog__container { .mdc-dialog__container {
align-items: var(--vertical-align-dialog, center); align-items: var(--vertical-align-dialog, center);
padding: var(--dialog-container-padding, var(--ha-space-0)); padding: var(--dialog-container-padding, 0);
} }
.mdc-dialog__title { .mdc-dialog__title {
padding: var(--ha-space-4) var(--ha-space-4) var(--ha-space-0) padding: var(--ha-space-4) var(--ha-space-4) 0 var(--ha-space-4);
var(--ha-space-4);
} }
.mdc-dialog__title:has(span) { .mdc-dialog__title:has(span) {
padding: var(--ha-space-3) var(--ha-space-3) var(--ha-space-0); padding: var(--ha-space-3) var(--ha-space-3) 0;
} }
.mdc-dialog__title::before { .mdc-dialog__title::before {
content: unset; content: unset;
@@ -136,7 +135,7 @@ export class HaDialog extends DialogBase {
--ha-dialog-surface-background, --ha-dialog-surface-background,
var(--mdc-theme-surface, #fff) var(--mdc-theme-surface, #fff)
); );
padding: var(--dialog-surface-padding, var(--ha-space-0)); padding: var(--dialog-surface-padding, 0);
} }
:host([flexContent]) .mdc-dialog .mdc-dialog__content { :host([flexContent]) .mdc-dialog .mdc-dialog__content {
display: flex; display: flex;
@@ -168,7 +167,7 @@ export class HaDialog extends DialogBase {
} }
.dialog-actions { .dialog-actions {
inset-inline-start: initial !important; inset-inline-start: initial !important;
inset-inline-end: var(--ha-space-0) !important; inset-inline-end: 0 !important;
direction: var(--direction); direction: var(--direction);
} }
`, `,

View File

@@ -1,5 +1,5 @@
import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import { mdiPlus, mdiTextureBox } from "@mdi/js"; import { mdiPlus, mdiTextureBox } from "@mdi/js";
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import type { HassEntity } from "home-assistant-js-websocket"; import type { HassEntity } from "home-assistant-js-websocket";
import type { TemplateResult } from "lit"; import type { TemplateResult } from "lit";
import { LitElement, html } from "lit"; import { LitElement, html } from "lit";
@@ -303,7 +303,7 @@ export class HaFloorPicker extends LitElement {
} }
); );
private _rowRenderer: ComboBoxLitRenderer<FloorComboBoxItem> = (item) => html` private _rowRenderer: RenderItemFunction<FloorComboBoxItem> = (item) => html`
<ha-combo-box-item type="button" compact> <ha-combo-box-item type="button" compact>
${item.icon_path ${item.icon_path
? html` ? html`

View File

@@ -393,7 +393,7 @@ export class HaGenericPicker extends PickerMixin(LitElement) {
} }
wa-popover { wa-popover {
--wa-space-l: var(--ha-space-0); --wa-space-l: 0;
} }
wa-popover::part(body) { wa-popover::part(body) {
@@ -418,7 +418,7 @@ export class HaGenericPicker extends PickerMixin(LitElement) {
--ha-bottom-sheet-height: calc(100dvh - var(--ha-space-12)); --ha-bottom-sheet-height: calc(100dvh - var(--ha-space-12));
--ha-bottom-sheet-max-height: var(--ha-bottom-sheet-height); --ha-bottom-sheet-max-height: var(--ha-bottom-sheet-height);
--ha-bottom-sheet-max-width: 600px; --ha-bottom-sheet-max-width: 600px;
--ha-bottom-sheet-padding: var(--ha-space-0); --ha-bottom-sheet-padding: 0;
--ha-bottom-sheet-surface-background: var(--card-background-color); --ha-bottom-sheet-surface-background: var(--card-background-color);
--ha-bottom-sheet-border-radius: var(--ha-border-radius-2xl); --ha-bottom-sheet-border-radius: var(--ha-border-radius-2xl);
} }

View File

@@ -175,10 +175,10 @@ export class HaMdDialog extends Dialog {
} }
.container { .container {
margin-top: var(--safe-area-inset-top, var(--ha-space-0)); margin-top: var(--safe-area-inset-top, 0);
margin-bottom: var(--safe-area-inset-bottom, var(--ha-space-0)); margin-bottom: var(--safe-area-inset-bottom, 0);
margin-left: var(--safe-area-inset-left, var(--ha-space-0)); margin-left: var(--safe-area-inset-left, 0);
margin-right: var(--safe-area-inset-right, var(--ha-space-0)); margin-right: var(--safe-area-inset-right, 0);
} }
} }

View File

@@ -0,0 +1,202 @@
import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../common/dom/fire_event";
import { isTemplate } from "../../common/string/has-template";
import type { ChooseSelector, Selector } from "../../data/selector";
import type { HomeAssistant } from "../../types";
import "../ha-button-toggle-group";
import "./ha-selector";
@customElement("ha-selector-choose")
export class HaChooseSelector extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public selector!: ChooseSelector;
@property() public value?: any;
@property() public label?: string;
@property() public helper?: string;
@property({ attribute: false })
public localizeValue?: (key: string) => string;
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public required = true;
@state() public _activeChoice?: string;
protected willUpdate(changedProperties: PropertyValues): void {
if (
changedProperties.has("selector") &&
(!this._activeChoice ||
!(this._activeChoice in this.selector.choose.choices))
) {
this._setActiveChoice();
}
}
protected render() {
if (!this._activeChoice) {
return nothing;
}
const selector = this._selector(this._activeChoice);
const value = this._value(this._activeChoice);
return html`<div class="multi-header">
<span>${this.label}${this.required ? "*" : ""}</span>
<ha-button-toggle-group
size="small"
.buttons=${this._toggleButtons(
this.selector.choose.choices,
this.selector.choose.translation_key
)}
.active=${this._activeChoice}
@value-changed=${this._choiceChanged}
></ha-button-toggle-group>
</div>
<ha-selector
.hass=${this.hass}
.selector=${selector}
.value=${value}
.disabled=${this.disabled}
.required=${this.required}
@value-changed=${this._handleValueChanged}
.helper=${this.helper}
></ha-selector>`;
}
private _toggleButtons = memoizeOne(
(choices: ChooseSelector["choose"]["choices"], translationKey?: string) =>
Object.keys(choices).map((choice) => ({
label:
this.localizeValue && translationKey
? this.localizeValue(`${translationKey}.choices.${choice}`)
: choice,
value: choice,
}))
);
private _choiceChanged(ev) {
ev.stopPropagation();
const value =
typeof this.value === "object"
? this.value
: {
[this._activeChoice!]: this.value,
};
this._activeChoice = ev.detail?.value || ev.target.value;
fireEvent(this, "value-changed", {
value: {
...value,
active_choice: this._activeChoice,
},
});
}
private _handleValueChanged(ev: CustomEvent) {
ev.stopPropagation();
const value = typeof this.value === "object" ? this.value : {};
fireEvent(this, "value-changed", {
value: {
...value,
[this._activeChoice!]: ev.detail.value,
active_choice: this._activeChoice,
},
});
}
private _selector(choice?: string): Selector {
const choices = this.selector.choose.choices;
choice = choice || this.value?.active_choice;
if (choice && choice in choices) {
return choices[choice].selector;
}
return choices[Object.keys(choices)[0]].selector;
}
private _value(choice?: string): any {
if (!this.value) {
return undefined;
}
return typeof this.value === "object"
? this.value[choice || this.value.active_choice]
: this.value;
}
private _setActiveChoice() {
if (this.value) {
if (typeof this.value === "object") {
if (this.value.active_choice in this.selector.choose.choices) {
this._activeChoice = this.value.active_choice;
return;
}
} else {
const typeofValue = typeof this.value;
const selectorTypes = Object.values(this.selector.choose.choices).map(
(choice) => Object.keys(choice.selector)[0]
);
if (typeofValue === "number" && selectorTypes.includes("number")) {
this._activeChoice = Object.keys(this.selector.choose.choices)[
selectorTypes.indexOf("number")
];
return;
}
if (
typeofValue === "string" &&
isTemplate(this.value) &&
selectorTypes.includes("template")
) {
this._activeChoice = Object.keys(this.selector.choose.choices)[
selectorTypes.indexOf("template")
];
return;
}
if (
typeofValue === "string" &&
this.value.includes(".") &&
selectorTypes.includes("entity")
) {
this._activeChoice = Object.keys(this.selector.choose.choices)[
selectorTypes.indexOf("entity")
];
return;
}
if (typeofValue === "string" && selectorTypes.includes("text")) {
this._activeChoice = Object.keys(this.selector.choose.choices)[
selectorTypes.indexOf("text")
];
return;
}
}
}
this._activeChoice = Object.keys(this.selector.choose.choices)[0];
}
static styles = css`
.multi-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--ha-space-2);
}
ha-button-toggle-group {
display: block;
justify-self: end;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-selector-choose": HaChooseSelector;
}
}

View File

@@ -18,6 +18,7 @@ const LOAD_ELEMENTS = {
attribute: () => import("./ha-selector-attribute"), attribute: () => import("./ha-selector-attribute"),
assist_pipeline: () => import("./ha-selector-assist-pipeline"), assist_pipeline: () => import("./ha-selector-assist-pipeline"),
boolean: () => import("./ha-selector-boolean"), boolean: () => import("./ha-selector-boolean"),
choose: () => import("./ha-selector-choose"),
color_rgb: () => import("./ha-selector-color-rgb"), color_rgb: () => import("./ha-selector-color-rgb"),
condition: () => import("./ha-selector-condition"), condition: () => import("./ha-selector-condition"),
config_entry: () => import("./ha-selector-config-entry"), config_entry: () => import("./ha-selector-config-entry"),

View File

@@ -726,6 +726,7 @@ export class HaServiceControl extends LitElement {
: undefined} : undefined}
.placeholder=${dataField.default} .placeholder=${dataField.default}
.localizeValue=${this._localizeValueCallback} .localizeValue=${this._localizeValueCallback}
.required=${dataField.required}
></ha-selector> ></ha-selector>
</ha-settings-row>` </ha-settings-row>`
: ""; : "";

View File

@@ -1,5 +1,5 @@
import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import { mdiRoomService } from "@mdi/js"; import { mdiRoomService } from "@mdi/js";
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { html, LitElement, nothing, type TemplateResult } from "lit"; import { html, LitElement, nothing, type TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators"; import { customElement, property, query } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
@@ -56,9 +56,9 @@ class HaServicePicker extends LitElement {
getServiceIcons(this.hass); getServiceIcons(this.hass);
} }
private _rowRenderer: ComboBoxLitRenderer<ServiceComboBoxItem> = ( private _rowRenderer: RenderItemFunction<ServiceComboBoxItem> = (
item, item,
{ index } index
) => html` ) => html`
<ha-combo-box-item type="button" .borderTop=${index !== 0}> <ha-combo-box-item type="button" .borderTop=${index !== 0}>
<ha-service-icon <ha-service-icon

View File

@@ -681,7 +681,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
tooltip.style.display = "block"; tooltip.style.display = "block";
tooltip.style.position = "fixed"; tooltip.style.position = "fixed";
tooltip.style.top = `${top}px`; tooltip.style.top = `${top}px`;
tooltip.style.left = `calc(${item.offsetLeft + item.clientWidth + 8}px + var(--safe-area-inset-left, var(--ha-space-0)))`; tooltip.style.left = `calc(${item.offsetLeft + item.clientWidth + 8}px + var(--safe-area-inset-left, 0px))`;
} }
private _hideTooltip() { private _hideTooltip() {
@@ -720,14 +720,10 @@ class HaSidebar extends SubscribeMixin(LitElement) {
background-color: var(--sidebar-background-color); background-color: var(--sidebar-background-color);
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
padding-bottom: calc( padding-bottom: calc(14px + var(--safe-area-inset-bottom, 0px));
14px + var(--safe-area-inset-bottom, var(--ha-space-0))
);
} }
.menu { .menu {
height: calc( height: calc(var(--header-height) + var(--safe-area-inset-top, 0px));
var(--header-height) + var(--safe-area-inset-top, var(--ha-space-0))
);
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
padding: 0 var(--ha-space-1); padding: 0 var(--ha-space-1);
@@ -746,16 +742,16 @@ class HaSidebar extends SubscribeMixin(LitElement) {
font-size: var(--ha-font-size-xl); font-size: var(--ha-font-size-xl);
align-items: center; align-items: center;
padding-left: calc( padding-left: calc(
var(--ha-space-1) + var(--safe-area-inset-left, var(--ha-space-0)) var(--ha-space-1) + var(--safe-area-inset-left, 0px)
); );
padding-inline-start: calc( padding-inline-start: calc(
var(--ha-space-1) + var(--safe-area-inset-left, var(--ha-space-0)) var(--ha-space-1) + var(--safe-area-inset-left, 0px)
); );
padding-inline-end: initial; padding-inline-end: initial;
padding-top: var(--safe-area-inset-top, var(--ha-space-0)); padding-top: var(--safe-area-inset-top, 0px);
} }
:host([expanded]) .menu { :host([expanded]) .menu {
width: calc(256px + var(--safe-area-inset-left, var(--ha-space-0))); width: calc(256px + var(--safe-area-inset-left, 0px));
} }
:host([narrow][expanded]) .menu { :host([narrow][expanded]) .menu {
width: 100%; width: 100%;
@@ -771,8 +767,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
display: none; display: none;
} }
:host([narrow]) .title { :host([narrow]) .title {
margin: var(--ha-space-0); margin: 0;
padding: var(--ha-space-0) var(--ha-space-4); padding: 0 var(--ha-space-4);
} }
:host([expanded]) .title { :host([expanded]) .title {
display: initial; display: initial;
@@ -784,16 +780,13 @@ class HaSidebar extends SubscribeMixin(LitElement) {
ha-fade-in, ha-fade-in,
ha-md-list { ha-md-list {
height: calc( height: calc(
100% - var(--header-height) - var( 100% - var(--header-height) - var(--safe-area-inset-top, 0px) -
--safe-area-inset-top,
var(--ha-space-0)
) -
132px 132px
); );
} }
ha-fade-in { ha-fade-in {
padding: var(--ha-space-1) var(--ha-space-0); padding: var(--ha-space-1) 0;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -803,7 +796,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
ha-md-list { ha-md-list {
overflow-x: hidden; overflow-x: hidden;
background: none; background: none;
margin-left: var(--safe-area-inset-left, var(--ha-space-0)); margin-left: var(--safe-area-inset-left, 0px);
} }
ha-md-list-item { ha-md-list-item {
@@ -825,7 +818,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
width: 248px; width: 248px;
} }
:host([narrow][expanded]) ha-md-list-item { :host([narrow][expanded]) ha-md-list-item {
width: calc(240px - var(--safe-area-inset-left, var(--ha-space-0))); width: calc(240px - var(--safe-area-inset-left, 0px));
} }
ha-md-list-item.selected { ha-md-list-item.selected {
@@ -898,7 +891,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
border-radius: var(--ha-border-radius-md); border-radius: var(--ha-border-radius-md);
font-size: 0.65em; font-size: 0.65em;
line-height: var(--ha-line-height-expanded); line-height: var(--ha-line-height-expanded);
padding: var(--ha-space-0) var(--ha-space-1); padding: 0 var(--ha-space-1);
} }
ha-md-list-item.user { ha-md-list-item.user {

View File

@@ -988,7 +988,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
style=${styleMap({ style=${styleMap({
width: "var(--ha-space-12)", width: "var(--ha-space-12)",
position: "absolute", position: "absolute",
top: "var(--ha-space-0)", top: "0",
left: rtl ? undefined : "var(--ha-space-1)", left: rtl ? undefined : "var(--ha-space-1)",
right: rtl ? "var(--ha-space-1)" : undefined, right: rtl ? "var(--ha-space-1)" : undefined,
transform: rtl ? "scaleX(-1)" : "", transform: rtl ? "scaleX(-1)" : "",
@@ -1092,7 +1092,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
z-index: 2; z-index: 2;
} }
.mdc-chip-set { .mdc-chip-set {
padding: var(--ha-space-1) var(--ha-space-0); padding: var(--ha-space-1) 0;
gap: var(--ha-space-2); gap: var(--ha-space-2);
} }

View File

@@ -266,15 +266,15 @@ export class HaWaDialog extends ScrollableFadeMixin(LitElement) {
/* Used to offset the dialog from the safe areas when space is limited */ /* Used to offset the dialog from the safe areas when space is limited */
transform: translate( transform: translate(
calc( calc(
var(--safe-area-offset-left, var(--ha-space-0)) - var( var(--safe-area-offset-left, 0px) - var(
--safe-area-offset-right, --safe-area-offset-right,
var(--ha-space-0) 0px
) )
), ),
calc( calc(
var(--safe-area-offset-top, var(--ha-space-0)) - var( var(--safe-area-offset-top, 0px) - var(
--safe-area-offset-bottom, --safe-area-offset-bottom,
var(--ha-space-0) 0px
) )
) )
); );
@@ -285,7 +285,7 @@ export class HaWaDialog extends ScrollableFadeMixin(LitElement) {
@media all and (max-width: 450px), all and (max-height: 500px) { @media all and (max-width: 450px), all and (max-height: 500px) {
:host([type="standard"]) { :host([type="standard"]) {
--ha-dialog-border-radius: var(--ha-space-0); --ha-dialog-border-radius: 0;
wa-dialog { wa-dialog {
/* Make the container fill the whole screen width and not the safe width */ /* Make the container fill the whole screen width and not the safe width */
@@ -372,7 +372,7 @@ export class HaWaDialog extends ScrollableFadeMixin(LitElement) {
} }
wa-dialog::part(footer) { wa-dialog::part(footer) {
padding: var(--ha-space-0); padding: 0;
} }
::slotted([slot="footer"]) { ::slotted([slot="footer"]) {

View File

@@ -89,7 +89,7 @@ export class HaTargetPickerItemGroup extends LitElement {
static styles = css` static styles = css`
:host { :host {
display: block; display: block;
--expansion-panel-content-padding: var(--ha-space-0); --expansion-panel-content-padding: 0;
} }
ha-expansion-panel::part(summary) { ha-expansion-panel::part(summary) {
background-color: var(--ha-color-fill-neutral-quiet-resting); background-color: var(--ha-color-fill-neutral-quiet-resting);
@@ -101,7 +101,7 @@ export class HaTargetPickerItemGroup extends LitElement {
min-height: unset; min-height: unset;
} }
ha-md-list { ha-md-list {
padding: var(--ha-space-0); padding: 0;
} }
`; `;
} }

View File

@@ -605,8 +605,8 @@ export class HaTargetPickerItemRow extends LitElement {
buttonLinkStyle, buttonLinkStyle,
css` css`
:host { :host {
--md-list-item-top-space: var(--ha-space-0); --md-list-item-top-space: 0;
--md-list-item-bottom-space: var(--ha-space-0); --md-list-item-bottom-space: 0;
--md-list-item-leading-space: var(--ha-space-2); --md-list-item-leading-space: var(--ha-space-2);
--md-list-item-trailing-space: var(--ha-space-2); --md-list-item-trailing-space: var(--ha-space-2);
--md-list-item-two-line-container-height: 56px; --md-list-item-two-line-container-height: 56px;

View File

@@ -278,8 +278,8 @@ export class HaTargetPickerValueChip extends LitElement {
direction: var(--direction); direction: var(--direction);
} }
.expand-btn { .expand-btn {
margin-right: var(--ha-space-0); margin-right: 0;
margin-inline-end: var(--ha-space-0); margin-inline-end: 0;
margin-inline-start: initial; margin-inline-start: initial;
} }
.mdc-chip.area:not(.add), .mdc-chip.area:not(.add),

View File

@@ -1,4 +1,4 @@
import type { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import type { TemplateResult } from "lit"; import type { TemplateResult } from "lit";
import { html, LitElement, nothing } from "lit"; import { html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
@@ -73,7 +73,7 @@ class HaUserPicker extends LitElement {
`; `;
}; };
private _rowRenderer: ComboBoxLitRenderer<UserComboBoxItem> = (item) => { private _rowRenderer: RenderItemFunction<UserComboBoxItem> = (item) => {
const user = item.user; const user = item.user;
if (!user) { if (!user) {
return html`<ha-combo-box-item type="button" compact> return html`<ha-combo-box-item type="button" compact>

View File

@@ -27,6 +27,7 @@ export type Selector =
| AttributeSelector | AttributeSelector
| BooleanSelector | BooleanSelector
| ButtonToggleSelector | ButtonToggleSelector
| ChooseSelector
| ColorRGBSelector | ColorRGBSelector
| ColorTempSelector | ColorTempSelector
| ConditionSelector | ConditionSelector
@@ -116,6 +117,13 @@ export interface ButtonToggleSelector {
} | null; } | null;
} }
export interface ChooseSelector {
choose: {
choices: Record<string, { selector: Selector }>;
translation_key?: string;
};
}
export interface ColorRGBSelector { export interface ColorRGBSelector {
color_rgb: {} | null; color_rgb: {} | null;
} }

View File

@@ -37,8 +37,8 @@ export class HaMoreInfoControlSelectContainer extends LitElement {
overflow: auto; overflow: auto;
-ms-overflow-style: none; /* IE and Edge */ -ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */ scrollbar-width: none; /* Firefox */
margin: -2px -24px; margin: -2px calc(var(--ha-space-6) * -1);
padding: 2px 24px; padding: 2px var(--ha-space-6);
} }
.controls-scroll::-webkit-scrollbar { .controls-scroll::-webkit-scrollbar {
display: none; display: none;

View File

@@ -84,8 +84,8 @@ export class HaMoreInfoStateHeader extends LitElement {
font-weight: var(--ha-font-weight-medium); font-weight: var(--ha-font-weight-medium);
line-height: var(--ha-line-height-normal); line-height: var(--ha-line-height-normal);
letter-spacing: 0.1px; letter-spacing: 0.1px;
padding: 4px 0; padding: var(--ha-space-1) 0;
margin-bottom: 20px; margin-bottom: var(--ha-space-5);
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
-webkit-user-select: none; -webkit-user-select: none;

View File

@@ -268,14 +268,14 @@ class DialogLightColorFavorite extends LitElement {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 24px; padding: var(--ha-space-6);
flex: 1; flex: 1;
} }
.modes { .modes {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-end; justify-content: flex-end;
padding: 0 24px; padding: 0 var(--ha-space-6);
} }
.wheel { .wheel {
width: 30px; width: 30px;

View File

@@ -254,14 +254,14 @@ export class HaMoreInfoLightFavoriteColors extends LitElement {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: -8px; margin: calc(var(--ha-space-2) * -1);
flex-wrap: wrap; flex-wrap: wrap;
max-width: 250px; max-width: 250px;
user-select: none; user-select: none;
} }
.container > * { .container > * {
margin: 8px; margin: var(--ha-space-2);
} }
.color { .color {

View File

@@ -515,7 +515,7 @@ class LightRgbColorPicker extends LitElement {
hr { hr {
border-color: var(--divider-color); border-color: var(--divider-color);
border-bottom: none; border-bottom: none;
margin: 16px 0; margin: var(--ha-space-4) 0;
} }
`, `,
]; ];

View File

@@ -15,22 +15,22 @@ export const moreInfoControlStyle = css`
} }
.controls:not(:last-child) { .controls:not(:last-child) {
margin-bottom: 24px; margin-bottom: var(--ha-space-6);
} }
.controls > *:not(:last-child) { .controls > *:not(:last-child) {
margin-bottom: 24px; margin-bottom: var(--ha-space-6);
} }
.buttons { .buttons {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-bottom: 12px; margin-bottom: var(--ha-space-3);
} }
.buttons > * { .buttons > * {
margin: 8px; margin: var(--ha-space-2);
} }
ha-attributes { ha-attributes {
@@ -38,6 +38,6 @@ export const moreInfoControlStyle = css`
width: 100%; width: 100%;
} }
ha-more-info-control-select-container + ha-attributes:not([empty]) { ha-more-info-control-select-container + ha-attributes:not([empty]) {
margin-top: 16px; margin-top: var(--ha-space-4);
} }
`; `;

View File

@@ -209,7 +209,7 @@ class MoreInfoSirenAdvancedControls extends LitElement {
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
gap: var(--ha-space-4); gap: var(--ha-space-4);
margin-top: 16px; margin-top: var(--ha-space-4);
} }
ha-control-button { ha-control-button {
--control-button-border-radius: var(--ha-border-radius-xl); --control-button-border-radius: var(--ha-border-radius-xl);

View File

@@ -48,7 +48,7 @@ class MoreInfoViewVoiceAssistants extends LitElement {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 24px; padding: var(--ha-space-6);
flex: 1; flex: 1;
} }
`, `,

View File

@@ -52,7 +52,7 @@ class MoreInfoAutomation extends LitElement {
justify-content: space-between; justify-content: space-between;
} }
.actions { .actions {
margin: 8px 0; margin: var(--ha-space-2) 0;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;
@@ -60,7 +60,7 @@ class MoreInfoAutomation extends LitElement {
hr { hr {
border-color: var(--divider-color); border-color: var(--divider-color);
border-bottom: none; border-bottom: none;
margin: 16px 0; margin: var(--ha-space-4) 0;
} }
`; `;
} }

View File

@@ -106,7 +106,7 @@ class MoreInfoCamera extends LitElement {
flex-wrap: wrap; flex-wrap: wrap;
justify-content: flex-end; justify-content: flex-end;
box-sizing: border-box; box-sizing: border-box;
padding: 16px; padding: var(--ha-space-4);
z-index: 1; z-index: 1;
gap: var(--ha-space-2); gap: var(--ha-space-2);
} }

View File

@@ -511,7 +511,7 @@ class MoreInfoClimate extends LitElement {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
margin-bottom: 40px; margin-bottom: var(--ha-space-10);
} }
.current div { .current div {
@@ -534,7 +534,7 @@ class MoreInfoClimate extends LitElement {
font-size: var(--ha-font-size-m); font-size: var(--ha-font-size-m);
line-height: var(--ha-line-height-condensed); line-height: var(--ha-line-height-condensed);
letter-spacing: 0.4px; letter-spacing: 0.4px;
margin-bottom: 4px; margin-bottom: var(--ha-space-1);
} }
.current .value { .current .value {
@@ -545,7 +545,7 @@ class MoreInfoClimate extends LitElement {
} }
ha-select { ha-select {
width: 100%; width: 100%;
margin-top: 8px; margin-top: var(--ha-space-2);
} }
.container-humidity .single-row { .container-humidity .single-row {
@@ -561,7 +561,7 @@ class MoreInfoClimate extends LitElement {
} }
.single-row { .single-row {
padding: 8px 0; padding: var(--ha-space-2) 0;
} }
`, `,
]; ];

View File

@@ -87,7 +87,7 @@ export class MoreInfoConfigurator extends LitElement {
flex-direction: column; flex-direction: column;
} }
p { p {
margin: 8px 0; margin: var(--ha-space-2) 0;
} }
a { a {

View File

@@ -62,7 +62,7 @@ class MoreInfoCounter extends LitElement {
static styles = css` static styles = css`
.actions { .actions {
margin: 8px 0; margin: var(--ha-space-2) 0;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;

View File

@@ -194,7 +194,7 @@ class MoreInfoCover extends LitElement {
align-items: center; align-items: center;
} }
.main-control > * { .main-control > * {
margin: 0 8px; margin: 0 var(--ha-space-2);
} }
`, `,
]; ];

View File

@@ -72,8 +72,8 @@ class MoreInfoDatetime extends LitElement {
justify-content: flex-end; justify-content: flex-end;
} }
ha-date-input + ha-time-input { ha-date-input + ha-time-input {
margin-left: 4px; margin-left: var(--ha-space-1);
margin-inline-start: 4px; margin-inline-start: var(--ha-space-1);
margin-inline-end: initial; margin-inline-end: initial;
} }
`; `;

View File

@@ -100,7 +100,7 @@ class MoreInfoGroup extends LitElement {
css` css`
state-card-content { state-card-content {
display: block; display: block;
margin-top: 8px; margin-top: var(--ha-space-2);
} }
`, `,
]; ];

View File

@@ -217,7 +217,7 @@ class MoreInfoHumidifier extends LitElement {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
margin-bottom: 40px; margin-bottom: var(--ha-space-10);
} }
.current div { .current div {
display: flex; display: flex;
@@ -237,7 +237,7 @@ class MoreInfoHumidifier extends LitElement {
font-size: var(--ha-font-size-m); font-size: var(--ha-font-size-m);
line-height: var(--ha-line-height-condensed); line-height: var(--ha-line-height-condensed);
letter-spacing: 0.4px; letter-spacing: 0.4px;
margin-bottom: 4px; margin-bottom: var(--ha-space-1);
} }
.current .value { .current .value {
font-size: var(--ha-font-size-xl); font-size: var(--ha-font-size-xl);

View File

@@ -84,8 +84,8 @@ class MoreInfoInputDatetime extends LitElement {
justify-content: flex-end; justify-content: flex-end;
} }
ha-date-input + ha-time-input { ha-date-input + ha-time-input {
margin-left: 4px; margin-left: var(--ha-space-1);
margin-inline-start: 4px; margin-inline-start: var(--ha-space-1);
margin-inline-end: initial; margin-inline-end: initial;
} }
`; `;

View File

@@ -192,7 +192,7 @@ class MoreInfoLock extends LitElement {
margin: 0 auto; margin: 0 auto;
} }
ha-control-button-group + ha-attributes:not([empty]) { ha-control-button-group + ha-attributes:not([empty]) {
margin-top: 16px; margin-top: var(--ha-space-4);
} }
@keyframes pulse { @keyframes pulse {
0% { 0% {

View File

@@ -528,11 +528,11 @@ class MoreInfoMediaPlayer extends LitElement {
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--ha-space-3); gap: var(--ha-space-3);
margin-left: 8px; margin-left: var(--ha-space-2);
} }
.volume ha-svg-icon { .volume ha-svg-icon {
padding: 4px; padding: var(--ha-space-1);
height: 16px; height: 16px;
width: 16px; width: 16px;
} }
@@ -545,17 +545,17 @@ class MoreInfoMediaPlayer extends LitElement {
.badge { .badge {
position: absolute; position: absolute;
top: -10px; top: -10px;
left: 16px; left: var(--ha-space-4);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 16px; height: 16px;
min-width: 8px; min-width: var(--ha-space-2);
border-radius: var(--ha-border-radius-md); border-radius: var(--ha-border-radius-md);
font-weight: var(--ha-font-weight-normal); font-weight: var(--ha-font-weight-normal);
font-size: var(--ha-font-size-xs); font-size: var(--ha-font-size-xs);
background-color: var(--primary-color); background-color: var(--primary-color);
padding: 0 4px; padding: 0 var(--ha-space-1);
color: var(--text-primary-color); color: var(--text-primary-color);
} }
@@ -572,13 +572,13 @@ class MoreInfoMediaPlayer extends LitElement {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
margin: 8px 0 8px 8px; margin: var(--ha-space-2) 0 var(--ha-space-2) var(--ha-space-2);
} }
.media-title { .media-title {
font-size: var(--ha-font-size-xl); font-size: var(--ha-font-size-xl);
font-weight: var(--ha-font-weight-bold); font-weight: var(--ha-font-weight-bold);
margin-bottom: 4px; margin-bottom: var(--ha-space-1);
} }
.media-artist { .media-artist {

View File

@@ -72,12 +72,12 @@ class MoreInfoPerson extends LitElement {
justify-content: space-between; justify-content: space-between;
} }
.actions { .actions {
margin: 8px 0; margin: var(--ha-space-2) 0;
text-align: right; text-align: right;
} }
ha-map { ha-map {
margin-top: 16px; margin-top: var(--ha-space-4);
margin-bottom: 16px; margin-bottom: var(--ha-space-4);
} }
`; `;
} }

View File

@@ -227,24 +227,24 @@ class MoreInfoScript extends LitElement {
visibility: hidden; visibility: hidden;
color: var(--secondary-text-color); color: var(--secondary-text-color);
text-align: center; text-align: center;
margin-bottom: 16px; margin-bottom: var(--ha-space-4);
height: 21px; height: 21px;
} }
.queue.has-queue { .queue.has-queue {
visibility: visible; visibility: visible;
} }
.fields { .fields {
padding: 16px; padding: var(--ha-space-4);
border: 1px solid var(--divider-color); border: 1px solid var(--divider-color);
border-radius: var(--ha-border-radius-md); border-radius: var(--ha-border-radius-md);
margin-bottom: 16px; margin-bottom: var(--ha-space-4);
} }
.fields .title { .fields .title {
font-weight: var(--ha-font-weight-bold); font-weight: var(--ha-font-weight-bold);
} }
ha-control-button ha-svg-icon { ha-control-button ha-svg-icon {
z-index: -1; z-index: -1;
margin-right: 4px; margin-right: var(--ha-space-1);
} }
ha-service-control { ha-service-control {
--service-control-padding: 0; --service-control-padding: 0;
@@ -252,7 +252,7 @@ class MoreInfoScript extends LitElement {
} }
ha-markdown { ha-markdown {
text-align: center; text-align: center;
padding: 0 16px; padding: 0 var(--ha-space-4);
} }
`; `;
} }

View File

@@ -83,7 +83,7 @@ class MoreInfoSun extends LitElement {
hr { hr {
border-color: var(--divider-color); border-color: var(--divider-color);
border-bottom: none; border-bottom: none;
margin: 16px 0; margin: var(--ha-space-4) 0;
} }
`; `;
} }

View File

@@ -80,7 +80,7 @@ class MoreInfoTimer extends LitElement {
static styles = css` static styles = css`
.actions { .actions {
margin: 8px 0; margin: var(--ha-space-2) 0;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;

View File

@@ -448,14 +448,14 @@ class MoreInfoUpdate extends LitElement {
hr { hr {
border-color: var(--divider-color); border-color: var(--divider-color);
border-bottom: none; border-bottom: none;
margin: 16px 0; margin: var(--ha-space-4) 0;
} }
ha-expansion-panel { ha-expansion-panel {
margin: 16px 0; margin: var(--ha-space-4) 0;
} }
.summary { .summary {
margin-bottom: 16px; margin-bottom: var(--ha-space-4);
} }
.row { .row {
@@ -473,8 +473,10 @@ class MoreInfoUpdate extends LitElement {
); );
position: sticky; position: sticky;
bottom: 0; bottom: 0;
margin: 0 -24px 0 -24px; margin: 0 calc(var(--ha-space-6) * -1) 0 calc(var(--ha-space-6) * -1);
margin-bottom: calc(-1 * max(var(--safe-area-inset-bottom), 24px)); margin-bottom: calc(
-1 * max(var(--safe-area-inset-bottom), var(--ha-space-6))
);
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -486,8 +488,8 @@ class MoreInfoUpdate extends LitElement {
ha-md-list { ha-md-list {
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
margin-bottom: -16px; margin-bottom: calc(var(--ha-space-4) * -1);
margin-top: -4px; margin-top: calc(var(--ha-space-1) * -1);
--md-sys-color-surface: var( --md-sys-color-surface: var(
--ha-dialog-surface-background, --ha-dialog-surface-background,
var(--mdc-theme-surface, #fff) var(--mdc-theme-surface, #fff)
@@ -495,8 +497,8 @@ class MoreInfoUpdate extends LitElement {
} }
ha-md-list-item { ha-md-list-item {
--md-list-item-leading-space: 24px; --md-list-item-leading-space: var(--ha-space-6);
--md-list-item-trailing-space: 24px; --md-list-item-trailing-space: var(--ha-space-6);
} }
.actions { .actions {
@@ -506,7 +508,7 @@ class MoreInfoUpdate extends LitElement {
flex-wrap: wrap; flex-wrap: wrap;
justify-content: flex-end; justify-content: flex-end;
box-sizing: border-box; box-sizing: border-box;
padding: 16px; padding: var(--ha-space-4);
z-index: 1; z-index: 1;
gap: var(--ha-space-2); gap: var(--ha-space-2);
} }
@@ -520,12 +522,12 @@ class MoreInfoUpdate extends LitElement {
align-items: center; align-items: center;
} }
mwc-linear-progress { mwc-linear-progress {
margin-bottom: -8px; margin-bottom: calc(var(--ha-space-2) * -1);
margin-top: 4px; margin-top: var(--ha-space-1);
} }
ha-markdown { ha-markdown {
direction: ltr; direction: ltr;
padding-bottom: 16px; padding-bottom: var(--ha-space-4);
box-sizing: border-box; box-sizing: border-box;
} }
ha-markdown.hidden { ha-markdown.hidden {
@@ -534,7 +536,7 @@ class MoreInfoUpdate extends LitElement {
.loader { .loader {
height: 80px; height: 80px;
box-sizing: border-box; box-sizing: border-box;
padding-bottom: 16px; padding-bottom: var(--ha-space-4);
} }
`; `;
} }

View File

@@ -173,7 +173,7 @@ class MoreInfoValve extends LitElement {
align-items: center; align-items: center;
} }
.main-control > * { .main-control > * {
margin: 0 8px; margin: 0 var(--ha-space-2);
} }
`, `,
]; ];

View File

@@ -214,7 +214,7 @@ class MoreInfoWaterHeater extends LitElement {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
margin-bottom: 40px; margin-bottom: var(--ha-space-10);
} }
.current div { .current div {
@@ -237,7 +237,7 @@ class MoreInfoWaterHeater extends LitElement {
font-size: var(--ha-font-size-m); font-size: var(--ha-font-size-m);
line-height: var(--ha-line-height-condensed); line-height: var(--ha-line-height-condensed);
letter-spacing: 0.4px; letter-spacing: 0.4px;
margin-bottom: 4px; margin-bottom: var(--ha-space-1);
} }
.current .value { .current .value {

View File

@@ -440,13 +440,13 @@ class MoreInfoWeather extends LitElement {
css` css`
ha-svg-icon { ha-svg-icon {
color: var(--state-icon-color); color: var(--state-icon-color);
margin-left: 8px; margin-left: var(--ha-space-2);
margin-inline-start: 8px; margin-inline-start: var(--ha-space-2);
margin-inline-end: initial; margin-inline-end: initial;
} }
.section { .section {
margin: 16px 0 8px 0; margin: var(--ha-space-4) 0 var(--ha-space-2) 0;
font-size: 1.2em; font-size: 1.2em;
} }
@@ -470,14 +470,14 @@ class MoreInfoWeather extends LitElement {
.main { .main {
flex: 1; flex: 1;
margin-left: 24px; margin-left: var(--ha-space-6);
margin-inline-start: 24px; margin-inline-start: var(--ha-space-6);
margin-inline-end: initial; margin-inline-end: initial;
} }
.attribution { .attribution {
text-align: center; text-align: center;
margin-top: 16px; margin-top: var(--ha-space-4);
} }
.time-ago, .time-ago,
@@ -500,15 +500,15 @@ class MoreInfoWeather extends LitElement {
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 16px; margin-bottom: var(--ha-space-4);
} }
.icon-image { .icon-image {
display: flex; display: flex;
align-items: center; align-items: center;
min-width: 64px; min-width: 64px;
margin-right: 16px; margin-right: var(--ha-space-4);
margin-inline-end: 16px; margin-inline-end: var(--ha-space-4);
margin-inline-start: initial; margin-inline-start: initial;
} }
@@ -534,7 +534,7 @@ class MoreInfoWeather extends LitElement {
.temp-attribute .temp { .temp-attribute .temp {
position: relative; position: relative;
margin-right: 24px; margin-right: var(--ha-space-6);
direction: ltr; direction: ltr;
} }
@@ -557,8 +557,8 @@ class MoreInfoWeather extends LitElement {
.name-state { .name-state {
overflow: hidden; overflow: hidden;
padding-right: 12px; padding-right: var(--ha-space-3);
padding-inline-end: 12px; padding-inline-end: var(--ha-space-3);
padding-inline-start: initial; padding-inline-start: initial;
width: 100%; width: 100%;
} }
@@ -572,7 +572,7 @@ class MoreInfoWeather extends LitElement {
.forecast { .forecast {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
padding: 16px; padding: var(--ha-space-4);
padding-bottom: 0px; padding-bottom: 0px;
overflow-x: auto; overflow-x: auto;
scrollbar-color: var(--scrollbar-thumb-color) transparent; scrollbar-color: var(--scrollbar-thumb-color) transparent;
@@ -634,8 +634,8 @@ class MoreInfoWeather extends LitElement {
} }
.forecast-image-icon { .forecast-image-icon {
padding-top: 4px; padding-top: var(--ha-space-1);
padding-bottom: 4px; padding-bottom: var(--ha-space-1);
display: flex; display: flex;
justify-content: center; justify-content: center;
} }

View File

@@ -802,8 +802,7 @@ export class MoreInfoDialog extends ScrollableFadeMixin(LitElement) {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
margin: var(--ha-space-0) var(--ha-space-0) margin: 0 0 calc(var(--ha-space-2) * -1) 0;
calc(var(--ha-space-2) * -1) var(--ha-space-0);
} }
.title p { .title p {

View File

@@ -58,7 +58,7 @@ export class MoreInfoHistoryAndLogbook extends LitElement {
display: block; display: block;
} }
ha-more-info-history + ha-more-info-logbook { ha-more-info-history + ha-more-info-logbook {
margin-top: 16px; margin-top: var(--ha-space-4);
} }
`; `;
} }

View File

@@ -264,7 +264,7 @@ export class MoreInfoHistory extends LitElement {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 8px; margin-bottom: var(--ha-space-2);
} }
.header > a, .header > a,
a:visited { a:visited {

View File

@@ -130,8 +130,8 @@ export class MoreInfoInfo extends LitElement {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1; flex: 1;
padding: 24px; padding: var(--ha-space-6);
padding-bottom: max(var(--safe-area-inset-bottom), 24px); padding-bottom: max(var(--safe-area-inset-bottom), var(--ha-space-6));
} }
[data-domain="camera"] .content { [data-domain="camera"] .content {
@@ -153,7 +153,7 @@ export class MoreInfoInfo extends LitElement {
ha-more-info-history, ha-more-info-history,
ha-more-info-logbook:not(:last-child) { ha-more-info-logbook:not(:last-child) {
display: block; display: block;
margin-bottom: 16px; margin-bottom: var(--ha-space-4);
} }
ha-alert { ha-alert {

View File

@@ -82,7 +82,7 @@ export class MoreInfoLogbook extends LitElement {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 8px; margin-bottom: var(--ha-space-2);
} }
.header > a, .header > a,
a:visited { a:visited {

View File

@@ -83,7 +83,8 @@ export class HaMoreInfoSettings extends LitElement {
return [ return [
css` css`
.content { .content {
padding: 8px 24px 24px 24px; padding: var(--ha-space-2) var(--ha-space-6) var(--ha-space-6)
var(--ha-space-6);
} }
`, `,
]; ];

View File

@@ -119,7 +119,7 @@ class MoreInfoContent extends LitElement {
hui-section { hui-section {
width: 100%; width: 100%;
display: block; display: block;
margin-top: 16px; margin-top: var(--ha-space-4);
} }
`; `;
} }

View File

@@ -1120,7 +1120,7 @@ export class QuickBar extends LitElement {
} }
.nothing-found { .nothing-found {
padding: var(--ha-space-4) var(--ha-space-0); padding: var(--ha-space-4) 0;
text-align: center; text-align: center;
} }

View File

@@ -123,8 +123,8 @@ export const ScrollableFadeMixin = <T extends Constructor<LitElement>>(
.fade-top, .fade-top,
.fade-bottom { .fade-bottom {
position: absolute; position: absolute;
left: var(--ha-space-0); left: 0;
right: var(--ha-space-0); right: 0;
height: var(--ha-space-4); height: var(--ha-space-4);
pointer-events: none; pointer-events: none;
transition: opacity 180ms ease-in-out; transition: opacity 180ms ease-in-out;
@@ -137,10 +137,10 @@ export const ScrollableFadeMixin = <T extends Constructor<LitElement>>(
opacity: 0; opacity: 0;
} }
.fade-top { .fade-top {
top: var(--ha-space-0); top: 0;
} }
.fade-bottom { .fade-bottom {
bottom: var(--ha-space-0); bottom: 0;
transform: rotate(180deg); transform: rotate(180deg);
} }

View File

@@ -2016,12 +2016,12 @@ class DialogAddAutomationElement
--ha-bottom-sheet-height: calc(100dvh - var(--ha-space-12)); --ha-bottom-sheet-height: calc(100dvh - var(--ha-space-12));
--ha-bottom-sheet-max-height: var(--ha-bottom-sheet-height); --ha-bottom-sheet-max-height: var(--ha-bottom-sheet-height);
--ha-bottom-sheet-max-width: 888px; --ha-bottom-sheet-max-width: 888px;
--ha-bottom-sheet-padding: var(--ha-space-0); --ha-bottom-sheet-padding: 0;
--ha-bottom-sheet-surface-background: var(--card-background-color); --ha-bottom-sheet-surface-background: var(--card-background-color);
} }
ha-wa-dialog { ha-wa-dialog {
--dialog-content-padding: var(--ha-space-0); --dialog-content-padding: 0;
--ha-dialog-min-height: min( --ha-dialog-min-height: min(
800px, 800px,
calc( calc(
@@ -2045,7 +2045,7 @@ class DialogAddAutomationElement
search-input { search-input {
display: block; display: block;
margin: var(--ha-space-0) var(--ha-space-4); margin: 0 var(--ha-space-4);
} }
ha-button-toggle-group { ha-button-toggle-group {
@@ -2079,7 +2079,7 @@ class DialogAddAutomationElement
.groups { .groups {
overflow: auto; overflow: auto;
flex: 4; flex: 4;
margin-inline-end: var(--ha-space-0); margin-inline-end: 0;
} }
ha-automation-add-from-target.hidden { ha-automation-add-from-target.hidden {

View File

@@ -213,8 +213,8 @@ export class HaAutomationAddItems extends LitElement {
background-color: var(--ha-color-surface-default); background-color: var(--ha-color-surface-default);
align-items: center; align-items: center;
color: var(--ha-color-text-secondary); color: var(--ha-color-text-secondary);
padding: var(--ha-space-0); padding: 0;
margin: var(--ha-space-0) var(--ha-space-4) margin: 0 var(--ha-space-4)
max(var(--safe-area-inset-bottom), var(--ha-space-3)); max(var(--safe-area-inset-bottom), var(--ha-space-3));
line-height: var(--ha-line-height-expanded); line-height: var(--ha-line-height-expanded);
justify-content: center; justify-content: center;
@@ -233,7 +233,7 @@ export class HaAutomationAddItems extends LitElement {
--md-list-item-supporting-text-font: var(--ha-font-family-body); --md-list-item-supporting-text-font: var(--ha-font-family-body);
--ha-md-list-item-gap: var(--ha-space-3); --ha-md-list-item-gap: var(--ha-space-3);
gap: var(--ha-space-2); gap: var(--ha-space-2);
padding: var(--ha-space-0) var(--ha-space-4); padding: 0 var(--ha-space-4);
} }
.items ha-md-list ha-md-list-item { .items ha-md-list ha-md-list-item {
border-radius: var(--ha-border-radius-lg); border-radius: var(--ha-border-radius-lg);

View File

@@ -327,7 +327,7 @@ export class HaAutomationAddSearch extends LitElement {
style=${styleMap({ style=${styleMap({
width: "var(--ha-space-12)", width: "var(--ha-space-12)",
position: "absolute", position: "absolute",
top: "var(--ha-space-0)", top: "0",
left: rtl ? undefined : "var(--ha-space-1)", left: rtl ? undefined : "var(--ha-space-1)",
right: rtl ? "var(--ha-space-1)" : undefined, right: rtl ? "var(--ha-space-1)" : undefined,
transform: rtl ? "scaleX(-1)" : "", transform: rtl ? "scaleX(-1)" : "",

View File

@@ -256,6 +256,7 @@ export class HaPlatformCondition extends LitElement {
: undefined} : undefined}
.placeholder=${dataField.default} .placeholder=${dataField.default}
.localizeValue=${this._localizeValueCallback} .localizeValue=${this._localizeValueCallback}
.required=${dataField.required}
></ha-selector> ></ha-selector>
</ha-settings-row>` </ha-settings-row>`
: nothing; : nothing;

View File

@@ -292,6 +292,7 @@ export class HaPlatformTrigger extends LitElement {
: undefined} : undefined}
.placeholder=${dataField.default} .placeholder=${dataField.default}
.localizeValue=${this._localizeValueCallback} .localizeValue=${this._localizeValueCallback}
.required=${dataField.required}
></ha-selector> ></ha-selector>
</ha-settings-row>` </ha-settings-row>`
: nothing; : nothing;

View File

@@ -462,7 +462,7 @@ class AddIntegrationDialog extends LitElement {
style=${styleMap({ style=${styleMap({
width: `${this._width}px`, width: `${this._width}px`,
height: this._narrow height: this._narrow
? "calc(100vh - 184px - var(--safe-area-inset-top, var(--ha-space-0)) - var(--safe-area-inset-bottom, var(--ha-space-0)))" ? "calc(100vh - 184px - var(--safe-area-inset-top, 0px) - var(--safe-area-inset-bottom, 0px))"
: "500px", : "500px",
})} })}
@click=${this._integrationPicked} @click=${this._integrationPicked}

View File

@@ -199,7 +199,7 @@ export class DialogLabsPreviewFeatureEnable
static readonly styles = css` static readonly styles = css`
ha-wa-dialog { ha-wa-dialog {
--dialog-content-padding: var(--ha-space-0); --dialog-content-padding: 0;
} }
p { p {

View File

@@ -31,7 +31,11 @@ import { formatTime } from "../../../../../common/datetime/format_time";
import type { ECOption } from "../../../../../resources/echarts/echarts"; import type { ECOption } from "../../../../../resources/echarts/echarts";
import { filterXSS } from "../../../../../common/util/xss"; import { filterXSS } from "../../../../../common/util/xss";
export function getSuggestedMax(dayDifference: number, end: Date): number { export function getSuggestedMax(
dayDifference: number,
end: Date,
detailedDailyData = false
): number {
let suggestedMax = new Date(end); let suggestedMax = new Date(end);
// Sometimes around DST we get a time of 0:59 instead of 23:59 as expected. // Sometimes around DST we get a time of 0:59 instead of 23:59 as expected.
@@ -40,7 +44,9 @@ export function getSuggestedMax(dayDifference: number, end: Date): number {
suggestedMax = subHours(suggestedMax, 1); suggestedMax = subHours(suggestedMax, 1);
} }
suggestedMax.setMinutes(0, 0, 0); if (!detailedDailyData) {
suggestedMax.setMinutes(0, 0, 0);
}
if (dayDifference > 35) { if (dayDifference > 35) {
suggestedMax.setDate(1); suggestedMax.setDate(1);
} }
@@ -77,7 +83,8 @@ export function getCommonOptions(
unit?: string, unit?: string,
compareStart?: Date, compareStart?: Date,
compareEnd?: Date, compareEnd?: Date,
formatTotal?: (total: number) => string formatTotal?: (total: number) => string,
detailedDailyData = false
): ECOption { ): ECOption {
const dayDifference = differenceInDays(end, start); const dayDifference = differenceInDays(end, start);
@@ -89,7 +96,7 @@ export function getCommonOptions(
xAxis: { xAxis: {
type: "time", type: "time",
min: start, min: start,
max: getSuggestedMax(dayDifference, end), max: getSuggestedMax(dayDifference, end, detailedDailyData),
}, },
yAxis: { yAxis: {
type: "value", type: "value",

View File

@@ -1,4 +1,4 @@
import { endOfToday, isToday, startOfToday } from "date-fns"; import { endOfToday, isSameDay, isToday, startOfToday } from "date-fns";
import type { HassConfig, UnsubscribeFunc } from "home-assistant-js-websocket"; import type { HassConfig, UnsubscribeFunc } from "home-assistant-js-websocket";
import type { PropertyValues } from "lit"; import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
@@ -132,7 +132,9 @@ export class HuiPowerSourcesGraphCard
config, config,
"kW", "kW",
compareStart, compareStart,
compareEnd compareEnd,
undefined,
true
), ),
legend: { legend: {
show: this._config?.show_legend !== false, show: this._config?.show_legend !== false,
@@ -210,14 +212,17 @@ export class HuiPowerSourcesGraphCard
const { positive, negative } = this._processData( const { positive, negative } = this._processData(
statIds[key].stats.map((id: string) => { statIds[key].stats.map((id: string) => {
const stats = energyData.stats[id] ?? []; const stats = energyData.stats[id] ?? [];
const currentStateWatts = getPowerFromState(this.hass.states[id]); if (isSameDay(now, this._start) && isSameDay(now, this._end)) {
if (currentStateWatts !== undefined) { // Append current state if we are showing today
// getPowerFromState returns power in W; convert to kW for this graph const currentStateWatts = getPowerFromState(this.hass.states[id]);
stats.push({ if (currentStateWatts !== undefined) {
start: now, // getPowerFromState returns power in W; convert to kW for this graph
end: now, stats.push({
mean: currentStateWatts / 1000, start: now,
}); end: now,
mean: currentStateWatts / 1000,
});
}
} }
return stats; return stats;
}) })

View File

@@ -732,9 +732,7 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
padding: 0 var(--ha-space-3) var(--ha-space-3) var(--ha-space-3); padding: 0 var(--ha-space-3) var(--ha-space-3) var(--ha-space-3);
} }
.container.horizontal hui-card-features { .container.horizontal hui-card-features {
width: calc( width: calc(50% - var(--column-gap, 0px) / 2 - var(--ha-space-3));
50% - var(--column-gap, var(--ha-space-0)) / 2 - var(--ha-space-3)
);
flex: none; flex: none;
--feature-height: var(--ha-space-9); --feature-height: var(--ha-space-9);
padding: 0 var(--ha-space-3); padding: 0 var(--ha-space-3);

View File

@@ -142,11 +142,10 @@ export const haStyleDialog = css`
--mdc-dialog-max-width: 600px; --mdc-dialog-max-width: 600px;
--mdc-dialog-max-width: min(600px, 95vw); --mdc-dialog-max-width: min(600px, 95vw);
--justify-action-buttons: space-between; --justify-action-buttons: space-between;
--dialog-container-padding: var(--safe-area-inset-top, var(--ha-space-0)) --dialog-container-padding: var(--safe-area-inset-top, 0)
var(--safe-area-inset-right, var(--ha-space-0)) var(--safe-area-inset-right, 0) var(--safe-area-inset-bottom, 0)
var(--safe-area-inset-bottom, var(--ha-space-0)) var(--safe-area-inset-left, 0);
var(--safe-area-inset-left, var(--ha-space-0)); --dialog-surface-padding: 0px;
--dialog-surface-padding: var(--ha-space-0);
} }
ha-dialog .form { ha-dialog .form {
@@ -166,11 +165,10 @@ export const haStyleDialog = css`
--mdc-dialog-min-height: 100svh; --mdc-dialog-min-height: 100svh;
--mdc-dialog-max-height: 100vh; --mdc-dialog-max-height: 100vh;
--mdc-dialog-max-height: 100svh; --mdc-dialog-max-height: 100svh;
--dialog-container-padding: var(--ha-space-0); --dialog-container-padding: 0px;
--dialog-surface-padding: var(--safe-area-inset-top, var(--ha-space-0)) --dialog-surface-padding: var(--safe-area-inset-top, 0)
var(--safe-area-inset-right, var(--ha-space-0)) var(--safe-area-inset-right, 0) var(--safe-area-inset-bottom, 0)
var(--safe-area-inset-bottom, var(--ha-space-0)) var(--safe-area-inset-left, 0);
var(--safe-area-inset-left, var(--ha-space-0));
--vertical-align-dialog: flex-end; --vertical-align-dialog: flex-end;
--ha-dialog-border-radius: var(--ha-border-radius-square); --ha-dialog-border-radius: var(--ha-border-radius-square);
} }
@@ -188,13 +186,13 @@ export const haStyleDialogFixedTop = css`
--mdc-dialog-max-height: calc( --mdc-dialog-max-height: calc(
100vh - var(--dialog-surface-margin-top) - var(--ha-space-2) - var( 100vh - var(--dialog-surface-margin-top) - var(--ha-space-2) - var(
--safe-area-inset-y, --safe-area-inset-y,
var(--ha-space-0) 0px
) )
); );
--mdc-dialog-max-height: calc( --mdc-dialog-max-height: calc(
100svh - var(--dialog-surface-margin-top) - var(--ha-space-2) - var( 100svh - var(--dialog-surface-margin-top) - var(--ha-space-2) - var(
--safe-area-inset-y, --safe-area-inset-y,
var(--ha-space-0) 0px
) )
); );
} }
@@ -202,7 +200,7 @@ export const haStyleDialogFixedTop = css`
@media all and (max-width: 450px), all and (max-height: 500px) { @media all and (max-width: 450px), all and (max-height: 500px) {
ha-dialog { ha-dialog {
/* When in fullscreen, dialog should be attached to top */ /* When in fullscreen, dialog should be attached to top */
--dialog-surface-margin-top: var(--ha-space-0); --dialog-surface-margin-top: 0px;
--mdc-dialog-min-height: 100vh; --mdc-dialog-min-height: 100vh;
--mdc-dialog-min-height: 100svh; --mdc-dialog-min-height: 100svh;
--mdc-dialog-max-height: 100vh; --mdc-dialog-max-height: 100vh;

View File

@@ -339,12 +339,6 @@ export const colorStyles = css`
--ha-assist-chip-filled-container-color: rgba(var(--rgb-primary-text-color), 0.15); --ha-assist-chip-filled-container-color: rgba(var(--rgb-primary-text-color), 0.15);
--ha-assist-chip-active-container-color: rgba(var(--rgb-primary-color), 0.15); --ha-assist-chip-active-container-color: rgba(var(--rgb-primary-color), 0.15);
--chip-background-color: rgba(var(--rgb-primary-text-color), 0.15); --chip-background-color: rgba(var(--rgb-primary-text-color), 0.15);
/* Vaadin */
--material-body-text-color: var(--primary-text-color);
--material-background-color: var(--card-background-color);
--material-secondary-background-color: var(--secondary-background-color);
--material-secondary-text-color: var(--secondary-text-color);
} }
`; `;

View File

@@ -21,7 +21,6 @@ export const coreStyles = css`
--ha-border-radius-square: 0; --ha-border-radius-square: 0;
/* Spacing */ /* Spacing */
--ha-space-0: 0px;
--ha-space-1: 4px; --ha-space-1: 4px;
--ha-space-2: 8px; --ha-space-2: 8px;
--ha-space-3: 12px; --ha-space-3: 12px;

View File

@@ -36,12 +36,6 @@ export const typographyStyles = css`
--ha-font-smoothing: antialiased; --ha-font-smoothing: antialiased;
--ha-moz-osx-font-smoothing: grayscale; --ha-moz-osx-font-smoothing: grayscale;
/* Vaadin typography */
--material-h6-font-size: var(--ha-font-size-m);
--material-small-font-size: var(--ha-font-size-xs);
--material-caption-font-size: var(--ha-font-size-2xs);
--material-button-font-size: var(--ha-font-size-xs);
/* Add font to lists since default does not handle non-latin characters */ /* Add font to lists since default does not handle non-latin characters */
--md-list-item-label-text-font: var(--ha-font-family-body); --md-list-item-label-text-font: var(--ha-font-family-body);
--md-list-item-supporting-text-font: var(--ha-font-family-body); --md-list-item-supporting-text-font: var(--ha-font-family-body);

View File

@@ -76,6 +76,60 @@
], ],
"@lit-labs/observers/resize-controller": [ "@lit-labs/observers/resize-controller": [
"./node_modules/@lit-labs/observers/resize-controller.js" "./node_modules/@lit-labs/observers/resize-controller.js"
],
"@formatjs/intl-durationformat/should-polyfill": [
"./node_modules/@formatjs/intl-durationformat/should-polyfill.js"
],
"@formatjs/intl-durationformat/polyfill-force": [
"./node_modules/@formatjs/intl-durationformat/polyfill-force.js"
],
"@formatjs/intl-datetimeformat/should-polyfill": [
"./node_modules/@formatjs/intl-datetimeformat/should-polyfill.js"
],
"@formatjs/intl-datetimeformat/polyfill-force": [
"./node_modules/@formatjs/intl-datetimeformat/polyfill-force.js"
],
"@formatjs/intl-displaynames/should-polyfill": [
"./node_modules/@formatjs/intl-displaynames/should-polyfill.js"
],
"@formatjs/intl-displaynames/polyfill-force": [
"./node_modules/@formatjs/intl-displaynames/polyfill-force.js"
],
"@formatjs/intl-getcanonicallocales/should-polyfill": [
"./node_modules/@formatjs/intl-getcanonicallocales/should-polyfill.js"
],
"@formatjs/intl-getcanonicallocales/polyfill-force": [
"./node_modules/@formatjs/intl-getcanonicallocales/polyfill-force.js"
],
"@formatjs/intl-listformat/should-polyfill": [
"./node_modules/@formatjs/intl-listformat/should-polyfill.js"
],
"@formatjs/intl-listformat/polyfill-force": [
"./node_modules/@formatjs/intl-listformat/polyfill-force.js"
],
"@formatjs/intl-locale/should-polyfill": [
"./node_modules/@formatjs/intl-locale/should-polyfill.js"
],
"@formatjs/intl-locale/polyfill-force": [
"./node_modules/@formatjs/intl-locale/polyfill-force.js"
],
"@formatjs/intl-numberformat/should-polyfill": [
"./node_modules/@formatjs/intl-numberformat/should-polyfill.js"
],
"@formatjs/intl-numberformat/polyfill-force": [
"./node_modules/@formatjs/intl-numberformat/polyfill-force.js"
],
"@formatjs/intl-pluralrules/should-polyfill": [
"./node_modules/@formatjs/intl-pluralrules/should-polyfill.js"
],
"@formatjs/intl-pluralrules/polyfill-force": [
"./node_modules/@formatjs/intl-pluralrules/polyfill-force.js"
],
"@formatjs/intl-relativetimeformat/should-polyfill": [
"./node_modules/@formatjs/intl-relativetimeformat/should-polyfill.js"
],
"@formatjs/intl-relativetimeformat/polyfill-force": [
"./node_modules/@formatjs/intl-relativetimeformat/polyfill-force.js"
] ]
} }
} }

2005
yarn.lock

File diff suppressed because it is too large Load Diff