import { h } from 'preact'; import { useState, useEffect } from 'preact/hooks'; import type { Widget, Interface } from './lib/types'; interface Props { selected: Widget | null; multiCount: number; iface: Interface; onChange: (updated: Widget) => void; onIfaceChange: (updated: Interface) => void; width?: number; } function Field({ label, children }: { label: string; children: any }) { return (
{children}
); } function TextInput({ value, onCommit }: { value: string; onCommit: (v: string) => void }) { const [local, setLocal] = useState(value || ''); // Sync when external value changes (e.g. different widget selected) useEffect(() => { setLocal(value || ''); }, [value]); return ( setLocal((e.target as HTMLInputElement).value)} onChange={(e) => onCommit((e.target as HTMLInputElement).value)} onKeyDown={(e) => { if (e.key === 'Enter') { onCommit((e.target as HTMLInputElement).value); (e.target as HTMLInputElement).blur(); } }} /> ); } // Widgets that show units from signal metadata (can be overridden) const UNIT_WIDGETS = new Set(['textview', 'gauge', 'barh', 'barv', 'setvalue']); // Widgets where the user can set a numeric format string const FORMAT_WIDGETS = new Set(['textview', 'gauge', 'barh', 'barv']); // Widgets with a signal-based label (can be overridden) const LABEL_WIDGETS = new Set(['textview', 'gauge', 'barh', 'barv', 'setvalue', 'led', 'multiled']); // Widgets with multiple signals const MULTI_SIGNAL_WIDGETS = new Set(['plot', 'multiled']); export default function PropertiesPane({ selected, multiCount, iface, onChange, onIfaceChange, width }: Props) { const [collapsed, setCollapsed] = useState(false); const [configSets, setConfigSets] = useState<{ id: string; name: string }[]>([]); // Config sets are only needed by the Config Selector widget; fetch lazily the // first time one is selected. useEffect(() => { if (selected?.type !== 'configselect' || configSets.length > 0) return; fetch('/api/v1/config/sets') .then(r => r.ok ? r.json() : []) .then((list: { id: string; name: string }[]) => setConfigSets(list ?? [])) .catch(() => {}); }, [selected?.type]); function setOpt(key: string, value: string) { if (!selected) return; onChange({ ...selected, options: { ...selected.options, [key]: value } }); } function setProp(key: keyof Widget, value: any) { if (!selected) return; onChange({ ...selected, [key]: value } as Widget); } function removeSignal(idx: number) { if (!selected) return; const signals = selected.signals.filter((_, i) => i !== idx); onChange({ ...selected, signals }); } const w = selected; return ( ); }