Compare commits

..

No commits in common. "dev" and "20250730.0" have entirely different histories.

143 changed files with 1428 additions and 1664 deletions

View File

@ -310,11 +310,7 @@ export class DialogMyFeature
.heading=${createCloseHeading(this.hass, this._params.title)} .heading=${createCloseHeading(this.hass, this._params.title)}
> >
<!-- Dialog content --> <!-- Dialog content -->
<ha-button <ha-button @click=${this.closeDialog} slot="secondaryAction">
appearance="plain"
@click=${this.closeDialog}
slot="secondaryAction"
>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button @click=${this._submit} slot="primaryAction"> <ha-button @click=${this._submit} slot="primaryAction">

View File

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

View File

@ -1,8 +0,0 @@
# 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

@ -89,14 +89,11 @@ export class HADemoCard extends LitElement implements LovelaceCard {
)} )}
</div> </div>
<div class="actions small-hidden"> <div class="actions small-hidden">
<ha-button <a href="https://www.home-assistant.io" target="_blank">
appearance="plain" <ha-button>
size="small"
href="https://www.home-assistant.io"
target="_blank"
>
${this.hass.localize("ui.panel.page-demo.cards.demo.learn_more")} ${this.hass.localize("ui.panel.page-demo.cards.demo.learn_more")}
</ha-button> </ha-button>
</a>
</div> </div>
</ha-card> </ha-card>
`; `;

View File

@ -147,13 +147,13 @@ The `title ` option should not be used without a description.
<ha-alert alert-type="success"> <ha-alert alert-type="success">
This is a success alert — check it out! This is a success alert — check it out!
<ha-button slot="action">Undo</ha-button> <ha-button slot="action" label="Undo"></ha-button>
</ha-alert> </ha-alert>
```html ```html
<ha-alert alert-type="success"> <ha-alert alert-type="success">
This is a success alert — check it out! This is a success alert — check it out!
<ha-button slot="action">Undo</ha-button> <ha-button slot="action" label="Undo"></ha-button>
</ha-alert> </ha-alert>
``` ```

View File

