aboutsummaryrefslogtreecommitdiff
path: root/input/file.ts
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-02-05 01:09:49 +0700
committerShulhan <ms@kilabit.info>2024-02-05 02:32:51 +0700
commit7e0b412323db013e225cc8122c83cc765e561229 (patch)
treeb948f4f80dcd6bc5df0864cb2ba2774935ac848f /input/file.ts
parentef954b5aae36934165103c398b783bac1fb4c911 (diff)
downloadpakakeh.ts-7e0b412323db013e225cc8122c83cc765e561229.tar.xz
input: implement component for inputing file
Diffstat (limited to 'input/file.ts')
-rw-r--r--input/file.ts134
1 files changed, 134 insertions, 0 deletions
diff --git a/input/file.ts b/input/file.ts
new file mode 100644
index 0000000..fd42f6d
--- /dev/null
+++ b/input/file.ts
@@ -0,0 +1,134 @@
+// SPDX-FileCopyrightText: 2024 M. Shulhan <ms@kilabit.info>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+export class WuiInputFile {
+ id: string = "";
+ class: string = "";
+
+ // Filter for files. For example "image/*" to allow selecting image files.
+ accept: string = "";
+ label: string = "";
+ hint: string = "";
+
+ classInput: string = ""; // Custom CSS class for input element.
+ classLabel: string = ""; // Custom CSS class for label.
+ classHint: string = ""; // Custom CSS class for hint text.
+ classHintToggle: string = ""; // Custom CSS class for hint toggler.
+
+ isDisabled: boolean = false;
+ isHintShowed: boolean = false;
+
+ onChange?: (file: File) => void;
+
+ private elHint: HTMLElement = document.createElement("div");
+
+ constructor() {}
+
+ element(): HTMLElement {
+ const el = document.createElement("div");
+
+ if (this.id) {
+ el.id = this.id;
+ }
+
+ el.classList.add("wui_input_file");
+ if (this.class) {
+ el.classList.add(this.class);
+ }
+
+ const wrapper = document.createElement("div");
+ this.generateLabel(wrapper);
+ this.generateInput(wrapper);
+ this.generateHintToggler(wrapper);
+ el.appendChild(wrapper);
+ this.generateHint(el);
+
+ return el;
+ }
+
+ private generateLabel(wrapper: HTMLElement) {
+ const elLabel = document.createElement("label");
+
+ elLabel.classList.add("wui_input_file_label");
+ if (this.classLabel) {
+ elLabel.classList.add(this.classLabel);
+ }
+
+ elLabel.innerHTML = `${this.label} `;
+
+ wrapper.appendChild(elLabel);
+ }
+
+ private generateInput(wrapper: HTMLElement) {
+ const elInput = document.createElement("input") as HTMLInputElement;
+
+ elInput.type = "file";
+
+ elInput.classList.add("wui_input_file_input");
+ if (this.classInput) {
+ elInput.classList.add(this.classInput);
+ }
+
+ if (this.accept) {
+ elInput.accept = this.accept;
+ }
+
+ if (this.isDisabled) {
+ elInput.disabled = true;
+ }
+
+ elInput.onchange = (event) => {
+ const file = (event.target as HTMLInputElement).files![0];
+ if (file && this.onChange) {
+ this.onChange(file);
+ }
+ };
+
+ wrapper.appendChild(elInput);
+ }
+
+ private generateHintToggler(wrapper: HTMLElement) {
+ const elHintToggler = document.createElement("span");
+
+ elHintToggler.classList.add("wui_input_file_hint_toggler");
+ if (this.classHintToggle) {
+ elHintToggler.classList.add(this.classHintToggle);
+ }
+
+ elHintToggler.innerHTML = " &#x2139;";
+
+ elHintToggler.onmouseover = () => {
+ elHintToggler.style.cursor = "pointer";
+ };
+ elHintToggler.onclick = () => {
+ if (this.elHint.style.display === "none") {
+ this.elHint.style.display = "block";
+ } else {
+ this.elHint.style.display = "none";
+ }
+ };
+ wrapper.appendChild(elHintToggler);
+ }
+
+ private generateHint(parent: HTMLElement) {
+ this.elHint = document.createElement("div");
+
+ this.elHint.classList.add("wui_input_file_hint");
+ if (this.classHint) {
+ this.elHint.classList.add(this.classHint);
+ }
+
+ this.elHint.innerHTML = this.hint;
+ this.elHint.style.borderRadius = "2px";
+ this.elHint.style.padding = "4px";
+ this.elHint.style.marginTop = "2px";
+
+ if (this.isHintShowed) {
+ this.elHint.style.display = "block";
+ } else {
+ this.elHint.style.display = "none";
+ }
+
+ parent.appendChild(this.elHint);
+ }
+}