@caffeinebounce/ui 0.62.2 → 0.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +1 -1
  2. package/dist/blog.js +8 -6
  3. package/dist/blog.mjs +3 -1
  4. package/dist/charts.d.cts +1 -1
  5. package/dist/charts.d.ts +1 -1
  6. package/dist/{chunk-6DVWMJ3H.mjs → chunk-2EFVMX6V.mjs} +4 -3
  7. package/dist/chunk-33JR5SYE.js +1 -0
  8. package/dist/{chunk-OZZWDIOY.js → chunk-375DECW4.js} +32 -31
  9. package/dist/chunk-3NDB4YPC.js +1 -0
  10. package/dist/{chunk-PZRI43EZ.js → chunk-46JYKBRX.js} +0 -43
  11. package/dist/chunk-5D55OVD5.js +75 -0
  12. package/dist/chunk-5RW4PYZ6.js +1 -0
  13. package/dist/chunk-5THF4YP6.mjs +1 -0
  14. package/dist/{chunk-JORVSG52.js → chunk-663CFAHS.js} +212 -269
  15. package/dist/chunk-6BUBNZPG.mjs +1 -0
  16. package/dist/chunk-6HKJDV43.mjs +48 -0
  17. package/dist/chunk-6NCRGHV3.mjs +64 -0
  18. package/dist/{chunk-OLAAXLXY.mjs → chunk-6QAKQG57.mjs} +5 -4
  19. package/dist/chunk-72JGQ7IJ.mjs +1 -0
  20. package/dist/{chunk-N6AFNFZR.mjs → chunk-7ERVZXIN.mjs} +215 -270
  21. package/dist/chunk-7IKHZKAC.js +1 -0
  22. package/dist/chunk-APFEP5B7.mjs +100 -0
  23. package/dist/chunk-C3OADNSG.js +348 -0
  24. package/dist/{chunk-RVEFPVZF.mjs → chunk-C57MX3BG.mjs} +1 -0
  25. package/dist/{chunk-CC4KUIKC.js → chunk-DH5Z3ETN.js} +67 -45
  26. package/dist/chunk-DYWZ23QT.mjs +90 -0
  27. package/dist/{chunk-KRRIRS6A.mjs → chunk-E67IR6HU.mjs} +31 -9
  28. package/dist/{chunk-D3QXPL47.mjs → chunk-EXQSWHLD.mjs} +7 -6
  29. package/dist/{chunk-ZOA7B32D.js → chunk-F35KL6TX.js} +10 -9
  30. package/dist/{chunk-YSLD2HLP.mjs → chunk-FFJC66KO.mjs} +2 -1
  31. package/dist/chunk-FRRS2YZH.mjs +1 -0
  32. package/dist/chunk-G5TQWWQA.mjs +1 -0
  33. package/dist/{chunk-MPZFPU4X.js → chunk-GMBLPQ3I.js} +4 -3
  34. package/dist/chunk-IJFPPLQW.js +50 -0
  35. package/dist/chunk-J6OLBSZR.js +1 -0
  36. package/dist/chunk-KGGQ5NZV.js +1 -0
  37. package/dist/chunk-KHCC5UKW.mjs +1 -0
  38. package/dist/{chunk-BMFQG6RA.mjs → chunk-KJIX6V32.mjs} +108 -1885
  39. package/dist/chunk-LABHD4PU.js +109 -0
  40. package/dist/chunk-LQCVRWVF.js +1 -0
  41. package/dist/{chunk-GAIQJCAZ.js → chunk-LT5VD4KR.js} +150 -1953
  42. package/dist/{chunk-7DHKQODW.mjs → chunk-LTLCIRZY.mjs} +257 -474
  43. package/dist/chunk-N5BHXWR3.mjs +34 -0
  44. package/dist/chunk-OCO3Z5YA.js +37 -0
  45. package/dist/chunk-OFQLWSUR.mjs +1 -0
  46. package/dist/chunk-OIJ7XMDV.mjs +71 -0
  47. package/dist/chunk-ORBH4IBC.mjs +316 -0
  48. package/dist/{chunk-C4UT5V3P.js → chunk-OWHI5VGJ.js} +1 -0
  49. package/dist/chunk-OWWOAYIY.js +2652 -0
  50. package/dist/chunk-PFHOXDSW.mjs +10 -0
  51. package/dist/chunk-Q52ZEL62.mjs +1 -0
  52. package/dist/chunk-QRS7DJGS.js +103 -0
  53. package/dist/chunk-R26Y7LGJ.js +1 -0
  54. package/dist/{chunk-BFWX5GJZ.mjs → chunk-R3X4B4JJ.mjs} +56 -8
  55. package/dist/chunk-RBUYW6QQ.js +1 -0
  56. package/dist/chunk-RM7ACPTM.mjs +2601 -0
  57. package/dist/chunk-RODSGPBB.mjs +75 -0
  58. package/dist/chunk-SORWLKOK.js +1 -0
  59. package/dist/{chunk-T6ZBA6VJ.js → chunk-UHAV34YX.js} +9 -8
  60. package/dist/{chunk-GUSTCU2W.mjs → chunk-ULANYJ7Y.mjs} +1 -59
  61. package/dist/chunk-ULDE7QSN.js +70 -0
  62. package/dist/chunk-UT36VNVZ.mjs +47 -0
  63. package/dist/chunk-UY3H4PKB.js +71 -0
  64. package/dist/{chunk-KB7UXIQZ.mjs → chunk-VIVWFQG5.mjs} +3 -1
  65. package/dist/{chunk-ESZ7CBA2.js → chunk-VKBJ3SGT.js} +7 -5
  66. package/dist/{chunk-UM7WMXIU.js → chunk-W3YOQ5ZD.js} +265 -505
  67. package/dist/chunk-WOITB4JL.js +1 -0
  68. package/dist/{chunk-E42B4GSB.js → chunk-XGJL6DLV.js} +58 -7
  69. package/dist/chunk-YKZEKJMZ.mjs +1 -0
  70. package/dist/chunk-YRIBFIQ5.js +116 -0
  71. package/dist/chunk-ZFLZA7UP.mjs +1 -0
  72. package/dist/chunk-ZKUIUE7W.mjs +1 -0
  73. package/dist/chunk-ZWWJ3RRA.js +15 -0
  74. package/dist/data-grid.d.cts +241 -0
  75. package/dist/data-grid.d.ts +241 -0
  76. package/dist/data-grid.js +6486 -0
  77. package/dist/data-grid.mjs +6459 -0
  78. package/dist/data-table-CDQBo-Ve.d.ts +818 -0
  79. package/dist/data-table-jLzt6plY.d.cts +818 -0
  80. package/dist/data-table.d.cts +8 -42
  81. package/dist/data-table.d.ts +8 -42
  82. package/dist/data-table.js +61 -187
  83. package/dist/data-table.mjs +11 -5
  84. package/dist/finance.d.cts +534 -0
  85. package/dist/finance.d.ts +534 -0
  86. package/dist/finance.js +188 -0
  87. package/dist/finance.mjs +15 -0
  88. package/dist/forms.js +9 -6
  89. package/dist/forms.mjs +7 -4
  90. package/dist/{hooks-B2jU1GVT.d.ts → hooks-A55E0fgf.d.ts} +3 -2
  91. package/dist/{hooks-8ORd7T1A.d.cts → hooks-Bys_AZPI.d.cts} +3 -2
  92. package/dist/hooks.d.cts +1 -1
  93. package/dist/hooks.d.ts +1 -1
  94. package/dist/hooks.js +26 -23
  95. package/dist/hooks.mjs +6 -3
  96. package/dist/index.d.cts +536 -665
  97. package/dist/index.d.ts +536 -665
  98. package/dist/index.js +3830 -3408
  99. package/dist/index.mjs +2068 -1767
  100. package/dist/layouts.js +26 -25
  101. package/dist/layouts.mjs +5 -4
  102. package/dist/marketing-3d.js +1 -0
  103. package/dist/marketing-3d.mjs +1 -0
  104. package/dist/marketing.js +75 -74
  105. package/dist/marketing.mjs +5 -4
  106. package/dist/media.js +1 -0
  107. package/dist/media.mjs +1 -0
  108. package/dist/navigation.js +29 -28
  109. package/dist/navigation.mjs +7 -6
  110. package/dist/primitives.d.cts +72 -109
  111. package/dist/primitives.d.ts +72 -109
  112. package/dist/primitives.js +78 -72
  113. package/dist/primitives.mjs +8 -6
  114. package/dist/settings.js +9 -9
  115. package/dist/settings.mjs +4 -4
  116. package/package.json +21 -4
  117. package/dist/UnifiedTableControls-CG299y9h.d.ts +0 -1233
  118. package/dist/UnifiedTableControls-CIjRpNhy.d.cts +0 -1233
  119. package/dist/chunk-GMBGWOCR.mjs +0 -48
  120. package/dist/chunk-HBLKVQIQ.mjs +0 -23
  121. package/dist/chunk-HMAMMC72.js +0 -26
  122. package/dist/chunk-MVYRNJA6.js +0 -74
