stem-core
Version:
Frontend and core-library framework
284 lines (227 loc) • 6.17 kB
JSX
import {UI} from "../UIBase";
import {DOMAttributesMap} from "../NodeAttributes";
import {InputStyle} from "./Style";
import {registerStyle} from "../style/Theme";
class InputableElement extends UI.Element {
extraNodeAttributes(attr) {
super.extraNodeAttributes(attr);
attr.addClass(this.styleSheet.inputElement);
}
}
class Input extends UI.Primitive(InputableElement, "input") {
extraNodeAttributes(attr) {
let type = this.getInputType();
if (type) {
attr.setAttribute("type", type);
}
}
redraw() {
super.redraw();
if (this.options.hasOwnProperty("value")) {
this.setValue(this.options.value);
}
}
getValue() {
return this.node.value;
}
setValue(newValue) {
this.node.value = newValue;
}
getInputType() {
// Must be overloaded
return null;
}
onInput(callback) {
this.addNodeListener("input change", callback);
}
onKeyUp(callback) {
this.addNodeListener("keyup", callback);
}
}
Input.domAttributesMap = new DOMAttributesMap(UI.Element.domAttributesMap, [
["autocomplete"],
["autofocus", {noValue: true}],
["formaction"],
["maxLength", {domName: "maxlength"}],
["minLength", {domName: "minlength"}],
["name"],
["placeholder"],
["readonly"],
["required"],
["value"],
["pattern"],
["type"],
]);
class SubmitInput extends Input {
getInputType() {
return "submit";
}
}
SubmitInput.domAttributesMap = new DOMAttributesMap(UI.Element.domAttributesMap, [
["formenctype"],
["formmethod"],
["formnovalidate"],
["formtarget"]
]);
class TextInput extends Input {
getInputType() {
return "text";
}
}
class NumberInput extends Input {
getInputType() {
return "number";
}
getValue() {
let val = super.getValue();
return parseFloat(val);
}
}
NumberInput.domAttributesMap = new DOMAttributesMap(UI.Element.domAttributesMap, [
["min"],
["max"],
["step"],
]);
class EmailInput extends Input {
getInputType() {
return "email";
}
}
class PasswordInput extends Input {
getInputType() {
return "password";
}
}
class FileInput extends Input {
getInputType() {
return "file";
}
getFiles() {
return this.node.files;
}
getFile() {
// TODO: this is valid only if multipleFiles is false
return this.getFiles()[0];
}
getAsFormData() {
let formData = new FormData();
for (let file of this.getFiles()) {
formData.append(file.name, file);
}
return formData;
}
}
FileInput.domAttributesMap = new DOMAttributesMap(UI.Element.domAttributesMap, [
["multipleFiles", {domName: "multiple", noValue: true}],
["fileTypes", {domName: "accept"}],
]);
class CheckboxInput extends Input {
extraNodeAttributes(attr) {
super.extraNodeAttributes(attr);
attr.addClass(this.styleSheet.checkboxInput);
}
getInputType() {
return "checkbox";
}
getValue() {
return this.node.checked;
}
setValue(newValue) {
this.node.checked = newValue;
}
}
CheckboxInput.domAttributesMap = new DOMAttributesMap(UI.Element.domAttributesMap, [
["checked", {noValue: true}]
]);
class RadioInput extends CheckboxInput {
getInputType() {
return "radio";
}
getValue() {
return this.node.checked;
}
setValue(newValue) {
this.node.checked = newValue;
}
}
RadioInput.domAttributesMap = new DOMAttributesMap(CheckboxInput.domAttributesMap, [
["name"]
]);
class TextArea extends UI.Primitive(InputableElement, "textarea") {
applyNodeAttributes() {
super.applyNodeAttributes();
this.node.readOnly = this.options.readOnly || false;
}
setReadOnly(value) {
this.options.readOnly = value;
this.node.readOnly = value;
}
getValue() {
return this.node.value;
}
redraw() {
super.redraw();
if (this.options.hasOwnProperty("value")) {
this.node.value = this.options.value + "";
}
}
setValue(value) {
this.options.value = value;
this.node.value = value;
}
onInput(callback) {
this.addNodeListener("input change", callback);
}
onKeyUp(callback) {
this.addNodeListener("keyup", callback);
}
}
class Select extends UI.Primitive(InputableElement, "select") {
render() {
this.givenOptions = this.options.options || [];
let selectOptions = [];
for (let i = 0; i < this.givenOptions.length; i += 1) {
let options = {
key: i
};
if (this.givenOptions[i] == this.options.selected) {
options.selected = true;
}
selectOptions.push(<option {...options}>{this.givenOptions[i].toString()}</option>);
}
return selectOptions;
}
extraNodeAttributes(attr) {
super.extraNodeAttributes(attr);
attr.addClass(this.styleSheet.select);
}
get() {
let selectedIndex = this.getIndex();
return this.givenOptions[selectedIndex];
}
set(value) {
for (let i = 0; i < this.givenOptions.length; i++) {
if (this.givenOptions[i] === value) {
this.setIndex(i);
return;
}
}
console.error("Can't set the select option ", value, "\nAvailable options: ", this.givenOptions);
}
getIndex() {
return this.node.selectedIndex;
}
setIndex(index) {
this.node.selectedIndex = index;
this.options.selected = this.givenOptions[index];
}
redraw() {
super.redraw();
if (this.options.selected) {
this.set(this.options.selected);
}
}
}
export {InputStyle, Input, SubmitInput, TextInput, NumberInput, EmailInput, PasswordInput, FileInput,
CheckboxInput, RadioInput, TextArea, Select};