Add the theme cycler component.
This commit is contained in:
parent
548984a6df
commit
6e275916a0
|
@ -0,0 +1,12 @@
|
|||
.tish-theme-cycler {
|
||||
align-items: center;
|
||||
border: 1px solid var(--button-color);
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-bottom: 0.4rem;
|
||||
padding: 4px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
@use "shepherd-defaults";
|
||||
@use "shepherd-custom";
|
||||
@use "components/theme-cycler";
|
||||
|
||||
[data-tildes-shepherd-counter] {
|
||||
position: relative;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export * from "./theme-cycler.js";
|
|
@ -0,0 +1,115 @@
|
|||
import {Component} from "preact";
|
||||
|
||||
type Props = Record<string, unknown>;
|
||||
|
||||
type State = {
|
||||
delayIndex: number;
|
||||
intervalId: number | undefined;
|
||||
};
|
||||
|
||||
export class ThemeCycler extends Component<Props, State> {
|
||||
delayValues: number[] = [100, 250, 500, 1000, 2500, 5000, 10_000];
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
delayIndex: 4,
|
||||
intervalId: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
cycle = () => {
|
||||
const themeSelect =
|
||||
document.querySelector<HTMLSelectElement>("#theme") ?? undefined;
|
||||
if (themeSelect === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const themeOptions = Array.from(themeSelect.options);
|
||||
const nextIndex = themeOptions.findIndex((option) => option.selected) + 1;
|
||||
|
||||
themeSelect.selectedIndex =
|
||||
// If the next option can't be found, we're at the end so start back at zero.
|
||||
themeOptions[nextIndex] === undefined ? 0 : nextIndex;
|
||||
|
||||
// Emit a change event so the Tildes JS handles changing the theme.
|
||||
themeSelect.dispatchEvent(new Event("change"));
|
||||
};
|
||||
|
||||
decreaseDelay = () => {
|
||||
const {delayIndex, intervalId} = this.state;
|
||||
if (delayIndex <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({delayIndex: delayIndex - 1}, () => {
|
||||
if (intervalId !== undefined) {
|
||||
this.startInterval();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
increaseDelay = () => {
|
||||
const {delayIndex, intervalId} = this.state;
|
||||
if (delayIndex >= this.delayValues.length - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({delayIndex: delayIndex + 1}, () => {
|
||||
if (intervalId !== undefined) {
|
||||
this.startInterval();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
startInterval = () => {
|
||||
const {delayIndex, intervalId} = this.state;
|
||||
if (intervalId !== undefined) {
|
||||
window.clearInterval(intervalId);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
intervalId: window.setInterval(this.cycle, this.delayValues[delayIndex]),
|
||||
});
|
||||
};
|
||||
|
||||
toggle = () => {
|
||||
const {intervalId} = this.state;
|
||||
if (intervalId === undefined) {
|
||||
this.startInterval();
|
||||
this.cycle();
|
||||
} else {
|
||||
window.clearInterval(intervalId);
|
||||
this.setState({intervalId: undefined});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const isEnabled = this.state.intervalId !== undefined;
|
||||
const delay = this.delayValues[this.state.delayIndex];
|
||||
|
||||
return (
|
||||
<div class="tish-theme-cycler">
|
||||
<p>Theme Cycler ({delay / 1000}s)</p>
|
||||
<button class="btn btn-sm" title="Toggle cycling" onClick={this.toggle}>
|
||||
{isEnabled ? "Stop" : "Start"}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
title="Decrease delay between changes"
|
||||
onClick={this.decreaseDelay}
|
||||
>
|
||||
Faster
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
title="Increase delay between changes"
|
||||
onClick={this.increaseDelay}
|
||||
>
|
||||
Slower
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue