Replace paper-toast with mwc-snackbar (#19579)

* toast

* Fixes

* Linting

* Remove empty styles

* PR feedback

Co-authored-by: Bram Kragten <mail@bramkragten.nl>

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Simon Lamon 2024-02-28 21:50:58 +01:00 committed by GitHub
parent 5287061699
commit 9ef07484dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 724 additions and 679 deletions

View File

@ -72,6 +72,7 @@
"@material/mwc-radio": "0.27.0", "@material/mwc-radio": "0.27.0",
"@material/mwc-ripple": "0.27.0", "@material/mwc-ripple": "0.27.0",
"@material/mwc-select": "0.27.0", "@material/mwc-select": "0.27.0",
"@material/mwc-snackbar": "0.27.0",
"@material/mwc-switch": "0.27.0", "@material/mwc-switch": "0.27.0",
"@material/mwc-tab": "0.27.0", "@material/mwc-tab": "0.27.0",
"@material/mwc-tab-bar": "0.27.0", "@material/mwc-tab-bar": "0.27.0",
@ -86,7 +87,6 @@
"@polymer/paper-item": "3.0.1", "@polymer/paper-item": "3.0.1",
"@polymer/paper-listbox": "3.0.1", "@polymer/paper-listbox": "3.0.1",
"@polymer/paper-tabs": "3.1.0", "@polymer/paper-tabs": "3.1.0",
"@polymer/paper-toast": "3.0.1",
"@polymer/polymer": "3.5.1", "@polymer/polymer": "3.5.1",
"@thomasloven/round-slider": "0.6.0", "@thomasloven/round-slider": "0.6.0",
"@vaadin/combo-box": "24.3.6", "@vaadin/combo-box": "24.3.6",

View File

@ -1,35 +1,8 @@
import "@polymer/paper-toast/paper-toast";
import type { PaperToastElement } from "@polymer/paper-toast/paper-toast";
import { customElement } from "lit/decorators"; import { customElement } from "lit/decorators";
import type { Constructor } from "../types"; import { Snackbar } from "@material/mwc-snackbar/mwc-snackbar";
const PaperToast = customElements.get(
"paper-toast"
) as Constructor<PaperToastElement>;
@customElement("ha-toast") @customElement("ha-toast")
export class HaToast extends PaperToast { export class HaToast extends Snackbar {}
private _resizeListener?: (obj: { matches: boolean }) => unknown;
private _mediaq?: MediaQueryList;
public connectedCallback() {
super.connectedCallback();
if (!this._resizeListener) {
this._resizeListener = (ev) =>
this.classList.toggle("fit-bottom", ev.matches);
this._mediaq = window.matchMedia("(max-width: 599px");
}
this._mediaq!.addListener(this._resizeListener);
this._resizeListener(this._mediaq!);
}
public disconnectedCallback() {
super.disconnectedCallback();
this._mediaq!.removeListener(this._resizeListener!);
}
}
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {

View File

@ -341,7 +341,7 @@ class DialogRestart extends LitElement {
showToast(this, { showToast(this, {
message: this.hass.localize("ui.dialogs.restart.reboot.rebooting"), message: this.hass.localize("ui.dialogs.restart.reboot.rebooting"),
duration: 0, duration: -1,
}); });
try { try {
@ -380,7 +380,7 @@ class DialogRestart extends LitElement {
showToast(this, { showToast(this, {
message: this.hass.localize("ui.dialogs.restart.shutdown.shutting_down"), message: this.hass.localize("ui.dialogs.restart.shutdown.shutting_down"),
duration: 0, duration: -1,
}); });
try { try {

View File

@ -1,10 +1,11 @@
import "@material/mwc-button"; import { html, LitElement, nothing } from "lit";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { property, state, query } from "lit/decorators"; import { property, state, query } from "lit/decorators";
import { mdiClose } from "@mdi/js";
import { computeRTL } from "../common/util/compute_rtl"; import { computeRTL } from "../common/util/compute_rtl";
import "../components/ha-toast"; import "../components/ha-toast";
import type { HaToast } from "../components/ha-toast"; import type { HaToast } from "../components/ha-toast";
import type { HomeAssistant } from "../types"; import type { HomeAssistant } from "../types";
import "../components/ha-button";
export interface ShowToastParams { export interface ShowToastParams {
message: string; message: string;
@ -21,72 +22,78 @@ export interface ToastActionParams {
class NotificationManager extends LitElement { class NotificationManager extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@state() private _action?: ToastActionParams; @state() private _parameters?: ShowToastParams;
@state() private _noCancelOnOutsideClick = false; @query("ha-toast") private _toast!: HaToast | undefined;
@query("ha-toast") private _toast!: HaToast; public async showDialog(parameters: ShowToastParams) {
if (this._parameters) {
public async showDialog({ this._parameters = undefined;
message,
action,
duration,
dismissable,
}: ShowToastParams) {
let toast = this._toast;
// Can happen on initial load
if (!toast) {
await this.updateComplete; await this.updateComplete;
toast = this._toast;
} }
toast.setAttribute("dir", computeRTL(this.hass) ? "rtl" : "ltr");
this._action = action || undefined; if (!parameters || parameters.duration === 0) {
this._noCancelOnOutsideClick = return;
dismissable === undefined ? false : !dismissable; }
toast.hide();
toast.show({ this._parameters = parameters;
text: message,
duration: duration === undefined ? 3000 : duration, if (
}); this._parameters.duration === undefined ||
(this._parameters.duration > 0 && this._parameters.duration <= 4000)
) {
this._parameters.duration = 4000;
}
} }
protected render(): TemplateResult { public shouldUpdate(changedProperties) {
return !this._toast || changedProperties.has("_parameters");
}
private _toastClosed() {
this._parameters = undefined;
}
protected render() {
if (!this._parameters) {
return nothing;
}
return html` return html`
<ha-toast .noCancelOnOutsideClick=${this._noCancelOnOutsideClick}> <ha-toast
${this._action leading
open
dir=${computeRTL(this.hass) ? "rtl" : "ltr"}
.labelText=${this._parameters.message}
.timeoutMs=${this._parameters.duration!}
@MDCSnackbar:closed=${this._toastClosed}
>
${this._parameters?.action
? html` ? html`
<mwc-button <ha-button
.label=${this._action.text} slot="action"
.label=${this._parameters?.action.text}
@click=${this.buttonClicked} @click=${this.buttonClicked}
></mwc-button> ></ha-button>
` `
: ""} : nothing}
${this._parameters?.dismissable
? html`<ha-icon-button
.label=${this.hass.localize("ui.common.close")}
.path=${mdiClose}
dialogAction="close"
slot="dismiss"
></ha-icon-button>`
: nothing}
</ha-toast> </ha-toast>
`; `;
} }
private buttonClicked() { private buttonClicked() {
this._toast.hide(); this._toast?.close("action");
if (this._action) { if (this._parameters?.action) {
this._action.action(); this._parameters?.action.action();
} }
} }
static get styles(): CSSResultGroup {
return css`
ha-toast {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
}
mwc-button {
color: var(--primary-color);
font-weight: bold;
margin-left: 8px;
}
`;
}
} }
customElements.define("notification-manager", NotificationManager); customElements.define("notification-manager", NotificationManager);

View File

@ -811,7 +811,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
"ui.panel.config.script.editor.id_already_exists_save_error" "ui.panel.config.script.editor.id_already_exists_save_error"
), ),
dismissable: false, dismissable: false,
duration: 0, duration: -1,
action: { action: {
action: () => {}, action: () => {},
text: this.hass.localize("ui.dialogs.generic.ok"), text: this.hass.localize("ui.dialogs.generic.ok"),

View File

@ -221,7 +221,7 @@ export class LovelacePanel extends LitElement {
action: () => this._fetchConfig(false), action: () => this._fetchConfig(false),
text: this.hass!.localize("ui.common.refresh"), text: this.hass!.localize("ui.common.refresh"),
}, },
duration: 0, duration: -1,
dismissable: false, dismissable: false,
}); });
} }

View File

@ -132,7 +132,7 @@ class LovelaceFullConfigEditor extends LitElement {
"ui.panel.lovelace.editor.raw_editor.reload" "ui.panel.lovelace.editor.raw_editor.reload"
), ),
}, },
duration: 0, duration: -1,
dismissable: false, dismissable: false,
}); });
} }

