aboutsummaryrefslogtreecommitdiff
path: root/input
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-09-05 16:09:55 +0700
committerShulhan <ms@kilabit.info>2021-09-05 18:36:42 +0700
commit2df99a87e652db2c82383b59307b6016ae2ba4f4 (patch)
treeddca74b85f61962dae505e404706b5f2336ed901 /input
parent437cee56693f69b2a58f37f8a5ff5b931ea803a2 (diff)
downloadpakakeh.ts-2df99a87e652db2c82383b59307b6016ae2ba4f4.tar.xz
input: implement class WuiInputString
The WuiInputString create an HTML input for string with predefined options. The required options are "label" and "value".
Diffstat (limited to 'input')
-rw-r--r--input/example.ts46
-rw-r--r--input/string.d.ts23
-rw-r--r--input/string.ts135
3 files changed, 204 insertions, 0 deletions
diff --git a/input/example.ts b/input/example.ts
index 3e68451..aa26d2d 100644
--- a/input/example.ts
+++ b/input/example.ts
@@ -1,5 +1,50 @@
+import { WuiInputString, WuiInputStringOpts } from "./string.js"
import { WuiInputNumber, WuiInputNumberOpts } from "./number.js"
+function exampleInputString() {
+ let el_example = document.createElement("div")
+
+ let el_title = document.createElement("h3")
+ el_title.innerText = "Input string"
+ el_example.appendChild(el_title)
+
+ let opts: WuiInputStringOpts = {
+ id: "my_input_string",
+ label: "Input string with ID",
+ value: "Hello, input string",
+ hint: "The input ID is 'my_input_string'",
+ onChangeHandler: (new_value: string) => {
+ console.log("input string new value: ", new_value)
+ }
+ }
+ let el_input_string = new WuiInputString(opts)
+ el_example.appendChild(el_input_string.el)
+
+ opts = {
+ label: "Input string disabled",
+ value: "Hello, disabled input string",
+ is_disabled: true,
+ hint: "The input string is disabled",
+ onChangeHandler: (new_value: string) => {
+ console.log("input string new value: ", new_value)
+ }
+ }
+ el_input_string = new WuiInputString(opts)
+ el_example.appendChild(el_input_string.el)
+
+ opts = {
+ label: "Input string without hint",
+ value: "Hello, input string without hint",
+ onChangeHandler: (new_value: string) => {
+ console.log("input string without hint: new value: ", new_value)
+ }
+ }
+ el_input_string = new WuiInputString(opts)
+ el_example.appendChild(el_input_string.el)
+
+ document.body.appendChild(el_example)
+}
+
function exampleInputNumber() {
let el_example = document.createElement("div")
@@ -66,4 +111,5 @@ function exampleInputNumber() {
document.body.appendChild(el_example)
}
+exampleInputString()
exampleInputNumber()
diff --git a/input/string.d.ts b/input/string.d.ts
new file mode 100644
index 0000000..f0a36fe
--- /dev/null
+++ b/input/string.d.ts
@@ -0,0 +1,23 @@
+export interface WuiInputStringOpts {
+ label: string;
+ value: string;
+ id?: string;
+ hint?: string;
+ is_disabled?: boolean;
+ onChangeHandler?: (new_value: string) => void;
+}
+export declare class WuiInputString {
+ opts: WuiInputStringOpts;
+ el: HTMLElement;
+ private el_label;
+ private el_input;
+ private el_hint;
+ private el_hint_toggler;
+ private value;
+ constructor(opts: WuiInputStringOpts);
+ private generateLabel;
+ private generateInput;
+ private generateHintToggler;
+ private generateHint;
+ private onClickHintToggler;
+}
diff --git a/input/string.ts b/input/string.ts
new file mode 100644
index 0000000..d8faf36
--- /dev/null
+++ b/input/string.ts
@@ -0,0 +1,135 @@
+export interface WuiInputStringOpts {
+ label: string
+ value: string
+ id?: string
+ hint?: string
+ is_disabled?: boolean
+ onChangeHandler?: (new_value: string) => void
+}
+
+const WUI_INPUT_STRING_CLASS = "wui_input_string"
+const WUI_INPUT_STRING_CLASS_HINT = "wui_input_string_hint"
+const WUI_INPUT_STRING_CLASS_HINT_TOGGLER = "wui_input_string_hint_toggler"
+const WUI_INPUT_STRING_CLASS_INPUT = "wui_input_string_input"
+const WUI_INPUT_STRING_CLASS_LABEL = "wui_input_string_label"
+
+//
+// WuiInputString create an HTML input for string with predefined options.
+// The required options are "label" and "value".
+//
+// Format of generated HTML output,
+//
+// <div [id=${id}] class="${WUI_INPUT_STRING_CLASS}">
+// <div>
+// <label class="${WUI_INPUT_STRING_CLASS_LABEL}">${label}</label>
+// <input
+// class="${WUI_INPUT_STRING_CLASS_INPUT}"
+// [disabled=${is_disabled}]
+// value=${value}
+// >
+// [<span class="${WUI_INPUT_STRING_CLASS_HINT_TOGGLER}">i </span>]
+// </div>
+// [<div class="${WUI_INPUT_STRING_CLASS_HINT}">${hint}</div>]
+// </div>
+//
+// The "hint" option is optional, if it set the input will have a hint toggler
+// to display or hide the input information.
+//
+// User can set onChangeHandler to receive new value when the input value
+// changes.
+//
+export class WuiInputString {
+ el: HTMLElement
+ private el_label!: HTMLElement
+ private el_input!: HTMLInputElement
+ private el_hint!: HTMLElement
+ private el_hint_toggler!: HTMLElement
+ private value: string = ""
+
+ constructor(public opts: WuiInputStringOpts) {
+ this.value = opts.value
+
+ this.el = document.createElement("div")
+ if (opts.id) {
+ this.el.id = opts.id
+ }
+ this.el.classList.add(WUI_INPUT_STRING_CLASS)
+ this.el.style.padding = "2px"
+
+ let wrapper = document.createElement("div")
+ this.generateLabel(wrapper)
+ this.generateInput(wrapper)
+ if (opts.hint) {
+ this.generateHintToggler(wrapper)
+ }
+ this.el.appendChild(wrapper)
+
+ if (opts.hint) {
+ this.generateHint()
+ }
+ }
+
+ private generateLabel(wrapper: HTMLElement) {
+ this.el_label = document.createElement("label")
+ this.el_label.classList.add(WUI_INPUT_STRING_CLASS_LABEL)
+ this.el_label.innerHTML = `${this.opts.label} `
+ wrapper.appendChild(this.el_label)
+ }
+
+ private generateInput(wrapper: HTMLElement) {
+ this.el_input = document.createElement("input") as HTMLInputElement
+ this.el_input.classList.add(WUI_INPUT_STRING_CLASS_INPUT)
+ this.el_input.value = "" + this.opts.value
+
+ if (this.opts.is_disabled) {
+ this.el_input.disabled = true
+ }
+
+ if (this.opts.onChangeHandler) {
+ console.log("register onchange")
+ this.el_input.onkeyup = (ev: Event) => {
+ if (this.opts.onChangeHandler) {
+ if (this.value !== this.el_input.value) {
+ this.opts.onChangeHandler(this.el_input.value)
+ this.value = this.el_input.value
+ }
+ }
+ }
+ }
+
+ wrapper.appendChild(this.el_input)
+ }
+
+ private generateHintToggler(wrapper: HTMLElement) {
+ this.el_hint_toggler = document.createElement("span")
+ this.el_hint_toggler.classList.add(WUI_INPUT_STRING_CLASS_HINT_TOGGLER)
+ this.el_hint_toggler.innerHTML = " &#x2139;"
+
+ this.el_hint_toggler.onmouseover = () => {
+ this.el_hint_toggler.style.cursor = "pointer"
+ }
+ this.el_hint_toggler.onclick = () => {
+ this.onClickHintToggler()
+ }
+ wrapper.appendChild(this.el_hint_toggler)
+ }
+
+ private generateHint() {
+ this.el_hint = document.createElement("div")
+ this.el_hint.classList.add(WUI_INPUT_STRING_CLASS_HINT)
+ this.el_hint.innerHTML = this.opts.hint || ""
+ this.el_hint.style.display = "none"
+ this.el_hint.style.backgroundColor = "gainsboro"
+ this.el_hint.style.borderRadius = "2px"
+ this.el_hint.style.padding = "4px"
+ this.el.appendChild(this.el_hint)
+ }
+
+ private onClickHintToggler() {
+ if (this.el_hint.style.display === "none") {
+ this.el_hint.style.display = "block"
+ } else {
+ this.el_hint.style.display = "none"
+ }
+ }
+}