package/dist/index.mjs CHANGED
@@ -1,41 +1,51 @@
1
- export { AppleCard, AppleCardsCarousel, BackgroundRippleEffect, BenefitsSection, CTAWithDashedGridLines, Carousel, CtaWithDashedGridLines, EditorialHero, FaqAccordion, GlowingEffect, HeroSection, HeroSectionWithRipple, ImpactSection, LampContainer, LampHero, MarketingProse, MediaTextHero, MetricStory, MissionSection, NextStepsSection, PageHero, PartnerLogoGrid, PixelatedCanvas, ProgramCard, RollingBackground, SectionShell, StackedIsometricFeatures, TeamCard, TestimonialsSection, TextGenerateEffect } from './chunk-6DVWMJ3H.mjs';
2
- export { FormWizard, useFormWizardNavigation } from './chunk-YSLD2HLP.mjs';
3
- export { PageHeader, SettingsLayout, SettingsRow, SettingsSection, SettingsTabContent, SettingsTabs } from './chunk-OLAAXLXY.mjs';
4
- import { Textarea, InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './chunk-N6AFNFZR.mjs';
5
- export { Checkbox, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, PasswordInput, PasswordRequirements, Textarea, VerificationCodeInput, defaultPasswordRules, extendedPasswordRules } from './chunk-N6AFNFZR.mjs';
6
- import { Badge } from './chunk-GUSTCU2W.mjs';
7
- export { Alert, AlertDescription, AlertTitle, Badge, badgeVariants } from './chunk-GUSTCU2W.mjs';
1
+ "use client";
2
+ export { AppSwitcher, ComingSoonButton, EntitySwitcher, Footer, MarketingHeaderPreset, Navbar, NavbarLogo, NavbarUserMenu, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuPrimitive, NavigationMenuTrigger, NavigationMenuViewport, NavigationMenuViewportPrimitive, NonprofitFooterPreset, RouteSegmentedSwitcher, SegmentedSwitcher, navigationMenuTriggerStyle } from './chunk-EXQSWHLD.mjs';
3
+ export { AppleCard, AppleCardsCarousel, BackgroundRippleEffect, BenefitsSection, CTAWithDashedGridLines, Carousel, CtaWithDashedGridLines, EditorialHero, FaqAccordion, GlowingEffect, HeroSection, HeroSectionWithRipple, ImpactSection, LampContainer, LampHero, MarketingProse, MediaTextHero, MetricStory, MissionSection, NextStepsSection, PageHero, PartnerLogoGrid, PixelatedCanvas, ProgramCard, RollingBackground, SectionShell, StackedIsometricFeatures, TeamCard, TestimonialsSection, TextGenerateEffect } from './chunk-2EFVMX6V.mjs';
4
+ export { NewsletterSignup } from './chunk-ZFLZA7UP.mjs';
5
+ import './chunk-T5R6HUDG.mjs';
6
+ export { FormWizard, useFormWizardNavigation } from './chunk-FFJC66KO.mjs';
7
+ import { useSessionErrors } from './chunk-VIVWFQG5.mjs';
8
+ export { createDataRestorationHandler, createFormResetHandler, createFormSubmitHandler, createStepHasFieldErrors, extractZodErrors, formatShortcut, getDefaultLtmRange, matchesShortcut, breakpoints as mediaBreakpoints, useBreakpoints, useComparisonData, useCopyToClipboard, useDebounce, useFinancialStatementState, useKeyboardShortcut, useLocalStorage, useMediaQuery, useSessionErrors, useStatementExport, useStatementMobileMode, useToast, useWizardForm } from './chunk-VIVWFQG5.mjs';
9
+ export { useScrollDirection } from './chunk-G5TQWWQA.mjs';
10
+ export { PageHeader, SettingsLayout, SettingsRow, SettingsSection, SettingsTabContent, SettingsTabs } from './chunk-6QAKQG57.mjs';
11
+ export { Container } from './chunk-C57MX3BG.mjs';
12
+ import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './chunk-7ERVZXIN.mjs';
13
+ export { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, PasswordInput, PasswordRequirements, VerificationCodeInput, defaultPasswordRules, extendedPasswordRules } from './chunk-7ERVZXIN.mjs';
14
+ export { Alert, AlertDescription, AlertTitle } from './chunk-6NCRGHV3.mjs';
8
15
  import { Card, CardHeader, CardTitle, CardDescription, CardContent } from './chunk-YL7RZRHM.mjs';
9
16
  export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-YL7RZRHM.mjs';
10
- import { Switch, DatePicker } from './chunk-BMFQG6RA.mjs';
11
- export { CASH_FLOW_CHART_CONFIG, Calendar, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ComparisonSelector, DataTableAddButton, DataTableExportButton, DataTablePagination, DataTableRowActions, DataTableSearch, DataTableSettings, DataTableSkeleton, DataTableSummary, DataTableToolbar, DataTableTopper, DataTableViewOptions, DataTableViews, DatePicker, DateRangePicker, FinancialStatementControls, FinancialSummaryChart, INCOME_STATEMENT_CHART_CONFIG, IconButton, MobilePeriodStepper, MobileStatementActions, MobileStatementFilters, ModernCalendar, PeriodSelector, Skeleton, AreaLineChart as SummaryAreaChart, ColumnChart as SummaryBarChart, SummaryPanel, PieChartView as SummaryPieChart, Switch, UnifiedTableControls, createFinanceTableSettingsItems, exportToCsv, exportToExcel, iconButtonVariants, normalizeUnifiedTableControls, unifiedTableControlOrder, useDataTableSettings, useUnifiedTableSettings } from './chunk-BMFQG6RA.mjs';
12
- import { Dialog, DialogContent, DialogClose, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './chunk-5THF4YP6.mjs';
13
- export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-5THF4YP6.mjs';
17
+ export { DataTable, DataTableAddButton, DataTableColumnHeader, DataTableDateFilter, DataTableExportButton, DataTableFacetedFilter, DataTablePagination, DataTableRowActions, DataTableSearch, DataTableSkeleton, DataTableSliderFilter, DataTableSummary, DataTableToolbar, DataTableTopper, DataTableViewOptions, DataTableViews, IconButton, Slider, dataTableConfig, exportToCsv, exportToExcel, getColumnPinningStyle, getDefaultFilterOperator, getFilterOperators, getFiltersStateParser, getSortingStateParser, getValidFilters, iconButtonVariants, useDataTable } from './chunk-RM7ACPTM.mjs';
18
+ import './chunk-OIJ7XMDV.mjs';
14
19
  import { Label } from './chunk-KHCC5UKW.mjs';
15
20
  export { Label } from './chunk-KHCC5UKW.mjs';
16
- export { StudioEditor } from './chunk-72JGQ7IJ.mjs';
17
- export { AdminPageLayout, AppFooter, AppHeader, AppLayout, AppSidebar, AutoSaveIndicator, BackLink, BasePageLayout, ClarityAnalytics, Collapsible, CollapsibleContent, CollapsibleTrigger, DashboardGrid, FloatingUserMenu, GoogleAnalytics, GoogleTagManager, HelpLayout, HelpPageLayout, HelpPanelLayout, LegalLayout, LegalSection, MarketingLayout, ProgressBar, RootLayout, Stepper, ThemeToggle, TimeEstimate, Toaster, UserPageLayout, WizardLayout, isNavDivider, isNavItem, isNavSection, themeScript, useTheme } from './chunk-KRRIRS6A.mjs';
18
- export { Tabs, TabsContent, TabsList, TabsTrigger } from './chunk-GMBGWOCR.mjs';
19
- export { ChartContainer, ChartTooltip, ChartTooltipContent } from './chunk-Q52ZEL62.mjs';
20
- import { useSessionErrors } from './chunk-KB7UXIQZ.mjs';
21
- export { createDataRestorationHandler, createFormResetHandler, createFormSubmitHandler, createStepHasFieldErrors, extractZodErrors, formatShortcut, getDefaultLtmRange, matchesShortcut, breakpoints as mediaBreakpoints, useBreakpoints, useComparisonData, useCopyToClipboard, useDebounce, useFinancialStatementState, useKeyboardShortcut, useLocalStorage, useMediaQuery, useSessionErrors, useStatementExport, useStatementMobileMode, useToast, useWizardForm } from './chunk-KB7UXIQZ.mjs';
22
- import { useDataTableContext, Popover, PopoverAnchor, PopoverContent } from './chunk-7DHKQODW.mjs';
23
- export { BALANCE_SHEET_CONFIG, DataTable, DataTableColumnFilter, DataTableColumnHeader, DataTableCurrencyCell, DataTableFilterBadges, FinanceDecimalsProvider, FinanceDisplayProvider, FinancialStatementTable, INCOME_STATEMENT_CONFIG, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, buildFinancialStatementData, createFinancialStatementRowImportanceResolver, flattenStatementForExport, formatCurrencyValue, getFinancialStatementRowImportanceClassName, getUnitDivisor, getUnitLabel, getUnitSuffix, useDataTableContext, useFinanceDecimals, useFinanceDecimalsSetting, useFinanceDisplay } from './chunk-7DHKQODW.mjs';
21
+ import { Switch, DatePicker } from './chunk-KJIX6V32.mjs';
22
+ export { CASH_FLOW_CHART_CONFIG, ChartTooltipRow, ChartTooltipShell, ChartTooltipTitle, Combobox, ComparisonSelector, DataTableSettings, DatePicker, DateRangePicker, FinancialStatementControls, FinancialSummaryChart, INCOME_STATEMENT_CHART_CONFIG, MobilePeriodStepper, MobileStatementActions, MobileStatementFilters, ModernCalendar, PeriodSelector, AreaLineChart as SummaryAreaChart, ColumnChart as SummaryBarChart, SummaryPanel, PieChartView as SummaryPieChart, Switch, UnifiedTableControls, createFinanceTableSettingsItems, normalizeUnifiedTableControls, unifiedTableControlOrder, useDataTableSettings, useUnifiedTableSettings } from './chunk-KJIX6V32.mjs';
23
+ export { BALANCE_SHEET_CONFIG, DataTableCurrencyCell, FinanceDecimalsProvider, FinanceDisplayProvider, FinancialStatementTable, INCOME_STATEMENT_CONFIG, buildFinancialStatementData, calculateDesktopFinancialColumnSizing, createFinancialStatementRowImportanceResolver, flattenStatementForExport, formatCurrencyValue, getFinancialStatementRowImportanceClassName, getUnitDivisor, getUnitLabel, getUnitSuffix, resolvePeriodColumns, useFinanceDecimals, useFinanceDecimalsSetting, useFinanceDisplay } from './chunk-LTLCIRZY.mjs';
24
+ export { dataTableTopperButtonProps, dataTableTopperIconClasses, dataTableTopperOpenStateClasses, dataTableTopperResponsiveClasses } from './chunk-PFHOXDSW.mjs';
25
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from './chunk-APFEP5B7.mjs';
26
+ import { Textarea } from './chunk-6HKJDV43.mjs';
27
+ export { BooleanCheckbox as Checkbox, Textarea } from './chunk-6HKJDV43.mjs';
28
+ export { Skeleton } from './chunk-UT36VNVZ.mjs';
29
+ import { Badge } from './chunk-ULANYJ7Y.mjs';
30
+ export { Badge, badgeVariants } from './chunk-ULANYJ7Y.mjs';
31
+ export { Calendar, CalendarDayButton, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from './chunk-ORBH4IBC.mjs';
32
+ import { Popover, PopoverAnchor, PopoverContent } from './chunk-RODSGPBB.mjs';
33
+ export { Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger } from './chunk-RODSGPBB.mjs';
34
+ import { Dialog, DialogContent, DialogClose, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './chunk-5THF4YP6.mjs';
35
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-5THF4YP6.mjs';
24
36
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-6BUBNZPG.mjs';
25
37
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './chunk-6BUBNZPG.mjs';
26
- export { AppSwitcher, ComingSoonButton, EntitySwitcher, Footer, MarketingHeaderPreset, Navbar, NavbarLogo, NavbarUserMenu, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuPrimitive, NavigationMenuTrigger, NavigationMenuViewport, NavigationMenuViewportPrimitive, NonprofitFooterPreset, RouteSegmentedSwitcher, SegmentedSwitcher, navigationMenuTriggerStyle } from './chunk-D3QXPL47.mjs';
27
- export { NewsletterSignup } from './chunk-ZFLZA7UP.mjs';
28
- import './chunk-T5R6HUDG.mjs';
29
- export { Container } from './chunk-RVEFPVZF.mjs';
30
- export { Avatar, AvatarFallback, AvatarImage, Kbd, KbdGroup, KeyboardShortcut, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, UserAvatarMenu, useSidebar } from './chunk-BFWX5GJZ.mjs';
38
+ import { Button } from './chunk-VBD4Q5LL.mjs';
39
+ export { Button, buttonVariants } from './chunk-VBD4Q5LL.mjs';
40
+ export { StudioEditor } from './chunk-72JGQ7IJ.mjs';
41
+ export { AdminPageLayout, AppFooter, AppHeader, AppLayout, AppSidebar, AutoSaveIndicator, BackLink, BasePageLayout, ClarityAnalytics, Collapsible, CollapsibleContent, CollapsibleTrigger, DashboardGrid, FloatingUserMenu, GoogleAnalytics, GoogleTagManager, HelpLayout, HelpPageLayout, HelpPanelLayout, LegalLayout, LegalSection, MarketingLayout, ProgressBar, RootLayout, Stepper, ThemeToggle, TimeEstimate, Toaster, UserPageLayout, WizardLayout, isNavDivider, isNavItem, isNavSection, themeScript, useTheme } from './chunk-E67IR6HU.mjs';
42
+ export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Kbd, KbdGroup, KeyboardShortcut, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, UserAvatarMenu, useSidebar } from './chunk-R3X4B4JJ.mjs';
43
+ export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants } from './chunk-DYWZ23QT.mjs';
31
44
  import { Separator } from './chunk-ZKUIUE7W.mjs';
32
45
  export { Separator } from './chunk-ZKUIUE7W.mjs';
46
+ import { SizedSpinner } from './chunk-N5BHXWR3.mjs';
47
+ export { SizedSpinner as Spinner, spinnerVariants } from './chunk-N5BHXWR3.mjs';
33
48
  export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger } from './chunk-FRRS2YZH.mjs';
34
- import { Spinner } from './chunk-HBLKVQIQ.mjs';
35
- export { Spinner, spinnerVariants } from './chunk-HBLKVQIQ.mjs';
36
- export { useScrollDirection } from './chunk-G5TQWWQA.mjs';
37
- import { Button } from './chunk-VBD4Q5LL.mjs';
38
- export { Button, buttonVariants } from './chunk-VBD4Q5LL.mjs';
39
49
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './chunk-OFQLWSUR.mjs';
40
50
  import { Tooltip, TooltipTrigger, TooltipContent } from './chunk-YKZEKJMZ.mjs';
41
51
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-YKZEKJMZ.mjs';
@@ -43,6 +53,7 @@ import { Input } from './chunk-STEP6C4C.mjs';
43
53
  export { Input, inputVariants } from './chunk-STEP6C4C.mjs';
44
54
  import { getDataStateIcon, DATA_STATE_COPY, getDataStateIconClassName } from './chunk-MHZXUOGN.mjs';
45
55
  export { getAvatarGradient, getGradientIndex, getGradientPairs, resolveDataState } from './chunk-MHZXUOGN.mjs';
56
+ export { ChartContainer, ChartTooltip, ChartTooltipContent } from './chunk-Q52ZEL62.mjs';
46
57
  import { cn } from './chunk-IMKLN273.mjs';
47
58
  export { cn } from './chunk-IMKLN273.mjs';
48
59
  import { toast } from 'sonner';
@@ -51,15 +62,16 @@ import * as React from 'react';
51
62
  import { createContext, useState, useRef, useEffect, useCallback, useId, useMemo, useContext, isValidElement, cloneElement, createElement } from 'react';
52
63
  import { useErrorLoggerSafe } from '@caffeinebounce/logger/client';
53
64
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
54
- import { Check, X, ArrowLeft, MapPin, Monitor, Mail, AlertTriangle, CheckCircle2, Clock, XCircle, Camera, Send, Globe, ChevronDown, ChevronRight, HelpCircle, Pencil, Loader2, Plus, ExternalLink, GripHorizontal, Search, Info, Calendar, Minus, Circle, MessageSquare, Smartphone, Phone, ArrowUpRight, TrendingUp, TrendingDown } from 'lucide-react';
65
+ import { Check, X, ArrowLeft, MapPin, Monitor, Mail, AlertTriangle, CheckCircle2, Clock, XCircle, Camera, Send, Globe, ChevronDown, Pencil, Loader2, Plus, ExternalLink, GripHorizontal, Search, Info, Calendar, Minus, ChevronRight, HelpCircle, Circle, MessageSquare, Smartphone, Phone, ArrowUpRight, TrendingUp, TrendingDown } from 'lucide-react';
55
66
  import { REGEXP_ONLY_DIGITS } from 'input-otp';
56
67
  import { cva } from 'class-variance-authority';
57
68
  export { ThemeProvider } from 'next-themes';
58
69
  import { createPortal } from 'react-dom';
59
70
  import { AnimatePresence, motion, useMotionValue, useAnimationControls, useSpring, useTransform } from 'motion/react';
71
+ import { Slot } from '@radix-ui/react-slot';
60
72
  import * as ProgressPrimitive from '@radix-ui/react-progress';
61
73
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
62
- import * as SliderPrimitive from '@radix-ui/react-slider';
74
+ import * as TogglePrimitive from '@radix-ui/react-toggle';
63
75
  import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
64
76
  import { preventWidows } from '@caffeinebounce/shared-utils';
65
77
 
@@ -127,8 +139,6 @@ function CompanyNameEditableCell({
127
139
  const [name, setName] = useState(initialName || "");
128
140
  const [dbaName, setDbaName] = useState(initialDbaName || "");
129
141
  const firstInputRef = useRef(null);
130
- const context = useDataTableContext();
131
- const isCompact = context?.density === "compact";
132
142
  const { isLoading, save } = useEditableCellSave();
133
143
  useEffect(() => {
134
144
  if (isEditing && firstInputRef.current) {
@@ -254,13 +264,13 @@ function CompanyNameEditableCell({
254
264
  type: "button",
255
265
  className: cn(
256
266
  "group flex w-full text-left cursor-pointer hover:bg-muted/50 px-2 -mx-2 rounded transition-colors",
257
- isCompact ? "items-center" : "flex-col py-1"
267
+ "flex-col py-1"
258
268
  ),
259
269
  onClick: () => setIsEditing(true),
260
270
  title: "Click to edit company details",
261
271
  children: [
262
272
  /* @__PURE__ */ jsx("span", { className: "font-medium truncate", children: name }),
263
- !isCompact && dbaName && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground truncate", children: [
273
+ dbaName && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground truncate", children: [
264
274
  "DBA: ",
265
275
  dbaName
266
276
  ] })
@@ -284,8 +294,6 @@ function EditableCell({
284
294
  );
285
295
  const inputRef = useRef(null);
286
296
  const textareaRef = useRef(null);
287
- const context = useDataTableContext();
288
- const isCompact = context?.density === "compact";
289
297
  const { isLoading, save } = useEditableCellSave();
290
298
  useEffect(() => {
291
299
  if (isEditing) {
@@ -464,7 +472,7 @@ function EditableCell({
464
472
  type: "button",
465
473
  className: cn(
466
474
  "group flex items-center w-full text-left gap-2 cursor-pointer hover:bg-muted/50 px-2 -mx-2 rounded transition-colors",
467
- !isCompact && "min-h-[32px]"
475
+ "min-h-[32px]"
468
476
  ),
469
477
  onClick: () => setIsEditing(true),
470
478
  title: "Click to edit",
@@ -636,7 +644,7 @@ function MFAChallenge({
636
644
  setCodeSent(false);
637
645
  };
638
646
  if (loading) {
639
- return /* @__PURE__ */ jsx("div", { className: "relative z-20 flex min-h-svh flex-col items-center justify-center px-6 py-12 pointer-events-none", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx(Spinner, { size: "lg" }) }) });
647
+ return /* @__PURE__ */ jsx("div", { className: "relative z-20 flex min-h-svh flex-col items-center justify-center px-6 py-12 pointer-events-none", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx(SizedSpinner, { size: "lg" }) }) });
640
648
  }
641
649
  if (factors.length === 0) {
642
650
  return null;
@@ -935,7 +943,7 @@ function MFARecovery({
935
943
  setLinkSent(false);
936
944
  };
937
945
  if (loading) {
938
- return /* @__PURE__ */ jsx("div", { className: "relative z-20 flex min-h-svh flex-col items-center justify-center px-6 py-12 pointer-events-none", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx(Spinner, { size: "lg" }) }) });
946
+ return /* @__PURE__ */ jsx("div", { className: "relative z-20 flex min-h-svh flex-col items-center justify-center px-6 py-12 pointer-events-none", children: /* @__PURE__ */ jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx(SizedSpinner, { size: "lg" }) }) });
939
947
  }
940
948
  return /* @__PURE__ */ jsx(
941
949
  "div",
@@ -1560,7 +1568,7 @@ function FeedbackDialog({
1560
1568
  /* @__PURE__ */ jsxs(DialogFooter, { children: [
1561
1569
  /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
1562
1570
  /* @__PURE__ */ jsx(Button, { onClick: handleSubmit, disabled: isSubmitDisabled, children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
1563
- /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }),
1571
+ /* @__PURE__ */ jsx(SizedSpinner, { className: "mr-2 h-4 w-4" }),
1564
1572
  "Sending..."
1565
1573
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1566
1574
  /* @__PURE__ */ jsx(Send, { className: "mr-2 h-4 w-4" }),
@@ -1816,570 +1824,235 @@ function DisclosureFootnotes({
1816
1824
  }
1817
1825
  );
1818
1826
  }
1819
- function HelpArticleIndex({ groups, onSelect }) {
1820
- return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: groups.map((group, index) => /* @__PURE__ */ jsxs("div", { children: [
1821
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
1822
- group.icon,
1823
- /* @__PURE__ */ jsx("h3", { className: "font-medium", children: group.title })
1824
- ] }),
1825
- /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.articles.map((article) => /* @__PURE__ */ jsxs(
1826
- "button",
1827
- {
1828
- type: "button",
1829
- onClick: () => onSelect(article.slug),
1830
- className: "w-full text-left p-2 rounded hover:bg-accent transition-colors flex items-center justify-between group",
1831
- children: [
1832
- /* @__PURE__ */ jsx("span", { className: "text-sm", children: article.title }),
1833
- /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
1834
- ]
1835
- },
1836
- article.slug
1837
- )) })
1838
- ] }, index)) });
1839
- }
1840
- function HelpArticleView({
1841
- article,
1842
- onNavigate,
1843
- onBackToIndex,
1844
- relatedArticles = [],
1845
- isLoading = false,
1846
- children
1847
- }) {
1848
- return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
1849
- /* @__PURE__ */ jsxs("div", { children: [
1850
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground mb-2", children: [
1851
- /* @__PURE__ */ jsx(
1852
- "button",
1853
- {
1854
- type: "button",
1855
- onClick: onBackToIndex,
1856
- className: "capitalize hover:text-foreground hover:underline transition-colors cursor-pointer",
1857
- children: article.category
1858
- }
1859
- ),
1860
- article.subcategory && /* @__PURE__ */ jsxs(Fragment, { children: [
1861
- /* @__PURE__ */ jsx(ChevronRight, { className: "size-3" }),
1862
- /* @__PURE__ */ jsx("span", { className: "capitalize", children: article.subcategory })
1863
- ] })
1864
- ] }),
1865
- /* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold", children: article.title }),
1866
- /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: article.description })
1867
- ] }),
1868
- /* @__PURE__ */ jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none prose-headings:font-semibold prose-a:text-primary hover:prose-a:underline [&>*:first-child]:mt-0", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-8", children: /* @__PURE__ */ jsx(Spinner, { className: "size-6" }) }) : children ? children : /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "Failed to load article content. Please try again later." }) }),
1869
- article.tags && article.tags.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
1870
- /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Tags" }),
1871
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: article.tags.map((tag) => /* @__PURE__ */ jsx(
1872
- "span",
1873
- {
1874
- className: "inline-flex px-2 py-0.5 text-xs rounded-full bg-muted",
1875
- children: tag
1876
- },
1877
- tag
1878
- )) })
1879
- ] }),
1880
- relatedArticles.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
1881
- /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Related Articles" }),
1882
- /* @__PURE__ */ jsx("div", { className: "space-y-2", children: relatedArticles.map((related) => /* @__PURE__ */ jsx(
1883
- "button",
1884
- {
1885
- type: "button",
1886
- onClick: () => onNavigate(related.slug),
1887
- className: "w-full text-left p-2 rounded border hover:bg-accent transition-colors text-sm",
1888
- children: /* @__PURE__ */ jsx("p", { className: "font-medium", children: related.title })
1889
- },
1890
- related.slug
1891
- )) })
1892
- ] })
1893
- ] });
1894
- }
1895
- var HelpContext = createContext(null);
1896
- function HelpProvider({
1897
- children,
1898
- getArticle,
1899
- searchArticles,
1900
- getArticleForFeature,
1901
- getArticleForRoute,
1902
- getContextForRoute,
1903
- pathname,
1904
- isAdmin = false
1827
+ function Autocomplete({
1828
+ options,
1829
+ value,
1830
+ onValueChange,
1831
+ placeholder = "Type to search...",
1832
+ emptyText = "No results found.",
1833
+ disabled = false,
1834
+ allowCreate = false,
1835
+ createLabel = "Create new",
1836
+ onCreateNew,
1837
+ onEditSelected,
1838
+ loading = false,
1839
+ className,
1840
+ error = false,
1841
+ "aria-label": ariaLabel,
1842
+ id,
1843
+ name
1905
1844
  }) {
1906
- const [isOpen, setIsOpen] = useState(false);
1907
- const [activeArticleSlug, setActiveArticleSlug] = useState(
1908
- null
1909
- );
1910
- const [searchQuery, setSearchQuery] = useState("");
1911
- const [history, setHistory] = useState([]);
1912
- const helpContext = useMemo(
1913
- () => isAdmin ? "admin" : getContextForRoute(pathname),
1914
- [isAdmin, pathname, getContextForRoute]
1845
+ const [open, setOpen] = useState(false);
1846
+ const [inputValue, setInputValue] = useState("");
1847
+ const [highlightedIndex, setHighlightedIndex] = useState(-1);
1848
+ const inputRef = useRef(null);
1849
+ const listRef = useRef(null);
1850
+ const [tooltipVisible, setTooltipVisible] = useState(false);
1851
+ const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
1852
+ const selectedOption = useMemo(
1853
+ () => options.find((opt) => opt.value === value),
1854
+ [options, value]
1915
1855
  );
1916
- const activeArticle = useMemo(() => {
1917
- if (!activeArticleSlug) return null;
1918
- return getArticle(activeArticleSlug);
1919
- }, [activeArticleSlug, getArticle]);
1920
- const searchResults = useMemo(() => {
1921
- if (!searchQuery.trim()) return [];
1922
- return searchArticles(searchQuery);
1923
- }, [searchQuery, searchArticles]);
1924
- const openHelp = useCallback(
1925
- (articleSlug) => {
1926
- setIsOpen(true);
1927
- if (articleSlug) {
1928
- setActiveArticleSlug(articleSlug);
1929
- setHistory([]);
1930
- } else {
1931
- const contextualSlug = getArticleForRoute(pathname);
1932
- setActiveArticleSlug(contextualSlug);
1933
- setHistory([]);
1934
- }
1935
- setSearchQuery("");
1856
+ useEffect(() => {
1857
+ if (selectedOption && !open) {
1858
+ setInputValue(selectedOption.label);
1859
+ } else if (!value && !open) {
1860
+ setInputValue("");
1861
+ }
1862
+ }, [selectedOption, value, open]);
1863
+ const filteredOptions = useMemo(() => {
1864
+ if (!inputValue) return options;
1865
+ const search = inputValue.toLowerCase();
1866
+ return options.filter(
1867
+ (opt) => opt.label.toLowerCase().includes(search) || opt.description?.toLowerCase().includes(search)
1868
+ );
1869
+ }, [options, inputValue]);
1870
+ const exactMatch = useMemo(() => {
1871
+ if (!inputValue) return true;
1872
+ const search = inputValue.toLowerCase();
1873
+ return options.some((opt) => opt.label.toLowerCase() === search);
1874
+ }, [options, inputValue]);
1875
+ const showCreateOption = allowCreate && !!inputValue && !exactMatch;
1876
+ const totalItems = filteredOptions.length + (showCreateOption ? 1 : 0);
1877
+ const hasContent = filteredOptions.length > 0 || showCreateOption;
1878
+ const effectiveOpen = open && hasContent;
1879
+ useEffect(() => {
1880
+ setHighlightedIndex(-1);
1881
+ }, []);
1882
+ const handleSelect = useCallback(
1883
+ (selectedValue, label) => {
1884
+ onValueChange?.(selectedValue);
1885
+ setInputValue(label);
1886
+ setOpen(false);
1887
+ setHighlightedIndex(-1);
1936
1888
  },
1937
- [pathname, getArticleForRoute]
1889
+ [onValueChange]
1938
1890
  );
1939
- const closeHelp = useCallback(() => {
1940
- setIsOpen(false);
1941
- }, []);
1942
- const toggleHelp = useCallback(() => {
1943
- if (isOpen) {
1944
- closeHelp();
1945
- } else {
1946
- openHelp();
1891
+ const handleCreateNew = useCallback(() => {
1892
+ onCreateNew?.(inputValue);
1893
+ setOpen(false);
1894
+ setHighlightedIndex(-1);
1895
+ }, [onCreateNew, inputValue]);
1896
+ const [shouldFocusAfterClear, setShouldFocusAfterClear] = useState(false);
1897
+ const handleClear = useCallback(() => {
1898
+ onValueChange?.("");
1899
+ setInputValue("");
1900
+ setOpen(false);
1901
+ setShouldFocusAfterClear(true);
1902
+ }, [onValueChange]);
1903
+ useEffect(() => {
1904
+ if (shouldFocusAfterClear && !value && inputRef.current) {
1905
+ inputRef.current.focus();
1906
+ setShouldFocusAfterClear(false);
1947
1907
  }
1948
- }, [isOpen, openHelp, closeHelp]);
1949
- const setActiveArticle = useCallback((slug) => {
1950
- setActiveArticleSlug(slug);
1951
- setSearchQuery("");
1908
+ }, [shouldFocusAfterClear, value]);
1909
+ const handleInputChange = useCallback((e) => {
1910
+ const newValue = e.target.value;
1911
+ setInputValue(newValue);
1912
+ setOpen(true);
1952
1913
  }, []);
1953
- const performSearch = useCallback((query) => {
1954
- setIsOpen(true);
1955
- setSearchQuery(query);
1956
- setActiveArticleSlug(null);
1914
+ const handleInputFocus = useCallback(() => {
1915
+ setOpen(true);
1957
1916
  }, []);
1958
- const openFeatureHelp = useCallback(
1959
- (featureKey) => {
1960
- const articleSlug = getArticleForFeature(featureKey);
1961
- if (articleSlug) {
1962
- setIsOpen(true);
1963
- setActiveArticleSlug(articleSlug);
1964
- setHistory([]);
1965
- setSearchQuery("");
1917
+ const handleInputClick = useCallback(() => {
1918
+ setOpen(true);
1919
+ }, []);
1920
+ const handleKeyDown = useCallback(
1921
+ (e) => {
1922
+ if (!open) {
1923
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
1924
+ e.preventDefault();
1925
+ setOpen(true);
1926
+ }
1927
+ return;
1966
1928
  }
1967
- },
1968
- [getArticleForFeature]
1969
- );
1970
- const navigateToArticle = useCallback(
1971
- (slug) => {
1972
- if (activeArticleSlug && activeArticleSlug !== slug) {
1973
- setHistory((prev) => [...prev, activeArticleSlug]);
1929
+ switch (e.key) {
1930
+ case "ArrowDown":
1931
+ e.preventDefault();
1932
+ setHighlightedIndex(
1933
+ (prev) => prev < totalItems - 1 ? prev + 1 : prev
1934
+ );
1935
+ break;
1936
+ case "ArrowUp":
1937
+ e.preventDefault();
1938
+ setHighlightedIndex((prev) => prev > 0 ? prev - 1 : -1);
1939
+ break;
1940
+ case "Enter":
1941
+ e.preventDefault();
1942
+ if (highlightedIndex >= 0) {
1943
+ if (showCreateOption && highlightedIndex === filteredOptions.length) {
1944
+ handleCreateNew();
1945
+ } else if (highlightedIndex < filteredOptions.length) {
1946
+ const option = filteredOptions[highlightedIndex];
1947
+ if (!option.disabled) {
1948
+ handleSelect(option.value, option.label);
1949
+ }
1950
+ }
1951
+ } else if (showCreateOption && filteredOptions.length === 0) {
1952
+ handleCreateNew();
1953
+ }
1954
+ break;
1955
+ case "Escape":
1956
+ e.preventDefault();
1957
+ setOpen(false);
1958
+ setHighlightedIndex(-1);
1959
+ if (selectedOption) {
1960
+ setInputValue(selectedOption.label);
1961
+ }
1962
+ break;
1963
+ case "Tab":
1964
+ setOpen(false);
1965
+ break;
1974
1966
  }
1975
- setActiveArticleSlug(slug);
1976
- setSearchQuery("");
1977
1967
  },
1978
- [activeArticleSlug]
1968
+ [
1969
+ open,
1970
+ highlightedIndex,
1971
+ totalItems,
1972
+ showCreateOption,
1973
+ filteredOptions,
1974
+ handleCreateNew,
1975
+ handleSelect,
1976
+ selectedOption
1977
+ ]
1979
1978
  );
1980
- const goBack = useCallback(() => {
1981
- if (history.length > 0) {
1982
- const newHistory = [...history];
1983
- const previousSlug = newHistory.pop();
1984
- setHistory(newHistory);
1985
- setActiveArticleSlug(previousSlug || null);
1986
- }
1987
- }, [history]);
1988
- const canGoBack = history.length > 0;
1989
1979
  useEffect(() => {
1990
- function handleKeyDown(event) {
1991
- if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "H") {
1992
- event.preventDefault();
1993
- toggleHelp();
1994
- }
1995
- if (event.key === "Escape" && isOpen) {
1996
- event.preventDefault();
1997
- closeHelp();
1998
- }
1980
+ if (highlightedIndex >= 0 && listRef.current) {
1981
+ const items = listRef.current.querySelectorAll("[data-option]");
1982
+ const item = items[highlightedIndex];
1983
+ item?.scrollIntoView({ block: "nearest" });
1999
1984
  }
2000
- window.addEventListener("keydown", handleKeyDown);
2001
- return () => window.removeEventListener("keydown", handleKeyDown);
2002
- }, [toggleHelp, closeHelp, isOpen]);
2003
- useEffect(() => {
2004
- function handleClick(event) {
2005
- const target = event.target;
2006
- const link = target.closest('a[href="/help"], a[href="/admin/help"]');
2007
- if (link && !link.hasAttribute("data-prevent-help-intercept")) {
2008
- event.preventDefault();
2009
- event.stopPropagation();
2010
- toggleHelp();
1985
+ }, [highlightedIndex]);
1986
+ const handleMouseMove = useCallback(
1987
+ (e) => {
1988
+ if (selectedOption?.description) {
1989
+ setTooltipPosition({ x: e.clientX, y: e.clientY });
2011
1990
  }
2012
- }
2013
- document.addEventListener("click", handleClick, true);
2014
- return () => document.removeEventListener("click", handleClick, true);
2015
- }, [toggleHelp]);
2016
- const value = {
2017
- isOpen,
2018
- openHelp,
2019
- closeHelp,
2020
- toggleHelp,
2021
- activeArticle,
2022
- setActiveArticle,
2023
- helpContext,
2024
- searchQuery,
2025
- setSearchQuery,
2026
- performSearch,
2027
- searchResults,
2028
- openFeatureHelp,
2029
- navigateToArticle,
2030
- goBack,
2031
- history,
2032
- canGoBack
2033
- };
2034
- return /* @__PURE__ */ jsx(HelpContext.Provider, { value, children });
2035
- }
2036
- function useHelp() {
2037
- const context = useContext(HelpContext);
2038
- if (!context) {
2039
- throw new Error("useHelp must be used within a HelpProvider");
2040
- }
2041
- return context;
2042
- }
2043
- function HelpButton({
2044
- featureKey,
2045
- variant = "ghost",
2046
- size = "icon",
2047
- className,
2048
- label = "Help",
2049
- showLabel = false
2050
- }) {
2051
- const { openHelp, openFeatureHelp } = useHelp();
2052
- const handleClick = () => {
2053
- if (featureKey) {
2054
- openFeatureHelp(featureKey);
2055
- } else {
2056
- openHelp();
2057
- }
2058
- };
2059
- return /* @__PURE__ */ jsxs(
2060
- Button,
2061
- {
2062
- variant,
2063
- size: showLabel ? size : "icon",
2064
- onClick: handleClick,
2065
- className: cn(showLabel && "gap-2", className),
2066
- "aria-label": label,
2067
- children: [
2068
- /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" }),
2069
- showLabel && /* @__PURE__ */ jsx("span", { children: label })
2070
- ]
2071
- }
1991
+ },
1992
+ [selectedOption?.description]
2072
1993
  );
2073
- }
2074
- function HelpSearchResults({
2075
- results,
2076
- query,
2077
- onSelect,
2078
- categoryIcons = {}
2079
- }) {
2080
- if (results.length === 0) {
2081
- return /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
2082
- /* @__PURE__ */ jsx(HelpCircle, { className: "size-12 mx-auto text-muted-foreground/50 mb-3" }),
2083
- /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
2084
- "No results found for \u201C",
2085
- query,
2086
- "\u201D"
2087
- ] }),
2088
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground/70 mt-1", children: "Try different keywords or browse categories below" })
2089
- ] });
2090
- }
2091
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2092
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: [
2093
- results.length,
2094
- " result",
2095
- results.length !== 1 ? "s" : "",
2096
- " for \u201C",
2097
- query,
2098
- "\u201D"
2099
- ] }),
2100
- results.map((result) => {
2101
- const Icon = categoryIcons[result.category] || HelpCircle;
2102
- return /* @__PURE__ */ jsx(
2103
- "button",
1994
+ const handleMouseEnter = useCallback(() => {
1995
+ if (selectedOption?.description) {
1996
+ setTooltipVisible(true);
1997
+ }
1998
+ }, [selectedOption?.description]);
1999
+ const handleMouseLeave = useCallback(() => {
2000
+ setTooltipVisible(false);
2001
+ }, []);
2002
+ return /* @__PURE__ */ jsxs(Popover, { open: effectiveOpen, onOpenChange: setOpen, children: [
2003
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "relative", children: selectedOption ? /* @__PURE__ */ jsxs(Fragment, { children: [
2004
+ /* @__PURE__ */ jsxs(
2005
+ "div",
2104
2006
  {
2105
- type: "button",
2106
- onClick: () => onSelect(result.slug),
2107
- className: "w-full text-left p-3 rounded-lg border hover:bg-accent transition-colors",
2108
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
2109
- /* @__PURE__ */ jsx(Icon, { className: "size-4 mt-0.5 text-muted-foreground" }),
2110
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2111
- /* @__PURE__ */ jsx("p", { className: "font-medium text-sm", children: result.title }),
2112
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2 mt-0.5", children: result.description })
2113
- ] }),
2114
- /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
2115
- ] })
2116
- },
2117
- result.slug
2118
- );
2119
- })
2120
- ] });
2121
- }
2122
- function HelpTooltip({
2123
- content,
2124
- featureKey,
2125
- size = "sm",
2126
- className
2127
- }) {
2128
- const { openFeatureHelp } = useHelp();
2129
- const iconSize = size === "sm" ? "size-3.5" : "size-4";
2130
- const handleClick = (e) => {
2131
- if (featureKey) {
2132
- e.preventDefault();
2133
- e.stopPropagation();
2134
- openFeatureHelp(featureKey);
2135
- }
2136
- };
2137
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
2138
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
2139
- "button",
2140
- {
2141
- type: "button",
2142
- onClick: handleClick,
2143
- className: `inline-flex items-center justify-center text-muted-foreground hover:text-foreground transition-colors ${className}`,
2144
- "aria-label": "Help",
2145
- children: /* @__PURE__ */ jsx(HelpCircle, { className: iconSize })
2146
- }
2147
- ) }),
2148
- /* @__PURE__ */ jsxs(TooltipContent, { className: "max-w-xs", children: [
2149
- /* @__PURE__ */ jsx("p", { className: "text-sm", children: content }),
2150
- featureKey && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Click to learn more" })
2151
- ] })
2152
- ] });
2153
- }
2154
- function Autocomplete({
2155
- options,
2156
- value,
2157
- onValueChange,
2158
- placeholder = "Type to search...",
2159
- emptyText = "No results found.",
2160
- disabled = false,
2161
- allowCreate = false,
2162
- createLabel = "Create new",
2163
- onCreateNew,
2164
- onEditSelected,
2165
- loading = false,
2166
- className,
2167
- error = false,
2168
- "aria-label": ariaLabel,
2169
- id,
2170
- name
2171
- }) {
2172
- const [open, setOpen] = useState(false);
2173
- const [inputValue, setInputValue] = useState("");
2174
- const [highlightedIndex, setHighlightedIndex] = useState(-1);
2175
- const inputRef = useRef(null);
2176
- const listRef = useRef(null);
2177
- const [tooltipVisible, setTooltipVisible] = useState(false);
2178
- const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
2179
- const selectedOption = useMemo(
2180
- () => options.find((opt) => opt.value === value),
2181
- [options, value]
2182
- );
2183
- useEffect(() => {
2184
- if (selectedOption && !open) {
2185
- setInputValue(selectedOption.label);
2186
- } else if (!value && !open) {
2187
- setInputValue("");
2188
- }
2189
- }, [selectedOption, value, open]);
2190
- const filteredOptions = useMemo(() => {
2191
- if (!inputValue) return options;
2192
- const search = inputValue.toLowerCase();
2193
- return options.filter(
2194
- (opt) => opt.label.toLowerCase().includes(search) || opt.description?.toLowerCase().includes(search)
2195
- );
2196
- }, [options, inputValue]);
2197
- const exactMatch = useMemo(() => {
2198
- if (!inputValue) return true;
2199
- const search = inputValue.toLowerCase();
2200
- return options.some((opt) => opt.label.toLowerCase() === search);
2201
- }, [options, inputValue]);
2202
- const showCreateOption = allowCreate && !!inputValue && !exactMatch;
2203
- const totalItems = filteredOptions.length + (showCreateOption ? 1 : 0);
2204
- const hasContent = filteredOptions.length > 0 || showCreateOption;
2205
- const effectiveOpen = open && hasContent;
2206
- useEffect(() => {
2207
- setHighlightedIndex(-1);
2208
- }, []);
2209
- const handleSelect = useCallback(
2210
- (selectedValue, label) => {
2211
- onValueChange?.(selectedValue);
2212
- setInputValue(label);
2213
- setOpen(false);
2214
- setHighlightedIndex(-1);
2215
- },
2216
- [onValueChange]
2217
- );
2218
- const handleCreateNew = useCallback(() => {
2219
- onCreateNew?.(inputValue);
2220
- setOpen(false);
2221
- setHighlightedIndex(-1);
2222
- }, [onCreateNew, inputValue]);
2223
- const [shouldFocusAfterClear, setShouldFocusAfterClear] = useState(false);
2224
- const handleClear = useCallback(() => {
2225
- onValueChange?.("");
2226
- setInputValue("");
2227
- setOpen(false);
2228
- setShouldFocusAfterClear(true);
2229
- }, [onValueChange]);
2230
- useEffect(() => {
2231
- if (shouldFocusAfterClear && !value && inputRef.current) {
2232
- inputRef.current.focus();
2233
- setShouldFocusAfterClear(false);
2234
- }
2235
- }, [shouldFocusAfterClear, value]);
2236
- const handleInputChange = useCallback((e) => {
2237
- const newValue = e.target.value;
2238
- setInputValue(newValue);
2239
- setOpen(true);
2240
- }, []);
2241
- const handleInputFocus = useCallback(() => {
2242
- setOpen(true);
2243
- }, []);
2244
- const handleInputClick = useCallback(() => {
2245
- setOpen(true);
2246
- }, []);
2247
- const handleKeyDown = useCallback(
2248
- (e) => {
2249
- if (!open) {
2250
- if (e.key === "ArrowDown" || e.key === "ArrowUp") {
2251
- e.preventDefault();
2252
- setOpen(true);
2253
- }
2254
- return;
2255
- }
2256
- switch (e.key) {
2257
- case "ArrowDown":
2258
- e.preventDefault();
2259
- setHighlightedIndex(
2260
- (prev) => prev < totalItems - 1 ? prev + 1 : prev
2261
- );
2262
- break;
2263
- case "ArrowUp":
2264
- e.preventDefault();
2265
- setHighlightedIndex((prev) => prev > 0 ? prev - 1 : -1);
2266
- break;
2267
- case "Enter":
2268
- e.preventDefault();
2269
- if (highlightedIndex >= 0) {
2270
- if (showCreateOption && highlightedIndex === filteredOptions.length) {
2271
- handleCreateNew();
2272
- } else if (highlightedIndex < filteredOptions.length) {
2273
- const option = filteredOptions[highlightedIndex];
2274
- if (!option.disabled) {
2275
- handleSelect(option.value, option.label);
2276
- }
2277
- }
2278
- } else if (showCreateOption && filteredOptions.length === 0) {
2279
- handleCreateNew();
2280
- }
2281
- break;
2282
- case "Escape":
2283
- e.preventDefault();
2284
- setOpen(false);
2285
- setHighlightedIndex(-1);
2286
- if (selectedOption) {
2287
- setInputValue(selectedOption.label);
2288
- }
2289
- break;
2290
- case "Tab":
2291
- setOpen(false);
2292
- break;
2293
- }
2294
- },
2295
- [
2296
- open,
2297
- highlightedIndex,
2298
- totalItems,
2299
- showCreateOption,
2300
- filteredOptions,
2301
- handleCreateNew,
2302
- handleSelect,
2303
- selectedOption
2304
- ]
2305
- );
2306
- useEffect(() => {
2307
- if (highlightedIndex >= 0 && listRef.current) {
2308
- const items = listRef.current.querySelectorAll("[data-option]");
2309
- const item = items[highlightedIndex];
2310
- item?.scrollIntoView({ block: "nearest" });
2311
- }
2312
- }, [highlightedIndex]);
2313
- const handleMouseMove = useCallback(
2314
- (e) => {
2315
- if (selectedOption?.description) {
2316
- setTooltipPosition({ x: e.clientX, y: e.clientY });
2317
- }
2318
- },
2319
- [selectedOption?.description]
2320
- );
2321
- const handleMouseEnter = useCallback(() => {
2322
- if (selectedOption?.description) {
2323
- setTooltipVisible(true);
2324
- }
2325
- }, [selectedOption?.description]);
2326
- const handleMouseLeave = useCallback(() => {
2327
- setTooltipVisible(false);
2328
- }, []);
2329
- return /* @__PURE__ */ jsxs(Popover, { open: effectiveOpen, onOpenChange: setOpen, children: [
2330
- /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "relative", children: selectedOption ? /* @__PURE__ */ jsxs(Fragment, { children: [
2331
- /* @__PURE__ */ jsxs(
2332
- "div",
2333
- {
2334
- className: cn(
2335
- "flex h-9 w-full items-center gap-2 rounded-box border border-input bg-muted/30 px-2 py-1 shadow-xs",
2336
- disabled && "cursor-not-allowed opacity-50",
2337
- error && "border-destructive",
2338
- className
2339
- ),
2340
- onMouseEnter: handleMouseEnter,
2341
- onMouseLeave: handleMouseLeave,
2342
- onMouseMove: handleMouseMove,
2343
- children: [
2344
- /* @__PURE__ */ jsx(
2345
- Badge,
2346
- {
2347
- variant: "secondary",
2348
- className: "max-w-[calc(100%-4.5rem)] truncate font-normal",
2349
- children: selectedOption.label
2350
- }
2351
- ),
2352
- !disabled && !loading && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-0.5 shrink-0", children: [
2353
- onEditSelected && /* @__PURE__ */ jsxs(
2354
- Button,
2355
- {
2356
- type: "button",
2357
- variant: "ghost",
2358
- size: "icon",
2359
- className: "h-6 w-6 text-muted-foreground hover:text-foreground",
2360
- onClick: () => onEditSelected(selectedOption),
2361
- tabIndex: -1,
2362
- children: [
2363
- /* @__PURE__ */ jsx(Pencil, { className: "h-3 w-3" }),
2364
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit selection" })
2365
- ]
2366
- }
2367
- ),
2368
- /* @__PURE__ */ jsxs(
2369
- Button,
2370
- {
2371
- type: "button",
2372
- variant: "ghost",
2373
- size: "icon",
2374
- className: "h-6 w-6 text-muted-foreground hover:text-foreground",
2375
- onClick: handleClear,
2376
- tabIndex: -1,
2377
- children: [
2378
- /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" }),
2379
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Clear selection" })
2380
- ]
2381
- }
2382
- )
2007
+ className: cn(
2008
+ "flex h-9 w-full items-center gap-2 rounded-box border border-input bg-muted/30 px-2 py-1 shadow-xs",
2009
+ disabled && "cursor-not-allowed opacity-50",
2010
+ error && "border-destructive",
2011
+ className
2012
+ ),
2013
+ onMouseEnter: handleMouseEnter,
2014
+ onMouseLeave: handleMouseLeave,
2015
+ onMouseMove: handleMouseMove,
2016
+ children: [
2017
+ /* @__PURE__ */ jsx(
2018
+ Badge,
2019
+ {
2020
+ variant: "secondary",
2021
+ className: "max-w-[calc(100%-4.5rem)] truncate font-normal",
2022
+ children: selectedOption.label
2023
+ }
2024
+ ),
2025
+ !disabled && !loading && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-0.5 shrink-0", children: [
2026
+ onEditSelected && /* @__PURE__ */ jsxs(
2027
+ Button,
2028
+ {
2029
+ type: "button",
2030
+ variant: "ghost",
2031
+ size: "icon",
2032
+ className: "h-6 w-6 text-muted-foreground hover:text-foreground",
2033
+ onClick: () => onEditSelected(selectedOption),
2034
+ tabIndex: -1,
2035
+ children: [
2036
+ /* @__PURE__ */ jsx(Pencil, { className: "h-3 w-3" }),
2037
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit selection" })
2038
+ ]
2039
+ }
2040
+ ),
2041
+ /* @__PURE__ */ jsxs(
2042
+ Button,
2043
+ {
2044
+ type: "button",
2045
+ variant: "ghost",
2046
+ size: "icon",
2047
+ className: "h-6 w-6 text-muted-foreground hover:text-foreground",
2048
+ onClick: handleClear,
2049
+ tabIndex: -1,
2050
+ children: [
2051
+ /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" }),
2052
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Clear selection" })
2053
+ ]
2054
+ }
2055
+ )
2383
2056
  ] }),
2384
2057
  loading && /* @__PURE__ */ jsx(Loader2, { className: "ml-auto h-4 w-4 shrink-0 animate-spin text-muted-foreground" })
2385
2058
  ]
@@ -2550,81 +2223,6 @@ function Autocomplete({
2550
2223
  )
2551
2224
  ] });
2552
2225
  }
2553
- function ButtonGroup({
2554
- className,
2555
- orientation = "horizontal",
2556
- ...props
2557
- }) {
2558
- return (
2559
- // biome-ignore lint/a11y/useSemanticElements: ButtonGroup is visual grouping, not a form fieldset
2560
- /* @__PURE__ */ jsx(
2561
- "div",
2562
- {
2563
- role: "group",
2564
- "data-orientation": orientation,
2565
- className: cn(
2566
- "flex",
2567
- orientation === "horizontal" ? "flex-row items-center -space-x-px" : "flex-col -space-y-px",
2568
- // Style direct children to have connected appearance
2569
- // Use !important to override Button's own shared box radius classes
2570
- "[&>*]:!rounded-none",
2571
- "[&>*:first-child]:!rounded-l-box",
2572
- "[&>*:last-child]:!rounded-r-box",
2573
- orientation === "vertical" && [
2574
- "[&>*:first-child]:!rounded-t-box [&>*:first-child]:!rounded-l-none",
2575
- "[&>*:last-child]:!rounded-b-box [&>*:last-child]:!rounded-r-none"
2576
- ],
2577
- // Handle nested button groups
2578
- "**:[role=group]:flex",
2579
- "**:[role=group]>*:!rounded-none",
2580
- "[&>[role=group]:first-child>*:first-child]:!rounded-l-box",
2581
- "[&>[role=group]:last-child>*:last-child]:!rounded-r-box",
2582
- className
2583
- ),
2584
- ...props
2585
- }
2586
- )
2587
- );
2588
- }
2589
- function ButtonGroupSeparator({
2590
- className,
2591
- orientation = "vertical",
2592
- ...props
2593
- }) {
2594
- return /* @__PURE__ */ jsx(
2595
- "hr",
2596
- {
2597
- "aria-orientation": orientation,
2598
- className: cn(
2599
- "bg-border border-0",
2600
- orientation === "vertical" ? "h-6 w-px" : "h-px w-6",
2601
- className
2602
- ),
2603
- ...props
2604
- }
2605
- );
2606
- }
2607
- function ButtonGroupText({
2608
- className,
2609
- asChild = false,
2610
- children,
2611
- ...props
2612
- }) {
2613
- if (asChild) {
2614
- return /* @__PURE__ */ jsx(Fragment, { children });
2615
- }
2616
- return /* @__PURE__ */ jsx(
2617
- "span",
2618
- {
2619
- className: cn(
2620
- "flex items-center px-3 text-sm text-muted-foreground",
2621
- className
2622
- ),
2623
- ...props,
2624
- children
2625
- }
2626
- );
2627
- }
2628
2226
  function HoverEffect({ items, className }) {
2629
2227
  const [hoveredIndex, setHoveredIndex] = useState(null);
2630
2228
  return /* @__PURE__ */ jsx(
@@ -3625,1269 +3223,1972 @@ function GooeyInput({
3625
3223
  }
3626
3224
  );
3627
3225
  }
3628
- function InfoTooltip({
3629
- content,
3630
- size = "sm",
3631
- className,
3632
- side = "top",
3633
- align = "center"
3634
- }) {
3635
- const iconSize = size === "sm" ? "size-3.5" : "size-4";
3636
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
3637
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
3638
- "button",
3639
- {
3640
- type: "button",
3641
- className: cn(
3642
- "inline-flex items-center justify-center text-muted-foreground hover:text-foreground transition-colors ml-1",
3643
- className
3644
- ),
3645
- "aria-label": "More information",
3646
- children: /* @__PURE__ */ jsx(Info, { className: iconSize })
3647
- }
3648
- ) }),
3649
- /* @__PURE__ */ jsx(TooltipContent, { side, align, className: "max-w-xs", children: typeof content === "string" ? /* @__PURE__ */ jsx("p", { className: "text-sm", children: content }) : content })
3650
- ] });
3651
- }
3652
- function InlineEditableText({
3226
+ function InfoTooltip({
3227
+ content,
3228
+ size = "sm",
3229
+ className,
3230
+ side = "top",
3231
+ align = "center"
3232
+ }) {
3233
+ const iconSize = size === "sm" ? "size-3.5" : "size-4";
3234
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
3235
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
3236
+ "button",
3237
+ {
3238
+ type: "button",
3239
+ className: cn(
3240
+ "inline-flex items-center justify-center text-muted-foreground hover:text-foreground transition-colors ml-1",
3241
+ className
3242
+ ),
3243
+ "aria-label": "More information",
3244
+ children: /* @__PURE__ */ jsx(Info, { className: iconSize })
3245
+ }
3246
+ ) }),
3247
+ /* @__PURE__ */ jsx(TooltipContent, { side, align, className: "max-w-xs", children: typeof content === "string" ? /* @__PURE__ */ jsx("p", { className: "text-sm", children: content }) : content })
3248
+ ] });
3249
+ }
3250
+ function InlineEditableText({
3251
+ value,
3252
+ onSave,
3253
+ isLoading,
3254
+ placeholder = "Click to edit...",
3255
+ className,
3256
+ multiline = false,
3257
+ maxLength,
3258
+ rows = 2
3259
+ }) {
3260
+ const [isEditing, setIsEditing] = useState(false);
3261
+ const [editValue, setEditValue] = useState(value);
3262
+ const inputRef = useRef(null);
3263
+ const textareaRef = useRef(null);
3264
+ useEffect(() => {
3265
+ setEditValue(value);
3266
+ }, [value]);
3267
+ useEffect(() => {
3268
+ if (isEditing) {
3269
+ if (multiline && textareaRef.current) {
3270
+ textareaRef.current.focus();
3271
+ textareaRef.current.select();
3272
+ } else if (inputRef.current) {
3273
+ inputRef.current.focus();
3274
+ inputRef.current.select();
3275
+ }
3276
+ }
3277
+ }, [isEditing, multiline]);
3278
+ const handleSave = () => {
3279
+ const trimmedValue = editValue.trim();
3280
+ if (trimmedValue !== value) {
3281
+ onSave(trimmedValue);
3282
+ }
3283
+ setIsEditing(false);
3284
+ };
3285
+ const handleCancel = () => {
3286
+ setEditValue(value);
3287
+ setIsEditing(false);
3288
+ };
3289
+ const handleKeyDown = (e) => {
3290
+ if (e.key === "Enter" && !e.shiftKey) {
3291
+ e.preventDefault();
3292
+ handleSave();
3293
+ } else if (e.key === "Escape") {
3294
+ handleCancel();
3295
+ }
3296
+ };
3297
+ if (isEditing) {
3298
+ if (multiline) {
3299
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1 w-full", children: [
3300
+ /* @__PURE__ */ jsx(
3301
+ "textarea",
3302
+ {
3303
+ ref: textareaRef,
3304
+ value: editValue,
3305
+ onChange: (e) => setEditValue(e.target.value),
3306
+ onKeyDown: handleKeyDown,
3307
+ onBlur: handleSave,
3308
+ disabled: isLoading,
3309
+ className: cn(
3310
+ "flex-1 bg-transparent border-none outline-none resize-none",
3311
+ "text-muted-foreground focus:text-foreground min-h-[40px]",
3312
+ "border-b border-dashed border-primary/50 focus:border-primary",
3313
+ className
3314
+ ),
3315
+ placeholder,
3316
+ rows
3317
+ }
3318
+ ),
3319
+ isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground mt-1" })
3320
+ ] });
3321
+ }
3322
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
3323
+ /* @__PURE__ */ jsx(
3324
+ "input",
3325
+ {
3326
+ ref: inputRef,
3327
+ value: editValue,
3328
+ onChange: (e) => setEditValue(e.target.value),
3329
+ onKeyDown: handleKeyDown,
3330
+ onBlur: handleSave,
3331
+ disabled: isLoading,
3332
+ maxLength,
3333
+ className: cn(
3334
+ "bg-transparent border-none outline-none",
3335
+ "border-b border-dashed border-primary/50 focus:border-primary",
3336
+ className
3337
+ ),
3338
+ placeholder,
3339
+ style: {
3340
+ width: `${Math.max(editValue.length, placeholder.length) + 2}ch`
3341
+ }
3342
+ }
3343
+ ),
3344
+ isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" })
3345
+ ] });
3346
+ }
3347
+ return /* @__PURE__ */ jsx(
3348
+ "button",
3349
+ {
3350
+ type: "button",
3351
+ onClick: () => setIsEditing(true),
3352
+ className: cn(
3353
+ "text-left hover:text-primary transition-colors cursor-pointer",
3354
+ "border-b border-transparent hover:border-dashed hover:border-primary/30",
3355
+ !value && "text-muted-foreground/60 italic text-sm",
3356
+ className
3357
+ ),
3358
+ children: value || placeholder
3359
+ }
3360
+ );
3361
+ }
3362
+ function InlineEditableDate({
3363
+ value,
3364
+ onSave,
3365
+ isLoading,
3366
+ placeholder = "Select date...",
3367
+ className,
3368
+ formatDisplay
3369
+ }) {
3370
+ const [isEditing, setIsEditing] = useState(false);
3371
+ const handleDateChange = (date) => {
3372
+ if (date) {
3373
+ const newValue = date.toISOString().split("T")[0];
3374
+ if (newValue !== value) {
3375
+ onSave(newValue);
3376
+ }
3377
+ }
3378
+ setIsEditing(false);
3379
+ };
3380
+ const displayDate = () => {
3381
+ if (!value) return placeholder;
3382
+ const date = new Date(value);
3383
+ if (formatDisplay) return formatDisplay(date);
3384
+ return date.toLocaleDateString();
3385
+ };
3386
+ if (isEditing) {
3387
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
3388
+ /* @__PURE__ */ jsx(
3389
+ DatePicker,
3390
+ {
3391
+ value: value ? new Date(value) : void 0,
3392
+ onChange: handleDateChange
3393
+ }
3394
+ ),
3395
+ isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }),
3396
+ /* @__PURE__ */ jsx(
3397
+ Button,
3398
+ {
3399
+ variant: "ghost",
3400
+ size: "icon",
3401
+ className: "h-6 w-6 hover:bg-transparent hover:text-primary",
3402
+ onClick: () => setIsEditing(false),
3403
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
3404
+ }
3405
+ )
3406
+ ] });
3407
+ }
3408
+ return /* @__PURE__ */ jsxs(
3409
+ "button",
3410
+ {
3411
+ type: "button",
3412
+ onClick: () => setIsEditing(true),
3413
+ className: cn(
3414
+ "flex items-center gap-1 text-sm text-muted-foreground",
3415
+ "hover:text-foreground transition-colors cursor-pointer",
3416
+ className
3417
+ ),
3418
+ children: [
3419
+ /* @__PURE__ */ jsx(Calendar, { className: "h-4 w-4" }),
3420
+ displayDate()
3421
+ ]
3422
+ }
3423
+ );
3424
+ }
3425
+ function InlineEditableSelect({
3653
3426
  value,
3427
+ options,
3654
3428
  onSave,
3655
3429
  isLoading,
3656
- placeholder = "Click to edit...",
3657
- className,
3658
- multiline = false,
3659
- maxLength,
3660
- rows = 2
3430
+ placeholder = "Select...",
3431
+ className
3661
3432
  }) {
3662
3433
  const [isEditing, setIsEditing] = useState(false);
3663
- const [editValue, setEditValue] = useState(value);
3664
- const inputRef = useRef(null);
3665
- const textareaRef = useRef(null);
3666
- useEffect(() => {
3667
- setEditValue(value);
3668
- }, [value]);
3434
+ const selectRef = useRef(null);
3669
3435
  useEffect(() => {
3670
- if (isEditing) {
3671
- if (multiline && textareaRef.current) {
3672
- textareaRef.current.focus();
3673
- textareaRef.current.select();
3674
- } else if (inputRef.current) {
3675
- inputRef.current.focus();
3676
- inputRef.current.select();
3677
- }
3436
+ if (isEditing && selectRef.current) {
3437
+ selectRef.current.focus();
3678
3438
  }
3679
- }, [isEditing, multiline]);
3680
- const handleSave = () => {
3681
- const trimmedValue = editValue.trim();
3682
- if (trimmedValue !== value) {
3683
- onSave(trimmedValue);
3439
+ }, [isEditing]);
3440
+ const handleChange = (e) => {
3441
+ const selectedValue = e.target.value;
3442
+ if (selectedValue !== value) {
3443
+ onSave(selectedValue);
3684
3444
  }
3685
3445
  setIsEditing(false);
3686
3446
  };
3687
- const handleCancel = () => {
3688
- setEditValue(value);
3447
+ const handleBlur = () => {
3689
3448
  setIsEditing(false);
3690
3449
  };
3691
3450
  const handleKeyDown = (e) => {
3692
- if (e.key === "Enter" && !e.shiftKey) {
3693
- e.preventDefault();
3694
- handleSave();
3695
- } else if (e.key === "Escape") {
3696
- handleCancel();
3451
+ if (e.key === "Escape") {
3452
+ setIsEditing(false);
3697
3453
  }
3698
3454
  };
3455
+ const currentLabel = options.find((opt) => opt.value === value)?.label || placeholder;
3699
3456
  if (isEditing) {
3700
- if (multiline) {
3701
- return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1 w-full", children: [
3457
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
3458
+ /* @__PURE__ */ jsx(
3459
+ "select",
3460
+ {
3461
+ ref: selectRef,
3462
+ value,
3463
+ onChange: handleChange,
3464
+ onBlur: handleBlur,
3465
+ onKeyDown: handleKeyDown,
3466
+ disabled: isLoading,
3467
+ className: cn(
3468
+ "bg-transparent border-none outline-none cursor-pointer",
3469
+ "border-b border-dashed border-primary/50 focus:border-primary",
3470
+ "text-foreground",
3471
+ className
3472
+ ),
3473
+ children: options.map((option) => /* @__PURE__ */ jsx("option", { value: String(option.value), children: option.label }, String(option.value)))
3474
+ }
3475
+ ),
3476
+ isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" })
3477
+ ] });
3478
+ }
3479
+ return /* @__PURE__ */ jsx(
3480
+ "button",
3481
+ {
3482
+ type: "button",
3483
+ onClick: () => setIsEditing(true),
3484
+ className: cn(
3485
+ "text-left hover:text-primary transition-colors cursor-pointer",
3486
+ "border-b border-transparent hover:border-dashed hover:border-primary/30",
3487
+ !value && "text-muted-foreground/60 italic text-sm",
3488
+ className
3489
+ ),
3490
+ children: currentLabel
3491
+ }
3492
+ );
3493
+ }
3494
+ var sizeClasses = {
3495
+ sm: {
3496
+ wrapper: "h-7",
3497
+ button: "h-7 w-7",
3498
+ input: "h-7 w-12 text-xs",
3499
+ icon: "h-3 w-3"
3500
+ },
3501
+ md: {
3502
+ wrapper: "h-8",
3503
+ button: "h-8 w-8",
3504
+ input: "h-8 w-14 text-sm",
3505
+ icon: "h-3.5 w-3.5"
3506
+ },
3507
+ lg: {
3508
+ wrapper: "h-10",
3509
+ button: "h-10 w-10",
3510
+ input: "h-10 w-16 text-base",
3511
+ icon: "h-4 w-4"
3512
+ }
3513
+ };
3514
+ function NumberStepper({
3515
+ value,
3516
+ onChange,
3517
+ min = 0,
3518
+ max = Number.MAX_SAFE_INTEGER,
3519
+ step = 1,
3520
+ size = "md",
3521
+ disabled,
3522
+ className,
3523
+ ...props
3524
+ }) {
3525
+ const sizes = sizeClasses[size];
3526
+ const [inputValue, setInputValue] = React.useState(value.toString());
3527
+ const [isFocused, setIsFocused] = React.useState(false);
3528
+ React.useEffect(() => {
3529
+ if (!isFocused) {
3530
+ setInputValue(value.toString());
3531
+ }
3532
+ }, [value, isFocused]);
3533
+ const handleDecrement = () => {
3534
+ const newValue = Math.max(min, value - step);
3535
+ onChange(newValue);
3536
+ setInputValue(newValue.toString());
3537
+ };
3538
+ const handleIncrement = () => {
3539
+ const newValue = Math.min(max, value + step);
3540
+ onChange(newValue);
3541
+ setInputValue(newValue.toString());
3542
+ };
3543
+ const handleInputChange = (e) => {
3544
+ const inputVal = e.target.value;
3545
+ if (inputVal === "" || /^[0-9]*$/.test(inputVal)) {
3546
+ setInputValue(inputVal);
3547
+ }
3548
+ };
3549
+ const handleFocus = () => {
3550
+ setIsFocused(true);
3551
+ };
3552
+ const handleBlur = () => {
3553
+ setIsFocused(false);
3554
+ if (inputValue === "") {
3555
+ onChange(min);
3556
+ setInputValue(min.toString());
3557
+ return;
3558
+ }
3559
+ const numValue = Number.parseInt(inputValue, 10);
3560
+ if (Number.isNaN(numValue)) {
3561
+ onChange(min);
3562
+ setInputValue(min.toString());
3563
+ } else {
3564
+ const clampedValue = Math.min(max, Math.max(min, numValue));
3565
+ onChange(clampedValue);
3566
+ setInputValue(clampedValue.toString());
3567
+ }
3568
+ };
3569
+ const handleKeyDown = (e) => {
3570
+ if (e.key === "ArrowUp") {
3571
+ e.preventDefault();
3572
+ handleIncrement();
3573
+ } else if (e.key === "ArrowDown") {
3574
+ e.preventDefault();
3575
+ handleDecrement();
3576
+ }
3577
+ };
3578
+ const canDecrement = !disabled && value > min;
3579
+ const canIncrement = !disabled && value < max;
3580
+ return /* @__PURE__ */ jsxs(
3581
+ "div",
3582
+ {
3583
+ className: cn(
3584
+ "inline-flex items-center rounded-box border border-input bg-transparent dark:bg-input/30",
3585
+ disabled && "opacity-50",
3586
+ sizes.wrapper,
3587
+ className
3588
+ ),
3589
+ children: [
3590
+ /* @__PURE__ */ jsx(
3591
+ "button",
3592
+ {
3593
+ type: "button",
3594
+ onClick: handleDecrement,
3595
+ disabled: !canDecrement,
3596
+ className: cn(
3597
+ "inline-flex items-center justify-center border-r border-input",
3598
+ "text-muted-foreground hover:text-foreground hover:bg-muted/50",
3599
+ "transition-colors disabled:opacity-50 disabled:pointer-events-none",
3600
+ "rounded-l-md",
3601
+ sizes.button
3602
+ ),
3603
+ tabIndex: -1,
3604
+ "aria-label": "Decrease value",
3605
+ children: /* @__PURE__ */ jsx(Minus, { className: sizes.icon })
3606
+ }
3607
+ ),
3608
+ /* @__PURE__ */ jsx(
3609
+ "input",
3610
+ {
3611
+ type: "text",
3612
+ inputMode: "numeric",
3613
+ pattern: "[0-9]*",
3614
+ value: inputValue,
3615
+ onChange: handleInputChange,
3616
+ onKeyDown: handleKeyDown,
3617
+ onFocus: handleFocus,
3618
+ onBlur: handleBlur,
3619
+ disabled,
3620
+ className: cn(
3621
+ "border-0 bg-transparent text-center focus:outline-none focus:ring-0 selection:bg-primary selection:text-primary-foreground",
3622
+ "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
3623
+ sizes.input
3624
+ ),
3625
+ ...props
3626
+ }
3627
+ ),
3702
3628
  /* @__PURE__ */ jsx(
3703
- "textarea",
3629
+ "button",
3704
3630
  {
3705
- ref: textareaRef,
3706
- value: editValue,
3707
- onChange: (e) => setEditValue(e.target.value),
3708
- onKeyDown: handleKeyDown,
3709
- onBlur: handleSave,
3710
- disabled: isLoading,
3631
+ type: "button",
3632
+ onClick: handleIncrement,
3633
+ disabled: !canIncrement,
3711
3634
  className: cn(
3712
- "flex-1 bg-transparent border-none outline-none resize-none",
3713
- "text-muted-foreground focus:text-foreground min-h-[40px]",
3714
- "border-b border-dashed border-primary/50 focus:border-primary",
3715
- className
3635
+ "inline-flex items-center justify-center border-l border-input",
3636
+ "text-muted-foreground hover:text-foreground hover:bg-muted/50",
3637
+ "transition-colors disabled:opacity-50 disabled:pointer-events-none",
3638
+ "rounded-r-md",
3639
+ sizes.button
3716
3640
  ),
3717
- placeholder,
3718
- rows
3641
+ tabIndex: -1,
3642
+ "aria-label": "Increase value",
3643
+ children: /* @__PURE__ */ jsx(Plus, { className: sizes.icon })
3719
3644
  }
3720
- ),
3721
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground mt-1" })
3722
- ] });
3645
+ )
3646
+ ]
3723
3647
  }
