Example: Components Table Widget
Source project: octopus-widgets/ska-octopus-components-table-widget
Why This Example Matters
It combines:
Rich schema shortcuts (
INPUT_DEVICES,INPUT_ATTRIBUTES,INPUT_STRINGS)Table interaction persistence (order, widths, sort)
Live stream + polling behavior switch
Brush filtering and hover value mapping
Definition Pattern
In src/index.ts, the widget:
Defines a single schema with both user and persisted table settings
Uses
polls: trueto participate in refresh behaviorExposes a stable
keyanddocsUrl
Snippet adapted from src/index.ts:
const schema = {
type: "object",
properties: {
devices: {
type: INPUT_DEVICES,
title: "Devices (rows)",
minItems: 1,
default: [{ endpoint: "", device: "low-mccs/tile/s8-1-tpm01" }],
},
attributes: {
type: INPUT_ATTRIBUTES,
title: "Attributes (columns)",
default: ["Status", "State", "HealthState"],
},
columnOrder: { type: "array", default: [] },
columnWidths: { type: "object", default: {} },
sortKey: { type: "string", default: "__component__" },
sortDir: { type: "string", enum: ["asc", "desc"], default: "asc" },
},
} as const;
Runtime Pattern
In src/ComponentsTableWidget.tsx, the widget:
Normalizes input devices once using variables
Reads host layout with
useWidgetLayout(instanceId)Persists user table interactions with
useWidgetConfigPersistence(instanceId)Applies brush filtering via
useBrush
Snippet adapted from src/ComponentsTableWidget.tsx:
const { persistConfig } = useWidgetConfigPersistence(instanceId);
const handleColumnOrderChange = (nextOrder: string[]) => {
persistConfig({ columnOrder: nextOrder });
};
const handleSortChange = (next: { key: string; dir: "asc" | "desc" }) => {
persistConfig({ sortKey: next.key, sortDir: next.dir });
};
Table Rendering Pattern
In src/components/ComponentsTable.tsx, the widget:
Uses
useInteractiveTableStateas the state engineUses
InteractiveTableas the rendering layerUses
StateChipfor enum-like valuesComputes responsive width fitting before first user resize
What To Reuse In New Widgets
Schema-first configuration approach from
src/index.tsPersistence callbacks from
src/ComponentsTableWidget.tsxShared table toolkit integration from
src/components/ComponentsTable.tsx
Related docs: