stylescape
Version:
Stylescape is a visual identity framework developed by Scape Agency.
128 lines • 4.27 kB
JavaScript
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