maille
Version:
Component library for MithrilJS
124 lines (123 loc) • 4.58 kB
JavaScript
"use strict";
// THIS FILE WAS AUTO-GENERATED FOR PACKAGING, DO NOT MODIFY
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("../../types");
class Button {
constructor(vnode) {
this.type = types_1.ButtonType.Default;
this.size = types_1.Size.Medium;
this.outlined = false;
this.rounded = false;
this.disabled = false;
this.isLoading = false;
if (vnode) {
if (vnode.attrs.size) {
this.size = vnode.attrs.size;
}
if (vnode.attrs.type) {
this.type = vnode.attrs.type;
}
if (vnode.attrs.outlined) {
this.outlined = vnode.attrs.outlined;
}
if (vnode.attrs.rounded) {
this.rounded = vnode.attrs.rounded;
}
if (vnode.attrs.disabled) {
this.disabled = vnode.attrs.disabled;
}
if (vnode.attrs.loadingSettings) {
this.loadingSettings = vnode.attrs.loadingSettings;
}
if (vnode.attrs.isLoading) {
this.isLoading = vnode.attrs.isLoading;
}
if (vnode.attrs.onclick) {
this.internalOnClick = vnode.attrs.onclick;
}
if (vnode.attrs.componentSettings) {
this.componentSettings = vnode.attrs.componentSettings;
}
}
}
view(vnode) {
const classes = new Set(["maille", "maille-button"]);
// Class updates based on attributes
const buttonType = vnode.attrs.type || this.type;
classes.add(buttonType);
// If outlined, add the outline class
if (this.outlined) {
classes.add("outlined");
}
if (this.rounded) {
classes.add("rounded");
}
if (this.disabled) {
classes.add("disabled");
}
// Add additional styling classes
classes.add(`size-${this.size}`);
// Add vnode-specified classes
if (vnode.attrs.className) {
vnode.attrs.className.split(" ").forEach(v => classes.add(v));
}
const className = [...classes].join(" ");
const passthroughAttrs = vnode.attrs.attrs || {};
return m("button", Object.assign({ id: vnode.attrs.id, className, disabled: this.disabled, onclick: (e) => this.onclick(e) }, passthroughAttrs), this.buildContent(vnode.children));
}
oncreate(vnode) {
// Save the dom node to avoid having to use m.dredraw
this.vnode = vnode;
}
// Content of the button
buildContent(children) {
// If no loading settings always show the text
if (!this.loadingSettings) {
return m("span", children);
}
// If loading settings present, but not currently in isLoading state, then return text
if (!this.isLoading) {
return m("span", children);
}
// If some children to show while loading were provided then use them
if (this.loadingSettings.children) {
return m("span", this.loadingSettings.children);
}
// By default
return m("span", children);
}
redrawChildren() {
// If optimized redraw isn't happening
if (!this.componentSettings || !this.componentSettings.redrawChildrenOnly) {
m.redraw();
return;
}
// Clear out & re-render
// TODO: fix this, rendering children isn't really the right way, need to make "full" wrapper component
m.render(this.vnode.dom, this.view(this.vnode).children);
}
// Onclick handler that enhanced passed in onclick function
onclick(e) {
// Disable redraw if it's been optimized
if (this.componentSettings && this.componentSettings.redrawChildrenOnly) {
e.redraw = false;
}
// If there is no onclick then exit early
if (!this.internalOnClick) {
return Promise.resolve();
}
// Set loading to start
this.isLoading = true;
this.redrawChildren();
// Perform onclick logic, converting the result to a promise if it isn't one
const result = Promise.resolve(this.internalOnClick(e));
// Resolve the promise and then reset the loading status
return result
.then(() => {
this.isLoading = false;
this.redrawChildren();
return arguments;
});
}
}
exports.default = Button;