@ -78,13 +78,21 @@ const alerts: {
title: "Error with action", title: "Error with action",
description: "This is a test error alert with action", description: "This is a test error alert with action",
type: "error", type: "error",
actionSlot: html`<ha-button size="small" slot="action">restart</ha-button>`, actionSlot: html`<ha-button
size="small"
slot="action"
label="restart"
></ha-button>`,
}, },
{ {
title: "Unsaved data", title: "Unsaved data",
description: "You have unsaved data", description: "You have unsaved data",
type: "warning", type: "warning",
actionSlot: html`<ha-button size="small" slot="action">save</ha-button>`, actionSlot: html`<ha-button
size="small"
slot="action"
label="save"
></ha-button>`,
}, },
{ {
title: "Slotted icon", title: "Slotted icon",
@ -108,7 +116,7 @@ const alerts: {
title: "Slotted action", title: "Slotted action",
description: "Alert with slotted action", description: "Alert with slotted action",
type: "info", type: "info",
actionSlot: html`<ha-button slot="action">action</ha-button>`, actionSlot: html`<ha-button slot="action" label="action"></ha-button>`,
}, },
{ {
description: "Dismissable information (RTL)", description: "Dismissable information (RTL)",
@ -120,7 +128,7 @@ const alerts: {
title: "Error with action", title: "Error with action",
description: "This is a test error alert with action (RTL)", description: "This is a test error alert with action (RTL)",
type: "error", type: "error",
actionSlot: html`<ha-button slot="action">restart</ha-button>`, actionSlot: html`<ha-button slot="action" label="restart"></ha-button>`,
rtl: true, rtl: true,
}, },
{ {

View File

@ -54,14 +54,13 @@ Check the [webawesome documentation](https://webawesome.com/docs/components/butt
**Properties/Attributes** **Properties/Attributes**
| Name | Type | Default | Description | | Name | Type | Default | Description |
| ---------- | ---------------------------------------------- | -------- | --------------------------------------------------------------------------------- | | ----------- | ---------------------------------------------- | -------- | -------------------------------------------------- |
| appearance | "accent"/"filled"/"plain" | "accent" | Sets the button appearance. | | appearance | "accent"/"filled"/"plain" | "accent" | Sets the button appearance. |
| variants | "brand"/"danger"/"neutral"/"warning"/"success" | "brand" | Sets the button color variant. "brand" is default. | | variants | "brand"/"danger"/"neutral"/"warning"/"success" | "brand" | Sets the button color variant. "brand" is default. |
| size | "small"/"medium" | "medium" | Sets the button size. | | size | "small"/"medium" | "medium" | Sets the button size. |
| loading | Boolean | false | Shows a loading indicator instead of the buttons label and disable buttons click. | | hideContent | Boolean | false | Hides the button content (for overlays) |
| disabled | Boolean | false | Disables the button and prevents user interaction. |
**CSS Custom Properties** **CSS Custom Properties**
- `--ha-button-height` - Height of the button. - `--ha-button-height` - Height of the button.
- `--ha-button-border-radius` - Border radius of the button. Defaults to `var(--ha-border-radius-pill)`. - `--ha-button-radius` - Border radius of the button. Defaults to `var(--wa-border-radius-pill)`.

View File

@ -21,8 +21,8 @@ import type { HomeAssistant } from "../../../../src/types";
import type { HassioDatatiskDialogParams } from "./show-dialog-hassio-datadisk"; import type { HassioDatatiskDialogParams } from "./show-dialog-hassio-datadisk";
const calculateMoveTime = memoizeOne((supervisor: Supervisor): number => { const calculateMoveTime = memoizeOne((supervisor: Supervisor): number => {
// Assume a speed of 30 MB/s. const speed = supervisor.host.disk_life_time !== "" ? 30 : 10;
const moveTime = (supervisor.host.disk_used * 1000) / 60 / 30; const moveTime = (supervisor.host.disk_used * 1000) / 60 / speed;
const rebootTime = (supervisor.host.startup_time * 4) / 60; const rebootTime = (supervisor.host.startup_time * 4) / 60;
return Math.ceil((moveTime + rebootTime) / 10) * 10; return Math.ceil((moveTime + rebootTime) / 10) * 10;
}); });

View File

@ -604,8 +604,8 @@ export class DialogHassioNetwork
var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12)); var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12));
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 16px; padding: 8px;
padding-bottom: max(var(--safe-area-inset-bottom), 16px); padding-bottom: max(var(--safe-area-inset-bottom), 8px);
background-color: var(--mdc-theme-surface, #fff); background-color: var(--mdc-theme-surface, #fff);
} }
.warning { .warning {

View File

@ -143,12 +143,16 @@ class HassioHostInfo extends LitElement {
: ""} : ""}
</div> </div>
<div> <div>
${this.supervisor.host.disk_life_time !== null ${this.supervisor.host.disk_life_time !== "" &&
this.supervisor.host.disk_life_time >= 10
? html` <ha-settings-row> ? html` <ha-settings-row>
<span slot="heading"> <span slot="heading">
${this.supervisor.localize("system.host.lifetime_used")} ${this.supervisor.localize(
"system.host.emmc_lifetime_used"
)}
</span> </span>
<span slot="description"> <span slot="description">
${this.supervisor.host.disk_life_time - 10} % -
${this.supervisor.host.disk_life_time} % ${this.supervisor.host.disk_life_time} %
</span> </span>
</ha-settings-row>` </ha-settings-row>`

View File

@ -208,16 +208,14 @@ class UpdateAvailableCard extends LitElement {
<div class="card-actions"> <div class="card-actions">
${changelog ${changelog
? html` ? html`
<a href=${changelog} target="_blank" rel="noreferrer">
<ha-button <ha-button
href=${changelog} .label=${this.supervisor.localize(
target="_blank"
rel="noreferrer"
appearance="plain"
>
${this.supervisor.localize(
"update_available.open_release_notes" "update_available.open_release_notes"
)} )}
>
</ha-button> </ha-button>
</a>
` `
: nothing} : nothing}
<span></span> <span></span>

View File

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

View File

@ -160,8 +160,8 @@
"@octokit/plugin-retry": "8.0.1", "@octokit/plugin-retry": "8.0.1",
"@octokit/rest": "22.0.0", "@octokit/rest": "22.0.0",
"@rsdoctor/rspack-plugin": "1.1.10", "@rsdoctor/rspack-plugin": "1.1.10",
"@rspack/cli": "1.4.11", "@rspack/cli": "1.4.10",
"@rspack/core": "1.4.11", "@rspack/core": "1.4.10",
"@types/babel__plugin-transform-runtime": "7.9.5", "@types/babel__plugin-transform-runtime": "7.9.5",
"@types/chromecast-caf-receiver": "6.0.22", "@types/chromecast-caf-receiver": "6.0.22",
"@types/chromecast-caf-sender": "1.0.11", "@types/chromecast-caf-sender": "1.0.11",
@ -173,7 +173,7 @@
"@types/leaflet-draw": "1.0.12", "@types/leaflet-draw": "1.0.12",
"@types/leaflet.markercluster": "1.5.5", "@types/leaflet.markercluster": "1.5.5",
"@types/lodash.merge": "4.6.9", "@types/lodash.merge": "4.6.9",
"@types/luxon": "3.7.1", "@types/luxon": "3.6.2",
"@types/mocha": "10.0.10", "@types/mocha": "10.0.10",
"@types/qrcode": "1.5.5", "@types/qrcode": "1.5.5",
"@types/sortablejs": "1.15.8", "@types/sortablejs": "1.15.8",
@ -205,7 +205,7 @@
"husky": "9.1.7", "husky": "9.1.7",
"jsdom": "26.1.0", "jsdom": "26.1.0",
"jszip": "3.10.1", "jszip": "3.10.1",
"lint-staged": "16.1.4", "lint-staged": "16.1.2",
"lit-analyzer": "2.0.3", "lit-analyzer": "2.0.3",
"lodash.merge": "4.6.2", "lodash.merge": "4.6.2",
"lodash.template": "4.5.0", "lodash.template": "4.5.0",

View File

@ -22,8 +22,8 @@ export type LocalizeKeys =
| `ui.dialogs.more_info_control.lawn_mower.${string}` | `ui.dialogs.more_info_control.lawn_mower.${string}`
| `ui.dialogs.more_info_control.vacuum.${string}` | `ui.dialogs.more_info_control.vacuum.${string}`
| `ui.dialogs.quick-bar.commands.${string}` | `ui.dialogs.quick-bar.commands.${string}`
| `ui.dialogs.unhealthy.reasons.${string}` | `ui.dialogs.unhealthy.reason.${string}`
| `ui.dialogs.unsupported.reasons.${string}` | `ui.dialogs.unsupported.reason.${string}`
| `ui.panel.config.${string}.${"caption" | "description"}` | `ui.panel.config.${string}.${"caption" | "description"}`
| `ui.panel.config.dashboard.${string}` | `ui.panel.config.dashboard.${string}`
| `ui.panel.config.zha.${string}` | `ui.panel.config.zha.${string}`

View File

@ -117,7 +117,7 @@ export class HaProgressButton extends LitElement {
} }
ha-svg-icon { ha-svg-icon {
color: var(--white-color); color: var(--white);
} }
`; `;
} }

View File

@ -29,6 +29,7 @@ import { formatTimeLabel } from "./axis-label";
import { ensureArray } from "../../common/array/ensure-array"; import { ensureArray } from "../../common/array/ensure-array";
import "../chips/ha-assist-chip"; import "../chips/ha-assist-chip";
import { downSampleLineData } from "./down-sample"; import { downSampleLineData } from "./down-sample";
import { colorVariables } from "../../resources/theme/color/color.globals";
export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000; export const MIN_TIME_BETWEEN_UPDATES = 60 * 5 * 1000;
const LEGEND_OVERFLOW_LIMIT = 10; const LEGEND_OVERFLOW_LIMIT = 10;
@ -167,16 +168,14 @@ export class HaChartBase extends LitElement {
} }
protected firstUpdated() { protected firstUpdated() {
if (this.isConnected) {
this._setupChart(); this._setupChart();
} }
}
public willUpdate(changedProps: PropertyValues): void { public willUpdate(changedProps: PropertyValues): void {
if (!this.chart) { if (!this.chart) {
return; return;
} }
if (changedProps.has("_themes") && this.hasUpdated) { if (changedProps.has("_themes")) {
this._setupChart(); this._setupChart();
return; return;
} }
@ -343,8 +342,7 @@ export class HaChartBase extends LitElement {
echarts.use(this.extraComponents); echarts.use(this.extraComponents);
} }
const style = getComputedStyle(this); echarts.registerTheme("custom", this._createTheme());
echarts.registerTheme("custom", this._createTheme(style));
this.chart = echarts.init(container, "custom"); this.chart = echarts.init(container, "custom");
this.chart.on("datazoom", (e: any) => { this.chart.on("datazoom", (e: any) => {
@ -396,7 +394,7 @@ export class HaChartBase extends LitElement {
...axis.axisPointer, ...axis.axisPointer,
status: "show", status: "show",
handle: { handle: {
color: style.getPropertyValue("primary-color"), color: colorVariables["primary-color"],
margin: 0, margin: 0,
size: 20, size: 20,
...axis.axisPointer?.handle, ...axis.axisPointer?.handle,
@ -570,7 +568,8 @@ export class HaChartBase extends LitElement {
return options; return options;
} }
private _createTheme(style: CSSStyleDeclaration) { private _createTheme() {
const style = getComputedStyle(this);
return { return {
color: getAllGraphColors(style), color: getAllGraphColors(style),
backgroundColor: "transparent", backgroundColor: "transparent",
@ -803,7 +802,6 @@ export class HaChartBase extends LitElement {
}; };
} }
} }
const replaceMerge = options.series ? ["series"] : []; const replaceMerge = options.series ? ["series"] : [];
this.chart.setOption(options, { replaceMerge }); this.chart.setOption(options, { replaceMerge });
} }

View File

@ -105,14 +105,12 @@ export class HaNetworkGraph extends SubscribeMixin(LitElement) {
} }
protected render() { protected render() {
if (!GraphChart || !this.data.nodes?.length) { if (!GraphChart) {
return nothing; return nothing;
} }
const isMobile = window.matchMedia( const isMobile = window.matchMedia(
"all and (max-width: 450px), all and (max-height: 500px)" "all and (max-width: 450px), all and (max-height: 500px)"
).matches; ).matches;
return html`<ha-chart-base return html`<ha-chart-base
.hass=${this.hass} .hass=${this.hass}
.data=${this._getSeries( .data=${this._getSeries(
@ -245,7 +243,6 @@ export class HaNetworkGraph extends SubscribeMixin(LitElement) {
) { ) {
const containerWidth = this.clientWidth; const containerWidth = this.clientWidth;
const containerHeight = this.clientHeight; const containerHeight = this.clientHeight;
const positionedNodes: NetworkNode[] = nodes.map((node) => ({ ...node })); const positionedNodes: NetworkNode[] = nodes.map((node) => ({ ...node }));
positionedNodes.forEach((node) => { positionedNodes.forEach((node) => {
if (nodePositions[node.id]) { if (nodePositions[node.id]) {

View File

@ -27,13 +27,12 @@ export type Appearance = "accent" | "filled" | "outlined" | "plain";
* @csspart spinner - The spinner that shows when the button is in the loading state. * @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-height - The height of the button.
* @cssprop --ha-button-border-radius - The border radius of the button. defaults to `var(--ha-border-radius-pill)`. * @cssprop --ha-button-radius - The border radius of the button. defaults to `var(--wa-border-radius-pill)`.
* *
* @attr {("small"|"medium")} size - Sets the button size. * @attr {("small"|"medium")} size - Sets the button size.
* @attr {("brand"|"neutral"|"danger"|"warning"|"success")} variant - Sets the button color variant. "primary" is default. * @attr {("brand"|"neutral"|"danger"|"warning"|"success")} variant - Sets the button color variant. "primary" is default.
* @attr {("accent"|"filled"|"plain")} appearance - Sets the button appearance. * @attr {("accent"|"filled"|"plain")} appearance - Sets the button appearance.
* @attr {boolean} loading - shows a loading indicator instead of the buttons label and disable buttons click. * @attr {boolean} hideContent - Hides the button content (for overlays).
* @attr {boolean} disabled - Disables the button and prevents user interaction.
*/ */
@customElement("ha-button") @customElement("ha-button")
export class HaButton extends Button { export class HaButton extends Button {
@ -55,9 +54,10 @@ export class HaButton extends Button {
/* set theme vars */ /* set theme vars */
--wa-form-control-padding-inline: 16px; --wa-form-control-padding-inline: 16px;
--wa-font-weight-action: var(--ha-font-weight-medium); --wa-font-weight-action: var(--ha-font-weight-medium);
--wa-border-radius-pill: 9999px;
--wa-form-control-border-radius: var( --wa-form-control-border-radius: var(
--ha-button-border-radius, --ha-button-radius,
var(--ha-border-radius-pill) var(--wa-border-radius-pill)
); );
--wa-form-control-height: var( --wa-form-control-height: var(
@ -66,7 +66,6 @@ export class HaButton extends Button {
); );
font-size: var(--ha-font-size-m); font-size: var(--ha-font-size-m);
line-height: 1;
} }
:host([size="small"]) .button { :host([size="small"]) .button {
@ -78,101 +77,61 @@ export class HaButton extends Button {
} }
:host([variant="brand"]) { :host([variant="brand"]) {
--button-color-fill-normal-active: var( --color-fill-normal-active: var(--color-fill-primary-normal-active);
--ha-color-fill-primary-normal-active --color-fill-normal-hover: var(--color-fill-primary-normal-hover);
); --color-fill-loud-active: var(--color-fill-primary-loud-active);
--button-color-fill-normal-hover: var( --color-fill-loud-hover: var(--color-fill-primary-loud-hover);
--ha-color-fill-primary-normal-hover
);
--button-color-fill-loud-active: var(
--ha-color-fill-primary-loud-active
);
--button-color-fill-loud-hover: var(
--ha-color-fill-primary-loud-hover
);
} }
:host([variant="neutral"]) { :host([variant="neutral"]) {
--button-color-fill-normal-active: var( --color-fill-normal-active: var(--color-fill-neutral-normal-active);
--ha-color-fill-neutral-normal-active --color-fill-normal-hover: var(--color-fill-neutral-normal-hover);
); --color-fill-loud-active: var(--color-fill-neutral-loud-active);
--button-color-fill-normal-hover: var( --color-fill-loud-hover: var(--color-fill-neutral-loud-hover);
--ha-color-fill-neutral-normal-hover
);
--button-color-fill-loud-active: var(
--ha-color-fill-neutral-loud-active
);
--button-color-fill-loud-hover: var(
--ha-color-fill-neutral-loud-hover
);
} }
:host([variant="success"]) { :host([variant="success"]) {
--button-color-fill-normal-active: var( --color-fill-normal-active: var(--color-fill-success-normal-active);
--ha-color-fill-success-normal-active --color-fill-normal-hover: var(--color-fill-success-normal-hover);
); --color-fill-loud-active: var(--color-fill-success-loud-active);
--button-color-fill-normal-hover: var( --color-fill-loud-hover: var(--color-fill-success-loud-hover);
--ha-color-fill-success-normal-hover
);
--button-color-fill-loud-active: var(
--ha-color-fill-success-loud-active
);
--button-color-fill-loud-hover: var(
--ha-color-fill-success-loud-hover
);
} }
:host([variant="warning"]) { :host([variant="warning"]) {
--button-color-fill-normal-active: var( --color-fill-normal-active: var(--color-fill-warning-normal-active);
--ha-color-fill-warning-normal-active --color-fill-normal-hover: var(--color-fill-warning-normal-hover);
); --color-fill-loud-active: var(--color-fill-warning-loud-active);
--button-color-fill-normal-hover: var( --color-fill-loud-hover: var(--color-fill-warning-loud-hover);
--ha-color-fill-warning-normal-hover
);
--button-color-fill-loud-active: var(
--ha-color-fill-warning-loud-active
);
--button-color-fill-loud-hover: var(
--ha-color-fill-warning-loud-hover
);
} }
:host([variant="danger"]) { :host([variant="danger"]) {
--button-color-fill-normal-active: var( --color-fill-normal-active: var(--color-fill-danger-normal-active);
--ha-color-fill-danger-normal-active --color-fill-normal-hover: var(--color-fill-danger-normal-hover);
); --color-fill-loud-active: var(--color-fill-danger-loud-active);
--button-color-fill-normal-hover: var( --color-fill-loud-hover: var(--color-fill-danger-loud-hover);
--ha-color-fill-danger-normal-hover
);
--button-color-fill-loud-active: var(
--ha-color-fill-danger-loud-active
);
--button-color-fill-loud-hover: var(
--ha-color-fill-danger-loud-hover
);
} }
:host([appearance~="plain"]) .button { :host([appearance~="plain"]) .button {
color: var(--wa-color-on-normal); color: var(--wa-color-on-normal);
} }
:host([appearance~="plain"]) .button.disabled { :host([appearance~="plain"]) .button.disabled {
background-color: transparent; background-color: var(--transparent-none);
color: var(--ha-color-on-disabled-quiet); color: var(--color-on-disabled-quiet);
} }
:host([appearance~="outlined"]) .button.disabled { :host([appearance~="outlined"]) .button.disabled {
background-color: transparent; background-color: var(--transparent-none);
color: var(--ha-color-on-disabled-quiet); color: var(--color-on-disabled-quiet);
} }
@media (hover: hover) { @media (hover: hover) {
:host([appearance~="filled"]) :host([appearance~="filled"])
.button:not(.disabled):not(.loading):hover { .button:not(.disabled):not(.loading):hover {
background-color: var(--button-color-fill-normal-hover); background-color: var(--color-fill-normal-hover);
} }
:host([appearance~="accent"]) :host([appearance~="accent"])
.button:not(.disabled):not(.loading):hover { .button:not(.disabled):not(.loading):hover {
background-color: var(--button-color-fill-loud-hover); background-color: var(--color-fill-loud-hover);
} }
:host([appearance~="plain"]) :host([appearance~="plain"])
.button:not(.disabled):not(.loading):hover { .button:not(.disabled):not(.loading):hover {
@ -181,11 +140,11 @@ export class HaButton extends Button {
} }
:host([appearance~="filled"]) :host([appearance~="filled"])
.button:not(.disabled):not(.loading):active { .button:not(.disabled):not(.loading):active {
background-color: var(--button-color-fill-normal-active); background-color: var(--color-fill-normal-active);
} }
:host([appearance~="filled"]) .button.disabled { :host([appearance~="filled"]) .button.disabled {
background-color: var(--ha-color-fill-disabled-normal-resting); background-color: var(--color-fill-disabled-normal-resting);
color: var(--ha-color-on-disabled-normal); color: var(--color-on-disabled-normal);
} }
:host([appearance~="accent"]) .button { :host([appearance~="accent"]) .button {
@ -196,11 +155,11 @@ export class HaButton extends Button {
} }
:host([appearance~="accent"]) :host([appearance~="accent"])
.button:not(.disabled):not(.loading):active { .button:not(.disabled):not(.loading):active {
background-color: var(--button-color-fill-loud-active); background-color: var(--color-fill-loud-active);
} }
:host([appearance~="accent"]) .button.disabled { :host([appearance~="accent"]) .button.disabled {
background-color: var(--ha-color-fill-disabled-loud-resting); background-color: var(--color-fill-disabled-loud-resting);
color: var(--ha-color-on-disabled-loud); color: var(--color-on-disabled-loud);
} }
:host([loading]) { :host([loading]) {

View File

@ -506,7 +506,7 @@ export class HaControlSlider extends LitElement {
width: 100%; width: 100%;
} }
.slider .slider-track-bar { .slider .slider-track-bar {
--ha-border-radius: var(--control-slider-border-radius); --border-radius: var(--control-slider-border-radius);
--slider-size: 100%; --slider-size: 100%;
position: absolute; position: absolute;
height: 100%; height: 100%;

View File

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

View File

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

View File

@ -92,12 +92,11 @@ export class HaPictureUpload extends LitElement {
/> />
<div> <div>
<ha-button <ha-button
appearance="plain"
size="small"
variant="danger"
@click=${this._handleChangeClick} @click=${this._handleChangeClick}
.label=${this.hass.localize(
"ui.components.picture-upload.clear_picture"
)}
> >
${this.hass.localize("ui.components.picture-upload.clear_picture")}
</ha-button> </ha-button>
</div> </div>
</div> </div>

View File

@ -130,7 +130,7 @@ export class HaYamlEditor extends LitElement {
<div class="card-actions"> <div class="card-actions">
${this.copyClipboard ${this.copyClipboard
? html` ? html`
<ha-button appearance="plain" @click=${this._copyYaml}> <ha-button @click=${this._copyYaml}>
${this.hass.localize( ${this.hass.localize(
"ui.components.yaml-editor.copy_to_clipboard" "ui.components.yaml-editor.copy_to_clipboard"
)} )}

View File

@ -119,15 +119,15 @@ class DialogMediaManage extends LitElement {
class="danger" class="danger"
slot="navigationIcon" slot="navigationIcon"
.disabled=${this._deleting} .disabled=${this._deleting}
@click=${this._handleDelete} .label=${this.hass.localize(
>
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
${this.hass.localize(
`ui.components.media-browser.file_management.${ `ui.components.media-browser.file_management.${
this._deleting ? "deleting" : "delete" this._deleting ? "deleting" : "delete"
}`, }`,
{ count: this._selected.size } { count: this._selected.size }
)} )}
@click=${this._handleDelete}
>
<ha-svg-icon .path=${mdiDelete} slot="start"></ha-svg-icon>
</ha-button> </ha-button>
${this._deleting ${this._deleting
@ -135,15 +135,15 @@ class DialogMediaManage extends LitElement {
: html` : html`
<ha-button <ha-button
slot="actionItems" slot="actionItems"
.label=${this.hass.localize(
`ui.components.media-browser.file_management.deselect_all`
)}
@click=${this._handleDeselectAll} @click=${this._handleDeselectAll}
> >
<ha-svg-icon <ha-svg-icon
.path=${mdiClose} .path=${mdiClose}
slot="start" slot="icon"
></ha-svg-icon> ></ha-svg-icon>
${this.hass.localize(
`ui.components.media-browser.file_management.deselect_all`
)}
</ha-button> </ha-button>
`} `}
`} `}
@ -331,10 +331,20 @@ class DialogMediaManage extends LitElement {
--mdc-theme-primary: var(--error-color); --mdc-theme-primary: var(--error-color);
} }
ha-svg-icon[slot="icon"] {
vertical-align: middle;
}
ha-tip { ha-tip {
margin: 16px; margin: 16px;
} }
ha-svg-icon[slot="icon"] {
margin-inline-start: 0px !important;
margin-inline-end: 8px !important;
direction: var(--direction);
}
.refresh { .refresh {
display: flex; display: flex;
height: 200px; height: 200px;

View File

@ -1,5 +1,5 @@
import { mdiFolderEdit } from "@mdi/js"; import { mdiFolderEdit } from "@mdi/js";
import { html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import type { MediaPlayerItem } from "../../data/media-player"; import type { MediaPlayerItem } from "../../data/media-player";
@ -53,6 +53,18 @@ class MediaManageButton extends LitElement {
onClose: () => fireEvent(this, "media-refresh"), onClose: () => fireEvent(this, "media-refresh"),
}); });
} }
static styles = css`
ha-svg-icon[slot="icon"] {
vertical-align: middle;
}
ha-svg-icon[slot="icon"] {
margin-inline-start: 0px;
margin-inline-end: 8px;
direction: var(--direction);
}
`;
} }
declare global { declare global {

View File

@ -169,7 +169,6 @@ export interface TagTrigger extends BaseTrigger {
export interface TimeTrigger extends BaseTrigger { export interface TimeTrigger extends BaseTrigger {
trigger: "time"; trigger: "time";
at: string | { entity_id: string; offset?: string }; at: string | { entity_id: string; offset?: string };
weekday?: string | string[];
} }
export interface TemplateTrigger extends BaseTrigger { export interface TemplateTrigger extends BaseTrigger {

View File

@ -400,23 +400,8 @@ const tryDescribeTrigger = (
return `${entityStr}${offsetStr}`; return `${entityStr}${offsetStr}`;
}); });
// Handle weekday information if present
let weekdays: string[] = [];
if (trigger.weekday) {
const weekdayArray = ensureArray(trigger.weekday);
if (weekdayArray.length > 0) {
weekdays = weekdayArray.map((day) =>
hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.weekdays.${day}` as any
)
);
}
}
return hass.localize(`${triggerTranslationBaseKey}.time.description.full`, { return hass.localize(`${triggerTranslationBaseKey}.time.description.full`, {
time: formatListWithOrs(hass.locale, result), time: formatListWithOrs(hass.locale, result),
hasWeekdays: weekdays.length > 0 ? "true" : "false",
weekdays: formatListWithOrs(hass.locale, weekdays),
}); });
} }

View File

@ -8,7 +8,7 @@ export interface HassioHostInfo {
chassis: string; chassis: string;
cpe: string; cpe: string;
deployment: string; deployment: string;
disk_life_time: number | null; disk_life_time: number | "";
disk_free: number; disk_free: number;
disk_total: number; disk_total: number;
disk_used: number; disk_used: number;

View File

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

View File

@ -104,13 +104,23 @@ class StepFlowForm extends LitElement {
</div>` </div>`
: nothing} : nothing}
<div class="buttons"> <div class="buttons">
<ha-button @click=${this._submitStep} .loading=${this._loading}> ${this._loading
? html`
<div class="submit-spinner">
<ha-spinner size="small"></ha-spinner>
</div>
`
: html`
<div>
<ha-button @click=${this._submitStep}>
${this.flowConfig.renderShowFormStepSubmitButton( ${this.flowConfig.renderShowFormStepSubmitButton(
this.hass, this.hass,
this.step this.step
)} )}
</ha-button> </ha-button>
</div> </div>
`}
</div>
`; `;
} }
@ -294,6 +304,15 @@ class StepFlowForm extends LitElement {
color: red; color: red;
} }
.submit-spinner {
height: 36px;
display: flex;
align-items: center;
margin-right: 16px;
margin-inline-end: 16px;
margin-inline-start: initial;
}
ha-alert, ha-alert,
ha-form { ha-form {
margin-top: 24px; margin-top: 24px;
@ -301,7 +320,7 @@ class StepFlowForm extends LitElement {
} }
.buttons { .buttons {
padding: 16px; padding: 8px;
} }
`, `,
]; ];

View File

@ -34,7 +34,7 @@ export const configFlowContentStyles = css`
.buttons { .buttons {
position: relative; position: relative;
padding: 16px; padding: 8px 16px 8px 24px;
margin: 8px 0 0; margin: 8px 0 0;
color: var(--primary-color); color: var(--primary-color);
display: flex; display: flex;

View File

@ -228,7 +228,7 @@ class DialogLightColorFavorite extends LitElement {
</div> </div>
</div> </div>
<div slot="actions"> <div slot="actions">
<ha-button appearance="plain" @click=${this._cancelDialog}> <ha-button @click=${this._cancelDialog}>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button @click=${this._save} .disabled=${!this._color} <ha-button @click=${this._save} .disabled=${!this._color}

View File

@ -1,13 +1,13 @@
import { css, html, LitElement, nothing } from "lit"; import { css, html, LitElement, nothing } from "lit";
import { property, state } from "lit/decorators"; import { property, state } from "lit/decorators";
import { slugify } from "../../../common/string/slugify";
import "../../../components/buttons/ha-progress-button";
import "../../../components/ha-camera-stream"; import "../../../components/ha-camera-stream";
import type { CameraEntity } from "../../../data/camera"; import type { CameraEntity } from "../../../data/camera";
import { UNAVAILABLE } from "../../../data/entity";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import "../../../components/buttons/ha-progress-button";
import { UNAVAILABLE } from "../../../data/entity";
import { fileDownload } from "../../../util/file_download"; import { fileDownload } from "../../../util/file_download";
import { showToast } from "../../../util/toast"; import { showToast } from "../../../util/toast";
import { slugify } from "../../../common/string/slugify";
class MoreInfoCamera extends LitElement { class MoreInfoCamera extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@ -46,7 +46,6 @@ class MoreInfoCamera extends LitElement {
@click=${this._downloadSnapshot} @click=${this._downloadSnapshot}
.progress=${this._waiting} .progress=${this._waiting}
.disabled=${this.stateObj.state === UNAVAILABLE} .disabled=${this.stateObj.state === UNAVAILABLE}
appearance="filled"
> >
${this.hass.localize( ${this.hass.localize(
"ui.dialogs.more_info_control.camera.download_snapshot" "ui.dialogs.more_info_control.camera.download_snapshot"
@ -105,7 +104,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: 12px;
z-index: 1; z-index: 1;
gap: 8px; gap: 8px;
} }

View File

@ -51,11 +51,7 @@ class MoreInfoSiren extends LitElement {
.iconPathOff=${mdiVolumeOff} .iconPathOff=${mdiVolumeOff}
></ha-state-control-toggle> ></ha-state-control-toggle>
${allowAdvanced ${allowAdvanced
? html`<ha-button ? html`<ha-button @click=${this._showAdvancedControlsDialog}>
appearance="plain"
size="small"
@click=${this._showAdvancedControlsDialog}
>
${this.hass.localize("ui.components.siren.advanced_controls")} ${this.hass.localize("ui.components.siren.advanced_controls")}
</ha-button>` </ha-button>`
: nothing} : nothing}

View File

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

View File

@ -38,7 +38,7 @@ export class HuiNotificationItemTemplate extends LitElement {
.actions { .actions {
border-top: 1px solid var(--divider-color, #e8e8e8); border-top: 1px solid var(--divider-color, #e8e8e8);
padding: 8px; padding: 5px 16px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }

View File

@ -32,7 +32,7 @@ class DialogBox extends LitElement {
)} )}
> >
<p>${this.hass.localize("ui.dialogs.update_backup.text")}</p> <p>${this.hass.localize("ui.dialogs.update_backup.text")}</p>
<ha-button appearance="plain" @click=${this._no} slot="secondaryAction"> <ha-button @click=${this._no} slot="secondaryAction">
${this.hass!.localize("ui.common.no")} ${this.hass!.localize("ui.common.no")}
</ha-button> </ha-button>
<ha-button @click=${this._yes} slot="primaryAction"> <ha-button @click=${this._yes} slot="primaryAction">

View File

@ -76,6 +76,7 @@ export class CloudStepSignin extends LitElement {
</div> </div>
<div class="footer"> <div class="footer">
<ha-button <ha-button
unelevated
@click=${this._handleLogin} @click=${this._handleLogin}
.disabled=${this._requestInProgress} .disabled=${this._requestInProgress}
>${this.hass.localize( >${this.hass.localize(

View File

@ -90,11 +90,11 @@ export class CloudStepSignup extends LitElement {
? html`<ha-button ? html`<ha-button
@click=${this._handleResendVerifyEmail} @click=${this._handleResendVerifyEmail}
.disabled=${this._requestInProgress} .disabled=${this._requestInProgress}
appearance="plain"
>${this.hass.localize( >${this.hass.localize(
"ui.panel.config.cloud.register.resend_confirm_email" "ui.panel.config.cloud.register.resend_confirm_email"
)}</ha-button )}</ha-button
><ha-button ><ha-button
unelevated
@click=${this._login} @click=${this._login}
.disabled=${this._requestInProgress} .disabled=${this._requestInProgress}
>${this.hass.localize( >${this.hass.localize(
@ -104,12 +104,12 @@ export class CloudStepSignup extends LitElement {
: html`<ha-button : html`<ha-button
@click=${this._signIn} @click=${this._signIn}
.disabled=${this._requestInProgress} .disabled=${this._requestInProgress}
appearance="plain"
>${this.hass.localize( >${this.hass.localize(
"ui.panel.config.cloud.login.sign_in" "ui.panel.config.cloud.login.sign_in"
)}</ha-button )}</ha-button
> >
<ha-button <ha-button
unelevated
@click=${this._handleRegister} @click=${this._handleRegister}
.disabled=${this._requestInProgress} .disabled=${this._requestInProgress}
>${this.hass.localize("ui.common.next")}</ha-button >${this.hass.localize("ui.common.next")}</ha-button

View File

@ -70,7 +70,6 @@ export class HaVoiceAssistantSetupStepArea extends LitElement {
display: block; display: block;
width: 100%; width: 100%;
margin-bottom: 24px; margin-bottom: 24px;
text-align: initial;
} }
`, `,
]; ];

View File

@ -51,16 +51,16 @@ export class HaVoiceAssistantSetupStepCheck extends LitElement {
)} )}
</p> </p>
<div class="footer"> <div class="footer">
<ha-button <a
appearance="plain"
href=${documentationUrl( href=${documentationUrl(
this.hass, this.hass,
"/voice_control/troubleshooting/#i-dont-get-a-voice-response" "/voice_control/troubleshooting/#i-dont-get-a-voice-response"
)} )}
> ><ha-button
>${this.hass.localize( >${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.check.help" "ui.panel.config.voice_assistants.satellite_wizard.check.help"
)}</ha-button )}</ha-button
></a
> >
<ha-button @click=${this._testConnection} <ha-button @click=${this._testConnection}
>${this.hass.localize( >${this.hass.localize(

View File

@ -95,27 +95,24 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
"ui.panel.config.voice_assistants.satellite_wizard.local.failed_secondary" "ui.panel.config.voice_assistants.satellite_wizard.local.failed_secondary"
)} )}
</p> </p>
<ha-button <ha-button @click=${this._prevStep}
appearance="plain"
size="small"
@click=${this._prevStep}
>${this.hass.localize("ui.common.back")}</ha-button >${this.hass.localize("ui.common.back")}</ha-button
> >
<ha-button <a
href=${documentationUrl( href=${documentationUrl(
this.hass, this.hass,
"/voice_control/voice_remote_local_assistant/" "/voice_control/voice_remote_local_assistant/"
)} )}
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
size="small"
appearance="plain"
> >
<ha-svg-icon .path=${mdiOpenInNew} slot="start"></ha-svg-icon> <ha-button>
<ha-svg-icon .path=${mdiOpenInNew} slot="icon"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.common.learn_more" "ui.panel.config.common.learn_more"
)}</ha-button )}</ha-button
>` >
</a>`
: this._state === "NOT_SUPPORTED" : this._state === "NOT_SUPPORTED"
? html`<img ? html`<img
src="/static/images/voice-assistant/error.png" src="/static/images/voice-assistant/error.png"
@ -131,27 +128,27 @@ export class HaVoiceAssistantSetupStepLocal extends LitElement {
"ui.panel.config.voice_assistants.satellite_wizard.local.not_supported_secondary" "ui.panel.config.voice_assistants.satellite_wizard.local.not_supported_secondary"
)} )}
</p> </p>
<ha-button <ha-button @click=${this._prevStep}
appearance="plain"
size="small"
@click=${this._prevStep}
>${this.hass.localize("ui.common.back")}</ha-button >${this.hass.localize("ui.common.back")}</ha-button
> >
<ha-button <a
href=${documentationUrl( href=${documentationUrl(
this.hass, this.hass,
"/voice_control/voice_remote_local_assistant/" "/voice_control/voice_remote_local_assistant/"
)} )}
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
appearance="plain"
size="small"
> >
<ha-svg-icon .path=${mdiOpenInNew} slot="start"></ha-svg-icon> <ha-button>
<ha-svg-icon
.path=${mdiOpenInNew}
slot="icon"
></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.common.learn_more" "ui.panel.config.common.learn_more"
)}</ha-button )}</ha-button
>` >
</a>`
: nothing} : nothing}
</div>`; </div>`;
} }

View File

@ -235,7 +235,10 @@ export class HaVoiceAssistantSetupStepPipeline extends LitElement {
: nothing} : nothing}
</div> </div>
<div class="footer"> <div class="footer">
<ha-button @click=${this._createPipeline} .disabled=${!this._value} <ha-button
@click=${this._createPipeline}
unelevated
.disabled=${!this._value}
>${this.hass.localize("ui.common.next")}</ha-button >${this.hass.localize("ui.common.next")}</ha-button
> >
</div>`; </div>`;

View File

@ -126,15 +126,8 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
</ha-list-item>` </ha-list-item>`
)} )}
</ha-select> </ha-select>
<ha-button <ha-button @click=${this._testWakeWord}>
appearance="plain" <ha-svg-icon slot="icon" .path=${mdiMicrophone}></ha-svg-icon>
size="small"
@click=${this._testWakeWord}
>
<ha-svg-icon
slot="start"
.path=${mdiMicrophone}
></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.success.test_wakeword" "ui.panel.config.voice_assistants.satellite_wizard.success.test_wakeword"
)} )}
@ -158,12 +151,8 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
</ha-list-item>` </ha-list-item>`
)} )}
</ha-select> </ha-select>
<ha-button <ha-button @click=${this._openPipeline}>
appearance="plain" <ha-svg-icon slot="icon" .path=${mdiCog}></ha-svg-icon>
size="small"
@click=${this._openPipeline}
>
<ha-svg-icon slot="start" .path=${mdiCog}></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.success.edit_pipeline" "ui.panel.config.voice_assistants.satellite_wizard.success.edit_pipeline"
)} )}
@ -180,12 +169,8 @@ export class HaVoiceAssistantSetupStepSuccess extends LitElement {
@value-changed=${this._voicePicked} @value-changed=${this._voicePicked}
@closed=${stopPropagation} @closed=${stopPropagation}
></ha-tts-voice-picker> ></ha-tts-voice-picker>
<ha-button <ha-button @click=${this._testTts}>
appearance="plain" <ha-svg-icon slot="icon" .path=${mdiPlay}></ha-svg-icon>
size="small"
@click=${this._testTts}
>
<ha-svg-icon slot="start" .path=${mdiPlay}></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.success.try_tts" "ui.panel.config.voice_assistants.satellite_wizard.success.try_tts"
)} )}

View File

@ -148,10 +148,7 @@ export class HaVoiceAssistantSetupStepWakeWord extends LitElement {
${this.assistConfiguration && ${this.assistConfiguration &&
this.assistConfiguration.available_wake_words.length > 1 this.assistConfiguration.available_wake_words.length > 1
? html`<div class="footer centered"> ? html`<div class="footer centered">
<ha-button <ha-button @click=${this._changeWakeWord}
appearance="plain"
size="small"
@click=${this._changeWakeWord}
>${this.hass.localize( >${this.hass.localize(
"ui.panel.config.voice_assistants.satellite_wizard.wake_word.change_wake_word" "ui.panel.config.voice_assistants.satellite_wizard.wake_word.change_wake_word"
)}</ha-button )}</ha-button

View File

@ -271,6 +271,7 @@ export class HaVoiceCommandDialog extends LitElement {
margin-inline-start: -8px; margin-inline-start: -8px;
} }
ha-button-menu ha-button { ha-button-menu ha-button {
--ha-font-size-l: var(--ha-font-size-m);
--ha-button-height: 20px; --ha-button-height: 20px;
} }
ha-button-menu ha-button::part(base) { ha-button-menu ha-button::part(base) {

View File

@ -22,9 +22,7 @@ class HaInitPage extends LitElement {
<p class="retry-text"> <p class="retry-text">
Retrying in ${this._retryInSeconds} seconds... Retrying in ${this._retryInSeconds} seconds...
</p> </p>
<ha-button size="small" appearance="plain" @click=${this._retry} <ha-button @click=${this._retry}>Retry now</ha-button>
>Retry now</ha-button
>
${location.host.includes("ui.nabu.casa") ${location.host.includes("ui.nabu.casa")
? html` ? html`
<p> <p>

View File

@ -69,13 +69,10 @@ class NotificationManager extends LitElement {
${this._parameters?.action ${this._parameters?.action
? html` ? html`
<ha-button <ha-button
appearance="plain"
size="small"
slot="action" slot="action"
.label=${this._parameters?.action.text}
@click=${this._buttonClicked} @click=${this._buttonClicked}
> ></ha-button>
${this._parameters?.action.text}
</ha-button>
` `
: nothing} : nothing}
${this._parameters?.dismissable ${this._parameters?.dismissable

View File

@ -32,16 +32,17 @@ class OnboardingRestoreBackupNoCloudBackup extends LitElement {
<ha-button @click=${this._signOut}> <ha-button @click=${this._signOut}>
${this.localize("ui.panel.page-onboarding.restore.ha-cloud.sign_out")} ${this.localize("ui.panel.page-onboarding.restore.ha-cloud.sign_out")}
</ha-button> </ha-button>
<ha-button <a
href="https://www.nabucasa.com/config/backups/" href="https://www.nabucasa.com/config/backups/"
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
appearance="plain"
> >
<ha-button>
${this.localize( ${this.localize(
"ui.panel.page-onboarding.restore.ha-cloud.learn_more" "ui.panel.page-onboarding.restore.ha-cloud.learn_more"
)} )}
</ha-button> </ha-button>
</a>
</div> </div>
`; `;
} }

View File

@ -131,17 +131,18 @@ class OnboardingRestoreBackupRestore extends LitElement {
${this.localize( ${this.localize(
"ui.panel.page-onboarding.restore.details.addons_unsupported" "ui.panel.page-onboarding.restore.details.addons_unsupported"
)} )}
<ha-button <a
slot="action" slot="action"
href="https://www.home-assistant.io/installation/#advanced-installation-methods" href="https://www.home-assistant.io/installation/#advanced-installation-methods"
target="_blank" target="_blank"
rel="noreferrer noopener" rel="noreferrer noopener"
size="small"
> >
${this.localize( <ha-button
>${this.localize(
"ui.panel.page-onboarding.restore.ha-cloud.learn_more" "ui.panel.page-onboarding.restore.ha-cloud.learn_more"
)}</ha-button )}</ha-button
> >
</a>
</ha-alert>` </ha-alert>`
: nothing} : nothing}
${!onlyHomeAssistantBackup ${!onlyHomeAssistantBackup
@ -190,13 +191,14 @@ class OnboardingRestoreBackupRestore extends LitElement {
<div class="actions${this.mode === "cloud" ? " cloud" : ""}"> <div class="actions${this.mode === "cloud" ? " cloud" : ""}">
${this.mode === "cloud" ${this.mode === "cloud"
? html`<ha-button appearance="plain" @click=${this._signOut}> ? html`<ha-button @click=${this._signOut}>
${this.localize( ${this.localize(
"ui.panel.page-onboarding.restore.ha-cloud.sign_out" "ui.panel.page-onboarding.restore.ha-cloud.sign_out"
)} )}
</ha-button>` </ha-button>`
: nothing} : nothing}
<ha-progress-button <ha-progress-button
unelevated
.progress=${this._loading} .progress=${this._loading}
.disabled=${this._loading || .disabled=${this._loading ||
(backupProtected && this._encryptionKey === "") || (backupProtected && this._encryptionKey === "") ||

View File

@ -40,11 +40,7 @@ class ConfirmEventDialogBox extends LitElement {
<div> <div>
<p>${this._params.text}</p> <p>${this._params.text}</p>
</div> </div>
<ha-button <ha-button @click=${this._dismiss} slot="secondaryAction">
appearance="plain"
@click=${this._dismiss}
slot="secondaryAction"
>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button <ha-button

View File

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

View File

@ -135,7 +135,10 @@ class PanelCalendar extends LitElement {
> >
<ha-button slot="trigger"> <ha-button slot="trigger">
${this.hass.localize("ui.components.calendar.my_calendars")} ${this.hass.localize("ui.components.calendar.my_calendars")}
<ha-svg-icon slot="end" .path=${mdiChevronDown}></ha-svg-icon> <ha-svg-icon
slot="trailingIcon"
.path=${mdiChevronDown}
></ha-svg-icon>
</ha-button> </ha-button>
${calendarItems} ${calendarItems}
${this.hass.user?.is_admin ${this.hass.user?.is_admin
@ -300,7 +303,25 @@ class PanelCalendar extends LitElement {
--calendar-border-width: 1px 0; --calendar-border-width: 1px 0;
} }
ha-button-menu ha-button { ha-button-menu ha-button {
--ha-font-size-m: var(--ha-font-size-l); --mdc-theme-primary: currentColor;
--mdc-typography-button-text-transform: none;
--mdc-typography-button-font-size: var(
--mdc-typography-headline6-font-size,
var(--ha-font-size-l)
);
--mdc-typography-button-font-weight: var(
--mdc-typography-headline6-font-weight,
var(--ha-font-weight-medium)
);
--mdc-typography-button-letter-spacing: var(
--mdc-typography-headline6-letter-spacing,
0.0125em
);
--mdc-typography-button-line-height: var(
--mdc-typography-headline6-line-height,
var(--ha-line-height-expanded)
);
--button-height: 40px;
} }
:host([mobile]) .lists { :host([mobile]) .lists {
--mdc-menu-min-width: 100vw; --mdc-menu-min-width: 100vw;

View File

@ -220,25 +220,32 @@ export class DialogAddApplicationCredential extends LitElement {
helperPersistent helperPersistent
></ha-password-field> ></ha-password-field>
</div> </div>
${this._loading
? html`
<div slot="primaryAction" class="submit-spinner">
<ha-spinner></ha-spinner>
</div>
`
: html`
<ha-button <ha-button
appearance="plain" appearance="plain"
slot="secondaryAction" slot="secondaryAction"
@click=${this._abortDialog} @click=${this._abortDialog}
.disabled=${this._loading}
> >
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button <ha-button
slot="primaryAction" slot="primaryAction"
.disabled=${!this._domain || !this._clientId || !this._clientSecret} .disabled=${!this._domain ||
!this._clientId ||
!this._clientSecret}
@click=${this._addApplicationCredential} @click=${this._addApplicationCredential}
.loading=${this._loading}
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.application_credentials.editor.add" "ui.panel.config.application_credentials.editor.add"
)} )}
</ha-button> </ha-button>
`}
</ha-dialog> </ha-dialog>
`; `;
} }

View File

@ -30,8 +30,6 @@ export default class HaAutomationAction extends LitElement {
@property({ type: Boolean }) public disabled = false; @property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public root = false;
@property({ attribute: false }) public actions!: Action[]; @property({ attribute: false }) public actions!: Action[];
@property({ attribute: false }) public highlightedActions?: Action[]; @property({ attribute: false }) public highlightedActions?: Action[];
@ -112,8 +110,6 @@ export default class HaAutomationAction extends LitElement {
<ha-button <ha-button
.disabled=${this.disabled} .disabled=${this.disabled}
@click=${this._addActionDialog} @click=${this._addActionDialog}
.appearance=${this.root ? "accent" : "filled"}
.size=${this.root ? "medium" : "small"}
> >
<ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon> <ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
@ -121,10 +117,9 @@ export default class HaAutomationAction extends LitElement {
)} )}
</ha-button> </ha-button>
<ha-button <ha-button
appearance="plain"
.disabled=${this.disabled} .disabled=${this.disabled}
@click=${this._addActionBuildingBlockDialog} @click=${this._addActionBuildingBlockDialog}
appearance="plain"
.size=${this.root ? "medium" : "small"}
> >
<ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon> <ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(

View File

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

View File

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

View File

@ -260,14 +260,12 @@ class DialogAutomationSave extends LitElement implements HassDialog {
.path=${mdiClose} .path=${mdiClose}
></ha-icon-button> ></ha-icon-button>
<span slot="title">${this._params.title || title}</span> <span slot="title">${this._params.title || title}</span>
${this._params.hideInputs <ha-suggest-with-ai-button
? nothing
: html` <ha-suggest-with-ai-button
slot="actionItems" slot="actionItems"
.hass=${this.hass} .hass=${this.hass}
.generateTask=${this._generateTask} .generateTask=${this._generateTask}
@suggestion=${this._handleSuggestion} @suggestion=${this._handleSuggestion}
></ha-suggest-with-ai-button>`} ></ha-suggest-with-ai-button>
</ha-dialog-header> </ha-dialog-header>
${this._error ${this._error
? html`<ha-alert alert-type="error" ? html`<ha-alert alert-type="error"
@ -383,7 +381,7 @@ class DialogAutomationSave extends LitElement implements HassDialog {
return { return {
type: "data", type: "data",
task: { task: {
task_name: `frontend__${term}__save`, task_name: `frontend:${term}:save`,
instructions: `Suggest in language "${this.hass.language}" a name, description, category and labels for the following Home Assistant ${term}. instructions: `Suggest in language "${this.hass.language}" a name, description, category and labels for the following Home Assistant ${term}.
The name should be relevant to the ${term}'s purpose. The name should be relevant to the ${term}'s purpose.

View File

@ -34,8 +34,6 @@ export default class HaAutomationCondition extends LitElement {
@property({ type: Boolean }) public disabled = false; @property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public root = false;
@state() private _showReorder = false; @state() private _showReorder = false;
@state() @state()
@ -161,8 +159,6 @@ export default class HaAutomationCondition extends LitElement {
<ha-button <ha-button
.disabled=${this.disabled} .disabled=${this.disabled}
@click=${this._addConditionDialog} @click=${this._addConditionDialog}
.appearance=${this.root ? "accent" : "filled"}
.size=${this.root ? "medium" : "small"}
> >
<ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon> <ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
@ -172,7 +168,6 @@ export default class HaAutomationCondition extends LitElement {
<ha-button <ha-button
.disabled=${this.disabled} .disabled=${this.disabled}
appearance="plain" appearance="plain"
.size=${this.root ? "medium" : "small"}
@click=${this._addConditionBuildingBlockDialog} @click=${this._addConditionBuildingBlockDialog}
> >
<ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon> <ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon>

View File

@ -487,7 +487,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
.disabled=${Boolean(this._readOnly)} .disabled=${Boolean(this._readOnly)}
.dirty=${this._dirty} .dirty=${this._dirty}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
@editor-save=${this._handleSaveAutomation}
></manual-automation-editor> ></manual-automation-editor>
`} `}
</div> </div>
@ -518,7 +517,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
.defaultValue=${this._preprocessYaml()} .defaultValue=${this._preprocessYaml()}
.readOnly=${this._readOnly} .readOnly=${this._readOnly}
@value-changed=${this._yamlChanged} @value-changed=${this._yamlChanged}
@editor-save=${this._handleSaveAutomation}
.showErrors=${false} .showErrors=${false}
disable-fullscreen disable-fullscreen
></ha-yaml-editor>` ></ha-yaml-editor>`

View File

@ -228,7 +228,6 @@ export class HaManualAutomationEditor extends LitElement {
@value-changed=${this._conditionChanged} @value-changed=${this._conditionChanged}
.hass=${this.hass} .hass=${this.hass}
.disabled=${this.disabled} .disabled=${this.disabled}
root
></ha-automation-condition> ></ha-automation-condition>
<div class="header"> <div class="header">
@ -270,7 +269,6 @@ export class HaManualAutomationEditor extends LitElement {
.hass=${this.hass} .hass=${this.hass}
.narrow=${this.narrow} .narrow=${this.narrow}
.disabled=${this.disabled} .disabled=${this.disabled}
root
></ha-automation-action> ></ha-automation-action>
`; `;
} }

View File

@ -100,14 +100,14 @@ export default class HaAutomationOption extends LitElement {
)} )}
<div class="buttons"> <div class="buttons">
<ha-button <ha-button
appearance="filled" outlined
.disabled=${this.disabled} .disabled=${this.disabled}
@click=${this._addOption} .label=${this.hass.localize(
>
<ha-svg-icon .path=${mdiPlus} slot="start"></ha-svg-icon>
${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.choose.add_option" "ui.panel.config.automation.editor.actions.type.choose.add_option"
)} )}
@click=${this._addOption}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</ha-button> </ha-button>
</div> </div>
</div> </div>

View File

@ -58,7 +58,7 @@ class DialogPasteReplace extends LitElement implements HassDialog {
></ha-yaml-editor> ></ha-yaml-editor>
<div slot="primaryAction"> <div slot="primaryAction">
<ha-button appearance="plain" @click=${this._handleAppend}> <ha-button @click=${this._handleAppend}>
${this.hass.localize("ui.common.append")} ${this.hass.localize("ui.common.append")}
</ha-button> </ha-button>
<ha-button @click=${this._handleReplace}> <ha-button @click=${this._handleReplace}>
@ -89,10 +89,6 @@ class DialogPasteReplace extends LitElement implements HassDialog {
font-size: inherit; font-size: inherit;
font-weight: inherit; font-weight: inherit;
} }
div[slot="primaryAction"] {
display: flex;
gap: 8px;
}
`, `,
]; ];
} }

View File

@ -2,13 +2,11 @@ import type { PropertyValues } from "lit";
import { html, LitElement, nothing } from "lit"; import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { firstWeekdayIndex } from "../../../../../common/datetime/first_weekday";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../../components/ha-form/types";
import type { TimeTrigger } from "../../../../../data/automation"; import type { TimeTrigger } from "../../../../../data/automation";
import type { FrontendLocaleData } from "../../../../../data/translation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
import { computeDomain } from "../../../../../common/entity/compute_domain"; import { computeDomain } from "../../../../../common/entity/compute_domain";
@ -16,7 +14,6 @@ import { computeDomain } from "../../../../../common/entity/compute_domain";
const MODE_TIME = "time"; const MODE_TIME = "time";
const MODE_ENTITY = "entity"; const MODE_ENTITY = "entity";
const VALID_DOMAINS = ["sensor", "input_datetime"]; const VALID_DOMAINS = ["sensor", "input_datetime"];
const DAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] as const;
@customElement("ha-automation-trigger-time") @customElement("ha-automation-trigger-time")
export class HaTimeTrigger extends LitElement implements TriggerElement { export class HaTimeTrigger extends LitElement implements TriggerElement {
@ -38,14 +35,9 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
private _schema = memoizeOne( private _schema = memoizeOne(
( (
localize: LocalizeFunc, localize: LocalizeFunc,
locale: FrontendLocaleData,
inputMode: typeof MODE_TIME | typeof MODE_ENTITY inputMode: typeof MODE_TIME | typeof MODE_ENTITY
) => { ) =>
const dayIndex = firstWeekdayIndex(locale); [
const sortedDays = DAYS.slice(dayIndex, DAYS.length).concat(
DAYS.slice(0, dayIndex)
);
return [
{ {
name: "mode", name: "mode",
type: "select", type: "select",
@ -81,21 +73,7 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
}, },
{ name: "offset", selector: { text: {} } }, { name: "offset", selector: { text: {} } },
] as const)), ] as const)),
{
type: "multi_select",
name: "weekday",
options: sortedDays.map(
(day) =>
[
day,
localize(
`ui.panel.config.automation.editor.triggers.type.time.weekdays.${day}`
),
] as const ] as const
),
},
] as const;
}
); );
public willUpdate(changedProperties: PropertyValues) { public willUpdate(changedProperties: PropertyValues) {
@ -117,14 +95,12 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
inputMode: undefined | typeof MODE_ENTITY | typeof MODE_TIME, inputMode: undefined | typeof MODE_ENTITY | typeof MODE_TIME,
at: at:
| string | string
| { entity_id: string | undefined; offset?: string | undefined }, | { entity_id: string | undefined; offset?: string | undefined }
weekday: string | string[] | undefined
): { ): {
mode: typeof MODE_TIME | typeof MODE_ENTITY; mode: typeof MODE_TIME | typeof MODE_ENTITY;
entity: string | undefined; entity: string | undefined;
time: string | undefined; time: string | undefined;
offset: string | undefined; offset: string | undefined;
weekday: string | string[] | undefined;
} => { } => {
const entity = const entity =
typeof at === "object" typeof at === "object"
@ -140,7 +116,6 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
entity, entity,
time, time,
offset, offset,
weekday,
}; };
} }
); );
@ -152,12 +127,8 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
return nothing; return nothing;
} }
const data = this._data(this._inputMode, at, this.trigger.weekday); const data = this._data(this._inputMode, at);
const schema = this._schema( const schema = this._schema(this.hass.localize, data.mode);
this.hass.localize,
this.hass.locale,
data.mode
);
return html` return html`
<ha-form <ha-form
@ -175,18 +146,14 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
ev.stopPropagation(); ev.stopPropagation();
const newValue = { ...ev.detail.value }; const newValue = { ...ev.detail.value };
this._inputMode = newValue.mode; this._inputMode = newValue.mode;
const weekday = newValue.weekday;
delete newValue.weekday;
if (newValue.mode === MODE_TIME) { if (newValue.mode === MODE_TIME) {
delete newValue.entity; delete newValue.entity;
delete newValue.offset; delete newValue.offset;
} else { } else {
delete newValue.time; delete newValue.time;
} }
fireEvent(this, "value-changed", {
const triggerUpdate: TimeTrigger = { value: {
...this.trigger, ...this.trigger,
at: newValue.offset at: newValue.offset
? { ? {
@ -194,17 +161,7 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
offset: newValue.offset, offset: newValue.offset,
} }
: newValue.entity || newValue.time, : newValue.entity || newValue.time,
}; },
// Only include weekday if it has a value
if (weekday && weekday.length > 0) {
triggerUpdate.weekday = weekday;
} else {
delete triggerUpdate.weekday;
}
fireEvent(this, "value-changed", {
value: triggerUpdate,
}); });
} }
@ -216,10 +173,6 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
return this.hass.localize( return this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.at` `ui.panel.config.automation.editor.triggers.type.time.at`
); );
case "weekday":
return this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.weekday`
);
} }
return this.hass.localize( return this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.${schema.name}` `ui.panel.config.automation.editor.triggers.type.time.${schema.name}`

View File

@ -99,11 +99,13 @@ class HaBackupOverviewBackups extends LitElement {
</ha-md-list> </ha-md-list>
</div> </div>
<div class="card-actions"> <div class="card-actions">
<ha-button appearance="filled" href="/config/backup/backups?type=all"> <a href="/config/backup/backups?type=all">
<ha-button appearance="filled">
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.overview.backups.show_all" "ui.panel.config.backup.overview.backups.show_all"
)} )}
</ha-button> </ha-button>
</a>
</div> </div>
</ha-card> </ha-card>
`; `;

View File

@ -375,13 +375,8 @@ class DialogBackupOnboarding extends LitElement implements HassDialog {
"ui.panel.config.backup.encryption_key.download_emergency_kit_description" "ui.panel.config.backup.encryption_key.download_emergency_kit_description"
)} )}
</span> </span>
<ha-button <ha-button slot="end" @click=${this._downloadKey}>
size="small" <ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
appearance="plain"
slot="end"
@click=${this._downloadKey}
>
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.encryption_key.download_emergency_kit_action" "ui.panel.config.backup.encryption_key.download_emergency_kit_action"
)} )}

View File

@ -128,7 +128,7 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
<ha-button <ha-button
@click=${this._submit} @click=${this._submit}
.disabled=${!this._newEncryptionKey} .disabled=${!this._newEncryptionKey}
variant="danger" class="danger"
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.dialogs.change_encryption_key.actions.change" "ui.panel.config.backup.dialogs.change_encryption_key.actions.change"
@ -176,7 +176,7 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
)} )}
</span> </span>
<ha-button slot="end" @click=${this._downloadOld}> <ha-button slot="end" @click=${this._downloadOld}>
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon> <ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.encryption_key.download_old_emergency_kit_action" "ui.panel.config.backup.encryption_key.download_old_emergency_kit_action"
)} )}
@ -211,7 +211,7 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
)} )}
</span> </span>
<ha-button slot="end" @click=${this._downloadNew}> <ha-button slot="end" @click=${this._downloadNew}>
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon> <ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.encryption_key.download_emergency_kit_action" "ui.panel.config.backup.encryption_key.download_emergency_kit_action"
)} )}
@ -297,6 +297,9 @@ class DialogChangeBackupEncryptionKey extends LitElement implements HassDialog {
--md-list-item-leading-space: 0; --md-list-item-leading-space: 0;
--md-list-item-trailing-space: 0; --md-list-item-trailing-space: 0;
} }
ha-button.danger {
--mdc-theme-primary: var(--error-color);
}
.encryption-key { .encryption-key {
border: 1px solid var(--divider-color); border: 1px solid var(--divider-color);
background-color: var(--primary-background-color); background-color: var(--primary-background-color);

View File

@ -112,7 +112,7 @@ class DialogDownloadDecryptedBackup extends LitElement implements HassDialog {
: nothing} : nothing}
</div> </div>
<div slot="actions"> <div slot="actions">
<ha-button appearance="plain" @click=${this._cancel}> <ha-button @click=${this._cancel}>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>

View File

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

View File

@ -227,7 +227,7 @@ class DialogRestoreBackup extends LitElement implements HassDialog {
private _renderConfirmActions() { private _renderConfirmActions() {
return html` return html`
<ha-button appearance="plain" @click=${this.closeDialog}> <ha-button @click=${this.closeDialog}>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button @click=${this._restoreBackup} variant="danger"> <ha-button @click=${this._restoreBackup} variant="danger">

View File

@ -151,13 +151,8 @@ class DialogSetBackupEncryptionKey extends LitElement implements HassDialog {
"ui.panel.config.backup.encryption_key.download_emergency_kit_description" "ui.panel.config.backup.encryption_key.download_emergency_kit_description"
)} )}
</span> </span>
<ha-button <ha-button slot="end" @click=${this._download}>
size="small" <ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
appearance="plain"
slot="end"
@click=${this._download}
>
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.encryption_key.download_emergency_kit_action" "ui.panel.config.backup.encryption_key.download_emergency_kit_action"
)} )}

View File

@ -87,13 +87,8 @@ class DialogShowBackupEncryptionKey extends LitElement implements HassDialog {
"ui.panel.config.backup.encryption_key.download_emergency_kit_description" "ui.panel.config.backup.encryption_key.download_emergency_kit_description"
)} )}
</span> </span>
<ha-button <ha-button slot="end" @click=${this._download}>
size="small" <ha-svg-icon .path=${mdiDownload} slot="icon"></ha-svg-icon>
appearance="plain"
slot="end"
@click=${this._download}
>
<ha-svg-icon .path=${mdiDownload} slot="start"></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.encryption_key.download_emergency_kit_action" "ui.panel.config.backup.encryption_key.download_emergency_kit_action"
)} )}

View File

@ -113,10 +113,7 @@ export class DialogUploadBackup
></ha-file-upload> ></ha-file-upload>
</div> </div>
<div slot="actions"> <div slot="actions">
<ha-button <ha-button @click=${this.closeDialog} .disabled=${this._uploading}
appearance="plain"
@click=${this.closeDialog}
.disabled=${this._uploading}
>${this.hass.localize("ui.common.cancel")}</ha-button >${this.hass.localize("ui.common.cancel")}</ha-button
> >
<ha-button <ha-button

View File

@ -417,11 +417,7 @@ class HaConfigBackupBackups extends SubscribeMixin(LitElement) {
<div slot="selection-bar"> <div slot="selection-bar">
${!this.narrow ${!this.narrow
? html` ? html`
<ha-button <ha-button @click=${this._deleteSelected} class="warning">
appearance="plain"
@click=${this._deleteSelected}
variant="danger"
>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.backups.delete_selected" "ui.panel.config.backup.backups.delete_selected"
)} )}

View File

@ -158,18 +158,18 @@ class HaConfigBackupDetails extends LitElement {
"ui.panel.config.backup.location.encryption.location_encrypted_cloud_description" "ui.panel.config.backup.location.encryption.location_encrypted_cloud_description"
)} )}
</span> </span>
<ha-button <a
href="https://www.nabucasa.com/config/backups/" href="https://www.nabucasa.com/config/backups/"
target="_blank" target="_blank"
slot="end" slot="end"
rel="noreferrer noopener" rel="noreferrer noopener"
appearance="plain"
size="small"
> >
<ha-button>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.backup.location.encryption.location_encrypted_cloud_learn_more" "ui.panel.config.backup.location.encryption.location_encrypted_cloud_learn_more"
)} )}
</ha-button> </ha-button>
</a>
</ha-md-list-item> </ha-md-list-item>
` `
: encrypted : encrypted

View File

@ -187,11 +187,7 @@ export class CloudRemotePref extends LitElement {
) )
: nothing}</span : nothing}</span
> >
<ha-button <ha-button @click=${this._openCertInfo}>
appearance="plain"
size="small"
@click=${this._openCertInfo}
>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.cloud.account.remote.more_info" "ui.panel.config.cloud.account.remote.more_info"
)} )}

View File

@ -126,7 +126,7 @@ export class CloudTTSPref extends LitElement {
`} `}
</div> </div>
<div class="flex"></div> <div class="flex"></div>
<ha-button appearance="plain" @click=${this._openTryDialog}> <ha-button @click=${this._openTryDialog}>
${this.hass.localize("ui.panel.config.cloud.account.tts.try")} ${this.hass.localize("ui.panel.config.cloud.account.tts.try")}
</ha-button> </ha-button>
</div> </div>

View File

@ -77,9 +77,7 @@ export class DialogSupportPackage extends LitElement {
</ha-alert> </ha-alert>
<hr /> <hr />
<div class="actions"> <div class="actions">
<ha-button appearance="plain" @click=${this.closeDialog} <ha-button @click=${this.closeDialog}>Close</ha-button>
>Close</ha-button
>
<ha-button @click=${this._download}>Download</ha-button> <ha-button @click=${this._download}>Download</ha-button>
</div> </div>
</div> </div>

View File

@ -2,20 +2,19 @@ import "@material/mwc-button";
import { mdiHelpCircle, mdiStarFourPoints } from "@mdi/js"; import { mdiHelpCircle, mdiStarFourPoints } from "@mdi/js";
import { css, html, LitElement } from "lit"; import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import type { HaProgressButton } from "../../../components/buttons/ha-progress-button";
import "../../../components/entity/ha-entity-picker";
import type { HaEntityPicker } from "../../../components/entity/ha-entity-picker";
import "../../../components/ha-card"; import "../../../components/ha-card";
import "../../../components/ha-settings-row"; import "../../../components/ha-settings-row";
import "../../../components/entity/ha-entity-picker";
import type { HaEntityPicker } from "../../../components/entity/ha-entity-picker";
import type { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
import { import {
fetchAITaskPreferences, fetchAITaskPreferences,
saveAITaskPreferences, saveAITaskPreferences,
type AITaskPreferences, type AITaskPreferences,
} from "../../../data/ai_task"; } from "../../../data/ai_task";
import type { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
import { documentationUrl } from "../../../util/documentation-url"; import { documentationUrl } from "../../../util/documentation-url";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
@customElement("ai-task-pref") @customElement("ai-task-pref")
export class AITaskPref extends LitElement { export class AITaskPref extends LitElement {
@ -25,8 +24,6 @@ export class AITaskPref extends LitElement {
@state() private _prefs?: AITaskPreferences; @state() private _prefs?: AITaskPreferences;
private _gen_data_entity_id?: string | null;
protected firstUpdated(changedProps) { protected firstUpdated(changedProps) {
super.firstUpdated(changedProps); super.firstUpdated(changedProps);
if (!this.hass || !isComponentLoaded(this.hass, "ai_task")) { if (!this.hass || !isComponentLoaded(this.hass, "ai_task")) {
@ -89,51 +86,30 @@ export class AITaskPref extends LitElement {
.hass=${this.hass} .hass=${this.hass}
.disabled=${this._prefs === undefined && .disabled=${this._prefs === undefined &&
isComponentLoaded(this.hass, "ai_task")} isComponentLoaded(this.hass, "ai_task")}
.value=${this._gen_data_entity_id || .value=${this._prefs?.gen_data_entity_id}
this._prefs?.gen_data_entity_id}
.includeDomains=${["ai_task"]} .includeDomains=${["ai_task"]}
@value-changed=${this._handlePrefChange} @value-changed=${this._handlePrefChange}
></ha-entity-picker> ></ha-entity-picker>
</ha-settings-row> </ha-settings-row>
</div> </div>
<div class="card-actions">
<ha-progress-button @click=${this._update}>
${this.hass!.localize("ui.common.save")}
</ha-progress-button>
</div>
</ha-card> </ha-card>
`; `;
} }
private _handlePrefChange(ev: CustomEvent<{ value: string | undefined }>) { private async _handlePrefChange(
ev: CustomEvent<{ value: string | undefined }>
) {
const input = ev.target as HaEntityPicker; const input = ev.target as HaEntityPicker;
const key = input.dataset.name as keyof AITaskPreferences; const key = input.getAttribute("data-name") as keyof AITaskPreferences;
const value = ev.detail.value || null; const entityId = ev.detail.value || null;
this[`_${key}`] = value;
}
private async _update(ev) {
const button = ev.target as HaProgressButton;
if (button.progress) {
return;
}
button.progress = true;
const oldPrefs = this._prefs; const oldPrefs = this._prefs;
const update: Partial<AITaskPreferences> = { this._prefs = { ...this._prefs!, [key]: entityId };
gen_data_entity_id: this._gen_data_entity_id,
};
this._prefs = { ...this._prefs!, ...update };
try { try {
this._prefs = await saveAITaskPreferences(this.hass, { this._prefs = await saveAITaskPreferences(this.hass, {
...update, [key]: entityId,
}); });
button.actionSuccess();
} catch (_err: any) { } catch (_err: any) {
button.actionError();
this._prefs = oldPrefs; this._prefs = oldPrefs;
} finally {
button.progress = false;
} }
} }
@ -169,9 +145,6 @@ export class AITaskPref extends LitElement {
direction: var(--direction); direction: var(--direction);
color: var(--secondary-text-color); color: var(--secondary-text-color);
} }
.card-actions {
text-align: right;
}
ha-entity-picker { ha-entity-picker {
flex: 1; flex: 1;
margin-left: 16px; margin-left: 16px;

View File

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

View File

@ -202,7 +202,7 @@ export class EntitySettingsHelperTab extends LitElement {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 16px; padding: 0 24px 24px 24px;
background-color: var(--mdc-theme-surface, #fff); background-color: var(--mdc-theme-surface, #fff);
} }
.error { .error {

View File

@ -249,9 +249,9 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
.buttons { .buttons {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
padding: 16px; padding: 8px;
justify-content: space-between; justify-content: space-between;
padding-bottom: max(var(--safe-area-inset-bottom), 16px); padding-bottom: max(var(--safe-area-inset-bottom), 8px);
background-color: var(--mdc-theme-surface, #fff); background-color: var(--mdc-theme-surface, #fff);
border-top: 1px solid var(--divider-color); border-top: 1px solid var(--divider-color);
position: sticky; position: sticky;

View File

@ -92,9 +92,8 @@ class DialogScheduleBlockInfo extends LitElement {
</div> </div>
<ha-button <ha-button
slot="secondaryAction" slot="secondaryAction"
class="warning"
@click=${this._deleteBlock} @click=${this._deleteBlock}
appearance="plain"
variant="danger"
> >
${this.hass!.localize("ui.common.delete")} ${this.hass!.localize("ui.common.delete")}
</ha-button> </ha-button>

View File

@ -145,7 +145,7 @@ class HaInputSelectForm extends LitElement {
)} )}
@keydown=${this._handleKeyAdd} @keydown=${this._handleKeyAdd}
></ha-textfield> ></ha-textfield>
<ha-button size="small" appearance="plain" @click=${this._addOption} <ha-button @click=${this._addOption}
>${this.hass!.localize( >${this.hass!.localize(
"ui.dialogs.helper_settings.input_select.add" "ui.dialogs.helper_settings.input_select.add"
)}</ha-button )}</ha-button

View File

@ -207,7 +207,7 @@ class HaConfigEntryRow extends LitElement {
: nothing} : nothing}
</div> </div>
${item.disabled_by === "user" ${item.disabled_by === "user"
? html`<ha-button slot="end" @click=${this._handleEnable}> ? html`<ha-button unelevated slot="end" @click=${this._handleEnable}>
${this.hass.localize("ui.common.enable")} ${this.hass.localize("ui.common.enable")}
</ha-button>` </ha-button>`
: configPanel && : configPanel &&

View File

@ -45,9 +45,10 @@ export class HaDisabledConfigEntryCard extends LitElement {
> >
<ha-icon-button .path=${mdiCog}></ha-icon-button> <ha-icon-button .path=${mdiCog}></ha-icon-button>
</a> </a>
<ha-button @click=${this._handleEnable} appearance="filled"> <ha-button
${this.hass.localize("ui.common.enable")} @click=${this._handleEnable}
</ha-button> .label=${this.hass.localize("ui.common.enable")}
></ha-button>
</ha-integration-action-card> </ha-integration-action-card>
`; `;
} }

View File

@ -34,11 +34,12 @@ export class HaIgnoredConfigEntryCard extends LitElement {
this.entry.localized_domain_name this.entry.localized_domain_name
: this.entry.title} : this.entry.title}
> >
<ha-button appearance="plain" @click=${this._removeIgnoredIntegration}> <ha-button
${this.hass.localize( @click=${this._removeIgnoredIntegration}
.label=${this.hass.localize(
"ui.panel.config.integrations.ignore.stop_ignore" "ui.panel.config.integrations.ignore.stop_ignore"
)} )}
</ha-button> ></ha-button>
</ha-integration-action-card> </ha-integration-action-card>
`; `;
} }

View File

@ -112,8 +112,7 @@ export class HaIntegrationCard extends LitElement {
return html` return html`
<div class="card-actions"> <div class="card-actions">
${devices.length > 0 ${devices.length > 0
? html`<ha-button ? html`<a
appearance="plain"
href=${devices.length === 1 && href=${devices.length === 1 &&
// Always link to device page for protocol integrations to show Add Device button // Always link to device page for protocol integrations to show Add Device button
// @ts-expect-error // @ts-expect-error
@ -121,28 +120,31 @@ export class HaIntegrationCard extends LitElement {
? `/config/devices/device/${devices[0].id}` ? `/config/devices/device/${devices[0].id}`
: `/config/devices/dashboard?historyBack=1&domain=${this.domain}`} : `/config/devices/dashboard?historyBack=1&domain=${this.domain}`}
> >
<ha-button appearance="plain">
${this.hass.localize( ${this.hass.localize(
`ui.panel.config.integrations.config_entry.${ `ui.panel.config.integrations.config_entry.${
services ? "services" : "devices" services ? "services" : "devices"
}`, }`,
{ count: devices.length } { count: devices.length }
)} )}
</ha-button>` </ha-button>
</a>`
: entitiesCount > 0 : entitiesCount > 0
? html`<ha-button ? html`<a
appearance="plain"
href=${`/config/entities?historyBack=1&domain=${this.domain}`} href=${`/config/entities?historyBack=1&domain=${this.domain}`}
> >
<ha-button appearance="plain">
${this.hass.localize( ${this.hass.localize(
`ui.panel.config.integrations.config_entry.entities`, `ui.panel.config.integrations.config_entry.entities`,
{ count: entitiesCount } { count: entitiesCount }
)} )}
</ha-button>` </ha-button>
</a>`
: this.items.find((itm) => itm.source !== "yaml") : this.items.find((itm) => itm.source !== "yaml")
? html`<ha-button ? html`<a
appearance="plain"
href=${`/config/integrations/integration/${this.domain}`} href=${`/config/integrations/integration/${this.domain}`}
> >
<ha-button appearance="plain">
${this.hass.localize( ${this.hass.localize(
`ui.panel.config.integrations.config_entry.entries`, `ui.panel.config.integrations.config_entry.entries`,
{ {
@ -150,7 +152,8 @@ export class HaIntegrationCard extends LitElement {
.length, .length,
} }
)} )}
</ha-button>` </ha-button>
</a>`
: html`<div class="spacer"></div>`} : html`<div class="spacer"></div>`}
<div class="icons"> <div class="icons">
${this.manifest && !this.manifest.is_built_in ${this.manifest && !this.manifest.is_built_in

View File

@ -26,6 +26,7 @@ import {
} from "../../../../../data/bluetooth"; } from "../../../../../data/bluetooth";
import type { DeviceRegistryEntry } from "../../../../../data/device_registry"; import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
import "../../../../../layouts/hass-subpage"; import "../../../../../layouts/hass-subpage";
import { colorVariables } from "../../../../../resources/theme/color/color.globals";
import type { HomeAssistant, Route } from "../../../../../types"; import type { HomeAssistant, Route } from "../../../../../types";
import { bluetoothAdvertisementMonitorTabs } from "./bluetooth-advertisement-monitor"; import { bluetoothAdvertisementMonitorTabs } from "./bluetooth-advertisement-monitor";
@ -130,34 +131,33 @@ export class BluetoothNetworkVisualization extends LitElement {
data: BluetoothDeviceData[], data: BluetoothDeviceData[],
scanners: BluetoothScannersDetails scanners: BluetoothScannersDetails
): NetworkData => { ): NetworkData => {
const style = getComputedStyle(this);
const categories = [ const categories = [
{ {
name: CORE_SOURCE_LABEL, name: CORE_SOURCE_LABEL,
symbol: "roundRect", symbol: "roundRect",
itemStyle: { itemStyle: {
color: style.getPropertyValue("--primary-color"), color: colorVariables["primary-color"],
}, },
}, },
{ {
name: this.hass.localize("ui.panel.config.bluetooth.scanners"), name: this.hass.localize("ui.panel.config.bluetooth.scanners"),
symbol: "circle", symbol: "circle",
itemStyle: { itemStyle: {
color: style.getPropertyValue("--cyan-color"), color: colorVariables["cyan-color"],
}, },
}, },
{ {
name: this.hass.localize("ui.panel.config.bluetooth.known_devices"), name: this.hass.localize("ui.panel.config.bluetooth.known_devices"),
symbol: "circle", symbol: "circle",
itemStyle: { itemStyle: {
color: style.getPropertyValue("--teal-color"), color: colorVariables["teal-color"],
}, },
}, },
{ {
name: this.hass.localize("ui.panel.config.bluetooth.unknown_devices"), name: this.hass.localize("ui.panel.config.bluetooth.unknown_devices"),
symbol: "circle", symbol: "circle",
itemStyle: { itemStyle: {
color: style.getPropertyValue("--disabled-color"), color: colorVariables["disabled-color"],
}, },
}, },
]; ];
@ -192,7 +192,7 @@ export class BluetoothNetworkVisualization extends LitElement {
symbol: "none", symbol: "none",
lineStyle: { lineStyle: {
width: 3, width: 3,
color: style.getPropertyValue("--primary-color"), color: colorVariables["primary-color"],
}, },
}); });
}); });
@ -206,7 +206,7 @@ export class BluetoothNetworkVisualization extends LitElement {
symbol: "none", symbol: "none",
lineStyle: { lineStyle: {
width: this._getLineWidth(node.rssi), width: this._getLineWidth(node.rssi),
color: style.getPropertyValue("--primary-color"), color: colorVariables["primary-color"],
}, },
}); });
return; return;
@ -227,8 +227,8 @@ export class BluetoothNetworkVisualization extends LitElement {
lineStyle: { lineStyle: {
width: this._getLineWidth(node.rssi), width: this._getLineWidth(node.rssi),
color: device color: device
? style.getPropertyValue("--primary-color") ? colorVariables["primary-color"]
: style.getPropertyValue("--disabled-color"), : colorVariables["disabled-color"],
}, },
}); });
}); });

View File

@ -114,11 +114,7 @@ class DialogSSDPDiscoveryInfo extends LitElement implements HassDialog {
</tbody> </tbody>
</table> </table>
<ha-button <ha-button slot="secondaryAction" @click=${this._copyToClipboard}>
appearance="plain"
slot="secondaryAction"
@click=${this._copyToClipboard}
>
${this.hass.localize("ui.panel.config.ssdp.copy_to_clipboard")} ${this.hass.localize("ui.panel.config.ssdp.copy_to_clipboard")}
</ha-button> </ha-button>
</ha-dialog> </ha-dialog>

View File

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

View File

@ -160,11 +160,7 @@ class DialogZHAReconfigureDevice extends LitElement {
<ha-button slot="primaryAction" @click=${this.closeDialog}> <ha-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.common.close")} ${this.hass.localize("ui.common.close")}
</ha-button> </ha-button>
<ha-button <ha-button slot="secondaryAction" @click=${this._toggleDetails}>
appearance="plain"
slot="secondaryAction"
@click=${this._toggleDetails}
>
${this._showDetails ${this._showDetails
? this.hass.localize( ? this.hass.localize(
`ui.dialogs.zha_reconfigure_device.button_hide` `ui.dialogs.zha_reconfigure_device.button_hide`
@ -193,11 +189,7 @@ class DialogZHAReconfigureDevice extends LitElement {
<ha-button slot="primaryAction" @click=${this.closeDialog}> <ha-button slot="primaryAction" @click=${this.closeDialog}>
${this.hass.localize("ui.common.close")} ${this.hass.localize("ui.common.close")}
</ha-button> </ha-button>
<ha-button <ha-button slot="secondaryAction" @click=${this._toggleDetails}>
appearance="plain"
slot="secondaryAction"
@click=${this._toggleDetails}
>
${this._showDetails ${this._showDetails
? this.hass.localize( ? this.hass.localize(
`ui.dialogs.zha_reconfigure_device.button_hide` `ui.dialogs.zha_reconfigure_device.button_hide`

View File

@ -176,7 +176,7 @@ export class ZHAAddGroupPage extends LitElement {
} }
.buttons { .buttons {
align-items: flex-end; align-items: flex-end;
padding: 16px; padding: 8px;
} }
.buttons .warning { .buttons .warning {
--mdc-theme-primary: var(--error-color); --mdc-theme-primary: var(--error-color);

View File

@ -305,7 +305,7 @@ export class ZHAGroupPage extends LitElement {
} }
.buttons { .buttons {
align-items: flex-end; align-items: flex-end;
padding: 16px; padding: 8px;
} }
.buttons .warning { .buttons .warning {
--mdc-theme-primary: var(--error-color); --mdc-theme-primary: var(--error-color);

View File

@ -16,6 +16,7 @@ import type {
import type { ZHADevice } from "../../../../../data/zha"; import type { ZHADevice } from "../../../../../data/zha";
import { fetchDevices, refreshTopology } from "../../../../../data/zha"; import { fetchDevices, refreshTopology } from "../../../../../data/zha";
import "../../../../../layouts/hass-tabs-subpage"; import "../../../../../layouts/hass-tabs-subpage";
import { colorVariables } from "../../../../../resources/theme/color/color.globals";
import type { HomeAssistant, Route } from "../../../../../types"; import type { HomeAssistant, Route } from "../../../../../types";
import { formatAsPaddedHex } from "./functions"; import { formatAsPaddedHex } from "./functions";
import { zhaTabs } from "./zha-config-dashboard"; import { zhaTabs } from "./zha-config-dashboard";
@ -155,12 +156,10 @@ export class ZHANetworkVisualizationPage extends LitElement {
} }
private _createChartData(devices: ZHADevice[]): NetworkData { private _createChartData(devices: ZHADevice[]): NetworkData {
const style = getComputedStyle(this); const primaryColor = colorVariables["primary-color"];
const routerColor = colorVariables["cyan-color"];
const primaryColor = style.getPropertyValue("--primary-color"); const endDeviceColor = colorVariables["teal-color"];
const routerColor = style.getPropertyValue("--cyan-color"); const offlineColor = colorVariables["error-color"];
const endDeviceColor = style.getPropertyValue("--teal-color");
const offlineColor = style.getPropertyValue("--error-color");
const nodes: NetworkNode[] = []; const nodes: NetworkNode[] = [];
const links: NetworkLink[] = []; const links: NetworkLink[] = [];
const categories = [ const categories = [
@ -283,7 +282,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
color: color:
route.route_status === "Active" route.route_status === "Active"
? primaryColor ? primaryColor
: style.getPropertyValue("--disabled-color"), : colorVariables["disabled-color"],
type: ["Child", "Parent"].includes(neighbor.relationship) type: ["Child", "Parent"].includes(neighbor.relationship)
? "solid" ? "solid"
: "dotted", : "dotted",
@ -323,7 +322,7 @@ export class ZHANetworkVisualizationPage extends LitElement {
symbolSize: 5, symbolSize: 5,
lineStyle: { lineStyle: {
width: 1, width: 1,
color: style.getPropertyValue("--disabled-color"), color: colorVariables["disabled-color"],
type: "dotted", type: "dotted",
}, },
ignoreForceLayout: true, ignoreForceLayout: true,

View File

@ -33,11 +33,13 @@ export class ZWaveJsAddNodeFailed extends LitElement {
</div>` </div>`
: nothing} : nothing}
${this.device?.id ${this.device?.id
? html`<ha-button href=${`/config/devices/device/${this.device.id}`}> ? html`<a href=${`/config/devices/device/${this.device.id}`}>
<ha-button>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.zwave_js.add_node.view_device" "ui.panel.config.zwave_js.add_node.view_device"
)} )}
</ha-button>` </ha-button>
</a>`
: nothing} : nothing}
`; `;
} }

View File

@ -219,11 +219,7 @@ class DialogZWaveJSRemoveNode extends LitElement {
if (this._step === "start_removal") { if (this._step === "start_removal") {
return html` return html`
<ha-button <ha-button slot="secondaryAction" @click=${this.closeDialog}>
appearance="plain"
slot="secondaryAction"
@click=${this.closeDialog}
>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button <ha-button
@ -238,11 +234,7 @@ class DialogZWaveJSRemoveNode extends LitElement {
if (this._step === "start_exclusion") { if (this._step === "start_exclusion") {
return html` return html`
<ha-button <ha-button slot="secondaryAction" @click=${this.closeDialog}>
appearance="plain"
slot="secondaryAction"
@click=${this.closeDialog}
>
${this.hass.localize("ui.common.cancel")} ${this.hass.localize("ui.common.cancel")}
</ha-button> </ha-button>
<ha-button <ha-button

View File

@ -157,7 +157,6 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
.path=${mdiRefresh} .path=${mdiRefresh}
.label=${this.hass!.localize("ui.common.refresh")} .label=${this.hass!.localize("ui.common.refresh")}
></ha-icon-button> ></ha-icon-button>
<div class="container">
${this._network ${this._network
? html` ? html`
<ha-card class="content network-status"> <ha-card class="content network-status">
@ -230,20 +229,6 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
)} )}
</ha-button>` </ha-button>`
: nothing} : nothing}
<ha-button
class="remove-node-button"
@click=${this._removeNodeClicked}
appearance="filled"
.disabled=${this._status !== "connected" ||
(this._network?.controller.inclusion_state !==
InclusionState.Idle &&
this._network?.controller.inclusion_state !==
InclusionState.SmartStart)}
>
${this.hass.localize(
"ui.panel.config.zwave_js.common.remove_a_node"
)}
</ha-button>
</div> </div>
</ha-card> </ha-card>
<ha-card header="Diagnostics"> <ha-card header="Diagnostics">
@ -422,6 +407,19 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
</ha-expansion-panel> </ha-expansion-panel>
</div> </div>
<div class="card-actions"> <div class="card-actions">
<ha-button
appearance="plain"
@click=${this._removeNodeClicked}
.disabled=${this._status !== "connected" ||
(this._network?.controller.inclusion_state !==
InclusionState.Idle &&
this._network?.controller.inclusion_state !==
InclusionState.SmartStart)}
>
${this.hass.localize(
"ui.panel.config.zwave_js.common.remove_a_node"
)}
</ha-button>
<ha-button <ha-button
appearance="plain" appearance="plain"
@click=${this._rebuildNetworkRoutesClicked} @click=${this._rebuildNetworkRoutesClicked}
@ -435,11 +433,7 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
</ha-card> </ha-card>
<ha-card> <ha-card>
<div class="card-header"> <div class="card-header">
<h1> <h1>Third-party data reporting</h1>
${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.data_collection.title"
)}
</h1>
${this._dataCollectionOptIn !== undefined ${this._dataCollectionOptIn !== undefined
? html` ? html`
<ha-switch <ha-switch
@ -451,18 +445,17 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
</div> </div>
<div class="card-content"> <div class="card-content">
<p> <p>
${this.hass.localize( Enable the reporting of anonymized telemetry and statistics
"ui.panel.config.zwave_js.dashboard.data_collection.description", to the <em>Z-Wave JS organization</em>. This data will be
{ used to focus development efforts and improve the user
documentation_link: html`<a 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" target="_blank"
href="https://zwave-js.github.io/node-zwave-js/#/data-collection/data-collection" href="https://zwave-js.github.io/node-zwave-js/#/data-collection/data-collection"
>${this.hass.localize( >Z-Wave JS data collection documentation</a
"ui.panel.config.zwave_js.dashboard.data_collection.documentation_link" >.
)}</a
>`,
}
)}
</p> </p>
</div> </div>
</ha-card> </ha-card>
@ -505,11 +498,11 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
"ui.panel.config.zwave_js.dashboard.nvm_backup.download_backup" "ui.panel.config.zwave_js.dashboard.nvm_backup.download_backup"
)} )}
</ha-button> </ha-button>
<div class="right-buttons">
<div class="upload-button"> <div class="upload-button">
<ha-button <ha-button
appearance="filled" appearance="plain"
@click=${this._restoreButtonClick} @click=${this._restoreButtonClick}
variant="danger"
> >
<span class="button-content"> <span class="button-content">
${this.hass.localize( ${this.hass.localize(
@ -526,19 +519,18 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
/> />
</div> </div>
<ha-button <ha-button
appearance="filled" variant="danger"
@click=${this._openConfigFlow} @click=${this._openConfigFlow}
class="migrate-button"
> >
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.zwave_js.dashboard.nvm_backup.migrate" "ui.panel.config.zwave_js.dashboard.nvm_backup.migrate"
)} )}
</ha-button> </ha-button>`}
</div>`}
</div> </div>
</ha-card> </ha-card>
` `
: nothing} : nothing}
</div>
<ha-fab <ha-fab
slot="fab" slot="fab"
.label=${this.hass.localize( .label=${this.hass.localize(
@ -965,7 +957,6 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
.card-actions { .card-actions {
display: flex; display: flex;
align-items: center; align-items: center;
flex-wrap: wrap;
} }
.card-actions ha-progress-ring { .card-actions ha-progress-ring {
@ -990,19 +981,9 @@ class ZWaveJSConfigDashboard extends SubscribeMixin(LitElement) {
pointer-events: none; pointer-events: none;
} }
.remove-node-button { .migrate-button {
margin-left: auto; margin-left: auto;
} }
.right-buttons {
display: flex;
gap: 8px;
margin-left: auto;
}
.container {
padding: 8px 16px 16px;
}
`, `,
]; ];
} }

View File

@ -92,12 +92,12 @@ class ZWaveJSCustomParam extends LitElement {
</div> </div>
<div class="custom-config-buttons"> <div class="custom-config-buttons">
${this._isLoading ? html`<ha-spinner></ha-spinner>` : nothing} ${this._isLoading ? html`<ha-spinner></ha-spinner>` : nothing}
<ha-button appearance="plain" @click=${this._getCustomConfigValue}> <ha-button @click=${this._getCustomConfigValue}>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.zwave_js.node_config.get_value" "ui.panel.config.zwave_js.node_config.get_value"
)} )}
</ha-button> </ha-button>
<ha-button appearance="plain" @click=${this._setCustomConfigValue}> <ha-button @click=${this._setCustomConfigValue}>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.zwave_js.node_config.set_value" "ui.panel.config.zwave_js.node_config.set_value"
)} )}

View File

@ -162,7 +162,6 @@ class ZWaveJSLogs extends SubscribeMixin(LitElement) {
textarea { textarea {
flex-grow: 1; flex-grow: 1;
padding: 16px; padding: 16px;
font-family: var(--ha-font-family-code);
} }
ha-card { ha-card {
margin: 16px 0; margin: 16px 0;

Some files were not shown because too many files have changed in this diff Show More