diff --git a/public/index.html b/public/index.html
index 436a822..134bbfe 100644
--- a/public/index.html
+++ b/public/index.html
@@ -7,7 +7,6 @@
Drum Slayer
-
diff --git a/src/ui/BeatGroup/Beat/BeatUnit/BeatUnit.css b/src/ui/BeatGroup/Beat/BeatUnit/BeatUnit.css
index 62b4a2d..5ba6096 100644
--- a/src/ui/BeatGroup/Beat/BeatUnit/BeatUnit.css
+++ b/src/ui/BeatGroup/Beat/BeatUnit/BeatUnit.css
@@ -27,8 +27,8 @@
}
.beat-unit.beat-unit-on {
- background-color: var(--color-ui-accent-light);
- border-color: var(--color-ui-neutral-light);
+ background-color: var(--color-ui-accent);
+ border-color: var(--color-ui-accent);
transition: none;
}
diff --git a/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts b/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts
index ba6e216..7952c2e 100644
--- a/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts
+++ b/src/ui/BeatGroupSettings/BeatGroupSettingsView.ts
@@ -7,6 +7,7 @@ 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";
export type BeatGroupSettingsUINodeOptions = UINodeOptions & {
beatGroup: BeatGroup,
@@ -89,7 +90,7 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
onInput: (isChecked: boolean) => this.beatGroup.setIsUsingAutoBeatLength(isChecked),
});
this.remakeBeatSettingsViews();
- this.node = UINode.make("div", {
+ return UINode.make("div", {
classes: ["beat-group-settings"],
subs: [
UINode.make("div", {
@@ -114,14 +115,13 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
],
}),
this.beatSettingsContainer,
- UINode.make("button", {
- innerText: "New Track",
- onclick: () => this.beatGroup.addBeat(),
- }),
+ new ActionButtonView({
+ label: "New Track",
+ onClick: () => this.beatGroup.addBeat(),
+ }).render(),
],
}),
],
});
- return this.node;
}
}
\ No newline at end of file
diff --git a/src/ui/BeatSettings/BeatSettingsView.ts b/src/ui/BeatSettings/BeatSettingsView.ts
index 67e3535..a68912c 100644
--- a/src/ui/BeatSettings/BeatSettingsView.ts
+++ b/src/ui/BeatSettings/BeatSettingsView.ts
@@ -2,11 +2,10 @@ import "./BeatSettings.css";
import Beat, {BeatEvents} from "../../Beat";
import UINode, {UINodeOptions} from "../UINode";
import ISubscriber from "../../Subscriber";
-import BeatLikeLoopSettingsView from "../BeatLikeLoopSettings/BeatLikeLoopSettingsView";
import {IPublisher} from "../../Publisher";
-import BeatLike from "../../BeatLike";
import NumberInputView from "../Widgets/NumberInput/NumberInputView";
import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
+import ActionButtonView from "../Widgets/ActionButton/ActionButtonView";
export type BeatSettingsViewUINodeOptions = UINodeOptions & {
beat: Beat,
@@ -15,7 +14,7 @@ export type BeatSettingsViewUINodeOptions = UINodeOptions & {
export default class BeatSettingsView extends UINode implements ISubscriber {
private beat: Beat;
private nameInput!: HTMLInputElement;
- private deleteButton!: HTMLButtonElement;
+ private deleteButton!: ActionButtonView;
private loopLengthInput!: NumberInputView;
private loopCheckbox!: BoolBoxView;
private loopLengthSection!: HTMLDivElement;
@@ -62,10 +61,10 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
type: "text",
oninput: (event: Event) => this.beat.setName((event.target as HTMLInputElement).value),
});
- this.deleteButton = UINode.make("button", {
- classes: ["beat-settings-delete"],
- innerText: "Delete",
- onclick: () => this.beat.delete(),
+ this.deleteButton = new ActionButtonView({
+ label: "Delete",
+ type: "secondary",
+ onClick: () => this.beat.delete(),
});
this.loopLengthInput = new NumberInputView({
initialValue: this.beat.getLoopLength(),
@@ -89,7 +88,7 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
} else {
this.loopLengthSection.classList.add("hide");
}
- this.node = UINode.make("div", {
+ return UINode.make("div", {
classes: ["beat-settings"],
subs: [
this.nameInput,
@@ -100,9 +99,8 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
]
}),
this.loopLengthSection,
- this.deleteButton,
+ this.deleteButton.render(),
],
});
- return this.node;
}
}
diff --git a/src/ui/Root/Root.css b/src/ui/Root/Root.css
index e365837..326c14f 100644
--- a/src/ui/Root/Root.css
+++ b/src/ui/Root/Root.css
@@ -1,13 +1,21 @@
:root {
- --color-ui-accent-light: #07afb6;
- --color-ui-accent-dark: #00888b;
+ --color-ui-accent: #00b3ba;
+ --color-ui-accent-hover: #00c1c9;
+ --color-ui-accent-active: #008e93;
--color-ui-neutral-light: #fdfdfe;
+ --color-ui-neutral-light-hover: #fdfdfe;
+ --color-ui-neutral-light-active: #fdfdfe;
--color-ui-neutral-dark: #8b8b8b;
--color-ui-neutral-dark-hover: #a1a1a1;
+ --color-ui-neutral-dark-active: #c1c1c1;
--color-bg-light: #464646;
--color-bg-dark: #282828;
--color-p-light: #fafafa;
+ --color-p-light-hover: #fafafa;
+ --color-p-light-active: #fafafa;
--color-p-dark: #282828;
+ --color-p-dark-hover: #464646;
+ --color-p-dark-active: #464646;
--color-title-light: #fafafa;
--color-title-dark: #282828;
}
diff --git a/src/ui/Widgets/ActionButton/ActionButton.css b/src/ui/Widgets/ActionButton/ActionButton.css
new file mode 100644
index 0000000..bf7190c
--- /dev/null
+++ b/src/ui/Widgets/ActionButton/ActionButton.css
@@ -0,0 +1,36 @@
+.action-button {
+ border-radius: 0.5em;
+ margin: 0.5em;
+ cursor: pointer;
+ border: none;
+}
+
+.action-button.action-button-primary {
+ background-color: var(--color-ui-accent);
+ color: var(--color-p-light);
+}
+
+.action-button.action-button-primary:hover {
+ background-color: var(--color-ui-accent-hover);
+ color: var(--color-p-light-hover);
+}
+
+.action-button.action-button-primary:active {
+ background-color: var(--color-ui-accent-active);
+ color: var(--color-p-light-active);
+}
+
+.action-button.action-button-secondary {
+ background-color: var(--color-ui-neutral-dark);
+ color: var(--color-p-light);
+}
+
+.action-button.action-button-secondary:hover {
+ background-color: var(--color-ui-neutral-dark-hover);
+ color: var(--color-p-light-hover);
+}
+
+.action-button.action-button-secondary:active {
+ background-color: var(--color-ui-neutral-dark-active);
+ color: var(--color-p-light-active);
+}
diff --git a/src/ui/Widgets/ActionButton/ActionButtonView.ts b/src/ui/Widgets/ActionButton/ActionButtonView.ts
new file mode 100644
index 0000000..b75c897
--- /dev/null
+++ b/src/ui/Widgets/ActionButton/ActionButtonView.ts
@@ -0,0 +1,39 @@
+import "./ActionButton.css";
+import UINode, {UINodeOptions} from "../../UINode";
+
+export type ActionButtonUINodeOptions = UINodeOptions & {
+ label: string,
+ type?: "primary" | "secondary",
+ onClick?: (isChecked: boolean) => void,
+};
+
+export default class ActionButtonView extends UINode {
+ private label: string | null;
+ private buttonElement!: HTMLButtonElement;
+ private onClick: (isChecked: boolean) => void;
+ private type: "primary" | "secondary";
+
+ constructor(options: ActionButtonUINodeOptions) {
+ super(options);
+ 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 {
+ this.buttonElement = UINode.make("button", {
+ classes: ["action-button", `action-button-${this.type}`],
+ innerText: this.label ?? "",
+ onclick: this.onClick,
+ });
+ return this.buttonElement;
+ }
+}
\ No newline at end of file
diff --git a/src/ui/Widgets/BoolBox/BoolBox.css b/src/ui/Widgets/BoolBox/BoolBox.css
index 0c51e54..cf134cd 100644
--- a/src/ui/Widgets/BoolBox/BoolBox.css
+++ b/src/ui/Widgets/BoolBox/BoolBox.css
@@ -29,7 +29,7 @@ input.bool-box-checkbox[type="checkbox"]::before {
width: 2em;
height: 1em;
border-radius: 1em;
- background-color: var(--color-ui-accent-dark);
+ background-color: var(--color-ui-accent-active);
display: inline-block;
content: "";
z-index: 0;
@@ -38,7 +38,7 @@ input.bool-box-checkbox[type="checkbox"]::before {
}
input.bool-box-checkbox[type="checkbox"]:checked::before {
- background-color: var(--color-ui-accent-light);
+ background-color: var(--color-ui-accent);
}
input.bool-box-checkbox[type="checkbox"]::after {
diff --git a/src/ui/Widgets/NumberInput/NumberInput.css b/src/ui/Widgets/NumberInput/NumberInput.css
index cda6b5c..ec172e9 100644
--- a/src/ui/Widgets/NumberInput/NumberInput.css
+++ b/src/ui/Widgets/NumberInput/NumberInput.css
@@ -1,5 +1,6 @@
.number-input {
text-align: center;
+ white-space: nowrap;
}
.number-input-label {
@@ -17,6 +18,7 @@
}
input[type="number"].number-input-input {
+ position: relative;
-webkit-appearance: textfield;
-moz-appearance: textfield;
text-align: center;
@@ -25,7 +27,8 @@ input[type="number"].number-input-input {
border-width: 0;
border-radius: 0;
background-color: var(--color-ui-neutral-light);
- color: var(--color-p-dark)
+ color: var(--color-p-dark);
+ z-index: 1;
}
input[type="number"].number-input-input::-webkit-inner-spin-button,
@@ -39,9 +42,13 @@ input[type="number"].number-input-input::-webkit-outer-spin-button {
color: var(--color-ui-neutral-light);
cursor: pointer;
}
-
.number-input-button:hover {
background-color: var(--color-ui-neutral-dark-hover);
+ color: var(--color-ui-neutral-light-hover);
+}
+.number-input-button:active {
+ background-color: var(--color-ui-neutral-dark-active);
+ color: var(--color-ui-neutral-light-active);
}
.number-input-inc {