Add user database migration, core reusable components, and layout structure
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
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({ nodes: [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);
|
||||
Reference in New Issue
Block a user