3724
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
3725
- /* @__PURE__ */ jsx(
3726
- "input",
3727
- {
3728
- ref: inputRef,
3729
- value: editValue,
3730
- onChange: (e) => setEditValue(e.target.value),
3731
- onKeyDown: handleKeyDown,
3732
- onBlur: handleSave,
3733
- disabled: isLoading,
3734
- maxLength,
3735
- className: cn(
3736
- "bg-transparent border-none outline-none",
3737
- "border-b border-dashed border-primary/50 focus:border-primary",
3738
- className
3648
+ );
3649
+ }
3650
+ function PageLoader({ className, message, ...props }) {
3651
+ return /* @__PURE__ */ jsxs(
3652
+ "div",
3653
+ {
3654
+ className: cn(
3655
+ "flex flex-col items-center justify-center min-h-[calc(100vh-3.5rem)] gap-3",
3656
+ className
3657
+ ),
3658
+ ...props,
3659
+ children: [
3660
+ /* @__PURE__ */ jsx(SizedSpinner, { size: "lg" }),
3661
+ message && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: message })
3662
+ ]
3663
+ }
3664
+ );
3665
+ }
3666
+ function PageSection({ children, className }) {
3667
+ return /* @__PURE__ */ jsx("div", { className: cn(className), children });
3668
+ }
3669
+ function PageSections({
3670
+ children,
3671
+ separator: defaultSeparator = true,
3672
+ separatorClassName,
3673
+ className
3674
+ }) {
3675
+ const sections = React.Children.toArray(children).filter(
3676
+ React.isValidElement
3677
+ );
3678
+ return /* @__PURE__ */ jsx("div", { className: cn(className), children: sections.map((child, index) => {
3679
+ const isLast = index === sections.length - 1;
3680
+ const showSeparator = child.props.separator ?? defaultSeparator;
3681
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
3682
+ child,
3683
+ !isLast && showSeparator && /* @__PURE__ */ jsx(Separator, { className: cn("w-full", separatorClassName) })
3684
+ ] }, index);
3685
+ }) });
3686
+ }
3687
+ function ProfileSection({
3688
+ title,
3689
+ description,
3690
+ children,
3691
+ icon: Icon,
3692
+ isEditing,
3693
+ onEdit,
3694
+ onCancel,
3695
+ onSave,
3696
+ isSaving,
3697
+ editDisabled,
3698
+ editLabel,
3699
+ action,
3700
+ collapsible = false,
3701
+ defaultCollapsed = false,
3702
+ className,
3703
+ contentClassName,
3704
+ variant = "card"
3705
+ }) {
3706
+ const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
3707
+ const renderActions = () => {
3708
+ if (action) {
3709
+ return action;
3710
+ }
3711
+ if (onEdit) {
3712
+ if (isEditing) {
3713
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
3714
+ onCancel && /* @__PURE__ */ jsx(
3715
+ Button,
3716
+ {
3717
+ variant: "ghost",
3718
+ size: "icon",
3719
+ className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-destructive",
3720
+ onClick: onCancel,
3721
+ disabled: isSaving,
3722
+ "aria-label": "Cancel",
3723
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
3724
+ }
3739
3725
  ),
3740
- placeholder,
3741
- style: {
3742
- width: `${Math.max(editValue.length, placeholder.length) + 2}ch`
3743
- }
3726
+ onSave && /* @__PURE__ */ jsx(
3727
+ Button,
3728
+ {
3729
+ variant: "ghost",
3730
+ size: "icon",
3731
+ className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-green-600",
3732
+ onClick: onSave,
3733
+ disabled: isSaving,
3734
+ "aria-label": "Save",
3735
+ children: isSaving ? /* @__PURE__ */ jsx(SizedSpinner, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
3736
+ }
3737
+ )
3738
+ ] });
3739
+ }
3740
+ return /* @__PURE__ */ jsx(
3741
+ Button,
3742
+ {
3743
+ variant: "ghost",
3744
+ size: "icon",
3745
+ className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-primary",
3746
+ onClick: onEdit,
3747
+ disabled: editDisabled,
3748
+ "aria-label": editLabel ?? `Edit ${title}`,
3749
+ children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
3744
3750
  }
3745
- ),
3746
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" })
3751
+ );
3752
+ }
3753
+ if (collapsible) {
3754
+ return /* @__PURE__ */ jsx(
3755
+ Button,
3756
+ {
3757
+ variant: "ghost",
3758
+ size: "icon",
3759
+ className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent",
3760
+ onClick: () => setIsCollapsed(!isCollapsed),
3761
+ "aria-expanded": !isCollapsed,
3762
+ "aria-label": isCollapsed ? "Expand" : "Collapse",
3763
+ children: /* @__PURE__ */ jsx(
3764
+ ChevronDown,
3765
+ {
3766
+ className: cn(
3767
+ "h-4 w-4 transition-transform duration-200",
3768
+ isCollapsed && "-rotate-90"
3769
+ )
3770
+ }
3771
+ )
3772
+ }
3773
+ );
3774
+ }
3775
+ return null;
3776
+ };
3777
+ if (variant === "simple") {
3778
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
3779
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [
3780
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
3781
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-muted-foreground" }),
3782
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold tracking-tight", children: title })
3783
+ ] }),
3784
+ renderActions()
3785
+ ] }),
3786
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground px-1", children: description }),
3787
+ (!collapsible || !isCollapsed) && /* @__PURE__ */ jsx("div", { className: contentClassName, children })
3747
3788
  ] });
3748
3789
  }
3749
- return /* @__PURE__ */ jsx(
3750
- "button",
3790
+ return /* @__PURE__ */ jsxs(Card, { className, children: [
3791
+ /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between space-y-0 pb-2", children: [
3792
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
3793
+ /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2", children: [
3794
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "size-5" }),
3795
+ title
3796
+ ] }),
3797
+ description && /* @__PURE__ */ jsx(CardDescription, { children: description })
3798
+ ] }),
3799
+ renderActions()
3800
+ ] }),
3801
+ (!collapsible || !isCollapsed) && /* @__PURE__ */ jsx(CardContent, { className: contentClassName, children })
3802
+ ] });
3803
+ }
3804
+ var spacingClasses = {
3805
+ sm: "py-8",
3806
+ // 32px
3807
+ md: "py-16",
3808
+ // 64px
3809
+ lg: "py-24",
3810
+ // 96px
3811
+ xl: "py-32"
3812
+ // 128px
3813
+ };
3814
+ var Section = React.forwardRef(
3815
+ ({
3816
+ className,
3817
+ spacing: spacing2 = "md",
3818
+ as: Component = "section",
3819
+ children,
3820
+ ...props
3821
+ }, ref) => {
3822
+ return /* @__PURE__ */ jsx(
3823
+ Component,
3824
+ {
3825
+ ref,
3826
+ className: cn(spacingClasses[spacing2], className),
3827
+ ...props,
3828
+ children
3829
+ }
3830
+ );
3831
+ }
3832
+ );
3833
+ Section.displayName = "Section";
3834
+ function formatTrendValue(value, isPercentage = true) {
3835
+ const sign = value >= 0 ? "+" : "";
3836
+ return isPercentage ? `${sign}${value}%` : `${sign}${value}`;
3837
+ }
3838
+ function formatStatValue(value, format, options) {
3839
+ if (typeof value === "string") {
3840
+ return value;
3841
+ }
3842
+ const num = value;
3843
+ switch (format) {
3844
+ case "currency":
3845
+ return new Intl.NumberFormat("en-US", {
3846
+ style: "currency",
3847
+ currency: options?.currencyCode ?? "USD",
3848
+ minimumFractionDigits: 0,
3849
+ maximumFractionDigits: num >= 1e3 ? 0 : 2
3850
+ }).format(num);
3851
+ case "percent":
3852
+ return new Intl.NumberFormat("en-US", {
3853
+ style: "percent",
3854
+ minimumFractionDigits: 0,
3855
+ maximumFractionDigits: options?.percentDecimals ?? 1
3856
+ }).format(num / 100);
3857
+ case "compact":
3858
+ return new Intl.NumberFormat("en-US", {
3859
+ notation: "compact",
3860
+ compactDisplay: "short",
3861
+ maximumFractionDigits: 1
3862
+ }).format(num);
3863
+ case "number":
3864
+ if (Math.abs(num) >= 1e6) {
3865
+ return new Intl.NumberFormat("en-US", {
3866
+ notation: "compact",
3867
+ compactDisplay: "short",
3868
+ maximumFractionDigits: 1
3869
+ }).format(num);
3870
+ }
3871
+ return new Intl.NumberFormat("en-US").format(num);
3872
+ default:
3873
+ return String(value);
3874
+ }
3875
+ }
3876
+ function TrendBadge({ trend }) {
3877
+ const Icon = trend.direction === "up" ? TrendingUp : trend.direction === "down" ? TrendingDown : null;
3878
+ const colorClass = trend.direction === "up" ? "text-emerald-600 dark:text-emerald-400" : trend.direction === "down" ? "text-destructive" : "text-muted-foreground";
3879
+ return /* @__PURE__ */ jsxs(
3880
+ Badge,
3751
3881
  {
3752
- type: "button",
3753
- onClick: () => setIsEditing(true),
3754
- className: cn(
3755
- "text-left hover:text-primary transition-colors cursor-pointer",
3756
- "border-b border-transparent hover:border-dashed hover:border-primary/30",
3757
- !value && "text-muted-foreground/60 italic text-sm",
3758
- className
3759
- ),
3760
- children: value || placeholder
3882
+ variant: "outline",
3883
+ className: cn("gap-1 rounded-md text-xs", colorClass),
3884
+ children: [
3885
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "size-3" }),
3886
+ formatTrendValue(trend.value, trend.isPercentage ?? true)
3887
+ ]
3761
3888
  }
