Skip to content

Commit 4d720df

Browse files
man4ishclaude
andcommitted
docs: update README to reflect phases 1-3
- Fix Badge/Card/Button/StatusDot prop documentation - Add Table, Tabs, ProgressBar, Tooltip, Select component docs - Update imports section with all 11 components + type exports - Add test and Storybook commands to local dev section - Update repo layout to show real file structure - Add omnibioai-control-center to related packages Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2adb435 commit 4d720df

1 file changed

Lines changed: 190 additions & 16 deletions

File tree

README.md

Lines changed: 190 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @man4ish/ui
22

3-
Shared React component library for the [OmniBioAI](https://github.com/man4ish/omnibioai-studio) platform. Provides `Button`, `Badge`, `Card`, `Input`, `StatusDot`, and `Spinner` components built on unified design tokens with zero hardcoded colors.
3+
Shared React component library for the [OmniBioAI](https://github.com/man4ish/omnibioai-studio) platform. Provides `Button`, `Badge`, `Card`, `Input`, `StatusDot`, `Spinner`, `Table`, `Tabs`, `ProgressBar`, `Tooltip`, and `Select` components built on unified design tokens with zero hardcoded colors.
44

55
---
66

@@ -10,6 +10,9 @@ Shared React component library for the [OmniBioAI](https://github.com/man4ish/om
1010
- **Design-token driven** — all colors, spacing, and radii come from `@man4ish/design-tokens`; no hardcoded hex values anywhere in the library
1111
- **Tree-shakeable** — built as ES module + CJS with Vite library mode; only import what you use
1212
- **React 18+ peer dep** — works with any React 18+ project including the OmniBioAI Electron app and any downstream consumer
13+
- **Fully tested** — 50+ unit tests with Vitest + React Testing Library
14+
- **Storybook catalogue** — visual stories for every component and variant
15+
- **Type-safe exports** — full `.d.ts` declarations via vite-plugin-dts
1316

1417
---
1518

@@ -76,6 +79,8 @@ import { Button } from '@man4ish/ui';
7679
| `disabled` | `boolean` | `false` | Disables button |
7780
| `onClick` | `() => void` || Click handler |
7881

82+
> **Note:** When `loading` is `true`, a `Spinner` is shown and the button is automatically disabled.
83+
7984
---
8085

8186
### `Badge`
@@ -92,7 +97,9 @@ import { Badge } from '@man4ish/ui';
9297

9398
| Prop | Type | Default | Description |
9499
|---|---|---|---|
95-
| `variant` | `'success' \| 'warning' \| 'danger' \| 'info' \| 'neutral'` | `'neutral'` | Semantic color |
100+
| `variant` | `'success' \| 'warning' \| 'danger' \| 'info' \| 'neutral' \| 'default'` | `'neutral'` | Semantic color |
101+
102+
> **Note:** `'default'` is a legacy alias for `'neutral'` and maps to the same visual style.
96103
97104
---
98105

@@ -162,11 +169,14 @@ import { StatusDot } from '@man4ish/ui';
162169
<StatusDot status="failed" />
163170
<StatusDot status="queued" />
164171
<StatusDot status="idle" />
172+
173+
<StatusDot status="running" label="Job in progress" />
165174
```
166175

167-
| Prop | Type | Description |
168-
|---|---|---|
169-
| `status` | `'running' \| 'success' \| 'failed' \| 'queued' \| 'idle'` | Determines color and animation |
176+
| Prop | Type | Default | Description |
177+
|---|---|---|---|
178+
| `status` | `'running' \| 'success' \| 'failed' \| 'queued' \| 'idle'` || Determines color and animation |
179+
| `label` | `string` || Optional text label beside the dot |
170180

171181
---
172182

@@ -186,12 +196,157 @@ import { Spinner } from '@man4ish/ui';
186196

187197
---
188198

199+
### `Table`
200+
201+
Generic sortable, paginated table. Columns are fully typed.
202+
203+
```tsx
204+
import { Table } from '@man4ish/ui';
205+
import type { Column } from '@man4ish/ui';
206+
207+
const columns: Column<MyRow>[] = [
208+
{ key: 'name', label: 'Repository', sortable: true },
209+
{ key: 'code', label: 'Code lines', sortable: true, align: 'right' },
210+
{ key: 'status', label: 'Status',
211+
render: (v) => <Badge variant="success">{String(v)}</Badge> },
212+
];
213+
214+
<Table columns={columns} data={rows} pageSize={10} />
215+
```
216+
217+
**Props:**
218+
219+
| Prop | Type | Default | Description |
220+
|---|---|---|---|
221+
| `columns` | `Column<T>[]` || Column definitions |
222+
| `data` | `T[]` || Row data |
223+
| `pageSize` | `number` | `10` | Rows per page |
224+
| `emptyMessage` | `string` | `'No results'` | Empty state text |
225+
226+
**Column definition:**
227+
228+
| Key | Type | Default | Description |
229+
|---|---|---|---|
230+
| `key` | `keyof T` || Data key |
231+
| `label` | `string` || Column header text |
232+
| `sortable` | `boolean` | `false` | Enable sort on click |
233+
| `align` | `'left' \| 'right'` | `'left'` | Text alignment |
234+
| `render` | `(value, row) => ReactNode` || Custom cell renderer |
235+
236+
---
237+
238+
### `Tabs`
239+
240+
```tsx
241+
import { Tabs } from '@man4ish/ui';
242+
import type { Tab } from '@man4ish/ui';
243+
244+
<Tabs
245+
tabs={[
246+
{ key: 'arch', label: 'Architecture', content: <ArchView /> },
247+
{ key: 'health', label: 'Health', content: <HealthView /> },
248+
]}
249+
defaultTab="arch"
250+
onChange={(key) => console.log('switched to', key)}
251+
/>
252+
```
253+
254+
**Props:**
255+
256+
| Prop | Type | Default | Description |
257+
|---|---|---|---|
258+
| `tabs` | `Tab[]` || Tab definitions |
259+
| `defaultTab` | `string` | first | Initially active tab key |
260+
| `onChange` | `(key: string) => void` || Called on tab switch |
261+
262+
**Tab definition:**
263+
264+
| Key | Type | Default | Description |
265+
|---|---|---|---|
266+
| `key` | `string` || Unique identifier |
267+
| `label` | `string` || Tab button text |
268+
| `content` | `ReactNode` || Panel content |
269+
270+
---
271+
272+
### `ProgressBar`
273+
274+
```tsx
275+
import { ProgressBar } from '@man4ish/ui';
276+
277+
<ProgressBar value={98.7} variant="success" label="98.7%" />
278+
<ProgressBar value={60} variant="accent" />
279+
<ProgressBar value={25} variant="danger" size="lg" />
280+
```
281+
282+
| Prop | Type | Default | Description |
283+
|---|---|---|---|
284+
| `value` | `number` || Current value (0–max) |
285+
| `max` | `number` | `100` | Maximum value |
286+
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Bar height |
287+
| `variant` | `'success' \| 'danger' \| 'warning' \| 'accent' \| 'info'` | `'accent'` | Fill color |
288+
| `showLabel` | `boolean` | `true` | Show percentage label |
289+
| `label` | `string` || Override auto label text |
290+
291+
---
292+
293+
### `Tooltip`
294+
295+
```tsx
296+
import { Tooltip } from '@man4ish/ui';
297+
298+
<Tooltip content="27/27 services healthy">
299+
<Badge variant="success">UP</Badge>
300+
</Tooltip>
301+
```
302+
303+
| Prop | Type | Default | Description |
304+
|---|---|---|---|
305+
| `content` | `string` || Tooltip text shown on hover |
306+
| `children` | `ReactNode` || Element that triggers hover |
307+
308+
---
309+
310+
### `Select`
311+
312+
```tsx
313+
import { Select } from '@man4ish/ui';
314+
import type { SelectOption } from '@man4ish/ui';
315+
316+
<Select
317+
label="Category"
318+
options={[
319+
{ value: 'all', label: 'All categories' },
320+
{ value: 'core', label: 'Core' },
321+
]}
322+
value={selected}
323+
onChange={setSelected}
324+
placeholder="Choose a category"
325+
/>
326+
```
327+
328+
| Prop | Type | Default | Description |
329+
|---|---|---|---|
330+
| `options` | `SelectOption[]` || Option list |
331+
| `value` | `string` || Controlled value |
332+
| `onChange` | `(v: string) => void` || Change handler |
333+
| `label` | `string` || Label above the select |
334+
| `placeholder` | `string` || Placeholder option |
335+
| `disabled` | `boolean` | `false` | Disables the select |
336+
337+
---
338+
189339
## Importing
190340

191341
Everything is exported from the package root:
192342

193343
```ts
194-
import { Button, Badge, Card, Input, StatusDot, Spinner } from '@man4ish/ui';
344+
import {
345+
Button, Badge, Card, Input, StatusDot, Spinner,
346+
Table, Tabs, ProgressBar, Tooltip, Select,
347+
} from '@man4ish/ui';
348+
349+
import type { Column, Tab, SelectOption } from '@man4ish/ui';
195350
```
196351

197352
Tree-shaking is automatic — unused components are excluded from your bundle at build time.
@@ -210,6 +365,15 @@ npm run build
210365

211366
# Watch mode (rebuilds on every save)
212367
npm run dev
368+
369+
# Run tests
370+
npm run test
371+
372+
# Watch mode
373+
npm run test:watch
374+
375+
# View Storybook (visual catalogue of all components)
376+
npm run storybook
213377
```
214378

215379
Output lands in `dist/` as `index.js` (ES module) and `index.cjs` (CommonJS) with `index.d.ts` type declarations.
@@ -232,17 +396,26 @@ npm link @man4ish/ui
232396
```
233397
omnibioai-ui/
234398
├── src/
235-
│ ├── index.ts ← package entry — re-exports all components
236-
│ ├── Button/
237-
│ ├── Badge/
238-
│ ├── Card/
239-
│ ├── Input/
240-
│ ├── StatusDot/
241-
│ └── Spinner/
242-
├── vite.config.ts ← library build config (ES + CJS, React external)
399+
│ ├── index.ts
400+
│ ├── test-setup.ts
401+
│ ├── components/
402+
│ │ ├── Button/ (Button.tsx, Button.css, Button.test.tsx, Button.stories.tsx)
403+
│ │ ├── Badge/ (Badge.tsx, Badge.css, Badge.test.tsx, Badge.stories.tsx)
404+
│ │ ├── Card/ (Card.tsx, Card.css, Card.test.tsx, Card.stories.tsx)
405+
│ │ ├── Input/ (Input.tsx, Input.css, Input.test.tsx, Input.stories.tsx)
406+
│ │ ├── StatusDot/ (StatusDot.tsx, StatusDot.css, StatusDot.test.tsx, StatusDot.stories.tsx)
407+
│ │ ├── Spinner/ (Spinner.tsx, Spinner.css, Spinner.test.tsx, Spinner.stories.tsx)
408+
│ │ ├── Table/ (Table.tsx, Table.css, Table.test.tsx, Table.stories.tsx)
409+
│ │ ├── Tabs/ (Tabs.tsx, Tabs.css, Tabs.test.tsx, Tabs.stories.tsx)
410+
│ │ ├── ProgressBar/ (ProgressBar.tsx, ProgressBar.css, ProgressBar.test.tsx, ProgressBar.stories.tsx)
411+
│ │ ├── Tooltip/ (Tooltip.tsx, Tooltip.css, Tooltip.test.tsx, Tooltip.stories.tsx)
412+
│ │ └── Select/ (Select.tsx, Select.css, Select.test.tsx, Select.stories.tsx)
413+
├── .storybook/
414+
├── vite.config.ts ← library build config
415+
├── vitest.config.ts ← test config (separate from vite)
243416
├── tsconfig.json
244-
├── package.json ← published as @man4ish/ui to GitHub Packages
245-
└── .npmrc ← scoped registry config
417+
├── CHANGELOG.md
418+
└── package.json
246419
```
247420

248421
---
@@ -264,6 +437,7 @@ Components reference CSS custom properties from `@man4ish/design-tokens`. No com
264437
| [`@man4ish/design-tokens`](https://github.com/man4ish/omnibioai-design-tokens) | CSS custom properties — required peer dependency |
265438
| [`omnibioai-studio`](https://github.com/man4ish/omnibioai-studio) | Electron + React app — primary consumer |
266439
| [`omnibioai`](https://github.com/man4ish/omnibioai) | Django backend — 150+ plugin bioinformatics platform |
440+
| `omnibioai-control-center` | Health dashboard + ecosystem report (consumes design tokens) |
267441

268442
---
269443

0 commit comments

Comments
 (0)