import type { ReactNode } from "react";
import { Card, CardAction, CardContent, CardHeader, CardTitle } from "./components/card";
import { Skeleton } from "./components/skeleton";
import { ToggleGroup, ToggleGroupItem } from "./components/toggle-group";
import type { Loaded } from "./lib/api";
import { cn } from "./lib/cn";
export function Panel({
title,
aside,
className,
children,
}: {
title?: string;
aside?: ReactNode;
className?: string;
children: ReactNode;
}) {
return (
{title && (
{title}
{aside && {aside}}
)}
{children}
);
}
export interface SegOption {
value: T;
label: string;
}
export function Seg({
options,
value,
onPick,
label,
}: {
options: readonly SegOption[];
value: T;
onPick: (next: T) => void;
label: string;
}) {
return (
next && onPick(next as T)}
>
{options.map((option) => (
{option.label}
))}
);
}
/**
* A screen whose frame stays put: the title and whatever toolbar it carries
* hold their place, and only `children` scrolls. Children are handed a region
* that is already the right height, so a table inside it scrolls its own rows
* rather than the window.
*/
export function Screen({
title,
aside,
toolbar,
children,
}: {
title: string;
aside?: ReactNode;
toolbar?: ReactNode;
children: ReactNode;
}) {
return (
{title}
{aside}
{toolbar}
{children}
);
}
/** The scroll region itself — one per screen, and the only thing that moves. */
export function Scroller({
className,
children,
}: {
className?: string;
children: ReactNode;
}) {
return {children}
;
}
export function Pending({ value }: { value: Loaded }) {
if (value.state === "loading")
return (
reading
);
if (value.state === "error")
return (
{value.message}
);
return null;
}
export function Empty({ children }: { children: ReactNode }) {
return {children}
;
}