@iotype/casys
v0.1.4
Published
React + TypeScript component library for building CA-style practice management apps — designed by Iotypes Private Limited.
Maintainers
Readme
@iotype/casys
React + TypeScript component library for building CA-style practice management apps — designed by Iotypes Private Limited.
- 20+ components, all typed (
.d.tsshipped) - Zero runtime dependencies beyond React — uses only native DOM + CSS
- One stylesheet, one import — no CSS-in-JS, no Tailwind, no build-step gymnastics
- Design tokens exposed as CSS variables — override any colour, radius, or font at a single selector
- Ships ESM + CJS, Node / Vite / Next / CRA all work
Install
npm install @iotype/casys
# peer deps
npm install react react-domUsage
// 1. Import the stylesheet once, at the app entry point.
import '@iotype/casys/styles.css';
// 2. Use components.
import {
AppShell, Sidebar, SidebarBrand, NavGroup, NavItem,
PageHeader, PageContent,
KPIRow, KPI,
Button, Badge, HomeIcon, LayersIcon, PlusIcon,
} from '@iotype/casys';
export function Dashboard() {
return (
<AppShell
sidebar={
<Sidebar>
<SidebarBrand mark="M" name="Mehta & Co." role="Rohan · Admin" />
<NavGroup label="Practice">
<NavItem icon={<HomeIcon />} label="Overview" active />
<NavItem icon={<LayersIcon />} label="Tasks" count={12} />
</NavGroup>
</Sidebar>
}
>
<PageHeader
title="Overview"
subtitle="Your practice at a glance"
actions={<Button variant="accent" leftIcon={<PlusIcon />}>New task</Button>}
/>
<PageContent>
<KPIRow>
<KPI label="Overdue" value={4} delta="Needs attention" danger />
<KPI label="Due in 7 days" value={9} delta="Across 6 clients" />
<KPI label="Awaiting docs" value={3} delta="Auto-reminded" />
<KPI label="Active tasks" value={28} delta="82 clients total" />
</KPIRow>
</PageContent>
</AppShell>
);
}Component index
| Category | Components |
|---|---|
| Primitives | Button, Badge, Avatar, Icon + 28 named glyphs |
| Layout | AppShell, PageHeader, PageContent, Sidebar, SidebarBrand, NavGroup, NavItem, TopBar, TopBarTab, TopBarPill |
| Data display | KPI, KPIRow, Panel, Section, EmptyHint, DataTable<T>, DetailCard, KeyValue, DetailSide, TwoCol, Timeline, TimelineItem, DocumentList, DocumentRow, Calendar, ServiceCard, ServiceGrid, ServiceCardChip, ClientCell |
| Forms | Field, FieldRow, Input, Select, Textarea, UploadDrop, Composer |
| Overlays | Modal |
| Helpers | formatDate, formatDateTime, daysUntil, getInitials, STATUS_META |
| Types | TaskStatus, TaskPriority, Client, Service, Task, TeamMember |
Run the Previewer (npm run preview from the repo root) for live examples, code snippets, and prop tables for every component.
Theming
Override any token at :root — or a scoped class if you want a themed subtree:
/* Change the brand accent globally */
:root {
--accent: #0EA5E9;
--accent-soft: #E0F2FE;
--accent-ink: #0369A1;
}
/* Or only inside .client-portal */
.client-portal {
--bg: #FAFAF7;
--ink: #1F1E1A;
}Full token list lives in @iotype/casys/tokens.css (also re-exported in styles.css).
Generic DataTable
DataTable<T> is the one component that meaningfully benefits from generics — it gives you typed row access inside column renderers:
interface Task { id: string; client: string; due: string; status: TaskStatus }
<DataTable<Task>
rows={tasks}
getRowKey={t => t.id}
onRowClick={t => open(t.id)}
isRowSelected={t => t.id === selectedId}
columns={[
{ key: 'client', header: 'Client', render: t => <ClientCell name={t.client} /> },
{ key: 'due', header: 'Due', render: t => formatDate(t.due) },
{
key: 'status', header: 'Status',
render: t => {
const m = STATUS_META[t.status];
return <Badge tone={m.tone}>{m.label}</Badge>;
},
},
]}
/>Conventions
- CSS class names are preserved verbatim from the original app (
btn,badge,kpi,ca-sidebar, etc.). If you've already been hand-rolling markup against these classes, the components are fully compatible — switch incrementally, class by class. - All components forward standard HTML props (
onClick,style,className,aria-*) unless explicitly typed to prevent collisions (see note ontitlebelow). titleprop naming: Some components accepttitleas a content prop (e.g.Panel,Section,ServiceCard). Where this would have collided with the native HTMLtitletooltip, thetitletooltip attribute has been omitted from the component's accepted props. Usearia-labelinstead if you need a tooltip.
Building locally
npm install
npm run typecheck # tsc --noEmit
npm run build # tsup → dist/ (ESM + CJS + .d.ts)
npm run preview # opens the component previewerLicense
MIT
