forked from
grain.social/grain-pwa
WIP PWA for Grain
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);