Compare commits

..

25 Commits

Author SHA1 Message Date
karwosts
6068c32176
Pass narrow through parallel/sequence automation actions (#26386) 2025-08-04 17:51:17 +02:00
karwosts
38893324af
Fix energy now button (#26384)
Update hui-energy-period-selector.ts
2025-08-04 16:19:26 +02:00
Wendelin
a39ab3c174
Improve ha button radius variables (#26382)
* Improve ha button radius variables

* fixes

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2025-08-04 12:58:12 +00:00
Christoph
797d2be5bf
show spinner on update button (during update installation) (#26110)
* scroll to top when installing an update

* Revert "scroll to top when installing an update"

This reverts commit d0051b0c4c38a884328b85a67da0583121ddd84c.

* add progress spinner to update button

* refactor disabled logic for update/skip button

* do not run update when disabled button is clicked

* refactor: use new ha-button to show progress

* refactor: move functions to update.ts
2025-08-04 14:51:38 +02:00
Wendelin
99a91e1019
Improve neutral color palette (#26381)
Improve neutral, add docs, removed unused var.
2025-08-04 12:24:42 +00:00
Wendelin
5de8d07ce0
Fix ha-buttons (#26373)
* Fix ha-button supervisor network

* Fix button appearance for entity row

* Fix logs button menu mobile width

* Fix new logs indicator
2025-08-04 14:18:31 +02:00
dependabot[bot]
3a31a4a721
Bump home-assistant/wheels from 2025.03.0 to 2025.07.0 (#26375)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-04 11:01:02 +02:00
Squazel
05f4419a92
Fix picture-glance card icon styling for unavailable/unknown entities (#26352) 2025-08-04 08:16:11 +02:00
renovate[bot]
5ea8feb86b
Update rspack monorepo to v1.4.11 (#26365)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 06:52:21 +02:00
Jan-Philipp Benecke
8fd70b3ae6
Improve Z-Wave JS config dashboard styling (#26368) 2025-08-04 06:50:35 +02:00
renovate[bot]
343aa40bc8
Update dependency @types/luxon to v3.7.1 (#26351)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-03 08:10:32 +02:00
Jan-Philipp Benecke
6022f9a77e
Do not show AI suggestion button when no inputs in save dialog (#26357) 2025-08-03 08:10:06 +02:00
renovate[bot]
bd9de0680e
Update dependency @types/luxon to v3.7.0 (#26342)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-01 17:09:44 +02:00
Simon Lamon
b8000d5bc1
Fix diagnostic download on integration level (#26341) 2025-08-01 13:16:09 +02:00
Wendelin
c6efa1127f
Fix dialog secondary button design (#26344) 2025-08-01 13:13:42 +02:00
Bram Kragten
688a3d91d3
Add support for sub config flows in conversation agent picker (#26336) 2025-08-01 13:13:28 +02:00
Timothy
68151a2a70
Add Bruno and Timo as codeowners of the external_app folders (#26345) 2025-08-01 11:49:47 +02:00
Wendelin
c2ca556151
Fix line-height, fix script editor buttons (#26337)
* Fix line-height

* Fix script root buttons
2025-07-31 16:52:36 +02:00
Wendelin
df86b27af4
Use tilecard button feature editor (#26335)
Use button feature editor
2025-07-31 13:27:40 +02:00
Wendelin
eba1f401cc
Fix ha-button with missing label and links (#26332) 2025-07-31 12:40:17 +02:00
Wendelin
19c2f9c9e8
Revert "Use query params instead of path for media browser navigate ids" (#26333) 2025-07-31 12:38:52 +02:00
Bram Kragten
4250447d14
Fix area picker text alignment in voice wizard (#26330) 2025-07-31 11:52:33 +02:00
Joost Lekkerkerker
4666197f28
Use underscores in AI task name (#26327) 2025-07-30 21:52:09 +02:00
Franck Nijhof
a5ca36c93f
Add weekdays to time trigger (#25908)
* Add weekdays to time trigger

* Update src/translations/en.json

Co-authored-by: Norbert Rittel <norbert@rittel.de>

* Localization changes

---------

Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com>
2025-07-30 19:45:10 +02:00
Norbert Rittel
a88950e16c
Correct the setup steps for Matter sharing in Google Home app (#26322)
Correct the setup steps in the Google Home app
2025-07-30 19:40:41 +02:00
32 changed files with 666 additions and 534 deletions

View File

@ -74,7 +74,7 @@ jobs:
echo "home-assistant-frontend==$version" > ./requirements.txt
- name: Build wheels
uses: home-assistant/wheels@2025.03.0
uses: home-assistant/wheels@2025.07.0
with:
abi: cp313
tag: musllinux_1_2

8
CODEOWNERS Normal file
View File

@ -0,0 +1,8 @@
# People marked here will be automatically requested for a review
# when the code that they own is touched.
# https://github.com/blog/2392-introducing-code-owners
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Part of the frontend that mobile developper should review
src/external_app/ @bgoncal @TimoPtr
test/external_app/ @bgoncal @TimoPtr

View File

@ -64,4 +64,4 @@ Check the [webawesome documentation](https://webawesome.com/docs/components/butt
**CSS Custom Properties**
- `--ha-button-height` - Height of the button.
- `--ha-button-radius` - Border radius of the button. Defaults to `var(--wa-border-radius-pill)`.
- `--ha-button-border-radius` - Border radius of the button. Defaults to `var(--border-radius-pill)`.

View File

@ -3,26 +3,26 @@ import { mdiArrowCollapseDown, mdiDownload } from "@mdi/js";
// eslint-disable-next-line import/extensions
import { IntersectionController } from "@lit-labs/observers/intersection-controller.js";
import { LitElement, type PropertyValues, css, html, nothing } from "lit";
import { classMap } from "lit/directives/class-map";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../../../src/common/dom/fire_event";
import type {
LandingPageKeys,
LocalizeFunc,
} from "../../../src/common/translations/localize";
import { waitForSeconds } from "../../../src/common/util/wait";
import "../../../src/components/ha-alert";
import "../../../src/components/ha-ansi-to-html";
import type { HaAnsiToHtml } from "../../../src/components/ha-ansi-to-html";
import "../../../src/components/ha-button";
import "../../../src/components/ha-icon-button";
import "../../../src/components/ha-svg-icon";
import "../../../src/components/ha-ansi-to-html";
import "../../../src/components/ha-alert";
import type { HaAnsiToHtml } from "../../../src/components/ha-ansi-to-html";
import { fileDownload } from "../../../src/util/file_download";
import {
getObserverLogs,
downloadUrl as observerLogsDownloadUrl,
} from "../data/observer";
import { fireEvent } from "../../../src/common/dom/fire_event";
import { fileDownload } from "../../../src/util/file_download";
import { getSupervisorLogs, getSupervisorLogsFollow } from "../data/supervisor";
import { waitForSeconds } from "../../../src/common/util/wait";
import { ASSUME_CORE_START_SECONDS } from "../ha-landing-page";
const ERROR_CHECK = /^[\d\s-:]+(ERROR|CRITICAL)(.*)/gm;
@ -108,6 +108,8 @@ class LandingPageLogs extends LitElement {
!this._scrolledToBottomController.value) ||
false,
})}"
size="small"
appearance="filled"
@click=${this._scrollToBottom}
>
<ha-svg-icon .path=${mdiArrowCollapseDown} slot="start"></ha-svg-icon>
@ -309,21 +311,14 @@ class LandingPageLogs extends LitElement {
}
.new-logs-indicator {
--mdc-theme-primary: var(--text-primary-color);
overflow: hidden;
position: absolute;
bottom: 0;
left: 0;
right: 0;
bottom: 4px;
left: 4px;
height: 0;
background-color: var(--primary-color);
border-radius: 8px;
transition: height 0.4s ease-out;
display: flex;
justify-content: space-between;
align-items: center;
}
.new-logs-indicator.visible {

View File

@ -160,8 +160,8 @@
"@octokit/plugin-retry": "8.0.1",
"@octokit/rest": "22.0.0",
"@rsdoctor/rspack-plugin": "1.1.10",
"@rspack/cli": "1.4.10",
"@rspack/core": "1.4.10",
"@rspack/cli": "1.4.11",
"@rspack/core": "1.4.11",
"@types/babel__plugin-transform-runtime": "7.9.5",
"@types/chromecast-caf-receiver": "6.0.22",
"@types/chromecast-caf-sender": "1.0.11",
@ -173,7 +173,7 @@
"@types/leaflet-draw": "1.0.12",
"@types/leaflet.markercluster": "1.5.5",
"@types/lodash.merge": "4.6.9",
"@types/luxon": "3.6.2",
"@types/luxon": "3.7.1",
"@types/mocha": "10.0.10",
"@types/qrcode": "1.5.5",
"@types/sortablejs": "1.15.8",

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
version = "20250731.0"
version = "20250730.0"
license = "Apache-2.0"
license-files = ["LICENSE*"]
description = "The Home Assistant frontend"

View File

@ -27,7 +27,7 @@ export type Appearance = "accent" | "filled" | "outlined" | "plain";
* @csspart spinner - The spinner that shows when the button is in the loading state.
*
* @cssprop --ha-button-height - The height of the button.
* @cssprop --ha-button-radius - The border radius of the button. defaults to `var(--wa-border-radius-pill)`.
* @cssprop --ha-button-border-radius - The border radius of the button. defaults to `var(--border-radius-pill)`.
*
* @attr {("small"|"medium")} size - Sets the button size.
* @attr {("brand"|"neutral"|"danger"|"warning"|"success")} variant - Sets the button color variant. "primary" is default.
@ -55,10 +55,9 @@ export class HaButton extends Button {
/* set theme vars */
--wa-form-control-padding-inline: 16px;
--wa-font-weight-action: var(--ha-font-weight-medium);
--wa-border-radius-pill: 9999px;
--wa-form-control-border-radius: var(
--ha-button-radius,
var(--wa-border-radius-pill)
--ha-button-border-radius,
var(--border-radius-pill)
);
--wa-form-control-height: var(

View File

@ -5,8 +5,8 @@ import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import { stopPropagation } from "../common/dom/stop_propagation";
import { debounce } from "../common/util/debounce";
import type { ConfigEntry } from "../data/config_entries";
import { getConfigEntry } from "../data/config_entries";
import type { ConfigEntry, SubEntry } from "../data/config_entries";
import { getConfigEntry, getSubEntries } from "../data/config_entries";
import type { Agent } from "../data/conversation";
import { listAgents } from "../data/conversation";
import { fetchIntegrationManifest } from "../data/integration";
@ -16,6 +16,7 @@ import "./ha-list-item";
import "./ha-select";
import type { HaSelect } from "./ha-select";
import { getExtendedEntityRegistryEntry } from "../data/entity_registry";
import { showSubConfigFlowDialog } from "../dialogs/config-flow/show-dialog-sub-config-flow";
const NONE = "__NONE_OPTION__";
@ -37,6 +38,8 @@ export class HaConversationAgentPicker extends LitElement {
@state() private _configEntry?: ConfigEntry;
@state() private _subConfigEntry?: SubEntry;
protected render() {
if (!this._agents) {
return nothing;
@ -101,7 +104,11 @@ export class HaConversationAgentPicker extends LitElement {
${agent.name}
</ha-list-item>`
)}</ha-select
>${this._configEntry?.supports_options
>${(this._subConfigEntry &&
this._configEntry?.supported_subentry_types[
this._subConfigEntry.subentry_type
]?.supports_reconfigure) ||
this._configEntry?.supports_options
? html`<ha-icon-button
.path=${mdiCog}
@click=${this._openOptionsFlow}
@ -142,8 +149,17 @@ export class HaConversationAgentPicker extends LitElement {
this._configEntry = (
await getConfigEntry(this.hass, regEntry.config_entry_id)
).config_entry;
if (!regEntry.config_subentry_id) {
this._subConfigEntry = undefined;
} else {
this._subConfigEntry = (
await getSubEntries(this.hass, regEntry.config_entry_id)
).find((entry) => entry.subentry_id === regEntry.config_subentry_id);
}
} catch (_err) {
this._configEntry = undefined;
this._subConfigEntry = undefined;
}
}
@ -182,6 +198,25 @@ export class HaConversationAgentPicker extends LitElement {
if (!this._configEntry) {
return;
}
if (
this._subConfigEntry &&
this._configEntry.supported_subentry_types[
this._subConfigEntry.subentry_type
]?.supports_reconfigure
) {
showSubConfigFlowDialog(
this,
this._configEntry,
this._subConfigEntry.subentry_type,
{
startFlowHandler: this._configEntry.entry_id,
subEntryId: this._subConfigEntry.subentry_id,
}
);
return;
}
showOptionsFlowDialog(this, this._configEntry, {
manifest: await fetchIntegrationManifest(
this.hass,

View File

@ -20,6 +20,18 @@ export class HaFab extends FabBase {
--mdc-typography-button-font-family: var(--ha-font-family-body);
--mdc-typography-button-font-weight: var(--ha-font-weight-medium);
}
:host .mdc-fab--extended {
border-radius: var(
--ha-button-border-radius,
var(--border-radius-pill)
);
}
:host .mdc-fab.mdc-fab--extended .ripple {
border-radius: var(
--ha-button-border-radius,
var(--border-radius-pill)
);
}
:host .mdc-fab--extended .mdc-fab__icon {
margin-inline-start: -8px;
margin-inline-end: 12px;

View File

@ -4,7 +4,7 @@ import type {
HassEntityBase,
HassEvent,
} from "home-assistant-js-websocket";
import { BINARY_STATE_ON } from "../common/const";
import { BINARY_STATE_ON, BINARY_STATE_OFF } from "../common/const";
import { computeDomain } from "../common/entity/compute_domain";
import { computeStateDomain } from "../common/entity/compute_state_domain";
import { supportsFeature } from "../common/entity/supports-feature";
@ -52,6 +52,15 @@ export const updateCanInstall = (
(showSkipped && Boolean(entity.attributes.skipped_version))) &&
supportsFeature(entity, UpdateEntityFeature.INSTALL);
export const latestVersionIsSkipped = (entity: UpdateEntity): boolean =>
!!(
entity.attributes.latest_version &&
entity.attributes.skipped_version === entity.attributes.latest_version
);
export const updateButtonIsDisabled = (entity: UpdateEntity): boolean =>
entity.state === BINARY_STATE_OFF && !latestVersionIsSkipped(entity);
export const updateIsInstalling = (entity: UpdateEntity): boolean =>
!!entity.attributes.in_progress;

View File

@ -7,6 +7,7 @@ import { relativeTime } from "../../../common/datetime/relative_time";
import { supportsFeature } from "../../../common/entity/supports-feature";
import "../../../components/ha-alert";
import "../../../components/ha-button";
import "../../../components/buttons/ha-progress-button";
import "../../../components/ha-checkbox";
import "../../../components/ha-faded";
import "../../../components/ha-markdown";
@ -26,6 +27,8 @@ import {
UpdateEntityFeature,
updateIsInstalling,
updateReleaseNotes,
latestVersionIsSkipped,
updateButtonIsDisabled,
} from "../../../data/update";
import type { HomeAssistant } from "../../../types";
import { showAlertDialog } from "../../generic/show-dialog-box";
@ -180,11 +183,6 @@ class MoreInfoUpdate extends LitElement {
return nothing;
}
const skippedVersion =
this.stateObj.attributes.latest_version &&
this.stateObj.attributes.skipped_version ===
this.stateObj.attributes.latest_version;
const createBackupTexts = this._computeCreateBackupTexts();
return html`
@ -312,7 +310,7 @@ class MoreInfoUpdate extends LitElement {
<ha-button
appearance="plain"
@click=${this._handleSkip}
.disabled=${skippedVersion ||
.disabled=${latestVersionIsSkipped(this.stateObj) ||
this.stateObj.state === BINARY_STATE_OFF ||
updateIsInstalling(this.stateObj)}
>
@ -325,9 +323,8 @@ class MoreInfoUpdate extends LitElement {
? html`
<ha-button
@click=${this._handleInstall}
.disabled=${(this.stateObj.state === BINARY_STATE_OFF &&
!skippedVersion) ||
updateIsInstalling(this.stateObj)}
.loading=${updateIsInstalling(this.stateObj)}
.disabled=${updateButtonIsDisabled(this.stateObj)}
>
${this.hass.localize(
"ui.dialogs.more_info_control.update.update"

View File

@ -1,4 +1,3 @@
import { formatInTimeZone, toDate } from "date-fns-tz";
import {
addDays,
addHours,
@ -6,6 +5,7 @@ import {
differenceInMilliseconds,
startOfHour,
} from "date-fns";
import { formatInTimeZone, toDate } from "date-fns-tz";
import type { HassEntity } from "home-assistant-js-websocket";
import type { CSSResultGroup } from "lit";
import { LitElement, css, html, nothing } from "lit";
@ -18,11 +18,11 @@ import { supportsFeature } from "../../common/entity/supports-feature";
import { isDate } from "../../common/string/is_date";
import "../../components/entity/ha-entity-picker";
import "../../components/ha-alert";
import "../../components/ha-button";
import "../../components/ha-date-input";
import { createCloseHeading } from "../../components/ha-dialog";
import "../../components/ha-formfield";
import "../../components/ha-switch";
import "../../components/ha-button";
import "../../components/ha-textarea";
import "../../components/ha-textfield";
import "../../components/ha-time-input";
@ -282,6 +282,7 @@ class DialogCalendarEventEditor extends LitElement {
? html`
<ha-button
slot="secondaryAction"
appearance="plain"
variant="danger"
@click=${this._deleteEvent}
.disabled=${this._submitting}

View File

@ -15,6 +15,8 @@ export class HaParallelAction extends LitElement implements ActionElement {
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public narrow = false;
@property({ attribute: false }) public action!: ParallelAction;
public static get defaultConfig(): ParallelAction {
@ -29,6 +31,7 @@ export class HaParallelAction extends LitElement implements ActionElement {
return html`
<ha-automation-action
.actions=${action.parallel}
.narrow=${this.narrow}
.disabled=${this.disabled}
@value-changed=${this._actionsChanged}
.hass=${this.hass}

View File

@ -15,6 +15,8 @@ export class HaSequenceAction extends LitElement implements ActionElement {
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public narrow = false;
@property({ attribute: false }) public action!: SequenceAction;
public static get defaultConfig(): SequenceAction {
@ -29,6 +31,7 @@ export class HaSequenceAction extends LitElement implements ActionElement {
return html`
<ha-automation-action
.actions=${action.sequence}
.narrow=${this.narrow}
.disabled=${this.disabled}
@value-changed=${this._actionsChanged}
.hass=${this.hass}

View File

@ -260,12 +260,14 @@ class DialogAutomationSave extends LitElement implements HassDialog {
.path=${mdiClose}
></ha-icon-button>
<span slot="title">${this._params.title || title}</span>
<ha-suggest-with-ai-button
${this._params.hideInputs
? nothing
: html` <ha-suggest-with-ai-button
slot="actionItems"
.hass=${this.hass}
.generateTask=${this._generateTask}
@suggestion=${this._handleSuggestion}
></ha-suggest-with-ai-button>
></ha-suggest-with-ai-button>`}
</ha-dialog-header>
${this._error
? html`<ha-alert alert-type="error"

View File

@ -2,10 +2,10 @@ import type { CSSResultGroup } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-alert";
import "../../../../components/ha-button";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-form/ha-form";
import "../../../../components/ha-alert";
import type {
HaFormSchema,
SchemaUnion,
@ -91,6 +91,7 @@ class LocalBackupLocationDialog extends LitElement {
</ha-alert>
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this.closeDialog}
dialogInitialFocus
>

View File

@ -1442,10 +1442,9 @@ export class HaConfigDevicePage extends LitElement {
}
private async _signUrl(ev) {
const anchor = ev.currentTarget.closest("a");
const signedUrl = await getSignedPath(
this.hass,
anchor.getAttribute("href")
ev.currentTarget.getAttribute("href")
);
fileDownload(signedUrl.path);
}

View File

@ -3,16 +3,16 @@ import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { stopPropagation } from "../../../../../common/dom/stop_propagation";
import type { HassDialog } from "../../../../../dialogs/make-dialog-manager";
import { changeZHANetworkChannel } from "../../../../../data/zha";
import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box";
import { createCloseHeading } from "../../../../../components/ha-dialog";
import type { HomeAssistant } from "../../../../../types";
import "../../../../../components/buttons/ha-progress-button";
import "../../../../../components/ha-alert";
import "../../../../../components/ha-button";
import "../../../../../components/ha-select";
import { createCloseHeading } from "../../../../../components/ha-dialog";
import "../../../../../components/ha-list-item";
import "../../../../../components/ha-select";
import { changeZHANetworkChannel } from "../../../../../data/zha";
import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box";
import type { HassDialog } from "../../../../../dialogs/make-dialog-manager";
import type { HomeAssistant } from "../../../../../types";
import type { ZHAChangeChannelDialogParams } from "./show-dialog-zha-change-channel";
const VALID_CHANNELS = [
@ -128,6 +128,7 @@ class DialogZHAChangeChannel extends LitElement implements HassDialog {
<ha-button
slot="secondaryAction"
appearance="plain"
@click=${this.closeDialog}
.disabled=${this._migrationInProgress}
>${this.hass.localize("ui.common.cancel")}</ha-button

View File

@ -157,6 +157,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
.path=${mdiRefresh}
.label=${this.hass!.localize("ui.common.refresh")}
></ha-icon-button>
<div class="container">
${this._network
? html`
<ha-card class="content network-status">
@ -445,12 +446,12 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
</div>
<div class="card-content">
<p>
Enable the reporting of anonymized telemetry and statistics
to the <em>Z-Wave JS organization</em>. This data will be
used to focus development efforts and improve the user
experience. Information about the data that is collected and
how it is used, including an example of the data collected,
can be found in the
Enable the reporting of anonymized telemetry and
statistics to the <em>Z-Wave JS organization</em>. This
data will be used to focus development efforts and improve
the user experience. Information about the data that is
collected and how it is used, including an example of the
data collected, can be found in the
<a
target="_blank"
href="https://zwave-js.github.io/node-zwave-js/#/data-collection/data-collection"
@ -531,6 +532,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
</ha-card>
`
: nothing}
</div>
<ha-fab
slot="fab"
.label=${this.hass.localize(
@ -957,6 +959,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
.card-actions {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.card-actions ha-progress-ring {
@ -984,6 +987,10 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
.migrate-button {
margin-left: auto;
}
.container {
padding: 8px 16px 16px;
}
`,
];
}

View File

@ -825,6 +825,7 @@ class ErrorLogCard extends LitElement {
overflow: hidden;
position: absolute;
bottom: 4px;
left: 4px;
height: 0;
transition: height 0.4s ease-out;
}

View File

@ -250,6 +250,21 @@ export class HaConfigLogs extends LitElement {
.content {
direction: ltr;
}
@media all and (max-width: 870px) {
ha-button-menu {
max-width: 50%;
}
ha-button {
max-width: 100%;
}
ha-button::part(label) {
overflow: hidden;
white-space: nowrap;
}
}
ha-list-item[selected] {
color: var(--primary-color);
}
`,
];
}

View File

@ -260,9 +260,6 @@ export class HassioNetwork extends LitElement {
: nothing}
</div>
<div class="card-actions">
<ha-button appearance="plain" @click=${this._clear}>
${this.hass.localize("ui.panel.config.network.supervisor.reset")}
</ha-button>
<ha-button
.loading=${this._processing}
@click=${this._updateNetwork}
@ -270,6 +267,9 @@ export class HassioNetwork extends LitElement {
>
${this.hass.localize("ui.common.save")}
</ha-button>
<ha-button variant="danger" appearance="plain" @click=${this._clear}>
${this.hass.localize("ui.panel.config.network.supervisor.reset")}
</ha-button>
</div>`;
}

View File

@ -30,7 +30,14 @@ import type {
} from "./types";
import type { PersonEntity } from "../../../data/person";
const STATES_OFF = new Set(["closed", "locked", "not_home", "off"]);
const STATES_OFF = new Set([
"closed",
"locked",
"not_home",
"off",
"unavailable",
"unknown",
]);
@customElement("hui-picture-glance-card")
class HuiPictureGlanceCard extends LitElement implements LovelaceCard {

View File

@ -208,7 +208,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
? html`<ha-button
appearance="filled"
size="small"
click=${this._pickNow}
@click=${this._pickNow}
>
${this.hass.localize(
"ui.panel.lovelace.components.energy_period_selector.now"

View File

@ -47,7 +47,7 @@ class HuiSceneEntityRow extends LitElement implements LovelaceRow {
return html`
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
<ha-button
appearance="filled"
appearance="plain"
size="small"
@click=${this._callService}
.disabled=${stateObj.state === UNAVAILABLE}

View File

@ -49,8 +49,9 @@ class HuiScriptEntityRow extends LitElement implements LovelaceRow {
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
${stateObj.state === "on"
? html`<ha-button
appearance="filled"
appearance="plain"
size="small"
variant="danger"
@click=${this._cancelScript}
>
${stateObj.attributes.mode !== "single" &&
@ -61,10 +62,10 @@ class HuiScriptEntityRow extends LitElement implements LovelaceRow {
})
: this.hass.localize("ui.card.script.cancel")}
</ha-button>`
: ""}
: nothing}
${stateObj.state === "off" || stateObj.attributes.max
? html`<ha-button
appearance="filled"
appearance="plain"
size="small"
@click=${this._runScript}
.disabled=${isUnavailableState(stateObj.state) ||
@ -73,7 +74,7 @@ class HuiScriptEntityRow extends LitElement implements LovelaceRow {
${this._config.action_name ||
this.hass!.localize("ui.card.script.run")}
</ha-button>`
: ""}
: nothing}
</hui-generic-entity-row>
`;
}

View File

@ -1,6 +1,13 @@
import { css } from "lit";
import { extractVars } from "../../../common/style/derived-css-vars";
/*
* Core color tokens are the foundational color values used throughout the design system.
* These tokens represent raw, brand-independent colors such as grayscale shades, base hues, and accent tones.
* Core tokens shouldn't be tied to any specific UI purpose or role. Instead, they serve as building blocks from which semantic tokens are derived.
* Changes to core tokens will cascade into semantic tokens that reference them, enabling flexible theming and consistent design language.
* Please note that these core tokens are not intended to be used directly in components or styles.
*/
export const coreColorStyles = css`
html {
--white: #ffffff;
@ -21,17 +28,17 @@ export const coreColorStyles = css`
--color-primary-95: #eff9fe;
/* neutral */
--color-neutral-05: #101219;
--color-neutral-10: #1b1d26;
--color-neutral-20: #2f323f;
--color-neutral-30: #424554;
--color-neutral-40: #545868;
--color-neutral-50: #717584;
--color-neutral-60: #9194a2;
--color-neutral-70: #abaeb9;
--color-neutral-80: #c7c9d0;
--color-neutral-90: #e4e5e9;
--color-neutral-95: #f1f2f3;
--color-neutral-05: #141414;
--color-neutral-10: #202020;
--color-neutral-20: #363636;
--color-neutral-30: #4a4a4a;
--color-neutral-40: #5e5e5e;
--color-neutral-50: #7a7a7a;
--color-neutral-60: #989898;
--color-neutral-70: #b1b1b1;
--color-neutral-80: #b1b1b1;
--color-neutral-90: #e6e6e6;
--color-neutral-95: #f3f3f3;
/* orange */
--color-orange-05: #280700;

View File

@ -1,5 +1,10 @@
import { css } from "lit";
/*
* Semantic color tokens are abstractions built on top of core color tokens to represent colors based on their usage or purpose.
* These tokens are named according to their semantic role in the UI (e.g., "primary," "success," "error"), making it easier to maintain consistency and scalability in design.
* Semantic tokens use core tokens to reference the actual color values. This separation allows for adjustments in color schemes without affecting the semantic meaning or intent.
*/
export const semanticColorStyles = css`
html {
--color-overlay-modal: rgba(0, 0, 0, 0.25);
@ -153,9 +158,6 @@ export const semanticColorStyles = css`
--color-on-success-quiet: var(--color-green-50);
--color-on-success-normal: var(--color-green-40);
--color-on-success-loud: var(--white);
/* logo */
--color-logo-primary: var(--color-primary-50);
}
`;

View File

@ -0,0 +1,24 @@
import { css } from "lit";
import { extractDerivedVars } from "../../common/style/derived-css-vars";
export const coreStyles = css`
html {
--border-width-sm: 1px;
--border-width-md: 2px;
--border-width-lg: 3px;
--border-radius-sm: 4px;
--border-radius-md: 8px;
--border-radius-lg: 12px;
--border-radius-xl: 16px;
--border-radius-2xl: 24px;
--border-radius-3xl: 28px;
--border-radius-4xl: 32px;
--border-radius-5xl: 36px;
--border-radius-pill: 9999px;
--border-radius-circle: 50%;
--border-radius-square: 0;
}
`;
export const coreDerivedVariables = extractDerivedVars(coreStyles);

View File

@ -1,5 +1,6 @@
import { fontStyles } from "../roboto";
import { colorDerivedVariables, colorStylesCollection } from "./color";
import { coreDerivedVariables, coreStyles } from "./core.globals";
import { mainDerivedVariables, mainStyles } from "./main.globals";
import {
typographyDerivedVariables,
@ -8,6 +9,7 @@ import {
import { waMainDerivedVariables, waMainStyles } from "./wa.globals";
export const themeStyles = [
coreStyles.toString(),
mainStyles.toString(),
typographyStyles.toString(),
...colorStylesCollection,
@ -16,6 +18,7 @@ export const themeStyles = [
].join("");
export const derivedStyles = {
...coreDerivedVariables,
...mainDerivedVariables,
...typographyDerivedVariables,
...colorDerivedVariables,

View File

@ -1972,11 +1972,11 @@
},
"google_home": {
"header": "Share from Google Home",
"step_1": "Find your device in the Google Home app. Tap the gear icon to open the device settings.",
"step_1": "Find your device in the Google Home app. Tap the gear icon to open the device settings, then tap on Device information.",
"step_2": "Tap {linked_matter_apps_services}.",
"step_3": "Tap {link_apps_services} and choose {home_assistant} from the list.",
"linked_matter_apps_services": "Linked Matter apps and services",
"link_apps_services": "Link apps & services",
"link_apps_services": "Link apps and services",
"no_home_assistant": "I can't find Home Assistant on the list",
"redirect": "You are redirected to the Home Assistant app. Please follow the instructions."
},

188
yarn.lock
View File

@ -3252,58 +3252,58 @@ __metadata:
languageName: node
linkType: hard
"@module-federation/error-codes@npm:0.17.0":
version: 0.17.0
resolution: "@module-federation/error-codes@npm:0.17.0"
checksum: 10/24fc0147737415b1834a612911bd31bab682a1b165c3ea588fa2a9c3052bbbd26609be59c4ec67d902253a791a57fe1b1dcfa2a9964c9dd91bc97ac91b6d6f5d
"@module-federation/error-codes@npm:0.17.1":
version: 0.17.1
resolution: "@module-federation/error-codes@npm:0.17.1"
checksum: 10/5f5f02a90a423479c84e4ff4398a3a9e31b66bd545e7c978ecb8a417f33162b86e749356baab14c006e741c9cebae549335a4c99e94ce7ef54210269fdf74f7f
languageName: node
linkType: hard
"@module-federation/runtime-core@npm:0.17.0":
version: 0.17.0
resolution: "@module-federation/runtime-core@npm:0.17.0"
"@module-federation/runtime-core@npm:0.17.1":
version: 0.17.1
resolution: "@module-federation/runtime-core@npm:0.17.1"
dependencies:
"@module-federation/error-codes": "npm:0.17.0"
"@module-federation/sdk": "npm:0.17.0"
checksum: 10/0378bb5b4080f9c7ddbcaff7b2259f7e3630cc2cebb41a667d5d3db6cf6c81a7ad3c7c089a99065e4c99e3b04ae29e6fc1715cb7c50c9d515ed31d7b9cf74cf4
"@module-federation/error-codes": "npm:0.17.1"
"@module-federation/sdk": "npm:0.17.1"
checksum: 10/b0c945379bde13af84ceb833e3bfe3c8cf11fd265af0ad7640a1506017529458f408a4a3f1bd0f4b5983da71438913d5c25ed25e20908eb1f789bd1483616650
languageName: node
linkType: hard
"@module-federation/runtime-tools@npm:0.17.0":
version: 0.17.0
resolution: "@module-federation/runtime-tools@npm:0.17.0"
"@module-federation/runtime-tools@npm:0.17.1":
version: 0.17.1
resolution: "@module-federation/runtime-tools@npm:0.17.1"
dependencies:
"@module-federation/runtime": "npm:0.17.0"
"@module-federation/webpack-bundler-runtime": "npm:0.17.0"
checksum: 10/330b145a37065d0fd99445e7dbd745b6dee4d739b54547bbd9c5cacd83cbbd4ab4ae0d0c1ffd3bc27370e917bae491176b78fd10002b3112f4b2e05c7c36db11
"@module-federation/runtime": "npm:0.17.1"
"@module-federation/webpack-bundler-runtime": "npm:0.17.1"
checksum: 10/2e183e357b644dbe015d0e51df3fe601852ca79ffe3a30c582eee7a2050d7600eb3253f5de15e476c60741d0a1dd70add1ade7b5a3537cd2ee12bfee286284ea
languageName: node
linkType: hard
"@module-federation/runtime@npm:0.17.0":
version: 0.17.0
resolution: "@module-federation/runtime@npm:0.17.0"
"@module-federation/runtime@npm:0.17.1":
version: 0.17.1
resolution: "@module-federation/runtime@npm:0.17.1"
dependencies:
"@module-federation/error-codes": "npm:0.17.0"
"@module-federation/runtime-core": "npm:0.17.0"
"@module-federation/sdk": "npm:0.17.0"
checksum: 10/442ac331316d727db2fcfe68017f10fefb550234213f68053b9080cb0538e578e8ee32e75a9233af61cbd785cb40325556ebc13952e14fe61bd328da75dcfbb3
"@module-federation/error-codes": "npm:0.17.1"
"@module-federation/runtime-core": "npm:0.17.1"
"@module-federation/sdk": "npm:0.17.1"
checksum: 10/f5405968dff4fa2cf510127701ec1722105f44298fd09eafeecead450b7bb95a05450749157fe2fc39caf6241bec9e45caa9a55375b48e7f195db84799a8df0c
languageName: node
linkType: hard
"@module-federation/sdk@npm:0.17.0":
version: 0.17.0
resolution: "@module-federation/sdk@npm:0.17.0"
checksum: 10/fec4e4243953274368ae16d668cd7fba9bbc01c7e38954f2a8e1261dd6159828ba3471c1a160092dde86ebe32a5d824abe75d1645f0155b2127a9f50518e7b40
"@module-federation/sdk@npm:0.17.1":
version: 0.17.1
resolution: "@module-federation/sdk@npm:0.17.1"
checksum: 10/daaaa49ed900c00a69641130cf673ad5d5b8623d82fb4bd03a67c839a6da760a0a5ae29b836ba66eeb95ee5392e558588ffd987a2c00b05c2b0a7c5039ed042d
languageName: node
linkType: hard
"@module-federation/webpack-bundler-runtime@npm:0.17.0":
version: 0.17.0
resolution: "@module-federation/webpack-bundler-runtime@npm:0.17.0"
"@module-federation/webpack-bundler-runtime@npm:0.17.1":
version: 0.17.1
resolution: "@module-federation/webpack-bundler-runtime@npm:0.17.1"
dependencies:
"@module-federation/runtime": "npm:0.17.0"
"@module-federation/sdk": "npm:0.17.0"
checksum: 10/ce3e9dd45a16fb62f1645105cce6d19f1f62a2b68c65c8835f69bf9a2729cebac23d8a9b046c5ea53e974d2df025011e746ab95e0086237d24124bddd78cb40c
"@module-federation/runtime": "npm:0.17.1"
"@module-federation/sdk": "npm:0.17.1"
checksum: 10/72e5030529dbc53df6271fa78bdb63976d0601fe9fde5105f8a7325e0fa296bc35277b9b084e52995cd314b89e12d33f8b869c1d63a13231c2948d4c741e72fd
languageName: node
linkType: hard
@ -3964,92 +3964,92 @@ __metadata:
languageName: node
linkType: hard
"@rspack/binding-darwin-arm64@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-darwin-arm64@npm:1.4.10"
"@rspack/binding-darwin-arm64@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-darwin-arm64@npm:1.4.11"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@rspack/binding-darwin-x64@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-darwin-x64@npm:1.4.10"
"@rspack/binding-darwin-x64@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-darwin-x64@npm:1.4.11"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@rspack/binding-linux-arm64-gnu@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-linux-arm64-gnu@npm:1.4.10"
"@rspack/binding-linux-arm64-gnu@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-linux-arm64-gnu@npm:1.4.11"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@rspack/binding-linux-arm64-musl@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-linux-arm64-musl@npm:1.4.10"
"@rspack/binding-linux-arm64-musl@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-linux-arm64-musl@npm:1.4.11"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@rspack/binding-linux-x64-gnu@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-linux-x64-gnu@npm:1.4.10"
"@rspack/binding-linux-x64-gnu@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-linux-x64-gnu@npm:1.4.11"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@rspack/binding-linux-x64-musl@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-linux-x64-musl@npm:1.4.10"
"@rspack/binding-linux-x64-musl@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-linux-x64-musl@npm:1.4.11"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@rspack/binding-wasm32-wasi@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-wasm32-wasi@npm:1.4.10"
"@rspack/binding-wasm32-wasi@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-wasm32-wasi@npm:1.4.11"
dependencies:
"@napi-rs/wasm-runtime": "npm:^1.0.1"
conditions: cpu=wasm32
languageName: node
linkType: hard
"@rspack/binding-win32-arm64-msvc@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-win32-arm64-msvc@npm:1.4.10"
"@rspack/binding-win32-arm64-msvc@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-win32-arm64-msvc@npm:1.4.11"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@rspack/binding-win32-ia32-msvc@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-win32-ia32-msvc@npm:1.4.10"
"@rspack/binding-win32-ia32-msvc@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-win32-ia32-msvc@npm:1.4.11"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@rspack/binding-win32-x64-msvc@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding-win32-x64-msvc@npm:1.4.10"
"@rspack/binding-win32-x64-msvc@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding-win32-x64-msvc@npm:1.4.11"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@rspack/binding@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/binding@npm:1.4.10"
"@rspack/binding@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/binding@npm:1.4.11"
dependencies:
"@rspack/binding-darwin-arm64": "npm:1.4.10"
"@rspack/binding-darwin-x64": "npm:1.4.10"
"@rspack/binding-linux-arm64-gnu": "npm:1.4.10"
"@rspack/binding-linux-arm64-musl": "npm:1.4.10"
"@rspack/binding-linux-x64-gnu": "npm:1.4.10"
"@rspack/binding-linux-x64-musl": "npm:1.4.10"
"@rspack/binding-wasm32-wasi": "npm:1.4.10"
"@rspack/binding-win32-arm64-msvc": "npm:1.4.10"
"@rspack/binding-win32-ia32-msvc": "npm:1.4.10"
"@rspack/binding-win32-x64-msvc": "npm:1.4.10"
"@rspack/binding-darwin-arm64": "npm:1.4.11"
"@rspack/binding-darwin-x64": "npm:1.4.11"
"@rspack/binding-linux-arm64-gnu": "npm:1.4.11"
"@rspack/binding-linux-arm64-musl": "npm:1.4.11"
"@rspack/binding-linux-x64-gnu": "npm:1.4.11"
"@rspack/binding-linux-x64-musl": "npm:1.4.11"
"@rspack/binding-wasm32-wasi": "npm:1.4.11"
"@rspack/binding-win32-arm64-msvc": "npm:1.4.11"
"@rspack/binding-win32-ia32-msvc": "npm:1.4.11"
"@rspack/binding-win32-x64-msvc": "npm:1.4.11"
dependenciesMeta:
"@rspack/binding-darwin-arm64":
optional: true
@ -4071,13 +4071,13 @@ __metadata:
optional: true
"@rspack/binding-win32-x64-msvc":
optional: true
checksum: 10/65da06db1317ce780176d5eab8bac62ecf42a2e78433e4fe5aa0a2ea3f02e878a5588606e16b8b91908eba0894c0d66351d03275a474bc6a5781e90612e8d100
checksum: 10/8bb94774204f41888ff442afec06f019d008abba79964b74d566acf64f7216a148a1842f90c44b3bf680e69b697d8e5cd0f1cca6fd0b8a94df5f97c2a3f05510
languageName: node
linkType: hard
"@rspack/cli@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/cli@npm:1.4.10"
"@rspack/cli@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/cli@npm:1.4.11"
dependencies:
"@discoveryjs/json-ext": "npm:^0.5.7"
"@rspack/dev-server": "npm:~1.1.3"
@ -4091,23 +4091,23 @@ __metadata:
"@rspack/core": ^1.0.0-alpha || ^1.x
bin:
rspack: bin/rspack.js
checksum: 10/91350c731ef7729e826dcd4f2a552b6df0fe8c9b8a6aae91971ab3952857b9190a9f1a76c273456d0a4dd232f5944aab095459e967ccd3319b0076c0a9978a14
checksum: 10/0a6f2feb1d5e58fd1c373350178cfa56bffce4acb88e335eef83ebbfc227c099c096ed13e51ee929701a07006e59901963dc32e743eea0bc95b666108b92669c
languageName: node
linkType: hard
"@rspack/core@npm:1.4.10":
version: 1.4.10
resolution: "@rspack/core@npm:1.4.10"
"@rspack/core@npm:1.4.11":
version: 1.4.11
resolution: "@rspack/core@npm:1.4.11"
dependencies:
"@module-federation/runtime-tools": "npm:0.17.0"
"@rspack/binding": "npm:1.4.10"
"@module-federation/runtime-tools": "npm:0.17.1"
"@rspack/binding": "npm:1.4.11"
"@rspack/lite-tapable": "npm:1.0.1"
peerDependencies:
"@swc/helpers": ">=0.5.1"
peerDependenciesMeta:
"@swc/helpers":
optional: true
checksum: 10/51534697062ed351d85b75d958253b760fcca7e426cb39b053ac4816f84e0a7bad3d969f48d0cf76ab7733b0e5695cf82770e6b8f5c95e22fa4a697cb5dd286b
checksum: 10/77d463bd90feb2d24f7bc56df198f0b7ad310a9eb676070eac8d78014d151e783943c5b44c64700a51a36708c626a341eeaa9b3287e358616d09dfe25ab04e77
languageName: node
linkType: hard
@ -4732,10 +4732,10 @@ __metadata:
languageName: node
linkType: hard
"@types/luxon@npm:3.6.2":
version: 3.6.2
resolution: "@types/luxon@npm:3.6.2"
checksum: 10/73ca30059e0b1e352ce3a208837bc042e0bae9cf6e5b42f63de9ddfe15348a9e9bf9fcde3d4034038be24cb24adc579ae984cadff3bf70432e54fed1ad249d12
"@types/luxon@npm:3.7.1":
version: 3.7.1
resolution: "@types/luxon@npm:3.7.1"
checksum: 10/c7bc164c278393ea0be938f986c74b4cddfab9013b1aff4495b016f771ded1d5b7b7b4825b2c7f0b8799edce19c5f531c28ff434ab3dedf994ac2d99a20fd4c4
languageName: node
linkType: hard
@ -9409,8 +9409,8 @@ __metadata:
"@octokit/rest": "npm:22.0.0"
"@replit/codemirror-indentation-markers": "npm:6.5.3"
"@rsdoctor/rspack-plugin": "npm:1.1.10"
"@rspack/cli": "npm:1.4.10"
"@rspack/core": "npm:1.4.10"
"@rspack/cli": "npm:1.4.11"
"@rspack/core": "npm:1.4.11"
"@shoelace-style/shoelace": "npm:2.20.1"
"@swc/helpers": "npm:0.5.17"
"@thomasloven/round-slider": "npm:0.6.0"
@ -9427,7 +9427,7 @@ __metadata:
"@types/leaflet-draw": "npm:1.0.12"
"@types/leaflet.markercluster": "npm:1.5.5"
"@types/lodash.merge": "npm:4.6.9"
"@types/luxon": "npm:3.6.2"
"@types/luxon": "npm:3.7.1"
"@types/mocha": "npm:10.0.10"
"@types/qrcode": "npm:1.5.5"
"@types/sortablejs": "npm:1.15.8"