3762
3889
  );
3763
3890
  }
3764
- function InlineEditableDate({
3765
- value,
3766
- onSave,
3767
- isLoading,
3768
- placeholder = "Select date...",
3769
- className,
3770
- formatDisplay
3891
+ function StatCardValueContent({
3892
+ isCompact,
3893
+ displayValue,
3894
+ description,
3895
+ trend,
3896
+ footer
3771
3897
  }) {
3772
- const [isEditing, setIsEditing] = useState(false);
3773
- const handleDateChange = (date) => {
3774
- if (date) {
3775
- const newValue = date.toISOString().split("T")[0];
3776
- if (newValue !== value) {
3777
- onSave(newValue);
3778
- }
3779
- }
3780
- setIsEditing(false);
3781
- };
3782
- const displayDate = () => {
3783
- if (!value) return placeholder;
3784
- const date = new Date(value);
3785
- if (formatDisplay) return formatDisplay(date);
3786
- return date.toLocaleDateString();
3787
- };
3788
- if (isEditing) {
3789
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
3790
- /* @__PURE__ */ jsx(
3791
- DatePicker,
3792
- {
3793
- value: value ? new Date(value) : void 0,
3794
- onChange: handleDateChange
3795
- }
3796
- ),
3797
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }),
3798
- /* @__PURE__ */ jsx(
3799
- Button,
3800
- {
3801
- variant: "ghost",
3802
- size: "icon",
3803
- className: "h-6 w-6 hover:bg-transparent hover:text-primary",
3804
- onClick: () => setIsEditing(false),
3805
- children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
3806
- }
3807
- )
3898
+ if (isCompact) {
3899
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3900
+ /* @__PURE__ */ jsx("div", { className: "mt-2 min-w-0", children: /* @__PURE__ */ jsx("span", { className: "block text-2xl md:text-3xl font-semibold tracking-tight tabular-nums leading-none md:leading-tight truncate", children: displayValue }) }),
3901
+ (description || trend) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-center gap-2 min-w-0", children: [
3902
+ trend && /* @__PURE__ */ jsx(TrendBadge, { trend }),
3903
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate", children: description })
3904
+ ] }),
3905
+ trend?.label && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: trend.label }),
3906
+ footer && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: footer })
3808
3907
  ] });
3809
3908
  }
3909
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
3910
+ /* @__PURE__ */ jsx("div", { className: "relative overflow-hidden", children: /* @__PURE__ */ jsx("span", { className: "block text-7xl md:text-8xl font-black tabular-nums leading-none tracking-tighter text-foreground/10 truncate", children: displayValue }) }),
3911
+ (description || trend) && /* @__PURE__ */ jsxs("div", { className: "-mt-6 flex items-center gap-2 min-w-0", children: [
3912
+ trend && /* @__PURE__ */ jsx(TrendBadge, { trend }),
3913
+ description && /* @__PURE__ */ jsx("p", { className: "text-xs text-foreground/80 truncate", children: description })
3914
+ ] }),
3915
+ footer && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: footer }),
3916
+ trend?.label && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: trend.label })
3917
+ ] });
3918
+ }
3919
+ function FlipIndicator({ activeSide }) {
3810
3920
  return /* @__PURE__ */ jsxs(
3811
- "button",
3921
+ "div",
3812
3922
  {
3813
- type: "button",
3814
- onClick: () => setIsEditing(true),
3815
- className: cn(
3816
- "flex items-center gap-1 text-sm text-muted-foreground",
3817
- "hover:text-foreground transition-colors cursor-pointer",
3818
- className
3819
- ),
3923
+ className: "absolute bottom-2 left-1/2 -translate-x-1/2 flex items-center gap-1.5 z-10 pointer-events-none",
3924
+ "aria-hidden": "true",
3820
3925
  children: [
3821
- /* @__PURE__ */ jsx(Calendar, { className: "h-4 w-4" }),
3822
- displayDate()
3926
+ /* @__PURE__ */ jsx(
3927
+ "span",
3928
+ {
3929
+ className: cn(
3930
+ "h-1.5 w-1.5 rounded-full transition-colors",
3931
+ activeSide === "stat" ? "bg-foreground/60" : "bg-foreground/20"
3932
+ )
3933
+ }
3934
+ ),
3935
+ /* @__PURE__ */ jsx(
3936
+ "span",
3937
+ {
3938
+ className: cn(
3939
+ "h-1.5 w-1.5 rounded-full transition-colors",
3940
+ activeSide === "chart" ? "bg-foreground/60" : "bg-foreground/20"
3941
+ )
3942
+ }
3943
+ )
3823
3944
  ]
3824
3945
  }
3825
3946
  );
3826
3947
  }
3827
- function InlineEditableSelect({
3948
+ function MiniChart({ data, type = "area", periodLabel }) {
3949
+ if (!data || data.length === 0) return null;
3950
+ const values = data.map((d) => d.value);
3951
+ const maxValue = Math.max(...values);
3952
+ const minValue = Math.min(...values);
3953
+ const range = maxValue - minValue || 1;
3954
+ const width = 100;
3955
+ const height = 40;
3956
+ const paddingX = 0;
3957
+ const paddingY = 4;
3958
+ const points = data.map((d, i) => {
3959
+ const normalizedX = data.length > 1 ? i / (data.length - 1) : 0.5;
3960
+ const x = paddingX + normalizedX * (width - paddingX * 2);
3961
+ const y = height - paddingY - (d.value - minValue) / range * (height - paddingY * 2);
3962
+ return { x, y, ...d };
3963
+ });
3964
+ const createSmoothPath = (pts) => {
3965
+ if (pts.length < 2) return "";
3966
+ let path = `M ${pts[0].x} ${pts[0].y}`;
3967
+ for (let i = 0; i < pts.length - 1; i++) {
3968
+ const p0 = pts[Math.max(0, i - 1)];
3969
+ const p1 = pts[i];
3970
+ const p2 = pts[i + 1];
3971
+ const p3 = pts[Math.min(pts.length - 1, i + 2)];
3972
+ const tension = 0.3;
3973
+ const cp1x = p1.x + (p2.x - p0.x) * tension;
3974
+ const cp1y = p1.y + (p2.y - p0.y) * tension;
3975
+ const cp2x = p2.x - (p3.x - p1.x) * tension;
3976
+ const cp2y = p2.y - (p3.y - p1.y) * tension;
3977
+ path += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
3978
+ }
3979
+ return path;
3980
+ };
3981
+ const smoothPath = createSmoothPath(points);
3982
+ const areaPath = `${smoothPath} L ${points[points.length - 1].x} ${height} L ${points[0].x} ${height} Z`;
3983
+ const barWidth = (width - paddingX * 2) / data.length - 2;
3984
+ const gradientId = `miniChartGradient-${Math.random().toString(36).substring(2, 11)}`;
3985
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full justify-center px-1", children: [
3986
+ periodLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-2", children: periodLabel }),
3987
+ /* @__PURE__ */ jsxs(
3988
+ "svg",
3989
+ {
3990
+ viewBox: `0 0 ${width} ${height}`,
3991
+ className: "w-full h-20",
3992
+ preserveAspectRatio: "none",
3993
+ "aria-label": "Chart showing trend data",
3994
+ role: "img",
3995
+ children: [
3996
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
3997
+ /* @__PURE__ */ jsx(
3998
+ "stop",
3999
+ {
4000
+ offset: "5%",
4001
+ className: "[stop-color:hsl(var(--primary))]",
4002
+ stopOpacity: 0.8
4003
+ }
4004
+ ),
4005
+ /* @__PURE__ */ jsx(
4006
+ "stop",
4007
+ {
4008
+ offset: "95%",
4009
+ className: "[stop-color:hsl(var(--primary))]",
4010
+ stopOpacity: 0.1
4011
+ }
4012
+ )
4013
+ ] }) }),
4014
+ type === "bar" ? (
4015
+ // Bar chart
4016
+ /* @__PURE__ */ jsx("g", { children: points.map((p, i) => /* @__PURE__ */ jsx(
4017
+ "rect",
4018
+ {
4019
+ x: paddingX + i * (width - paddingX * 2) / data.length + 1,
4020
+ y: p.y,
4021
+ width: barWidth,
4022
+ height: height - p.y,
4023
+ className: "fill-primary/30",
4024
+ rx: 1
4025
+ },
4026
+ p.label
4027
+ )) })
4028
+ ) : (
4029
+ // Line/Area chart - matching NewUsersChart style
4030
+ /* @__PURE__ */ jsxs("g", { children: [
4031
+ type === "area" && /* @__PURE__ */ jsx("path", { d: areaPath, fill: `url(#${gradientId})` }),
4032
+ /* @__PURE__ */ jsx(
4033
+ "path",
4034
+ {
4035
+ d: smoothPath,
4036
+ fill: "none",
4037
+ className: "stroke-primary",
4038
+ strokeWidth: 1.5,
4039
+ strokeLinecap: "round",
4040
+ strokeLinejoin: "round"
4041
+ }
4042
+ )
4043
+ ] })
4044
+ )
4045
+ ]
4046
+ }
4047
+ ),
4048
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-[10px] text-muted-foreground mt-1", children: [
4049
+ /* @__PURE__ */ jsx("span", { children: data[0]?.label }),
4050
+ /* @__PURE__ */ jsx("span", { children: data[data.length - 1]?.label })
4051
+ ] })
4052
+ ] });
4053
+ }
4054
+ function StatCard({
4055
+ title,
3828
4056
  value,
3829
- options,
3830
- onSave,
3831
- isLoading,
3832
- placeholder = "Select...",
3833
- className
4057
+ description,
4058
+ footer,
4059
+ icon,
4060
+ trend,
4061
+ variant = "default",
4062
+ className,
4063
+ size = "default",
4064
+ format,
4065
+ currencyCode,
4066
+ percentDecimals,
4067
+ formatValue = false,
4068
+ onClick,
4069
+ href,
4070
+ chart,
4071
+ defaultSide = "stat"
3834
4072
  }) {
3835
- const [isEditing, setIsEditing] = useState(false);
3836
- const selectRef = useRef(null);
3837
- useEffect(() => {
3838
- if (isEditing && selectRef.current) {
3839
- selectRef.current.focus();
3840
- }
3841
- }, [isEditing]);
3842
- const handleChange = (e) => {
3843
- const selectedValue = e.target.value;
3844
- if (selectedValue !== value) {
3845
- onSave(selectedValue);
3846
- }
3847
- setIsEditing(false);
4073
+ const [activeSide, setActiveSide] = useState(defaultSide);
4074
+ const effectiveFormat = format ?? (formatValue ? "number" : typeof value === "number" ? "number" : "none");
4075
+ const displayValue = formatStatValue(value, effectiveFormat, {
4076
+ currencyCode,
4077
+ percentDecimals
4078
+ });
4079
+ const variantStyles = {
4080
+ default: "",
4081
+ muted: "bg-linear-to-t from-muted/60 to-muted/20 hover:from-muted/70 hover:to-muted/30 transition-colors",
4082
+ gradient: "bg-gradient-to-t from-primary/5 to-card dark:bg-card",
4083
+ outline: "border-2"
3848
4084
  };
3849
- const handleBlur = () => {
3850
- setIsEditing(false);
4085
+ const isInteractive = onClick || href;
4086
+ const hasChart = !!chart;
4087
+ const isCompact = size === "compact";
4088
+ const handleFlip = () => {
4089
+ setActiveSide((prev) => prev === "stat" ? "chart" : "stat");
3851
4090
  };
3852
- const handleKeyDown = (e) => {
3853
- if (e.key === "Escape") {
3854
- setIsEditing(false);
4091
+ const handleBodyClick = (e) => {
4092
+ e.stopPropagation();
4093
+ if (hasChart) {
4094
+ handleFlip();
4095
+ } else if (onClick) {
4096
+ onClick();
3855
4097
  }
3856
4098
  };
3857
- const currentLabel = options.find((opt) => opt.value === value)?.label || placeholder;
3858
- if (isEditing) {
3859
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
3860
- /* @__PURE__ */ jsx(
3861
- "select",
3862
- {
3863
- ref: selectRef,
3864
- value,
3865
- onChange: handleChange,
3866
- onBlur: handleBlur,
3867
- onKeyDown: handleKeyDown,
3868
- disabled: isLoading,
3869
- className: cn(
3870
- "bg-transparent border-none outline-none cursor-pointer",
3871
- "border-b border-dashed border-primary/50 focus:border-primary",
3872
- "text-foreground",
3873
- className
3874
- ),
3875
- children: options.map((option) => /* @__PURE__ */ jsx("option", { value: String(option.value), children: option.label }, String(option.value)))
3876
- }
3877
- ),
3878
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" })
3879
- ] });
3880
- }
3881
- return /* @__PURE__ */ jsx(
3882
- "button",
4099
+ const handleHeaderClick = (e) => {
4100
+ e.stopPropagation();
4101
+ if (href) {
4102
+ return;
4103
+ }
4104
+ if (onClick) {
4105
+ onClick();
4106
+ } else if (hasChart) {
4107
+ handleFlip();
4108
+ }
4109
+ };
4110
+ const cardBaseStyles = cn(
4111
+ "h-full relative overflow-hidden gap-0",
4112
+ isCompact ? "min-h-[112px] p-3 md:min-h-[120px] md:p-4" : "py-3",
4113
+ variantStyles[variant],
4114
+ hasChart && "pb-6"
4115
+ );
4116
+ const renderHeader = (showIcon = true) => /* @__PURE__ */ jsxs(
4117
+ CardHeader,
3883
4118
  {
3884
- type: "button",
3885
- onClick: () => setIsEditing(true),
3886
4119
  className: cn(
3887
- "text-left hover:text-primary transition-colors cursor-pointer",
3888
- "border-b border-transparent hover:border-dashed hover:border-primary/30",
3889
- !value && "text-muted-foreground/60 italic text-sm",
3890
- className
4120
+ "flex flex-row items-center justify-between space-y-0 py-0",
4121
+ isCompact ? "px-0" : "px-4"
3891
4122
  ),
3892
- children: currentLabel
4123
+ children: [
4124
+ href ? /* @__PURE__ */ jsxs(
4125
+ "a",
4126
+ {
4127
+ href,
4128
+ className: "flex items-center gap-2 hover:text-primary transition-colors z-10",
4129
+ onClick: (e) => e.stopPropagation(),
4130
+ children: [
4131
+ /* @__PURE__ */ jsx(
4132
+ CardTitle,
4133
+ {
4134
+ className: cn(
4135
+ isCompact ? "text-xs md:text-sm font-medium text-muted-foreground" : "text-sm font-medium"
4136
+ ),
4137
+ children: title
4138
+ }
4139
+ ),
4140
+ /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-4 w-4 opacity-0 group-hover:opacity-100 transition-opacity" })
4141
+ ]
4142
+ }
4143
+ ) : /* @__PURE__ */ jsx(
4144
+ CardTitle,
4145
+ {
4146
+ className: cn(
4147
+ isCompact ? "text-xs md:text-sm font-medium text-muted-foreground" : "text-sm font-medium",
4148
+ "flex items-center gap-2",
4149
+ onClick && "cursor-pointer hover:text-primary transition-colors"
4150
+ ),
4151
+ onClick: handleHeaderClick,
4152
+ children: title
4153
+ }
4154
+ ),
4155
+ showIcon && icon && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: icon })
4156
+ ]
3893
4157
  }
3894
4158
  );
3895
- }
3896
- var sizeClasses = {
3897
- sm: {
3898
- wrapper: "h-7",
3899
- button: "h-7 w-7",
3900
- input: "h-7 w-12 text-xs",
3901
- icon: "h-3 w-3"
3902
- },
3903
- md: {
3904
- wrapper: "h-8",
3905
- button: "h-8 w-8",
3906
- input: "h-8 w-14 text-sm",
3907
- icon: "h-3.5 w-3.5"
3908
- },
3909
- lg: {
3910
- wrapper: "h-10",
3911
- button: "h-10 w-10",
3912
- input: "h-10 w-16 text-base",
3913
- icon: "h-4 w-4"
4159
+ if (!hasChart) {
4160
+ return /* @__PURE__ */ jsxs(
4161
+ Card,
4162
+ {
4163
+ className: cn(
4164
+ cardBaseStyles,
4165
+ "group",
4166
+ isInteractive && "cursor-pointer transition-colors hover:border-primary/50",
4167
+ className
4168
+ ),
4169
+ onClick,
4170
+ children: [
4171
+ renderHeader(),
4172
+ /* @__PURE__ */ jsx(
4173
+ CardContent,
4174
+ {
4175
+ className: cn("relative py-0", isCompact ? "px-0" : "px-4"),
4176
+ children: /* @__PURE__ */ jsx(
4177
+ StatCardValueContent,
4178
+ {
4179
+ isCompact,
4180
+ displayValue,
4181
+ description,
4182
+ trend,
4183
+ footer
4184
+ }
4185
+ )
4186
+ }
4187
+ )
4188
+ ]
4189
+ }
4190
+ );
3914
4191
  }
3915
- };
3916
- function NumberStepper({
3917
- value,
3918
- onChange,
3919
- min = 0,
3920
- max = Number.MAX_SAFE_INTEGER,
3921
- step = 1,
3922
- size = "md",
3923
- disabled,
3924
- className,
3925
- ...props
3926
- }) {
3927
- const sizes = sizeClasses[size];
3928
- const [inputValue, setInputValue] = React.useState(value.toString());
3929
- const [isFocused, setIsFocused] = React.useState(false);
3930
- React.useEffect(() => {
3931
- if (!isFocused) {
3932
- setInputValue(value.toString());
3933
- }
3934
- }, [value, isFocused]);
3935
- const handleDecrement = () => {
3936
- const newValue = Math.max(min, value - step);
3937
- onChange(newValue);
3938
- setInputValue(newValue.toString());
3939
- };
3940
- const handleIncrement = () => {
3941
- const newValue = Math.min(max, value + step);
3942
- onChange(newValue);
3943
- setInputValue(newValue.toString());
3944
- };
3945
- const handleInputChange = (e) => {
3946
- const inputVal = e.target.value;
3947
- if (inputVal === "" || /^[0-9]*$/.test(inputVal)) {
3948
- setInputValue(inputVal);
4192
+ return /* @__PURE__ */ jsx(
4193
+ "div",
4194
+ {
4195
+ className: cn("group h-full min-h-[160px]", className),
4196
+ style: { perspective: "1000px" },
4197
+ children: /* @__PURE__ */ jsxs(
4198
+ "button",
4199
+ {
4200
+ type: "button",
4201
+ className: cn(
4202
+ "relative h-full w-full transition-transform duration-500 cursor-pointer text-left",
4203
+ "[transform-style:preserve-3d]",
4204
+ activeSide === "chart" && "[transform:rotateY(180deg)]"
4205
+ ),
4206
+ onClick: handleBodyClick,
4207
+ "aria-label": activeSide === "chart" ? "Show statistic view" : "Show chart view",
4208
+ "aria-pressed": activeSide === "chart",
4209
+ children: [
4210
+ /* @__PURE__ */ jsxs(
4211
+ Card,
4212
+ {
4213
+ className: cn(
4214
+ cardBaseStyles,
4215
+ "absolute inset-0 [backface-visibility:hidden] [transform-style:preserve-3d] [transform:rotateY(0deg)]",
4216
+ "transition-colors hover:border-primary/50"
4217
+ ),
4218
+ children: [
4219
+ renderHeader(),
4220
+ /* @__PURE__ */ jsx(
4221
+ CardContent,
4222
+ {
4223
+ className: cn("relative py-0", isCompact ? "px-0" : "px-4"),
4224
+ children: /* @__PURE__ */ jsx(
4225
+ StatCardValueContent,
4226
+ {
4227
+ isCompact,
4228
+ displayValue,
4229
+ description,
4230
+ trend,
4231
+ footer
4232
+ }
4233
+ )
4234
+ }
4235
+ ),
4236
+ /* @__PURE__ */ jsx(FlipIndicator, { activeSide })
4237
+ ]
4238
+ }
4239
+ ),
4240
+ /* @__PURE__ */ jsxs(
4241
+ Card,
4242
+ {
4243
+ className: cn(
4244
+ cardBaseStyles,
4245
+ "absolute inset-0 [backface-visibility:hidden] [transform-style:preserve-3d] [transform:rotateY(180deg)]",
4246
+ "transition-colors hover:border-primary/50"
4247
+ ),
4248
+ children: [
4249
+ renderHeader(false),
4250
+ /* @__PURE__ */ jsx(CardContent, { className: "relative px-4 py-0 h-full", children: /* @__PURE__ */ jsx(MiniChart, { ...chart }) }),
4251
+ /* @__PURE__ */ jsx(FlipIndicator, { activeSide })
4252
+ ]
4253
+ }
4254
+ )
4255
+ ]
4256
+ }
4257
+ )
3949
4258
  }
4259
+ );
4260
+ }
4261
+ function StatCardsContainer({
4262
+ children,
4263
+ columns = { default: 1, sm: 2, lg: 4 },
4264
+ className
4265
+ }) {
4266
+ const colClasses = {
4267
+ 1: "grid-cols-1",
4268
+ 2: "grid-cols-2",
4269
+ 3: "grid-cols-3",
4270
+ 4: "grid-cols-4"
3950
4271
  };
3951
- const handleFocus = () => {
3952
- setIsFocused(true);
4272
+ const smColClasses = {
4273
+ 1: "sm:grid-cols-1",
4274
+ 2: "sm:grid-cols-2",
4275
+ 3: "sm:grid-cols-3",
4276
+ 4: "sm:grid-cols-4"
3953
4277
  };
3954
- const handleBlur = () => {
3955
- setIsFocused(false);
3956
- if (inputValue === "") {
3957
- onChange(min);
3958
- setInputValue(min.toString());
3959
- return;
3960
- }
3961
- const numValue = Number.parseInt(inputValue, 10);
3962
- if (Number.isNaN(numValue)) {
3963
- onChange(min);
3964
- setInputValue(min.toString());
3965
- } else {
3966
- const clampedValue = Math.min(max, Math.max(min, numValue));
3967
- onChange(clampedValue);
3968
- setInputValue(clampedValue.toString());
3969
- }
4278
+ const mdColClasses = {
4279
+ 1: "md:grid-cols-1",
4280
+ 2: "md:grid-cols-2",
4281
+ 3: "md:grid-cols-3",
4282
+ 4: "md:grid-cols-4"
3970
4283
  };
3971
- const handleKeyDown = (e) => {
3972
- if (e.key === "ArrowUp") {
3973
- e.preventDefault();
3974
- handleIncrement();
3975
- } else if (e.key === "ArrowDown") {
3976
- e.preventDefault();
3977
- handleDecrement();
3978
- }
4284
+ const lgColClasses = {
4285
+ 1: "lg:grid-cols-1",
4286
+ 2: "lg:grid-cols-2",
4287
+ 3: "lg:grid-cols-3",
4288
+ 4: "lg:grid-cols-4"
3979
4289
  };
3980
- const canDecrement = !disabled && value > min;
3981
- const canIncrement = !disabled && value < max;
3982
- return /* @__PURE__ */ jsxs(
4290
+ return /* @__PURE__ */ jsx(
3983
4291
  "div",
3984
4292
  {
3985
4293
  className: cn(
3986
- "inline-flex items-center rounded-box border border-input bg-transparent dark:bg-input/30",
3987
- disabled && "opacity-50",
3988
- sizes.wrapper,
4294
+ "grid gap-4",
4295
+ columns.default && colClasses[columns.default],
4296
+ columns.sm && smColClasses[columns.sm],
4297
+ columns.md && mdColClasses[columns.md],
4298
+ columns.lg && lgColClasses[columns.lg],
3989
4299
  className
3990
4300
  ),
3991
- children: [
3992
- /* @__PURE__ */ jsx(
3993
- "button",
3994
- {
3995
- type: "button",
3996
- onClick: handleDecrement,
3997
- disabled: !canDecrement,
3998
- className: cn(
3999
- "inline-flex items-center justify-center border-r border-input",
4000
- "text-muted-foreground hover:text-foreground hover:bg-muted/50",
4001
- "transition-colors disabled:opacity-50 disabled:pointer-events-none",
4002
- "rounded-l-md",
4003
- sizes.button
4004
- ),
4005
- tabIndex: -1,
4006
- "aria-label": "Decrease value",
4007
- children: /* @__PURE__ */ jsx(Minus, { className: sizes.icon })
4008
- }
4009
- ),
4010
- /* @__PURE__ */ jsx(
4011
- "input",
4012
- {
4013
- type: "text",
4014
- inputMode: "numeric",
4015
- pattern: "[0-9]*",
4016
- value: inputValue,
4017
- onChange: handleInputChange,
4018
- onKeyDown: handleKeyDown,
4019
- onFocus: handleFocus,
4020
- onBlur: handleBlur,
4021
- disabled,
4022
- className: cn(
4023
- "border-0 bg-transparent text-center focus:outline-none focus:ring-0 selection:bg-primary selection:text-primary-foreground",
4024
- "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
4025
- sizes.input
4026
- ),
4027
- ...props
4028
- }
4029
- ),
4030
- /* @__PURE__ */ jsx(
4031
- "button",
4032
- {
4033
- type: "button",
4034
- onClick: handleIncrement,
4035
- disabled: !canIncrement,
4036
- className: cn(
4037
- "inline-flex items-center justify-center border-l border-input",
4038
- "text-muted-foreground hover:text-foreground hover:bg-muted/50",
4039
- "transition-colors disabled:opacity-50 disabled:pointer-events-none",
4040
- "rounded-r-md",
4041
- sizes.button
4042
- ),
4043
- tabIndex: -1,
4044
- "aria-label": "Increase value",
4045
- children: /* @__PURE__ */ jsx(Plus, { className: sizes.icon })
4046
- }
4047
- )
4048
- ]
4301
+ children
4049
4302
  }
4050
4303
  );
4051
4304
  }
4052
- function PageLoader({ className, message, ...props }) {
4053
- return /* @__PURE__ */ jsxs(
4054
- "div",
4305
+ function TextHighlight({
4306
+ children,
4307
+ className,
4308
+ duration = 2,
4309
+ delay = 0.5,
4310
+ gradient = "from-indigo-300 to-purple-300 dark:from-indigo-500 dark:to-purple-500",
4311
+ disableAnimation = false
4312
+ }) {
4313
+ const animationStyle = disableAnimation ? { backgroundSize: "100% 100%" } : {
4314
+ "--highlight-duration": `${duration}s`,
4315
+ "--highlight-delay": `${delay}s`
4316
+ };
4317
+ return /* @__PURE__ */ jsx(
4318
+ "span",
4055
4319
  {
4320
+ "data-slot": "text-highlight",
4321
+ "data-animated": !disableAnimation,
4056
4322
  className: cn(
4057
- "flex flex-col items-center justify-center min-h-[calc(100vh-3.5rem)] gap-3",
4323
+ "relative inline-block rounded-lg bg-gradient-to-r bg-no-repeat px-1 pb-1",
4324
+ !disableAnimation && "text-highlight-animated",
4325
+ gradient,
4058
4326
  className
4059
4327
  ),
4060
- ...props,
4061
- children: [
4062
- /* @__PURE__ */ jsx(Spinner, { size: "lg" }),
4063
- message && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: message })
4064
- ]
4328
+ style: {
4329
+ backgroundPosition: "left center",
4330
+ ...animationStyle
4331
+ },
4332
+ children
4065
4333
  }
4066
4334
  );
4067
4335
  }
4068
- function PageSection({ children, className }) {
4069
- return /* @__PURE__ */ jsx("div", { className: cn(className), children });
4336
+ function TooltipCard({
4337
+ children,
4338
+ className,
4339
+ containerClassName,
4340
+ content,
4341
+ triggerClassName,
4342
+ delayDuration = 150,
4343
+ side = "top",
4344
+ align = "center",
4345
+ sideOffset = 10,
4346
+ ...tooltipProps
4347
+ }) {
4348
+ return /* @__PURE__ */ jsxs(Tooltip, { delayDuration, ...tooltipProps, children: [
4349
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
4350
+ "button",
4351
+ {
4352
+ type: "button",
4353
+ className: cn(
4354
+ "inline cursor-help appearance-none border-0 bg-transparent p-0 align-baseline font-medium text-inherit underline decoration-current/35 underline-offset-4 transition-colors",
4355
+ "hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4356
+ className,
4357
+ triggerClassName
4358
+ ),
4359
+ "data-slot": "tooltip-card-trigger",
4360
+ children
4361
+ }
4362
+ ) }),
4363
+ /* @__PURE__ */ jsx(
4364
+ TooltipContent,
4365
+ {
4366
+ align,
4367
+ className: cn(
4368
+ "max-w-sm rounded-box border border-border bg-popover px-4 py-3 text-popover-foreground shadow-xl",
4369
+ "text-sm leading-6 font-normal",
4370
+ containerClassName
4371
+ ),
4372
+ "data-slot": "tooltip-card-content",
4373
+ side,
4374
+ sideOffset,
4375
+ children: typeof content === "string" ? /* @__PURE__ */ jsx("p", { "data-slot": "tooltip-card-text", children: content }) : content
4376
+ }
4377
+ )
4378
+ ] });
4379
+ }
4380
+ function HelpArticleIndex({ groups, onSelect }) {
4381
+ return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: groups.map((group, index) => /* @__PURE__ */ jsxs("div", { children: [
4382
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
4383
+ group.icon,
4384
+ /* @__PURE__ */ jsx("h3", { className: "font-medium", children: group.title })
4385
+ ] }),
4386
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.articles.map((article) => /* @__PURE__ */ jsxs(
4387
+ "button",
4388
+ {
4389
+ type: "button",
4390
+ onClick: () => onSelect(article.slug),
4391
+ className: "w-full text-left p-2 rounded hover:bg-accent transition-colors flex items-center justify-between group",
4392
+ children: [
4393
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: article.title }),
4394
+ /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
4395
+ ]
4396
+ },
4397
+ article.slug
4398
+ )) })
4399
+ ] }, index)) });
4070
4400
  }
