Skip to content

Repository files navigation

@omnibioai/ui

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.


Overview

  • 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.ts declarations via vite-plugin-dts
  • CI token lint — GitHub Actions workflow blocks hardcoded hex values in CSS and TSX on every push and pull request

Installation

This package is published to the GitHub Packages registry under @omnibioai.

1. Authenticate with GitHub Packages

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.

2. Install the package

npm install @omnibioai/ui @omnibioai/design-tokens

@omnibioai/design-tokens is a required peer — it provides the CSS custom properties that all components reference.

3. Load design tokens

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.


Components

Button

import{Button}from'@omnibioai/ui';<Buttonvariant="primary"onClick={handleRun}>
Run analysis
</Button><Buttonvariant="secondary"size="sm"disabled>Cancel</Button><Buttonvariant="danger"loading>
Deleting...
</Button>
PropTypeDefaultDescription
variant'primary' | 'secondary' | 'ghost' | 'danger''primary'Visual style
size'sm' | 'md' | 'lg''md'Button size
loadingbooleanfalseShows spinner, disables interaction
disabledbooleanfalseDisables button
onClick() => voidClick handler

Note: When loading is true, a Spinner is shown and the button is automatically disabled.


Badge

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>
PropTypeDefaultDescription
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.


Card

import{Card}from'@omnibioai/ui';<Card><h3>Plugin output</h3><p>Run completed in 4.2s</p></Card><CardelevatedonClick={handleClick}>Clickablecard</Card>
PropTypeDefaultDescription
elevatedbooleanfalseAdds shadow for visual prominence
onClick() => voidMakes card interactive
classNamestringAdditional CSS classes

Input

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)}/>
PropTypeDefaultDescription
labelstringLabel above the input
errorstringError message below; turns border red
placeholderstringPlaceholder text
valuestringControlled value
onChangeChangeEventHandlerChange handler
disabledbooleanfalseDisables input

StatusDot

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"/>
PropTypeDefaultDescription
status'running' | 'success' | 'failed' | 'queued' | 'idle'Determines color and animation
labelstringOptional text label beside the dot

Spinner

import{Spinner}from'@omnibioai/ui';<Spinner/><Spinnersize="sm"/><Spinnersize="lg"/>
PropTypeDefaultDescription
size'sm' | 'md' | 'lg''md'Spinner diameter

Table

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:

PropTypeDefaultDescription
columnsColumn<T>[]Column definitions
dataT[]Row data
pageSizenumber10Rows per page
emptyMessagestring'No results'Empty state text

Column definition:

KeyTypeDefaultDescription
keykeyof TData key
labelstringColumn header text
sortablebooleanfalseEnable sort on click
align'left' | 'right''left'Text alignment
render(value, row) => ReactNodeCustom cell renderer

Tabs

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:

PropTypeDefaultDescription
tabsTab[]Tab definitions
defaultTabstringfirstInitially active tab key
onChange(key: string) => voidCalled on tab switch

Tab definition:

KeyTypeDefaultDescription
keystringUnique identifier
labelstringTab button text
contentReactNodePanel content

ProgressBar

import{ProgressBar}from'@omnibioai/ui';<ProgressBarvalue={98.7}variant="success"label="98.7%"/><ProgressBarvalue={60} variant="accent"/><ProgressBarvalue={25}variant="danger"size="lg"/>
PropTypeDefaultDescription
valuenumberCurrent value (0–max)
maxnumber100Maximum value
size'sm' | 'md' | 'lg''md'Bar height
variant'success' | 'danger' | 'warning' | 'accent' | 'info''accent'Fill color
showLabelbooleantrueShow percentage label
labelstringOverride auto label text

Tooltip

import{Tooltip}from'@omnibioai/ui';<Tooltipcontent="27/27 services healthy"><Badgevariant="success">UP</Badge></Tooltip>
PropTypeDefaultDescription
contentstringTooltip text shown on hover
childrenReactNodeElement that triggers hover

Select

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"/>
PropTypeDefaultDescription
optionsSelectOption[]Option list
valuestringControlled value
onChange(v: string) => voidChange handler
labelstringLabel above the select
placeholderstringPlaceholder option
disabledbooleanfalseDisables the select

Importing

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.


Local development

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 storybook

Output lands in dist/ as index.js (ES module) and index.cjs (CommonJS) with index.d.ts type declarations.

Using in another local repo without publishing

# In this repo
npm run build
npm link
# In your consuming repo
npm link @omnibioai/ui

Repository layout

omnibioai-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

Design token contract

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 !important hacks or specificity wars when overriding in consuming apps

Related packages

PackagePurpose
@omnibioai/design-tokensCSS custom properties — required peer dependency
omnibioai-studioElectron + React app — primary consumer
omnibioai-workbenchDjango backend — 231-plugin bioinformatics platform (checked out locally as omnibioai/)
omnibioai-control-centerHealth dashboard + ecosystem report (consumes design tokens)

License

MIT

About

Shared React component library for OmniBioAI — Button, Badge, Card, Input, StatusDot, and Spinner built on @man4ish/design-tokens. TypeScript-first, tree-shakeable ES+CJS build via Vite, published to GitHub Packages. Zero hardcoded colors; all styling delegated to the token layer.

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages