import { LitElement } from 'lit'; import { customElement, property, query } from 'lit/decorators.js'; import { unsafeStatic, html } from 'lit/static-html.js'; import { assertTagNameIsAllowed } from './utils/AssertHelpers'; import { InputTone, RoundedCorners } from './utils/CommonTypes'; import { ifDefined, spread } from './utils/LitHelper'; import { SpreadController } from './utils/SpreadController'; import { TailwindStylesController } from './utils/TailwindStylesController'; export type ButtonSize = 'sm' | 'base' | 'lg'; export type ButtonVariant = 'solid' | 'ghost'; export const validButtonElementTagNames = ['button', 'a'] as const; export type ButtonElementTagName = typeof validButtonElementTagNames[number]; @customElement('mono-button') export class MonoButtonComp extends LitElement { private __spreadController: SpreadController = new SpreadController(this); private __stylesController: TailwindStylesController = new TailwindStylesController( this, ); @property({ type: String, reflect: true }) as: ButtonElementTagName = 'button'; @property({ type: String, reflect: true }) tone: InputTone = 'primary'; @property({ type: String, reflect: true }) size: ButtonSize = 'base'; @property({ type: String, reflect: true }) variant: ButtonVariant = 'solid'; @property({ type: String, reflect: true }) corners: RoundedCorners = 'none'; @property({ type: Boolean, reflect: true }) disabled: boolean = false; @property({ type: Boolean, reflect: true }) loading: boolean = false; @property({ type: Boolean, reflect: true }) submit = false; @property({ type: Number, reflect: true, attribute: 'insets-x', }) insetsX: number = 3; @query('button,a', true) __buttonEl!: HTMLButtonElement; constructor() { super(); this.addEventListener('click', this.__onClick); } private __computePaddingYForSize() { switch (this.size) { case 'sm': return 'py-1'; case 'lg': return 'py-3'; default: return 'py-2'; } } private __computeFontForSize() { switch (this.size) { case 'sm': return 'base'; case 'lg': return 'lg'; default: return 'lg'; } } private __computeStyleForToneAndVariant() { if (this.tone === 'primary' && this.variant === 'ghost') { return 'text-primary border-primary border-2 hover:bg-primary hover:text-white'; } if (this.tone === 'accent' && this.variant === 'ghost') { return 'text-accent border-accent border-2 hover:bg-accent hover:text-white'; } if (this.tone === 'highlight' && this.variant === 'ghost') { return 'text-highlight-2 border-highlight-2 border-2 hover:bg-highlight-2 hover:text-white'; } if (this.tone === 'dark' && this.variant === 'ghost') { return 'text-neutral-5 border-neutral-5 border-2 hover:bg-neutral-5 hover:text-white'; } if (this.tone === 'white' && this.variant === 'ghost') { return 'text-white border-white border-2 hover:bg-white hover:text-bg-neutral-5'; } if (this.tone === 'accent') { return 'bg-accent text-white border-accent border-2 hover:bg-accent-dark hover:border-accent-dark'; } if (this.tone === 'highlight') { return 'bg-highlight-2 text-white border-highlight-2 border-2 hover:bg-highlight-2-dark hover:border-highlight-2-dark'; } if (this.tone === 'dark') { return 'bg-neutral-5 text-white border-neutral-5 border-2 hover:bg-black hover:border-black'; } if (this.tone === 'white') { return 'bg-white text-neutral-5 border-white border-2 hover:bg-neutral-4 hover:border-neutral-4'; } return 'bg-primary text-white border-primary border-2 hover:bg-primary-dark hover:border-primary-dark'; } private __computeInsetsX() { return `px-${this.insetsX}`; } private __onClick(event: MouseEvent) { if (this.disabled && this.loading) { event.preventDefault(); event.stopPropagation(); event.stopImmediatePropagation(); } } private __renderContent() { return html`