4071
- function PageSections({
4072
- children,
4073
- separator: defaultSeparator = true,
4074
- separatorClassName,
4075
- className
4401
+ function HelpArticleView({
4402
+ article,
4403
+ onNavigate,
4404
+ onBackToIndex,
4405
+ relatedArticles = [],
4406
+ isLoading = false,
4407
+ children
4076
4408
  }) {
4077
- const sections = React.Children.toArray(children).filter(
4078
- React.isValidElement
4079
- );
4080
- return /* @__PURE__ */ jsx("div", { className: cn(className), children: sections.map((child, index) => {
4081
- const isLast = index === sections.length - 1;
4082
- const showSeparator = child.props.separator ?? defaultSeparator;
4083
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
4084
- child,
4085
- !isLast && showSeparator && /* @__PURE__ */ jsx(Separator, { className: cn("w-full", separatorClassName) })
4086
- ] }, index);
4087
- }) });
4409
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
4410
+ /* @__PURE__ */ jsxs("div", { children: [
4411
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground mb-2", children: [
4412
+ /* @__PURE__ */ jsx(
4413
+ "button",
4414
+ {
4415
+ type: "button",
4416
+ onClick: onBackToIndex,
4417
+ className: "capitalize hover:text-foreground hover:underline transition-colors cursor-pointer",
4418
+ children: article.category
4419
+ }
4420
+ ),
4421
+ article.subcategory && /* @__PURE__ */ jsxs(Fragment, { children: [
4422
+ /* @__PURE__ */ jsx(ChevronRight, { className: "size-3" }),
4423
+ /* @__PURE__ */ jsx("span", { className: "capitalize", children: article.subcategory })
4424
+ ] })
4425
+ ] }),
4426
+ /* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold", children: article.title }),
4427
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: article.description })
4428
+ ] }),
4429
+ /* @__PURE__ */ jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none prose-headings:font-semibold prose-a:text-primary hover:prose-a:underline [&>*:first-child]:mt-0", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "flex justify-center py-8", children: /* @__PURE__ */ jsx(SizedSpinner, { className: "size-6" }) }) : children ? children : /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "Failed to load article content. Please try again later." }) }),
4430
+ article.tags && article.tags.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
4431
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Tags" }),
4432
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: article.tags.map((tag) => /* @__PURE__ */ jsx(
4433
+ "span",
4434
+ {
4435
+ className: "inline-flex px-2 py-0.5 text-xs rounded-full bg-muted",
4436
+ children: tag
4437
+ },
4438
+ tag
4439
+ )) })
4440
+ ] }),
4441
+ relatedArticles.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
4442
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Related Articles" }),
4443
+ /* @__PURE__ */ jsx("div", { className: "space-y-2", children: relatedArticles.map((related) => /* @__PURE__ */ jsx(
4444
+ "button",
4445
+ {
4446
+ type: "button",
4447
+ onClick: () => onNavigate(related.slug),
4448
+ className: "w-full text-left p-2 rounded border hover:bg-accent transition-colors text-sm",
4449
+ children: /* @__PURE__ */ jsx("p", { className: "font-medium", children: related.title })
4450
+ },
4451
+ related.slug
4452
+ )) })
4453
+ ] })
4454
+ ] });
4088
4455
  }
4089
- function ProfileSection({
4090
- title,
4091
- description,
4456
+ var HelpContext = createContext(null);
4457
+ function HelpProvider({
4092
4458
  children,
4093
- icon: Icon,
4094
- isEditing,
4095
- onEdit,
4096
- onCancel,
4097
- onSave,
4098
- isSaving,
4099
- editDisabled,
4100
- editLabel,
4101
- action,
4102
- collapsible = false,
4103
- defaultCollapsed = false,
4104
- className,
4105
- contentClassName,
4106
- variant = "card"
4459
+ getArticle,
4460
+ searchArticles,
4461
+ getArticleForFeature,
4462
+ getArticleForRoute,
4463
+ getContextForRoute,
4464
+ pathname,
4465
+ isAdmin = false
4107
4466
  }) {
4108
- const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
4109
- const renderActions = () => {
4110
- if (action) {
4111
- return action;
4467
+ const [isOpen, setIsOpen] = useState(false);
4468
+ const [activeArticleSlug, setActiveArticleSlug] = useState(
4469
+ null
4470
+ );
4471
+ const [searchQuery, setSearchQuery] = useState("");
4472
+ const [history, setHistory] = useState([]);
4473
+ const helpContext = useMemo(
4474
+ () => isAdmin ? "admin" : getContextForRoute(pathname),
4475
+ [isAdmin, pathname, getContextForRoute]
4476
+ );
4477
+ const activeArticle = useMemo(() => {
4478
+ if (!activeArticleSlug) return null;
4479
+ return getArticle(activeArticleSlug);
4480
+ }, [activeArticleSlug, getArticle]);
4481
+ const searchResults = useMemo(() => {
4482
+ if (!searchQuery.trim()) return [];
4483
+ return searchArticles(searchQuery);
4484
+ }, [searchQuery, searchArticles]);
4485
+ const openHelp = useCallback(
4486
+ (articleSlug) => {
4487
+ setIsOpen(true);
4488
+ if (articleSlug) {
4489
+ setActiveArticleSlug(articleSlug);
4490
+ setHistory([]);
4491
+ } else {
4492
+ const contextualSlug = getArticleForRoute(pathname);
4493
+ setActiveArticleSlug(contextualSlug);
4494
+ setHistory([]);
4495
+ }
4496
+ setSearchQuery("");
4497
+ },
4498
+ [pathname, getArticleForRoute]
4499
+ );
4500
+ const closeHelp = useCallback(() => {
4501
+ setIsOpen(false);
4502
+ }, []);
4503
+ const toggleHelp = useCallback(() => {
4504
+ if (isOpen) {
4505
+ closeHelp();
4506
+ } else {
4507
+ openHelp();
4112
4508
  }
4113
- if (onEdit) {
4114
- if (isEditing) {
4115
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
4116
- onCancel && /* @__PURE__ */ jsx(
4117
- Button,
4118
- {
4119
- variant: "ghost",
4120
- size: "icon",
4121
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-destructive",
4122
- onClick: onCancel,
4123
- disabled: isSaving,
4124
- "aria-label": "Cancel",
4125
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
4126
- }
4127
- ),
4128
- onSave && /* @__PURE__ */ jsx(
4129
- Button,
4130
- {
4131
- variant: "ghost",
4132
- size: "icon",
4133
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-green-600",
4134
- onClick: onSave,
4135
- disabled: isSaving,
4136
- "aria-label": "Save",
4137
- children: isSaving ? /* @__PURE__ */ jsx(Spinner, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
4138
- }
4139
- )
4140
- ] });
4509
+ }, [isOpen, openHelp, closeHelp]);
4510
+ const setActiveArticle = useCallback((slug) => {
4511
+ setActiveArticleSlug(slug);
4512
+ setSearchQuery("");
4513
+ }, []);
4514
+ const performSearch = useCallback((query) => {
4515
+ setIsOpen(true);
4516
+ setSearchQuery(query);
4517
+ setActiveArticleSlug(null);
4518
+ }, []);
4519
+ const openFeatureHelp = useCallback(
4520
+ (featureKey) => {
4521
+ const articleSlug = getArticleForFeature(featureKey);
4522
+ if (articleSlug) {
4523
+ setIsOpen(true);
4524
+ setActiveArticleSlug(articleSlug);
4525
+ setHistory([]);
4526
+ setSearchQuery("");
4141
4527
  }
4142
- return /* @__PURE__ */ jsx(
4143
- Button,
4144
- {
4145
- variant: "ghost",
4146
- size: "icon",
4147
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-primary",
4148
- onClick: onEdit,
4149
- disabled: editDisabled,
4150
- "aria-label": editLabel ?? `Edit ${title}`,
4151
- children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
4152
- }
4153
- );
4528
+ },
4529
+ [getArticleForFeature]
4530
+ );
4531
+ const navigateToArticle = useCallback(
4532
+ (slug) => {
4533
+ if (activeArticleSlug && activeArticleSlug !== slug) {
4534
+ setHistory((prev) => [...prev, activeArticleSlug]);
4535
+ }
4536
+ setActiveArticleSlug(slug);
4537
+ setSearchQuery("");
4538
+ },
4539
+ [activeArticleSlug]
4540
+ );
4541
+ const goBack = useCallback(() => {
4542
+ if (history.length > 0) {
4543
+ const newHistory = [...history];
4544
+ const previousSlug = newHistory.pop();
4545
+ setHistory(newHistory);
4546
+ setActiveArticleSlug(previousSlug || null);
4154
4547
  }
4155
- if (collapsible) {
4156
- return /* @__PURE__ */ jsx(
4157
- Button,
4158
- {
4159
- variant: "ghost",
4160
- size: "icon",
4161
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent",
4162
- onClick: () => setIsCollapsed(!isCollapsed),
4163
- "aria-expanded": !isCollapsed,
4164
- "aria-label": isCollapsed ? "Expand" : "Collapse",
4165
- children: /* @__PURE__ */ jsx(
4166
- ChevronDown,
4167
- {
4168
- className: cn(
4169
- "h-4 w-4 transition-transform duration-200",
4170
- isCollapsed && "-rotate-90"
4171
- )
4172
- }
4173
- )
4174
- }
4175
- );
4548
+ }, [history]);
4549
+ const canGoBack = history.length > 0;
4550
+ useEffect(() => {
4551
+ function handleKeyDown(event) {
4552
+ if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "H") {
4553
+ event.preventDefault();
4554
+ toggleHelp();
4555
+ }
4556
+ if (event.key === "Escape" && isOpen) {
4557
+ event.preventDefault();
4558
+ closeHelp();
4559
+ }
4560
+ }
4561
+ window.addEventListener("keydown", handleKeyDown);
4562
+ return () => window.removeEventListener("keydown", handleKeyDown);
4563
+ }, [toggleHelp, closeHelp, isOpen]);
4564
+ useEffect(() => {
4565
+ function handleClick(event) {
4566
+ const target = event.target;
4567
+ const link = target.closest('a[href="/help"], a[href="/admin/help"]');
4568
+ if (link && !link.hasAttribute("data-prevent-help-intercept")) {
4569
+ event.preventDefault();
4570
+ event.stopPropagation();
4571
+ toggleHelp();
4572
+ }
4176
4573
  }
4177
- return null;
4574
+ document.addEventListener("click", handleClick, true);
4575
+ return () => document.removeEventListener("click", handleClick, true);
4576
+ }, [toggleHelp]);
4577
+ const value = {
4578
+ isOpen,
4579
+ openHelp,
4580
+ closeHelp,
4581
+ toggleHelp,
4582
+ activeArticle,
4583
+ setActiveArticle,
4584
+ helpContext,
4585
+ searchQuery,
4586
+ setSearchQuery,
4587
+ performSearch,
4588
+ searchResults,
4589
+ openFeatureHelp,
4590
+ navigateToArticle,
4591
+ goBack,
4592
+ history,
4593
+ canGoBack
4178
4594
  };
4179
- if (variant === "simple") {
4180
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
4181
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [
4182
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4183
- Icon && /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-muted-foreground" }),
4184
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold tracking-tight", children: title })
4185
- ] }),
4186
- renderActions()
4187
- ] }),
4188
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground px-1", children: description }),
4189
- (!collapsible || !isCollapsed) && /* @__PURE__ */ jsx("div", { className: contentClassName, children })
4190
- ] });
4191
- }
4192
- return /* @__PURE__ */ jsxs(Card, { className, children: [
4193
- /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between space-y-0 pb-2", children: [
4194
- /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
4195
- /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2", children: [
4196
- Icon && /* @__PURE__ */ jsx(Icon, { className: "size-5" }),
4197
- title
4198
- ] }),
4199
- description && /* @__PURE__ */ jsx(CardDescription, { children: description })
4200
- ] }),
4201
- renderActions()
4202
- ] }),
4203
- (!collapsible || !isCollapsed) && /* @__PURE__ */ jsx(CardContent, { className: contentClassName, children })
4204
- ] });
4595
+ return /* @__PURE__ */ jsx(HelpContext.Provider, { value, children });
4205
4596
  }
