Files
workorders/web/components/shared/ui-dialog.mjs
T

57 lines
2.6 KiB
JavaScript

class UiDialog extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host { display: contents; }
dialog {
border: none; border-radius: var(--radius-lg); padding: 0;
background: var(--surface); color: var(--text);
box-shadow: var(--shadow-lg); max-height: 90vh; overflow: hidden;
display: flex; flex-direction: column;
}
dialog[open] { display: flex; }
dialog::backdrop { background: rgba(0,0,0,.45); backdrop-filter: blur(2px); }
.size-sm { width: min(400px, 95vw); }
.size-md { width: min(600px, 95vw); }
.size-lg { width: min(860px, 95vw); }
.header {
display: flex; align-items: center; justify-content: space-between;
padding: 1.1rem 1.25rem; border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.header h2 { font-size: 1rem; font-weight: 600; }
.close-btn {
background: none; border: none; cursor: pointer; color: var(--text-muted);
padding: .25rem; border-radius: var(--radius-sm); display: flex;
transition: color .15s;
}
.close-btn:hover { color: var(--text); }
.body { padding: 1.25rem; overflow-y: auto; flex: 1; }
@media (max-width: 768px) {
dialog { width: 100vw !important; max-height: 85vh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
dialog[open] { position: fixed; bottom: 0; left: 0; margin: 0; }
}
</style>
<dialog class="size-${this.getAttribute('size') || 'md'}">
<div class="header">
<h2>${this.getAttribute('title') || ''}</h2>
<button class="close-btn" aria-label="Close">
<i data-lucide="x" style="width:18px;height:18px"></i>
</button>
</div>
<div class="body"><slot></slot></div>
</dialog>`;
const dialog = this.shadowRoot.querySelector('dialog');
this.shadowRoot.querySelector('.close-btn').addEventListener('click', () => this.close());
dialog.addEventListener('click', e => { if (e.target === dialog) this.close(); });
document.addEventListener('keydown', e => { if (e.key === 'Escape') this.close(); });
if (window.lucide) lucide.createIcons({ root: this.shadowRoot });
}
open() { this.shadowRoot?.querySelector('dialog')?.showModal(); }
close() { this.shadowRoot?.querySelector('dialog')?.close(); this.dispatchEvent(new CustomEvent('ui:close', { bubbles: true, composed: true })); }
}
customElements.define('ui-dialog', UiDialog);