@noggin/ui — overview
@noggin/ui is the shared React component library that powers the VS Code extension's webview, the Electron desktop renderer, and this documentation site's playground. The same components render in every host.
The library is deliberately small. Three top-level components plus a few controllers and utilities are everything a host needs to put a noggin on the screen:
| Component | What it is |
|---|---|
NogginTree | The drag-and-drop tree view. |
NogginDetails | The right-hand details pane showing notes + metadata. |
NogginList | Sidebar list of open / recent / bookmarked noggins. |
Both tree and details components consume a single actions: NogginActions prop for every mutation they initiate (drag-drop, the kebab menu, every keyboard gesture). Hosts build the actions object once via createNogginActions(noggin) and pass it to both components.
NogginList is a step outside the single-noggin surface — it takes a store (createNogginListStore), a provider-type catalog (createNogginProviderRegistry), and controlled preferences.
The shared components don't know about VS Code, Electron, or fetch — they only know React props and CSS. They consume a Noggin (the engine's canonical handle) and they don't care whether it lives in the same process or behind an RPC transport — an in-process noggin from @noggin/engine and a RemoteNoggin from @noggin/rpc both satisfy the same interface and both work as input to createNogginActions.
Install
npm install @noggin/ui
@noggin/ui is published as an internal workspace package and is consumed via npm workspaces; you don't normally install it directly from a registry. If you're embedding it elsewhere, follow the pattern the extension and desktop renderer use.
What you import
import {
NogginTree,
NogginDetails,
NogginList,
createNogginActions,
createNogginListStore,
createNogginProviderRegistry,
defaultNogginProviders,
createMRUManager,
buildTreeMenuEntries,
projectTree,
renderMarkdown,
uiErrorMessage,
} from '@noggin/ui';
// One stylesheet for the whole library.
import '@noggin/ui/styles.css';
// One theme. Pick one — see the theming page.
import '@noggin/ui/themes/light.css'; // or dark.css, vscode.css, auto.css
Subpath exports the library publishes:
| Subpath | Purpose |
|---|---|
@noggin/ui | All React components + types + the createNogginActions factory + the buildTreeMenuEntries helper. |
@noggin/ui/styles.css | Component styles. Required. |
@noggin/ui/tokens.css | Raw design-token CSS variables (light defaults). Imported automatically by styles.css. |
@noggin/ui/themes/light.css | Explicit light theme. |
@noggin/ui/themes/dark.css | Dark theme tuned for desktop hosts. |
@noggin/ui/themes/vscode.css | Adapter that maps --noggin-* → --vscode-* workbench tokens. |
@noggin/ui/themes/auto.css | prefers-color-scheme toggle (light defaults, dark below (prefers-color-scheme: dark)). |
@noggin/ui/contrast-check | Dev-only WCAG checker (see theming page). |
The RemoteNoggin optimistic adapter that drives a noggin over a transport ships in @noggin/rpc, not here.
Architecture in one paragraph
Everything visual lives behind two layers of override:
- Design tokens in
tokens.css— 27--noggin-*CSS variables organised in pairs (every*-bghas a matching*-fg). Theme files (themes/*.css) just redefine these variables. Hosts swap themes by importing a different file.
classNamesslot props on every component — hand a component a per-slot map of extra class names and they're merged into the built-in ones with a tinycn(...)helper. Use this for one-off tweaks (a host-specific banner colour, animations, branding) that don't belong in a global theme.
Components never read host theming directly. They only read CSS custom properties, which means any host that sets the right CSS variables can re-skin the entire library without touching React code.
Where to go next
- Theming — design tokens, the four built-in themes, how to write a new one, and the dev-time contrast checker.
- Component reference — props, slots, gotchas for each component, with live examples.
- Playground — try the components in your browser with a temporary in-memory noggin.