UI Component Library
UI Component Library
Section titled “UI Component Library”Package: @nexischat/ui Design System: Atomic Design (Atoms → Molecules → Organisms) Styling: TailwindCSS 4 + Radix UI primitives Testing: Storybook 9 + Vitest + Chromatic Generated: 2026-01-04
Overview
Section titled “Overview”The shared UI component library follows Atomic Design principles:
- Atoms: Basic building blocks (buttons, inputs, badges)
- Molecules: Combinations of atoms (form fields, cards with actions)
- Organisms: Complex components (chat lists, subscription panels)
All components are built with:
- TypeScript for type safety
- Radix UI for accessible primitives
- TailwindCSS 4 for styling
cvafor variant management- Full dark mode support via CSS variables
Installation
Section titled “Installation”pnpm add @nexischat/uiButton
Section titled “Button”Primary action component with multiple variants.
import { Button } from '@nexischat/ui/atoms/button'
;<Button variant="default" size="md" disabled={false}> Click Me</Button>Variants: default, destructive, outline, secondary, ghost, link
Sizes: sm, default, lg, icon
Text input with optional icon slots.
import { Input } from '@nexischat/ui/atoms/input'
;<Input type="text" placeholder="Enter text..." startIcon={<SearchIcon />} />Status indicators and labels.
import { Badge } from '@nexischat/ui/atoms/badge'
<Badge variant="default">Active</Badge><Badge variant="secondary">Pending</Badge><Badge variant="destructive">Error</Badge><Badge variant="outline">Draft</Badge>Avatar
Section titled “Avatar”User/contact profile images with fallback.
import { Avatar, AvatarImage, AvatarFallback } from '@nexischat/ui/atoms/avatar'
;<Avatar> <AvatarImage src={user.avatar} alt={user.name} /> <AvatarFallback>{user.initials}</AvatarFallback></Avatar>Checkbox / Switch
Section titled “Checkbox / Switch”Toggle inputs.
import { Checkbox } from '@nexischat/ui/atoms/checkbox'import { Switch } from '@nexischat/ui/atoms/switch'
<Checkbox checked={value} onCheckedChange={setValue} /><Switch checked={enabled} onCheckedChange={setEnabled} />Form labels with accessibility.
import { Label } from '@nexischat/ui/atoms/label'
;<Label htmlFor="email">Email Address</Label>Separator
Section titled “Separator”Visual dividers.
import { Separator } from '@nexischat/ui/atoms/separator'
;<Separator orientation="horizontal" />Skeleton
Section titled “Skeleton”Loading placeholders.
import { Skeleton } from '@nexischat/ui/atoms/skeleton'
;<Skeleton className="h-4 w-[200px]" />Spinner
Section titled “Spinner”Loading indicators.
import { Spinner } from '@nexischat/ui/atoms/spinner'
;<Spinner size="md" />Typography
Section titled “Typography”Text components with semantic variants.
import { Heading, Text, Paragraph } from '@nexischat/ui/atoms/typography'
<Heading level={1}>Main Title</Heading><Paragraph>Body text content...</Paragraph><Text variant="muted">Secondary text</Text>Other Atoms
Section titled “Other Atoms”ScrollArea- Custom scrollbarsTextarea- Multi-line text inputProgress- Progress barsTooltip- Hover hintsKBD- Keyboard shortcuts display
Molecules
Section titled “Molecules”Content containers with header, content, footer.
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter} from '@nexischat/ui/molecules/card'
;<Card> <CardHeader> <CardTitle>Card Title</CardTitle> <CardDescription>Card description</CardDescription> </CardHeader> <CardContent>{/* Content */}</CardContent> <CardFooter> <Button>Action</Button> </CardFooter></Card>Dialog
Section titled “Dialog”Modal dialogs with accessible focus management.
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose} from '@nexischat/ui/molecules/dialog'
;<Dialog> <DialogTrigger asChild> <Button>Open Dialog</Button> </DialogTrigger> <DialogContent> <DialogHeader> <DialogTitle>Dialog Title</DialogTitle> <DialogDescription>Description text</DialogDescription> </DialogHeader> {/* Content */} <DialogFooter> <DialogClose asChild> <Button variant="outline">Cancel</Button> </DialogClose> <Button>Confirm</Button> </DialogFooter> </DialogContent></Dialog>DropdownMenu
Section titled “DropdownMenu”Context menus and action menus.
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator} from '@nexischat/ui/molecules/dropdown-menu'
;<DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="ghost" size="icon"> <MoreVertical /> </Button> </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuItem>Edit</DropdownMenuItem> <DropdownMenuItem>Duplicate</DropdownMenuItem> <DropdownMenuSeparator /> <DropdownMenuItem variant="destructive">Delete</DropdownMenuItem> </DropdownMenuContent></DropdownMenu>Form Components
Section titled “Form Components”Form handling with react-hook-form integration.
import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage} from '@nexischat/ui/molecules/form'
;<Form {...form}> <FormField control={form.control} name="email" render={({ field }) => ( <FormItem> <FormLabel>Email</FormLabel> <FormControl> <Input {...field} /> </FormControl> <FormDescription>Your work email</FormDescription> <FormMessage /> </FormItem> )} /></Form>Select
Section titled “Select”Dropdown selection with search.
import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem} from '@nexischat/ui/molecules/select'
;<Select value={value} onValueChange={setValue}> <SelectTrigger> <SelectValue placeholder="Select..." /> </SelectTrigger> <SelectContent> <SelectItem value="option1">Option 1</SelectItem> <SelectItem value="option2">Option 2</SelectItem> </SelectContent></Select>Tabbed interfaces.
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@nexischat/ui/molecules/tabs'
;<Tabs defaultValue="tab1"> <TabsList> <TabsTrigger value="tab1">Tab 1</TabsTrigger> <TabsTrigger value="tab2">Tab 2</TabsTrigger> </TabsList> <TabsContent value="tab1">Content 1</TabsContent> <TabsContent value="tab2">Content 2</TabsContent></Tabs>Alert / AlertDialog
Section titled “Alert / AlertDialog”Notifications and confirmation dialogs.
import { Alert, AlertTitle, AlertDescription } from '@nexischat/ui/molecules/alert'import { AlertDialog, AlertDialogAction, AlertDialogCancel} from '@nexischat/ui/molecules/alert-dialog'
;<Alert variant="destructive"> <AlertTitle>Error</AlertTitle> <AlertDescription>Something went wrong.</AlertDescription></Alert>Toast / Sonner
Section titled “Toast / Sonner”Toast notifications (via Sonner).
import { toast } from '@nexischat/ui/molecules/sonner'
toast.success('Message sent!')toast.error('Failed to send message')toast.loading('Sending...')Other Molecules
Section titled “Other Molecules”Accordion- Collapsible sectionsCollapsible- Toggle visibilityCommand- Command palette (cmdk)Popover- Floating contentSheet- Slide-out panelsTable- Data tablesBreadcrumb- Navigation pathPagination- Page navigationRadioGroup- Single selectionSlider- Range inputCalendar- Date pickerHoverCard- Rich hover content
Organisms
Section titled “Organisms”ConversationCard
Section titled “ConversationCard”Chat conversation preview card.
import { ConversationCard } from '@nexischat/ui/organisms/conversation-card'
;<ConversationCard conversation={{ id: '123', name: 'John Doe', lastMessage: 'Hello!', timestamp: new Date(), unreadCount: 3, avatar: '/avatars/john.jpg', isOnline: true }} isSelected={selected} onClick={() => selectConversation('123')}/>MessageItem
Section titled “MessageItem”Individual chat message bubble.
import { MessageItem } from '@nexischat/ui/organisms/message-item'
;<MessageItem message={{ id: 'msg1', content: 'Hello, how are you?', timestamp: new Date(), sender: { name: 'John', avatar: '...' }, isOwn: false, status: 'read' }}/>ChatList
Section titled “ChatList”Scrollable conversation list.
import { ChatList } from '@nexischat/ui/organisms/chat-list'
;<ChatList conversations={conversations} selectedId={selectedConversationId} onSelect={setSelectedConversationId} isLoading={isLoading}/>Sidebar
Section titled “Sidebar”App navigation sidebar.
import { Sidebar, SidebarHeader, SidebarContent, SidebarFooter} from '@nexischat/ui/organisms/sidebar'
;<Sidebar> <SidebarHeader> <Logo /> </SidebarHeader> <SidebarContent> <NavLinks /> </SidebarContent> <SidebarFooter> <UserMenu /> </SidebarFooter></Sidebar>SubscriptionPlans
Section titled “SubscriptionPlans”Pricing table component.
import { SubscriptionPlans } from '@nexischat/ui/organisms/subscription-plans'
;<SubscriptionPlans currentPlan="free" onSelectPlan={handleSelectPlan} isLoading={isCheckingOut} />DataTable
Section titled “DataTable”Full-featured data table with sorting, filtering, pagination.
import { DataTable } from '@nexischat/ui/organisms/data-table'
;<DataTable columns={columns} data={data} searchKey="name" pagination sorting />Other Organisms
Section titled “Other Organisms”AccountSelector- WhatsApp account switcherFolderList- Chat folder managementTemplateEditor- Message template editingQRCodeScanner- WhatsApp QR auth displayProfileEditor- User profile form
Utilities
Section titled “Utilities”cn() - Class Name Merger
Section titled “cn() - Class Name Merger”import { cn } from '@nexischat/ui/lib/utils'
;<div className={cn('base-class', conditional && 'conditional-class')} />Theme Provider
Section titled “Theme Provider”import { ThemeProvider } from '@nexischat/ui/providers/theme'
;<ThemeProvider defaultTheme="system" storageKey="nexischat-theme"> <App /></ThemeProvider>Storybook
Section titled “Storybook”Run Storybook locally:
cd packages/uipnpm storybookStories are located alongside components:
src/ atoms/ button/ button.tsx button.stories.tsx molecules/ card/ card.tsx card.stories.tsxTesting
Section titled “Testing”Components are tested with:
- Unit Tests: Vitest + Testing Library
- Visual Regression: Chromatic
- Accessibility: axe-core via Storybook
# Run unit testspnpm test
# Run Storybook testspnpm test:storybookDesign Tokens
Section titled “Design Tokens”CSS variables are defined in src/styles/globals.css:
:root { --background: 0 0% 100%; --foreground: 240 10% 3.9%; --card: 0 0% 100%; --card-foreground: 240 10% 3.9%; --primary: 142.1 76.2% 36.3%; --primary-foreground: 355.7 100% 97.3%; /* ... */}
.dark { --background: 240 10% 3.9%; --foreground: 0 0% 98%; /* ... */}