import type { ParamSpec } from "@/lib/api"; import InfoTip from "@/components/InfoTip"; type Props = { specs: ParamSpec[]; values: Record; onChange: (next: Record) => void; }; function ParamLabel({ id, label, help }: { id: string; label: string; help?: string }) { return ( {help && } ); } function renderControl( s: ParamSpec, values: Record, set: (name: string, v: unknown) => void, ) { const id = `param-${s.name}`; const current: unknown = values[s.name] ?? s.default; if (s.name === "seed") { const v = (values[s.name] ?? s.default) as number; return (
set(s.name, Number(e.target.value))} className="field-input !w-40 sm:!w-44 font-mono text-[12px] py-1" /> {v === -1 && ( (random per generate) )}
); } if (s.type === "float" || s.type === "int") { const n = typeof current === "number" ? current : Number(current); return (
{Number.isFinite(n) ? n.toFixed(2) : String(current)}
set(s.name, Number(e.target.value))} className="w-full accent-[hsl(var(--ember))]" />
); } if (s.type === "bool") { return (
set(s.name, e.target.checked)} className="accent-[hsl(var(--ember))]" />
); } return (
); } export default function ParamsPanel({ specs, values, onChange }: Props) { function set(name: string, v: unknown) { onChange({ ...values, [name]: v }); } const basic = specs.filter((s) => (s.group ?? "basic") === "basic"); const advanced = specs.filter((s) => s.group === "advanced"); return (
{basic.map((s) => renderControl(s, values, set))} {advanced.length > 0 && (
advanced · {advanced.length} params
{advanced.map((s) => renderControl(s, values, set))}
)}
); }