1
Fork 0

Add the theme cycler component.

This commit is contained in:
Bauke 2023-07-22 17:31:52 +02:00
parent 548984a6df
commit 6e275916a0
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
4 changed files with 129 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -1,5 +1,6 @@
@use "shepherd-defaults";
@use "shepherd-custom";
@use "components/theme-cycler";
[data-tildes-shepherd-counter] {
position: relative;

View File

@ -0,0 +1 @@
export * from "./theme-cycler.js";

View File

@ -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>
);
}
}