# common/ui — reference > Generated from `common/ui/src` by `make reference` in common/ui (`python3 -m common.slice reference`). > Do not edit this page: the next build replaces it. Prose goes in `soleprint/common/ui/notes/.md`, > and `make reference-spots` lists every spot. ## What this is A panel framework, not a dashboard: boxes with a title and a status light, splits that resize, a feed that pushes typed events, and renderers for what arrives. It was built for high-frequency operational views — a minimal Grafana — and every piece below exists because an app needed it. **The contract is the framework; Vue is one binding of it.** The contract is four things: the token names, the element layer (`base.css`), the class names (`.panel`, `.panel-header`, `.split-pane`, …) and the status words. Those are not whole yet: a feed reports `idle`, `connecting`, `live`, `error`, while the panel's dot shows `idle`, `live`, `processing`, `error` — so `connecting` has no dot, and a consumer has to map it by hand. That is a gap in the contract, listed below. `common/theme/parts` is the second binding: the same contract as plain CSS and JS, for pages that must open from a file with no build. docgen's site is not a binding yet: it bakes its colours from its own style slots, a third token vocabulary. ## The layers, as use shaped them | layer | what | the evidence | | --- | --- | --- | | contract | tokens, element layer, class names, status words | every consumer reads `tokens.css`; four apps pasted their own `base.css` before it shipped here | | chrome | `Panel` (+ maximize), `SplitPane`, `ParameterEditor`, `VideoPlayer` | `Panel` and `SplitPane` are the only exports all five consumers use; nested splits, not `LayoutGrid`, turned out to be the layout | | feed | `DataSource`, `SSEDataSource` | one stream, typed events, a terminal `done` | | renderers | `LogRenderer`, `TableRenderer`, `FrameRenderer`, `TimeSeriesRenderer`, `GraphRenderer` | opt-in; the only two external packages arrive through these | | app state | not here | mpr keeps its own Pinia stores; `pinia` is imported nowhere in this library | | delivery | slices, not this whole folder | see below | ## How to take it Not as this folder. A consumer takes a **slice**: the closure of the exports it uses, as readable source, with a barrel exporting only those and a `tokens.css` cut down to what is read — `make ui scan ` computes it, `ctrl/ui.sh slice ` writes it, and `check` reports drift both ways. The "Contents" table is the price list. ## How this document is made Everything outside these notes is generated from `src/` by `make reference` (in `common/ui`), so a prop that is removed disappears from here on the next build. The notes are the only hand-written part, one file per spot in `soleprint/common/ui/notes/`; a note whose spot disappears fails `make check`. `make docs` — anywhere in soleprint — launches this site. ## What came in `common/ui/src` — **24 file(s) seen, 24 read, 0 failed**; 19 exports and 15 types in the barrel. ## Contents **Who uses what**, measured 2026-09-22 with `make ui scan ` over the five apps that consume this library. It is the one table here that is not generated — the apps live outside this repository — so re-run the scan before trusting a row. | export | mpr detection | mts meetus | mts doocus | unt | nvi | | --- | --- | --- | --- | --- | --- | | `Panel`, `SplitPane` | ✓ | ✓ | ✓ | ✓ | ✓ | | `LogRenderer` | ✓ | | | ✓ | | | `VideoPlayer` | | ✓ | | | | | `ParameterEditor`, `ResizeHandle`, all renderers but Log, `SSEDataSource`, `useRegistry`, `useEditorExecution` | ✓ | | | | | | `LayoutGrid`, `StaticDataSource`, `useDataSource`, `BBoxDrawPlugin`, `CrosshairPlugin` | | | | | | The last row has **no users at all**. Those exports stay in the library — they are small and a slice never carries them unless asked — but nothing should be built on them as if they were proven. `ResizeHandle` is imported by mpr and never rendered: it is what `SplitPane` replaced. What each export costs a consumer that takes it: the files it pulls in, the packages it brings, and whether a plain-HTML part exists for it (`common/theme/parts`). | export | kind | file | pulls in | packages | size | plain part | | --- | --- | --- | --- | --- | --- | --- | | [`DataSource`](#datasource) | datasource | `datasources/DataSource.ts` | — | vue | 1.3 KB | feed | | [`SSEDataSource`](#ssedatasource) | datasource | `datasources/SSEDataSource.ts` | DataSource.ts | vue | 3.8 KB | feed | | [`StaticDataSource`](#staticdatasource) | datasource | `datasources/StaticDataSource.ts` | DataSource.ts | vue | 2.4 KB | — | | [`useDataSource`](#usedatasource) | composable | `composables/useDataSource.ts` | DataSource.ts | vue | 2.0 KB | — | | [`useRegistry`](#useregistry) | composable | `composables/useRegistry.ts` | — | vue | 1.9 KB | — | | [`useEditorExecution`](#useeditorexecution) | composable | `composables/useEditorExecution.ts` | — | vue | 1.4 KB | — | | [`Panel`](#panel) | component | `components/Panel.vue` | — | vue | 4.3 KB | maximize, panel | | [`LayoutGrid`](#layoutgrid) | component | `components/LayoutGrid.vue` | — | vue | 0.5 KB | — | | [`ResizeHandle`](#resizehandle) | component | `components/ResizeHandle.vue` | — | vue | 1.3 KB | — | | [`SplitPane`](#splitpane) | component | `components/SplitPane.vue` | — | vue | 3.7 KB | split | | [`ParameterEditor`](#parametereditor) | component | `components/ParameterEditor.vue` | — | vue | 3.1 KB | params | | [`VideoPlayer`](#videoplayer) | component | `components/VideoPlayer.vue` | — | vue | 4.1 KB | — | | [`LogRenderer`](#logrenderer) | renderer | `renderers/LogRenderer.vue` | — | vue | 3.7 KB | — | | [`TimeSeriesRenderer`](#timeseriesrenderer) | renderer | `renderers/TimeSeriesRenderer.vue` | — | uplot, vue | 4.3 KB | — | | [`GraphRenderer`](#graphrenderer) | renderer | `renderers/GraphRenderer.vue` | — | @vue-flow/core, vue | 7.9 KB | — | | [`FrameRenderer`](#framerenderer) | renderer | `renderers/FrameRenderer.vue` | — | vue | 4.9 KB | — | | [`TableRenderer`](#tablerenderer) | renderer | `renderers/TableRenderer.vue` | — | vue | 2.4 KB | — | | [`BBoxDrawPlugin`](#bboxdrawplugin) | plugin | `plugins/BBoxDrawPlugin.ts` | InteractionPlugin.ts | — | 3.0 KB | — | | [`CrosshairPlugin`](#crosshairplugin) | plugin | `plugins/CrosshairPlugin.ts` | InteractionPlugin.ts | — | 2.5 KB | — | ## Components ### Panel The one component everything uses — 13 instances in mpr, 7 across mts's two apps. **Maximize came from mts.** mts's copy grew `v-model:maximized` and `maximizable` while spr's stood still, and it was brought upstream on 2026-09-22 — the framework spec's own rule ("a second application finds the holes") working as written. The reason it is the panel's job and not the video's is in the source: a fullscreen `