UI library
The @africaos/ui component package - structure, theming, and conventions.
@africaos/ui is the shared React component library used by the web app and the application modules. It provides everything from primitives (Button, Input) to complex composed components (Sidebar, Combobox, DataTable-style tables), all styled with Tailwind v4.
The component surface
The library exports a broad surface (see packages/ui/src/index.ts):
- Primitives -
Button,Badge,Card,Input,Textarea,Label,Checkbox,Switch,Slider,Separator,Spinner,Skeleton. - Data display -
Avatar(+ group/badge),Table,Tabs,Badge,Calendar,Chart(ChartContainer/Tooltip/Legend),Progress. - Overlays -
Dialog,Sheet,Drawer,Popover,HoverCard,Tooltip,DropdownMenu,ContextMenu,Menubar,AlertDialog,Command(palette). - Forms -
Field(label/description/error group),FormField,FormSection,TextField,FormCard,InputOTP,Combobox,Select,NativeSelect,RadioGroup,Questionnaire(wizard),PasswordStrength,zodFormValidator. - Layout & navigation -
Sidebar(full composition set),Breadcrumb,NavigationMenu,Pagination,Resizable,Carousel,ScrollArea,Collapsible,Accordion. - Status & feedback -
Toast(withcreateToastManager),Alert,Empty,ErrorBoundary,TopLoader,Skeleton. - Utilities -
cn,getInitials,formatCurrency,useIsMobile,ThemeProvider/useTheme,DirectionProvider.
How to use it
Components are exported as named exports from @africaos/ui:
import { Button, Card, CardHeader, CardTitle, CardContent } from "@africaos/ui";
export function ProductCard() {
return (
<Card>
<CardHeader>
<CardTitle>Product</CardTitle>
</CardHeader>
<CardContent>
<Button>Save</Button>
</CardContent>
</Card>
);
}
Most components follow the shadcn-style compound-component pattern: a root component plus subcomponents (CardHeader, CardContent, DialogContent, …). They accept standard React props; variant classes are exposed through exports like buttonVariants and badgeVariants.
Theming
ThemeProvider + useTheme handle light/dark mode. The library uses Tailwind v4 with a token-based design (design tokens like bg-background, text-muted-foreground). Follow the theme in the consuming app’s CSS rather than hardcoding colors.
The form primitives
Forms are a first-class concern. The Field group composes label, description, and error:
import { Field, FieldLabel, FieldDescription, FieldError, Input } from "@africaos/ui";
<Field>
<FieldLabel htmlFor="name">Name</FieldLabel>
<Input id="name" />
<FieldDescription>Visible to customers.</FieldDescription>
<FieldError>Name is required.</FieldError>
</Field>
zodFormValidator bridges Zod schemas to the form’s validation, so the same schema that validates server input also validates the client form.
Conventions
- Import from the package root. Never deep-import
@africaos/ui/components/ui/button. - Compose, don’t fork. If the library covers your need, use it. New primitives belong in the library, not in app code.
- Keep application chrome in the app. The web app and admin console build their own layouts on top of the library’s
Sidebarcomposition set.
Next steps
- Data fetching - how components get their data.
- TanStack Start - the framework layer beneath.