UNPKG

stem-core

Version:

Frontend and core-library framework

284 lines (227 loc) 6.17 kB
import {UI} from "../UIBase"; import {DOMAttributesMap} from "../NodeAttributes"; import {InputStyle} from "./Style"; import {registerStyle} from "../style/Theme"; @registerStyle(InputStyle) 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};