@reinvented/design 0.3.0 → 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.
- package/package.json +55 -21
- package/src/components/blocks/auth/auth-card/AuthCard.tsx +62 -0
- package/src/components/blocks/auth/auth-card/index.ts +1 -0
- package/src/components/blocks/auth/index.ts +3 -0
- package/src/components/blocks/auth/social-login/SocialLoginGroup.tsx +75 -0
- package/src/components/blocks/auth/social-login/index.ts +1 -0
- package/src/components/blocks/auth/two-factor/TwoFactorForm.tsx +59 -0
- package/src/components/blocks/auth/two-factor/index.ts +1 -0
- package/src/components/blocks/communication/activity-item/ActivityItem.tsx +17 -0
- package/src/components/blocks/communication/activity-item/ActivityItemAvatar.tsx +21 -0
- package/src/components/blocks/communication/activity-item/ActivityItemContent.tsx +16 -0
- package/src/components/blocks/communication/activity-item/index.ts +3 -0
- package/src/components/blocks/communication/chat-bubble/ChatBubble.tsx +21 -0
- package/src/components/blocks/communication/chat-bubble/ChatBubbleAvatar.tsx +19 -0
- package/src/components/blocks/communication/chat-bubble/ChatBubbleMessage.tsx +35 -0
- package/src/components/blocks/communication/chat-bubble/ChatBubbleTimestamp.tsx +15 -0
- package/src/components/blocks/communication/chat-bubble/index.ts +4 -0
- package/src/components/blocks/communication/index.ts +2 -0
- package/src/components/blocks/content/article-header/ArticleHeader.tsx +73 -0
- package/src/components/blocks/content/article-header/index.ts +1 -0
- package/src/components/blocks/content/author-card/AuthorCard.tsx +46 -0
- package/src/components/blocks/content/author-card/index.ts +1 -0
- package/src/components/blocks/content/index.ts +3 -0
- package/src/components/blocks/content/rich-text/RichTextContent.tsx +27 -0
- package/src/components/blocks/content/rich-text/index.ts +1 -0
- package/src/components/blocks/data-management/index.ts +2 -0
- package/src/components/blocks/data-management/kanban/KanbanBoard.tsx +10 -0
- package/src/components/blocks/data-management/kanban/KanbanCard.tsx +102 -0
- package/src/components/blocks/data-management/kanban/KanbanColumn.tsx +41 -0
- package/src/components/blocks/data-management/kanban/index.ts +3 -0
- package/src/components/blocks/data-management/tree-view/TreeItem.tsx +68 -0
- package/src/components/blocks/data-management/tree-view/TreeView.tsx +10 -0
- package/src/components/blocks/data-management/tree-view/index.ts +2 -0
- package/src/components/blocks/data-viz/financial-ticker/FinancialTicker.tsx +35 -0
- package/src/components/blocks/data-viz/financial-ticker/index.ts +1 -0
- package/src/components/blocks/data-viz/index.ts +3 -0
- package/src/components/blocks/data-viz/kpi-card/KpiCard.tsx +61 -0
- package/src/components/blocks/data-viz/kpi-card/index.ts +1 -0
- package/src/components/blocks/data-viz/stat-grid/StatGrid.tsx +28 -0
- package/src/components/blocks/data-viz/stat-grid/index.ts +1 -0
- package/src/components/blocks/ecommerce/index.ts +3 -0
- package/src/components/blocks/ecommerce/pricing-tier/PricingFeatureList.tsx +27 -0
- package/src/components/blocks/ecommerce/pricing-tier/PricingHeader.tsx +25 -0
- package/src/components/blocks/ecommerce/pricing-tier/PricingTier.tsx +31 -0
- package/src/components/blocks/ecommerce/pricing-tier/index.ts +3 -0
- package/src/components/blocks/ecommerce/product-card/ProductCard.tsx +17 -0
- package/src/components/blocks/ecommerce/product-card/ProductCardContent.tsx +15 -0
- package/src/components/blocks/ecommerce/product-card/ProductCardImage.tsx +20 -0
- package/src/components/blocks/ecommerce/product-card/ProductCardPrice.tsx +20 -0
- package/src/components/blocks/ecommerce/product-card/index.ts +4 -0
- package/src/components/blocks/ecommerce/rating-summary/RatingStars.tsx +32 -0
- package/src/components/blocks/ecommerce/rating-summary/index.ts +1 -0
- package/src/components/blocks/feedback/empty-state/EmptyState.tsx +53 -0
- package/src/components/blocks/feedback/empty-state/index.ts +1 -0
- package/src/components/blocks/feedback/error-state/ErrorState.tsx +50 -0
- package/src/components/blocks/feedback/error-state/index.ts +1 -0
- package/src/components/blocks/feedback/index.ts +3 -0
- package/src/components/blocks/feedback/not-found/NotFoundState.tsx +47 -0
- package/src/components/blocks/feedback/not-found/index.ts +1 -0
- package/src/components/blocks/filtering/faceted-sidebar/FacetedGroup.tsx +32 -0
- package/src/components/blocks/filtering/faceted-sidebar/FacetedSidebar.tsx +26 -0
- package/src/components/blocks/filtering/faceted-sidebar/index.ts +2 -0
- package/src/components/blocks/filtering/filter-bar/FilterBar.tsx +85 -0
- package/src/components/blocks/filtering/filter-bar/index.ts +1 -0
- package/src/components/blocks/filtering/index.ts +3 -0
- package/src/components/blocks/filtering/search-result/SearchResultItem.tsx +70 -0
- package/src/components/blocks/filtering/search-result/index.ts +1 -0
- package/src/components/blocks/index.ts +21 -0
- package/src/components/blocks/marketing/cta-block/CtaBlock.tsx +80 -0
- package/src/components/blocks/marketing/cta-block/index.ts +1 -0
- package/src/components/blocks/marketing/feature-grid/FeatureGrid.tsx +47 -0
- package/src/components/blocks/marketing/feature-grid/index.ts +1 -0
- package/src/components/blocks/marketing/hero-section/HeroSection.tsx +89 -0
- package/src/components/blocks/marketing/hero-section/index.ts +1 -0
- package/src/components/blocks/marketing/index.ts +4 -0
- package/src/components/blocks/marketing/testimonial-card/TestimonialCard.tsx +71 -0
- package/src/components/blocks/marketing/testimonial-card/index.ts +1 -0
- package/src/components/blocks/media/call-controls/CallControlButton.tsx +52 -0
- package/src/components/blocks/media/call-controls/CallControls.tsx +10 -0
- package/src/components/blocks/media/call-controls/index.ts +2 -0
- package/src/components/blocks/media/index.ts +2 -0
- package/src/components/blocks/media/media-player/MediaPlayer.tsx +20 -0
- package/src/components/blocks/media/media-player/MediaPlayerControls.tsx +16 -0
- package/src/components/blocks/media/media-player/MediaPlayerScrubber.tsx +29 -0
- package/src/components/blocks/media/media-player/MediaPlayerVideo.tsx +25 -0
- package/src/components/blocks/media/media-player/index.ts +4 -0
- package/src/components/blocks/navigation/app-sidebar/AppSidebar.tsx +32 -0
- package/src/components/blocks/navigation/app-sidebar/NavItem.tsx +43 -0
- package/src/components/blocks/navigation/app-sidebar/index.ts +2 -0
- package/src/components/blocks/navigation/context-switcher/ContextSwitcher.tsx +77 -0
- package/src/components/blocks/navigation/context-switcher/index.ts +1 -0
- package/src/components/blocks/navigation/index.ts +3 -0
- package/src/components/blocks/navigation/top-navbar/TopNavbar.tsx +47 -0
- package/src/components/blocks/navigation/top-navbar/index.ts +1 -0
- package/src/components/blocks/onboarding/index.ts +2 -0
- package/src/components/blocks/onboarding/onboarding-welcome/OnboardingWelcome.tsx +74 -0
- package/src/components/blocks/onboarding/onboarding-welcome/index.ts +1 -0
- package/src/components/blocks/onboarding/step-wizard/StepWizard.tsx +72 -0
- package/src/components/blocks/onboarding/step-wizard/index.ts +1 -0
- package/src/components/blocks/profiles/connection-list/ConnectionItem.tsx +35 -0
- package/src/components/blocks/profiles/connection-list/ConnectionList.tsx +16 -0
- package/src/components/blocks/profiles/connection-list/index.ts +2 -0
- package/src/components/blocks/profiles/index.ts +3 -0
- package/src/components/blocks/profiles/profile-header/ProfileHeader.tsx +88 -0
- package/src/components/blocks/profiles/profile-header/index.ts +1 -0
- package/src/components/blocks/profiles/profile-stats/ProfileStats.tsx +20 -0
- package/src/components/blocks/profiles/profile-stats/index.ts +1 -0
- package/src/components/blocks/scheduling/booking-slot/BookingSlot.tsx +44 -0
- package/src/components/blocks/scheduling/booking-slot/index.ts +1 -0
- package/src/components/blocks/scheduling/event-card/EventCard.tsx +85 -0
- package/src/components/blocks/scheduling/event-card/index.ts +1 -0
- package/src/components/blocks/scheduling/index.ts +3 -0
- package/src/components/blocks/scheduling/timeline-row/TimelineRow.tsx +82 -0
- package/src/components/blocks/scheduling/timeline-row/index.ts +1 -0
- package/src/components/blocks/settings/billing-usage/BillingUsage.tsx +49 -0
- package/src/components/blocks/settings/billing-usage/index.ts +1 -0
- package/src/components/blocks/settings/index.ts +3 -0
- package/src/components/blocks/settings/integration-card/IntegrationCard.tsx +62 -0
- package/src/components/blocks/settings/integration-card/index.ts +1 -0
- package/src/components/blocks/settings/settings-section/SettingsSection.tsx +23 -0
- package/src/components/blocks/settings/settings-section/index.ts +1 -0
- package/src/components/ui/accordion.tsx +56 -0
- package/src/components/ui/alert-dialog.tsx +141 -0
- package/src/components/ui/alert.tsx +59 -0
- package/src/components/ui/aspect-ratio.tsx +5 -0
- package/src/components/ui/avatar.tsx +50 -0
- package/src/components/ui/badge.tsx +36 -0
- package/src/components/ui/breadcrumb.tsx +115 -0
- package/src/components/ui/button.tsx +56 -0
- package/src/components/ui/calendar.tsx +211 -0
- package/src/components/ui/card.tsx +79 -0
- package/src/components/ui/carousel.tsx +262 -0
- package/src/components/ui/chart.tsx +367 -0
- package/src/components/ui/checkbox.tsx +28 -0
- package/src/components/ui/collapsible.tsx +11 -0
- package/src/components/ui/command.tsx +153 -0
- package/src/components/ui/component-placeholder.tsx +38 -0
- package/src/components/ui/context-menu.tsx +198 -0
- package/src/components/ui/dialog.tsx +122 -0
- package/src/components/ui/drawer.tsx +116 -0
- package/src/components/ui/dropdown-menu.tsx +200 -0
- package/src/components/ui/form.tsx +176 -0
- package/src/components/ui/hover-card.tsx +27 -0
- package/src/components/ui/input-otp.tsx +69 -0
- package/src/components/ui/input.tsx +22 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/menubar.tsx +256 -0
- package/src/components/ui/navigation-menu.tsx +128 -0
- package/src/components/ui/pagination.tsx +117 -0
- package/src/components/ui/popover.tsx +29 -0
- package/src/components/ui/progress.tsx +28 -0
- package/src/components/ui/radio-group.tsx +42 -0
- package/src/components/ui/resizable.tsx +45 -0
- package/src/components/ui/scroll-area.tsx +46 -0
- package/src/components/ui/select.tsx +160 -0
- package/src/components/ui/separator.tsx +29 -0
- package/src/components/ui/sheet.tsx +140 -0
- package/src/components/ui/skeleton.tsx +15 -0
- package/src/components/ui/slider.tsx +26 -0
- package/src/components/ui/sonner.tsx +45 -0
- package/src/components/ui/switch.tsx +27 -0
- package/src/components/ui/table.tsx +117 -0
- package/src/components/ui/tabs.tsx +53 -0
- package/src/components/ui/textarea.tsx +22 -0
- package/src/components/ui/toast.tsx +127 -0
- package/src/components/ui/toaster.tsx +33 -0
- package/src/components/ui/toggle-group.tsx +61 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/components/ui/tooltip.tsx +28 -0
- package/src/hooks/use-toast.ts +194 -0
- package/src/index.ts +53 -56
- package/src/styles/index.css +6 -0
- package/src/styles/tokens.css +30 -18
- package/tailwind.config.js +120 -98
- package/tsconfig.json +2 -2
- package/src/components/ui/accordion/Accordion.vue +0 -13
- package/src/components/ui/accordion/AccordionContent.vue +0 -20
- package/src/components/ui/accordion/AccordionItem.vue +0 -15
- package/src/components/ui/accordion/AccordionTrigger.vue +0 -25
- package/src/components/ui/accordion/index.ts +0 -4
- package/src/components/ui/alert/Alert.vue +0 -38
- package/src/components/ui/alert/AlertDescription.vue +0 -12
- package/src/components/ui/alert/AlertTitle.vue +0 -12
- package/src/components/ui/alert/index.ts +0 -3
- package/src/components/ui/alert-dialog/AlertDialog.vue +0 -13
- package/src/components/ui/alert-dialog/AlertDialogAction.vue +0 -21
- package/src/components/ui/alert-dialog/AlertDialogCancel.vue +0 -21
- package/src/components/ui/alert-dialog/AlertDialogContent.vue +0 -39
- package/src/components/ui/alert-dialog/AlertDialogDescription.vue +0 -15
- package/src/components/ui/alert-dialog/AlertDialogFooter.vue +0 -12
- package/src/components/ui/alert-dialog/AlertDialogHeader.vue +0 -12
- package/src/components/ui/alert-dialog/AlertDialogTitle.vue +0 -15
- package/src/components/ui/alert-dialog/AlertDialogTrigger.vue +0 -11
- package/src/components/ui/alert-dialog/index.ts +0 -9
- package/src/components/ui/avatar/Avatar.vue +0 -14
- package/src/components/ui/avatar/index.ts +0 -1
- package/src/components/ui/badge/Badge.vue +0 -27
- package/src/components/ui/badge/index.ts +0 -1
- package/src/components/ui/breadcrumb/Breadcrumb.vue +0 -6
- package/src/components/ui/breadcrumb/BreadcrumbEllipsis.vue +0 -12
- package/src/components/ui/breadcrumb/BreadcrumbItem.vue +0 -6
- package/src/components/ui/breadcrumb/BreadcrumbLink.vue +0 -20
- package/src/components/ui/breadcrumb/BreadcrumbList.vue +0 -6
- package/src/components/ui/breadcrumb/BreadcrumbPage.vue +0 -6
- package/src/components/ui/breadcrumb/BreadcrumbSeparator.vue +0 -11
- package/src/components/ui/breadcrumb/index.ts +0 -7
- package/src/components/ui/button/Button.vue +0 -65
- package/src/components/ui/button/index.ts +0 -1
- package/src/components/ui/card/Card.vue +0 -13
- package/src/components/ui/card/CardContent.vue +0 -7
- package/src/components/ui/card/CardDescription.vue +0 -7
- package/src/components/ui/card/CardFooter.vue +0 -7
- package/src/components/ui/card/CardHeader.vue +0 -9
- package/src/components/ui/card/CardTitle.vue +0 -7
- package/src/components/ui/card/index.ts +0 -6
- package/src/components/ui/checkbox/Checkbox.vue +0 -25
- package/src/components/ui/checkbox/index.ts +0 -1
- package/src/components/ui/collapsible/Collapsible.vue +0 -13
- package/src/components/ui/collapsible/index.ts +0 -2
- package/src/components/ui/command/Command.vue +0 -16
- package/src/components/ui/command/CommandEmpty.vue +0 -5
- package/src/components/ui/command/CommandGroup.vue +0 -22
- package/src/components/ui/command/CommandInput.vue +0 -21
- package/src/components/ui/command/CommandItem.vue +0 -22
- package/src/components/ui/command/CommandList.vue +0 -17
- package/src/components/ui/command/CommandSeparator.vue +0 -5
- package/src/components/ui/command/index.ts +0 -7
- package/src/components/ui/context-menu/ContextMenuContent.vue +0 -24
- package/src/components/ui/context-menu/ContextMenuItem.vue +0 -16
- package/src/components/ui/context-menu/ContextMenuLabel.vue +0 -9
- package/src/components/ui/context-menu/ContextMenuSeparator.vue +0 -9
- package/src/components/ui/context-menu/ContextMenuSubContent.vue +0 -14
- package/src/components/ui/context-menu/index.ts +0 -9
- package/src/components/ui/dialog/Dialog.vue +0 -14
- package/src/components/ui/dialog/DialogClose.vue +0 -12
- package/src/components/ui/dialog/DialogContent.vue +0 -48
- package/src/components/ui/dialog/DialogDescription.vue +0 -23
- package/src/components/ui/dialog/DialogFooter.vue +0 -12
- package/src/components/ui/dialog/DialogHeader.vue +0 -12
- package/src/components/ui/dialog/DialogScrollContent.vue +0 -47
- package/src/components/ui/dialog/DialogTitle.vue +0 -23
- package/src/components/ui/dialog/DialogTrigger.vue +0 -12
- package/src/components/ui/dialog/index.ts +0 -9
- package/src/components/ui/dropdown-menu/DropdownMenu.vue +0 -13
- package/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +0 -28
- package/src/components/ui/dropdown-menu/DropdownMenuContent.vue +0 -33
- package/src/components/ui/dropdown-menu/DropdownMenuGroup.vue +0 -11
- package/src/components/ui/dropdown-menu/DropdownMenuItem.vue +0 -27
- package/src/components/ui/dropdown-menu/DropdownMenuLabel.vue +0 -23
- package/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +0 -13
- package/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +0 -27
- package/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue +0 -13
- package/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue +0 -12
- package/src/components/ui/dropdown-menu/DropdownMenuSub.vue +0 -13
- package/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue +0 -27
- package/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +0 -23
- package/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue +0 -11
- package/src/components/ui/dropdown-menu/index.ts +0 -14
- package/src/components/ui/form/FormControl.vue +0 -3
- package/src/components/ui/form/FormDescription.vue +0 -6
- package/src/components/ui/form/FormItem.vue +0 -6
- package/src/components/ui/form/FormLabel.vue +0 -10
- package/src/components/ui/form/FormMessage.vue +0 -10
- package/src/components/ui/form/index.ts +0 -9
- package/src/components/ui/hover-card/HoverCard.vue +0 -13
- package/src/components/ui/hover-card/HoverCardContent.vue +0 -26
- package/src/components/ui/hover-card/HoverCardTrigger.vue +0 -11
- package/src/components/ui/hover-card/index.ts +0 -3
- package/src/components/ui/input/Input.vue +0 -23
- package/src/components/ui/input/index.ts +0 -1
- package/src/components/ui/label/Label.vue +0 -18
- package/src/components/ui/label/index.ts +0 -1
- package/src/components/ui/lib/utils.ts +0 -2
- package/src/components/ui/menubar/MenubarContent.vue +0 -15
- package/src/components/ui/menubar/MenubarItem.vue +0 -13
- package/src/components/ui/menubar/MenubarTrigger.vue +0 -13
- package/src/components/ui/menubar/index.ts +0 -5
- package/src/components/ui/navigation-menu/NavigationMenuContent.vue +0 -14
- package/src/components/ui/navigation-menu/NavigationMenuTrigger.vue +0 -15
- package/src/components/ui/navigation-menu/index.ts +0 -4
- package/src/components/ui/pagination/PaginationContent.vue +0 -13
- package/src/components/ui/pagination/PaginationEllipsis.vue +0 -12
- package/src/components/ui/pagination/PaginationNext.vue +0 -14
- package/src/components/ui/pagination/PaginationPrev.vue +0 -14
- package/src/components/ui/pagination/index.ts +0 -6
- package/src/components/ui/popover/Popover.vue +0 -13
- package/src/components/ui/popover/PopoverContent.vue +0 -27
- package/src/components/ui/popover/PopoverTrigger.vue +0 -11
- package/src/components/ui/popover/index.ts +0 -3
- package/src/components/ui/progress/Progress.vue +0 -21
- package/src/components/ui/progress/index.ts +0 -1
- package/src/components/ui/radio-group/RadioGroup.vue +0 -16
- package/src/components/ui/radio-group/RadioGroupItem.vue +0 -24
- package/src/components/ui/radio-group/index.ts +0 -2
- package/src/components/ui/scroll-area/ScrollArea.vue +0 -13
- package/src/components/ui/scroll-area/index.ts +0 -1
- package/src/components/ui/select/Select.vue +0 -13
- package/src/components/ui/select/SelectContent.vue +0 -40
- package/src/components/ui/select/SelectGroup.vue +0 -15
- package/src/components/ui/select/SelectItem.vue +0 -30
- package/src/components/ui/select/SelectLabel.vue +0 -15
- package/src/components/ui/select/SelectSeparator.vue +0 -13
- package/src/components/ui/select/SelectTrigger.vue +0 -23
- package/src/components/ui/select/SelectValue.vue +0 -11
- package/src/components/ui/select/index.ts +0 -8
- package/src/components/ui/separator/Separator.vue +0 -16
- package/src/components/ui/separator/index.ts +0 -1
- package/src/components/ui/sheet/Sheet.vue +0 -13
- package/src/components/ui/sheet/SheetClose.vue +0 -11
- package/src/components/ui/sheet/SheetContent.vue +0 -65
- package/src/components/ui/sheet/SheetDescription.vue +0 -15
- package/src/components/ui/sheet/SheetFooter.vue +0 -12
- package/src/components/ui/sheet/SheetHeader.vue +0 -12
- package/src/components/ui/sheet/SheetTitle.vue +0 -15
- package/src/components/ui/sheet/SheetTrigger.vue +0 -11
- package/src/components/ui/sheet/index.ts +0 -8
- package/src/components/ui/skeleton/Skeleton.vue +0 -9
- package/src/components/ui/skeleton/index.ts +0 -1
- package/src/components/ui/slider/Slider.vue +0 -26
- package/src/components/ui/slider/index.ts +0 -1
- package/src/components/ui/switch/Switch.vue +0 -24
- package/src/components/ui/switch/index.ts +0 -1
- package/src/components/ui/table/Table.vue +0 -13
- package/src/components/ui/table/TableBody.vue +0 -6
- package/src/components/ui/table/TableCaption.vue +0 -6
- package/src/components/ui/table/TableCell.vue +0 -6
- package/src/components/ui/table/TableFooter.vue +0 -6
- package/src/components/ui/table/TableHead.vue +0 -6
- package/src/components/ui/table/TableHeader.vue +0 -6
- package/src/components/ui/table/TableRow.vue +0 -6
- package/src/components/ui/table/index.ts +0 -8
- package/src/components/ui/tabs/Tabs.vue +0 -13
- package/src/components/ui/tabs/TabsContent.vue +0 -21
- package/src/components/ui/tabs/TabsList.vue +0 -21
- package/src/components/ui/tabs/TabsTrigger.vue +0 -21
- package/src/components/ui/tabs/index.ts +0 -4
- package/src/components/ui/textarea/Textarea.vue +0 -29
- package/src/components/ui/textarea/index.ts +0 -1
- package/src/components/ui/toggle/Toggle.vue +0 -40
- package/src/components/ui/toggle/index.ts +0 -1
- package/src/components/ui/toggle-group/ToggleGroup.vue +0 -16
- package/src/components/ui/toggle-group/ToggleGroupItem.vue +0 -21
- package/src/components/ui/toggle-group/index.ts +0 -2
- package/src/components/ui/tooltip/Tooltip.vue +0 -13
- package/src/components/ui/tooltip/TooltipContent.vue +0 -27
- package/src/components/ui/tooltip/TooltipProvider.vue +0 -12
- package/src/components/ui/tooltip/TooltipTrigger.vue +0 -11
- package/src/components/ui/tooltip/index.ts +0 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reinvented/design",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -22,36 +22,70 @@
|
|
|
22
22
|
"DESIGN_GUIDE.md"
|
|
23
23
|
],
|
|
24
24
|
"scripts": {
|
|
25
|
-
"build": "
|
|
25
|
+
"build": "tsc --noEmit",
|
|
26
26
|
"lint": "eslint src"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
|
-
"
|
|
29
|
+
"react": "^18.3.1",
|
|
30
|
+
"react-dom": "^18.3.1"
|
|
30
31
|
},
|
|
31
32
|
"dependencies": {
|
|
33
|
+
"@hookform/resolvers": "^5.2.2",
|
|
34
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
35
|
+
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
36
|
+
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
|
37
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
38
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
39
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
40
|
+
"@radix-ui/react-context-menu": "^2.2.16",
|
|
41
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
42
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
43
|
+
"@radix-ui/react-hover-card": "^1.1.15",
|
|
44
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
45
|
+
"@radix-ui/react-menubar": "^1.1.16",
|
|
46
|
+
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
47
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
48
|
+
"@radix-ui/react-progress": "^1.1.8",
|
|
49
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
50
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
51
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
52
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
53
|
+
"@radix-ui/react-slider": "^1.3.6",
|
|
54
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
55
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
56
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
57
|
+
"@radix-ui/react-toast": "^1.2.15",
|
|
58
|
+
"@radix-ui/react-toggle": "^1.1.10",
|
|
59
|
+
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
60
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
61
|
+
"@unovis/ts": "^1.6.4",
|
|
32
62
|
"class-variance-authority": "^0.7.0",
|
|
33
63
|
"clsx": "^2.1.0",
|
|
64
|
+
"cmdk": "^1.1.1",
|
|
65
|
+
"date-fns": "^4.1.0",
|
|
66
|
+
"embla-carousel-react": "^8.6.0",
|
|
67
|
+
"input-otp": "^1.4.2",
|
|
68
|
+
"lucide-react": "^0.460.0",
|
|
69
|
+
"next-themes": "^0.4.6",
|
|
70
|
+
"react-day-picker": "^9.14.0",
|
|
71
|
+
"react-hook-form": "^7.72.0",
|
|
72
|
+
"react-resizable-panels": "^4.8.0",
|
|
73
|
+
"recharts": "2.15.4",
|
|
74
|
+
"sonner": "^2.0.7",
|
|
34
75
|
"tailwind-merge": "^2.6.0",
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"embla-carousel-vue": "^8.5.0",
|
|
39
|
-
"vaul-vue": "^0.2.0",
|
|
40
|
-
"vee-validate": "^4.14.0",
|
|
41
|
-
"@vee-validate/zod": "^4.14.0",
|
|
42
|
-
"zod": "^3.23.0",
|
|
43
|
-
"vue-sonner": "^1.2.0",
|
|
44
|
-
"v-calendar": "^3.1.0",
|
|
45
|
-
"@tanstack/vue-table": "^8.21.0",
|
|
46
|
-
"eslint-plugin-vue": "^9.28.0",
|
|
47
|
-
"vue-eslint-parser": "^9.4.0"
|
|
76
|
+
"tailwindcss-animate": "^1.0.7",
|
|
77
|
+
"vaul": "^1.1.2",
|
|
78
|
+
"zod": "^3.23.0"
|
|
48
79
|
},
|
|
49
80
|
"devDependencies": {
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"tailwindcss": "^3.4.0",
|
|
81
|
+
"@types/google.maps": "^3.58.1",
|
|
82
|
+
"@types/react": "^18.3.12",
|
|
83
|
+
"@types/react-dom": "^18.3.1",
|
|
54
84
|
"autoprefixer": "^10.4.0",
|
|
55
|
-
"postcss": "^8.4.0"
|
|
85
|
+
"postcss": "^8.4.0",
|
|
86
|
+
"react": "^18.3.1",
|
|
87
|
+
"react-dom": "^18.3.1",
|
|
88
|
+
"tailwindcss": "^3.4.0",
|
|
89
|
+
"typescript": "^5.6.0"
|
|
56
90
|
}
|
|
57
91
|
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle, CardFooter } from '@/components/ui/card'
|
|
4
|
+
|
|
5
|
+
interface AuthCardProps {
|
|
6
|
+
title: string
|
|
7
|
+
description?: string
|
|
8
|
+
footerText?: string
|
|
9
|
+
footerLinkText?: string
|
|
10
|
+
footerLinkHref?: string
|
|
11
|
+
className?: string
|
|
12
|
+
children?: React.ReactNode
|
|
13
|
+
footer?: React.ReactNode
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function AuthCard({
|
|
17
|
+
title,
|
|
18
|
+
description,
|
|
19
|
+
footerText,
|
|
20
|
+
footerLinkText,
|
|
21
|
+
footerLinkHref,
|
|
22
|
+
className,
|
|
23
|
+
children,
|
|
24
|
+
footer,
|
|
25
|
+
}: AuthCardProps) {
|
|
26
|
+
const showFooter = footerText || footer
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Card className={cn('w-full mx-auto shadow-sm', className)}>
|
|
30
|
+
<CardHeader className="space-y-1 text-center pb-6">
|
|
31
|
+
<CardTitle className="text-2xl font-semibold tracking-tight">{title}</CardTitle>
|
|
32
|
+
{description && (
|
|
33
|
+
<CardDescription className="text-[13px]">
|
|
34
|
+
{description}
|
|
35
|
+
</CardDescription>
|
|
36
|
+
)}
|
|
37
|
+
</CardHeader>
|
|
38
|
+
<CardContent className="grid gap-6">
|
|
39
|
+
{children}
|
|
40
|
+
</CardContent>
|
|
41
|
+
{showFooter && (
|
|
42
|
+
<CardFooter className="flex flex-wrap items-center justify-center gap-1 text-sm text-muted-foreground pt-2">
|
|
43
|
+
{footer ? (
|
|
44
|
+
footer
|
|
45
|
+
) : (
|
|
46
|
+
<>
|
|
47
|
+
{footerText}
|
|
48
|
+
{footerLinkText && footerLinkHref && (
|
|
49
|
+
<a
|
|
50
|
+
href={footerLinkHref}
|
|
51
|
+
className="font-medium underline underline-offset-4 hover:text-primary transition-colors"
|
|
52
|
+
>
|
|
53
|
+
{footerLinkText}
|
|
54
|
+
</a>
|
|
55
|
+
)}
|
|
56
|
+
</>
|
|
57
|
+
)}
|
|
58
|
+
</CardFooter>
|
|
59
|
+
)}
|
|
60
|
+
</Card>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AuthCard'
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
import { Button } from '@/components/ui/button'
|
|
4
|
+
import { Github } from 'lucide-react'
|
|
5
|
+
|
|
6
|
+
interface SocialLoginGroupProps {
|
|
7
|
+
providers?: ('github' | 'google')[]
|
|
8
|
+
layout?: 'row' | 'column'
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function SocialLoginGroup({
|
|
13
|
+
providers,
|
|
14
|
+
layout,
|
|
15
|
+
className,
|
|
16
|
+
}: SocialLoginGroupProps) {
|
|
17
|
+
const activeProviders = providers || ['github', 'google']
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<div className={cn('space-y-4', className)}>
|
|
21
|
+
<div
|
|
22
|
+
className={cn(
|
|
23
|
+
'gap-3',
|
|
24
|
+
layout === 'column' ? 'flex flex-col' : 'grid grid-cols-2'
|
|
25
|
+
)}
|
|
26
|
+
>
|
|
27
|
+
{activeProviders.includes('github') && (
|
|
28
|
+
<Button variant="outline" className="w-full bg-background">
|
|
29
|
+
<Github className="mr-2 h-4 w-4" />
|
|
30
|
+
Github
|
|
31
|
+
</Button>
|
|
32
|
+
)}
|
|
33
|
+
{activeProviders.includes('google') && (
|
|
34
|
+
<Button variant="outline" className="w-full bg-background">
|
|
35
|
+
<svg
|
|
36
|
+
className="mr-2 h-4 w-4"
|
|
37
|
+
viewBox="0 0 24 24"
|
|
38
|
+
fill="none"
|
|
39
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
40
|
+
>
|
|
41
|
+
<path
|
|
42
|
+
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
|
43
|
+
fill="#4285F4"
|
|
44
|
+
/>
|
|
45
|
+
<path
|
|
46
|
+
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
|
47
|
+
fill="#34A853"
|
|
48
|
+
/>
|
|
49
|
+
<path
|
|
50
|
+
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
|
51
|
+
fill="#FBBC05"
|
|
52
|
+
/>
|
|
53
|
+
<path
|
|
54
|
+
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
|
55
|
+
fill="#EA4335"
|
|
56
|
+
/>
|
|
57
|
+
</svg>
|
|
58
|
+
Google
|
|
59
|
+
</Button>
|
|
60
|
+
)}
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<div className="relative">
|
|
64
|
+
<div className="absolute inset-0 flex items-center">
|
|
65
|
+
<span className="w-full border-t border-border"></span>
|
|
66
|
+
</div>
|
|
67
|
+
<div className="relative flex justify-center text-xs uppercase">
|
|
68
|
+
<span className="bg-card px-2 text-muted-foreground">
|
|
69
|
+
Or continue with
|
|
70
|
+
</span>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SocialLoginGroup'
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
import { Label } from '@/components/ui/label'
|
|
4
|
+
import { Button } from '@/components/ui/button'
|
|
5
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from '@/components/ui/input-otp'
|
|
6
|
+
|
|
7
|
+
interface TwoFactorFormProps {
|
|
8
|
+
email?: string
|
|
9
|
+
className?: string
|
|
10
|
+
onComplete?: (value: string) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function TwoFactorForm({ email, className, onComplete }: TwoFactorFormProps) {
|
|
14
|
+
const [value, setValue] = useState("")
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className={cn('space-y-6', className)}>
|
|
18
|
+
<div className="space-y-2 text-center text-sm">
|
|
19
|
+
{email && (
|
|
20
|
+
<p className="text-muted-foreground">
|
|
21
|
+
Please enter the 6-digit code sent to <span className="font-medium text-foreground">{email}</span>.
|
|
22
|
+
</p>
|
|
23
|
+
)}
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div className="flex justify-center">
|
|
27
|
+
<InputOTP
|
|
28
|
+
maxLength={6}
|
|
29
|
+
value={value}
|
|
30
|
+
onChange={(val) => setValue(val)}
|
|
31
|
+
onComplete={(val) => onComplete?.(val)}
|
|
32
|
+
>
|
|
33
|
+
<InputOTPGroup>
|
|
34
|
+
<InputOTPSlot index={0} />
|
|
35
|
+
<InputOTPSlot index={1} />
|
|
36
|
+
<InputOTPSlot index={2} />
|
|
37
|
+
</InputOTPGroup>
|
|
38
|
+
<InputOTPSeparator />
|
|
39
|
+
<InputOTPGroup>
|
|
40
|
+
<InputOTPSlot index={3} />
|
|
41
|
+
<InputOTPSlot index={4} />
|
|
42
|
+
<InputOTPSlot index={5} />
|
|
43
|
+
</InputOTPGroup>
|
|
44
|
+
</InputOTP>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<Button className="w-full" disabled={value.length !== 6}>
|
|
48
|
+
Verify Application
|
|
49
|
+
</Button>
|
|
50
|
+
|
|
51
|
+
<div className="text-center text-sm text-muted-foreground">
|
|
52
|
+
Didn't receive a code?{' '}
|
|
53
|
+
<Button variant="link" className="p-0 h-auto font-medium text-primary px-1 underline-offset-4">
|
|
54
|
+
Resend
|
|
55
|
+
</Button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TwoFactorForm'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
export function ActivityItem({
|
|
5
|
+
className,
|
|
6
|
+
children,
|
|
7
|
+
}: {
|
|
8
|
+
className?: string
|
|
9
|
+
children?: React.ReactNode
|
|
10
|
+
}) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={cn('flex gap-4 relative', className)}>
|
|
13
|
+
<div className="absolute left-4 top-8 bottom-[-16px] w-px bg-border -z-10 hidden last:!hidden sm:block" />
|
|
14
|
+
{children}
|
|
15
|
+
</div>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { HTMLAttributes } from 'react'
|
|
3
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
4
|
+
import { cn } from '@/lib/utils'
|
|
5
|
+
|
|
6
|
+
interface ActivityItemAvatarProps {
|
|
7
|
+
src?: string
|
|
8
|
+
fallback?: string
|
|
9
|
+
className?: HTMLAttributes<HTMLElement>['className']
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function ActivityItemAvatar({ src, fallback, className }: ActivityItemAvatarProps) {
|
|
13
|
+
return (
|
|
14
|
+
<div className="relative z-10 bg-background pb-2">
|
|
15
|
+
<Avatar className={cn('h-8 w-8 ring-2 ring-background', className)}>
|
|
16
|
+
{src && <AvatarImage src={src} />}
|
|
17
|
+
{fallback && <AvatarFallback>{fallback}</AvatarFallback>}
|
|
18
|
+
</Avatar>
|
|
19
|
+
</div>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
export function ActivityItemContent({
|
|
5
|
+
className,
|
|
6
|
+
children,
|
|
7
|
+
}: {
|
|
8
|
+
className?: string
|
|
9
|
+
children?: React.ReactNode
|
|
10
|
+
}) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={cn('flex flex-col gap-1 pb-4 pt-1', className)}>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
interface ChatBubbleProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
variant?: 'sent' | 'received'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function ChatBubble({ variant, className, children, ...props }: ChatBubbleProps) {
|
|
9
|
+
return (
|
|
10
|
+
<div
|
|
11
|
+
className={cn(
|
|
12
|
+
'flex w-full gap-2',
|
|
13
|
+
variant === 'sent' ? 'flex-row-reverse' : 'flex-row',
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
{children}
|
|
19
|
+
</div>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { HTMLAttributes } from 'react'
|
|
3
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
4
|
+
import { cn } from '@/lib/utils'
|
|
5
|
+
|
|
6
|
+
interface ChatBubbleAvatarProps {
|
|
7
|
+
src?: string
|
|
8
|
+
fallback?: string
|
|
9
|
+
className?: HTMLAttributes<HTMLElement>['className']
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function ChatBubbleAvatar({ src, fallback, className }: ChatBubbleAvatarProps) {
|
|
13
|
+
return (
|
|
14
|
+
<Avatar className={cn('h-8 w-8 shrink-0', className)}>
|
|
15
|
+
{src && <AvatarImage src={src} />}
|
|
16
|
+
{fallback && <AvatarFallback>{fallback}</AvatarFallback>}
|
|
17
|
+
</Avatar>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
interface ChatBubbleMessageProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
variant?: 'sent' | 'received'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function ChatBubbleMessage({
|
|
9
|
+
variant,
|
|
10
|
+
className,
|
|
11
|
+
children,
|
|
12
|
+
...props
|
|
13
|
+
}: ChatBubbleMessageProps) {
|
|
14
|
+
return (
|
|
15
|
+
<div
|
|
16
|
+
className={cn(
|
|
17
|
+
'flex flex-col gap-1 max-w-[80%]',
|
|
18
|
+
variant === 'sent' ? 'items-end' : 'items-start',
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
<div
|
|
24
|
+
className={cn(
|
|
25
|
+
'rounded-2xl px-4 py-2 text-sm',
|
|
26
|
+
variant === 'sent'
|
|
27
|
+
? 'bg-primary text-primary-foreground rounded-tr-sm'
|
|
28
|
+
: 'bg-muted text-foreground rounded-tl-sm',
|
|
29
|
+
)}
|
|
30
|
+
>
|
|
31
|
+
{children}
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
interface ChatBubbleTimestampProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
timestamp: string
|
|
6
|
+
className?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function ChatBubbleTimestamp({ timestamp, className, ...props }: ChatBubbleTimestampProps) {
|
|
10
|
+
return (
|
|
11
|
+
<span className={cn('text-[10px] text-muted-foreground px-1 mt-1 block', className)} {...props}>
|
|
12
|
+
{timestamp}
|
|
13
|
+
</span>
|
|
14
|
+
)
|
|
15
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { HTMLAttributes } from 'react'
|
|
3
|
+
import { cn } from '@/lib/utils'
|
|
4
|
+
import { Badge } from '@/components/ui/badge'
|
|
5
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
6
|
+
|
|
7
|
+
interface ArticleHeaderProps {
|
|
8
|
+
title: string
|
|
9
|
+
description?: string
|
|
10
|
+
authorName: string
|
|
11
|
+
authorAvatar?: string
|
|
12
|
+
authorRole?: string
|
|
13
|
+
date: string
|
|
14
|
+
readTime?: string
|
|
15
|
+
tags?: string[]
|
|
16
|
+
className?: HTMLAttributes<HTMLElement>['className']
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function ArticleHeader({
|
|
20
|
+
title,
|
|
21
|
+
description,
|
|
22
|
+
authorName,
|
|
23
|
+
authorAvatar,
|
|
24
|
+
authorRole,
|
|
25
|
+
date,
|
|
26
|
+
readTime,
|
|
27
|
+
tags,
|
|
28
|
+
className,
|
|
29
|
+
}: ArticleHeaderProps) {
|
|
30
|
+
return (
|
|
31
|
+
<header className={cn('flex flex-col gap-6 max-w-3xl mx-auto py-8', className)}>
|
|
32
|
+
{tags?.length ? (
|
|
33
|
+
<div className="flex flex-wrap gap-2">
|
|
34
|
+
{tags.map((tag) => (
|
|
35
|
+
<Badge key={tag} variant="secondary">
|
|
36
|
+
{tag}
|
|
37
|
+
</Badge>
|
|
38
|
+
))}
|
|
39
|
+
</div>
|
|
40
|
+
) : null}
|
|
41
|
+
|
|
42
|
+
<div className="space-y-4">
|
|
43
|
+
<h1 className="text-4xl md:text-5xl font-extrabold tracking-tight lg:text-5xl leading-tight text-foreground">
|
|
44
|
+
{title}
|
|
45
|
+
</h1>
|
|
46
|
+
{description && (
|
|
47
|
+
<p className="text-xl text-muted-foreground leading-relaxed">
|
|
48
|
+
{description}
|
|
49
|
+
</p>
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div className="flex items-center gap-4 mt-4 border-t pt-6">
|
|
54
|
+
<Avatar className="h-12 w-12">
|
|
55
|
+
{authorAvatar && <AvatarImage src={authorAvatar} />}
|
|
56
|
+
<AvatarFallback>{authorName.substring(0, 2).toUpperCase()}</AvatarFallback>
|
|
57
|
+
</Avatar>
|
|
58
|
+
<div className="flex flex-col">
|
|
59
|
+
<span className="font-semibold text-foreground leading-none mb-1.5">{authorName}</span>
|
|
60
|
+
<div className="flex items-center text-sm text-muted-foreground gap-2">
|
|
61
|
+
<span>{date}</span>
|
|
62
|
+
{readTime && (
|
|
63
|
+
<>
|
|
64
|
+
<span>·</span>
|
|
65
|
+
<span>{readTime}</span>
|
|
66
|
+
</>
|
|
67
|
+
)}
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</header>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ArticleHeader'
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
3
|
+
import { Card, CardContent } from '@/components/ui/card'
|
|
4
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
5
|
+
import { Button } from '@/components/ui/button'
|
|
6
|
+
import { cn } from '@/lib/utils'
|
|
7
|
+
|
|
8
|
+
interface AuthorCardProps {
|
|
9
|
+
name: string
|
|
10
|
+
role?: string
|
|
11
|
+
bio?: string
|
|
12
|
+
avatar?: string
|
|
13
|
+
className?: HTMLAttributes<HTMLElement>['className']
|
|
14
|
+
action?: ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function AuthorCard({ name, role, bio, avatar, className, action }: AuthorCardProps) {
|
|
18
|
+
return (
|
|
19
|
+
<Card className={cn('overflow-hidden max-w-3xl mx-auto mt-12 mb-8 bg-muted/30 border-none shadow-none', className)}>
|
|
20
|
+
<CardContent className="p-6 sm:p-8 flex flex-col sm:flex-row gap-6 items-start sm:items-center">
|
|
21
|
+
<Avatar className="h-20 w-20 border-2 border-background shadow-sm shrink-0">
|
|
22
|
+
{avatar && <AvatarImage src={avatar} />}
|
|
23
|
+
<AvatarFallback className="text-xl">{name.substring(0, 2).toUpperCase()}</AvatarFallback>
|
|
24
|
+
</Avatar>
|
|
25
|
+
|
|
26
|
+
<div className="flex-1 space-y-2">
|
|
27
|
+
<div>
|
|
28
|
+
<h4 className="text-xl font-bold">{name}</h4>
|
|
29
|
+
{role && <p className="text-sm font-medium text-primary mt-0.5">{role}</p>}
|
|
30
|
+
</div>
|
|
31
|
+
{bio && (
|
|
32
|
+
<p className="text-sm text-muted-foreground leading-relaxed max-w-xl">
|
|
33
|
+
{bio}
|
|
34
|
+
</p>
|
|
35
|
+
)}
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<div className="shrink-0 w-full sm:w-auto">
|
|
39
|
+
{action ?? (
|
|
40
|
+
<Button variant="outline" className="w-full sm:w-auto">Follow</Button>
|
|
41
|
+
)}
|
|
42
|
+
</div>
|
|
43
|
+
</CardContent>
|
|
44
|
+
</Card>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AuthorCard'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from 'react'
|
|
3
|
+
import { cn } from '@/lib/utils'
|
|
4
|
+
|
|
5
|
+
interface RichTextContentProps {
|
|
6
|
+
className?: HTMLAttributes<HTMLElement>['className']
|
|
7
|
+
children?: ReactNode
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function RichTextContent({ className, children }: RichTextContentProps) {
|
|
11
|
+
return (
|
|
12
|
+
<div
|
|
13
|
+
className={cn(
|
|
14
|
+
'prose prose-slate dark:prose-invert max-w-3xl mx-auto',
|
|
15
|
+
'prose-headings:font-bold prose-headings:tracking-tight prose-headings:text-foreground',
|
|
16
|
+
'prose-p:text-muted-foreground prose-p:leading-8',
|
|
17
|
+
'prose-a:text-primary prose-a:underline-offset-4 hover:prose-a:text-primary/80',
|
|
18
|
+
'prose-img:rounded-xl prose-img:border prose-img:shadow-sm',
|
|
19
|
+
'prose-blockquote:border-l-primary prose-blockquote:bg-muted/50 prose-blockquote:px-5 prose-blockquote:py-2 prose-blockquote:rounded-r-lg prose-blockquote:not-italic prose-blockquote:text-foreground font-normal',
|
|
20
|
+
'prose-strong:text-foreground prose-code:text-foreground prose-code:bg-muted prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded-md prose-code:before:content-none prose-code:after:content-none',
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
>
|
|
24
|
+
{children}
|
|
25
|
+
</div>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './RichTextContent'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
export function KanbanBoard({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
5
|
+
return (
|
|
6
|
+
<div className={cn('flex gap-6 overflow-x-auto pb-4 pt-2 -mx-4 px-4 sm:mx-0 sm:px-0', className)} {...props}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
)
|
|
10
|
+
}
|