import { Element } from "./element";
import { MaterialIcon } from "./icon";
import { Text } from "./text";
/**
* The button element.
*/
class Button extends Element {
/**
*
* @param {string} type one of available button types
*/
constructor(type) {
super("button");
this.addClasses("btn");
this.elem.type = type;
}
/**
* Disable button.
* @returns {Button} this
*/
disable() {
this.elem.disabled = true;
return this;
}
/**
* Enable button.
* @returns {Button} this
*/
enable() {
this.elem.disabled = false;
return this;
}
/**
* Replaces inner HTML with a loading spinner.
* @param {string | null | undefined} text the loading message
* @returns {string} replaced inner HTML
*/
runSpinner(text) {
const oldInnerHTML = this.innerHTML;
this.innerHTML = `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>${text ? text : ''}`;
return oldInnerHTML;
}
/**
* Binds a function for the onclick event.
* @param {function} fun
* @param {string | null | undefined} text the loading message displayed in button after click
* @returns {Button} this
*/
onClick(fun, text) {
this.cursor("pointer");
this.elem.onclick = async () => {
this.disable();
const oldInnerHTML = this.runSpinner(text);
try {
await fun(this);
} catch (error) {
console.error(error);
}
this.innerHTML = oldInnerHTML;
this.enable();
};
return this;
}
#class(cls, outline) {
this.addClasses(`btn-${outline ? "outline-" : ""}${cls}`);
}
/**
* Sets as primary button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asPrimary(outline) {
this.#class("primary", outline);
return this
}
/**
* Sets as secondary button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asSecondary(outline) {
this.#class("secondary", outline);
return this
}
/**
* Sets as success button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asSuccess(outline) {
this.#class("success", outline);
return this
}
/**
* Sets as danger button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asDanger(outline) {
this.#class("danger", outline);
return this
}
/**
* Sets as warning button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asWarning(outline) {
this.#class("warning", outline);
return this
}
/**
* Sets as info button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asInfo(outline) {
this.#class("info", outline);
return this
}
/**
* Sets as light button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asLight(outline) {
this.#class("light", outline);
return this
}
/**
* Sets as dark button.
* @param {boolean | null} outline specifies outline mode
* @returns {Button} this
*/
asDark(outline) {
this.#class("dark", outline);
return this
}
/**
* Sets as link button.
* @returns {Button} this
*/
asLink() {
this.#class("link", outline);
return this
}
}
/**
* The simple button element.
*/
export class SimpleButton extends Button {
/**
*
* @param {string} type one of available button types
* @param {string} img image src
* @param {string} text inner text
*/
constructor(type, img, text) {
super(type);
img && this.appendChild(img);
text && this.appendChild(new Text("b", text));
}
}
/**
* The material icon button element.
*/
export class IconButton extends Button {
/**
*
* @param {string} type one of available button types
* @param {string} iconName Material icon name
* @param {string} text inner text
*/
constructor(type, iconName, text) {
super(type);
iconName && this.appendChild(new MaterialIcon(iconName));
text && this.appendChild(new Text("b", text));
}
}