bonobo-ui-core
v1.8.5
Published
Bonobo Terminal UI component library — React components, theming, and visualizations.
Readme
bonobo-ui-core
React component library for Bonobo Terminal and related projects — components, theming, and visualizations.
Published two ways:
- npm package (
bonobo-ui-core, public registry) — build-time consumption, tree-shaken into the host bundle. - Module Federation bundle as Gitea release assets — runtime consumption by the terminal's
/componentsviewer.
Install
bun add bonobo-ui-core # or: npm install bonobo-ui-coreQuick start
// main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BonoboProvider, NotificationsHost } from "bonobo-ui-core";
import "bonobo-ui-core/styles.css";
import { App } from "./App";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<BonoboProvider colorScheme="dark">
<NotificationsHost position="top-right" />
<App />
</BonoboProvider>
</StrictMode>
);Importing bonobo-ui-core/styles.css is all a consumer needs — it ships the theme
tokens plus the html, body base rules.
Peer dependencies
Required: React 18/19, @tabler/icons-react 3, and the Radix primitives
(@radix-ui/react-{dropdown-menu,popover,tabs,tooltip}).
Optional (only needed if you use the component that depends on them — the bundle externalizes all of them):
streamdown,mermaid,shiki—StreamingMarkdown@xyflow/react,elkjs,@dagrejs/dagre,@mermaid-js/layout-elk—FlowDiagram/KMap*@xterm/xterm,@xterm/addon-search—TerminalSearch/TerminalThemesimple-icons—DistroIcon/DistroWatermark
Local development
bun install
bun run dev # watches the lib bundle (dist/bonobo-ui.js)
bun run dev:remote # serves the federation remote on http://localhost:5000
bun run ladle # story browser (http://localhost:61000)
bun run typecheck # runs codegen + tsc --noEmitTo point the terminal's /components route at your local federation remote:
cd ~/bonobo-terminal
VITE_BONOBO_UI_LOCAL=1 bun run devThe viewer then fetches http://localhost:5000/remoteEntry.js instead of the
Gitea release. HMR doesn't cover federation modules — refresh after save.
Release
bun run build # builds dist/ (lib bundle + themes)
npm version patch # or minor/major
npm publish # public registry (publishConfig.access = public)
git push --follow-tagsThe tag push also triggers .gitea/workflows/release.yml, which builds the
federation bundle and uploads dist/federation/* as Gitea release assets so
the terminal's /components viewer picks up the new version.
Architecture
| Path | Purpose |
|---|---|
| src/components/<Name>/ | Components: <Name>.tsx, <Name>.module.css, <Name>.stories.tsx, index.ts |
| src/components/_meta.ts | Source of truth for the component catalog (slug, name, category, description) |
| src/federation/manifest.ts | Federation-exposed entry. Re-exports components + version |
| src/federation/manifest.generated.ts | Codegen output (gitignored) |
| scripts/build-federation-manifest.ts | Walks stories + _meta.ts, emits manifest.generated.ts |
| vite.config.ts | Lib bundle (ES, external peer deps) |
| vite.federation.config.ts | Federation bundle (dist/federation/remoteEntry.js + chunks) |
| .gitea/workflows/release.yml | CI on v*.*.* tag push (federation assets) |
Adding a component
- Create
src/components/Foo/withFoo.tsx,Foo.module.css(optional),Foo.stories.tsx,index.ts. - Export from
src/index.ts(export { Foo } from "./components/Foo"+ type export). - Add an entry to
src/components/_meta.ts(slug, name, category, description). bun run typecheck && bun run build:federationto validate.- Cut a release.
Components exported from src/index.ts but not listed in _meta.ts are
build-time-only: they ship via the npm package but don't appear in the
/components viewer (which requires a stories file).
Theming contract
The library owns the theming cascade end-to-end:
src/theme/tokens.cssdefines every--bonobo-*token (and a deprecated--mantine-*compat alias) in both:root(light) and[data-theme="dark"], .darkblocks. These are the source of truth.html, bodybase rules live in the same stylesheet and bind--bonobo-color-body/--bonobo-color-text/--font-monoto the document.BonoboProviderflipsdata-themeand the.light/.darkclass on<html>. It does not set theme tokens via JS.
Prefer the --bonobo-* scale in your own CSS. The --mantine-* scale is a
deprecated compat alias and may be removed in a future major.
What NOT to do
- Don't set theme tokens via JS on
<html>. Writingroot.style.setProperty('--bonobo-color-body', …)fights the library's cascade and drifts across releases. Scope surface-specific overrides to a local selector instead. - Don't hard-code color hex values that duplicate a token. Alias through
the
--bonobo-*scale so dark/light switching keeps working.
Swapping light/dark at runtime
import { useColorScheme } from "bonobo-ui-core";
function ThemeToggle() {
const { colorScheme, setColorScheme } = useColorScheme();
return (
<button
onClick={() => setColorScheme(colorScheme === "dark" ? "light" : "dark")}
>
{colorScheme === "dark" ? "Light" : "Dark"}
</button>
);
}setColorScheme("auto") follows the OS preference. The hook reads from and
writes to localStorage["bonobo-color-scheme"].
License
MIT.
