create-app-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/boilerplate/README.md +18 -0
  4. package/boilerplate/react-base/.env.example +1 -0
  5. package/boilerplate/react-base/README.md +3 -0
  6. package/boilerplate/react-base/components.json +19 -0
  7. package/boilerplate/react-base/eslint.config.js +32 -0
  8. package/boilerplate/react-base/index.html +12 -0
  9. package/boilerplate/react-base/package.json +71 -0
  10. package/boilerplate/react-base/postcss.config.js +6 -0
  11. package/boilerplate/react-base/prettier.config.js +6 -0
  12. package/boilerplate/react-base/src/api/axios.ts +20 -0
  13. package/boilerplate/react-base/src/app/store.ts +13 -0
  14. package/boilerplate/react-base/src/components/data-table.tsx +919 -0
  15. package/boilerplate/react-base/src/components/ui/accordion.tsx +44 -0
  16. package/boilerplate/react-base/src/components/ui/alert-dialog.tsx +105 -0
  17. package/boilerplate/react-base/src/components/ui/alert.tsx +40 -0
  18. package/boilerplate/react-base/src/components/ui/avatar.tsx +30 -0
  19. package/boilerplate/react-base/src/components/ui/badge.tsx +27 -0
  20. package/boilerplate/react-base/src/components/ui/bar-chart.tsx +76 -0
  21. package/boilerplate/react-base/src/components/ui/breadcrumb.tsx +87 -0
  22. package/boilerplate/react-base/src/components/ui/button.tsx +34 -0
  23. package/boilerplate/react-base/src/components/ui/calendar.tsx +63 -0
  24. package/boilerplate/react-base/src/components/ui/card.tsx +36 -0
  25. package/boilerplate/react-base/src/components/ui/chart.tsx +280 -0
  26. package/boilerplate/react-base/src/components/ui/checkbox.tsx +51 -0
  27. package/boilerplate/react-base/src/components/ui/context-menu.tsx +173 -0
  28. package/boilerplate/react-base/src/components/ui/date-picker.tsx +42 -0
  29. package/boilerplate/react-base/src/components/ui/dialog.tsx +87 -0
  30. package/boilerplate/react-base/src/components/ui/drawer.tsx +81 -0
  31. package/boilerplate/react-base/src/components/ui/dropdown-menu.tsx +81 -0
  32. package/boilerplate/react-base/src/components/ui/dropdown-types.ts +28 -0
  33. package/boilerplate/react-base/src/components/ui/field.tsx +194 -0
  34. package/boilerplate/react-base/src/components/ui/hover-card.tsx +26 -0
  35. package/boilerplate/react-base/src/components/ui/input-group.tsx +98 -0
  36. package/boilerplate/react-base/src/components/ui/input-otp.tsx +63 -0
  37. package/boilerplate/react-base/src/components/ui/input.tsx +12 -0
  38. package/boilerplate/react-base/src/components/ui/item.tsx +152 -0
  39. package/boilerplate/react-base/src/components/ui/kbd.tsx +13 -0
  40. package/boilerplate/react-base/src/components/ui/label.tsx +14 -0
  41. package/boilerplate/react-base/src/components/ui/line-chart.tsx +65 -0
  42. package/boilerplate/react-base/src/components/ui/menubar.tsx +217 -0
  43. package/boilerplate/react-base/src/components/ui/multi-select-dropdown.tsx +200 -0
  44. package/boilerplate/react-base/src/components/ui/navigation-menu.tsx +120 -0
  45. package/boilerplate/react-base/src/components/ui/pie-chart.tsx +87 -0
  46. package/boilerplate/react-base/src/components/ui/popover.tsx +29 -0
  47. package/boilerplate/react-base/src/components/ui/progress.tsx +19 -0
  48. package/boilerplate/react-base/src/components/ui/radio-group.tsx +36 -0
  49. package/boilerplate/react-base/src/components/ui/scroll-area.tsx +38 -0
  50. package/boilerplate/react-base/src/components/ui/searchable-dropdown.tsx +118 -0
  51. package/boilerplate/react-base/src/components/ui/select.tsx +140 -0
  52. package/boilerplate/react-base/src/components/ui/separator.tsx +20 -0
  53. package/boilerplate/react-base/src/components/ui/sheet.tsx +70 -0
  54. package/boilerplate/react-base/src/components/ui/sidebar.tsx +470 -0
  55. package/boilerplate/react-base/src/components/ui/skeleton.tsx +11 -0
  56. package/boilerplate/react-base/src/components/ui/slider.tsx +23 -0
  57. package/boilerplate/react-base/src/components/ui/sonner.tsx +21 -0
  58. package/boilerplate/react-base/src/components/ui/sparkline.tsx +38 -0
  59. package/boilerplate/react-base/src/components/ui/spinner.tsx +10 -0
  60. package/boilerplate/react-base/src/components/ui/switch.tsx +16 -0
  61. package/boilerplate/react-base/src/components/ui/table.tsx +80 -0
  62. package/boilerplate/react-base/src/components/ui/tabs.tsx +32 -0
  63. package/boilerplate/react-base/src/components/ui/textarea.tsx +12 -0
  64. package/boilerplate/react-base/src/components/ui/toggle-group.tsx +49 -0
  65. package/boilerplate/react-base/src/components/ui/toggle.tsx +33 -0
  66. package/boilerplate/react-base/src/components/ui/tooltip.tsx +23 -0
  67. package/boilerplate/react-base/src/components/ui/typography.tsx +76 -0
  68. package/boilerplate/react-base/src/config/constants.ts +3 -0
  69. package/boilerplate/react-base/src/config/theme.ts +432 -0
  70. package/boilerplate/react-base/src/config/user.ts +52 -0
  71. package/boilerplate/react-base/src/context/theme-provider.tsx +12 -0
  72. package/boilerplate/react-base/src/features/auth/authSlice.ts +19 -0
  73. package/boilerplate/react-base/src/hooks/index.ts +1 -0
  74. package/boilerplate/react-base/src/hooks/use-mobile.ts +17 -0
  75. package/boilerplate/react-base/src/lib/utils.ts +6 -0
  76. package/boilerplate/react-base/src/routes/index.tsx +7 -0
  77. package/boilerplate/react-base/src/styles/globals.css +15 -0
  78. package/boilerplate/react-base/src/vite-env.d.ts +31 -0
  79. package/boilerplate/react-base/tailwind.config.ts +75 -0
  80. package/boilerplate/react-base/tsconfig.app.json +20 -0
  81. package/boilerplate/react-base/tsconfig.json +7 -0
  82. package/boilerplate/react-base/tsconfig.node.json +16 -0
  83. package/boilerplate/react-base/vite.config.ts +12 -0
  84. package/dist/bin/index.js +8 -0
  85. package/dist/src/cli-args.js +52 -0
  86. package/dist/src/generator.js +85 -0
  87. package/dist/src/installer.js +7 -0
  88. package/dist/src/paths.js +61 -0
  89. package/dist/src/prompts.js +79 -0
  90. package/dist/src/replace-placeholders.js +22 -0
  91. package/dist/src/utils.js +16 -0
  92. package/package.json +63 -0
  93. package/templates/admin-portal/README.md +26 -0
  94. package/templates/admin-portal/src/App.tsx +85 -0
  95. package/templates/admin-portal/src/assets/auth-hero.jpg +0 -0
  96. package/templates/admin-portal/src/assets/brand-logo.png +0 -0
  97. package/templates/admin-portal/src/components/app-breadcrumb.tsx +41 -0
  98. package/templates/admin-portal/src/components/app-header.tsx +20 -0
  99. package/templates/admin-portal/src/components/app-sidebar.tsx +78 -0
  100. package/templates/admin-portal/src/components/auth-layout.tsx +66 -0
  101. package/templates/admin-portal/src/components/dashboard-metric-card.tsx +105 -0
  102. package/templates/admin-portal/src/components/data-table.tsx +919 -0
  103. package/templates/admin-portal/src/components/layout-shell.tsx +23 -0
  104. package/templates/admin-portal/src/components/notifications-sheet.tsx +91 -0
  105. package/templates/admin-portal/src/components/sidebar-nav.tsx +164 -0
  106. package/templates/admin-portal/src/components/user-avatar.tsx +26 -0
  107. package/templates/admin-portal/src/components/user-menu.tsx +163 -0
  108. package/templates/admin-portal/src/config/branding.ts +17 -0
  109. package/templates/admin-portal/src/config/chart-data.ts +44 -0
  110. package/templates/admin-portal/src/config/navigation.ts +42 -0
  111. package/templates/admin-portal/src/context/auth-context.tsx +32 -0
  112. package/templates/admin-portal/src/lib/breadcrumbs.ts +58 -0
  113. package/templates/admin-portal/src/main.tsx +18 -0
  114. package/templates/admin-portal/src/pages/components/demo-columns.tsx +170 -0
  115. package/templates/admin-portal/src/pages/components.tsx +1368 -0
  116. package/templates/admin-portal/src/pages/dashboard.tsx +143 -0
  117. package/templates/admin-portal/src/pages/login.tsx +81 -0
  118. package/templates/admin-portal/src/pages/settings/notifications.tsx +31 -0
  119. package/templates/admin-portal/src/pages/settings/profile.tsx +26 -0
  120. package/templates/admin-portal/src/pages/signup.tsx +81 -0
  121. package/templates/admin-portal/src/pages/users.tsx +12 -0
  122. package/templates/admin-portal/tsconfig.json +10 -0
  123. package/templates/blank/README.md +15 -0
  124. package/templates/blank/src/App.tsx +5 -0
  125. package/templates/blank/src/main.tsx +15 -0
  126. package/templates/blank/src/pages/home.tsx +20 -0
  127. package/templates/blank/tsconfig.json +10 -0
  128. package/templates/tsconfig.overlay.base.json +7 -0
