diff --git a/src/Beat.ts b/src/Beat.ts
index 3ceea57..15cacca 100644
--- a/src/Beat.ts
+++ b/src/Beat.ts
@@ -1,8 +1,8 @@
-import BeatUnit from "./BeatUnit";
-import {IPublisher, Publisher} from "./Publisher";
-import ISubscriber from "./Subscriber";
-import BeatLike from "./BeatLike";
-import {isPosInt} from "./utils";
+import BeatUnit from "@/BeatUnit";
+import {IPublisher, Publisher} from "@/Publisher";
+import ISubscriber from "@/Subscriber";
+import BeatLike from "@/BeatLike";
+import {isPosInt} from "@/utils";
export type BeatInitOptions = {
timeSig?: {
diff --git a/src/BeatGroup.ts b/src/BeatGroup.ts
index 5a10083..649f73c 100644
--- a/src/BeatGroup.ts
+++ b/src/BeatGroup.ts
@@ -1,8 +1,8 @@
-import Beat, {BeatEvents, BeatInitOptions} from "./Beat";
-import {IPublisher, Publisher} from "./Publisher";
-import ISubscriber from "./Subscriber";
-import BeatLike from "./BeatLike";
-import {greatestCommonDivisor, isPosInt} from "./utils";
+import Beat, {BeatEvents, BeatInitOptions} from "@/Beat";
+import {IPublisher, Publisher} from "@/Publisher";
+import ISubscriber from "@/Subscriber";
+import BeatLike from "@/BeatLike";
+import {greatestCommonDivisor, isPosInt} from "@/utils";
type BeatGroupInitOptions = {
barCount: number;
diff --git a/src/main.ts b/src/main.ts
index 41b0e55..896a5eb 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,6 +1,6 @@
-import BeatGroup from "./BeatGroup";
-import RootView from "./ui/Root/RootView";
-import "./ui/global.css";
+import BeatGroup from "@/BeatGroup";
+import RootView from "@/ui/Root/RootView";
+import "@/ui/global.css";
const defaultSettings = {
barCount: 2,
diff --git a/src/types.d.ts b/src/types.d.ts
new file mode 100644
index 0000000..bc39be9
--- /dev/null
+++ b/src/types.d.ts
@@ -0,0 +1,12 @@
+declare module "*.gif" {
+ const value: string;
+ export = value;
+}
+declare module "*.png" {
+ const value: string;
+ export = value;
+}
+declare module "*.svg" {
+ const value: string;
+ export = value;
+}
\ No newline at end of file
diff --git a/src/ui/BeatGroup/Beat/BeatUnit/BeatUnitView.ts b/src/ui/BeatGroup/Beat/BeatUnit/BeatUnitView.ts
index 627aa16..3753e70 100644
--- a/src/ui/BeatGroup/Beat/BeatUnit/BeatUnitView.ts
+++ b/src/ui/BeatGroup/Beat/BeatUnit/BeatUnitView.ts
@@ -1,7 +1,7 @@
-import BeatUnit, {BeatUnitEvents, BeatUnitType} from "../../../../BeatUnit";
-import ISubscriber from "../../../../Subscriber";
-import UINode, {UINodeOptions} from "../../../UINode";
-import {IPublisher, ISubscription, Publisher} from "../../../../Publisher";
+import BeatUnit, {BeatUnitEvents, BeatUnitType} from "@/BeatUnit";
+import ISubscriber from "@/Subscriber";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import {IPublisher, ISubscription, Publisher} from "@/Publisher";
import "./BeatUnit.css";
export type BeatUnitUINodeOptions = UINodeOptions & {
@@ -29,6 +29,12 @@ export default class BeatUnitView extends UINode implements ISubscriber {
private setupBindings() {
this.subscription?.unbind();
this.subscription = this.beatUnit.addSubscriber(this, "all");
+ this.onMouseUp((ev: MouseEvent) => {
+ if (ev.button === 1) {
+ const currentType = this.beatUnit.getType();
+ this.beatUnit.setType(currentType === BeatUnitType.GhostNote ? BeatUnitType.Normal : BeatUnitType.GhostNote);
+ }
+ });
}
toggle(): void {
@@ -59,22 +65,15 @@ export default class BeatUnitView extends UINode implements ISubscriber {
}
}
- rebuild(): HTMLElement {
+ build(): HTMLElement {
const classes = ["beat-unit"];
if (this.beatUnit.isOn()) {
classes.push("beat-unit-on");
}
- this.node = UINode.make("div", {
+ return UINode.make("div", {
classes: classes,
oncontextmenu: () => false,
});
- this.onMouseUp((ev: MouseEvent) => {
- if (ev.button === 1) {
- const currentType = this.beatUnit.getType();
- this.beatUnit.setType(currentType === BeatUnitType.GhostNote ? BeatUnitType.Normal : BeatUnitType.GhostNote);
- }
- });
- return this.node;
}
onHover(cb: () => void): void {
diff --git a/src/ui/BeatGroup/Beat/BeatView.ts b/src/ui/BeatGroup/Beat/BeatView.ts
index 8ef384e..d4fabcd 100644
--- a/src/ui/BeatGroup/Beat/BeatView.ts
+++ b/src/ui/BeatGroup/Beat/BeatView.ts
@@ -1,7 +1,7 @@
-import UINode, {UINodeOptions} from "../../UINode";
-import Beat, {BeatEvents} from "../../../Beat";
-import {IPublisher} from "../../../Publisher";
-import ISubscriber from "../../../Subscriber";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import Beat, {BeatEvents} from "@/Beat";
+import {IPublisher} from "@/Publisher";
+import ISubscriber from "@/Subscriber";
import BeatUnitView from "./BeatUnit/BeatUnitView";
import "./Beat.css";
@@ -129,7 +129,7 @@ export default class BeatView extends UINode implements ISubscriber {
this.respaceBeatUnits();
}
- rebuild(): HTMLElement {
+ build(): HTMLElement {
this.title = UINode.make("h3", {
innerText: this.beat.getName(),
classes: ["beat-title"],
@@ -138,7 +138,7 @@ export default class BeatView extends UINode implements ISubscriber {
if (!this.beatUnitViewBlock) {
throw new Error("Beat unit block setup failed!");
}
- this.node = UINode.make("div", {
+ return UINode.make("div", {
classes: ["beat"],
subs: [
UINode.make("div", {
@@ -150,7 +150,6 @@ export default class BeatView extends UINode implements ISubscriber {
}),
],
});
- return this.node;
}
}
diff --git a/src/ui/BeatGroup/BeatGroupView.ts b/src/ui/BeatGroup/BeatGroupView.ts
index 7a14ca5..acd6ad9 100644
--- a/src/ui/BeatGroup/BeatGroupView.ts
+++ b/src/ui/BeatGroup/BeatGroupView.ts
@@ -1,9 +1,9 @@
-import UINode, {UINodeOptions} from "../UINode";
-import BeatGroup, {BeatGroupEvents} from "../../BeatGroup";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import BeatGroup, {BeatGroupEvents} from "@/BeatGroup";
import BeatView from "./Beat/BeatView";
import "./BeatGroup.css";
-import ISubscriber from "../../Subscriber";
-import {IPublisher} from "../../Publisher";
+import ISubscriber from "@/Subscriber";
+import {IPublisher} from "@/Publisher";
export type BeatGroupUINodeOptions = UINodeOptions & {
title: string,
@@ -28,7 +28,7 @@ export default class BeatGroupView extends UINode implements ISubscriber {
}
}
- rebuild(): HTMLDivElement {
+ build(): HTMLDivElement {
this.beatViews = [];
for (let i = 0; i < this.beatGroup.getBeatCount(); i++) {
this.beatViews.push(new BeatView({beat: this.beatGroup.getBeatByIndex(i)}));
diff --git a/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts b/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts
index de18505..7c55e29 100644
--- a/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts
+++ b/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts
@@ -1,13 +1,13 @@
import "./BeatGroupSettings.css";
-import UINode, {UINodeOptions} from "../UINode";
-import NumberInputView from "../Widgets/NumberInput/NumberInputView";
-import ISubscriber from "../../Subscriber";
-import BeatGroup, {BeatGroupEvents} from "../../BeatGroup";
-import {IPublisher} from "../../Publisher";
-import {BeatEvents} from "../../Beat";
-import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
-import BeatSettingsView from "../BeatSettings/BeatSettingsView";
-import ActionButtonView from "../Widgets/ActionButton/ActionButtonView";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import NumberInputView from "@/ui/Widgets/NumberInput/NumberInputView";
+import ISubscriber from "@/Subscriber";
+import BeatGroup, {BeatGroupEvents} from "@/BeatGroup";
+import {IPublisher} from "@/Publisher";
+import {BeatEvents} from "@/Beat";
+import BoolBoxView from "@/ui/Widgets/BoolBox/BoolBoxView";
+import BeatSettingsView from "@/ui/BeatSettings/BeatSettingsView";
+import ActionButtonView from "@/ui/Widgets/ActionButton/ActionButtonView";
export type BeatGroupSettingsUINodeOptions = UINodeOptions & {
beatGroup: BeatGroup,
@@ -71,7 +71,7 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
}
}
- rebuild(): HTMLElement {
+ build(): HTMLElement {
this.barCountInput = new NumberInputView({
label: "Bars:",
initialValue: this.beatGroup.getBarCount(),
diff --git a/src/ui/BeatLikeLoopSettings/BeatLikeLoopSettingsView.ts b/src/ui/BeatLikeLoopSettings/BeatLikeLoopSettingsView.ts
index d1f1d17..f44467b 100644
--- a/src/ui/BeatLikeLoopSettings/BeatLikeLoopSettingsView.ts
+++ b/src/ui/BeatLikeLoopSettings/BeatLikeLoopSettingsView.ts
@@ -1,11 +1,11 @@
import "./BeatLikeLoopSettings.css";
-import BeatLike from "../../BeatLike";
-import NumberInputView from "../Widgets/NumberInput/NumberInputView";
-import ISubscriber from "../../Subscriber";
-import UINode, {UINodeOptions} from "../UINode";
-import {BeatEvents} from "../../Beat";
-import {IPublisher} from "../../Publisher";
-import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
+import BeatLike from "@/BeatLike";
+import NumberInputView from "@/ui/Widgets/NumberInput/NumberInputView";
+import ISubscriber from "@/Subscriber";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import {BeatEvents} from "@/Beat";
+import {IPublisher} from "@/Publisher";
+import BoolBoxView from "@/ui/Widgets/BoolBox/BoolBoxView";
export type BeatLikeLoopSettingsViewUINodeOptions = UINodeOptions & {
beatLike: BeatLike,
@@ -52,7 +52,7 @@ export default class BeatLikeLoopSettingsView extends UINode implements ISubscri
this.notify(null, BeatEvents.DisplayTypeChanged);
}
- rebuild(): HTMLElement {
+ build(): HTMLElement {
this.loopLengthInput = new NumberInputView({
initialValue: this.beatLike.getLoopLength(),
label: "Length:",
@@ -76,7 +76,7 @@ export default class BeatLikeLoopSettingsView extends UINode implements ISubscri
} else {
this.loopLengthSection.classList.add("hide");
}
- this.node = UINode.make("div", {
+ return UINode.make("div", {
classes: ["loop-settings"],
subs: [
UINode.make("p", {innerText: this.title}),
@@ -94,6 +94,5 @@ export default class BeatLikeLoopSettingsView extends UINode implements ISubscri
}),
]
});
- return this.node;
}
}
diff --git a/src/ui/BeatSettings/BeatSettingsView.ts b/src/ui/BeatSettings/BeatSettingsView.ts
index f317886..429233a 100644
--- a/src/ui/BeatSettings/BeatSettingsView.ts
+++ b/src/ui/BeatSettings/BeatSettingsView.ts
@@ -1,11 +1,11 @@
import "./BeatSettings.css";
-import Beat, {BeatEvents} from "../../Beat";
-import UINode, {UINodeOptions} from "../UINode";
-import ISubscriber from "../../Subscriber";
-import {IPublisher, ISubscription} from "../../Publisher";
-import NumberInputView from "../Widgets/NumberInput/NumberInputView";
-import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
-import ActionButtonView from "../Widgets/ActionButton/ActionButtonView";
+import Beat, {BeatEvents} from "@/Beat";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import ISubscriber from "@/Subscriber";
+import {IPublisher, ISubscription} from "@/Publisher";
+import NumberInputView from "@/ui/Widgets/NumberInput/NumberInputView";
+import BoolBoxView from "@/ui/Widgets/BoolBox/BoolBoxView";
+import ActionButtonView from "@/ui/Widgets/ActionButton/ActionButtonView";
export type BeatSettingsViewUINodeOptions = UINodeOptions & {
beat: Beat,
@@ -54,7 +54,7 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
}
}
- rebuild(): HTMLElement {
+ build(): HTMLElement {
this.nameInput = UINode.make("input", {
value: this.beat.getName(),
classes: ["beat-settings-name-field"],
@@ -62,7 +62,7 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
oninput: (event: Event) => this.beat.setName((event.target as HTMLInputElement).value),
});
this.deleteButton = new ActionButtonView({
- label: "Delete",
+ icon: "trash",
type: "secondary",
onClick: () => this.beat.delete(),
});
diff --git a/src/ui/Root/Root.css b/src/ui/Root/Root.css
index 84ba9d5..855cd22 100644
--- a/src/ui/Root/Root.css
+++ b/src/ui/Root/Root.css
@@ -64,28 +64,11 @@
left: 0;
}
-.root-hamburger {
+.root-hamburger, .root-switch-mode {
right: 0;
width: 2em;
height: 2em;
cursor: pointer;
- -webkit-mask-image: url(./drawing.svg);
- mask-image: url(./drawing.svg);
- -webkit-mask-size: 2em;
- mask-size: 2em;
- background-color: var(--color-ui-neutral-dark);
-}
-
-.root-switch-mode {
- right: 0;
- width: 2em;
- height: 2em;
- cursor: pointer;
- -webkit-mask-image: url(./rotate.svg);
- mask-image: url(./rotate.svg);
- -webkit-mask-size: 2em;
- mask-size: 2em;
- background-color: var(--color-ui-neutral-dark);
}
.root-beat-stage-container {
diff --git a/src/ui/Root/RootView.ts b/src/ui/Root/RootView.ts
index e67f233..54385c9 100644
--- a/src/ui/Root/RootView.ts
+++ b/src/ui/Root/RootView.ts
@@ -1,8 +1,9 @@
-import UINode, {UINodeOptions} from "../UINode";
-import BeatGroupView from "../BeatGroup/BeatGroupView";
-import BeatGroup from "../../BeatGroup";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import BeatGroupView from "@/ui/BeatGroup/BeatGroupView";
+import BeatGroup from "@/BeatGroup";
import "./Root.css";
-import BeatGroupSettingsView from "../BeatGroupSettings/BeatGroupSettingsView";
+import BeatGroupSettingsView from "@/ui/BeatGroupSettings/BeatGroupSettingsView";
+import IconView from "@/ui/Widgets/Icon/IconView";
export type RootUINodeOptions = UINodeOptions & {
title: string,
@@ -20,7 +21,7 @@ export default class RootView extends UINode {
constructor(options: RootUINodeOptions) {
super(options);
this.mainBeatGroup = options.mainBeatGroup;
- this.beatGroupView = new BeatGroupView({title: "THE BEAT", beatGroup: this.mainBeatGroup});
+ this.beatGroupView = new BeatGroupView({title: options.title, beatGroup: this.mainBeatGroup});
this.title = options.title;
}
@@ -32,7 +33,7 @@ export default class RootView extends UINode {
this.getNode().classList.toggle("vertical-mode");
}
- rebuild(): HTMLElement {
+ build(): HTMLElement {
this.beatGroupSettingsView = new BeatGroupSettingsView({beatGroup: this.mainBeatGroup});
const sidebarMain = UINode.make("div", {
classes: ["root-settings"],
@@ -41,15 +42,17 @@ export default class RootView extends UINode {
this.beatGroupSettingsView.render(),
]
});
- const sidebarToggle = UINode.make("div", {
+ const sidebarStrip = UINode.make("div", {
classes: ["root-sidebar-toggle"],
subs: [
UINode.make("div", {
classes: ["root-hamburger"],
+ subs: [new IconView({iconName: "list"}).render()],
onclick: () => this.toggleSidebar(),
}),
UINode.make("div", {
classes: ["root-switch-mode"],
+ subs: [new IconView({iconName: "arrowClockwise"}).render()],
onclick: () => this.toggleOrientation(),
})
]
@@ -58,10 +61,10 @@ export default class RootView extends UINode {
classes: ["root-sidebar"],
subs: [
sidebarMain,
- sidebarToggle,
+ sidebarStrip,
]
});
- this.node = UINode.make("div", {
+ return UINode.make("div", {
classes: ["root", "sidebar-visible"],
subs: [
this.sidebar,
@@ -78,6 +81,5 @@ export default class RootView extends UINode {
})
],
});
- return this.node;
}
}
\ No newline at end of file
diff --git a/src/ui/Root/drawing.svg b/src/ui/Root/drawing.svg
deleted file mode 100644
index 7401431..0000000
--- a/src/ui/Root/drawing.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
diff --git a/src/ui/Root/rotate.svg b/src/ui/Root/rotate.svg
deleted file mode 100644
index 6b63d57..0000000
--- a/src/ui/Root/rotate.svg
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
diff --git a/src/ui/UINode.ts b/src/ui/UINode.ts
index 3d72619..d8a4993 100644
--- a/src/ui/UINode.ts
+++ b/src/ui/UINode.ts
@@ -17,7 +17,7 @@ export default abstract class UINode {
render(): HTMLElement {
if (!this.node) {
- this.node = this.rebuild();
+ this.node = this.build();
}
return this.node;
}
@@ -37,12 +37,14 @@ export default abstract class UINode {
}
const parent = this.node.parentElement;
if (parent) {
- this.node = this.rebuild();
+ this.node = this.build();
parent.replaceChild(this.node, oldNode);
+ } else {
+ this.render();
}
}
- abstract rebuild(): HTMLElement;
+ protected abstract build(): HTMLElement;
static make<
T extends keyof HTMLElementTagNameMap,
@@ -64,4 +66,16 @@ export default abstract class UINode {
}
return element;
}
+
+ static q(text: string): Text {
+ return document.createTextNode(text);
+ }
+
+ static frag(subs?: Node[]): DocumentFragment {
+ const frag = document.createDocumentFragment();
+ if (subs) {
+ frag.append(...subs);
+ }
+ return frag;
+ }
}
\ No newline at end of file
diff --git a/src/ui/Widgets/ActionButton/ActionButtonView.ts b/src/ui/Widgets/ActionButton/ActionButtonView.ts
index b75c897..2c46678 100644
--- a/src/ui/Widgets/ActionButton/ActionButtonView.ts
+++ b/src/ui/Widgets/ActionButton/ActionButtonView.ts
@@ -1,39 +1,48 @@
import "./ActionButton.css";
-import UINode, {UINodeOptions} from "../../UINode";
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import IconView, {IconName} from "@/ui/Widgets/Icon/IconView";
export type ActionButtonUINodeOptions = UINodeOptions & {
- label: string,
type?: "primary" | "secondary",
onClick?: (isChecked: boolean) => void,
-};
+} & ({
+ icon: IconName,
+ label?: never,
+} | {
+ label: string,
+ icon?: never,
+});
export default class ActionButtonView extends UINode {
- private label: string | null;
+ private label: string | null = null;
+ private icon: IconName | null = null;
private buttonElement!: HTMLButtonElement;
private onClick: (isChecked: boolean) => void;
private type: "primary" | "secondary";
constructor(options: ActionButtonUINodeOptions) {
super(options);
- this.label = options.label ?? "";
+ if (typeof options.icon !== "undefined") {
+ this.icon = options.icon;
+ } else if (typeof options.label !== "undefined") {
+ this.label = options.label;
+ }
this.type = options.type ?? "primary";
this.onClick = options.onClick ?? (() => { /* dummy */ });
}
- setLabel(newLabel: string | null): void {
- if (newLabel !== null) {
- this.buttonElement.innerText = newLabel;
- } else {
- this.buttonElement.innerText = "";
- }
- }
-
- rebuild(): HTMLButtonElement {
+ protected build(): HTMLButtonElement {
this.buttonElement = UINode.make("button", {
classes: ["action-button", `action-button-${this.type}`],
- innerText: this.label ?? "",
onclick: this.onClick,
+ subs: [
+ this.icon !== null ? new IconView({
+ iconName: this.icon
+ }).render() : UINode.make("span", {
+ innerText: this.label ?? ""
+ }),
+ ],
});
return this.buttonElement;
}
-}
\ No newline at end of file
+}
diff --git a/src/ui/Widgets/BoolBox/BoolBoxView.ts b/src/ui/Widgets/BoolBox/BoolBoxView.ts
index 4f584f4..7f47b9d 100644
--- a/src/ui/Widgets/BoolBox/BoolBoxView.ts
+++ b/src/ui/Widgets/BoolBox/BoolBoxView.ts
@@ -1,5 +1,5 @@
import "./BoolBox.css";
-import UINode, {UINodeOptions} from "../../UINode";
+import UINode, {UINodeOptions} from "@/ui/UINode";
export type BoolBoxUINodeOptions = UINodeOptions & {
label?: string,
@@ -35,7 +35,7 @@ export default class BoolBoxView extends UINode {
this.checkboxElement.checked = isChecked;
}
- rebuild(): HTMLDivElement {
+ build(): HTMLDivElement {
this.labelElement = UINode.make("label", {
classes: ["bool-box-label"],
innerText: this.label ?? "",
diff --git a/src/ui/Widgets/Icon/Icon.css b/src/ui/Widgets/Icon/Icon.css
new file mode 100644
index 0000000..20f410b
--- /dev/null
+++ b/src/ui/Widgets/Icon/Icon.css
@@ -0,0 +1,8 @@
+.icon-view {
+ width: 2em;
+ height: 2em;
+ -webkit-mask-size: 2em;
+ mask-size: 2em;
+ display: inline-block;
+ background-color: black;
+}
\ No newline at end of file
diff --git a/src/ui/Widgets/Icon/IconView.ts b/src/ui/Widgets/Icon/IconView.ts
new file mode 100644
index 0000000..14c3c8f
--- /dev/null
+++ b/src/ui/Widgets/Icon/IconView.ts
@@ -0,0 +1,34 @@
+import UINode, {UINodeOptions} from "@/ui/UINode";
+import "./Icon.css";
+import List from "./svgs/list.svg";
+import ArrowClockwise from "./svgs/arrow-clockwise.svg";
+import Trash from "./svgs/trash.svg";
+
+const IconUrlMap = {
+ arrowClockwise: ArrowClockwise,
+ list: List,
+ trash: Trash,
+} as const;
+
+export type IconName = keyof typeof IconUrlMap;
+
+export type IconViewOptions = UINodeOptions & {
+ iconName: IconName,
+};
+
+export default class IconView extends UINode {
+ private iconUrl: string;
+
+ constructor(options: IconViewOptions) {
+ super(options);
+ this.iconUrl = IconUrlMap[options.iconName];
+ }
+
+ build(): HTMLSpanElement {
+ const icon = UINode.make("div", {
+ classes: ["icon-view"],
+ });
+ icon.style.cssText = `-webkit-mask-image: url(${this.iconUrl}); mask-image: url(${this.iconUrl});`;
+ return icon;
+ }
+}
\ No newline at end of file
diff --git a/src/ui/Widgets/Icon/svgs/arrow-clockwise.svg b/src/ui/Widgets/Icon/svgs/arrow-clockwise.svg
new file mode 100644
index 0000000..b072eb0
--- /dev/null
+++ b/src/ui/Widgets/Icon/svgs/arrow-clockwise.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/src/ui/Widgets/Icon/svgs/list.svg b/src/ui/Widgets/Icon/svgs/list.svg
new file mode 100644
index 0000000..e039056
--- /dev/null
+++ b/src/ui/Widgets/Icon/svgs/list.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/ui/Widgets/Icon/svgs/trash.svg b/src/ui/Widgets/Icon/svgs/trash.svg
new file mode 100644
index 0000000..e0e81f1
--- /dev/null
+++ b/src/ui/Widgets/Icon/svgs/trash.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/src/ui/Widgets/NumberInput/NumberInputView.ts b/src/ui/Widgets/NumberInput/NumberInputView.ts
index b555006..8edcb8d 100644
--- a/src/ui/Widgets/NumberInput/NumberInputView.ts
+++ b/src/ui/Widgets/NumberInput/NumberInputView.ts
@@ -1,4 +1,4 @@
-import UINode, { UINodeOptions } from "../../UINode";
+import UINode, { UINodeOptions } from "@/ui/UINode";
import "./NumberInput.css";
type NumberInputUINodeOptionsBase = UINodeOptions & {
@@ -27,7 +27,6 @@ export type NumberInputUINodeOptions = NumberInputUINodeOptionsGetSet | NumberIn
export default class NumberInputView extends UINode {
private labelElement!: HTMLLabelElement;
- private mainElement!: HTMLDivElement;
private inputElement!: HTMLInputElement;
private labelPosition: "top" | "left";
private value: number;
@@ -63,12 +62,12 @@ export default class NumberInputView extends UINode {
}
disable(): void {
- this.mainElement.classList.add("disabled");
+ this.node?.classList.add("disabled");
this.inputElement.disabled = true;
}
enable(): void {
- this.mainElement.classList.remove("disabled");
+ this.node?.classList.remove("disabled");
this.inputElement.disabled = false;
}
@@ -77,7 +76,7 @@ export default class NumberInputView extends UINode {
this.inputElement.valueAsNumber = value;
}
- rebuild(): HTMLDivElement {
+ build(): HTMLDivElement {
this.labelElement = UINode.make("label", {
classes: ["number-input-label", this.labelPosition],
innerText: this.label ?? "",
@@ -100,7 +99,7 @@ export default class NumberInputView extends UINode {
}
},
});
- this.mainElement = UINode.make("div", {
+ return UINode.make("div", {
classes: ["number-input"],
subs: [
this.labelElement,
@@ -129,6 +128,5 @@ export default class NumberInputView extends UINode {
}),
],
});
- return this.mainElement;
}
}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 87af555..de319fe 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,11 @@
"allowJs": true,
"strict": true,
"moduleResolution": "Node",
- "resolveJsonModule": true
+ "resolveJsonModule": true,
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
},
"include": ["./src/**/*"]
}
diff --git a/webpack.config.js b/webpack.config.js
index b45100e..e6c67f5 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -15,7 +15,7 @@ const webpackConfig = {
test: /\.(ts|tsx)$/,
loader: "ts-loader",
include: [path.resolve(__dirname, "src")],
- exclude: [/node_modules/]
+ exclude: [/node_modules/],
},
{
test: /.css$/,
@@ -30,18 +30,21 @@ const webpackConfig = {
}
}]
},
- // {
- // test: /\.(png|jpe?g|gif|ttf|woff2?|eot|svg)$/i,
- // use: [
- // {
- // loader: "file-loader",
- // },
- // ],
- // }
+ {
+ test: /\.(png|jpe?g|gif|ttf|woff2?|eot|svg)$/i,
+ use: [
+ {
+ loader: "file-loader",
+ },
+ ],
+ }
]
},
resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src"),
+ },
extensions: [".tsx", ".ts", ".js"]
},