UNPKG

besper-frontend-site-dev-main

Version:

Professional B-esper Frontend Site - Site-wide integration toolkit for full website bot deployment

105 lines (88 loc) 2.93 kB
// Button component for consistent UI interactions import { Component } from './Component.js'; import { ButtonProps } from '../../types/components.types.js'; import { createElement } from '../../utils/dom.js'; export class Button extends Component { private props: ButtonProps; constructor(props: ButtonProps) { super(props); this.props = props; } protected createElement(): HTMLElement { const button = createElement( 'button', this.getButtonClasses() ) as HTMLButtonElement; button.id = this.id; button.innerHTML = this.render(); button.disabled = this.props.disabled || false; this.setupEventListeners(button); return button; } protected render(): string { if (this.props.loading) { return ` <span class="button-spinner"> <svg class="animate-spin" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M21 12a9 9 0 11-6.219-8.56"/> </svg> </span> <span>Loading...</span> `; } return '<span><!-- Button content will be set via setText() --></span>'; } private getButtonClasses(): string { const baseClass = 'besper-button'; const variantClass = `button-${this.props.variant || 'primary'}`; const sizeClass = `button-${this.props.size || 'md'}`; const stateClasses = [ this.props.disabled ? 'button-disabled' : '', this.props.loading ? 'button-loading' : '', ].filter(Boolean); return [baseClass, variantClass, sizeClass, ...stateClasses, this.className] .filter(Boolean) .join(' '); } private setupEventListeners(button: HTMLButtonElement): void { if (this.props.onClick) { this.addEventListener(button, 'click', e => { e.preventDefault(); if (!this.props.disabled && !this.props.loading && this.props.onClick) { this.props.onClick(); } }); } } public setText(text: string): void { if (!this.props.loading) { const span = this.element.querySelector('span') as HTMLElement; if (span) { span.textContent = text; } } } public setDisabled(disabled: boolean): void { this.props.disabled = disabled; (this.element as HTMLButtonElement).disabled = disabled; this.updateClasses(); } public setLoading(loading: boolean): void { this.props.loading = loading; (this.element as HTMLButtonElement).disabled = loading || this.props.disabled || false; this.element.innerHTML = this.render(); this.updateClasses(); } public setVariant(variant: ButtonProps['variant']): void { this.props.variant = variant; this.updateClasses(); } public setSize(size: ButtonProps['size']): void { this.props.size = size; this.updateClasses(); } private updateClasses(): void { this.element.className = this.getButtonClasses(); } }