UNPKG

stylescape

Version:

Stylescape is a visual identity framework developed by Scape Agency.

128 lines 4.27 kB
export class ButtonHandler { constructor(selectorOrElement, options = {}) { this.originalContent = ""; this.isLoading = false; this.handleClick = async (event) => { if (!this.button || this.isLoading) return; if (this.options.ripple) { this.createRipple(event); } if (this.options.loading) { this.startLoading(); } try { await this.options.onClick(this.button, event); } finally { if (this.options.loading) { this.stopLoading(); } } }; this.button = typeof selectorOrElement === "string" ? document.querySelector(selectorOrElement) : selectorOrElement; this.options = { loading: options.loading ?? false, disableOnLoading: options.disableOnLoading !== false, loadingHtml: options.loadingHtml ?? '<span class="button__spinner"></span>', ripple: options.ripple ?? false, rippleColor: options.rippleColor ?? "rgba(255, 255, 255, 0.3)", onClick: options.onClick ?? (() => { }), }; if (!this.button) { console.warn("[Stylescape] ButtonHandler button not found"); return; } this.originalContent = this.button.innerHTML; this.init(); } startLoading() { if (!this.button || this.isLoading) return; this.isLoading = true; this.originalContent = this.button.innerHTML; if (this.options.disableOnLoading) { this.button.disabled = true; } this.button.classList.add("button--loading"); this.button.innerHTML = this.options.loadingHtml; this.button.setAttribute("aria-busy", "true"); } stopLoading() { if (!this.button || !this.isLoading) return; this.isLoading = false; this.button.disabled = false; this.button.classList.remove("button--loading"); this.button.innerHTML = this.originalContent; this.button.setAttribute("aria-busy", "false"); } click() { this.button?.click(); } enable() { if (this.button) { this.button.disabled = false; } } disable() { if (this.button) { this.button.disabled = true; } } destroy() { this.button?.removeEventListener("click", this.handleClick); this.button = null; } init() { if (!this.button) return; this.button.addEventListener("click", this.handleClick); if (this.options.ripple) { this.button.style.position = "relative"; this.button.style.overflow = "hidden"; } } createRipple(event) { if (!this.button) return; const ripple = document.createElement("span"); ripple.className = "button__ripple"; const rect = this.button.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; width: ${size}px; height: ${size}px; left: ${x}px; top: ${y}px; background: ${this.options.rippleColor}; border-radius: 50%; transform: scale(0); animation: ripple 0.6s linear; pointer-events: none; `; this.button.appendChild(ripple); ripple.addEventListener("animationend", () => { ripple.remove(); }); } } export function initButtons() { document .querySelectorAll('[data-ss="button"]') .forEach((button) => { new ButtonHandler(button, { loading: button.dataset.ssButtonLoading === "true", ripple: button.dataset.ssButtonRipple === "true", rippleColor: button.dataset.ssButtonRippleColor, }); }); } export default ButtonHandler; //# sourceMappingURL=ButtonHandler.js.map