maille
Version:
Component library for MithrilJS
179 lines (178 loc) • 6.39 kB
JavaScript
"use strict";
// THIS FILE WAS AUTO-GENERATED FOR PACKAGING, DO NOT MODIFY
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const radio_input_1 = __importDefault(require("../radio-input"));
let DEFAULT_NAME_ID = 0;
var RadioInputStyle;
(function (RadioInputStyle) {
RadioInputStyle["Default"] = "default";
RadioInputStyle["Button"] = "button";
})(RadioInputStyle = exports.RadioInputStyle || (exports.RadioInputStyle = {}));
class RadioInputGroup {
constructor(vnode) {
this.value = undefined;
this.options = [];
this.children = [];
this.changedOnce = false;
this.disabled = false;
this.rounded = false;
this.inputStyle = RadioInputStyle.Default;
this.internalOnChange = () => undefined;
if (vnode) {
if (vnode.attrs.onchange) {
this.internalOnChange = vnode.attrs.onchange;
}
if (vnode.attrs.value) {
this.value = vnode.attrs.value;
}
if (vnode.attrs.options) {
this.options = vnode.attrs.options;
}
if (vnode.attrs.inputStyle) {
this.inputStyle = vnode.attrs.inputStyle;
}
if (typeof vnode.attrs.disabled !== "undefined") {
this.disabled = vnode.attrs.disabled;
}
if (typeof vnode.attrs.rounded !== "undefined") {
this.rounded = vnode.attrs.rounded;
}
}
this.name = vnode && vnode.attrs.name ? vnode.attrs.name : `autoname-${++DEFAULT_NAME_ID}`;
}
view(vnode) {
const classes = new Set(["maille", "maille-radio-input-group", "flex"]);
// Fix the name if it's changed
if (vnode.attrs.name) {
this.name = vnode.attrs.name;
}
if (vnode.attrs.disabled) {
this.disabled = vnode.attrs.disabled;
}
if (typeof vnode.attrs.rounded !== "undefined") {
this.rounded = vnode.attrs.rounded;
}
if (vnode.attrs.value !== this.value) {
this.value = vnode.attrs.value;
}
// If bordered, add the outline class
if (this.rounded) {
classes.add("rounded");
}
if (this.disabled) {
classes.add("disabled");
}
if (vnode.attrs.bordered) {
classes.add("bordered");
}
// Build children InputGroup elements
if (vnode.attrs.options && vnode.attrs.options !== this.options) {
this.options = vnode.attrs.options;
}
this.children = this.buildChildren(this.options);
// Build the container
return this.buildContainer([...classes], vnode);
}
buildContainer(classes, vnode) {
return m("div", {
id: vnode.attrs.id,
className: classes.join(" "),
disabled: vnode.attrs.disabled,
}, this.children);
}
buildChild(option, checked, idx) {
return m(radio_input_1.default, {
value: option.value,
rounded: option.rounded,
name: this.name,
disabled: this.disabled,
checked,
// When any radio input we assume it's when it's checked
oninput: (_, value, event) => {
this.onchange(event, value);
},
}, option.label);
}
buildChildren(options) {
let foundChecked = false;
// Build list of RadioInputs
return options
.map((o, idx) => {
// Figure out of the radio input is currently selected
const initiallyChecked = o.checked && !this.changedOnce;
const checked = initiallyChecked || (this.value && o.value === this.value && !foundChecked);
if (checked) {
foundChecked = true;
}
return this.buildChild(o, checked, idx);
});
}
getSelectedValue(e) {
if (!e) {
return;
}
// Return early if target is missing
const target = e.target;
if (!e.target) {
return;
}
// ONE of the ones just came in here
// need to figure out which one it is
const selectedChild = this.children.find(c => {
if (!c) {
return false;
}
if (typeof c !== "object") {
return false;
}
if (!("dom" in c)) {
return false;
}
const domObj = c.dom;
// Since the dom object will actually be the label that is around the input itself,
// we have to check if the children of the label contains the input
return Array.from(domObj.children).includes(target);
});
// Exit early if somehow we don't have the selected child
if (!selectedChild) {
return;
}
// Exit early if the child isn't an object
if (typeof selectedChild !== "object") {
return;
}
// Doesn't contain attributes (it should)
if (!("attrs" in selectedChild)) {
return;
}
return selectedChild.attrs.value;
}
// OnChange handler that enhanced passed in onchange function
onchange(e, value) {
// Mark that a change has happened once
this.changedOnce = true;
// Return early if we don't have any children somehow
if (!this.children) {
return;
}
// Set the current value of the group to the child's value
this.value = this.getSelectedValue(e);
// If there is no onchange then exit early
if (!this.internalOnChange) {
return Promise.resolve();
}
// Perform onchange logic, converting the result to a promise if it isn't one
const result = Promise.resolve(this.internalOnChange(this.value, e));
// Resolve the promise and then reset the loading status
return result
.then(res => {
// Trigger redraw that should change the radio input's state
m.redraw();
return res;
});
}
}
exports.default = RadioInputGroup;