freshened up some ui, added styled buttons
This commit is contained in:
@@ -7,7 +7,6 @@
|
|||||||
<title>Drum Slayer</title>
|
<title>Drum Slayer</title>
|
||||||
|
|
||||||
<link rel='icon' type='image/png' href='./favicon.png'>
|
<link rel='icon' type='image/png' href='./favicon.png'>
|
||||||
<link rel='stylesheet' href='./global.css'>
|
|
||||||
|
|
||||||
<script defer src='static/bundle.js'></script>
|
<script defer src='static/bundle.js'></script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.beat-unit.beat-unit-on {
|
.beat-unit.beat-unit-on {
|
||||||
background-color: var(--color-ui-accent-light);
|
background-color: var(--color-ui-accent);
|
||||||
border-color: var(--color-ui-neutral-light);
|
border-color: var(--color-ui-accent);
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {IPublisher} from "../../Publisher";
|
|||||||
import {BeatEvents} from "../../Beat";
|
import {BeatEvents} from "../../Beat";
|
||||||
import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
|
import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
|
||||||
import BeatSettingsView from "../BeatSettings/BeatSettingsView";
|
import BeatSettingsView from "../BeatSettings/BeatSettingsView";
|
||||||
|
import ActionButtonView from "../Widgets/ActionButton/ActionButtonView";
|
||||||
|
|
||||||
export type BeatGroupSettingsUINodeOptions = UINodeOptions & {
|
export type BeatGroupSettingsUINodeOptions = UINodeOptions & {
|
||||||
beatGroup: BeatGroup,
|
beatGroup: BeatGroup,
|
||||||
@@ -89,7 +90,7 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
|
|||||||
onInput: (isChecked: boolean) => this.beatGroup.setIsUsingAutoBeatLength(isChecked),
|
onInput: (isChecked: boolean) => this.beatGroup.setIsUsingAutoBeatLength(isChecked),
|
||||||
});
|
});
|
||||||
this.remakeBeatSettingsViews();
|
this.remakeBeatSettingsViews();
|
||||||
this.node = UINode.make("div", {
|
return UINode.make("div", {
|
||||||
classes: ["beat-group-settings"],
|
classes: ["beat-group-settings"],
|
||||||
subs: [
|
subs: [
|
||||||
UINode.make("div", {
|
UINode.make("div", {
|
||||||
@@ -114,14 +115,13 @@ export default class BeatGroupSettingsView extends UINode implements ISubscriber
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
this.beatSettingsContainer,
|
this.beatSettingsContainer,
|
||||||
UINode.make("button", {
|
new ActionButtonView({
|
||||||
innerText: "New Track",
|
label: "New Track",
|
||||||
onclick: () => this.beatGroup.addBeat(),
|
onClick: () => this.beatGroup.addBeat(),
|
||||||
}),
|
}).render(),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
return this.node;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,10 @@ import "./BeatSettings.css";
|
|||||||
import Beat, {BeatEvents} from "../../Beat";
|
import Beat, {BeatEvents} from "../../Beat";
|
||||||
import UINode, {UINodeOptions} from "../UINode";
|
import UINode, {UINodeOptions} from "../UINode";
|
||||||
import ISubscriber from "../../Subscriber";
|
import ISubscriber from "../../Subscriber";
|
||||||
import BeatLikeLoopSettingsView from "../BeatLikeLoopSettings/BeatLikeLoopSettingsView";
|
|
||||||
import {IPublisher} from "../../Publisher";
|
import {IPublisher} from "../../Publisher";
|
||||||
import BeatLike from "../../BeatLike";
|
|
||||||
import NumberInputView from "../Widgets/NumberInput/NumberInputView";
|
import NumberInputView from "../Widgets/NumberInput/NumberInputView";
|
||||||
import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
|
import BoolBoxView from "../Widgets/BoolBox/BoolBoxView";
|
||||||
|
import ActionButtonView from "../Widgets/ActionButton/ActionButtonView";
|
||||||
|
|
||||||
export type BeatSettingsViewUINodeOptions = UINodeOptions & {
|
export type BeatSettingsViewUINodeOptions = UINodeOptions & {
|
||||||
beat: Beat,
|
beat: Beat,
|
||||||
@@ -15,7 +14,7 @@ export type BeatSettingsViewUINodeOptions = UINodeOptions & {
|
|||||||
export default class BeatSettingsView extends UINode implements ISubscriber {
|
export default class BeatSettingsView extends UINode implements ISubscriber {
|
||||||
private beat: Beat;
|
private beat: Beat;
|
||||||
private nameInput!: HTMLInputElement;
|
private nameInput!: HTMLInputElement;
|
||||||
private deleteButton!: HTMLButtonElement;
|
private deleteButton!: ActionButtonView;
|
||||||
private loopLengthInput!: NumberInputView;
|
private loopLengthInput!: NumberInputView;
|
||||||
private loopCheckbox!: BoolBoxView;
|
private loopCheckbox!: BoolBoxView;
|
||||||
private loopLengthSection!: HTMLDivElement;
|
private loopLengthSection!: HTMLDivElement;
|
||||||
@@ -62,10 +61,10 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
|
|||||||
type: "text",
|
type: "text",
|
||||||
oninput: (event: Event) => this.beat.setName((event.target as HTMLInputElement).value),
|
oninput: (event: Event) => this.beat.setName((event.target as HTMLInputElement).value),
|
||||||
});
|
});
|
||||||
this.deleteButton = UINode.make("button", {
|
this.deleteButton = new ActionButtonView({
|
||||||
classes: ["beat-settings-delete"],
|
label: "Delete",
|
||||||
innerText: "Delete",
|
type: "secondary",
|
||||||
onclick: () => this.beat.delete(),
|
onClick: () => this.beat.delete(),
|
||||||
});
|
});
|
||||||
this.loopLengthInput = new NumberInputView({
|
this.loopLengthInput = new NumberInputView({
|
||||||
initialValue: this.beat.getLoopLength(),
|
initialValue: this.beat.getLoopLength(),
|
||||||
@@ -89,7 +88,7 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
|
|||||||
} else {
|
} else {
|
||||||
this.loopLengthSection.classList.add("hide");
|
this.loopLengthSection.classList.add("hide");
|
||||||
}
|
}
|
||||||
this.node = UINode.make("div", {
|
return UINode.make("div", {
|
||||||
classes: ["beat-settings"],
|
classes: ["beat-settings"],
|
||||||
subs: [
|
subs: [
|
||||||
this.nameInput,
|
this.nameInput,
|
||||||
@@ -100,9 +99,8 @@ export default class BeatSettingsView extends UINode implements ISubscriber {
|
|||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
this.loopLengthSection,
|
this.loopLengthSection,
|
||||||
this.deleteButton,
|
this.deleteButton.render(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
return this.node;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
:root {
|
:root {
|
||||||
--color-ui-accent-light: #07afb6;
|
--color-ui-accent: #00b3ba;
|
||||||
--color-ui-accent-dark: #00888b;
|
--color-ui-accent-hover: #00c1c9;
|
||||||
|
--color-ui-accent-active: #008e93;
|
||||||
--color-ui-neutral-light: #fdfdfe;
|
--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: #8b8b8b;
|
||||||
--color-ui-neutral-dark-hover: #a1a1a1;
|
--color-ui-neutral-dark-hover: #a1a1a1;
|
||||||
|
--color-ui-neutral-dark-active: #c1c1c1;
|
||||||
--color-bg-light: #464646;
|
--color-bg-light: #464646;
|
||||||
--color-bg-dark: #282828;
|
--color-bg-dark: #282828;
|
||||||
--color-p-light: #fafafa;
|
--color-p-light: #fafafa;
|
||||||
|
--color-p-light-hover: #fafafa;
|
||||||
|
--color-p-light-active: #fafafa;
|
||||||
--color-p-dark: #282828;
|
--color-p-dark: #282828;
|
||||||
|
--color-p-dark-hover: #464646;
|
||||||
|
--color-p-dark-active: #464646;
|
||||||
--color-title-light: #fafafa;
|
--color-title-light: #fafafa;
|
||||||
--color-title-dark: #282828;
|
--color-title-dark: #282828;
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/ui/Widgets/ActionButton/ActionButton.css
Normal file
36
src/ui/Widgets/ActionButton/ActionButton.css
Normal file
@@ -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);
|
||||||
|
}
|
||||||
39
src/ui/Widgets/ActionButton/ActionButtonView.ts
Normal file
39
src/ui/Widgets/ActionButton/ActionButtonView.ts
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,7 @@ input.bool-box-checkbox[type="checkbox"]::before {
|
|||||||
width: 2em;
|
width: 2em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background-color: var(--color-ui-accent-dark);
|
background-color: var(--color-ui-accent-active);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
content: "";
|
content: "";
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
@@ -38,7 +38,7 @@ input.bool-box-checkbox[type="checkbox"]::before {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input.bool-box-checkbox[type="checkbox"]:checked::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 {
|
input.bool-box-checkbox[type="checkbox"]::after {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
.number-input {
|
.number-input {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.number-input-label {
|
.number-input-label {
|
||||||
@@ -17,6 +18,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type="number"].number-input-input {
|
input[type="number"].number-input-input {
|
||||||
|
position: relative;
|
||||||
-webkit-appearance: textfield;
|
-webkit-appearance: textfield;
|
||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -25,7 +27,8 @@ input[type="number"].number-input-input {
|
|||||||
border-width: 0;
|
border-width: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: var(--color-ui-neutral-light);
|
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,
|
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);
|
color: var(--color-ui-neutral-light);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.number-input-button:hover {
|
.number-input-button:hover {
|
||||||
background-color: var(--color-ui-neutral-dark-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 {
|
.number-input-inc {
|
||||||
|
|||||||
Reference in New Issue
Block a user