View File

@ -38,7 +38,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
message: message:
this.hass!.localize("ui.notification_toast.starting") || this.hass!.localize("ui.notification_toast.starting") ||
"Home Assistant is starting, not everything will be available until it is finished.", "Home Assistant is starting, not everything will be available until it is finished.",
duration: 0, duration: -1,
dismissable: false, dismissable: false,
action: { action: {
text: text:
@ -97,7 +97,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
} }
showToast(this, { showToast(this, {
message: "", message: "",
duration: 1, duration: 0,
}); });
} }
@ -108,7 +108,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
this._disconnectedTimeout = undefined; this._disconnectedTimeout = undefined;
showToast(this, { showToast(this, {
message: this.hass!.localize("ui.notification_toast.connection_lost"), message: this.hass!.localize("ui.notification_toast.connection_lost"),
duration: 0, duration: -1,
dismissable: false, dismissable: false,
}); });
}, 1000); }, 1000);
@ -124,7 +124,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
message: message:
this.hass!.localize("ui.notification_toast.wrapping_up_startup") || this.hass!.localize("ui.notification_toast.wrapping_up_startup") ||
`Wrapping up startup, not everything will be available until it is finished.`, `Wrapping up startup, not everything will be available until it is finished.`,
duration: 0, duration: -1,
dismissable: false, dismissable: false,
action: { action: {
text: text:
@ -148,7 +148,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
integration: domainToName(this.hass!.localize, integration), integration: domainToName(this.hass!.localize, integration),
}) || }) ||
`Starting ${integration}, not everything will be available until it is finished.`, `Starting ${integration}, not everything will be available until it is finished.`,
duration: 0, duration: -1,
dismissable: false, dismissable: false,
action: { action: {
text: text:

View File

@ -48,7 +48,7 @@ export const registerServiceWorker = async (
action: () => installingWorker.postMessage({ type: "skipWaiting" }), action: () => installingWorker.postMessage({ type: "skipWaiting" }),
text: "reload", text: "reload",
}, },
duration: 0, duration: -1,
dismissable: false, dismissable: false,
}); });
}); });

1239
yarn.lock

File diff suppressed because it is too large Load Diff