@reinvented/design 1.0.0 → 1.2.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.
- package/README.md +1 -1
- package/SKILL.md +214 -0
- package/package.json +4 -3
- package/skills/apps/analytics.md +103 -0
- package/skills/apps/booking-scheduling.md +97 -0
- package/skills/apps/content-management.md +52 -0
- package/skills/apps/crm.md +80 -0
- package/skills/apps/e-commerce.md +109 -0
- package/skills/apps/education.md +79 -0
- package/skills/apps/finance.md +68 -0
- package/skills/apps/health-fitness.md +72 -0
- package/skills/apps/marketplace.md +99 -0
- package/skills/apps/messaging.md +84 -0
- package/skills/apps/portfolio-personal.md +90 -0
- package/skills/apps/project-management.md +95 -0
- package/skills/apps/saas-dashboard.md +104 -0
- package/skills/apps/social-platform.md +50 -0
- package/skills/blocks/auth.md +106 -0
- package/skills/blocks/communication.md +98 -0
- package/skills/blocks/content.md +107 -0
- package/skills/blocks/data-management.md +109 -0
- package/skills/blocks/data-viz.md +92 -0
- package/skills/blocks/ecommerce.md +126 -0
- package/skills/blocks/feedback.md +97 -0
- package/skills/blocks/filtering.md +127 -0
- package/skills/blocks/marketing.md +136 -0
- package/skills/blocks/media.md +102 -0
- package/skills/blocks/navigation.md +136 -0
- package/skills/blocks/onboarding.md +75 -0
- package/skills/blocks/profiles.md +131 -0
- package/skills/blocks/scheduling.md +117 -0
- package/skills/blocks/settings.md +102 -0
- package/skills/components/advanced-components.md +142 -0
- package/skills/components/avatar.md +92 -0
- package/skills/components/badge.md +105 -0
- package/skills/components/button.md +87 -0
- package/skills/components/card.md +144 -0
- package/skills/components/chart.md +88 -0
- package/skills/components/dialog.md +109 -0
- package/skills/components/dropdown-menu.md +117 -0
- package/skills/components/extended-components.md +187 -0
- package/skills/components/feedback.md +165 -0
- package/skills/components/form.md +112 -0
- package/skills/components/input.md +107 -0
- package/skills/components/map.md +53 -0
- package/skills/components/navigation.md +73 -0
- package/skills/components/overlay.md +77 -0
- package/skills/components/page-header.md +51 -0
- package/skills/components/select.md +175 -0
- package/skills/components/table.md +102 -0
- package/skills/components/tabs.md +105 -0
- package/skills/components/utilities.md +138 -0
- package/skills/devices/desktop.md +43 -0
- package/skills/devices/mobile.md +77 -0
- package/skills/foundation/design-principles.md +77 -0
- package/skills/foundation/design-tokens.md +121 -0
- package/skills/foundation/mockup-generation.md +118 -0
- package/skills/foundation/rules.md +54 -0
- package/skills/foundation/tailwind-usage.md +204 -0
- package/skills/layouts/dashboard.md +71 -0
- package/skills/layouts/full-page-form.md +75 -0
- package/skills/layouts/list-detail.md +70 -0
- package/skills/layouts/marketing.md +70 -0
- package/skills/layouts/responsive.md +67 -0
- package/skills/layouts/settings-page.md +106 -0
- package/skills/layouts/sidebar.md +73 -0
- package/skills/layouts/topbar.md +68 -0
- package/skills/patterns/auth.md +131 -0
- package/skills/patterns/content-display.md +164 -0
- package/skills/patterns/dashboards.md +104 -0
- package/skills/patterns/data-tables.md +113 -0
- package/skills/patterns/empty-states.md +71 -0
- package/skills/patterns/error-states.md +73 -0
- package/skills/patterns/forms.md +136 -0
- package/skills/patterns/loading-states.md +92 -0
- package/skills/patterns/navigation.md +113 -0
- package/skills/patterns/notifications.md +91 -0
- package/skills/patterns/onboarding.md +42 -0
- package/skills/patterns/search.md +55 -0
- package/skills/patterns/settings.md +132 -0
- package/skills/patterns/user-profiles.md +67 -0
- package/skills/personas/business-operator.md +114 -0
- package/skills/personas/consumer-casual.md +60 -0
- package/skills/personas/consumer-power-user.md +109 -0
- package/skills/personas/creative-professional.md +109 -0
- package/skills/personas/enterprise-admin.md +134 -0
- package/skills/visual/color-usage.md +62 -0
- package/skills/visual/dark-mode.md +50 -0
- package/skills/visual/polish-techniques.md +101 -0
- package/skills/visual/spacing-composition.md +69 -0
- package/skills/visual/transitions-animations.md +66 -0
- package/skills/visual/typography-hierarchy.md +66 -0
- package/src/components/blocks/auth/auth-card/AuthCard.tsx +2 -2
- package/src/components/blocks/auth/social-login/SocialLoginGroup.tsx +2 -2
- package/src/components/blocks/auth/two-factor/TwoFactorForm.tsx +4 -4
- package/src/components/blocks/communication/activity-item/ActivityItem.tsx +1 -1
- package/src/components/blocks/communication/activity-item/ActivityItemAvatar.tsx +2 -2
- package/src/components/blocks/communication/activity-item/ActivityItemContent.tsx +1 -1
- package/src/components/blocks/communication/chat-bubble/ChatBubble.tsx +1 -1
- package/src/components/blocks/communication/chat-bubble/ChatBubbleAvatar.tsx +2 -2
- package/src/components/blocks/communication/chat-bubble/ChatBubbleMessage.tsx +1 -1
- package/src/components/blocks/communication/chat-bubble/ChatBubbleTimestamp.tsx +1 -1
- package/src/components/blocks/content/article-header/ArticleHeader.tsx +3 -3
- package/src/components/blocks/content/author-card/AuthorCard.tsx +4 -4
- package/src/components/blocks/content/rich-text/RichTextContent.tsx +1 -1
- package/src/components/blocks/data-management/kanban/KanbanBoard.tsx +1 -1
- package/src/components/blocks/data-management/kanban/KanbanCard.tsx +4 -4
- package/src/components/blocks/data-management/kanban/KanbanColumn.tsx +3 -3
- package/src/components/blocks/data-management/tree-view/TreeItem.tsx +2 -2
- package/src/components/blocks/data-management/tree-view/TreeView.tsx +1 -1
- package/src/components/blocks/data-viz/financial-ticker/FinancialTicker.tsx +1 -1
- package/src/components/blocks/data-viz/kpi-card/KpiCard.tsx +2 -2
- package/src/components/blocks/data-viz/stat-grid/StatGrid.tsx +1 -1
- package/src/components/blocks/ecommerce/pricing-tier/PricingFeatureList.tsx +2 -2
- package/src/components/blocks/ecommerce/pricing-tier/PricingHeader.tsx +2 -2
- package/src/components/blocks/ecommerce/pricing-tier/PricingTier.tsx +2 -2
- package/src/components/blocks/ecommerce/product-card/ProductCard.tsx +2 -2
- package/src/components/blocks/ecommerce/product-card/ProductCardContent.tsx +2 -2
- package/src/components/blocks/ecommerce/product-card/ProductCardImage.tsx +1 -1
- package/src/components/blocks/ecommerce/product-card/ProductCardPrice.tsx +1 -1
- package/src/components/blocks/ecommerce/rating-summary/RatingStars.tsx +1 -1
- package/src/components/blocks/feedback/empty-state/EmptyState.tsx +2 -2
- package/src/components/blocks/feedback/error-state/ErrorState.tsx +2 -2
- package/src/components/blocks/feedback/not-found/NotFoundState.tsx +2 -2
- package/src/components/blocks/filtering/faceted-sidebar/FacetedGroup.tsx +2 -2
- package/src/components/blocks/filtering/faceted-sidebar/FacetedSidebar.tsx +2 -2
- package/src/components/blocks/filtering/filter-bar/FilterBar.tsx +4 -4
- package/src/components/blocks/filtering/search-result/SearchResultItem.tsx +2 -2
- package/src/components/blocks/marketing/cta-block/CtaBlock.tsx +2 -2
- package/src/components/blocks/marketing/feature-grid/FeatureGrid.tsx +1 -1
- package/src/components/blocks/marketing/hero-section/HeroSection.tsx +3 -3
- package/src/components/blocks/marketing/testimonial-card/TestimonialCard.tsx +3 -3
- package/src/components/blocks/media/call-controls/CallControlButton.tsx +3 -3
- package/src/components/blocks/media/call-controls/CallControls.tsx +1 -1
- package/src/components/blocks/media/media-player/MediaPlayer.tsx +1 -1
- package/src/components/blocks/media/media-player/MediaPlayerControls.tsx +1 -1
- package/src/components/blocks/media/media-player/MediaPlayerScrubber.tsx +1 -1
- package/src/components/blocks/media/media-player/MediaPlayerVideo.tsx +1 -1
- package/src/components/blocks/navigation/app-sidebar/AppSidebar.tsx +2 -2
- package/src/components/blocks/navigation/app-sidebar/NavItem.tsx +1 -1
- package/src/components/blocks/navigation/context-switcher/ContextSwitcher.tsx +3 -3
- package/src/components/blocks/navigation/top-navbar/TopNavbar.tsx +2 -2
- package/src/components/blocks/onboarding/onboarding-welcome/OnboardingWelcome.tsx +3 -3
- package/src/components/blocks/onboarding/step-wizard/StepWizard.tsx +1 -1
- package/src/components/blocks/profiles/connection-list/ConnectionItem.tsx +3 -3
- package/src/components/blocks/profiles/connection-list/ConnectionList.tsx +1 -1
- package/src/components/blocks/profiles/profile-header/ProfileHeader.tsx +3 -3
- package/src/components/blocks/profiles/profile-stats/ProfileStats.tsx +1 -1
- package/src/components/blocks/scheduling/booking-slot/BookingSlot.tsx +1 -1
- package/src/components/blocks/scheduling/event-card/EventCard.tsx +3 -3
- package/src/components/blocks/scheduling/timeline-row/TimelineRow.tsx +2 -2
- package/src/components/blocks/settings/billing-usage/BillingUsage.tsx +3 -3
- package/src/components/blocks/settings/integration-card/IntegrationCard.tsx +5 -5
- package/src/components/blocks/settings/settings-section/SettingsSection.tsx +1 -1
- package/src/components/ui/accordion.tsx +1 -1
- package/src/components/ui/alert-dialog.tsx +2 -2
- package/src/components/ui/alert.tsx +1 -1
- package/src/components/ui/avatar.tsx +1 -1
- package/src/components/ui/badge.tsx +7 -1
- package/src/components/ui/breadcrumb.tsx +1 -1
- package/src/components/ui/button.tsx +8 -1
- package/src/components/ui/calendar.tsx +2 -2
- package/src/components/ui/card.tsx +1 -1
- package/src/components/ui/carousel.tsx +2 -2
- package/src/components/ui/chart.tsx +1 -1
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/command.tsx +2 -2
- package/src/components/ui/component-placeholder.tsx +1 -1
- package/src/components/ui/context-menu.tsx +1 -1
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/drawer.tsx +1 -1
- package/src/components/ui/dropdown-menu.tsx +1 -1
- package/src/components/ui/form.tsx +2 -2
- package/src/components/ui/hover-card.tsx +1 -1
- package/src/components/ui/input-otp.tsx +1 -1
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/menubar.tsx +1 -1
- package/src/components/ui/navigation-menu.tsx +1 -1
- package/src/components/ui/pagination.tsx +2 -2
- package/src/components/ui/popover.tsx +1 -1
- package/src/components/ui/progress.tsx +1 -1
- package/src/components/ui/radio-group.tsx +1 -1
- package/src/components/ui/resizable.tsx +1 -1
- package/src/components/ui/scroll-area.tsx +1 -1
- package/src/components/ui/select.tsx +1 -1
- package/src/components/ui/separator.tsx +1 -1
- package/src/components/ui/sheet.tsx +1 -1
- package/src/components/ui/skeleton.tsx +1 -1
- package/src/components/ui/slider.tsx +1 -1
- package/src/components/ui/sonner.tsx +13 -6
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/table.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -1
- package/src/components/ui/textarea.tsx +1 -1
- package/src/components/ui/toast.tsx +1 -1
- package/src/components/ui/toaster.tsx +1 -1
- package/src/components/ui/toggle-group.tsx +2 -2
- package/src/components/ui/toggle.tsx +1 -1
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/hooks/use-toast.ts +1 -1
- package/src/styles/tokens.css +1 -1
- package/DESIGN_GUIDE.md +0 -148
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Advanced Components
|
|
2
|
+
|
|
3
|
+
Additional advanced structural and interactive components provided by Shadcn.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import {
|
|
7
|
+
Accordion, AccordionContent, AccordionItem, AccordionTrigger,
|
|
8
|
+
Calendar,
|
|
9
|
+
Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious,
|
|
10
|
+
Chart, // (And subcomponents like BarChart, LineChart)
|
|
11
|
+
Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList,
|
|
12
|
+
Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger,
|
|
13
|
+
ResizablePanelGroup, ResizablePanel, ResizableHandle,
|
|
14
|
+
Toggle, ToggleGroup, ToggleGroupItem
|
|
15
|
+
} from '@reinvented/design'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Accordion
|
|
19
|
+
|
|
20
|
+
Collapsible content panels.
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
<Accordion type="single" collapsible>
|
|
24
|
+
<AccordionItem value="item-1">
|
|
25
|
+
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
|
26
|
+
<AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
|
|
27
|
+
</AccordionItem>
|
|
28
|
+
</Accordion>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Calendar
|
|
32
|
+
|
|
33
|
+
A date picker calendar component using `v-calendar` under the hood.
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
<Calendar defaultValue="date" className="rounded-md border shadow" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Carousel
|
|
40
|
+
|
|
41
|
+
A hardware-accelerated carousel (via Embla).
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
<Carousel className="w-full max-w-xs">
|
|
45
|
+
<CarouselContent>
|
|
46
|
+
<CarouselItem v-for="(_, index) in 5" :key="index">
|
|
47
|
+
<div className="p-1">
|
|
48
|
+
<Card>
|
|
49
|
+
<CardContent className="flex aspect-square items-center justify-center p-6">
|
|
50
|
+
<span className="text-4xl font-semibold">{{ index + 1 }}</span>
|
|
51
|
+
</CardContent>
|
|
52
|
+
</Card>
|
|
53
|
+
</div>
|
|
54
|
+
</CarouselItem>
|
|
55
|
+
</CarouselContent>
|
|
56
|
+
<CarouselPrevious />
|
|
57
|
+
<CarouselNext />
|
|
58
|
+
</Carousel>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Chart
|
|
62
|
+
|
|
63
|
+
Data visualization using `recharts` / `@unovis/react`.
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
<!-- Uses standard Shadcn Chart implementations like BarChart, LineChart via react-echarts or recharts -->
|
|
67
|
+
<!-- See shadcn docs for exact data props structures -->
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Command (Command Palette)
|
|
71
|
+
|
|
72
|
+
Fast, composable command menu using `cmdk`.
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<Command>
|
|
76
|
+
<CommandInput placeholder="Type a command or search..." />
|
|
77
|
+
<CommandList>
|
|
78
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
79
|
+
<CommandGroup heading="Suggestions">
|
|
80
|
+
<CommandItem value="calendar">Calendar</CommandItem>
|
|
81
|
+
<CommandItem value="search-emoji">Search Emoji</CommandItem>
|
|
82
|
+
<CommandItem value="calculator">Calculator</CommandItem>
|
|
83
|
+
</CommandGroup>
|
|
84
|
+
</CommandList>
|
|
85
|
+
</Command>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Drawer
|
|
89
|
+
|
|
90
|
+
A bottom sheet component that acts as a slide-up dialog, especially tailored for mobile layouts where Dialogs might be awkward.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<Drawer>
|
|
94
|
+
<DrawerTrigger as-child>
|
|
95
|
+
<Button variant="outline">Open Drawer</Button>
|
|
96
|
+
</DrawerTrigger>
|
|
97
|
+
<DrawerContent>
|
|
98
|
+
<div className="mx-auto w-full max-w-sm">
|
|
99
|
+
<DrawerHeader>
|
|
100
|
+
<DrawerTitle>Move Goal</DrawerTitle>
|
|
101
|
+
<DrawerDescription>Set your daily activity goal.</DrawerDescription>
|
|
102
|
+
</DrawerHeader>
|
|
103
|
+
<!-- content -->
|
|
104
|
+
<DrawerFooter>
|
|
105
|
+
<Button>Submit</Button>
|
|
106
|
+
<DrawerClose as-child><Button variant="outline">Cancel</Button></DrawerClose>
|
|
107
|
+
</DrawerFooter>
|
|
108
|
+
</div>
|
|
109
|
+
</DrawerContent>
|
|
110
|
+
</Drawer>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Resizable
|
|
114
|
+
|
|
115
|
+
Resizable split panes.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<ResizablePanelGroup direction="horizontal" className="max-w-md rounded-lg border">
|
|
119
|
+
<ResizablePanel :default-size="50">
|
|
120
|
+
<div className="flex h-48 items-center justify-center p-6">Sidebar</div>
|
|
121
|
+
</ResizablePanel>
|
|
122
|
+
<ResizableHandle with-handle />
|
|
123
|
+
<ResizablePanel :default-size="50">
|
|
124
|
+
<div className="flex h-48 items-center justify-center p-6">Content</div>
|
|
125
|
+
</ResizablePanel>
|
|
126
|
+
</ResizablePanelGroup>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Toggle & ToggleGroup
|
|
130
|
+
|
|
131
|
+
A set of two-state buttons.
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
<ToggleGroup type="single">
|
|
135
|
+
<ToggleGroupItem value="bold" aria-label="Toggle bold">
|
|
136
|
+
<Bold className="h-4 w-4" />
|
|
137
|
+
</ToggleGroupItem>
|
|
138
|
+
<ToggleGroupItem value="italic" aria-label="Toggle italic">
|
|
139
|
+
<Italic className="h-4 w-4" />
|
|
140
|
+
</ToggleGroupItem>
|
|
141
|
+
</ToggleGroup>
|
|
142
|
+
```
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Avatar
|
|
2
|
+
|
|
3
|
+
User/entity representation. Displays an image, initials, or fallback.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Avatar, AvatarImage, AvatarFallback } from '@reinvented/design'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Basic Usage
|
|
10
|
+
|
|
11
|
+
The `Avatar` component handles the rendering logic automatically. It will try to load the `AvatarImage` first, and if it fails or hasn't loaded yet, it displays the `AvatarFallback`.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Avatar>
|
|
15
|
+
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
|
16
|
+
<AvatarFallback>CN</AvatarFallback>
|
|
17
|
+
</Avatar>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
In mockups, explicitly use the `AvatarFallback` without overriding its colors to maintain a clean aesthetic:
|
|
21
|
+
```tsx
|
|
22
|
+
<Avatar>
|
|
23
|
+
<!-- Generates initials like SC in standard muted Shadcn colors -->
|
|
24
|
+
<AvatarFallback className="bg-muted text-muted-foreground">
|
|
25
|
+
{{ user.name.split(' ').map(n => n[0]).join('') }}
|
|
26
|
+
</AvatarFallback>
|
|
27
|
+
</Avatar>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Sizes
|
|
31
|
+
|
|
32
|
+
Add Tailwind sizing classes directly to the `Avatar` wrapper:
|
|
33
|
+
|
|
34
|
+
| Size | Classes | When to Use |
|
|
35
|
+
|------|---------|-------------|
|
|
36
|
+
| Small | `<Avatar className="w-6 h-6 text-xs">` | Compact lists, inline mentions |
|
|
37
|
+
| Default | `<Avatar className="w-8 h-8 text-xs">` | Table rows, list items, comments |
|
|
38
|
+
| Medium | `<Avatar className="w-10 h-10 text-sm">` | Card headers, conversation items |
|
|
39
|
+
| Large | `<Avatar className="w-12 h-12 text-lg">` | Profile headers, detail views |
|
|
40
|
+
| XL | `<Avatar className="w-16 h-16 text-lg">` | Profile pages, settings |
|
|
41
|
+
|
|
42
|
+
## Avatar with Name
|
|
43
|
+
|
|
44
|
+
The standard user display pattern — avatar + name + secondary info:
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<div className="flex items-center gap-3">
|
|
48
|
+
<Avatar className="w-8 h-8">
|
|
49
|
+
<AvatarImage :src="user.avatarUrl" :alt="user.name" />
|
|
50
|
+
<AvatarFallback>{{ initials(user.name) }}</AvatarFallback>
|
|
51
|
+
</Avatar>
|
|
52
|
+
<div className="min-w-0">
|
|
53
|
+
<p className="text-sm font-medium truncate">{{ user.name }}</p>
|
|
54
|
+
<p className="text-xs text-muted-foreground truncate">{{ user.email }}</p>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Avatar Group (Stacked)
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
<div className="flex -space-x-2">
|
|
63
|
+
<Avatar v-for="user in users.slice(0, 4)" :key="user.id" className="w-8 h-8 border-2 border-background">
|
|
64
|
+
<AvatarImage :src="user.avatarUrl" />
|
|
65
|
+
<AvatarFallback>{{ initials(user.name) }}</AvatarFallback>
|
|
66
|
+
</Avatar>
|
|
67
|
+
<Avatar v-if="users.length > 4" className="w-8 h-8 border-2 border-background">
|
|
68
|
+
<AvatarFallback className="bg-muted text-muted-foreground">+{{ users.length - 4 }}</AvatarFallback>
|
|
69
|
+
</Avatar>
|
|
70
|
+
</div>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Key: Use `border-2 border-background` on each `<Avatar>` and `-space-x-2` on the container for the overlapping effect.
|
|
74
|
+
|
|
75
|
+
## Avatar with Status Dot
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
<div className="relative inline-block">
|
|
79
|
+
<Avatar className="w-10 h-10">
|
|
80
|
+
<AvatarImage src="/avatar.jpg" />
|
|
81
|
+
<AvatarFallback>JD</AvatarFallback>
|
|
82
|
+
</Avatar>
|
|
83
|
+
<!-- Top-right overlapping indicator with 'cutout' border effect -->
|
|
84
|
+
<span className="absolute -top-0.5 -right-0.5 w-3 h-3 rounded-full bg-success ring-2 ring-background z-10" />
|
|
85
|
+
</div>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use `bg-success` for online status, or `bg-destructive` for unread notifications.
|
|
89
|
+
|
|
90
|
+
## Rules
|
|
91
|
+
- In flex layouts, `<Avatar>` naturally behaves properly but applying `shrink-0` if it's placed inside a deep flex wrapper might help.
|
|
92
|
+
- In mockups without real images, always rely on `<AvatarFallback>` and DO NOT give it colorful gradients or custom styling. Maintain the strict Shadcn aesthetic using the default `bg-muted` and `text-muted-foreground`.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Badge
|
|
2
|
+
|
|
3
|
+
Small status indicators and labels.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Badge } from '@reinvented/design'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Variants
|
|
10
|
+
|
|
11
|
+
The standard Baseline Shadcn Badge includes:
|
|
12
|
+
| Variant | Appearance | When to Use |
|
|
13
|
+
|---------|-----------|-------------|
|
|
14
|
+
| `default` | `bg-primary text-primary-foreground` | Active status, primary category, count |
|
|
15
|
+
| `secondary` | `bg-secondary text-secondary-foreground` | Neutral tags, metadata labels |
|
|
16
|
+
| `destructive` | `bg-destructive text-destructive-foreground` | Error status, failed, expired |
|
|
17
|
+
| `outline` | `border` | Low-emphasis tags, filter chips |
|
|
18
|
+
|
|
19
|
+
| `success` | `bg-success text-success-foreground` | Success status, confirmed |
|
|
20
|
+
| `warning` | `bg-warning text-warning-foreground` | Warning status, pending review |
|
|
21
|
+
| `info` | `bg-info text-info-foreground` | Informational status |
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
<Badge>Active</Badge>
|
|
27
|
+
<Badge variant="secondary">Draft</Badge>
|
|
28
|
+
<Badge variant="destructive">Overdue</Badge>
|
|
29
|
+
<Badge variant="outline">v2.0.1</Badge>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Status Badge Pattern
|
|
33
|
+
|
|
34
|
+
Map data states to badge variants:
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
<Badge :variant="getStatusVariant(item.status)">
|
|
38
|
+
{{ item.status }}
|
|
39
|
+
</Badge>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import type { BadgeVariants } from '@reinvented/design/components/ui/badge'
|
|
44
|
+
|
|
45
|
+
function getStatusVariant(status: string): BadgeVariants['variant'] {
|
|
46
|
+
const map: Record<string, BadgeVariants['variant']> = {
|
|
47
|
+
active: 'default',
|
|
48
|
+
completed: 'success',
|
|
49
|
+
success: 'success',
|
|
50
|
+
warning: 'warning',
|
|
51
|
+
pending: 'secondary',
|
|
52
|
+
draft: 'secondary',
|
|
53
|
+
failed: 'destructive',
|
|
54
|
+
archived: 'outline',
|
|
55
|
+
}
|
|
56
|
+
return map[status] || 'secondary'
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Badge with Dot Indicator
|
|
61
|
+
|
|
62
|
+
For status badges that need a colored dot:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<Badge variant="outline" className="gap-1.5">
|
|
66
|
+
<span className="w-1.5 h-1.5 rounded-full bg-success" />
|
|
67
|
+
Online
|
|
68
|
+
</Badge>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Composition with Other Components
|
|
72
|
+
|
|
73
|
+
### In Table Cells
|
|
74
|
+
```tsx
|
|
75
|
+
<TableCell>
|
|
76
|
+
<Badge variant="secondary">{{ item.status }}</Badge>
|
|
77
|
+
</TableCell>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### In Card Headers
|
|
81
|
+
```tsx
|
|
82
|
+
<CardHeader className="flex flex-row items-center justify-between">
|
|
83
|
+
<CardTitle>Project Alpha</CardTitle>
|
|
84
|
+
<Badge>Active</Badge>
|
|
85
|
+
</CardHeader>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### As Count Indicator
|
|
89
|
+
```tsx
|
|
90
|
+
<Button variant="ghost">
|
|
91
|
+
Notifications
|
|
92
|
+
<Badge className="ml-1.5 px-1.5 py-0.5 text-xs">3</Badge>
|
|
93
|
+
</Button>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Rules
|
|
97
|
+
- Badge text should be **short** — 1-2 words max
|
|
98
|
+
- **Constrained-width contexts (table cells, narrow columns):** Add `whitespace-nowrap` to the Badge's `className` to prevent line breaks. Badges should never wrap to two lines — if text is wrapping, either the label is too long or the column is too narrow.
|
|
99
|
+
- Use `variant="secondary"` as the default when unsure
|
|
100
|
+
- **Always use built-in status variants**: For status badges, use `variant="warning"` for pending/caution states, `variant="success"` for confirmed/approved, `variant="destructive"` for errors/failures. Do **not** override colors manually (e.g., `className="bg-amber-500"`) — this bypasses dark mode handling and breaks visual consistency.
|
|
101
|
+
- Don't use badges for actions — they're display-only
|
|
102
|
+
- In tables, badges go in their own column (not inline with other text)
|
|
103
|
+
- **NEVER over-style badges**: Do not stack arbitrary Tailwind utilities (`bg-warning/5`, `text-warning/80`, `border-warning/30`) on top of a Badge to invent custom variations. This breaks dark/light mode contrast. Always rely on the built-in variants (`variant="secondary"`, `variant="warning"`, etc.).
|
|
104
|
+
- **NEVER invent new semantic solid colors**: Do not create your own badge variants by forcibly applying saturated background utility classes (e.g. `bg-emerald-500` or `bg-green-600/20 text-green-700`). Shadcn UI thrives on restraint. Use `default`, `secondary`, `outline`, or `destructive` exclusively.
|
|
105
|
+
- **NEVER override internal typography**: Do not apply font-weight (`font-normal`), text-sizes, or custom paddings (unless scaling down) to `<Badge>`. It should strictly use its native styles to maintain proportion with the rest of the Shadcn system.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
Primary interactive element. Always use `<Button>` — never raw `<button>`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Button } from '@reinvented/design'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Variants
|
|
10
|
+
|
|
11
|
+
| Variant | Classes | When to Use |
|
|
12
|
+
|---------|---------|-------------|
|
|
13
|
+
| `default` | `bg-primary text-primary-foreground` | **Primary actions**: Save, Create, Submit, Send. One per section max. |
|
|
14
|
+
| `secondary` | `bg-secondary text-secondary-foreground` | **Secondary actions**: Cancel, Back, Reset. Alongside a primary button. |
|
|
15
|
+
| `destructive` | `bg-destructive text-destructive-foreground` | **Dangerous actions**: Delete, Remove. Always pair with confirmation. |
|
|
16
|
+
| `outline` | `border bg-background` | **Tertiary actions**: Export, Filter, Share. Less visual weight than secondary. |
|
|
17
|
+
| `ghost` | `hover:bg-accent` | **Subtle actions**: Icon-only buttons, toolbar actions, table row actions. |
|
|
18
|
+
| `link` | `text-primary underline-offset-4` | **Inline links**: Text-level actions that look like links. |
|
|
19
|
+
| `success` | `bg-success text-success-foreground` | **Positive confirmations**: Approve, Accept, Confirm. |
|
|
20
|
+
| `warning` | `bg-warning text-warning-foreground` | **Warning actions**: Suspend, Delay, Acknowledge Risk. |
|
|
21
|
+
| `info` | `bg-info text-info-foreground` | **Informational actions**: View Details, Learn More. |
|
|
22
|
+
|
|
23
|
+
### Variant Decision Tree
|
|
24
|
+
```
|
|
25
|
+
Is this the main CTA?
|
|
26
|
+
├─ Yes → default
|
|
27
|
+
├─ No
|
|
28
|
+
│ ├─ Is it destructive? → destructive
|
|
29
|
+
│ ├─ Is it paired with a primary button? → secondary or outline
|
|
30
|
+
│ ├─ Is it an icon-only action? → ghost (size="icon")
|
|
31
|
+
│ ├─ Is it inline with text? → link
|
|
32
|
+
│ └─ Is it a positive confirmation? → success
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Sizes
|
|
36
|
+
|
|
37
|
+
| Size | Classes | When to Use |
|
|
38
|
+
|------|---------|-------------|
|
|
39
|
+
| `xs` | `h-7 px-2 text-xs` | Compact UI: table row actions, inline tags |
|
|
40
|
+
| `sm` | `h-8 px-3 text-xs` | Secondary area buttons, compact toolbars |
|
|
41
|
+
| `default` | `h-9 px-4 py-2` | **Standard** — use this for most buttons |
|
|
42
|
+
| `lg` | `h-10 px-8` | Emphasized CTAs, empty state actions |
|
|
43
|
+
| `xl` | `h-12 px-10 text-base` | Hero/marketing CTAs only |
|
|
44
|
+
| `icon` | `h-9 w-9` | Icon-only square buttons |
|
|
45
|
+
|
|
46
|
+
## Common Compositions
|
|
47
|
+
|
|
48
|
+
### Button with Icon
|
|
49
|
+
```tsx
|
|
50
|
+
<Button>
|
|
51
|
+
<Plus className="w-4 h-4" />
|
|
52
|
+
New Project
|
|
53
|
+
</Button>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Icon-Only Button
|
|
57
|
+
```tsx
|
|
58
|
+
<Button variant="ghost" size="icon" aria-label="Settings">
|
|
59
|
+
<Settings className="w-4 h-4" />
|
|
60
|
+
</Button>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Loading Button
|
|
64
|
+
```tsx
|
|
65
|
+
<Button :disabled="saving">
|
|
66
|
+
<Loader2 v-if="saving" className="w-4 h-4 animate-spin" />
|
|
67
|
+
{{ saving ? 'Saving...' : 'Save Changes' }}
|
|
68
|
+
</Button>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Button Group (primary + secondary)
|
|
72
|
+
```tsx
|
|
73
|
+
<div className="flex items-center gap-2">
|
|
74
|
+
<Button variant="outline">Cancel</Button>
|
|
75
|
+
<Button>Save Changes</Button>
|
|
76
|
+
</div>
|
|
77
|
+
```
|
|
78
|
+
Note: Primary action is always **last** (rightmost) in a button group.
|
|
79
|
+
|
|
80
|
+
### Destructive with Confirmation
|
|
81
|
+
Always pair destructive buttons with `<AlertDialog>` — never delete on single click.
|
|
82
|
+
|
|
83
|
+
## Rules
|
|
84
|
+
- One `default` variant button per logical section (the "primary CTA rule")
|
|
85
|
+
- Always add `aria-label` to icon-only buttons
|
|
86
|
+
- Loading state: show `<Loader2 className="w-4 h-4 animate-spin" />` and `:disabled="true"`
|
|
87
|
+
- In forms, use `type="submit"` on the primary button, `type="button"` on others
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
The primary content container. Use Cards to group related content into visually distinct blocks.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '@reinvented/design'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Subcomponents
|
|
10
|
+
|
|
11
|
+
| Component | Default Classes | Purpose |
|
|
12
|
+
|-----------|----------------|---------|
|
|
13
|
+
| `Card` | `rounded-lg border bg-card shadow-sm` | Outer container |
|
|
14
|
+
| `CardHeader` | `flex flex-col gap-1.5 p-6` | Title + description area |
|
|
15
|
+
| `CardTitle` | `font-semibold leading-none tracking-tight` | Card heading |
|
|
16
|
+
| `CardDescription` | `text-sm text-muted-foreground` | Subtitle / helper text |
|
|
17
|
+
| `CardContent` | `p-6 pt-0` | Body content area |
|
|
18
|
+
| `CardFooter` | `flex items-center p-6 pt-0` | Action buttons area |
|
|
19
|
+
|
|
20
|
+
## Standard Card
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
<Card>
|
|
24
|
+
<CardHeader>
|
|
25
|
+
<CardTitle>Team Members</CardTitle>
|
|
26
|
+
<CardDescription>Manage your team and their roles.</CardDescription>
|
|
27
|
+
</CardHeader>
|
|
28
|
+
<CardContent>
|
|
29
|
+
<!-- Content here -->
|
|
30
|
+
</CardContent>
|
|
31
|
+
<CardFooter className="justify-end gap-2">
|
|
32
|
+
<Button variant="outline">Cancel</Button>
|
|
33
|
+
<Button>Save</Button>
|
|
34
|
+
</CardFooter>
|
|
35
|
+
</Card>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Stat Card (Dashboard KPI)
|
|
39
|
+
|
|
40
|
+
Used in dashboard stat grids. Compact layout with metric + label + optional trend.
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
<Card>
|
|
44
|
+
<CardHeader className="flex flex-row items-center justify-between pb-2">
|
|
45
|
+
<CardTitle className="text-sm font-medium">Total Revenue</CardTitle>
|
|
46
|
+
<DollarSign className="h-4 w-4 text-muted-foreground" />
|
|
47
|
+
</CardHeader>
|
|
48
|
+
<CardContent>
|
|
49
|
+
<div className="text-2xl font-bold">$45,231.89</div>
|
|
50
|
+
<p className="text-xs text-muted-foreground">+20.1% from last month</p>
|
|
51
|
+
</CardContent>
|
|
52
|
+
</Card>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Key details:
|
|
56
|
+
- `CardHeader` uses `flex flex-row items-center justify-between pb-2` to place icon on the right
|
|
57
|
+
- `CardTitle` is downsized to `text-sm font-medium` (not the default heading size)
|
|
58
|
+
- Metric value is `text-2xl font-bold`
|
|
59
|
+
- Trend text is `text-xs text-muted-foreground`
|
|
60
|
+
- **NEVER wrap the icon in a colored background element** (like `bg-primary/20 p-2 rounded-full`). Stat card icons should remain minimal and transparent, using `text-muted-foreground` directly.
|
|
61
|
+
|
|
62
|
+
## Clickable Card (List Item)
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
<Card className="cursor-pointer transition-colors hover:bg-accent/50">
|
|
66
|
+
<CardContent className="flex items-center gap-4 p-4">
|
|
67
|
+
<div className="w-10 h-10 rounded-full shrink-0 bg-gradient-to-br from-primary/20 to-primary/40" />
|
|
68
|
+
<div className="flex-1 min-w-0">
|
|
69
|
+
<p className="text-sm font-medium truncate">Project Alpha</p>
|
|
70
|
+
<p className="text-xs text-muted-foreground">Updated 2 hours ago</p>
|
|
71
|
+
</div>
|
|
72
|
+
<ChevronRight className="w-4 h-4 text-muted-foreground shrink-0" />
|
|
73
|
+
</CardContent>
|
|
74
|
+
</Card>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Key details:
|
|
78
|
+
- Use `hover:bg-accent/50` for subtle hover (not `hover:shadow-md` which can look jarring)
|
|
79
|
+
- `min-w-0` on the text container enables `truncate` to work in flex layouts
|
|
80
|
+
- `shrink-0` on fixed-size elements prevents them from collapsing
|
|
81
|
+
|
|
82
|
+
## Card with Sections (Divided Content)
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<Card>
|
|
86
|
+
<CardHeader>
|
|
87
|
+
<CardTitle>Account Settings</CardTitle>
|
|
88
|
+
</CardHeader>
|
|
89
|
+
<CardContent className="space-y-4">
|
|
90
|
+
<div className="flex items-center justify-between">
|
|
91
|
+
<div>
|
|
92
|
+
<p className="text-sm font-medium">Email Notifications</p>
|
|
93
|
+
<p className="text-xs text-muted-foreground">Receive emails about your account activity.</p>
|
|
94
|
+
</div>
|
|
95
|
+
<Switch />
|
|
96
|
+
</div>
|
|
97
|
+
<Separator />
|
|
98
|
+
<div className="flex items-center justify-between">
|
|
99
|
+
<div>
|
|
100
|
+
<p className="text-sm font-medium">Marketing Emails</p>
|
|
101
|
+
<p className="text-xs text-muted-foreground">Receive emails about new features and updates.</p>
|
|
102
|
+
</div>
|
|
103
|
+
<Switch />
|
|
104
|
+
</div>
|
|
105
|
+
</CardContent>
|
|
106
|
+
</Card>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Card with Footer Link ("View All" Pattern)
|
|
110
|
+
|
|
111
|
+
When a card shows a preview of a longer list (e.g., recent activity, top items), use a footer link to navigate to the full view. This is a very common pattern — always implement it consistently:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
<Card>
|
|
115
|
+
<CardHeader>
|
|
116
|
+
<CardTitle>Recent Activity</CardTitle>
|
|
117
|
+
<CardDescription>Latest updates in this project</CardDescription>
|
|
118
|
+
</CardHeader>
|
|
119
|
+
<CardContent>
|
|
120
|
+
{/* Preview list items */}
|
|
121
|
+
</CardContent>
|
|
122
|
+
<CardFooter className="border-t px-6 py-3">
|
|
123
|
+
<Button variant="ghost" size="sm" className="w-full text-muted-foreground">
|
|
124
|
+
View all activity <ArrowRight className="ml-2 w-4 h-4" />
|
|
125
|
+
</Button>
|
|
126
|
+
</CardFooter>
|
|
127
|
+
</Card>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Key details:
|
|
131
|
+
- `CardFooter` gets `border-t px-6 py-3` — the border separates the link from content, and `py-3` keeps it compact (default `p-6` is too spacious for a single text link)
|
|
132
|
+
- Button uses `variant="ghost" size="sm"` — visually lightweight, clearly interactive on hover
|
|
133
|
+
- Button uses `w-full` so the entire footer row is clickable
|
|
134
|
+
- Text color is `text-muted-foreground` — secondary emphasis, not primary (this is navigation, not a CTA)
|
|
135
|
+
- Arrow icon (`ArrowRight`) signals navigation
|
|
136
|
+
- **Never** use a full-height default button or `variant="link"` here — ghost sm is the standard
|
|
137
|
+
|
|
138
|
+
## Rules
|
|
139
|
+
|
|
140
|
+
- **Padding**: Cards use `p-6` by default. Use `p-4` for compact cards (list items, stat cards).
|
|
141
|
+
- **List Items Alignment**: When rendering lists or `ScrollArea` items inside a card, avoid "double-padding" (the card's padding + the item's padding making items intuitively disconnected from the title). Manually offset the `<CardContent>` padding (e.g., `<CardContent className="flex-1 min-h-0 px-3 pb-3 pt-0">`).
|
|
142
|
+
- **Never hardcode backgrounds** — `bg-card` is automatic. Add custom backgrounds only for special cases.
|
|
143
|
+
- **Don't nest cards** — if you need sections within a card, use `<Separator>` or spacing.
|
|
144
|
+
- **Card grid gap**: Use `gap-4` for stat card grids, `gap-6` for content card grids.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Charts
|
|
2
|
+
|
|
3
|
+
Visual data representations. Supports `<AreaChart>`, `<BarChart>`, `<DonutChart>`, and `<LineChart>`.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { AreaChart, BarChart, DonutChart, LineChart } from '@reinvented/design'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Basic Structure
|
|
10
|
+
|
|
11
|
+
Charts require `data`, an `index` (the x-axis or category key), and `categories` (the data keys to plot). Note that `DonutChart` uses the `category` prop instead of `categories`.
|
|
12
|
+
|
|
13
|
+
### Area Chart
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
<AreaChart
|
|
17
|
+
:data="[
|
|
18
|
+
{ month: 'Jan', revenue: 1200, profit: 800 },
|
|
19
|
+
{ month: 'Feb', revenue: 2100, profit: 1200 }
|
|
20
|
+
]"
|
|
21
|
+
index="month"
|
|
22
|
+
:categories="['revenue', 'profit']"
|
|
23
|
+
className="h-72"
|
|
24
|
+
/>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Bar Chart
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
<BarChart
|
|
31
|
+
:data="chartData"
|
|
32
|
+
index="name"
|
|
33
|
+
:categories="['total', 'predicted']"
|
|
34
|
+
:rounded-corners="4"
|
|
35
|
+
className="h-72"
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Line Chart
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<LineChart
|
|
43
|
+
:data="chartData"
|
|
44
|
+
index="date"
|
|
45
|
+
:categories="['activeUsers']"
|
|
46
|
+
className="h-64"
|
|
47
|
+
/>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Donut Chart
|
|
51
|
+
|
|
52
|
+
Used for single-dimension distribution.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<DonutChart
|
|
56
|
+
:data="[
|
|
57
|
+
{ name: 'Direct', value: 400 },
|
|
58
|
+
{ name: 'Organic', value: 300 },
|
|
59
|
+
{ name: 'Referral', value: 300 },
|
|
60
|
+
]"
|
|
61
|
+
index="name"
|
|
62
|
+
category="value"
|
|
63
|
+
className="h-48"
|
|
64
|
+
/>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Key Props
|
|
68
|
+
|
|
69
|
+
| Prop | Description | Applies To |
|
|
70
|
+
|------|-------------|------------|
|
|
71
|
+
| `data` | Array of objects representing the dataset. | All |
|
|
72
|
+
| `index` | The key used for labels (X-axis) (e.g., 'month', 'name'). | All |
|
|
73
|
+
| `categories` | Array of keys to plot (e.g., `['revenue', 'profit']`). | Area, Bar, Line |
|
|
74
|
+
| `category` | Single key to plot for distributions. | Donut |
|
|
75
|
+
| `valueFormatter` | Function to format tooltip/axis values `(tick: number) => string`. | All |
|
|
76
|
+
| `colors` | Array of CSS color variables or raw values. Default colors apply automatically. | All |
|
|
77
|
+
| `showLegend` | Boolean to show/hide the legend (default true). | All |
|
|
78
|
+
|
|
79
|
+
## Rules
|
|
80
|
+
|
|
81
|
+
- Always set an explicit height (e.g., `className="h-72"`) on charts.
|
|
82
|
+
- Place charts inside a `<CardContent>` with a `<CardTitle>` describing the data.
|
|
83
|
+
- Ensure `index` matches a string field in the data (like a date or name).
|
|
84
|
+
- Provide plausible dummy data in mockup mode.
|
|
85
|
+
- **Formatting Currency**: When dealing with financial numbers, use `valueFormatter` and configure `toLocaleString` to show 2 decimal places: `:value-formatter="(tick) => tick.toLocaleString('en-US', { style: 'currency', currency: 'USD' })"`
|
|
86
|
+
- **Colors**: Shadcn charts (Unovis) expect valid CSS color strings (hex `#10b981`, standard color names like `red`, or css vars like `var(--theme-primary)`). Do NOT pass raw Tailwind semantic names (like `emerald` or `primary`) to the `colors` array as they will fail to resolve and render black. Instead, use their hex equivalents (e.g., `#10b981` for emerald).
|
|
87
|
+
- **Legends**: If building a custom legend beneath a chart, make sure to add `:show-legend="false"` to the chart so it doesn't render duplicate keys!
|
|
88
|
+
- **Donut Chart Key Clash**: When using `<DonutChart>`, do NOT use `'value'` as the `category` key in your data, because it clashes with Unovis internal segment variables and causes `[object Object]` tooltip rendering errors. Always use a semantic key like `revenue`, `amount`, `users`, etc. (e.g. `<DonutChart category="revenue" />`).
|