Shared React component library for the OmniBioAI platform. Provides Button, Badge, Card, Input, StatusDot, Spinner, Table, Tabs, ProgressBar, Tooltip, and Select components built on unified design tokens with zero hardcoded colors.
- TypeScript-first — full type definitions shipped with the package
- Design-token driven — all colors, spacing, and radii come from
@omnibioai/design-tokens; no hardcoded hex values anywhere in the library - Tree-shakeable — built as ES module + CJS with Vite library mode; only import what you use
- React 18+ peer dep — works with any React 18+ project including the OmniBioAI Electron app and any downstream consumer
- Fully tested — 50+ unit tests with Vitest + React Testing Library
- Storybook catalogue — visual stories for every component and variant
- Type-safe exports — full
.d.tsdeclarations via vite-plugin-dts - CI token lint — GitHub Actions workflow blocks hardcoded hex values in CSS and TSX on every push and pull request
This package is published to the GitHub Packages registry under @omnibioai.
Create or update .npmrc in your project root:
@omnibioai:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
Your token needs read:packages scope. Generate one at GitHub → Settings → Developer settings → Personal access tokens.
npm install @omnibioai/ui @omnibioai/design-tokens@omnibioai/design-tokens is a required peer — it provides the CSS custom properties that all components reference.
In your app entry point, import the token stylesheet once:
import'@omnibioai/design-tokens/tokens.css';All components will pick up the correct colors, spacing, and radii automatically from there.
import{Button}from'@omnibioai/ui';<Buttonvariant="primary"onClick={handleRun}>
Run analysis
</Button><Buttonvariant="secondary"size="sm"disabled>Cancel</Button><Buttonvariant="danger"loading>
Deleting...
</Button>| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'ghost' | 'danger' | 'primary' | Visual style |
size | 'sm' | 'md' | 'lg' | 'md' | Button size |
loading | boolean | false | Shows spinner, disables interaction |
disabled | boolean | false | Disables button |
onClick | () => void | — | Click handler |
Note: When
loadingistrue, aSpinneris shown and the button is automatically disabled.
import{Badge}from'@omnibioai/ui';<Badgevariant="success">Running</Badge><Badgevariant="warning">Queued</Badge><Badgevariant="danger">Failed</Badge><Badgevariant="info">v1.0.0</Badge><Badgevariant="neutral">Draft</Badge>| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'success' | 'warning' | 'danger' | 'info' | 'neutral' | 'default' | 'neutral' | Semantic color |
Note:
'default'is a legacy alias for'neutral'and maps to the same visual style.
import{Card}from'@omnibioai/ui';<Card><h3>Plugin output</h3><p>Run completed in 4.2s</p></Card><CardelevatedonClick={handleClick}>Clickablecard</Card>| Prop | Type | Default | Description |
|---|---|---|---|
elevated | boolean | false | Adds shadow for visual prominence |
onClick | () => void | — | Makes card interactive |
className | string | — | Additional CSS classes |
import{Input}from'@omnibioai/ui';<Inputlabel="Sample ID"placeholder="Enter sample identifier"value={sampleId}onChange={e=>setSampleId(e.target.value)}/><Inputlabel="VCF path"error="File not found"value={vcfPath}onChange={e=>setVcfPath(e.target.value)}/>| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Label above the input |
error | string | — | Error message below; turns border red |
placeholder | string | — | Placeholder text |
value | string | — | Controlled value |
onChange | ChangeEventHandler | — | Change handler |
disabled | boolean | false | Disables input |
Compact status indicator used in run lists, job monitors, and pipeline dashboards.
import{StatusDot}from'@omnibioai/ui';<StatusDotstatus="running"/>// animated pulse<StatusDotstatus="success"/><StatusDotstatus="failed"/><StatusDotstatus="queued"/><StatusDotstatus="idle"/><StatusDotstatus="running"label="Job in progress"/>| Prop | Type | Default | Description |
|---|---|---|---|
status | 'running' | 'success' | 'failed' | 'queued' | 'idle' | — | Determines color and animation |
label | string | — | Optional text label beside the dot |
import{Spinner}from'@omnibioai/ui';<Spinner/><Spinnersize="sm"/><Spinnersize="lg"/>| Prop | Type | Default | Description |
|---|---|---|---|
size | 'sm' | 'md' | 'lg' | 'md' | Spinner diameter |
Generic sortable, paginated table. Columns are fully typed.
import{Table}from'@omnibioai/ui';importtype{Column}from'@omnibioai/ui';constcolumns: Column<MyRow>[]=[{key: 'name',label: 'Repository',sortable: true},{key: 'code',label: 'Code lines',sortable: true,align: 'right'},{key: 'status',label: 'Status',render: (v)=><Badgevariant="success">{String(v)}</Badge>},];<Tablecolumns={columns}data={rows}pageSize={10}/>Props:
| Prop | Type | Default | Description |
|---|---|---|---|
columns | Column<T>[] | — | Column definitions |
data | T[] | — | Row data |
pageSize | number | 10 | Rows per page |
emptyMessage | string | 'No results' | Empty state text |
Column definition:
| Key | Type | Default | Description |
|---|---|---|---|
key | keyof T | — | Data key |
label | string | — | Column header text |
sortable | boolean | false | Enable sort on click |
align | 'left' | 'right' | 'left' | Text alignment |
render | (value, row) => ReactNode | — | Custom cell renderer |
import{Tabs}from'@omnibioai/ui';importtype{Tab}from'@omnibioai/ui';<Tabstabs={[{key: 'arch',label: 'Architecture',content: <ArchView/>},{key: 'health',label: 'Health',content: <HealthView/>},]}defaultTab="arch"onChange={(key)=>console.log('switched to',key)}/>Props:
| Prop | Type | Default | Description |
|---|---|---|---|
tabs | Tab[] | — | Tab definitions |
defaultTab | string | first | Initially active tab key |
onChange | (key: string) => void | — | Called on tab switch |
Tab definition:
| Key | Type | Default | Description |
|---|---|---|---|
key | string | — | Unique identifier |
label | string | — | Tab button text |
content | ReactNode | — | Panel content |
import{ProgressBar}from'@omnibioai/ui';<ProgressBarvalue={98.7}variant="success"label="98.7%"/><ProgressBarvalue={60} variant="accent"/><ProgressBarvalue={25}variant="danger"size="lg"/>| Prop | Type | Default | Description |
|---|---|---|---|
value | number | — | Current value (0–max) |
max | number | 100 | Maximum value |
size | 'sm' | 'md' | 'lg' | 'md' | Bar height |
variant | 'success' | 'danger' | 'warning' | 'accent' | 'info' | 'accent' | Fill color |
showLabel | boolean | true | Show percentage label |
label | string | — | Override auto label text |
import{Tooltip}from'@omnibioai/ui';<Tooltipcontent="27/27 services healthy"><Badgevariant="success">UP</Badge></Tooltip>| Prop | Type | Default | Description |
|---|---|---|---|
content | string | — | Tooltip text shown on hover |
children | ReactNode | — | Element that triggers hover |
import{Select}from'@omnibioai/ui';importtype{SelectOption}from'@omnibioai/ui';<Selectlabel="Category"options={[{value: 'all',label: 'All categories'},{value: 'core',label: 'Core'},]}value={selected}onChange={setSelected}placeholder="Choose a category"/>| Prop | Type | Default | Description |
|---|---|---|---|
options | SelectOption[] | — | Option list |
value | string | — | Controlled value |
onChange | (v: string) => void | — | Change handler |
label | string | — | Label above the select |
placeholder | string | — | Placeholder option |
disabled | boolean | false | Disables the select |
Everything is exported from the package root:
import{Button,Badge,Card,Input,StatusDot,Spinner,Table,Tabs,ProgressBar,Tooltip,Select,}from'@omnibioai/ui';importtype{Column,Tab,SelectOption}from'@omnibioai/ui';Tree-shaking is automatic — unused components are excluded from your bundle at build time.
git clone https://github.com/OmniBioAI/omnibioai-ui
cd omnibioai-ui
npm install
# Build once
npm run build
# Watch mode (rebuilds on every save)
npm run dev
# Run tests
npm run test# Watch mode
npm run test:watch
# View Storybook (visual catalogue of all components)
npm run storybookOutput lands in dist/ as index.js (ES module) and index.cjs (CommonJS) with index.d.ts type declarations.
# In this repo
npm run build
npm link
# In your consuming repo
npm link @omnibioai/uiomnibioai-ui/
├── src/
│ ├── index.ts
│ ├── test-setup.ts
│ ├── components/
│ │ ├── Button/ (Button.tsx, Button.css, Button.test.tsx, Button.stories.tsx)
│ │ ├── Badge/ (Badge.tsx, Badge.css, Badge.test.tsx, Badge.stories.tsx)
│ │ ├── Card/ (Card.tsx, Card.css, Card.test.tsx, Card.stories.tsx)
│ │ ├── Input/ (Input.tsx, Input.css, Input.test.tsx, Input.stories.tsx)
│ │ ├── StatusDot/ (StatusDot.tsx, StatusDot.css, StatusDot.test.tsx, StatusDot.stories.tsx)
│ │ ├── Spinner/ (Spinner.tsx, Spinner.css, Spinner.test.tsx, Spinner.stories.tsx)
│ │ ├── Table/ (Table.tsx, Table.css, Table.test.tsx, Table.stories.tsx)
│ │ ├── Tabs/ (Tabs.tsx, Tabs.css, Tabs.test.tsx, Tabs.stories.tsx)
│ │ ├── ProgressBar/ (ProgressBar.tsx, ProgressBar.css, ProgressBar.test.tsx, ProgressBar.stories.tsx)
│ │ ├── Tooltip/ (Tooltip.tsx, Tooltip.css, Tooltip.test.tsx, Tooltip.stories.tsx)
│ │ └── Select/ (Select.tsx, Select.css, Select.test.tsx, Select.stories.tsx)
├── .storybook/
├── vite.config.ts ← library build config
├── vitest.config.ts ← test config (separate from vite)
├── tsconfig.json
├── CHANGELOG.md ← release history (Keep a Changelog format)
└── package.json
Components reference CSS custom properties from @omnibioai/design-tokens. No component contains a hardcoded color, spacing value, or radius — all visual decisions are delegated to the token layer. This means:
- Swapping themes (light/dark, brand variants) requires only a token override
- All OmniBioAI surfaces (Electron app, web, plugin UIs) stay visually consistent from a single source of truth
- No
!importanthacks or specificity wars when overriding in consuming apps
| Package | Purpose |
|---|---|
@omnibioai/design-tokens | CSS custom properties — required peer dependency |
omnibioai-studio | Electron + React app — primary consumer |
omnibioai-workbench | Django backend — 231-plugin bioinformatics platform (checked out locally as omnibioai/) |
omnibioai-control-center | Health dashboard + ecosystem report (consumes design tokens) |
MIT