4206
- var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
4207
- ProgressPrimitive.Root,
4208
- {
4209
- ref,
4210
- className: cn(
4211
- "relative h-2 w-full overflow-hidden rounded-full bg-muted",
4212
- className
4213
- ),
4214
- ...props,
4215
- children: /* @__PURE__ */ jsx(
4216
- ProgressPrimitive.Indicator,
4217
- {
4218
- className: "h-full w-full flex-1 bg-primary transition-all duration-300 ease-out",
4219
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
4220
- }
4221
- )
4597
+ function useHelp() {
4598
+ const context = useContext(HelpContext);
4599
+ if (!context) {
4600
+ throw new Error("useHelp must be used within a HelpProvider");
4222
4601
  }
4223
- ));
4224
- Progress.displayName = ProgressPrimitive.Root.displayName;
4225
- var RadioGroup = ({
4602
+ return context;
4603
+ }
4604
+ function HelpButton({
4605
+ featureKey,
4606
+ variant = "ghost",
4607
+ size = "icon",
4226
4608
  className,
4227
- ...props
4228
- }) => {
4229
- return /* @__PURE__ */ jsx(
4230
- RadioGroupPrimitive.Root,
4231
- {
4232
- className: cn("grid gap-2", className),
4233
- ...props
4609
+ label = "Help",
4610
+ showLabel = false
4611
+ }) {
4612
+ const { openHelp, openFeatureHelp } = useHelp();
4613
+ const handleClick = () => {
4614
+ if (featureKey) {
4615
+ openFeatureHelp(featureKey);
4616
+ } else {
4617
+ openHelp();
4234
4618
  }
4235
- );
4236
- };
4237
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
4238
- var RadioGroupItem = ({
4239
- className,
4240
- ...props
4241
- }) => {
4242
- return /* @__PURE__ */ jsx(
4243
- RadioGroupPrimitive.Item,
4619
+ };
4620
+ return /* @__PURE__ */ jsxs(
4621
+ Button,
4244
4622
  {
4245
- className: cn(
4246
- "aspect-square h-4 w-4 rounded-full border-2 border-muted-foreground/50 text-primary shadow-sm transition-all",
4247
- "outline-none focus:border-primary focus:shadow-[0_0_0_3px_hsl(var(--primary)/0.3)]",
4248
- "disabled:cursor-not-allowed disabled:opacity-50",
4249
- "data-[state=checked]:border-primary data-[state=checked]:bg-primary",
4250
- className
4251
- ),
4252
- ...props,
4253
- children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-primary-foreground text-primary-foreground" }) })
4623
+ variant,
4624
+ size: showLabel ? size : "icon",
4625
+ onClick: handleClick,
4626
+ className: cn(showLabel && "gap-2", className),
4627
+ "aria-label": label,
4628
+ children: [
4629
+ /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" }),
4630
+ showLabel && /* @__PURE__ */ jsx("span", { children: label })
4631
+ ]
4254
4632
  }
4255
4633
  );
4256
- };
4257
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
4258
- var spacingClasses = {
4259
- sm: "py-8",
4260
- // 32px
4261
- md: "py-16",
4262
- // 64px
4263
- lg: "py-24",
4264
- // 96px
4265
- xl: "py-32"
4266
- // 128px
4267
- };
4268
- var Section = React.forwardRef(
4269
- ({
4270
- className,
4271
- spacing: spacing2 = "md",
4272
- as: Component = "section",
4273
- children,
4274
- ...props
4275
- }, ref) => {
4276
- return /* @__PURE__ */ jsx(
4277
- Component,
4278
- {
4279
- ref,
4280
- className: cn(spacingClasses[spacing2], className),
4281
- ...props,
4282
- children
4283
- }
4284
- );
4634
+ }
4635
+ function HelpSearchResults({
4636
+ results,
4637
+ query,
4638
+ onSelect,
4639
+ categoryIcons = {}
4640
+ }) {
4641
+ if (results.length === 0) {
4642
+ return /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
4643
+ /* @__PURE__ */ jsx(HelpCircle, { className: "size-12 mx-auto text-muted-foreground/50 mb-3" }),
4644
+ /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
4645
+ "No results found for \u201C",
4646
+ query,
4647
+ "\u201D"
4648
+ ] }),
4649
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground/70 mt-1", children: "Try different keywords or browse categories below" })
4650
+ ] });
4285
4651
  }
4286
- );
4287
- Section.displayName = "Section";
4288
- var Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
4289
- SliderPrimitive.Root,
4290
- {
4291
- ref,
4292
- className: cn(
4293
- "relative flex w-full touch-none select-none items-center",
4294
- className
4295
- ),
4296
- ...props,
4297
- children: [
4298
- /* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full bg-primary" }) }),
4299
- (props.defaultValue ?? props.value ?? [0]).map((_, index) => /* @__PURE__ */ jsx(
4300
- SliderPrimitive.Thumb,
4652
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
4653
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: [
4654
+ results.length,
4655
+ " result",
4656
+ results.length !== 1 ? "s" : "",
4657
+ " for \u201C",
4658
+ query,
4659
+ "\u201D"
4660
+ ] }),
4661
+ results.map((result) => {
4662
+ const Icon = categoryIcons[result.category] || HelpCircle;
4663
+ return /* @__PURE__ */ jsx(
4664
+ "button",
4301
4665
  {
4302
- className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50"
4666
+ type: "button",
4667
+ onClick: () => onSelect(result.slug),
4668
+ className: "w-full text-left p-3 rounded-lg border hover:bg-accent transition-colors",
4669
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
4670
+ /* @__PURE__ */ jsx(Icon, { className: "size-4 mt-0.5 text-muted-foreground" }),
4671
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
4672
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-sm", children: result.title }),
4673
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2 mt-0.5", children: result.description })
4674
+ ] }),
4675
+ /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
4676
+ ] })
4303
4677
  },
4304
- index
4305
- ))
4306
- ]
4307
- }
4308
- ));
4309
- Slider.displayName = SliderPrimitive.Root.displayName;
4310
- function formatTrendValue(value, isPercentage = true) {
4311
- const sign = value >= 0 ? "+" : "";
4312
- return isPercentage ? `${sign}${value}%` : `${sign}${value}`;
4678
+ result.slug
4679
+ );
4680
+ })
4681
+ ] });
4313
4682
  }
4314
- function formatStatValue(value, format, options) {
4315
- if (typeof value === "string") {
4316
- return value;
4317
- }
4318
- const num = value;
4319
- switch (format) {
4320
- case "currency":
4321
- return new Intl.NumberFormat("en-US", {
4322
- style: "currency",
4323
- currency: options?.currencyCode ?? "USD",
4324
- minimumFractionDigits: 0,
4325
- maximumFractionDigits: num >= 1e3 ? 0 : 2
4326
- }).format(num);
4327
- case "percent":
4328
- return new Intl.NumberFormat("en-US", {
4329
- style: "percent",
4330
- minimumFractionDigits: 0,
4331
- maximumFractionDigits: options?.percentDecimals ?? 1
4332
- }).format(num / 100);
4333
- case "compact":
4334
- return new Intl.NumberFormat("en-US", {
4335
- notation: "compact",
4336
- compactDisplay: "short",
4337
- maximumFractionDigits: 1
4338
- }).format(num);
4339
- case "number":
4340
- if (Math.abs(num) >= 1e6) {
4341
- return new Intl.NumberFormat("en-US", {
4342
- notation: "compact",
4343
- compactDisplay: "short",
4344
- maximumFractionDigits: 1
4345
- }).format(num);
4683
+ function HelpTooltip({
4684
+ content,
4685
+ featureKey,
4686
+ size = "sm",
4687
+ className
4688
+ }) {
4689
+ const { openFeatureHelp } = useHelp();
4690
+ const iconSize = size === "sm" ? "size-3.5" : "size-4";
4691
+ const handleClick = (e) => {
4692
+ if (featureKey) {
4693
+ e.preventDefault();
4694
+ e.stopPropagation();
4695
+ openFeatureHelp(featureKey);
4696
+ }
4697
+ };
4698
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
4699
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
4700
+ "button",
4701
+ {
4702
+ type: "button",
4703
+ onClick: handleClick,
4704
+ className: `inline-flex items-center justify-center text-muted-foreground hover:text-foreground transition-colors ${className}`,
4705
+ "aria-label": "Help",
4706
+ children: /* @__PURE__ */ jsx(HelpCircle, { className: iconSize })
4346
4707
  }
4347
- return new Intl.NumberFormat("en-US").format(num);
4348
- default:
4349
- return String(value);
4708
+ ) }),
4709
+ /* @__PURE__ */ jsxs(TooltipContent, { className: "max-w-xs", children: [
4710
+ /* @__PURE__ */ jsx("p", { className: "text-sm", children: content }),
4711
+ featureKey && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Click to learn more" })
4712
+ ] })
4713
+ ] });
4714
+ }
4715
+ var buttonGroupVariants = cva(
4716
+ "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
4717
+ {
4718
+ variants: {
4719
+ orientation: {
4720
+ horizontal: "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
4721
+ vertical: "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none"
4722
+ }
4723
+ },
4724
+ defaultVariants: {
4725
+ orientation: "horizontal"
4726
+ }
4350
4727
  }
4728
+ );
4729
+ function ButtonGroup({
4730
+ className,
4731
+ orientation,
4732
+ ...props
4733
+ }) {
4734
+ return (
4735
+ // biome-ignore lint/a11y/useSemanticElements: upstream shadcn markup; ButtonGroup is a visual grouping, not a form fieldset
4736
+ /* @__PURE__ */ jsx(
4737
+ "div",
4738
+ {
4739
+ role: "group",
4740
+ "data-slot": "button-group",
4741
+ "data-orientation": orientation,
4742
+ className: cn(buttonGroupVariants({ orientation }), className),
4743
+ ...props
4744
+ }
4745
+ )
4746
+ );
4351
4747
  }
4352
- function TrendBadge({ trend }) {
4353
- const Icon = trend.direction === "up" ? TrendingUp : trend.direction === "down" ? TrendingDown : null;
4354
- const colorClass = trend.direction === "up" ? "text-emerald-600 dark:text-emerald-400" : trend.direction === "down" ? "text-destructive" : "text-muted-foreground";
4355
- return /* @__PURE__ */ jsxs(
4356
- Badge,
4748
+ function ButtonGroupText({
4749
+ className,
4750
+ asChild = false,
4751
+ ...props
4752
+ }) {
4753
+ const Comp = asChild ? Slot : "div";
4754
+ return /* @__PURE__ */ jsx(
4755
+ Comp,
4357
4756
  {
4358
- variant: "outline",
4359
- className: cn("gap-1 rounded-md text-xs", colorClass),
4360
- children: [
4361
- Icon && /* @__PURE__ */ jsx(Icon, { className: "size-3" }),
4362
- formatTrendValue(trend.value, trend.isPercentage ?? true)
4363
- ]
4757
+ className: cn(
4758
+ "flex items-center gap-2 rounded-md border bg-muted px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
4759
+ className
4760
+ ),
4761
+ ...props
4364
4762
  }
4365
4763
  );
4366
4764
  }
4367
- function StatCardValueContent({
4368
- isCompact,
4369
- displayValue,
4370
- description,
4371
- trend,
4372
- footer
4765
+ function ButtonGroupSeparator({
4766
+ className,
4767
+ orientation = "vertical",
4768
+ ...props
4373
4769
  }) {
4374
- if (isCompact) {
4375
- return /* @__PURE__ */ jsxs(Fragment, { children: [
4376
- /* @__PURE__ */ jsx("div", { className: "mt-2 min-w-0", children: /* @__PURE__ */ jsx("span", { className: "block text-2xl md:text-3xl font-semibold tracking-tight tabular-nums leading-none md:leading-tight truncate", children: displayValue }) }),
4377
- (description || trend) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-center gap-2 min-w-0", children: [
4378
- trend && /* @__PURE__ */ jsx(TrendBadge, { trend }),
4379
- description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate", children: description })
4380
- ] }),
4381
- trend?.label && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: trend.label }),
4382
- footer && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: footer })
4383
- ] });
4384
- }
4385
- return /* @__PURE__ */ jsxs(Fragment, { children: [
4386
- /* @__PURE__ */ jsx("div", { className: "relative overflow-hidden", children: /* @__PURE__ */ jsx("span", { className: "block text-7xl md:text-8xl font-black tabular-nums leading-none tracking-tighter text-foreground/10 truncate", children: displayValue }) }),
4387
- (description || trend) && /* @__PURE__ */ jsxs("div", { className: "-mt-6 flex items-center gap-2 min-w-0", children: [
4388
- trend && /* @__PURE__ */ jsx(TrendBadge, { trend }),
4389
- description && /* @__PURE__ */ jsx("p", { className: "text-xs text-foreground/80 truncate", children: description })
4390
- ] }),
4391
- footer && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: footer }),
4392
- trend?.label && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: trend.label })
4393
- ] });
4394
- }
4395
- function FlipIndicator({ activeSide }) {
4396
- return /* @__PURE__ */ jsxs(
4397
- "div",
4770
+ return /* @__PURE__ */ jsx(
4771
+ Separator,
4398
4772
  {
4399
- className: "absolute bottom-2 left-1/2 -translate-x-1/2 flex items-center gap-1.5 z-10 pointer-events-none",
4400
- "aria-hidden": "true",
4401
- children: [
4402
- /* @__PURE__ */ jsx(
4403
- "span",
4404
- {
4405
- className: cn(
4406
- "h-1.5 w-1.5 rounded-full transition-colors",
4407
- activeSide === "stat" ? "bg-foreground/60" : "bg-foreground/20"
4408
- )
4409
- }
4410
- ),
4411
- /* @__PURE__ */ jsx(
4412
- "span",
4413
- {
4414
- className: cn(
4415
- "h-1.5 w-1.5 rounded-full transition-colors",
4416
- activeSide === "chart" ? "bg-foreground/60" : "bg-foreground/20"
4417
- )
4418
- }
4419
- )
4420
- ]
4773
+ "data-slot": "button-group-separator",
4774
+ orientation,
4775
+ className: cn(
4776
+ "relative m-0! self-stretch bg-input data-[orientation=vertical]:h-auto",
4777
+ className
4778
+ ),
4779
+ ...props
4421
4780
  }
4422
4781
  );
4423
4782
  }
4424
- function MiniChart({ data, type = "area", periodLabel }) {
4425
- if (!data || data.length === 0) return null;
4426
- const values = data.map((d) => d.value);
4427
- const maxValue = Math.max(...values);
4428
- const minValue = Math.min(...values);
4429
- const range = maxValue - minValue || 1;
4430
- const width = 100;
4431
- const height = 40;
4432
- const paddingX = 0;
4433
- const paddingY = 4;
4434
- const points = data.map((d, i) => {
4435
- const normalizedX = data.length > 1 ? i / (data.length - 1) : 0.5;
4436
- const x = paddingX + normalizedX * (width - paddingX * 2);
4437
- const y = height - paddingY - (d.value - minValue) / range * (height - paddingY * 2);
4438
- return { x, y, ...d };
4439
- });
4440
- const createSmoothPath = (pts) => {
4441
- if (pts.length < 2) return "";
4442
- let path = `M ${pts[0].x} ${pts[0].y}`;
4443
- for (let i = 0; i < pts.length - 1; i++) {
4444
- const p0 = pts[Math.max(0, i - 1)];
4445
- const p1 = pts[i];
4446
- const p2 = pts[i + 1];
4447
- const p3 = pts[Math.min(pts.length - 1, i + 2)];
4448
- const tension = 0.3;
4449
- const cp1x = p1.x + (p2.x - p0.x) * tension;
4450
- const cp1y = p1.y + (p2.y - p0.y) * tension;
4451
- const cp2x = p2.x - (p3.x - p1.x) * tension;
4452
- const cp2y = p2.y - (p3.y - p1.y) * tension;
4453
- path += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
4783
+ function Empty({ className, ...props }) {
4784
+ return /* @__PURE__ */ jsx(
4785
+ "div",
4786
+ {
4787
+ "data-slot": "empty",
4788
+ className: cn(
4789
+ "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12",
4790
+ className
4791
+ ),
4792
+ ...props
4454
4793
  }
4455
- return path;
4456
- };
4457
- const smoothPath = createSmoothPath(points);
4458
- const areaPath = `${smoothPath} L ${points[points.length - 1].x} ${height} L ${points[0].x} ${height} Z`;
4459
- const barWidth = (width - paddingX * 2) / data.length - 2;
4460
- const gradientId = `miniChartGradient-${Math.random().toString(36).substring(2, 11)}`;
4461
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full justify-center px-1", children: [
4462
- periodLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-2", children: periodLabel }),
4463
- /* @__PURE__ */ jsxs(
4464
- "svg",
4465
- {
4466
- viewBox: `0 0 ${width} ${height}`,
4467
- className: "w-full h-20",
4468
- preserveAspectRatio: "none",
4469
- "aria-label": "Chart showing trend data",
4470
- role: "img",
4471
- children: [
4472
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
4473
- /* @__PURE__ */ jsx(
4474
- "stop",
4475
- {
4476
- offset: "5%",
4477
- className: "[stop-color:hsl(var(--primary))]",
4478
- stopOpacity: 0.8
4479
- }
4480
- ),
4481
- /* @__PURE__ */ jsx(
4482
- "stop",
4483
- {
4484
- offset: "95%",
4485
- className: "[stop-color:hsl(var(--primary))]",
4486
- stopOpacity: 0.1
4487
- }
4488
- )
4489
- ] }) }),
4490
- type === "bar" ? (
4491
- // Bar chart
4492
- /* @__PURE__ */ jsx("g", { children: points.map((p, i) => /* @__PURE__ */ jsx(
4493
- "rect",
4494
- {
4495
- x: paddingX + i * (width - paddingX * 2) / data.length + 1,
4496
- y: p.y,
4497
- width: barWidth,
4498
- height: height - p.y,
4499
- className: "fill-primary/30",
4500
- rx: 1
4501
- },
4502
- p.label
4503
- )) })
4504
- ) : (
4505
- // Line/Area chart - matching NewUsersChart style
4506
- /* @__PURE__ */ jsxs("g", { children: [
4507
- type === "area" && /* @__PURE__ */ jsx("path", { d: areaPath, fill: `url(#${gradientId})` }),
4508
- /* @__PURE__ */ jsx(
4509
- "path",
4510
- {
4511
- d: smoothPath,
4512
- fill: "none",
4513
- className: "stroke-primary",
4514
- strokeWidth: 1.5,
4515
- strokeLinecap: "round",
4516
- strokeLinejoin: "round"
4517
- }
4518
- )
4519
- ] })
4520
- )
4521
- ]
4522
- }
4523
- ),
4524
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-[10px] text-muted-foreground mt-1", children: [
4525
- /* @__PURE__ */ jsx("span", { children: data[0]?.label }),
4526
- /* @__PURE__ */ jsx("span", { children: data[data.length - 1]?.label })
4527
- ] })
4528
- ] });
4794
+ );
4529
4795
  }
