import { html, LitElement, render as litRender } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { translateText } from "../Utils";
/**
* A reusable inline confirmation dialog.
*
* Usage:
* ```html
* doThing()}
* @cancel=${() => {}}
* >
* ```
*
* For ban-style flows, add a textarea:
* ```html
* ban(e.detail.text)}
* @cancel=${() => {}}
* >
* ```
*/
@customElement("confirm-dialog")
export class ConfirmDialog extends LitElement {
@property() message = "";
@property() variant: "danger" | "warning" = "danger";
@property() textareaPlaceholder = "";
@property({ type: Boolean }) disabled = false;
@state() private text = "";
private portal: HTMLDivElement | null = null;
createRenderRoot() {
return this;
}
connectedCallback() {
super.connectedCallback();
this.portal = document.createElement("div");
document.body.appendChild(this.portal);
}
disconnectedCallback() {
super.disconnectedCallback();
if (this.portal) {
litRender(html``, this.portal);
this.portal.remove();
this.portal = null;
}
}
render() {
if (this.portal) {
litRender(this.renderOverlay(), this.portal);
}
return html``;
}
private renderOverlay() {
const isDanger = this.variant === "danger";
const borderColor = isDanger ? "border-red-500/50" : "border-amber-500/50";
const cardBg = "bg-surface";
const textColor = isDanger ? "text-red-300" : "text-amber-300";
const btnClass = isDanger
? "bg-red-600 text-white hover:bg-red-700"
: "bg-amber-600 text-white hover:bg-amber-700";
return html`
{
if (e.target === e.currentTarget) this.handleCancel();
}}
>
${this.message}
${this.textareaPlaceholder
? html`
`
: ""}
`;
}
private handleConfirm() {
this.dispatchEvent(
new CustomEvent("confirm", { detail: { text: this.text } }),
);
this.text = "";
}
private handleCancel() {
this.dispatchEvent(new CustomEvent("cancel"));
this.text = "";
}
}