@nsxbet/admin-ui
v0.2.0
Published
UI component library for NSX Admin modules
Downloads
239
Maintainers
Readme
@nsxbet/admin-ui
UI component library for NSX Admin admin modules. Based on shadcn/ui with the Brasa Design System theme.
Installation
bun add @nsxbet/admin-uiSetup
1. Import CSS
In your src/index.css:
@import "@nsxbet/admin-ui/styles.css";
@tailwind base;
@tailwind components;
@tailwind utilities;2. Configure Tailwind
Recommended - Use withAdminSdk from the SDK (automatically includes the preset and content paths):
import { withAdminSdk } from "@nsxbet/admin-sdk/tailwind";
/** @type {import('tailwindcss').Config} */
export default withAdminSdk({
content: ["./index.html", "./src/**/*.{ts,tsx}"],
});Alternative - Use the preset directly (requires manual content paths):
import { preset } from "@nsxbet/admin-ui/tailwind-preset";
/** @type {import('tailwindcss').Config} */
export default {
presets: [preset],
content: [
"./index.html",
"./src/**/*.{ts,tsx}",
],
};The preset includes all theme colors, animations, and the tailwindcss-animate plugin.
Component Catalog
Buttons
import { Button } from "@nsxbet/admin-ui";
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
<Button size="sm">Small</Button>
<Button size="default">Default</Button>
<Button size="lg">Large</Button>
<Button size="icon"><Plus /></Button>Cards
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
} from "@nsxbet/admin-ui";
<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description text</CardDescription>
</CardHeader>
<CardContent>
<p>Card content goes here.</p>
</CardContent>
<CardFooter>
<Button>Action</Button>
</CardFooter>
</Card>Badges
import { Badge } from "@nsxbet/admin-ui";
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Error</Badge>
<Badge variant="outline">Outline</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="info">Info</Badge>Form Inputs
import { Input, Label, Textarea, Checkbox, Switch } from "@nsxbet/admin-ui";
// Text input
<div>
<Label htmlFor="name">Name</Label>
<Input id="name" placeholder="Enter name" />
</div>
// Textarea
<div>
<Label htmlFor="description">Description</Label>
<Textarea id="description" placeholder="Enter description" />
</div>
// Checkbox
<div className="flex items-center gap-2">
<Checkbox id="terms" />
<Label htmlFor="terms">Accept terms</Label>
</div>
// Switch
<div className="flex items-center gap-2">
<Switch id="notifications" />
<Label htmlFor="notifications">Enable notifications</Label>
</div>Select
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectItem,
} from "@nsxbet/admin-ui";
<Select>
<SelectTrigger>
<SelectValue placeholder="Select option" />
</SelectTrigger>
<SelectContent>
<SelectItem value="option1">Option 1</SelectItem>
<SelectItem value="option2">Option 2</SelectItem>
<SelectItem value="option3">Option 3</SelectItem>
</SelectContent>
</Select>Tables
import {
Table,
TableHeader,
TableBody,
TableRow,
TableHead,
TableCell,
} from "@nsxbet/admin-ui";
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>John Doe</TableCell>
<TableCell>[email protected]</TableCell>
<TableCell><Badge variant="success">Active</Badge></TableCell>
</TableRow>
</TableBody>
</Table>Dialog
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
} from "@nsxbet/admin-ui";
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>
This is a dialog description.
</DialogDescription>
</DialogHeader>
<div className="py-4">
Dialog content goes here.
</div>
<DialogFooter>
<Button variant="outline">Cancel</Button>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>Sheet (Slide-out Panel)
import {
Sheet,
SheetTrigger,
SheetContent,
SheetHeader,
SheetTitle,
SheetDescription,
} from "@nsxbet/admin-ui";
<Sheet>
<SheetTrigger asChild>
<Button>Open Panel</Button>
</SheetTrigger>
<SheetContent>
<SheetHeader>
<SheetTitle>Panel Title</SheetTitle>
<SheetDescription>Panel description</SheetDescription>
</SheetHeader>
<div className="py-4">Panel content</div>
</SheetContent>
</Sheet>Tabs
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@nsxbet/admin-ui";
<Tabs defaultValue="tab1">
<TabsList>
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Tab 1 content</TabsContent>
<TabsContent value="tab2">Tab 2 content</TabsContent>
</Tabs>Dropdown Menu
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
} from "@nsxbet/admin-ui";
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Options</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Duplicate</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>Tooltip
import {
Tooltip,
TooltipTrigger,
TooltipContent,
TooltipProvider,
} from "@nsxbet/admin-ui";
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline">Hover me</Button>
</TooltipTrigger>
<TooltipContent>
<p>Tooltip content</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>Alert
import { Alert, AlertTitle, AlertDescription } from "@nsxbet/admin-ui";
<Alert>
<AlertTitle>Information</AlertTitle>
<AlertDescription>This is an informational alert.</AlertDescription>
</Alert>
<Alert variant="destructive">
<AlertTitle>Error</AlertTitle>
<AlertDescription>Something went wrong.</AlertDescription>
</Alert>ScrollArea
import { ScrollArea } from "@nsxbet/admin-ui";
<ScrollArea className="h-[200px]">
<div className="p-4">
{/* Long content that scrolls */}
</div>
</ScrollArea>Separator
import { Separator } from "@nsxbet/admin-ui";
<div>
<p>Above separator</p>
<Separator className="my-4" />
<p>Below separator</p>
</div>Skeleton (Loading Placeholder)
import { Skeleton } from "@nsxbet/admin-ui";
<div className="space-y-2">
<Skeleton className="h-4 w-[250px]" />
<Skeleton className="h-4 w-[200px]" />
<Skeleton className="h-4 w-[150px]" />
</div>Data Components
LoadingState
import { LoadingState } from "@nsxbet/admin-ui";
<LoadingState />
<LoadingState text="Loading items..." />
<LoadingState size="sm" />
<LoadingState size="lg" />
<LoadingState fullPage />EmptyState
import { EmptyState } from "@nsxbet/admin-ui";
<EmptyState
title="No items found"
description="Get started by creating your first item."
action={{
label: "Create Item",
onClick: () => console.log("create"),
}}
/>StatusBadge
import { StatusBadge } from "@nsxbet/admin-ui";
<StatusBadge status="active" />
<StatusBadge status="inactive" />
<StatusBadge status="pending" />
<StatusBadge status="error" />
<StatusBadge status="success" />
<StatusBadge status="warning" />DataTable
import { DataTable } from "@nsxbet/admin-ui";
const columns = [
{ accessor: "name" as const, header: "Name" },
{ accessor: "email" as const, header: "Email" },
{
accessor: "status" as const,
header: "Status",
cell: (value: string) => <StatusBadge status={value as any} />,
},
];
<DataTable
data={users}
columns={columns}
loading={isLoading}
emptyState={{
title: "No users",
description: "Add your first user",
}}
/>Icon Component
Render Lucide icons dynamically by name (kebab-case):
import { Icon } from "@nsxbet/admin-ui";
<Icon name="clipboard-list" className="h-4 w-4" />
<Icon name="file-text" className="h-4 w-4" />
<Icon name="users" size={24} />
<Icon name="plus" className="h-4 w-4 text-primary" />Direct Icon Imports
For static icons, import directly:
import {
Plus,
Edit,
Trash,
Check,
X,
Search,
ChevronRight,
User,
Users,
Settings,
Home,
FileText,
ClipboardList,
} from "@nsxbet/admin-ui";
<Plus className="h-4 w-4" />
<Edit className="h-4 w-4" />
<Trash className="h-4 w-4 text-destructive" />Available Icons
| Category | Icons |
|----------|-------|
| Navigation | ChevronRight, ChevronLeft, ChevronDown, ChevronUp, Search, Menu, X, Home, Settings, LogOut, PanelLeft |
| Actions | Plus, Minus, Edit, Trash, Trash2, Copy, Pin, Clock, Star, Sparkles, Crown, Wrench |
| Status | Check, AlertCircle, Info, AlertTriangle, Ban, Lock, Unlock, Eye |
| Content | File, FileText, Folder, ClipboardList, Calendar, Mail, Phone |
| Users | User, Users |
| Theme | Sun, Moon |
Theming
The UI uses CSS variables for theming. Default is dark mode (Brasa Design System).
Color Tokens
| Token | Usage |
|-------|-------|
| --primary | Primary actions, links |
| --secondary | Secondary elements |
| --background | Page background |
| --foreground | Text color |
| --card | Card surfaces |
| --muted | Muted text/backgrounds |
| --accent | Accent elements |
| --destructive | Error/destructive actions |
| --success | Success states |
| --warning | Warning states |
| --info | Informational states |
Using Colors
// Text colors
<p className="text-primary">Primary text</p>
<p className="text-muted-foreground">Muted text</p>
<p className="text-destructive">Error text</p>
<p className="text-success">Success text</p>
// Background colors
<div className="bg-background">Page background</div>
<div className="bg-card">Card background</div>
<div className="bg-muted">Muted background</div>
<div className="bg-primary text-primary-foreground">Primary button</div>Utilities
cn() - Class Name Merger
import { cn } from "@nsxbet/admin-ui";
<div className={cn("base-class", isActive && "active-class", className)}>
Content
</div>DO NOT (Common Mistakes)
❌ DO NOT forget to import styles
/* WRONG - missing import */
@tailwind base;
@tailwind components;
@tailwind utilities;/* CORRECT - import before tailwind directives */
@import "@nsxbet/admin-ui/styles.css";
@tailwind base;
@tailwind components;
@tailwind utilities;❌ DO NOT forget to use the preset
// WRONG - manual theme configuration
export default {
content: ["./src/**/*.{ts,tsx}"],
theme: { /* manually copying colors... */ }
}// CORRECT - use withAdminSdk from SDK (recommended)
import { withAdminSdk } from "@nsxbet/admin-sdk/tailwind";
export default withAdminSdk({
content: ["./index.html", "./src/**/*.{ts,tsx}"],
});❌ DO NOT import SDK hooks from UI
// WRONG - hooks are in SDK, not UI
import { useAuth } from "@nsxbet/admin-ui"; // ❌// CORRECT - import from SDK
import { useAuth } from "@nsxbet/admin-sdk"; // ✅
import { Button, Card } from "@nsxbet/admin-ui"; // ✅License
UNLICENSED - Internal use only