@@ -0,0 +1,1368 @@
1
+ import { AlertCircle, AlignCenter, AlignLeft, AlignRight, Bold, CalendarIcon, Inbox, Italic, Search, Terminal, Underline } from "lucide-react";
2
+ import { useState } from "react";
3
+ import { Link } from "react-router-dom";
4
+ import {
5
+ Accordion,
6
+ AccordionContent,
7
+ AccordionItem,
8
+ AccordionTrigger,
9
+ } from "@/components/ui/accordion";
10
+ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
11
+ import {
12
+ AlertDialog,
13
+ AlertDialogAction,
14
+ AlertDialogCancel,
15
+ AlertDialogContent,
16
+ AlertDialogDescription,
17
+ AlertDialogFooter,
18
+ AlertDialogHeader,
19
+ AlertDialogTitle,
20
+ AlertDialogTrigger,
21
+ } from "@/components/ui/alert-dialog";
22
+ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
23
+ import { Badge } from "@/components/ui/badge";
24
+ import {
25
+ Breadcrumb,
26
+ BreadcrumbEllipsis,
27
+ BreadcrumbItem,
28
+ BreadcrumbLink,
29
+ BreadcrumbList,
30
+ BreadcrumbPage,
31
+ BreadcrumbSeparator,
32
+ } from "@/components/ui/breadcrumb";
33
+ import { Button } from "@/components/ui/button";
34
+ import { Checkbox } from "@/components/ui/checkbox";
35
+ import { DatePicker } from "@/components/ui/date-picker";
36
+ import {
37
+ Drawer,
38
+ DrawerClose,
39
+ DrawerContent,
40
+ DrawerDescription,
41
+ DrawerFooter,
42
+ DrawerHeader,
43
+ DrawerTitle,
44
+ DrawerTrigger,
45
+ } from "@/components/ui/drawer";
46
+ import {
47
+ Field,
48
+ FieldContent,
49
+ FieldDescription,
50
+ FieldError,
51
+ FieldGroup,
52
+ FieldLabel,
53
+ FieldLegend,
54
+ FieldSeparator,
55
+ FieldSet,
56
+ } from "@/components/ui/field";
57
+ import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card";
58
+ import {
59
+ InputGroup,
60
+ InputGroupAddon,
61
+ InputGroupButton,
62
+ InputGroupInput,
63
+ InputGroupText,
64
+ } from "@/components/ui/input-group";
65
+ import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from "@/components/ui/input-otp";
66
+ import {
67
+ Item,
68
+ ItemActions,
69
+ ItemContent,
70
+ ItemDescription,
71
+ ItemGroup,
72
+ ItemMedia,
73
+ ItemTitle,
74
+ } from "@/components/ui/item";
75
+ import { Kbd, KbdGroup } from "@/components/ui/kbd";
76
+ import { Progress } from "@/components/ui/progress";
77
+ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
78
+ import { ScrollArea } from "@/components/ui/scroll-area";
79
+ import {
80
+ Select,
81
+ SelectContent,
82
+ SelectGroup,
83
+ SelectItem,
84
+ SelectLabel,
85
+ SelectTrigger,
86
+ SelectValue,
87
+ } from "@/components/ui/select";
88
+ import { Skeleton } from "@/components/ui/skeleton";
89
+ import { Slider } from "@/components/ui/slider";
90
+ import { Spinner } from "@/components/ui/spinner";
91
+ import { Switch } from "@/components/ui/switch";
92
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
93
+ import { Textarea } from "@/components/ui/textarea";
94
+ import { Toggle } from "@/components/ui/toggle";
95
+ import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
96
+ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
97
+ import {
98
+ TypographyBlockquote,
99
+ TypographyH1,
100
+ TypographyH2,
101
+ TypographyH3,
102
+ TypographyH4,
103
+ TypographyInlineCode,
104
+ TypographyLarge,
105
+ TypographyLead,
106
+ TypographyList,
107
+ TypographyMuted,
108
+ TypographyP,
109
+ TypographySmall,
110
+ } from "@/components/ui/typography";
111
+ import { toast } from "sonner";
112
+ import {
113
+ Menubar,
114
+ MenubarContent,
115
+ MenubarItem,
116
+ MenubarMenu,
117
+ MenubarSeparator,
118
+ MenubarShortcut,
119
+ MenubarTrigger,
120
+ } from "@/components/ui/menubar";
121
+ import {
122
+ NavigationMenu,
123
+ NavigationMenuContent,
124
+ NavigationMenuItem,
125
+ NavigationMenuLink,
126
+ NavigationMenuList,
127
+ NavigationMenuTrigger,
128
+ navigationMenuTriggerStyle,
129
+ } from "@/components/ui/navigation-menu";
130
+ import {
131
+ Dialog,
132
+ DialogContent,
133
+ DialogDescription,
134
+ DialogFooter,
135
+ DialogHeader,
136
+ DialogTitle,
137
+ DialogTrigger,
138
+ } from "@/components/ui/dialog";
139
+ import {
140
+ ContextMenu,
141
+ ContextMenuCheckboxItem,
142
+ ContextMenuContent,
143
+ ContextMenuItem,
144
+ ContextMenuLabel,
145
+ ContextMenuRadioGroup,
146
+ ContextMenuRadioItem,
147
+ ContextMenuSeparator,
148
+ ContextMenuShortcut,
149
+ ContextMenuSub,
150
+ ContextMenuSubContent,
151
+ ContextMenuSubTrigger,
152
+ ContextMenuTrigger,
153
+ } from "@/components/ui/context-menu";
154
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
155
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
156
+ import { Input } from "@/components/ui/input";
157
+ import { Label } from "@/components/ui/label";
158
+ import { Separator } from "@/components/ui/separator";
159
+ import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
160
+ import { DemoUsersDataTable } from "@/pages/components/demo-columns";
161
+ import { BarChart } from "@/components/ui/bar-chart";
162
+ import { LineChart } from "@/components/ui/line-chart";
163
+ import { MultiSelectDropdown } from "@/components/ui/multi-select-dropdown";
164
+ import { PieChart } from "@/components/ui/pie-chart";
165
+ import { SearchableDropdown } from "@/components/ui/searchable-dropdown";
166
+ import {
167
+ deviceUsageData,
168
+ monthlyRevenueData,
169
+ userRoleDistribution,
170
+ weeklyActiveUsersData,
171
+ } from "@/config/chart-data";
172
+ import {
173
+ activeUsersChartConfig,
174
+ deviceChartConfig,
175
+ revenueChartConfig,
176
+ roleChartConfig,
177
+ } from "@/config/theme";
178
+
179
+ const navComponents: { title: string; href: string; description: string }[] = [
180
+ {
181
+ title: "Alert Dialog",
182
+ href: "/components",
183
+ description: "A modal dialog that interrupts the user with important content.",
184
+ },
185
+ {
186
+ title: "Data Table",
187
+ href: "/components",
188
+ description: "Powerful table with sorting, pagination, and row actions.",
189
+ },
190
+ {
191
+ title: "Date Picker",
192
+ href: "/components",
193
+ description: "Calendar popover for selecting dates in forms.",
194
+ },
195
+ ];
196
+
197
+ export function ComponentsPage() {
198
+ const [open, setOpen] = useState(false);
199
+ const [date, setDate] = useState<Date>();
200
+ const [otp, setOtp] = useState("");
201
+ const [progress, setProgress] = useState(66);
202
+ const [plan, setPlan] = useState("comfortable");
203
+ const [role, setRole] = useState("admin");
204
+ const [framework, setFramework] = useState("");
205
+ const [skills, setSkills] = useState<string[]>(["react", "typescript"]);
206
+ const [volume, setVolume] = useState([50]);
207
+
208
+ const frameworkOptions = [
209
+ { value: "react", label: "React", description: "UI library for the web" },
210
+ { value: "vue", label: "Vue", description: "Progressive JavaScript framework" },
211
+ { value: "angular", label: "Angular", description: "Platform for building mobile & desktop apps" },
212
+ { value: "svelte", label: "Svelte", description: "Cybernetically enhanced web apps" },
213
+ { value: "next", label: "Next.js", description: "React framework for production" },
214
+ { value: "nuxt", label: "Nuxt", description: "Intuitive Vue framework" },
215
+ { value: "remix", label: "Remix", description: "Full stack web framework" },
216
+ { value: "astro", label: "Astro", description: "Content-focused web framework" },
217
+ ];
218
+
219
+ const skillOptions = [
220
+ { value: "react", label: "React" },
221
+ { value: "typescript", label: "TypeScript" },
222
+ { value: "tailwind", label: "Tailwind CSS" },
223
+ { value: "node", label: "Node.js" },
224
+ { value: "graphql", label: "GraphQL" },
225
+ { value: "postgres", label: "PostgreSQL" },
226
+ { value: "docker", label: "Docker" },
227
+ { value: "aws", label: "AWS" },
228
+ { value: "figma", label: "Figma" },
229
+ { value: "testing", label: "Testing", description: "Vitest, Playwright, RTL" },
230
+ ];
231
+
232
+ const scrollTags = Array.from({ length: 24 }, (_, index) => `Tag ${index + 1}`);
233
+
234
+ return (
235
+ <div className="space-y-6">
236
+ <div>
237
+ <h1 className="text-2xl font-semibold">Components</h1>
238
+ <p className="text-sm text-muted-foreground">shadcn-compatible component showcase.</p>
239
+ </div>
240
+
241
+ <Card>
242
+ <CardHeader>
243
+ <CardTitle>Breadcrumb</CardTitle>
244
+ <CardDescription>Navigation hierarchy for nested pages and settings.</CardDescription>
245
+ </CardHeader>
246
+ <CardContent className="space-y-6">
247
+ <Breadcrumb>
248
+ <BreadcrumbList>
249
+ <BreadcrumbItem>
250
+ <BreadcrumbLink asChild>
251
+ <Link to="/dashboard">Home</Link>
252
+ </BreadcrumbLink>
253
+ </BreadcrumbItem>
254
+ <BreadcrumbSeparator />
255
+ <BreadcrumbItem>
256
+ <BreadcrumbLink asChild>
257
+ <Link to="/components">Components</Link>
258
+ </BreadcrumbLink>
259
+ </BreadcrumbItem>
260
+ <BreadcrumbSeparator />
261
+ <BreadcrumbItem>
262
+ <BreadcrumbPage>Breadcrumb</BreadcrumbPage>
263
+ </BreadcrumbItem>
264
+ </BreadcrumbList>
265
+ </Breadcrumb>
266
+
267
+ <Breadcrumb>
268
+ <BreadcrumbList>
269
+ <BreadcrumbItem>
270
+ <BreadcrumbLink asChild>
271
+ <Link to="/dashboard">Home</Link>
272
+ </BreadcrumbLink>
273
+ </BreadcrumbItem>
274
+ <BreadcrumbSeparator />
275
+ <BreadcrumbItem>
276
+ <BreadcrumbEllipsis />
277
+ </BreadcrumbItem>
278
+ <BreadcrumbSeparator />
279
+ <BreadcrumbItem>
280
+ <BreadcrumbLink asChild>
281
+ <Link to="/settings/profile">Settings</Link>
282
+ </BreadcrumbLink>
283
+ </BreadcrumbItem>
284
+ <BreadcrumbSeparator />
285
+ <BreadcrumbItem>
286
+ <BreadcrumbPage>Profile</BreadcrumbPage>
287
+ </BreadcrumbItem>
288
+ </BreadcrumbList>
289
+ </Breadcrumb>
290
+ </CardContent>
291
+ </Card>
292
+
293
+ <Card>
294
+ <CardHeader>
295
+ <CardTitle>Data Table</CardTitle>
296
+ <CardDescription>
297
+ Modern toolbar with filters, sort, export, and column visibility. Row selection, sorting, and pagination.
298
+ </CardDescription>
299
+ </CardHeader>
300
+ <CardContent>
301
+ <DemoUsersDataTable />
302
+ </CardContent>
303
+ </Card>
304
+
305
+ <Card>
306
+ <CardHeader>
307
+ <CardTitle>Accordion</CardTitle>
308
+ <CardDescription>Collapsible sections for FAQs, settings groups, and details.</CardDescription>
309
+ </CardHeader>
310
+ <CardContent>
311
+ <Accordion type="single" collapsible className="w-full max-w-xl">
312
+ <AccordionItem value="item-1">
313
+ <AccordionTrigger>Is this template production ready?</AccordionTrigger>
314
+ <AccordionContent>
315
+ Yes. It ships with routing, layout, sidebar navigation, and a growing shadcn-compatible UI kit.
316
+ </AccordionContent>
317
+ </AccordionItem>
318
+ <AccordionItem value="item-2">
319
+ <AccordionTrigger>Can I customize the theme?</AccordionTrigger>
320
+ <AccordionContent>
321
+ Update CSS variables in globals.css and Tailwind tokens to match your brand colors.
322
+ </AccordionContent>
323
+ </AccordionItem>
324
+ <AccordionItem value="item-3">
325
+ <AccordionTrigger>How do I add new pages?</AccordionTrigger>
326
+ <AccordionContent>
327
+ Register routes in App.tsx, add nav items in navigation.ts, and breadcrumbs update automatically.
328
+ </AccordionContent>
329
+ </AccordionItem>
330
+ </Accordion>
331
+ </CardContent>
332
+ </Card>
333
+
334
+ <Card>
335
+ <CardHeader>
336
+ <CardTitle>Alert</CardTitle>
337
+ <CardDescription>Inline feedback for success, info, and error states.</CardDescription>
338
+ </CardHeader>
339
+ <CardContent className="space-y-4">
340
+ <Alert>
341
+ <Terminal className="h-4 w-4" />
342
+ <AlertTitle>Heads up</AlertTitle>
343
+ <AlertDescription>
344
+ You can add new components to the showcase page as your design system grows.
345
+ </AlertDescription>
346
+ </Alert>
347
+ <Alert variant="destructive">
348
+ <AlertCircle className="h-4 w-4" />
349
+ <AlertTitle>Error</AlertTitle>
350
+ <AlertDescription>Your session has expired. Please sign in again to continue.</AlertDescription>
351
+ </Alert>
352
+ </CardContent>
353
+ </Card>
354
+
355
+ <Card>
356
+ <CardHeader>
357
+ <CardTitle>Alert Dialog</CardTitle>
358
+ <CardDescription>Modal confirmation for destructive or important actions.</CardDescription>
359
+ </CardHeader>
360
+ <CardContent>
361
+ <AlertDialog>
362
+ <AlertDialogTrigger asChild>
363
+ <Button variant="outline">Delete project</Button>
364
+ </AlertDialogTrigger>
365
+ <AlertDialogContent>
366
+ <AlertDialogHeader>
367
+ <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
368
+ <AlertDialogDescription>
369
+ This action cannot be undone. This will permanently delete the project and remove all
370
+ associated data from our servers.
371
+ </AlertDialogDescription>
372
+ </AlertDialogHeader>
373
+ <AlertDialogFooter>
374
+ <AlertDialogCancel>Cancel</AlertDialogCancel>
375
+ <AlertDialogAction>Continue</AlertDialogAction>
376
+ </AlertDialogFooter>
377
+ </AlertDialogContent>
378
+ </AlertDialog>
379
+ </CardContent>
380
+ </Card>
381
+
382
+ <Card>
383
+ <CardHeader>
384
+ <CardTitle>Avatar</CardTitle>
385
+ <CardDescription>User profile image with automatic fallback initials.</CardDescription>
386
+ </CardHeader>
387
+ <CardContent className="flex flex-wrap items-end gap-6">
388
+ <div className="flex flex-col items-center gap-2">
389
+ <Avatar className="h-8 w-8">
390
+ <AvatarImage src="https://github.com/shadcn.png" alt="Shadcn" />
391
+ <AvatarFallback>CN</AvatarFallback>
392
+ </Avatar>
393
+ <span className="text-xs text-muted-foreground">Small</span>
394
+ </div>
395
+ <div className="flex flex-col items-center gap-2">
396
+ <Avatar>
397
+ <AvatarImage src="https://github.com/shadcn.png" alt="Shadcn" />
398
+ <AvatarFallback>CN</AvatarFallback>
399
+ </Avatar>
400
+ <span className="text-xs text-muted-foreground">Default</span>
401
+ </div>
402
+ <div className="flex flex-col items-center gap-2">
403
+ <Avatar className="h-14 w-14">
404
+ <AvatarImage src="https://github.com/shadcn.png" alt="Shadcn" />
405
+ <AvatarFallback>CN</AvatarFallback>
406
+ </Avatar>
407
+ <span className="text-xs text-muted-foreground">Large</span>
408
+ </div>
409
+ <div className="flex flex-col items-center gap-2">
410
+ <Avatar>
411
+ <AvatarFallback>AD</AvatarFallback>
412
+ </Avatar>
413
+ <span className="text-xs text-muted-foreground">Fallback only</span>
414
+ </div>
415
+ <div className="flex flex-col items-center gap-2">
416
+ <div className="flex -space-x-2">
417
+ <Avatar className="border-2 border-background">
418
+ <AvatarFallback>A</AvatarFallback>
419
+ </Avatar>
420
+ <Avatar className="border-2 border-background">
421
+ <AvatarFallback>B</AvatarFallback>
422
+ </Avatar>
423
+ <Avatar className="border-2 border-background">
424
+ <AvatarFallback>C</AvatarFallback>
425
+ </Avatar>
426
+ </div>
427
+ <span className="text-xs text-muted-foreground">Group</span>
428
+ </div>
429
+ </CardContent>
430
+ </Card>
431
+
432
+ <Card>
433
+ <CardHeader>
434
+ <CardTitle>Badge</CardTitle>
435
+ <CardDescription>Compact labels for status, tags, and counts.</CardDescription>
436
+ </CardHeader>
437
+ <CardContent className="flex flex-wrap items-center gap-3">
438
+ <Badge>Default</Badge>
439
+ <Badge variant="secondary">Secondary</Badge>
440
+ <Badge variant="destructive">Destructive</Badge>
441
+ <Badge variant="outline">Outline</Badge>
442
+ </CardContent>
443
+ </Card>
444
+
445
+ <Card>
446
+ <CardHeader>
447
+ <CardTitle>Buttons</CardTitle>
448
+ <CardDescription>Primary actions and secondary controls.</CardDescription>
449
+ </CardHeader>
450
+ <CardContent className="flex flex-wrap items-center gap-3">
451
+ <Button>Primary</Button>
452
+ <Button variant="outline">Outline</Button>
453
+ </CardContent>
454
+ </Card>
455
+
456
+ <Card>
457
+ <CardHeader>
458
+ <CardTitle>Checkbox</CardTitle>
459
+ <CardDescription>Boolean inputs for forms, tables, and settings.</CardDescription>
460
+ </CardHeader>
461
+ <CardContent className="space-y-6">
462
+ <div className="space-y-3">
463
+ <p className="text-sm font-medium">Rounded (default)</p>
464
+ <div className="flex items-center space-x-2">
465
+ <Checkbox id="terms" defaultChecked />
466
+ <Label htmlFor="terms">Accept terms and conditions</Label>
467
+ </div>
468
+ <div className="flex items-center space-x-2">
469
+ <Checkbox id="notifications" />
470
+ <Label htmlFor="notifications">Email me about product updates</Label>
471
+ </div>
472
+ </div>
473
+ <div className="space-y-3">
474
+ <p className="text-sm font-medium">Square (tables &amp; dense UIs)</p>
475
+ <div className="flex items-center space-x-2">
476
+ <Checkbox id="terms-square" shape="square" defaultChecked />
477
+ <Label htmlFor="terms-square">Square checkbox</Label>
478
+ </div>
479
+ <div className="flex items-center space-x-2">
480
+ <Checkbox id="notifications-square" shape="square" />
481
+ <Label htmlFor="notifications-square">Used in the data table row selection</Label>
482
+ </div>
483
+ </div>
484
+ <div className="flex items-center space-x-2">
485
+ <Checkbox id="disabled" disabled />
486
+ <Label htmlFor="disabled" className="text-muted-foreground">
487
+ Disabled option
488
+ </Label>
489
+ </div>
490
+ </CardContent>
491
+ </Card>
492
+
493
+ <Card>
494
+ <CardHeader>
495
+ <CardTitle>Context Menu</CardTitle>
496
+ <CardDescription>Right-click menu for contextual actions on any surface.</CardDescription>
497
+ </CardHeader>
498
+ <CardContent>
499
+ <ContextMenu>
500
+ <ContextMenuTrigger className="flex h-32 w-full max-w-md items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground">
501
+ Right click here
502
+ </ContextMenuTrigger>
503
+ <ContextMenuContent className="w-56">
504
+ <ContextMenuItem inset>
505
+ Back
506
+ <ContextMenuShortcut>⌘[</ContextMenuShortcut>
507
+ </ContextMenuItem>
508
+ <ContextMenuItem inset disabled>
509
+ Forward
510
+ <ContextMenuShortcut>⌘]</ContextMenuShortcut>
511
+ </ContextMenuItem>
512
+ <ContextMenuItem inset>
513
+ Reload
514
+ <ContextMenuShortcut>⌘R</ContextMenuShortcut>
515
+ </ContextMenuItem>
516
+ <ContextMenuSub>
517
+ <ContextMenuSubTrigger inset>More Tools</ContextMenuSubTrigger>
518
+ <ContextMenuSubContent className="w-48">
519
+ <ContextMenuItem inset>Save Page As…</ContextMenuItem>
520
+ <ContextMenuItem inset>Create Shortcut…</ContextMenuItem>
521
+ <ContextMenuItem inset>Name Window…</ContextMenuItem>
522
+ <ContextMenuSeparator />
523
+ <ContextMenuItem inset>Developer Tools</ContextMenuItem>
524
+ </ContextMenuSubContent>
525
+ </ContextMenuSub>
526
+ <ContextMenuSeparator />
527
+ <ContextMenuCheckboxItem checked>Show Bookmarks Bar</ContextMenuCheckboxItem>
528
+ <ContextMenuCheckboxItem>Show Full URLs</ContextMenuCheckboxItem>
529
+ <ContextMenuSeparator />
530
+ <ContextMenuLabel inset>People</ContextMenuLabel>
531
+ <ContextMenuRadioGroup value="ava">
532
+ <ContextMenuRadioItem value="ava">Ava Johnson</ContextMenuRadioItem>
533
+ <ContextMenuRadioItem value="noah">Noah Patel</ContextMenuRadioItem>
534
+ </ContextMenuRadioGroup>
535
+ </ContextMenuContent>
536
+ </ContextMenu>
537
+ </CardContent>
538
+ </Card>
539
+
540
+ <Card>
541
+ <CardHeader>
542
+ <CardTitle>Dialog</CardTitle>
543
+ <CardDescription>Modal overlay for forms, confirmations, and focused tasks.</CardDescription>
544
+ </CardHeader>
545
+ <CardContent>
546
+ <Dialog>
547
+ <DialogTrigger asChild>
548
+ <Button variant="outline">Edit profile</Button>
549
+ </DialogTrigger>
550
+ <DialogContent className="sm:max-w-[425px]">
551
+ <DialogHeader>
552
+ <DialogTitle>Edit profile</DialogTitle>
553
+ <DialogDescription>
554
+ Make changes to your profile here. Click save when you are done.
555
+ </DialogDescription>
556
+ </DialogHeader>
557
+ <div className="grid gap-4 py-4">
558
+ <div className="grid grid-cols-4 items-center gap-4">
559
+ <Label htmlFor="dialog-name" className="text-right">
560
+ Name
561
+ </Label>
562
+ <Input id="dialog-name" defaultValue="Admin User" className="col-span-3" />
563
+ </div>
564
+ <div className="grid grid-cols-4 items-center gap-4">
565
+ <Label htmlFor="dialog-email" className="text-right">
566
+ Email
567
+ </Label>
568
+ <Input id="dialog-email" defaultValue="admin@company.com" className="col-span-3" />
569
+ </div>
570
+ </div>
571
+ <DialogFooter>
572
+ <Button type="submit">Save changes</Button>
573
+ </DialogFooter>
574
+ </DialogContent>
575
+ </Dialog>
576
+ </CardContent>
577
+ </Card>
578
+
579
+ <Card>
580
+ <CardHeader>
581
+ <CardTitle>Date Picker</CardTitle>
582
+ <CardDescription>Calendar popover for selecting dates in forms and filters.</CardDescription>
583
+ </CardHeader>
584
+ <CardContent className="flex flex-wrap items-center gap-4">
585
+ <DatePicker date={date} onDateChange={setDate} />
586
+ <DatePicker placeholder="Disabled" disabled />
587
+ </CardContent>
588
+ </Card>
589
+
590
+ <Card>
591
+ <CardHeader>
592
+ <CardTitle>Drawer</CardTitle>
593
+ <CardDescription>Slide-up panel for mobile-friendly forms and actions.</CardDescription>
594
+ </CardHeader>
595
+ <CardContent>
596
+ <Drawer>
597
+ <DrawerTrigger asChild>
598
+ <Button variant="outline">Open drawer</Button>
599
+ </DrawerTrigger>
600
+ <DrawerContent>
601
+ <DrawerHeader>
602
+ <DrawerTitle>Create project</DrawerTitle>
603
+ <DrawerDescription>Add a new project to your workspace.</DrawerDescription>
604
+ </DrawerHeader>
605
+ <div className="space-y-4 px-4 pb-4">
606
+ <div className="space-y-2">
607
+ <Label htmlFor="drawer-name">Project name</Label>
608
+ <Input id="drawer-name" placeholder="My project" />
609
+ </div>
610
+ <div className="space-y-2">
611
+ <Label htmlFor="drawer-desc">Description</Label>
612
+ <Input id="drawer-desc" placeholder="Optional description" />
613
+ </div>
614
+ </div>
615
+ <DrawerFooter>
616
+ <Button>Save project</Button>
617
+ <DrawerClose asChild>
618
+ <Button variant="outline">Cancel</Button>
619
+ </DrawerClose>
620
+ </DrawerFooter>
621
+ </DrawerContent>
622
+ </Drawer>
623
+ </CardContent>
624
+ </Card>
625
+
626
+ <Card>
627
+ <CardHeader>
628
+ <CardTitle>Field</CardTitle>
629
+ <CardDescription>Structured form fields with labels, descriptions, and validation messages.</CardDescription>
630
+ </CardHeader>
631
+ <CardContent>
632
+ <FieldSet className="max-w-xl">
633
+ <FieldLegend>Account details</FieldLegend>
634
+ <FieldGroup>
635
+ <Field>
636
+ <FieldLabel htmlFor="field-name">Full name</FieldLabel>
637
+ <FieldContent>
638
+ <Input id="field-name" placeholder="Jane Admin" />
639
+ <FieldDescription>Your name as it appears across the app.</FieldDescription>
640
+ </FieldContent>
641
+ </Field>
642
+ <Field>
643
+ <FieldLabel htmlFor="field-email">Email</FieldLabel>
644
+ <FieldContent>
645
+ <Input id="field-email" type="email" placeholder="admin@company.com" aria-invalid />
646
+ <FieldError>Enter a valid company email address.</FieldError>
647
+ </FieldContent>
648
+ </Field>
649
+ <FieldSeparator>Or continue with</FieldSeparator>
650
+ <Field orientation="horizontal">
651
+ <Checkbox id="field-marketing" />
652
+ <FieldContent>
653
+ <FieldLabel htmlFor="field-marketing">Marketing emails</FieldLabel>
654
+ <FieldDescription>Receive product updates and release notes.</FieldDescription>
655
+ </FieldContent>
656
+ </Field>
657
+ </FieldGroup>
658
+ </FieldSet>
659
+ </CardContent>
660
+ </Card>
661
+
662
+ <Card>
663
+ <CardHeader>
664
+ <CardTitle>Hover Card</CardTitle>
665
+ <CardDescription>Preview content on hover for profiles, links, and rich tooltips.</CardDescription>
666
+ </CardHeader>
667
+ <CardContent>
668
+ <HoverCard>
669
+ <HoverCardTrigger asChild>
670
+ <Button variant="outline">@omobio</Button>
671
+ </HoverCardTrigger>
672
+ <HoverCardContent className="w-80">
673
+ <div className="flex justify-between gap-4">
674
+ <Avatar>
675
+ <AvatarImage src="https://github.com/shadcn.png" alt="Omobio" />
676
+ <AvatarFallback>OB</AvatarFallback>
677
+ </Avatar>
678
+ <div className="space-y-1">
679
+ <h4 className="text-sm font-semibold">Omobio Platform</h4>
680
+ <p className="text-sm text-muted-foreground">
681
+ Shared UI components and templates for internal admin applications.
682
+ </p>
683
+ <div className="flex items-center pt-2">
684
+ <CalendarIcon className="mr-2 h-4 w-4 text-muted-foreground" />
685
+ <span className="text-xs text-muted-foreground">Updated June 2026</span>
686
+ </div>
687
+ </div>
688
+ </div>
689
+ </HoverCardContent>
690
+ </HoverCard>
691
+ </CardContent>
692
+ </Card>
693
+
694
+ <Card>
695
+ <CardHeader>
696
+ <CardTitle>Input Group</CardTitle>
697
+ <CardDescription>Combine inputs with icons, text addons, and action buttons.</CardDescription>
698
+ </CardHeader>
699
+ <CardContent className="mx-auto flex w-full max-w-md flex-col gap-4">
700
+ <InputGroup>
701
+ <InputGroupAddon>
702
+ <InputGroupText>https://</InputGroupText>
703
+ </InputGroupAddon>
704
+ <InputGroupInput placeholder="example.com" />
705
+ </InputGroup>
706
+ <InputGroup>
707
+ <InputGroupAddon>
708
+ <Search className="h-4 w-4" />
709
+ </InputGroupAddon>
710
+ <InputGroupInput placeholder="Search users..." />
711
+ <InputGroupAddon align="inline-end">
712
+ <InputGroupButton aria-label="Search">
713
+ <Search className="h-4 w-4" />
714
+ </InputGroupButton>
715
+ </InputGroupAddon>
716
+ </InputGroup>
717
+ <InputGroup>
718
+ <InputGroupInput type="email" placeholder="username" />
719
+ <InputGroupAddon align="inline-end">
720
+ <InputGroupText>@company.com</InputGroupText>
721
+ </InputGroupAddon>
722
+ </InputGroup>
723
+ </CardContent>
724
+ </Card>
725
+
726
+ <Card>
727
+ <CardHeader>
728
+ <CardTitle>Input OTP</CardTitle>
729
+ <CardDescription>One-time password input with grouped slots.</CardDescription>
730
+ </CardHeader>
731
+ <CardContent>
732
+ <InputOTP maxLength={6} value={otp} onChange={setOtp}>
733
+ <InputOTPGroup>
734
+ <InputOTPSlot index={0} />
735
+ <InputOTPSlot index={1} />
736
+ <InputOTPSlot index={2} />
737
+ </InputOTPGroup>
738
+ <InputOTPSeparator />
739
+ <InputOTPGroup>
740
+ <InputOTPSlot index={3} />
741
+ <InputOTPSlot index={4} />
742
+ <InputOTPSlot index={5} />
743
+ </InputOTPGroup>
744
+ </InputOTP>
745
+ {otp && <p className="mt-3 text-sm text-muted-foreground">Entered code: {otp}</p>}
746
+ </CardContent>
747
+ </Card>
748
+
749
+ <Card>
750
+ <CardHeader>
751
+ <CardTitle>Item</CardTitle>
752
+ <CardDescription>List rows with media, content, and actions.</CardDescription>
753
+ </CardHeader>
754
+ <CardContent>
755
+ <ItemGroup className="max-w-lg">
756
+ <Item variant="outline">
757
+ <ItemMedia variant="icon">
758
+ <Inbox className="h-4 w-4" />
759
+ </ItemMedia>
760
+ <ItemContent>
761
+ <ItemTitle>Messages</ItemTitle>
762
+ <ItemDescription>12 unread messages in your inbox.</ItemDescription>
763
+ </ItemContent>
764
+ <ItemActions>
765
+ <Button size="sm" variant="outline">
766
+ View
767
+ </Button>
768
+ </ItemActions>
769
+ </Item>
770
+ <Item variant="muted">
771
+ <ItemMedia variant="icon">
772
+ <Terminal className="h-4 w-4" />
773
+ </ItemMedia>
774
+ <ItemContent>
775
+ <ItemTitle>API Keys</ItemTitle>
776
+ <ItemDescription>Rotate keys and manage access tokens.</ItemDescription>
777
+ </ItemContent>
778
+ <ItemActions>
779
+ <Button size="sm">Manage</Button>
780
+ </ItemActions>
781
+ </Item>
782
+ </ItemGroup>
783
+ </CardContent>
784
+ </Card>
785
+
786
+ <Card>
787
+ <CardHeader>
788
+ <CardTitle>Kbd</CardTitle>
789
+ <CardDescription>Keyboard shortcut hints for menus and tooltips.</CardDescription>
790
+ </CardHeader>
791
+ <CardContent className="flex flex-wrap items-center gap-4">
792
+ <p className="text-sm text-muted-foreground">
793
+ Press <KbdGroup><Kbd>⌘</Kbd><Kbd>K</Kbd></KbdGroup> to open the command palette.
794
+ </p>
795
+ <p className="text-sm text-muted-foreground">
796
+ Save with <Kbd>Ctrl</Kbd> + <Kbd>S</Kbd>
797
+ </p>
798
+ </CardContent>
799
+ </Card>
800
+
801
+ <Card>
802
+ <CardHeader>
803
+ <CardTitle>Navigation Menu</CardTitle>
804
+ <CardDescription>Top navigation with dropdown panels.</CardDescription>
805
+ </CardHeader>
806
+ <CardContent>
807
+ <NavigationMenu>
808
+ <NavigationMenuList>
809
+ <NavigationMenuItem>
810
+ <NavigationMenuTrigger>Components</NavigationMenuTrigger>
811
+ <NavigationMenuContent>
812
+ <ul className="grid w-[400px] gap-3 p-4 md:grid-cols-2">
813
+ {navComponents.map((component) => (
814
+ <li key={component.title}>
815
+ <NavigationMenuLink asChild>
816
+ <a
817
+ href={component.href}
818
+ className="block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground"
819
+ >
820
+ <div className="text-sm font-medium leading-none">{component.title}</div>
821
+ <p className="line-clamp-2 text-sm leading-snug text-muted-foreground">
822
+ {component.description}
823
+ </p>
824
+ </a>
825
+ </NavigationMenuLink>
826
+ </li>
827
+ ))}
828
+ </ul>
829
+ </NavigationMenuContent>
830
+ </NavigationMenuItem>
831
+ <NavigationMenuItem>
832
+ <NavigationMenuLink className={navigationMenuTriggerStyle()} href="/dashboard">
833
+ Dashboard
834
+ </NavigationMenuLink>
835
+ </NavigationMenuItem>
836
+ </NavigationMenuList>
837
+ </NavigationMenu>
838
+ </CardContent>
839
+ </Card>
840
+
841
+ <Card>
842
+ <CardHeader>
843
+ <CardTitle>Menubar</CardTitle>
844
+ <CardDescription>Application menu bar with keyboard shortcuts.</CardDescription>
845
+ </CardHeader>
846
+ <CardContent>
847
+ <Menubar>
848
+ <MenubarMenu>
849
+ <MenubarTrigger>File</MenubarTrigger>
850
+ <MenubarContent>
851
+ <MenubarItem>
852
+ New Tab
853
+ <MenubarShortcut>⌘T</MenubarShortcut>
854
+ </MenubarItem>
855
+ <MenubarItem>
856
+ New Window
857
+ <MenubarShortcut>⌘N</MenubarShortcut>
858
+ </MenubarItem>
859
+ <MenubarSeparator />
860
+ <MenubarItem>Share</MenubarItem>
861
+ <MenubarSeparator />
862
+ <MenubarItem>
863
+ Print
864
+ <MenubarShortcut>⌘P</MenubarShortcut>
865
+ </MenubarItem>
866
+ </MenubarContent>
867
+ </MenubarMenu>
868
+ <MenubarMenu>
869
+ <MenubarTrigger>Edit</MenubarTrigger>
870
+ <MenubarContent>
871
+ <MenubarItem>
872
+ Undo
873
+ <MenubarShortcut>⌘Z</MenubarShortcut>
874
+ </MenubarItem>
875
+ <MenubarItem>
876
+ Redo
877
+ <MenubarShortcut>⇧⌘Z</MenubarShortcut>
878
+ </MenubarItem>
879
+ </MenubarContent>
880
+ </MenubarMenu>
881
+ <MenubarMenu>
882
+ <MenubarTrigger>View</MenubarTrigger>
883
+ <MenubarContent>
884
+ <MenubarItem>Reload</MenubarItem>
885
+ <MenubarItem>Full Screen</MenubarItem>
886
+ </MenubarContent>
887
+ </MenubarMenu>
888
+ </Menubar>
889
+ </CardContent>
890
+ </Card>
891
+
892
+ <Card>
893
+ <CardHeader>
894
+ <CardTitle>Progress</CardTitle>
895
+ <CardDescription>Visual indicator for task completion and loading states.</CardDescription>
896
+ </CardHeader>
897
+ <CardContent className="mx-auto w-full max-w-md space-y-6">
898
+ <div className="space-y-2">
899
+ <div className="flex justify-between text-sm">
900
+ <span className="text-muted-foreground">Uploading files</span>
901
+ <span className="font-medium">{progress}%</span>
902
+ </div>
903
+ <Progress value={progress} />
904
+ </div>
905
+ <div className="flex gap-2">
906
+ <Button variant="outline" size="sm" onClick={() => setProgress((value) => Math.max(0, value - 10))}>
907
+ -10%
908
+ </Button>
909
+ <Button variant="outline" size="sm" onClick={() => setProgress((value) => Math.min(100, value + 10))}>
910
+ +10%
911
+ </Button>
912
+ </div>
913
+ </CardContent>
914
+ </Card>
915
+
916
+ <Card>
917
+ <CardHeader>
918
+ <CardTitle>Radio Group</CardTitle>
919
+ <CardDescription>Single selection from a set of mutually exclusive options.</CardDescription>
920
+ </CardHeader>
921
+ <CardContent>
922
+ <RadioGroup value={plan} onValueChange={setPlan} className="max-w-sm">
923
+ <div className="flex items-center space-x-2">
924
+ <RadioGroupItem value="default" id="plan-default" />
925
+ <Label htmlFor="plan-default">Default</Label>
926
+ </div>
927
+ <div className="flex items-center space-x-2">
928
+ <RadioGroupItem value="comfortable" id="plan-comfortable" />
929
+ <Label htmlFor="plan-comfortable">Comfortable</Label>
930
+ </div>
931
+ <div className="flex items-center space-x-2">
932
+ <RadioGroupItem value="compact" id="plan-compact" />
933
+ <Label htmlFor="plan-compact">Compact</Label>
934
+ </div>
935
+ </RadioGroup>
936
+ <p className="mt-4 text-sm text-muted-foreground">Selected: {plan}</p>
937
+ </CardContent>
938
+ </Card>
939
+
940
+ <Card>
941
+ <CardHeader>
942
+ <CardTitle>Scroll Area</CardTitle>
943
+ <CardDescription>Custom scrollbars for overflow content in panels and lists.</CardDescription>
944
+ </CardHeader>
945
+ <CardContent>
946
+ <ScrollArea className="h-48 w-full max-w-sm rounded-md border p-4">
947
+ <div className="space-y-3 pr-4">
948
+ {scrollTags.map((tag) => (
949
+ <div key={tag} className="text-sm">
950
+ {tag}
951
+ </div>
952
+ ))}
953
+ </div>
954
+ </ScrollArea>
955
+ </CardContent>
956
+ </Card>
957
+
958
+ <Card>
959
+ <CardHeader>
960
+ <CardTitle>Select</CardTitle>
961
+ <CardDescription>Dropdown for choosing one option from a list.</CardDescription>
962
+ </CardHeader>
963
+ <CardContent className="mx-auto w-full max-w-sm space-y-4">
964
+ <Select value={role} onValueChange={setRole}>
965
+ <SelectTrigger>
966
+ <SelectValue placeholder="Select a role" />
967
+ </SelectTrigger>
968
+ <SelectContent>
969
+ <SelectGroup>
970
+ <SelectLabel>Roles</SelectLabel>
971
+ <SelectItem value="admin">Admin</SelectItem>
972
+ <SelectItem value="editor">Editor</SelectItem>
973
+ <SelectItem value="viewer">Viewer</SelectItem>
974
+ </SelectGroup>
975
+ </SelectContent>
976
+ </Select>
977
+ <p className="text-sm text-muted-foreground">Selected role: {role}</p>
978
+ </CardContent>
979
+ </Card>
980
+
981
+ <Card>
982
+ <CardHeader>
983
+ <CardTitle>Searchable Dropdown</CardTitle>
984
+ <CardDescription>Single-select combobox with inline search and filtering.</CardDescription>
985
+ </CardHeader>
986
+ <CardContent className="mx-auto w-full max-w-sm space-y-4">
987
+ <SearchableDropdown
988
+ options={frameworkOptions}
989
+ value={framework}
990
+ onValueChange={setFramework}
991
+ placeholder="Select framework..."
992
+ searchPlaceholder="Search frameworks..."
993
+ />
994
+ <p className="text-sm text-muted-foreground">
995
+ Selected: {frameworkOptions.find((option) => option.value === framework)?.label ?? "None"}
996
+ </p>
997
+ </CardContent>
998
+ </Card>
999
+
1000
+ <Card>
1001
+ <CardHeader>
1002
+ <CardTitle>Multi Select Dropdown</CardTitle>
1003
+ <CardDescription>Select multiple values with search, badges, and bulk actions.</CardDescription>
1004
+ </CardHeader>
1005
+ <CardContent className="mx-auto w-full max-w-sm space-y-4">
1006
+ <MultiSelectDropdown
1007
+ options={skillOptions}
1008
+ value={skills}
1009
+ onValueChange={setSkills}
1010
+ placeholder="Select skills..."
1011
+ searchPlaceholder="Search skills..."
1012
+ maxDisplay={3}
1013
+ />
1014
+ <p className="text-sm text-muted-foreground">
1015
+ Selected ({skills.length}): {skills.length ? skills.join(", ") : "None"}
1016
+ </p>
1017
+ </CardContent>
1018
+ </Card>
1019
+
1020
+ <Card>
1021
+ <CardHeader>
1022
+ <CardTitle>Skeleton</CardTitle>
1023
+ <CardDescription>Loading placeholders while content is being fetched.</CardDescription>
1024
+ </CardHeader>
1025
+ <CardContent>
1026
+ <div className="flex w-full max-w-sm items-center space-x-4">
1027
+ <Skeleton className="h-12 w-12 rounded-full" />
1028
+ <div className="flex-1 space-y-2">
1029
+ <Skeleton className="h-4 w-full" />
1030
+ <Skeleton className="h-4 w-4/5" />
1031
+ </div>
1032
+ </div>
1033
+ <div className="mt-6 space-y-2">
1034
+ <Skeleton className="h-4 w-full" />
1035
+ <Skeleton className="h-4 w-full" />
1036
+ <Skeleton className="h-4 w-3/5" />
1037
+ </div>
1038
+ </CardContent>
1039
+ </Card>
1040
+
1041
+ <Card>
1042
+ <CardHeader>
1043
+ <CardTitle>Slider</CardTitle>
1044
+ <CardDescription>Drag control for numeric values like volume, brightness, or price range.</CardDescription>
1045
+ </CardHeader>
1046
+ <CardContent className="mx-auto w-full max-w-sm space-y-4">
1047
+ <div className="space-y-3">
1048
+ <div className="flex justify-between text-sm">
1049
+ <Label>Volume</Label>
1050
+ <span className="text-muted-foreground">{volume[0]}%</span>
1051
+ </div>
1052
+ <Slider value={volume} onValueChange={setVolume} max={100} step={1} />
1053
+ </div>
1054
+ <div className="space-y-3">
1055
+ <Label>Price range</Label>
1056
+ <Slider defaultValue={[25, 75]} max={100} step={1} />
1057
+ </div>
1058
+ </CardContent>
1059
+ </Card>
1060
+
1061
+ <Card>
1062
+ <CardHeader>
1063
+ <CardTitle>Sonner</CardTitle>
1064
+ <CardDescription>Toast notifications for success, errors, and async feedback.</CardDescription>
1065
+ </CardHeader>
1066
+ <CardContent className="flex flex-wrap gap-3">
1067
+ <Button
1068
+ variant="outline"
1069
+ onClick={() => toast("Event has been created", { description: "Monday, January 3rd at 6:00pm" })}
1070
+ >
1071
+ Show toast
1072
+ </Button>
1073
+ <Button variant="outline" onClick={() => toast.success("Profile saved successfully")}>
1074
+ Success
1075
+ </Button>
1076
+ <Button variant="outline" onClick={() => toast.error("Something went wrong")}>
1077
+ Error
1078
+ </Button>
1079
+ <Button
1080
+ variant="outline"
1081
+ onClick={() =>
1082
+ toast.promise(new Promise((resolve) => setTimeout(resolve, 1500)), {
1083
+ loading: "Saving changes...",
1084
+ success: "Changes saved",
1085
+ error: "Failed to save",
1086
+ })
1087
+ }
1088
+ >
1089
+ Promise
1090
+ </Button>
1091
+ </CardContent>
1092
+ </Card>
1093
+
1094
+ <Card>
1095
+ <CardHeader>
1096
+ <CardTitle>Spinner</CardTitle>
1097
+ <CardDescription>Loading indicator for buttons, pages, and inline states.</CardDescription>
1098
+ </CardHeader>
1099
+ <CardContent className="flex flex-wrap items-center gap-6">
1100
+ <Spinner className="size-4" />
1101
+ <Spinner className="size-6" />
1102
+ <Spinner className="size-8 text-primary" />
1103
+ <Button variant="outline" disabled>
1104
+ <Spinner className="mr-2" />
1105
+ Loading
1106
+ </Button>
1107
+ </CardContent>
1108
+ </Card>
1109
+
1110
+ <Card>
1111
+ <CardHeader>
1112
+ <CardTitle>Switch</CardTitle>
1113
+ <CardDescription>Toggle control for settings and binary on/off states.</CardDescription>
1114
+ </CardHeader>
1115
+ <CardContent className="space-y-4">
1116
+ <div className="flex items-center space-x-2">
1117
+ <Switch id="airplane-mode" />
1118
+ <Label htmlFor="airplane-mode">Airplane mode</Label>
1119
+ </div>
1120
+ <div className="flex items-center space-x-2">
1121
+ <Switch id="marketing-emails" defaultChecked />
1122
+ <Label htmlFor="marketing-emails">Marketing emails</Label>
1123
+ </div>
1124
+ <div className="flex items-center space-x-2">
1125
+ <Switch id="disabled-switch" disabled />
1126
+ <Label htmlFor="disabled-switch" className="text-muted-foreground">
1127
+ Disabled
1128
+ </Label>
1129
+ </div>
1130
+ </CardContent>
1131
+ </Card>
1132
+
1133
+ <Card>
1134
+ <CardHeader>
1135
+ <CardTitle>Tabs</CardTitle>
1136
+ <CardDescription>Organize related content into switchable panels.</CardDescription>
1137
+ </CardHeader>
1138
+ <CardContent>
1139
+ <Tabs defaultValue="account" className="w-full max-w-md">
1140
+ <TabsList className="grid w-full grid-cols-2">
1141
+ <TabsTrigger value="account">Account</TabsTrigger>
1142
+ <TabsTrigger value="password">Password</TabsTrigger>
1143
+ </TabsList>
1144
+ <TabsContent value="account" className="space-y-2 text-sm text-muted-foreground">
1145
+ <p>Make changes to your account settings here.</p>
1146
+ </TabsContent>
1147
+ <TabsContent value="password" className="space-y-2 text-sm text-muted-foreground">
1148
+ <p>Change your password here. After saving, you will be logged out.</p>
1149
+ </TabsContent>
1150
+ </Tabs>
1151
+ </CardContent>
1152
+ </Card>
1153
+
1154
+ <Card>
1155
+ <CardHeader>
1156
+ <CardTitle>Textarea</CardTitle>
1157
+ <CardDescription>Multi-line text input for descriptions and messages.</CardDescription>
1158
+ </CardHeader>
1159
+ <CardContent className="mx-auto w-full max-w-md space-y-2">
1160
+ <Label htmlFor="message">Your message</Label>
1161
+ <Textarea id="message" placeholder="Type your message here." />
1162
+ </CardContent>
1163
+ </Card>
1164
+
1165
+ <Card>
1166
+ <CardHeader>
1167
+ <CardTitle>Toggle</CardTitle>
1168
+ <CardDescription>Pressable two-state buttons for formatting and toolbars.</CardDescription>
1169
+ </CardHeader>
1170
+ <CardContent className="flex flex-wrap gap-2">
1171
+ <Toggle aria-label="Toggle bold">
1172
+ <Bold className="h-4 w-4" />
1173
+ </Toggle>
1174
+ <Toggle aria-label="Toggle italic">
1175
+ <Italic className="h-4 w-4" />
1176
+ </Toggle>
1177
+ <Toggle aria-label="Toggle underline" variant="outline">
1178
+ <Underline className="h-4 w-4" />
1179
+ </Toggle>
1180
+ </CardContent>
1181
+ </Card>
1182
+
1183
+ <Card>
1184
+ <CardHeader>
1185
+ <CardTitle>Toggle Group</CardTitle>
1186
+ <CardDescription>Single or multiple selection from a grouped set of toggles.</CardDescription>
1187
+ </CardHeader>
1188
+ <CardContent className="space-y-4">
1189
+ <ToggleGroup type="single" defaultValue="left" variant="outline">
1190
+ <ToggleGroupItem value="left" aria-label="Align left">
1191
+ <AlignLeft className="h-4 w-4" />
1192
+ </ToggleGroupItem>
1193
+ <ToggleGroupItem value="center" aria-label="Align center">
1194
+ <AlignCenter className="h-4 w-4" />
1195
+ </ToggleGroupItem>
1196
+ <ToggleGroupItem value="right" aria-label="Align right">
1197
+ <AlignRight className="h-4 w-4" />
1198
+ </ToggleGroupItem>
1199
+ </ToggleGroup>
1200
+ <ToggleGroup type="multiple" variant="outline">
1201
+ <ToggleGroupItem value="bold" aria-label="Bold">
1202
+ <Bold className="h-4 w-4" />
1203
+ </ToggleGroupItem>
1204
+ <ToggleGroupItem value="italic" aria-label="Italic">
1205
+ <Italic className="h-4 w-4" />
1206
+ </ToggleGroupItem>
1207
+ <ToggleGroupItem value="underline" aria-label="Underline">
1208
+ <Underline className="h-4 w-4" />
1209
+ </ToggleGroupItem>
1210
+ </ToggleGroup>
1211
+ </CardContent>
1212
+ </Card>
1213
+
1214
+ <Card>
1215
+ <CardHeader>
1216
+ <CardTitle>Bar Chart</CardTitle>
1217
+ <CardDescription>Grouped vertical bars for comparing categories and metrics.</CardDescription>
1218
+ </CardHeader>
1219
+ <CardContent>
1220
+ <BarChart
1221
+ data={monthlyRevenueData}
1222
+ config={revenueChartConfig}
1223
+ dataKeys={["revenue", "users"]}
1224
+ categoryKey="month"
1225
+ />
1226
+ </CardContent>
1227
+ </Card>
1228
+
1229
+ <Card>
1230
+ <CardHeader>
1231
+ <CardTitle>Line Chart</CardTitle>
1232
+ <CardDescription>Trend lines for time-series and growth metrics.</CardDescription>
1233
+ </CardHeader>
1234
+ <CardContent>
1235
+ <LineChart
1236
+ data={weeklyActiveUsersData}
1237
+ config={activeUsersChartConfig}
1238
+ dataKeys={["users"]}
1239
+ categoryKey="week"
1240
+ />
1241
+ </CardContent>
1242
+ </Card>
1243
+
1244
+ <Card>
1245
+ <CardHeader>
1246
+ <CardTitle>Pie Chart</CardTitle>
1247
+ <CardDescription>Proportional slices for distribution and share breakdowns.</CardDescription>
1248
+ </CardHeader>
1249
+ <CardContent className="grid gap-8 md:grid-cols-2">
1250
+ <div className="space-y-2">
1251
+ <p className="text-sm font-medium">User roles</p>
1252
+ <PieChart
1253
+ data={userRoleDistribution}
1254
+ config={roleChartConfig}
1255
+ dataKey="count"
1256
+ nameKey="role"
1257
+ innerRadius={50}
1258
+ showCenterLabel
1259
+ centerLabel="Users"
1260
+ />
1261
+ </div>
1262
+ <div className="space-y-2">
1263
+ <p className="text-sm font-medium">Device usage</p>
1264
+ <PieChart
1265
+ data={deviceUsageData}
1266
+ config={deviceChartConfig}
1267
+ dataKey="value"
1268
+ nameKey="device"
1269
+ />
1270
+ </div>
1271
+ </CardContent>
1272
+ </Card>
1273
+
1274
+ <Card>
1275
+ <CardHeader>
1276
+ <CardTitle>Tooltip</CardTitle>
1277
+ <CardDescription>Contextual hints on hover or focus for icons and controls.</CardDescription>
1278
+ </CardHeader>
1279
+ <CardContent className="flex flex-wrap gap-4">
1280
+ <Tooltip>
1281
+ <TooltipTrigger asChild>
1282
+ <Button variant="outline">Hover me</Button>
1283
+ </TooltipTrigger>
1284
+ <TooltipContent>
1285
+ <p>Add to library</p>
1286
+ </TooltipContent>
1287
+ </Tooltip>
1288
+ <Tooltip>
1289
+ <TooltipTrigger asChild>
1290
+ <Button variant="outline" size="sm" className="h-9 w-9 p-0">
1291
+ <Search className="h-4 w-4" />
1292
+ </Button>
1293
+ </TooltipTrigger>
1294
+ <TooltipContent side="right">
1295
+ <p>Search</p>
1296
+ </TooltipContent>
1297
+ </Tooltip>
1298
+ </CardContent>
1299
+ </Card>
1300
+
1301
+ <Card>
1302
+ <CardHeader>
1303
+ <CardTitle>Typography</CardTitle>
1304
+ <CardDescription>Consistent text styles for headings, body copy, and supporting text.</CardDescription>
1305
+ </CardHeader>
1306
+ <CardContent className="max-w-2xl space-y-6">
1307
+ <TypographyH1>Taxing Laughter: The Joke Tax Chronicles</TypographyH1>
1308
+ <TypographyLead>
1309
+ A modal dialog that interrupts the user with important content and expects a response.
1310
+ </TypographyLead>
1311
+ <TypographyH2>The People of the Kingdom</TypographyH2>
1312
+ <TypographyP>
1313
+ The king, seeing how much happier his subjects were, levied a tax on jokes and puns.
1314
+ </TypographyP>
1315
+ <TypographyH3>The Joke Tax</TypographyH3>
1316
+ <TypographyP>
1317
+ People told fewer jokes, and the kingdom fell into gloom. But there was one person who
1318
+ refused to stop.
1319
+ </TypographyP>
1320
+ <TypographyH4>People stopped laughing</TypographyH4>
1321
+ <TypographyBlockquote>&ldquo;After all,&rdquo; he said, &ldquo;everyone enjoys a good joke.&rdquo;</TypographyBlockquote>
1322
+ <TypographyList>
1323
+ <li>1st level of puns: 5 gold coins</li>
1324
+ <li>2nd level of jokes: 10 gold coins</li>
1325
+ <li>3rd level of one-liners: 20 gold coins</li>
1326
+ </TypographyList>
1327
+ <TypographyInlineCode>@radix-ui/react-tooltip</TypographyInlineCode>
1328
+ <div className="flex items-center gap-4">
1329
+ <TypographyLarge>Large text</TypographyLarge>
1330
+ <TypographySmall>Small text</TypographySmall>
1331
+ </div>
1332
+ <TypographyMuted>Muted text for captions and secondary information.</TypographyMuted>
1333
+ </CardContent>
1334
+ </Card>
1335
+
1336
+ <Card>
1337
+ <CardHeader>
1338
+ <CardTitle>Dropdown + Sheet</CardTitle>
1339
+ </CardHeader>
1340
+ <CardContent className="flex gap-3">
1341
+ <DropdownMenu>
1342
+ <DropdownMenuTrigger asChild>
1343
+ <Button variant="outline">Open Menu</Button>
1344
+ </DropdownMenuTrigger>
1345
+ <DropdownMenuContent>
1346
+ <DropdownMenuItem>Profile</DropdownMenuItem>
1347
+ <DropdownMenuItem>Notifications</DropdownMenuItem>
1348
+ </DropdownMenuContent>
1349
+ </DropdownMenu>
1350
+
1351
+ <Sheet open={open} onOpenChange={setOpen}>
1352
+ <SheetTrigger asChild>
1353
+ <Button>Open Sheet</Button>
1354
+ </SheetTrigger>
1355
+ <SheetContent>
1356
+ <div className="space-y-2">
1357
+ <h2 className="text-lg font-semibold">Sheet Panel</h2>
1358
+ <p className="text-sm text-muted-foreground">
1359
+ Use this for mobile nav, details, or quick actions.
1360
+ </p>
1361
+ </div>
1362
+ </SheetContent>
1363
+ </Sheet>
1364
+ </CardContent>
1365
+ </Card>
1366
+ </div>
1367
+ );
1368
+ }