freshened up some ui, added styled buttons
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
<title>Drum Slayer</title>
|
||||
|
||||
<link rel='icon' type='image/png' href='./favicon.png'>
|
||||
<link rel='stylesheet' href='./global.css'>
|
||||
|
||||
<script defer src='static/bundle.js'></script>
|
||||
</head>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user