166 lines
3.7 KiB
TypeScript
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;
|
|
}
|
|
}
|