ha-frontend/src/components/ha-alert.ts

166 lines
3.7 KiB
TypeScript

import {
mdiAlertCircleOutline,
mdiAlertOutline,
mdiCheckboxMarkedCircleOutline,
mdiClose,
mdiInformationOutline,
} from "@mdi/js";
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { fireEvent } from "../common/dom/fire_event";
import "./ha-icon-button";
import "./ha-svg-icon";
const ALERT_ICONS = {
info: mdiInformationOutline,
warning: mdiAlertOutline,
error: mdiAlertCircleOutline,
success: mdiCheckboxMarkedCircleOutline,
};
declare global {
interface HASSDomEvents {
"alert-dismissed-clicked": undefined;
}
}
@customElement("ha-alert")
class HaAlert extends LitElement {
@property() public title = "";
@property({ attribute: "alert-type" }) public alertType:
| "info"
| "warning"
| "error"
| "success" = "info";
@property({ type: Boolean }) public dismissable = false;
public render() {
return html`
<div
class="issue-type ${classMap({
[this.alertType]: true,
})}"
role="alert"
>
<div class="icon ${this.title ? "" : "no-title"}">
<slot name="icon">
<ha-svg-icon .path=${ALERT_ICONS[this.alertType]}></ha-svg-icon>
</slot>
</div>
<div class="content">
<div class="main-content">
${this.title ? html`<div class="title">${this.title}</div>` : ""}
<slot></slot>
</div>
<div class="action">
<slot name="action">
${this.dismissable
? html`<ha-icon-button
@click=${this._dismiss_clicked}
label="Dismiss alert"
.path=${mdiClose}
></ha-icon-button>`
: ""}
</slot>
</div>
</div>
</div>
`;
}
private _dismiss_clicked() {
fireEvent(this, "alert-dismissed-clicked");
}
static styles = css`
.issue-type {
position: relative;
padding: 8px;
display: flex;
}
.issue-type::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0.12;
pointer-events: none;
content: "";
border-radius: 4px;
}
.icon {
z-index: 1;
}
.icon.no-title {
align-self: center;
}
.content {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
text-align: var(--float-start);
}
.action {
z-index: 1;
width: min-content;
--mdc-theme-primary: var(--primary-text-color);
}
.main-content {
overflow-wrap: anywhere;
word-break: break-word;
margin-left: 8px;
margin-right: 0;
margin-inline-start: 8px;
margin-inline-end: 0;
direction: var(--direction);
}
.title {
margin-top: 2px;
font-weight: bold;
}
.action mwc-button,
.action ha-icon-button {
--mdc-theme-primary: var(--primary-text-color);
--mdc-icon-button-size: 36px;
}
.issue-type.info > .icon {
color: var(--info-color);
}
.issue-type.info::after {
background-color: var(--info-color);
}
.issue-type.warning > .icon {
color: var(--warning-color);
}
.issue-type.warning::after {
background-color: var(--warning-color);
}
.issue-type.error > .icon {
color: var(--error-color);
}
.issue-type.error::after {
background-color: var(--error-color);
}
.issue-type.success > .icon {
color: var(--success-color);
}
.issue-type.success::after {
background-color: var(--success-color);
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-alert": HaAlert;
}
}