Luc UI / experiment 01
Design Lab
Three treatments of the same prepared observations and the same table-to-chart-to-inspector interaction. Use the Showcase theme and motion controls to compare states.
Precision Instrument
Calibrated hierarchy and instrument-like surfaces
Open treatment →02Editorial Research
Reading flow with the chart as evidence
Open treatment →03Focused Workspace
Linked selection, chart and inspector
Open treatment →Promoted recipe: linked data selection
The experiment's one reusable outcome. Three treatments disagreed about layout and agreed about behaviour, which is the signal that the behaviour — not a visual — is what the library should document. No new component or hook was added: the whole flow is three controlled props on primitives that already exist.
const [selectedId, setSelectedId] = useState<string | null>(null);
const selected = rows.find((row) => row.id === selectedId) ?? null;
<ChartInspectionProvider
groupId="transactions"
pinned={selected?.time.getTime() ?? null}
onPinnedChange={(time) =>
setSelectedId(rows.find((row) => row.time.getTime() === time)?.id ?? null)
}
>
{/* 1. the table owns selection… */}
<DataTable
data={rows}
columns={columns}
getRowId={(row) => row.id}
rowSelection={{ [selectedId ?? ""]: true }}
onRowSelectionChange={/* …map ids to one identity… */}
enableRowSelection="single"
ariaLabel="Observations"
/>
{/* 2. …the chart reads the same identity as a pinned point… */}
<LineChart spec={spec} />
{/* 3. …and the inspector shows the detail behind it. */}
<InspectorPane open={Boolean(selected)} title={selected?.sample}>
<InspectorRow label="Observed" value={`${selected?.responseMs} ms`} />
</InspectorPane>
</ChartInspectionProvider>ChartInspectionProvider— one identity shared by chart and inspector, controlled or uncontrolled.DataTable—rowSelection+onRowSelectionChange; the row is the source of the identity.InspectorPane— detail for the current identity, not a copy of the row.
Why this is a recipe and not an API
Promoted from screenshots to a gate as well: these four routes are now first-class entries in the Showcase's QA registry (qa/routes.mjs, group experiments, so the standard sweep — axe, light/dark, 1440/390 — covers them like any other page.