mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-30 04:36:36 +00:00
Fix ha-progress-button
This commit is contained in:
parent
39171c95d9
commit
7ce88da20e
32
gallery/src/pages/components/ha-progress-button.markdown
Normal file
32
gallery/src/pages/components/ha-progress-button.markdown
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Progress Button
|
||||
---
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
}
|
||||
</style>
|
||||
|
||||
# Progress Button `<ha-progress-button>`
|
||||
|
||||
### API
|
||||
|
||||
This component is a wrapper around `<ha-button>` that adds support for showing progress
|
||||
|
||||
**Slots**
|
||||
|
||||
- default slot: Label of the button
|
||||
` - no default
|
||||
|
||||
**Properties/Attributes**
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| ---------- | ---------------------------------------------- | --------- | -------------------------------------------------- |
|
||||
| label | string | "accent" | Sets the button label. |
|
||||
| disabled | Boolean | false | Disables the button if true. |
|
||||
| progress | Boolean | false | Shows a progress indicator on the button. |
|
||||
| appearance | "accent"/"filled"/"plain" | "accent" | Sets the button appearance. |
|
||||
| variants | "brand"/"danger"/"neutral"/"warning"/"success" | "brand" | Sets the button color variant. "brand" is default. |
|
||||
| iconPath | string | undefined | Sets the icon path for the button. |
|
139
gallery/src/pages/components/ha-progress-button.ts
Normal file
139
gallery/src/pages/components/ha-progress-button.ts
Normal file
@ -0,0 +1,139 @@
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement } from "lit/decorators";
|
||||
import { applyThemesOnElement } from "../../../../src/common/dom/apply_themes_on_element";
|
||||
import "../../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../../src/components/ha-card";
|
||||
import "../../../../src/components/ha-svg-icon";
|
||||
import { mdiHomeAssistant } from "../../../../src/resources/home-assistant-logo-svg";
|
||||
|
||||
@customElement("demo-components-ha-progress-button")
|
||||
export class DemoHaProgressButton extends LitElement {
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
${["light", "dark"].map(
|
||||
(mode) => html`
|
||||
<div class=${mode}>
|
||||
<ha-card header="ha-progress-button in ${mode}">
|
||||
<div class="card-content">
|
||||
<ha-progress-button @click=${this._clickedSuccess}>
|
||||
Success
|
||||
</ha-progress-button>
|
||||
<ha-progress-button @click=${this._clickedFail}>
|
||||
Fail
|
||||
</ha-progress-button>
|
||||
<ha-progress-button size="small" @click=${this._clickedSuccess}>
|
||||
small
|
||||
</ha-progress-button>
|
||||
<ha-progress-button
|
||||
appearance="filled"
|
||||
@click=${this._clickedSuccess}
|
||||
>
|
||||
filled
|
||||
</ha-progress-button>
|
||||
<ha-progress-button
|
||||
appearance="plain"
|
||||
@click=${this._clickedSuccess}
|
||||
>
|
||||
plain
|
||||
</ha-progress-button>
|
||||
<ha-progress-button
|
||||
variant="warning"
|
||||
@click=${this._clickedSuccess}
|
||||
>
|
||||
warning
|
||||
</ha-progress-button>
|
||||
<ha-progress-button
|
||||
variant="neutral"
|
||||
@click=${this._clickedSuccess}
|
||||
label="with icon"
|
||||
.iconPath=${mdiHomeAssistant}
|
||||
>
|
||||
With Icon
|
||||
</ha-progress-button>
|
||||
<ha-progress-button progress @click=${this._clickedSuccess}>
|
||||
progress
|
||||
</ha-progress-button>
|
||||
<ha-progress-button disabled @click=${this._clickedSuccess}>
|
||||
disabled
|
||||
</ha-progress-button>
|
||||
</div>
|
||||
</ha-card>
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
applyThemesOnElement(
|
||||
this.shadowRoot!.querySelector(".dark"),
|
||||
{
|
||||
default_theme: "default",
|
||||
default_dark_theme: "default",
|
||||
themes: {},
|
||||
darkMode: true,
|
||||
theme: "default",
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private async _clickedSuccess(ev: CustomEvent): Promise<void> {
|
||||
console.log("Clicked success");
|
||||
const button = ev.currentTarget as any;
|
||||
button.progress = true;
|
||||
|
||||
setTimeout(() => {
|
||||
button.actionSuccess();
|
||||
button.progress = false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private async _clickedFail(ev: CustomEvent): Promise<void> {
|
||||
const button = ev.currentTarget as any;
|
||||
button.progress = true;
|
||||
|
||||
setTimeout(() => {
|
||||
button.actionError();
|
||||
button.progress = false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.dark,
|
||||
.light {
|
||||
display: block;
|
||||
background-color: var(--primary-background-color);
|
||||
padding: 0 50px;
|
||||
}
|
||||
.button {
|
||||
padding: unset;
|
||||
}
|
||||
ha-card {
|
||||
margin: 24px auto;
|
||||
}
|
||||
.card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
.card-content div {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"demo-components-ha-progress-button": DemoHaProgressButton;
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ import { css, html, LitElement } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { atLeastVersion } from "../../../src/common/config/version";
|
||||
import "../../../src/components/buttons/ha-progress-button";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-button";
|
||||
import "../../../src/components/ha-button-menu";
|
||||
import "../../../src/components/ha-card";
|
||||
import "../../../src/components/ha-settings-row";
|
||||
import type { HassioStats } from "../../../src/data/hassio/common";
|
||||
@ -94,7 +94,7 @@ class HassioCoreInfo extends LitElement {
|
||||
<div class="card-actions">
|
||||
<ha-progress-button
|
||||
slot="primaryAction"
|
||||
class="warning"
|
||||
variant="danger"
|
||||
@click=${this._coreRestart}
|
||||
.title=${this.supervisor.localize("common.restart_name", {
|
||||
name: "Core",
|
||||
@ -187,11 +187,6 @@ class HassioCoreInfo extends LitElement {
|
||||
white-space: normal;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.warning {
|
||||
--mdc-theme-primary: var(--error-color);
|
||||
}
|
||||
|
||||
ha-button-menu {
|
||||
color: var(--secondary-text-color);
|
||||
--mdc-menu-min-width: 200px;
|
||||
|
@ -171,7 +171,7 @@ class HassioHostInfo extends LitElement {
|
||||
<div class="card-actions">
|
||||
${this.supervisor.host.features.includes("reboot")
|
||||
? html`
|
||||
<ha-progress-button class="warning" @click=${this._hostReboot}>
|
||||
<ha-progress-button variant="danger" @click=${this._hostReboot}>
|
||||
${this.supervisor.localize("system.host.reboot_host")}
|
||||
</ha-progress-button>
|
||||
`
|
||||
@ -179,7 +179,7 @@ class HassioHostInfo extends LitElement {
|
||||
${this.supervisor.host.features.includes("shutdown")
|
||||
? html`
|
||||
<ha-progress-button
|
||||
class="warning"
|
||||
variant="danger"
|
||||
@click=${this._hostShutdown}
|
||||
>
|
||||
${this.supervisor.localize("system.host.shutdown_host")}
|
||||
@ -435,10 +435,6 @@ class HassioHostInfo extends LitElement {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.warning {
|
||||
--mdc-theme-primary: var(--error-color);
|
||||
}
|
||||
|
||||
ha-button-menu {
|
||||
color: var(--secondary-text-color);
|
||||
--mdc-menu-min-width: 200px;
|
||||
|
@ -2,16 +2,11 @@ import { mdiAlertOctagram, mdiCheckBold } from "@mdi/js";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import "../ha-button";
|
||||
import type { Appearance } from "../ha-button";
|
||||
import "../ha-spinner";
|
||||
import "../ha-svg-icon";
|
||||
import type { Appearance } from "../ha-button";
|
||||
|
||||
const HIGHLIGHT_APPEARANCE = {
|
||||
accent: "accent" as Appearance,
|
||||
filled: "accent" as Appearance,
|
||||
plain: "filled" as Appearance,
|
||||
};
|
||||
|
||||
@customElement("ha-progress-button")
|
||||
export class HaProgressButton extends LitElement {
|
||||
@ -23,18 +18,16 @@ export class HaProgressButton extends LitElement {
|
||||
|
||||
@property() appearance: Appearance = "accent";
|
||||
|
||||
@property({ attribute: false }) public iconPath?: string;
|
||||
|
||||
@property() variant: "brand" | "danger" | "neutral" | "warning" | "success" =
|
||||
"brand";
|
||||
|
||||
@state() private _result?: "success" | "error";
|
||||
|
||||
@state() private _hasInitialIcon = false;
|
||||
|
||||
public render(): TemplateResult {
|
||||
const appearance =
|
||||
this.progress || this._result
|
||||
? HIGHLIGHT_APPEARANCE[this.appearance]
|
||||
: this.appearance;
|
||||
this.progress || this._result ? "accent" : this.appearance;
|
||||
|
||||
return html`
|
||||
<ha-button
|
||||
@ -46,20 +39,20 @@ export class HaProgressButton extends LitElement {
|
||||
: this._result === "error"
|
||||
? "danger"
|
||||
: this.variant}
|
||||
.hideContent=${this._result !== undefined}
|
||||
class=${classMap({
|
||||
result: !!this._result,
|
||||
success: this._result === "success",
|
||||
error: this._result === "error",
|
||||
})}
|
||||
>
|
||||
${this._hasInitialIcon
|
||||
? html`<slot name="icon" slot="start"></slot>`
|
||||
${this.iconPath
|
||||
? html`<ha-svg-icon
|
||||
.path=${this.iconPath}
|
||||
slot="start"
|
||||
></ha-svg-icon>`
|
||||
: nothing}
|
||||
<slot
|
||||
>${this._result
|
||||
? html`<ha-svg-icon
|
||||
.path=${this._result === "success"
|
||||
? mdiCheckBold
|
||||
: mdiAlertOctagram}
|
||||
></ha-svg-icon>`
|
||||
: this.label}</slot
|
||||
>
|
||||
|
||||
<slot>${this.label}</slot>
|
||||
</ha-button>
|
||||
${!this._result
|
||||
? nothing
|
||||
@ -75,14 +68,6 @@ export class HaProgressButton extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
const iconSlot = this.shadowRoot!.querySelector(
|
||||
'slot[name="icon"]'
|
||||
) as HTMLSlotElement;
|
||||
this._hasInitialIcon =
|
||||
iconSlot && iconSlot.assignedNodes({ flatten: true }).length > 0;
|
||||
}
|
||||
|
||||
public actionSuccess(): void {
|
||||
this._setResult("success");
|
||||
}
|
||||
@ -109,10 +94,6 @@ export class HaProgressButton extends LitElement {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
ha-button {
|
||||
transition: all 1s;
|
||||
}
|
||||
|
||||
.progress {
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
@ -123,14 +104,21 @@ export class HaProgressButton extends LitElement {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ha-svg-icon {
|
||||
color: white;
|
||||
ha-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ha-button.success slot,
|
||||
ha-button.error slot {
|
||||
ha-button.result::part(start),
|
||||
ha-button.result::part(end),
|
||||
ha-button.result::part(label),
|
||||
ha-button.result::part(caret),
|
||||
ha-button.result::part(spinner) {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
ha-svg-icon {
|
||||
color: var(--white);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Button from "@awesome.me/webawesome/dist/components/button/button";
|
||||
import { css, type CSSResultGroup } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { customElement } from "lit/decorators";
|
||||
|
||||
export type Appearance = "accent" | "filled" | "outlined" | "plain";
|
||||
|
||||
@ -36,9 +36,6 @@ export type Appearance = "accent" | "filled" | "outlined" | "plain";
|
||||
export class HaButton extends Button {
|
||||
variant: "brand" | "neutral" | "success" | "warning" | "danger" = "brand";
|
||||
|
||||
@property({ type: Boolean, attribute: "hide-content", reflect: true })
|
||||
hideContent = false;
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
Button.styles,
|
||||
@ -150,6 +147,10 @@ export class HaButton extends Button {
|
||||
background-color: var(--color-fill-disabled-loud-resting);
|
||||
color: var(--color-on-disabled-loud);
|
||||
}
|
||||
|
||||
:host([loading]) {
|
||||
pointer-events: none;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { storage } from "../../common/decorators/storage";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import "../../components/buttons/ha-progress-button";
|
||||
import { createCloseHeading } from "../../components/ha-dialog";
|
||||
import "../../components/ha-textarea";
|
||||
import type { HaTextArea } from "../../components/ha-textarea";
|
||||
@ -10,7 +11,6 @@ import { convertTextToSpeech } from "../../data/tts";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { showAlertDialog } from "../generic/show-dialog-box";
|
||||
import type { TTSTryDialogParams } from "./show-dialog-tts-try";
|
||||
import "../../components/buttons/ha-progress-button";
|
||||
|
||||
@customElement("dialog-tts-try")
|
||||
export class TTSTryDialog extends LitElement {
|
||||
@ -85,11 +85,11 @@ export class TTSTryDialog extends LitElement {
|
||||
.progress=${this._loadingExample}
|
||||
?dialogInitialFocus=${Boolean(this._defaultMessage)}
|
||||
slot="primaryAction"
|
||||
.label=${this.hass.localize("ui.dialogs.tts-try.play")}
|
||||
@click=${this._playExample}
|
||||
.disabled=${!this._valid}
|
||||
.iconPath=${mdiPlayCircleOutline}
|
||||
>
|
||||
<ha-svg-icon slot="icon" .path=${mdiPlayCircleOutline}></ha-svg-icon>
|
||||
${this.hass.localize("ui.dialogs.tts-try.play")}
|
||||
</ha-progress-button>
|
||||
</ha-dialog>
|
||||
`;
|
||||
|
@ -114,7 +114,6 @@ export class CloudLogin extends LitElement {
|
||||
)}
|
||||
</ha-button>
|
||||
<ha-progress-button
|
||||
unelevated
|
||||
@click=${this._handleLogin}
|
||||
.progress=${this._inProgress}
|
||||
>${this.localize(
|
||||
|
@ -8,7 +8,6 @@ import memoizeOne from "memoize-one";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { round } from "../../../common/number/round";
|
||||
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
|
||||
import "../../../components/buttons/ha-progress-button";
|
||||
import "../../../components/chart/ha-chart-base";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button";
|
||||
|
Loading…
x
Reference in New Issue
Block a user