/** Reusable confirmation dialog wrapping . */ import { LitElement, html, css, nothing } from "lit"; import { property, state } from "lit/decorators.js"; import type { HomeAssistant } from "../types"; import { t, nativeFieldStyles } from "../styles"; export interface ConfirmOptions { title: string; message: string; confirmText?: string; danger?: boolean; } export interface PromptOptions extends ConfirmOptions { inputLabel?: string; inputType?: string; // "text" | "date" etc. inputValue?: string; } export interface PromptResult { confirmed: boolean; value: string; } export class MaintenanceConfirmDialog extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @state() private _open = false; @state() private _title = ""; @state() private _message = ""; @state() private _confirmText = ""; @state() private _danger = false; @state() private _inputLabel = ""; @state() private _inputType = ""; @state() private _inputValue = ""; private _resolve: ((value: boolean) => void) | null = null; private _promptResolve: ((value: PromptResult) => void) | null = null; public confirm(opts: ConfirmOptions): Promise { this._title = opts.title; this._message = opts.message; this._confirmText = opts.confirmText || "OK"; this._danger = opts.danger || false; this._inputLabel = ""; this._inputType = ""; this._inputValue = ""; this._open = true; return new Promise((resolve) => { this._resolve = resolve; this._promptResolve = null; }); } public prompt(opts: PromptOptions): Promise { this._title = opts.title; this._message = opts.message; this._confirmText = opts.confirmText || "OK"; this._danger = opts.danger || false; this._inputLabel = opts.inputLabel || ""; this._inputType = opts.inputType || "text"; this._inputValue = opts.inputValue || ""; this._open = true; return new Promise((resolve) => { this._promptResolve = resolve; this._resolve = null; }); } private _cancel(): void { this._open = false; if (this._promptResolve) { this._promptResolve({ confirmed: false, value: "" }); this._promptResolve = null; } this._resolve?.(false); this._resolve = null; } private _confirmAction(): void { this._open = false; if (this._promptResolve) { this._promptResolve({ confirmed: true, value: this._inputValue }); this._promptResolve = null; } this._resolve?.(true); this._resolve = null; } render() { if (!this._open) return nothing; const lang = this.hass?.language || "en"; return html`
${this._title}
${this._message} ${this._inputLabel ? html` ` : nothing}
${t("cancel", lang)} ${this._confirmText}
`; } static styles = [nativeFieldStyles, css` .dialog-title { font-size: 18px; font-weight: 500; padding-bottom: 12px; } /* shared native-field scaffold from nativeFieldStyles; the prompt input follows the message text, hence the extra top margin here */ .field { margin-top: 12px; } .content { padding: 8px 0; min-width: 280px; line-height: 1.5; display: flex; flex-direction: column; gap: 12px; } .dialog-actions { display: flex; justify-content: flex-end; gap: 8px; padding-top: 16px; } ha-textfield { display: block; } ha-button.danger { --mdc-theme-primary: var(--error-color, #f44336); } `]; } if (!customElements.get("maintenance-confirm-dialog")) { customElements.define("maintenance-confirm-dialog", MaintenanceConfirmDialog); }