Files
byre/web/src/panes.ts
T
2026-10-14 19:35:34 -07:00

58 lines
1.8 KiB
TypeScript

import { mountChanges } from "./changes.js";
import { h, replace } from "./dom.js";
import { mountInbox } from "./inbox.js";
import { mountTranscript } from "./task.js";
import { mountTasks } from "./tasks.js";
export type View = "transcript" | "changes" | "tasks" | "inbox";
const views: Record<View, { label: string; mount: (root: HTMLElement) => () => void }> = {
transcript: { label: "Transcript", mount: mountTranscript },
changes: { label: "Changes", mount: (root) => mountChanges(root) },
tasks: { label: "Tasks", mount: mountTasks },
inbox: { label: "Inbox", mount: mountInbox },
};
const order: View[] = ["transcript", "changes", "tasks", "inbox"];
export class Pane {
readonly el: HTMLElement;
private readonly tabs: HTMLElement;
private readonly body: HTMLElement;
private view: View;
private dispose: () => void = () => {};
constructor(private readonly key: string, fallback: View) {
this.tabs = h("nav", { class: "pane-tabs" });
this.body = h("div", { class: "pane-body" });
this.el = h("section", { class: "pane" }, this.tabs, this.body);
const saved = localStorage.getItem(this.storageKey()) as View | null;
this.view = saved && saved in views ? saved : fallback;
this.show(this.view);
}
show(view: View): void {
this.dispose();
this.view = view;
localStorage.setItem(this.storageKey(), view);
replace(
this.tabs,
...order.map((v) => {
const b = h("button", { class: v === view ? "active" : "" }, views[v].label);
b.onclick = () => this.show(v);
return b;
}),
);
const root = h("div", { class: `view view-${view}` });
replace(this.body, root);
this.dispose = views[view].mount(root);
}
private storageKey(): string {
return `byre.pane.${this.key}`;
}
}