WIP PWA for Grain
at main 79 lines 1.8 kB view raw
1import { LitElement, html, css } from 'lit'; 2import './grain-spinner.js'; 3 4export class GrainButton extends LitElement { 5 static properties = { 6 variant: { type: String }, 7 loading: { type: Boolean }, 8 loadingText: { type: String }, 9 disabled: { type: Boolean, reflect: true } 10 }; 11 12 static styles = css` 13 :host { 14 display: inline-block; 15 } 16 button { 17 display: flex; 18 align-items: center; 19 justify-content: center; 20 gap: 6px; 21 border: none; 22 padding: 8px 16px; 23 border-radius: 6px; 24 font-size: var(--font-size-sm); 25 font-weight: var(--font-weight-semibold); 26 font-family: inherit; 27 cursor: pointer; 28 transition: opacity 0.15s; 29 } 30 button:disabled { 31 opacity: 0.5; 32 cursor: not-allowed; 33 } 34 button.primary { 35 background: var(--color-accent, #0066cc); 36 color: white; 37 } 38 button.secondary { 39 background: transparent; 40 color: var(--color-text-primary); 41 border: 1px solid var(--color-border); 42 } 43 button.danger { 44 background: #ff4444; 45 color: white; 46 } 47 button.ghost { 48 background: transparent; 49 color: var(--color-text-secondary); 50 padding: 8px; 51 } 52 `; 53 54 constructor() { 55 super(); 56 this.variant = 'primary'; 57 this.loading = false; 58 this.loadingText = ''; 59 this.disabled = false; 60 } 61 62 render() { 63 return html` 64 <button 65 class=${this.variant} 66 ?disabled=${this.disabled || this.loading} 67 > 68 ${this.loading ? html` 69 <grain-spinner size="16"></grain-spinner> 70 ${this.loadingText || html`<slot></slot>`} 71 ` : html` 72 <slot></slot> 73 `} 74 </button> 75 `; 76 } 77} 78 79customElements.define('grain-button', GrainButton);