4530
- function StatCard({
4531
- title,
4532
- value,
4533
- description,
4534
- footer,
4535
- icon,
4536
- trend,
4537
- variant = "default",
4796
+ function EmptyHeader({ className, ...props }) {
4797
+ return /* @__PURE__ */ jsx(
4798
+ "div",
4799
+ {
4800
+ "data-slot": "empty-header",
4801
+ className: cn(
4802
+ "flex max-w-sm flex-col items-center gap-2 text-center",
4803
+ className
4804
+ ),
4805
+ ...props
4806
+ }
4807
+ );
4808
+ }
4809
+ var emptyMediaVariants = cva(
4810
+ "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
4811
+ {
4812
+ variants: {
4813
+ variant: {
4814
+ default: "bg-transparent",
4815
+ icon: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6"
4816
+ }
4817
+ },
4818
+ defaultVariants: {
4819
+ variant: "default"
4820
+ }
4821
+ }
4822
+ );
4823
+ function EmptyMedia({
4538
4824
  className,
4539
- size = "default",
4540
- format,
4541
- currencyCode,
4542
- percentDecimals,
4543
- formatValue = false,
4544
- onClick,
4545
- href,
4546
- chart,
4547
- defaultSide = "stat"
4825
+ variant = "default",
4826
+ ...props
4548
4827
  }) {
4549
- const [activeSide, setActiveSide] = useState(defaultSide);
4550
- const effectiveFormat = format ?? (formatValue ? "number" : typeof value === "number" ? "number" : "none");
4551
- const displayValue = formatStatValue(value, effectiveFormat, {
4552
- currencyCode,
4553
- percentDecimals
4554
- });
4555
- const variantStyles = {
4556
- default: "",
4557
- muted: "bg-linear-to-t from-muted/60 to-muted/20 hover:from-muted/70 hover:to-muted/30 transition-colors",
4558
- gradient: "bg-gradient-to-t from-primary/5 to-card dark:bg-card",
4559
- outline: "border-2"
4560
- };
4561
- const isInteractive = onClick || href;
4562
- const hasChart = !!chart;
4563
- const isCompact = size === "compact";
4564
- const handleFlip = () => {
4565
- setActiveSide((prev) => prev === "stat" ? "chart" : "stat");
4566
- };
4567
- const handleBodyClick = (e) => {
4568
- e.stopPropagation();
4569
- if (hasChart) {
4570
- handleFlip();
4571
- } else if (onClick) {
4572
- onClick();
4828
+ return /* @__PURE__ */ jsx(
4829
+ "div",
4830
+ {
4831
+ "data-slot": "empty-icon",
4832
+ "data-variant": variant,
4833
+ className: cn(emptyMediaVariants({ variant, className })),
4834
+ ...props
4573
4835
  }
4574
- };
4575
- const handleHeaderClick = (e) => {
4576
- e.stopPropagation();
4577
- if (href) {
4578
- return;
4836
+ );
4837
+ }
4838
+ function EmptyTitle({ className, ...props }) {
4839
+ return /* @__PURE__ */ jsx(
4840
+ "div",
4841
+ {
4842
+ "data-slot": "empty-title",
4843
+ className: cn("text-lg font-medium tracking-tight", className),
4844
+ ...props
4579
4845
  }
4580
- if (onClick) {
4581
- onClick();
4582
- } else if (hasChart) {
4583
- handleFlip();
4846
+ );
4847
+ }
4848
+ function EmptyDescription({ className, ...props }) {
4849
+ return /* @__PURE__ */ jsx(
4850
+ "div",
4851
+ {
4852
+ "data-slot": "empty-description",
4853
+ className: cn(
4854
+ "text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
4855
+ className
4856
+ ),
4857
+ ...props
4584
4858
  }
4585
- };
4586
- const cardBaseStyles = cn(
4587
- "h-full relative overflow-hidden gap-0",
4588
- isCompact ? "min-h-[112px] p-3 md:min-h-[120px] md:p-4" : "py-3",
4589
- variantStyles[variant],
4590
- hasChart && "pb-6"
4591
4859
  );
4592
- const renderHeader = (showIcon = true) => /* @__PURE__ */ jsxs(
4593
- CardHeader,
4860
+ }
4861
+ function EmptyContent({ className, ...props }) {
4862
+ return /* @__PURE__ */ jsx(
4863
+ "div",
4594
4864
  {
4865
+ "data-slot": "empty-content",
4595
4866
  className: cn(
4596
- "flex flex-row items-center justify-between space-y-0 py-0",
4597
- isCompact ? "px-0" : "px-4"
4867
+ "flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",
4868
+ className
4598
4869
  ),
4599
- children: [
4600
- href ? /* @__PURE__ */ jsxs(
4601
- "a",
4602
- {
4603
- href,
4604
- className: "flex items-center gap-2 hover:text-primary transition-colors z-10",
4605
- onClick: (e) => e.stopPropagation(),
4606
- children: [
4607
- /* @__PURE__ */ jsx(
4608
- CardTitle,
4609
- {
4610
- className: cn(
4611
- isCompact ? "text-xs md:text-sm font-medium text-muted-foreground" : "text-sm font-medium"
4612
- ),
4613
- children: title
4614
- }
4615
- ),
4616
- /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-4 w-4 opacity-0 group-hover:opacity-100 transition-opacity" })
4617
- ]
4618
- }
4619
- ) : /* @__PURE__ */ jsx(
4620
- CardTitle,
4621
- {
4622
- className: cn(
4623
- isCompact ? "text-xs md:text-sm font-medium text-muted-foreground" : "text-sm font-medium",
4624
- "flex items-center gap-2",
4625
- onClick && "cursor-pointer hover:text-primary transition-colors"
4626
- ),
4627
- onClick: handleHeaderClick,
4628
- children: title
4629
- }
4630
- ),
4631
- showIcon && icon && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: icon })
4632
- ]
4870
+ ...props
4633
4871
  }
4634
4872
  );
4635
- if (!hasChart) {
4636
- return /* @__PURE__ */ jsxs(
4637
- Card,
4873
+ }
4874
+ function ItemGroup({ className, ...props }) {
4875
+ return (
4876
+ // biome-ignore lint/a11y/useSemanticElements: upstream shadcn markup; ItemGroup keeps a div so Item can be any element via asChild
4877
+ /* @__PURE__ */ jsx(
4878
+ "div",
4638
4879
  {
4639
- className: cn(
4640
- cardBaseStyles,
4641
- "group",
4642
- isInteractive && "cursor-pointer transition-colors hover:border-primary/50",
4643
- className
4644
- ),
4645
- onClick,
4646
- children: [
4647
- renderHeader(),
4648
- /* @__PURE__ */ jsx(
4649
- CardContent,
4650
- {
4651
- className: cn("relative py-0", isCompact ? "px-0" : "px-4"),
4652
- children: /* @__PURE__ */ jsx(
4653
- StatCardValueContent,
4654
- {
4655
- isCompact,
4656
- displayValue,
4657
- description,
4658
- trend,
4659
- footer
4660
- }
4661
- )
4662
- }
4663
- )
4664
- ]
4880
+ role: "list",
4881
+ "data-slot": "item-group",
4882
+ className: cn("group/item-group flex flex-col", className),
4883
+ ...props
4665
4884
  }
4666
- );
4667
- }
4885
+ )
4886
+ );
4887
+ }
4888
+ function ItemSeparator({
4889
+ className,
4890
+ ...props
4891
+ }) {
4668
4892
  return /* @__PURE__ */ jsx(
4669
- "div",
4893
+ Separator,
4670
4894
  {
4671
- className: cn("group h-full min-h-[160px]", className),
4672
- style: { perspective: "1000px" },
4673
- children: /* @__PURE__ */ jsxs(
4674
- "button",
4675
- {
4676
- type: "button",
4677
- className: cn(
4678
- "relative h-full w-full transition-transform duration-500 cursor-pointer text-left",
4679
- "[transform-style:preserve-3d]",
4680
- activeSide === "chart" && "[transform:rotateY(180deg)]"
4681
- ),
4682
- onClick: handleBodyClick,
4683
- "aria-label": activeSide === "chart" ? "Show statistic view" : "Show chart view",
4684
- "aria-pressed": activeSide === "chart",
4685
- children: [
4686
- /* @__PURE__ */ jsxs(
4687
- Card,
4688
- {
4689
- className: cn(
4690
- cardBaseStyles,
4691
- "absolute inset-0 [backface-visibility:hidden] [transform-style:preserve-3d] [transform:rotateY(0deg)]",
4692
- "transition-colors hover:border-primary/50"
4693
- ),
4694
- children: [
4695
- renderHeader(),
4696
- /* @__PURE__ */ jsx(
4697
- CardContent,
4698
- {
4699
- className: cn("relative py-0", isCompact ? "px-0" : "px-4"),
4700
- children: /* @__PURE__ */ jsx(
4701
- StatCardValueContent,
4702
- {
4703
- isCompact,
4704
- displayValue,
4705
- description,
4706
- trend,
4707
- footer
4708
- }
4709
- )
4710
- }
4711
- ),
4712
- /* @__PURE__ */ jsx(FlipIndicator, { activeSide })
4713
- ]
4714
- }
4715
- ),
4716
- /* @__PURE__ */ jsxs(
4717
- Card,
4718
- {
4719
- className: cn(
4720
- cardBaseStyles,
4721
- "absolute inset-0 [backface-visibility:hidden] [transform-style:preserve-3d] [transform:rotateY(180deg)]",
4722
- "transition-colors hover:border-primary/50"
4723
- ),
4724
- children: [
4725
- renderHeader(false),
4726
- /* @__PURE__ */ jsx(CardContent, { className: "relative px-4 py-0 h-full", children: /* @__PURE__ */ jsx(MiniChart, { ...chart }) }),
4727
- /* @__PURE__ */ jsx(FlipIndicator, { activeSide })
4728
- ]
4729
- }
4730
- )
4731
- ]
4732
- }
4733
- )
4895
+ "data-slot": "item-separator",
4896
+ orientation: "horizontal",
4897
+ className: cn("my-0", className),
4898
+ ...props
4899
+ }
4900
+ );
4901
+ }
4902
+ var itemVariants = cva(
4903
+ "group/item flex flex-wrap items-center rounded-md border border-transparent text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-accent/50",
4904
+ {
4905
+ variants: {
4906
+ variant: {
4907
+ default: "bg-transparent",
4908
+ outline: "border-border",
4909
+ muted: "bg-muted/50"
4910
+ },
4911
+ size: {
4912
+ default: "gap-4 p-4",
4913
+ sm: "gap-2.5 px-4 py-3"
4914
+ }
4915
+ },
4916
+ defaultVariants: {
4917
+ variant: "default",
4918
+ size: "default"
4919
+ }
4920
+ }
4921
+ );
4922
+ function Item({
4923
+ className,
4924
+ variant = "default",
4925
+ size = "default",
4926
+ asChild = false,
4927
+ ...props
4928
+ }) {
4929
+ const Comp = asChild ? Slot : "div";
4930
+ return /* @__PURE__ */ jsx(
4931
+ Comp,
4932
+ {
4933
+ "data-slot": "item",
4934
+ "data-variant": variant,
4935
+ "data-size": size,
4936
+ className: cn(itemVariants({ variant, size, className })),
4937
+ ...props
4734
4938
  }
4735
4939
  );
4736
4940
  }
4737
- function StatCardsContainer({
4738
- children,
4739
- columns = { default: 1, sm: 2, lg: 4 },
4740
- className
4941
+ var itemMediaVariants = cva(
4942
+ "flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none",
4943
+ {
4944
+ variants: {
4945
+ variant: {
4946
+ default: "bg-transparent",
4947
+ icon: "size-8 rounded-sm border bg-muted [&_svg:not([class*='size-'])]:size-4",
4948
+ image: "size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover"
4949
+ }
4950
+ },
4951
+ defaultVariants: {
4952
+ variant: "default"
4953
+ }
4954
+ }
4955
+ );
4956
+ function ItemMedia({
4957
+ className,
4958
+ variant = "default",
4959
+ ...props
4741
4960
  }) {
4742
- const colClasses = {
4743
- 1: "grid-cols-1",
4744
- 2: "grid-cols-2",
4745
- 3: "grid-cols-3",
4746
- 4: "grid-cols-4"
4747
- };
4748
- const smColClasses = {
4749
- 1: "sm:grid-cols-1",
4750
- 2: "sm:grid-cols-2",
4751
- 3: "sm:grid-cols-3",
4752
- 4: "sm:grid-cols-4"
4753
- };
4754
- const mdColClasses = {
4755
- 1: "md:grid-cols-1",
4756
- 2: "md:grid-cols-2",
4757
- 3: "md:grid-cols-3",
4758
- 4: "md:grid-cols-4"
4759
- };
4760
- const lgColClasses = {
4761
- 1: "lg:grid-cols-1",
4762
- 2: "lg:grid-cols-2",
4763
- 3: "lg:grid-cols-3",
4764
- 4: "lg:grid-cols-4"
4765
- };
4766
4961
  return /* @__PURE__ */ jsx(
4767
4962
  "div",
4768
4963
  {
4964
+ "data-slot": "item-media",
4965
+ "data-variant": variant,
4966
+ className: cn(itemMediaVariants({ variant, className })),
4967
+ ...props
4968
+ }
4969
+ );
4970
+ }
4971
+ function ItemContent({ className, ...props }) {
4972
+ return /* @__PURE__ */ jsx(
4973
+ "div",
4974
+ {
4975
+ "data-slot": "item-content",
4769
4976
  className: cn(
4770
- "grid gap-4",
4771
- columns.default && colClasses[columns.default],
4772
- columns.sm && smColClasses[columns.sm],
4773
- columns.md && mdColClasses[columns.md],
4774
- columns.lg && lgColClasses[columns.lg],
4977
+ "flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none",
4775
4978
  className
4776
4979
  ),
4777
- children
4980
+ ...props
4778
4981
  }
4779
4982
  );
4780
4983
  }
4781
- function TextHighlight({
4782
- children,
4783
- className,
4784
- duration = 2,
4785
- delay = 0.5,
4786
- gradient = "from-indigo-300 to-purple-300 dark:from-indigo-500 dark:to-purple-500",
4787
- disableAnimation = false
4788
- }) {
4789
- const animationStyle = disableAnimation ? { backgroundSize: "100% 100%" } : {
4790
- "--highlight-duration": `${duration}s`,
4791
- "--highlight-delay": `${delay}s`
4792
- };
4984
+ function ItemTitle({ className, ...props }) {
4793
4985
  return /* @__PURE__ */ jsx(
4794
- "span",
4986
+ "div",
4795
4987
  {
4796
- "data-slot": "text-highlight",
4797
- "data-animated": !disableAnimation,
4988
+ "data-slot": "item-title",
4798
4989
  className: cn(
4799
- "relative inline-block rounded-lg bg-gradient-to-r bg-no-repeat px-1 pb-1",
4800
- !disableAnimation && "text-highlight-animated",
4801
- gradient,
4990
+ "flex w-fit items-center gap-2 text-sm leading-snug font-medium",
4802
4991
  className
4803
4992
  ),
4804
- style: {
4805
- backgroundPosition: "left center",
4806
- ...animationStyle
4807
- },
4808
- children
4993
+ ...props
4994
+ }
4995
+ );
4996
+ }
4997
+ function ItemDescription({ className, ...props }) {
4998
+ return /* @__PURE__ */ jsx(
4999
+ "p",
5000
+ {
5001
+ "data-slot": "item-description",
5002
+ className: cn(
5003
+ "line-clamp-2 text-sm leading-normal font-normal text-balance text-muted-foreground",
5004
+ "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
5005
+ className
5006
+ ),
5007
+ ...props
5008
+ }
5009
+ );
5010
+ }
5011
+ function ItemActions({ className, ...props }) {
5012
+ return /* @__PURE__ */ jsx(
5013
+ "div",
5014
+ {
5015
+ "data-slot": "item-actions",
5016
+ className: cn("flex items-center gap-2", className),
5017
+ ...props
5018
+ }
5019
+ );
5020
+ }
5021
+ function ItemHeader({ className, ...props }) {
5022
+ return /* @__PURE__ */ jsx(
5023
+ "div",
5024
+ {
5025
+ "data-slot": "item-header",
5026
+ className: cn(
5027
+ "flex basis-full items-center justify-between gap-2",
5028
+ className
5029
+ ),
5030
+ ...props
5031
+ }
5032
+ );
5033
+ }
5034
+ function ItemFooter({ className, ...props }) {
5035
+ return /* @__PURE__ */ jsx(
5036
+ "div",
5037
+ {
5038
+ "data-slot": "item-footer",
5039
+ className: cn(
5040
+ "flex basis-full items-center justify-between gap-2",
5041
+ className
5042
+ ),
5043
+ ...props
4809
5044
  }
4810
5045
  );
4811
5046
  }
4812
- var ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(
4813
- ToggleGroupPrimitive.Root,
5047
+ var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
5048
+ ProgressPrimitive.Root,
4814
5049
  {
4815
5050
  ref,
4816
- className: cn("flex items-center justify-center gap-1", className),
5051
+ className: cn(
5052
+ "relative h-2 w-full overflow-hidden rounded-full bg-muted",
5053
+ className
5054
+ ),
4817
5055
  ...props,
4818
- children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children })
5056
+ children: /* @__PURE__ */ jsx(
5057
+ ProgressPrimitive.Indicator,
5058
+ {
5059
+ className: "h-full w-full flex-1 bg-primary transition-all duration-300 ease-out",
5060
+ style: { transform: `translateX(-${100 - (value || 0)}%)` }
5061
+ }
5062
+ )
4819
5063
  }
4820
5064
  ));
4821
- ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
5065
+ Progress.displayName = ProgressPrimitive.Root.displayName;
5066
+ var RadioGroup = ({
5067
+ className,
5068
+ ...props
5069
+ }) => {
5070
+ return /* @__PURE__ */ jsx(
5071
+ RadioGroupPrimitive.Root,
5072
+ {
5073
+ className: cn("grid gap-2", className),
5074
+ ...props
5075
+ }
5076
+ );
5077
+ };
5078
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
5079
+ var RadioGroupItem = ({
5080
+ className,
5081
+ ...props
5082
+ }) => {
5083
+ return /* @__PURE__ */ jsx(
5084
+ RadioGroupPrimitive.Item,
5085
+ {
5086
+ className: cn(
5087
+ "aspect-square h-4 w-4 rounded-full border-2 border-muted-foreground/50 text-primary shadow-sm transition-all",
5088
+ "outline-none focus:border-primary focus:shadow-[0_0_0_3px_hsl(var(--primary)/0.3)]",
5089
+ "disabled:cursor-not-allowed disabled:opacity-50",
5090
+ "data-[state=checked]:border-primary data-[state=checked]:bg-primary",
5091
+ className
5092
+ ),
5093
+ ...props,
5094
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-primary-foreground text-primary-foreground" }) })
5095
+ }
5096
+ );
5097
+ };
5098
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
5099
+ var toggleVariants = cva(
5100
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
5101
+ {
5102
+ variants: {
5103
+ variant: {
5104
+ default: "bg-transparent",
5105
+ outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
5106
+ },
5107
+ size: {
5108
+ default: "h-9 min-w-9 px-2",
5109
+ sm: "h-8 min-w-8 px-1.5",
5110
+ lg: "h-10 min-w-10 px-2.5"
5111
+ }
5112
+ },
5113
+ defaultVariants: {
5114
+ variant: "default",
5115
+ size: "default"
5116
+ }
5117
+ }
5118
+ );
5119
+ function Toggle({
5120
+ className,
5121
+ variant,
5122
+ size,
5123
+ ...props
5124
+ }) {
5125
+ return /* @__PURE__ */ jsx(
5126
+ TogglePrimitive.Root,
5127
+ {
5128
+ "data-slot": "toggle",
5129
+ className: cn(toggleVariants({ variant, size, className })),
5130
+ ...props
5131
+ }
5132
+ );
5133
+ }
4822
5134
  var ToggleGroupContext = React.createContext({
4823
- size: void 0,
4824
- variant: void 0
5135
+ size: "default",
5136
+ variant: "default",
5137
+ spacing: 0
4825
5138
  });
4826
- var ToggleGroupItem = React.forwardRef(({ className, children, variant, size, ...props }, ref) => {
5139
+ function ToggleGroup({
5140
+ className,
5141
+ variant,
5142
+ size,
5143
+ spacing: spacing2 = 0,
5144
+ children,
5145
+ ...props
5146
+ }) {
5147
+ return /* @__PURE__ */ jsx(
5148
+ ToggleGroupPrimitive.Root,
5149
+ {
5150
+ "data-slot": "toggle-group",
5151
+ "data-variant": variant,
5152
+ "data-size": size,
5153
+ "data-spacing": spacing2,
5154
+ style: { "--gap": spacing2 },
5155
+ className: cn(
5156
+ "group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",
5157
+ className
5158
+ ),
5159
+ ...props,
5160
+ children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size, spacing: spacing2 }, children })
5161
+ }
5162
+ );
5163
+ }
5164
+ function ToggleGroupItem({
5165
+ className,
5166
+ children,
5167
+ variant,
5168
+ size,
5169
+ ...props
5170
+ }) {
4827
5171
  const context = React.useContext(ToggleGroupContext);
4828
- const resolvedVariant = variant || context.variant || "default";
4829
- const resolvedSize = size || context.size || "default";
4830
5172
  return /* @__PURE__ */ jsx(
4831
5173
  ToggleGroupPrimitive.Item,
4832
5174
  {
4833
- ref,
5175
+ "data-slot": "toggle-group-item",
5176
+ "data-variant": context.variant || variant,
5177
+ "data-size": context.size || size,
5178
+ "data-spacing": context.spacing,
4834
5179
  className: cn(
4835
- "inline-flex items-center justify-center rounded-box text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
4836
- resolvedVariant === "outline" && "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
4837
- resolvedSize === "default" && "h-10 px-3",
4838
- resolvedSize === "sm" && "h-9 px-2.5",
4839
- resolvedSize === "lg" && "h-11 px-5",
5180
+ toggleVariants({
5181
+ variant: context.variant || variant,
5182
+ size: context.size || size
5183
+ }),
5184
+ "w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
5185
+ "data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
4840
5186
  className
4841
5187
  ),
4842
5188
  ...props,
4843
5189
  children
4844
5190
  }
4845
5191
  );
4846
- });
4847
- ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
4848
- function TooltipCard({
4849
- children,
4850
- className,
4851
- containerClassName,
4852
- content,
4853
- triggerClassName,
4854
- delayDuration = 150,
4855
- side = "top",
4856
- align = "center",
4857
- sideOffset = 10,
4858
- ...tooltipProps
4859
- }) {
4860
- return /* @__PURE__ */ jsxs(Tooltip, { delayDuration, ...tooltipProps, children: [
4861
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
4862
- "button",
4863
- {
4864
- type: "button",
4865
- className: cn(
4866
- "inline cursor-help appearance-none border-0 bg-transparent p-0 align-baseline font-medium text-inherit underline decoration-current/35 underline-offset-4 transition-colors",
4867
- "hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4868
- className,
4869
- triggerClassName
4870
- ),
4871
- "data-slot": "tooltip-card-trigger",
4872
- children
4873
- }
4874
- ) }),
4875
- /* @__PURE__ */ jsx(
4876
- TooltipContent,
4877
- {
4878
- align,
4879
- className: cn(
4880
- "max-w-sm rounded-box border border-border bg-popover px-4 py-3 text-popover-foreground shadow-xl",
4881
- "text-sm leading-6 font-normal",
4882
- containerClassName
4883
- ),
4884
- "data-slot": "tooltip-card-content",
4885
- side,
4886
- sideOffset,
4887
- children: typeof content === "string" ? /* @__PURE__ */ jsx("p", { "data-slot": "tooltip-card-text", children: content }) : content
4888
- }
4889
- )
4890
- ] });
4891
5192
  }
4892
5193
 
4893
5194
  // src/config/theme.ts
@@ -5873,4 +6174,4 @@ function NoWidowProvider({
5873
6174
  return children ?? null;
5874
6175
  }
5875
6176
 
5876
- export { Autocomplete, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CohortCard, CompanyNameEditableCell, ContactInfo, DataStateBanner, DataStateInline, DeleteConfirmationDialog, DisclosureFootnotes, DisplayField, DisplayFieldGroup, DraggableCardBody, DraggableCardContainer, DraggableStickyModal, EditableCell, FeedbackButton, FeedbackDialog, FormDialog, GooeyInput, HelpArticleIndex, HelpArticleView, HelpButton, HelpProvider, HelpSearchResults, HelpTooltip, HoverEffect, HoverEffectCard, HoverEffectCardDescription, HoverEffectCardTitle, InfoTooltip, InlineEditableDate, InlineEditableSelect, InlineEditableText, LocationMap, MFAChallenge, MFARecovery, NoWidowProvider, NoWidowText, NumberStepper, PageLoader, PageSection, PageSections, ProfileSection, Progress, RadioGroup, RadioGroupItem, Section, SignOutButton, Slider, SocialIcon, StatCard, StatCardsContainer, TextHighlight, ToggleGroup, ToggleGroupItem, TooltipCard, UserNameEditableCell, animation, applyNoWidowText, borderRadius, breakpoints2 as breakpoints, colorfulTheme, compassThemeConfig, darkTheme, defaultThemes, deuteranopiaTheme, getColorScheme, getDefaultTheme, highContrastDarkTheme, highContrastTheme, layout, lightTheme, preventWidowsInReactNode, protanopiaTheme, shadows, socialPlatforms, spacing, theme, tritanopiaTheme, typography, useHelp, zIndex, zenbidThemeConfig };
6177
+ export { Autocomplete, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CohortCard, CompanyNameEditableCell, ContactInfo, DataStateBanner, DataStateInline, DeleteConfirmationDialog, DisclosureFootnotes, DisplayField, DisplayFieldGroup, DraggableCardBody, DraggableCardContainer, DraggableStickyModal, EditableCell, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FeedbackButton, FeedbackDialog, FormDialog, GooeyInput, HelpArticleIndex, HelpArticleView, HelpButton, HelpProvider, HelpSearchResults, HelpTooltip, HoverEffect, HoverEffectCard, HoverEffectCardDescription, HoverEffectCardTitle, InfoTooltip, InlineEditableDate, InlineEditableSelect, InlineEditableText, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, LocationMap, MFAChallenge, MFARecovery, NoWidowProvider, NoWidowText, NumberStepper, PageLoader, PageSection, PageSections, ProfileSection, Progress, RadioGroup, RadioGroupItem, Section, SignOutButton, SocialIcon, StatCard, StatCardsContainer, TextHighlight, Toggle, ToggleGroup, ToggleGroupItem, TooltipCard, UserNameEditableCell, animation, applyNoWidowText, borderRadius, breakpoints2 as breakpoints, buttonGroupVariants, colorfulTheme, compassThemeConfig, darkTheme, defaultThemes, deuteranopiaTheme, getColorScheme, getDefaultTheme, highContrastDarkTheme, highContrastTheme, layout, lightTheme, preventWidowsInReactNode, protanopiaTheme, shadows, socialPlatforms, spacing, theme, toggleVariants, tritanopiaTheme, typography, useHelp, zIndex, zenbidThemeConfig };