@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
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
3
|
+
import { Badge } from '@/components/ui/badge'
|
|
4
|
+
import { cn } from '@/lib/utils'
|
|
5
|
+
|
|
6
|
+
interface ProfileHeaderProps {
|
|
7
|
+
name: string
|
|
8
|
+
handle?: string
|
|
9
|
+
bio?: string
|
|
10
|
+
avatar?: string
|
|
11
|
+
banner?: string
|
|
12
|
+
verified?: boolean
|
|
13
|
+
className?: string
|
|
14
|
+
actions?: React.ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ProfileHeader({
|
|
18
|
+
name,
|
|
19
|
+
handle,
|
|
20
|
+
bio,
|
|
21
|
+
avatar,
|
|
22
|
+
banner,
|
|
23
|
+
verified,
|
|
24
|
+
className,
|
|
25
|
+
actions,
|
|
26
|
+
}: ProfileHeaderProps) {
|
|
27
|
+
return (
|
|
28
|
+
<div className={cn('relative flex flex-col', className)}>
|
|
29
|
+
{/* Banner */}
|
|
30
|
+
<div className="h-48 md:h-64 w-full bg-muted overflow-hidden relative rounded-xl border">
|
|
31
|
+
{banner ? (
|
|
32
|
+
<img src={banner} className="w-full h-full object-cover" />
|
|
33
|
+
) : (
|
|
34
|
+
<div className="w-full h-full bg-gradient-to-tr from-primary/10 to-primary/5"></div>
|
|
35
|
+
)}
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
{/* Profile Info */}
|
|
39
|
+
<div className="px-6 md:px-8 relative flex flex-col md:flex-row md:items-end md:justify-between -mt-16 md:-mt-20 z-10 gap-4 mb-6">
|
|
40
|
+
<div className="flex flex-col md:flex-row md:items-end gap-4 md:gap-6">
|
|
41
|
+
<Avatar className="h-32 w-32 border-4 border-background shadow-md">
|
|
42
|
+
{avatar && <AvatarImage src={avatar} />}
|
|
43
|
+
<AvatarFallback className="text-4xl">
|
|
44
|
+
{name.substring(0, 2).toUpperCase()}
|
|
45
|
+
</AvatarFallback>
|
|
46
|
+
</Avatar>
|
|
47
|
+
|
|
48
|
+
<div className="flex flex-col pb-2">
|
|
49
|
+
<div className="flex items-center gap-2">
|
|
50
|
+
<h1 className="text-3xl font-bold">{name}</h1>
|
|
51
|
+
{verified && (
|
|
52
|
+
<Badge
|
|
53
|
+
variant="secondary"
|
|
54
|
+
className="h-6 px-1.5 bg-blue-500/10 text-blue-500 hover:bg-blue-500/20 border-transparent"
|
|
55
|
+
>
|
|
56
|
+
<svg
|
|
57
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
58
|
+
width="14"
|
|
59
|
+
height="14"
|
|
60
|
+
viewBox="0 0 24 24"
|
|
61
|
+
fill="currentColor"
|
|
62
|
+
stroke="none"
|
|
63
|
+
>
|
|
64
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
|
65
|
+
</svg>
|
|
66
|
+
</Badge>
|
|
67
|
+
)}
|
|
68
|
+
</div>
|
|
69
|
+
{handle && (
|
|
70
|
+
<p className="text-muted-foreground text-lg">{handle}</p>
|
|
71
|
+
)}
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div className="flex items-center gap-3 pb-2 w-full md:w-auto mt-2 md:mt-0 justify-start md:justify-end">
|
|
76
|
+
{actions}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
{/* Bio */}
|
|
81
|
+
{bio && (
|
|
82
|
+
<div className="px-6 md:px-8 max-w-3xl text-foreground text-base leading-relaxed">
|
|
83
|
+
{bio}
|
|
84
|
+
</div>
|
|
85
|
+
)}
|
|
86
|
+
</div>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ProfileHeader'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
interface ProfileStatsProps {
|
|
5
|
+
stats: { label: string; value: string | number }[]
|
|
6
|
+
className?: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function ProfileStats({ stats, className }: ProfileStatsProps) {
|
|
10
|
+
return (
|
|
11
|
+
<div className={cn('flex flex-wrap items-center gap-6 sm:gap-10 py-4', className)}>
|
|
12
|
+
{stats.map((stat) => (
|
|
13
|
+
<div key={stat.label} className="flex flex-col">
|
|
14
|
+
<span className="text-2xl font-bold tracking-tight text-foreground">{stat.value}</span>
|
|
15
|
+
<span className="text-sm text-muted-foreground font-medium">{stat.label}</span>
|
|
16
|
+
</div>
|
|
17
|
+
))}
|
|
18
|
+
</div>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ProfileStats'
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
import { Check } from 'lucide-react'
|
|
4
|
+
|
|
5
|
+
interface BookingSlotProps {
|
|
6
|
+
time: string
|
|
7
|
+
available?: boolean
|
|
8
|
+
selected?: boolean
|
|
9
|
+
className?: string
|
|
10
|
+
onSelect?: () => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function BookingSlot({
|
|
14
|
+
time,
|
|
15
|
+
available,
|
|
16
|
+
selected,
|
|
17
|
+
className,
|
|
18
|
+
onSelect,
|
|
19
|
+
}: BookingSlotProps) {
|
|
20
|
+
return (
|
|
21
|
+
<button
|
|
22
|
+
disabled={!available}
|
|
23
|
+
onClick={onSelect}
|
|
24
|
+
className={cn(
|
|
25
|
+
'relative flex items-center justify-center w-full py-3 px-4 rounded-md border text-sm font-semibold transition-all duration-200 outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2',
|
|
26
|
+
available && !selected
|
|
27
|
+
? 'bg-background hover:border-primary/50 hover:bg-primary/5 hover:text-primary cursor-pointer'
|
|
28
|
+
: '',
|
|
29
|
+
selected
|
|
30
|
+
? 'bg-primary border-primary text-primary-foreground shadow-md ring-2 ring-primary ring-offset-2'
|
|
31
|
+
: '',
|
|
32
|
+
!available
|
|
33
|
+
? 'bg-muted/50 border-muted text-muted-foreground cursor-not-allowed opacity-60'
|
|
34
|
+
: '',
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
<span className={selected ? 'pr-4' : ''}>{time}</span>
|
|
39
|
+
{selected && (
|
|
40
|
+
<Check className="h-4 w-4 absolute right-3 shrink-0 animate-in zoom-in-50" />
|
|
41
|
+
)}
|
|
42
|
+
</button>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BookingSlot'
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Card, CardContent } from '@/components/ui/card'
|
|
3
|
+
import { Badge } from '@/components/ui/badge'
|
|
4
|
+
import { Calendar, Clock, MapPin, Video } from 'lucide-react'
|
|
5
|
+
import { cn } from '@/lib/utils'
|
|
6
|
+
|
|
7
|
+
interface EventCardProps {
|
|
8
|
+
title: string
|
|
9
|
+
date: string
|
|
10
|
+
time: string
|
|
11
|
+
location?: string
|
|
12
|
+
isVirtual?: boolean
|
|
13
|
+
attendees?: number
|
|
14
|
+
tag?: string
|
|
15
|
+
tagVariant?: 'default' | 'secondary' | 'destructive' | 'outline'
|
|
16
|
+
className?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function EventCard({
|
|
20
|
+
title,
|
|
21
|
+
date,
|
|
22
|
+
time,
|
|
23
|
+
location,
|
|
24
|
+
isVirtual,
|
|
25
|
+
attendees,
|
|
26
|
+
tag,
|
|
27
|
+
tagVariant,
|
|
28
|
+
className,
|
|
29
|
+
}: EventCardProps) {
|
|
30
|
+
const LocationIcon = isVirtual ? Video : MapPin
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Card
|
|
34
|
+
className={cn(
|
|
35
|
+
'overflow-hidden transition-shadow hover:shadow-md cursor-pointer border-l-4 group',
|
|
36
|
+
className
|
|
37
|
+
)}
|
|
38
|
+
style={{ borderLeftColor: 'hsl(var(--primary))' }}
|
|
39
|
+
>
|
|
40
|
+
<CardContent className="p-5 flex flex-col h-full">
|
|
41
|
+
<div className="flex items-start justify-between gap-4 mb-2">
|
|
42
|
+
<h4 className="font-semibold text-lg leading-tight group-hover:text-primary transition-colors">
|
|
43
|
+
{title}
|
|
44
|
+
</h4>
|
|
45
|
+
{tag && (
|
|
46
|
+
<Badge variant={tagVariant || 'secondary'} className="shrink-0 text-[10px] uppercase font-mono">
|
|
47
|
+
{tag}
|
|
48
|
+
</Badge>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div className="space-y-2 mt-4 text-sm text-muted-foreground">
|
|
53
|
+
<div className="flex items-center gap-2">
|
|
54
|
+
<Calendar className="h-4 w-4 shrink-0 text-foreground/70" />
|
|
55
|
+
<span>{date}</span>
|
|
56
|
+
</div>
|
|
57
|
+
<div className="flex items-center gap-2">
|
|
58
|
+
<Clock className="h-4 w-4 shrink-0 text-foreground/70" />
|
|
59
|
+
<span>{time}</span>
|
|
60
|
+
</div>
|
|
61
|
+
{(location || isVirtual) && (
|
|
62
|
+
<div className="flex items-center gap-2">
|
|
63
|
+
<LocationIcon className="h-4 w-4 shrink-0 text-foreground/70" />
|
|
64
|
+
<span className="truncate">{location || 'Virtual Meeting'}</span>
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{attendees != null && attendees > 0 && (
|
|
70
|
+
<div className="mt-auto pt-4 border-t flex items-center justify-between text-xs text-muted-foreground">
|
|
71
|
+
<div className="flex -space-x-2 overflow-hidden">
|
|
72
|
+
{Array.from({ length: Math.min(attendees, 3) }, (_, i) => (
|
|
73
|
+
<div
|
|
74
|
+
key={i}
|
|
75
|
+
className="inline-block h-6 w-6 rounded-full ring-2 ring-background bg-muted border"
|
|
76
|
+
/>
|
|
77
|
+
))}
|
|
78
|
+
</div>
|
|
79
|
+
<span>{attendees} attendees</span>
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
</CardContent>
|
|
83
|
+
</Card>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './EventCard'
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
import { Badge } from '@/components/ui/badge'
|
|
4
|
+
|
|
5
|
+
interface TimelineRowProps {
|
|
6
|
+
time: string
|
|
7
|
+
title: string
|
|
8
|
+
description?: string
|
|
9
|
+
status?: 'past' | 'current' | 'future'
|
|
10
|
+
tag?: string
|
|
11
|
+
isLast?: boolean
|
|
12
|
+
className?: string
|
|
13
|
+
children?: React.ReactNode
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function TimelineRow({
|
|
17
|
+
time,
|
|
18
|
+
title,
|
|
19
|
+
description,
|
|
20
|
+
status,
|
|
21
|
+
tag,
|
|
22
|
+
isLast,
|
|
23
|
+
className,
|
|
24
|
+
children,
|
|
25
|
+
}: TimelineRowProps) {
|
|
26
|
+
return (
|
|
27
|
+
<div className={cn('flex relative min-h-[6rem]', className)}>
|
|
28
|
+
<div className="w-16 sm:w-24 shrink-0 pt-[3px] text-right pr-4 sm:pr-6 flex flex-col items-end">
|
|
29
|
+
<span
|
|
30
|
+
className={cn(
|
|
31
|
+
'text-xs sm:text-sm font-semibold tracking-tight',
|
|
32
|
+
status === 'future' ? 'text-muted-foreground' : 'text-foreground'
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
{time}
|
|
36
|
+
</span>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div className="relative flex flex-col items-center">
|
|
40
|
+
<div
|
|
41
|
+
className={cn(
|
|
42
|
+
'h-3 w-3 sm:h-3.5 sm:w-3.5 rounded-full z-10 ring-4 ring-background shrink-0 mt-1',
|
|
43
|
+
status === 'past' && 'bg-primary',
|
|
44
|
+
status === 'current' && 'bg-primary ring-primary/20 animate-pulse',
|
|
45
|
+
status === 'future' && 'bg-muted border-2 border-primary/30'
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
{!isLast && (
|
|
49
|
+
<div
|
|
50
|
+
className={cn(
|
|
51
|
+
'w-0.5 h-full absolute top-3 -z-10',
|
|
52
|
+
status === 'past' ? 'bg-primary/50' : 'bg-muted'
|
|
53
|
+
)}
|
|
54
|
+
/>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<div className="flex-1 pb-8 pl-4 sm:pl-6 pt-0">
|
|
59
|
+
<div className="flex flex-col sm:flex-row sm:items-center gap-2 mb-1">
|
|
60
|
+
<h4
|
|
61
|
+
className={cn(
|
|
62
|
+
'text-base font-semibold leading-none',
|
|
63
|
+
status === 'future' ? 'text-muted-foreground' : 'text-foreground'
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
{title}
|
|
67
|
+
</h4>
|
|
68
|
+
{tag && (
|
|
69
|
+
<Badge variant="outline" className="w-fit h-5 px-1.5 text-[10px] uppercase align-middle">
|
|
70
|
+
{tag}
|
|
71
|
+
</Badge>
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
{description && (
|
|
75
|
+
<p className="text-sm text-muted-foreground mt-1.5 leading-relaxed">{description}</p>
|
|
76
|
+
)}
|
|
77
|
+
|
|
78
|
+
{children && <div className="mt-3">{children}</div>}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimelineRow'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Progress } from '@/components/ui/progress'
|
|
3
|
+
import { Card, CardContent } from '@/components/ui/card'
|
|
4
|
+
import { cn } from '@/lib/utils'
|
|
5
|
+
|
|
6
|
+
interface BillingUsageProps {
|
|
7
|
+
title: string
|
|
8
|
+
used: number
|
|
9
|
+
limit: number
|
|
10
|
+
unit: string
|
|
11
|
+
description?: string
|
|
12
|
+
className?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function BillingUsage({ title, used, limit, unit, description, className }: BillingUsageProps) {
|
|
16
|
+
const percentage = Math.min(Math.round((used / limit) * 100), 100)
|
|
17
|
+
const isNearLimit = percentage >= 85
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<Card className={cn('shadow-sm', className)}>
|
|
21
|
+
<CardContent className="p-6">
|
|
22
|
+
<div className="flex justify-between items-start mb-4">
|
|
23
|
+
<div>
|
|
24
|
+
<h4 className="font-semibold text-sm">{title}</h4>
|
|
25
|
+
{description && (
|
|
26
|
+
<p className="text-sm text-muted-foreground mt-1">{description}</p>
|
|
27
|
+
)}
|
|
28
|
+
</div>
|
|
29
|
+
<div className="text-right">
|
|
30
|
+
<span className="text-2xl font-bold tracking-tight">{used.toLocaleString()}</span>
|
|
31
|
+
<span className="text-sm text-muted-foreground ml-1">/ {limit.toLocaleString()}</span>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<Progress
|
|
36
|
+
value={percentage}
|
|
37
|
+
className={cn('h-2 mb-2', isNearLimit && '[&>div]:bg-rose-500')}
|
|
38
|
+
/>
|
|
39
|
+
|
|
40
|
+
<div className="flex justify-between items-center text-xs">
|
|
41
|
+
<span className="text-muted-foreground">{percentage}% used</span>
|
|
42
|
+
<span className={isNearLimit ? 'text-rose-500 font-medium' : 'text-muted-foreground'}>
|
|
43
|
+
{(limit - used).toLocaleString()} {unit} remaining
|
|
44
|
+
</span>
|
|
45
|
+
</div>
|
|
46
|
+
</CardContent>
|
|
47
|
+
</Card>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BillingUsage'
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
import { Card, CardContent, CardFooter } from '@/components/ui/card'
|
|
4
|
+
import { Switch } from '@/components/ui/switch'
|
|
5
|
+
import { Badge } from '@/components/ui/badge'
|
|
6
|
+
import { Button } from '@/components/ui/button'
|
|
7
|
+
|
|
8
|
+
interface IntegrationCardProps {
|
|
9
|
+
name: string
|
|
10
|
+
description: string
|
|
11
|
+
icon?: string
|
|
12
|
+
status?: 'connected' | 'disconnected' | 'error'
|
|
13
|
+
isConfigurable?: boolean
|
|
14
|
+
className?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function IntegrationCard({
|
|
18
|
+
name,
|
|
19
|
+
description,
|
|
20
|
+
icon,
|
|
21
|
+
status,
|
|
22
|
+
isConfigurable,
|
|
23
|
+
className,
|
|
24
|
+
}: IntegrationCardProps) {
|
|
25
|
+
const [active, setActive] = useState(status === 'connected')
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Card className={cn('flex flex-col overflow-hidden', className)}>
|
|
29
|
+
<CardContent className="p-5 flex-1 flex flex-col">
|
|
30
|
+
<div className="flex items-start justify-between gap-4 mb-4">
|
|
31
|
+
<div className="h-10 w-10 flex items-center justify-center rounded-lg border bg-background shrink-0 overflow-hidden">
|
|
32
|
+
{icon ? (
|
|
33
|
+
<img src={icon} className="h-6 w-6 object-contain" />
|
|
34
|
+
) : (
|
|
35
|
+
<div className="h-6 w-6 bg-muted rounded-full" />
|
|
36
|
+
)}
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<Switch checked={active} onCheckedChange={setActive} />
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div className="flex items-center gap-2 mb-1.5 mt-auto">
|
|
43
|
+
<h4 className="font-semibold text-base leading-none">{name}</h4>
|
|
44
|
+
{status === 'error' && (
|
|
45
|
+
<Badge variant="destructive" className="h-5 px-1.5 text-[10px]">
|
|
46
|
+
Error
|
|
47
|
+
</Badge>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
<p className="text-sm text-muted-foreground line-clamp-2 mt-1">{description}</p>
|
|
51
|
+
</CardContent>
|
|
52
|
+
|
|
53
|
+
{isConfigurable && (
|
|
54
|
+
<CardFooter className="px-5 py-3 border-t bg-muted/30 mt-auto">
|
|
55
|
+
<Button variant="ghost" size="sm" className="w-full text-xs" disabled={!active}>
|
|
56
|
+
Configure integration
|
|
57
|
+
</Button>
|
|
58
|
+
</CardFooter>
|
|
59
|
+
)}
|
|
60
|
+
</Card>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './IntegrationCard'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
interface SettingsSectionProps {
|
|
5
|
+
title: string
|
|
6
|
+
description?: string
|
|
7
|
+
className?: string
|
|
8
|
+
children?: React.ReactNode
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function SettingsSection({ title, description, className, children }: SettingsSectionProps) {
|
|
12
|
+
return (
|
|
13
|
+
<div className={cn('grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-10 py-6 border-b last:border-0', className)}>
|
|
14
|
+
<div className="md:col-span-1 flex flex-col gap-1">
|
|
15
|
+
<h3 className="text-base font-semibold leading-none tracking-tight">{title}</h3>
|
|
16
|
+
{description && <p className="text-sm text-muted-foreground mt-1">{description}</p>}
|
|
17
|
+
</div>
|
|
18
|
+
<div className="md:col-span-2 flex flex-col gap-6">
|
|
19
|
+
{children}
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
)
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './SettingsSection'
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
|
3
|
+
import { ChevronDown } from "lucide-react"
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
|
|
7
|
+
const Accordion = AccordionPrimitive.Root
|
|
8
|
+
|
|
9
|
+
const AccordionItem = React.forwardRef<
|
|
10
|
+
React.ElementRef<typeof AccordionPrimitive.Item>,
|
|
11
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
|
12
|
+
>(({ className, ...props }, ref) => (
|
|
13
|
+
<AccordionPrimitive.Item
|
|
14
|
+
ref={ref}
|
|
15
|
+
className={cn("border-b", className)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
))
|
|
19
|
+
AccordionItem.displayName = "AccordionItem"
|
|
20
|
+
|
|
21
|
+
const AccordionTrigger = React.forwardRef<
|
|
22
|
+
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
|
23
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
|
24
|
+
>(({ className, children, ...props }, ref) => (
|
|
25
|
+
<AccordionPrimitive.Header className="flex">
|
|
26
|
+
<AccordionPrimitive.Trigger
|
|
27
|
+
ref={ref}
|
|
28
|
+
className={cn(
|
|
29
|
+
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" />
|
|
36
|
+
</AccordionPrimitive.Trigger>
|
|
37
|
+
</AccordionPrimitive.Header>
|
|
38
|
+
))
|
|
39
|
+
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
|
|
40
|
+
|
|
41
|
+
const AccordionContent = React.forwardRef<
|
|
42
|
+
React.ElementRef<typeof AccordionPrimitive.Content>,
|
|
43
|
+
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
|
44
|
+
>(({ className, children, ...props }, ref) => (
|
|
45
|
+
<AccordionPrimitive.Content
|
|
46
|
+
ref={ref}
|
|
47
|
+
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
<div className={cn("pb-4 pt-0", className)}>{children}</div>
|
|
51
|
+
</AccordionPrimitive.Content>
|
|
52
|
+
))
|
|
53
|
+
|
|
54
|
+
AccordionContent.displayName = AccordionPrimitive.Content.displayName
|
|
55
|
+
|
|
56
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|