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

48 lines
2.3 KiB
JavaScript

class UiButton extends HTMLElement {
static get observedAttributes() { return ['variant', 'size', 'loading', 'disabled']; }
connectedCallback() { this.#render(); }
attributeChangedCallback() { this.#render(); }
#render() {
const variant = this.getAttribute('variant') || 'primary';
const size = this.getAttribute('size') || 'md';
const loading = this.hasAttribute('loading');
const disabled = this.hasAttribute('disabled') || loading;
const pad = { sm: '.35rem .75rem', md: '.5rem 1rem', lg: '.65rem 1.25rem' }[size] || '.5rem 1rem';
const fs = { sm: '.813rem', md: '.875rem', lg: '1rem' }[size] || '.875rem';
if (!this.shadowRoot) this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host { display: inline-flex; }
button {
display: inline-flex; align-items: center; gap: .4rem;
padding: ${pad}; border: none; border-radius: var(--radius);
font-size: ${fs}; font-weight: 600; cursor: pointer;
transition: opacity .15s, background .15s;
white-space: nowrap;
}
button:disabled { opacity: .5; cursor: not-allowed; }
.primary { background: var(--teal); color: #fff; }
.primary:hover:not(:disabled) { background: var(--teal-dk); }
.ghost { background: transparent; border: 1px solid var(--border); color: var(--text); }
.ghost:hover:not(:disabled) { background: var(--surface-2); }
.danger { background: var(--danger); color: #fff; }
.danger:hover:not(:disabled) { opacity: .88; }
.icon { background: transparent; border: none; color: var(--text-muted); padding: .4rem; border-radius: var(--radius-sm); }
.icon:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.ring {
width: 14px; height: 14px; border: 2px solid rgba(255,255,255,.4);
border-top-color: #fff; border-radius: 50%;
animation: spin .6s linear infinite; flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }
</style>
<button class="${variant}" ${disabled ? 'disabled' : ''}>
${loading ? '<div class="ring"></div>' : ''}
<slot></slot>
</button>`;
}
}
customElements.define('ui-button', UiButton);