@caffeinebounce/ui 0.62.3 → 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 (96) hide show
  1. package/README.md +1 -1
  2. package/dist/blog.js +7 -6
  3. package/dist/blog.mjs +2 -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} +3 -3
  7. package/dist/{chunk-6ZJCK6KH.js → chunk-375DECW4.js} +31 -31
  8. package/dist/{chunk-PZRI43EZ.js → chunk-46JYKBRX.js} +0 -43
  9. package/dist/chunk-5D55OVD5.js +75 -0
  10. package/dist/{chunk-JORVSG52.js → chunk-663CFAHS.js} +211 -269
  11. package/dist/chunk-6HKJDV43.mjs +48 -0
  12. package/dist/chunk-6NCRGHV3.mjs +64 -0
  13. package/dist/{chunk-OLAAXLXY.mjs → chunk-6QAKQG57.mjs} +4 -4
  14. package/dist/{chunk-N6AFNFZR.mjs → chunk-7ERVZXIN.mjs} +214 -270
  15. package/dist/chunk-APFEP5B7.mjs +100 -0
  16. package/dist/chunk-C3OADNSG.js +348 -0
  17. package/dist/{chunk-GIJQE3JR.js → chunk-DH5Z3ETN.js} +66 -45
  18. package/dist/chunk-DYWZ23QT.mjs +90 -0
  19. package/dist/{chunk-DTVWRRFN.mjs → chunk-E67IR6HU.mjs} +30 -9
  20. package/dist/{chunk-OVNLC5RD.mjs → chunk-EXQSWHLD.mjs} +6 -6
  21. package/dist/{chunk-ZOA7B32D.js → chunk-F35KL6TX.js} +9 -9
  22. package/dist/{chunk-YSLD2HLP.mjs → chunk-FFJC66KO.mjs} +1 -1
  23. package/dist/{chunk-MPZFPU4X.js → chunk-GMBLPQ3I.js} +3 -3
  24. package/dist/chunk-IJFPPLQW.js +50 -0
  25. package/dist/{chunk-BMFQG6RA.mjs → chunk-KJIX6V32.mjs} +107 -1885
  26. package/dist/chunk-LABHD4PU.js +109 -0
  27. package/dist/{chunk-GAIQJCAZ.js → chunk-LT5VD4KR.js} +149 -1953
  28. package/dist/{chunk-7DHKQODW.mjs → chunk-LTLCIRZY.mjs} +256 -474
  29. package/dist/chunk-N5BHXWR3.mjs +34 -0
  30. package/dist/chunk-OCO3Z5YA.js +37 -0
  31. package/dist/chunk-OIJ7XMDV.mjs +71 -0
  32. package/dist/chunk-ORBH4IBC.mjs +316 -0
  33. package/dist/chunk-OWWOAYIY.js +2652 -0
  34. package/dist/chunk-PFHOXDSW.mjs +10 -0
  35. package/dist/chunk-QRS7DJGS.js +103 -0
  36. package/dist/{chunk-NXPEJ2UR.mjs → chunk-R3X4B4JJ.mjs} +53 -6
  37. package/dist/chunk-RM7ACPTM.mjs +2601 -0
  38. package/dist/chunk-RODSGPBB.mjs +75 -0
  39. package/dist/{chunk-T6ZBA6VJ.js → chunk-UHAV34YX.js} +8 -8
  40. package/dist/{chunk-GUSTCU2W.mjs → chunk-ULANYJ7Y.mjs} +1 -59
  41. package/dist/chunk-ULDE7QSN.js +70 -0
  42. package/dist/chunk-UT36VNVZ.mjs +47 -0
  43. package/dist/chunk-UY3H4PKB.js +71 -0
  44. package/dist/{chunk-KB7UXIQZ.mjs → chunk-VIVWFQG5.mjs} +2 -1
  45. package/dist/{chunk-ESZ7CBA2.js → chunk-VKBJ3SGT.js} +6 -5
  46. package/dist/{chunk-UM7WMXIU.js → chunk-W3YOQ5ZD.js} +264 -505
  47. package/dist/{chunk-GHOFYK2E.js → chunk-XGJL6DLV.js} +55 -5
  48. package/dist/chunk-YRIBFIQ5.js +116 -0
  49. package/dist/chunk-ZWWJ3RRA.js +15 -0
  50. package/dist/data-grid.d.cts +241 -0
  51. package/dist/data-grid.d.ts +241 -0
  52. package/dist/data-grid.js +6486 -0
  53. package/dist/data-grid.mjs +6459 -0
  54. package/dist/data-table-CDQBo-Ve.d.ts +818 -0
  55. package/dist/data-table-jLzt6plY.d.cts +818 -0
  56. package/dist/data-table.d.cts +8 -42
  57. package/dist/data-table.d.ts +8 -42
  58. package/dist/data-table.js +61 -187
  59. package/dist/data-table.mjs +11 -5
  60. package/dist/finance.d.cts +534 -0
  61. package/dist/finance.d.ts +534 -0
  62. package/dist/finance.js +188 -0
  63. package/dist/finance.mjs +15 -0
  64. package/dist/forms.js +9 -6
  65. package/dist/forms.mjs +7 -4
  66. package/dist/{hooks-B2jU1GVT.d.ts → hooks-A55E0fgf.d.ts} +3 -2
  67. package/dist/{hooks-8ORd7T1A.d.cts → hooks-Bys_AZPI.d.cts} +3 -2
  68. package/dist/hooks.d.cts +1 -1
  69. package/dist/hooks.d.ts +1 -1
  70. package/dist/hooks.js +26 -23
  71. package/dist/hooks.mjs +6 -3
  72. package/dist/index.d.cts +536 -665
  73. package/dist/index.d.ts +536 -665
  74. package/dist/index.js +3829 -3408
  75. package/dist/index.mjs +2067 -1767
  76. package/dist/layouts.js +25 -25
  77. package/dist/layouts.mjs +4 -4
  78. package/dist/marketing.js +74 -74
  79. package/dist/marketing.mjs +4 -4
  80. package/dist/navigation.js +28 -28
  81. package/dist/navigation.mjs +6 -6
  82. package/dist/primitives.d.cts +72 -109
  83. package/dist/primitives.d.ts +72 -109
  84. package/dist/primitives.js +78 -72
  85. package/dist/primitives.mjs +8 -6
  86. package/dist/settings.js +9 -9
  87. package/dist/settings.mjs +4 -4
  88. package/package.json +17 -1
  89. package/dist/UnifiedTableControls-CG299y9h.d.ts +0 -1233
  90. package/dist/UnifiedTableControls-CIjRpNhy.d.cts +0 -1233
  91. package/dist/chunk-GMBGWOCR.mjs +0 -49
  92. package/dist/chunk-HBLKVQIQ.mjs +0 -23
  93. package/dist/chunk-HMAMMC72.js +0 -26
  94. package/dist/chunk-MVYRNJA6.js +0 -75
  95. /package/dist/{chunk-RVEFPVZF.mjs → chunk-C57MX3BG.mjs} +0 -0
  96. /package/dist/{chunk-C4UT5V3P.js → chunk-OWHI5VGJ.js} +0 -0
package/dist/index.mjs CHANGED
@@ -1,42 +1,51 @@
1
1
  "use client";
2
- 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';
3
- export { FormWizard, useFormWizardNavigation } from './chunk-YSLD2HLP.mjs';
4
- export { PageHeader, SettingsLayout, SettingsRow, SettingsSection, SettingsTabContent, SettingsTabs } from './chunk-OLAAXLXY.mjs';
5
- import { Textarea, InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './chunk-N6AFNFZR.mjs';
6
- 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';
7
- import { Badge } from './chunk-GUSTCU2W.mjs';
8
- export { Alert, AlertDescription, AlertTitle, Badge, badgeVariants } from './chunk-GUSTCU2W.mjs';
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';
9
15
  import { Card, CardHeader, CardTitle, CardDescription, CardContent } from './chunk-YL7RZRHM.mjs';
10
16
  export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-YL7RZRHM.mjs';
11
- import { Switch, DatePicker } from './chunk-BMFQG6RA.mjs';
12
- 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';
13
- import { Dialog, DialogContent, DialogClose, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from './chunk-5THF4YP6.mjs';
14
- 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';
15
19
  import { Label } from './chunk-KHCC5UKW.mjs';
16
20
  export { Label } from './chunk-KHCC5UKW.mjs';
17
- export { StudioEditor } from './chunk-72JGQ7IJ.mjs';
18
- 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-DTVWRRFN.mjs';
19
- export { Tabs, TabsContent, TabsList, TabsTrigger } from './chunk-GMBGWOCR.mjs';
20
- export { ChartContainer, ChartTooltip, ChartTooltipContent } from './chunk-Q52ZEL62.mjs';
21
- import { useSessionErrors } from './chunk-KB7UXIQZ.mjs';
22
- 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';
23
- import { useDataTableContext, Popover, PopoverAnchor, PopoverContent } from './chunk-7DHKQODW.mjs';
24
- 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';
25
36
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-6BUBNZPG.mjs';
26
37
  export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './chunk-6BUBNZPG.mjs';
27
- 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-OVNLC5RD.mjs';
28
- export { NewsletterSignup } from './chunk-ZFLZA7UP.mjs';
29
- import './chunk-T5R6HUDG.mjs';
30
- export { Container } from './chunk-RVEFPVZF.mjs';
31
- 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-NXPEJ2UR.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';
32
44
  import { Separator } from './chunk-ZKUIUE7W.mjs';
33
45
  export { Separator } from './chunk-ZKUIUE7W.mjs';
46
+ import { SizedSpinner } from './chunk-N5BHXWR3.mjs';
47
+ export { SizedSpinner as Spinner, spinnerVariants } from './chunk-N5BHXWR3.mjs';
34
48
  export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger } from './chunk-FRRS2YZH.mjs';
35
- import { Spinner } from './chunk-HBLKVQIQ.mjs';
36
- export { Spinner, spinnerVariants } from './chunk-HBLKVQIQ.mjs';
37
- export { useScrollDirection } from './chunk-G5TQWWQA.mjs';
38
- import { Button } from './chunk-VBD4Q5LL.mjs';
39
- export { Button, buttonVariants } from './chunk-VBD4Q5LL.mjs';
40
49
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './chunk-OFQLWSUR.mjs';
41
50
  import { Tooltip, TooltipTrigger, TooltipContent } from './chunk-YKZEKJMZ.mjs';
42
51
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-YKZEKJMZ.mjs';
@@ -44,6 +53,7 @@ import { Input } from './chunk-STEP6C4C.mjs';
44
53
  export { Input, inputVariants } from './chunk-STEP6C4C.mjs';
45
54
  import { getDataStateIcon, DATA_STATE_COPY, getDataStateIconClassName } from './chunk-MHZXUOGN.mjs';
46
55
  export { getAvatarGradient, getGradientIndex, getGradientPairs, resolveDataState } from './chunk-MHZXUOGN.mjs';
56
+ export { ChartContainer, ChartTooltip, ChartTooltipContent } from './chunk-Q52ZEL62.mjs';
47
57
  import { cn } from './chunk-IMKLN273.mjs';
48
58
  export { cn } from './chunk-IMKLN273.mjs';
49
59
  import { toast } from 'sonner';
@@ -52,15 +62,16 @@ import * as React from 'react';
52
62
  import { createContext, useState, useRef, useEffect, useCallback, useId, useMemo, useContext, isValidElement, cloneElement, createElement } from 'react';
53
63
  import { useErrorLoggerSafe } from '@caffeinebounce/logger/client';
54
64
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
55
- 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';
56
66
  import { REGEXP_ONLY_DIGITS } from 'input-otp';
57
67
  import { cva } from 'class-variance-authority';
58
68
  export { ThemeProvider } from 'next-themes';
59
69
  import { createPortal } from 'react-dom';
60
70
  import { AnimatePresence, motion, useMotionValue, useAnimationControls, useSpring, useTransform } from 'motion/react';
71
+ import { Slot } from '@radix-ui/react-slot';
61
72
  import * as ProgressPrimitive from '@radix-ui/react-progress';
62
73
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
63
- import * as SliderPrimitive from '@radix-ui/react-slider';
74
+ import * as TogglePrimitive from '@radix-ui/react-toggle';
64
75
  import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
65
76
  import { preventWidows } from '@caffeinebounce/shared-utils';
66
77
 
@@ -128,8 +139,6 @@ function CompanyNameEditableCell({
128
139
  const [name, setName] = useState(initialName || "");
129
140
  const [dbaName, setDbaName] = useState(initialDbaName || "");
130
141
  const firstInputRef = useRef(null);
131
- const context = useDataTableContext();
132
- const isCompact = context?.density === "compact";
133
142
  const { isLoading, save } = useEditableCellSave();
134
143
  useEffect(() => {
135
144
  if (isEditing && firstInputRef.current) {
@@ -255,13 +264,13 @@ function CompanyNameEditableCell({
255
264
  type: "button",
256
265
  className: cn(
257
266
  "group flex w-full text-left cursor-pointer hover:bg-muted/50 px-2 -mx-2 rounded transition-colors",
258
- isCompact ? "items-center" : "flex-col py-1"
267
+ "flex-col py-1"
259
268
  ),
260
269
  onClick: () => setIsEditing(true),
261
270
  title: "Click to edit company details",
262
271
  children: [
263
272
  /* @__PURE__ */ jsx("span", { className: "font-medium truncate", children: name }),
264
- !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: [
265
274
  "DBA: ",
266
275
  dbaName
267
276
  ] })
@@ -285,8 +294,6 @@ function EditableCell({
285
294
  );
286
295
  const inputRef = useRef(null);
287
296
  const textareaRef = useRef(null);
288
- const context = useDataTableContext();
289
- const isCompact = context?.density === "compact";
290
297
  const { isLoading, save } = useEditableCellSave();
291
298
  useEffect(() => {
292
299
  if (isEditing) {
@@ -465,7 +472,7 @@ function EditableCell({
465
472
  type: "button",
466
473
  className: cn(
467
474
  "group flex items-center w-full text-left gap-2 cursor-pointer hover:bg-muted/50 px-2 -mx-2 rounded transition-colors",
468
- !isCompact && "min-h-[32px]"
475
+ "min-h-[32px]"
469
476
  ),
470
477
  onClick: () => setIsEditing(true),
471
478
  title: "Click to edit",
@@ -637,7 +644,7 @@ function MFAChallenge({
637
644
  setCodeSent(false);
638
645
  };
639
646
  if (loading) {
640
- 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" }) }) });
641
648
  }
642
649
  if (factors.length === 0) {
643
650
  return null;
@@ -936,7 +943,7 @@ function MFARecovery({
936
943
  setLinkSent(false);
937
944
  };
938
945
  if (loading) {
939
- 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" }) }) });
940
947
  }
941
948
  return /* @__PURE__ */ jsx(
942
949
  "div",
@@ -1561,7 +1568,7 @@ function FeedbackDialog({
1561
1568
  /* @__PURE__ */ jsxs(DialogFooter, { children: [
1562
1569
  /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
1563
1570
  /* @__PURE__ */ jsx(Button, { onClick: handleSubmit, disabled: isSubmitDisabled, children: isSubmitting ? /* @__PURE__ */ jsxs(Fragment, { children: [
1564
- /* @__PURE__ */ jsx(Spinner, { className: "mr-2 h-4 w-4" }),
1571
+ /* @__PURE__ */ jsx(SizedSpinner, { className: "mr-2 h-4 w-4" }),
1565
1572
  "Sending..."
1566
1573
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1567
1574
  /* @__PURE__ */ jsx(Send, { className: "mr-2 h-4 w-4" }),
@@ -1817,570 +1824,235 @@ function DisclosureFootnotes({
1817
1824
  }
1818
1825
  );
1819
1826
  }
1820
- function HelpArticleIndex({ groups, onSelect }) {
1821
- return /* @__PURE__ */ jsx("div", { className: "space-y-6", children: groups.map((group, index) => /* @__PURE__ */ jsxs("div", { children: [
1822
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
1823
- group.icon,
1824
- /* @__PURE__ */ jsx("h3", { className: "font-medium", children: group.title })
1825
- ] }),
1826
- /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.articles.map((article) => /* @__PURE__ */ jsxs(
1827
- "button",
1828
- {
1829
- type: "button",
1830
- onClick: () => onSelect(article.slug),
1831
- className: "w-full text-left p-2 rounded hover:bg-accent transition-colors flex items-center justify-between group",
1832
- children: [
1833
- /* @__PURE__ */ jsx("span", { className: "text-sm", children: article.title }),
1834
- /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity" })
1835
- ]
1836
- },
1837
- article.slug
1838
- )) })
1839
- ] }, index)) });
1840
- }
1841
- function HelpArticleView({
1842
- article,
1843
- onNavigate,
1844
- onBackToIndex,
1845
- relatedArticles = [],
1846
- isLoading = false,
1847
- children
1848
- }) {
1849
- return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
1850
- /* @__PURE__ */ jsxs("div", { children: [
1851
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground mb-2", children: [
1852
- /* @__PURE__ */ jsx(
1853
- "button",
1854
- {
1855
- type: "button",
1856
- onClick: onBackToIndex,
1857
- className: "capitalize hover:text-foreground hover:underline transition-colors cursor-pointer",
1858
- children: article.category
1859
- }
1860
- ),
1861
- article.subcategory && /* @__PURE__ */ jsxs(Fragment, { children: [
1862
- /* @__PURE__ */ jsx(ChevronRight, { className: "size-3" }),
1863
- /* @__PURE__ */ jsx("span", { className: "capitalize", children: article.subcategory })
1864
- ] })
1865
- ] }),
1866
- /* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold", children: article.title }),
1867
- /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1", children: article.description })
1868
- ] }),
1869
- /* @__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." }) }),
1870
- article.tags && article.tags.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
1871
- /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Tags" }),
1872
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: article.tags.map((tag) => /* @__PURE__ */ jsx(
1873
- "span",
1874
- {
1875
- className: "inline-flex px-2 py-0.5 text-xs rounded-full bg-muted",
1876
- children: tag
1877
- },
1878
- tag
1879
- )) })
1880
- ] }),
1881
- relatedArticles.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-4 border-t", children: [
1882
- /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-2", children: "Related Articles" }),
1883
- /* @__PURE__ */ jsx("div", { className: "space-y-2", children: relatedArticles.map((related) => /* @__PURE__ */ jsx(
1884
- "button",
1885
- {
1886
- type: "button",
1887
- onClick: () => onNavigate(related.slug),
1888
- className: "w-full text-left p-2 rounded border hover:bg-accent transition-colors text-sm",
1889
- children: /* @__PURE__ */ jsx("p", { className: "font-medium", children: related.title })
1890
- },
1891
- related.slug
1892
- )) })
1893
- ] })
1894
- ] });
1895
- }
1896
- var HelpContext = createContext(null);
1897
- function HelpProvider({
1898
- children,
1899
- getArticle,
1900
- searchArticles,
1901
- getArticleForFeature,
1902
- getArticleForRoute,
1903
- getContextForRoute,
1904
- pathname,
1905
- 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
1906
1844
  }) {
1907
- const [isOpen, setIsOpen] = useState(false);
1908
- const [activeArticleSlug, setActiveArticleSlug] = useState(
1909
- null
1910
- );
1911
- const [searchQuery, setSearchQuery] = useState("");
1912
- const [history, setHistory] = useState([]);
1913
- const helpContext = useMemo(
1914
- () => isAdmin ? "admin" : getContextForRoute(pathname),
1915
- [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]
1916
1855
  );
1917
- const activeArticle = useMemo(() => {
1918
- if (!activeArticleSlug) return null;
1919
- return getArticle(activeArticleSlug);
1920
- }, [activeArticleSlug, getArticle]);
1921
- const searchResults = useMemo(() => {
1922
- if (!searchQuery.trim()) return [];
1923
- return searchArticles(searchQuery);
1924
- }, [searchQuery, searchArticles]);
1925
- const openHelp = useCallback(
1926
- (articleSlug) => {
1927
- setIsOpen(true);
1928
- if (articleSlug) {
1929
- setActiveArticleSlug(articleSlug);
1930
- setHistory([]);
1931
- } else {
1932
- const contextualSlug = getArticleForRoute(pathname);
1933
- setActiveArticleSlug(contextualSlug);
1934
- setHistory([]);
1935
- }
1936
- 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);
1937
1888
  },
1938
- [pathname, getArticleForRoute]
1889
+ [onValueChange]
1939
1890
  );
1940
- const closeHelp = useCallback(() => {
1941
- setIsOpen(false);
1942
- }, []);
1943
- const toggleHelp = useCallback(() => {
1944
- if (isOpen) {
1945
- closeHelp();
1946
- } else {
1947
- 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);
1948
1907
  }
1949
- }, [isOpen, openHelp, closeHelp]);
1950
- const setActiveArticle = useCallback((slug) => {
1951
- setActiveArticleSlug(slug);
1952
- setSearchQuery("");
1908
+ }, [shouldFocusAfterClear, value]);
1909
+ const handleInputChange = useCallback((e) => {
1910
+ const newValue = e.target.value;
1911
+ setInputValue(newValue);
1912
+ setOpen(true);
1953
1913
  }, []);
1954
- const performSearch = useCallback((query) => {
1955
- setIsOpen(true);
1956
- setSearchQuery(query);
1957
- setActiveArticleSlug(null);
1914
+ const handleInputFocus = useCallback(() => {
1915
+ setOpen(true);
1958
1916
  }, []);
1959
- const openFeatureHelp = useCallback(
1960
- (featureKey) => {
1961
- const articleSlug = getArticleForFeature(featureKey);
1962
- if (articleSlug) {
1963
- setIsOpen(true);
1964
- setActiveArticleSlug(articleSlug);
1965
- setHistory([]);
1966
- 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;
1967
1928
  }
1968
- },
1969
- [getArticleForFeature]
1970
- );
1971
- const navigateToArticle = useCallback(
1972
- (slug) => {
1973
- if (activeArticleSlug && activeArticleSlug !== slug) {
1974
- 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;
1975
1966
  }
1976
- setActiveArticleSlug(slug);
1977
- setSearchQuery("");
1978
1967
  },
1979
- [activeArticleSlug]
1968
+ [
1969
+ open,
1970
+ highlightedIndex,
1971
+ totalItems,
1972
+ showCreateOption,
1973
+ filteredOptions,
1974
+ handleCreateNew,
1975
+ handleSelect,
1976
+ selectedOption
1977
+ ]
1980
1978
  );
1981
- const goBack = useCallback(() => {
1982
- if (history.length > 0) {
1983
- const newHistory = [...history];
1984
- const previousSlug = newHistory.pop();
1985
- setHistory(newHistory);
1986
- setActiveArticleSlug(previousSlug || null);
1987
- }
1988
- }, [history]);
1989
- const canGoBack = history.length > 0;
1990
1979
  useEffect(() => {
1991
- function handleKeyDown(event) {
1992
- if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "H") {
1993
- event.preventDefault();
1994
- toggleHelp();
1995
- }
1996
- if (event.key === "Escape" && isOpen) {
1997
- event.preventDefault();
1998
- closeHelp();
1999
- }
1980
+ if (highlightedIndex >= 0 && listRef.current) {
1981
+ const items = listRef.current.querySelectorAll("[data-option]");
1982
+ const item = items[highlightedIndex];
1983
+ item?.scrollIntoView({ block: "nearest" });
2000
1984
  }
2001
- window.addEventListener("keydown", handleKeyDown);
2002
- return () => window.removeEventListener("keydown", handleKeyDown);
2003
- }, [toggleHelp, closeHelp, isOpen]);
2004
- useEffect(() => {
2005
- function handleClick(event) {
2006
- const target = event.target;
2007
- const link = target.closest('a[href="/help"], a[href="/admin/help"]');
2008
- if (link && !link.hasAttribute("data-prevent-help-intercept")) {
2009
- event.preventDefault();
2010
- event.stopPropagation();
2011
- toggleHelp();
1985
+ }, [highlightedIndex]);
1986
+ const handleMouseMove = useCallback(
1987
+ (e) => {
1988
+ if (selectedOption?.description) {
1989
+ setTooltipPosition({ x: e.clientX, y: e.clientY });
2012
1990
  }
2013
- }
2014
- document.addEventListener("click", handleClick, true);
2015
- return () => document.removeEventListener("click", handleClick, true);
2016
- }, [toggleHelp]);
2017
- const value = {
2018
- isOpen,
2019
- openHelp,
2020
- closeHelp,
2021
- toggleHelp,
2022
- activeArticle,
2023
- setActiveArticle,
2024
- helpContext,
2025
- searchQuery,
2026
- setSearchQuery,
2027
- performSearch,
2028
- searchResults,
2029
- openFeatureHelp,
2030
- navigateToArticle,
2031
- goBack,
2032
- history,
2033
- canGoBack
2034
- };
2035
- return /* @__PURE__ */ jsx(HelpContext.Provider, { value, children });
2036
- }
2037
- function useHelp() {
2038
- const context = useContext(HelpContext);
2039
- if (!context) {
2040
- throw new Error("useHelp must be used within a HelpProvider");
2041
- }
2042
- return context;
2043
- }
2044
- function HelpButton({
2045
- featureKey,
2046
- variant = "ghost",
2047
- size = "icon",
2048
- className,
2049
- label = "Help",
2050
- showLabel = false
2051
- }) {
2052
- const { openHelp, openFeatureHelp } = useHelp();
2053
- const handleClick = () => {
2054
- if (featureKey) {
2055
- openFeatureHelp(featureKey);
2056
- } else {
2057
- openHelp();
2058
- }
2059
- };
2060
- return /* @__PURE__ */ jsxs(
2061
- Button,
2062
- {
2063
- variant,
2064
- size: showLabel ? size : "icon",
2065
- onClick: handleClick,
2066
- className: cn(showLabel && "gap-2", className),
2067
- "aria-label": label,
2068
- children: [
2069
- /* @__PURE__ */ jsx(HelpCircle, { className: "size-4" }),
2070
- showLabel && /* @__PURE__ */ jsx("span", { children: label })
2071
- ]
2072
- }
1991
+ },
1992
+ [selectedOption?.description]
2073
1993
  );
2074
- }
2075
- function HelpSearchResults({
2076
- results,
2077
- query,
2078
- onSelect,
2079
- categoryIcons = {}
2080
- }) {
2081
- if (results.length === 0) {
2082
- return /* @__PURE__ */ jsxs("div", { className: "text-center py-8", children: [
2083
- /* @__PURE__ */ jsx(HelpCircle, { className: "size-12 mx-auto text-muted-foreground/50 mb-3" }),
2084
- /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
2085
- "No results found for \u201C",
2086
- query,
2087
- "\u201D"
2088
- ] }),
2089
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground/70 mt-1", children: "Try different keywords or browse categories below" })
2090
- ] });
2091
- }
2092
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2093
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: [
2094
- results.length,
2095
- " result",
2096
- results.length !== 1 ? "s" : "",
2097
- " for \u201C",
2098
- query,
2099
- "\u201D"
2100
- ] }),
2101
- results.map((result) => {
2102
- const Icon = categoryIcons[result.category] || HelpCircle;
2103
- return /* @__PURE__ */ jsx(
2104
- "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",
2105
2006
  {
2106
- type: "button",
2107
- onClick: () => onSelect(result.slug),
2108
- className: "w-full text-left p-3 rounded-lg border hover:bg-accent transition-colors",
2109
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
2110
- /* @__PURE__ */ jsx(Icon, { className: "size-4 mt-0.5 text-muted-foreground" }),
2111
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2112
- /* @__PURE__ */ jsx("p", { className: "font-medium text-sm", children: result.title }),
2113
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2 mt-0.5", children: result.description })
2114
- ] }),
2115
- /* @__PURE__ */ jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" })
2116
- ] })
2117
- },
2118
- result.slug
2119
- );
2120
- })
2121
- ] });
2122
- }
2123
- function HelpTooltip({
2124
- content,
2125
- featureKey,
2126
- size = "sm",
2127
- className
2128
- }) {
2129
- const { openFeatureHelp } = useHelp();
2130
- const iconSize = size === "sm" ? "size-3.5" : "size-4";
2131
- const handleClick = (e) => {
2132
- if (featureKey) {
2133
- e.preventDefault();
2134
- e.stopPropagation();
2135
- openFeatureHelp(featureKey);
2136
- }
2137
- };
2138
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
2139
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
2140
- "button",
2141
- {
2142
- type: "button",
2143
- onClick: handleClick,
2144
- className: `inline-flex items-center justify-center text-muted-foreground hover:text-foreground transition-colors ${className}`,
2145
- "aria-label": "Help",
2146
- children: /* @__PURE__ */ jsx(HelpCircle, { className: iconSize })
2147
- }
2148
- ) }),
2149
- /* @__PURE__ */ jsxs(TooltipContent, { className: "max-w-xs", children: [
2150
- /* @__PURE__ */ jsx("p", { className: "text-sm", children: content }),
2151
- featureKey && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Click to learn more" })
2152
- ] })
2153
- ] });
2154
- }
2155
- function Autocomplete({
2156
- options,
2157
- value,
2158
- onValueChange,
2159
- placeholder = "Type to search...",
2160
- emptyText = "No results found.",
2161
- disabled = false,
2162
- allowCreate = false,
2163
- createLabel = "Create new",
2164
- onCreateNew,
2165
- onEditSelected,
2166
- loading = false,
2167
- className,
2168
- error = false,
2169
- "aria-label": ariaLabel,
2170
- id,
2171
- name
2172
- }) {
2173
- const [open, setOpen] = useState(false);
2174
- const [inputValue, setInputValue] = useState("");
2175
- const [highlightedIndex, setHighlightedIndex] = useState(-1);
2176
- const inputRef = useRef(null);
2177
- const listRef = useRef(null);
2178
- const [tooltipVisible, setTooltipVisible] = useState(false);
2179
- const [tooltipPosition, setTooltipPosition] = useState({ x: 0, y: 0 });
2180
- const selectedOption = useMemo(
2181
- () => options.find((opt) => opt.value === value),
2182
- [options, value]
2183
- );
2184
- useEffect(() => {
2185
- if (selectedOption && !open) {
2186
- setInputValue(selectedOption.label);
2187
- } else if (!value && !open) {
2188
- setInputValue("");
2189
- }
2190
- }, [selectedOption, value, open]);
2191
- const filteredOptions = useMemo(() => {
2192
- if (!inputValue) return options;
2193
- const search = inputValue.toLowerCase();
2194
- return options.filter(
2195
- (opt) => opt.label.toLowerCase().includes(search) || opt.description?.toLowerCase().includes(search)
2196
- );
2197
- }, [options, inputValue]);
2198
- const exactMatch = useMemo(() => {
2199
- if (!inputValue) return true;
2200
- const search = inputValue.toLowerCase();
2201
- return options.some((opt) => opt.label.toLowerCase() === search);
2202
- }, [options, inputValue]);
2203
- const showCreateOption = allowCreate && !!inputValue && !exactMatch;
2204
- const totalItems = filteredOptions.length + (showCreateOption ? 1 : 0);
2205
- const hasContent = filteredOptions.length > 0 || showCreateOption;
2206
- const effectiveOpen = open && hasContent;
2207
- useEffect(() => {
2208
- setHighlightedIndex(-1);
2209
- }, []);
2210
- const handleSelect = useCallback(
2211
- (selectedValue, label) => {
2212
- onValueChange?.(selectedValue);
2213
- setInputValue(label);
2214
- setOpen(false);
2215
- setHighlightedIndex(-1);
2216
- },
2217
- [onValueChange]
2218
- );
2219
- const handleCreateNew = useCallback(() => {
2220
- onCreateNew?.(inputValue);
2221
- setOpen(false);
2222
- setHighlightedIndex(-1);
2223
- }, [onCreateNew, inputValue]);
2224
- const [shouldFocusAfterClear, setShouldFocusAfterClear] = useState(false);
2225
- const handleClear = useCallback(() => {
2226
- onValueChange?.("");
2227
- setInputValue("");
2228
- setOpen(false);
2229
- setShouldFocusAfterClear(true);
2230
- }, [onValueChange]);
2231
- useEffect(() => {
2232
- if (shouldFocusAfterClear && !value && inputRef.current) {
2233
- inputRef.current.focus();
2234
- setShouldFocusAfterClear(false);
2235
- }
2236
- }, [shouldFocusAfterClear, value]);
2237
- const handleInputChange = useCallback((e) => {
2238
- const newValue = e.target.value;
2239
- setInputValue(newValue);
2240
- setOpen(true);
2241
- }, []);
2242
- const handleInputFocus = useCallback(() => {
2243
- setOpen(true);
2244
- }, []);
2245
- const handleInputClick = useCallback(() => {
2246
- setOpen(true);
2247
- }, []);
2248
- const handleKeyDown = useCallback(
2249
- (e) => {
2250
- if (!open) {
2251
- if (e.key === "ArrowDown" || e.key === "ArrowUp") {
2252
- e.preventDefault();
2253
- setOpen(true);
2254
- }
2255
- return;
2256
- }
2257
- switch (e.key) {
2258
- case "ArrowDown":
2259
- e.preventDefault();
2260
- setHighlightedIndex(
2261
- (prev) => prev < totalItems - 1 ? prev + 1 : prev
2262
- );
2263
- break;
2264
- case "ArrowUp":
2265
- e.preventDefault();
2266
- setHighlightedIndex((prev) => prev > 0 ? prev - 1 : -1);
2267
- break;
2268
- case "Enter":
2269
- e.preventDefault();
2270
- if (highlightedIndex >= 0) {
2271
- if (showCreateOption && highlightedIndex === filteredOptions.length) {
2272
- handleCreateNew();
2273
- } else if (highlightedIndex < filteredOptions.length) {
2274
- const option = filteredOptions[highlightedIndex];
2275
- if (!option.disabled) {
2276
- handleSelect(option.value, option.label);
2277
- }
2278
- }
2279
- } else if (showCreateOption && filteredOptions.length === 0) {
2280
- handleCreateNew();
2281
- }
2282
- break;
2283
- case "Escape":
2284
- e.preventDefault();
2285
- setOpen(false);
2286
- setHighlightedIndex(-1);
2287
- if (selectedOption) {
2288
- setInputValue(selectedOption.label);
2289
- }
2290
- break;
2291
- case "Tab":
2292
- setOpen(false);
2293
- break;
2294
- }
2295
- },
2296
- [
2297
- open,
2298
- highlightedIndex,
2299
- totalItems,
2300
- showCreateOption,
2301
- filteredOptions,
2302
- handleCreateNew,
2303
- handleSelect,
2304
- selectedOption
2305
- ]
2306
- );
2307
- useEffect(() => {
2308
- if (highlightedIndex >= 0 && listRef.current) {
2309
- const items = listRef.current.querySelectorAll("[data-option]");
2310
- const item = items[highlightedIndex];
2311
- item?.scrollIntoView({ block: "nearest" });
2312
- }
2313
- }, [highlightedIndex]);
2314
- const handleMouseMove = useCallback(
2315
- (e) => {
2316
- if (selectedOption?.description) {
2317
- setTooltipPosition({ x: e.clientX, y: e.clientY });
2318
- }
2319
- },
2320
- [selectedOption?.description]
2321
- );
2322
- const handleMouseEnter = useCallback(() => {
2323
- if (selectedOption?.description) {
2324
- setTooltipVisible(true);
2325
- }
2326
- }, [selectedOption?.description]);
2327
- const handleMouseLeave = useCallback(() => {
2328
- setTooltipVisible(false);
2329
- }, []);
2330
- return /* @__PURE__ */ jsxs(Popover, { open: effectiveOpen, onOpenChange: setOpen, children: [
2331
- /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "relative", children: selectedOption ? /* @__PURE__ */ jsxs(Fragment, { children: [
2332
- /* @__PURE__ */ jsxs(
2333
- "div",
2334
- {
2335
- className: cn(
2336
- "flex h-9 w-full items-center gap-2 rounded-box border border-input bg-muted/30 px-2 py-1 shadow-xs",
2337
- disabled && "cursor-not-allowed opacity-50",
2338
- error && "border-destructive",
2339
- className
2340
- ),
2341
- onMouseEnter: handleMouseEnter,
2342
- onMouseLeave: handleMouseLeave,
2343
- onMouseMove: handleMouseMove,
2344
- children: [
2345
- /* @__PURE__ */ jsx(
2346
- Badge,
2347
- {
2348
- variant: "secondary",
2349
- className: "max-w-[calc(100%-4.5rem)] truncate font-normal",
2350
- children: selectedOption.label
2351
- }
2352
- ),
2353
- !disabled && !loading && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-0.5 shrink-0", children: [
2354
- onEditSelected && /* @__PURE__ */ jsxs(
2355
- Button,
2356
- {
2357
- type: "button",
2358
- variant: "ghost",
2359
- size: "icon",
2360
- className: "h-6 w-6 text-muted-foreground hover:text-foreground",
2361
- onClick: () => onEditSelected(selectedOption),
2362
- tabIndex: -1,
2363
- children: [
2364
- /* @__PURE__ */ jsx(Pencil, { className: "h-3 w-3" }),
2365
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Edit selection" })
2366
- ]
2367
- }
2368
- ),
2369
- /* @__PURE__ */ jsxs(
2370
- Button,
2371
- {
2372
- type: "button",
2373
- variant: "ghost",
2374
- size: "icon",
2375
- className: "h-6 w-6 text-muted-foreground hover:text-foreground",
2376
- onClick: handleClear,
2377
- tabIndex: -1,
2378
- children: [
2379
- /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" }),
2380
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Clear selection" })
2381
- ]
2382
- }
2383
- )
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
+ )
2384
2056
  ] }),
2385
2057
  loading && /* @__PURE__ */ jsx(Loader2, { className: "ml-auto h-4 w-4 shrink-0 animate-spin text-muted-foreground" })
2386
2058
  ]
@@ -2551,81 +2223,6 @@ function Autocomplete({
2551
2223
  )
2552
2224
  ] });
2553
2225
  }
2554
- function ButtonGroup({
2555
- className,
2556
- orientation = "horizontal",
2557
- ...props
2558
- }) {
2559
- return (
2560
- // biome-ignore lint/a11y/useSemanticElements: ButtonGroup is visual grouping, not a form fieldset
2561
- /* @__PURE__ */ jsx(
2562
- "div",
2563
- {
2564
- role: "group",
2565
- "data-orientation": orientation,
2566
- className: cn(
2567
- "flex",
2568
- orientation === "horizontal" ? "flex-row items-center -space-x-px" : "flex-col -space-y-px",
2569
- // Style direct children to have connected appearance
2570
- // Use !important to override Button's own shared box radius classes
2571
- "[&>*]:!rounded-none",
2572
- "[&>*:first-child]:!rounded-l-box",
2573
- "[&>*:last-child]:!rounded-r-box",
2574
- orientation === "vertical" && [
2575
- "[&>*:first-child]:!rounded-t-box [&>*:first-child]:!rounded-l-none",
2576
- "[&>*:last-child]:!rounded-b-box [&>*:last-child]:!rounded-r-none"
2577
- ],
2578
- // Handle nested button groups
2579
- "**:[role=group]:flex",
2580
- "**:[role=group]>*:!rounded-none",
2581
- "[&>[role=group]:first-child>*:first-child]:!rounded-l-box",
2582
- "[&>[role=group]:last-child>*:last-child]:!rounded-r-box",
2583
- className
2584
- ),
2585
- ...props
2586
- }
2587
- )
2588
- );
2589
- }
2590
- function ButtonGroupSeparator({
2591
- className,
2592
- orientation = "vertical",
2593
- ...props
2594
- }) {
2595
- return /* @__PURE__ */ jsx(
2596
- "hr",
2597
- {
2598
- "aria-orientation": orientation,
2599
- className: cn(
2600
- "bg-border border-0",
2601
- orientation === "vertical" ? "h-6 w-px" : "h-px w-6",
2602
- className
2603
- ),
2604
- ...props
2605
- }
2606
- );
2607
- }
2608
- function ButtonGroupText({
2609
- className,
2610
- asChild = false,
2611
- children,
2612
- ...props
2613
- }) {
2614
- if (asChild) {
2615
- return /* @__PURE__ */ jsx(Fragment, { children });
2616
- }
2617
- return /* @__PURE__ */ jsx(
2618
- "span",
2619
- {
2620
- className: cn(
2621
- "flex items-center px-3 text-sm text-muted-foreground",
2622
- className
2623
- ),
2624
- ...props,
2625
- children
2626
- }
2627
- );
2628
- }
2629
2226
  function HoverEffect({ items, className }) {
2630
2227
  const [hoveredIndex, setHoveredIndex] = useState(null);
2631
2228
  return /* @__PURE__ */ jsx(
@@ -3626,1269 +3223,1972 @@ function GooeyInput({
3626
3223
  }
3627
3224
  );
3628
3225
  }
3629
- function InfoTooltip({
3630
- content,
3631
- size = "sm",
3632
- className,
3633
- side = "top",
3634
- align = "center"
3635
- }) {
3636
- const iconSize = size === "sm" ? "size-3.5" : "size-4";
3637
- return /* @__PURE__ */ jsxs(Tooltip, { children: [
3638
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
3639
- "button",
3640
- {
3641
- type: "button",
3642
- className: cn(
3643
- "inline-flex items-center justify-center text-muted-foreground hover:text-foreground transition-colors ml-1",
3644
- className
3645
- ),
3646
- "aria-label": "More information",
3647
- children: /* @__PURE__ */ jsx(Info, { className: iconSize })
3648
- }
3649
- ) }),
3650
- /* @__PURE__ */ jsx(TooltipContent, { side, align, className: "max-w-xs", children: typeof content === "string" ? /* @__PURE__ */ jsx("p", { className: "text-sm", children: content }) : content })
3651
- ] });
3652
- }
3653
- 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({
3654
3426
  value,
3427
+ options,
3655
3428
  onSave,
3656
3429
  isLoading,
3657
- placeholder = "Click to edit...",
3658
- className,
3659
- multiline = false,
3660
- maxLength,
3661
- rows = 2
3430
+ placeholder = "Select...",
3431
+ className
3662
3432
  }) {
3663
3433
  const [isEditing, setIsEditing] = useState(false);
3664
- const [editValue, setEditValue] = useState(value);
3665
- const inputRef = useRef(null);
3666
- const textareaRef = useRef(null);
3667
- useEffect(() => {
3668
- setEditValue(value);
3669
- }, [value]);
3434
+ const selectRef = useRef(null);
3670
3435
  useEffect(() => {
3671
- if (isEditing) {
3672
- if (multiline && textareaRef.current) {
3673
- textareaRef.current.focus();
3674
- textareaRef.current.select();
3675
- } else if (inputRef.current) {
3676
- inputRef.current.focus();
3677
- inputRef.current.select();
3678
- }
3436
+ if (isEditing && selectRef.current) {
3437
+ selectRef.current.focus();
3679
3438
  }
3680
- }, [isEditing, multiline]);
3681
- const handleSave = () => {
3682
- const trimmedValue = editValue.trim();
3683
- if (trimmedValue !== value) {
3684
- onSave(trimmedValue);
3439
+ }, [isEditing]);
3440
+ const handleChange = (e) => {
3441
+ const selectedValue = e.target.value;
3442
+ if (selectedValue !== value) {
3443
+ onSave(selectedValue);
3685
3444
  }
3686
3445
  setIsEditing(false);
3687
3446
  };
3688
- const handleCancel = () => {
3689
- setEditValue(value);
3447
+ const handleBlur = () => {
3690
3448
  setIsEditing(false);
3691
3449
  };
3692
3450
  const handleKeyDown = (e) => {
3693
- if (e.key === "Enter" && !e.shiftKey) {
3694
- e.preventDefault();
3695
- handleSave();
3696
- } else if (e.key === "Escape") {
3697
- handleCancel();
3451
+ if (e.key === "Escape") {
3452
+ setIsEditing(false);
3698
3453
  }
3699
3454
  };
3455
+ const currentLabel = options.find((opt) => opt.value === value)?.label || placeholder;
3700
3456
  if (isEditing) {
3701
- if (multiline) {
3702
- 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
+ ),
3703
3628
  /* @__PURE__ */ jsx(
3704
- "textarea",
3629
+ "button",
3705
3630
  {
3706
- ref: textareaRef,
3707
- value: editValue,
3708
- onChange: (e) => setEditValue(e.target.value),
3709
- onKeyDown: handleKeyDown,
3710
- onBlur: handleSave,
3711
- disabled: isLoading,
3631
+ type: "button",
3632
+ onClick: handleIncrement,
3633
+ disabled: !canIncrement,
3712
3634
  className: cn(
3713
- "flex-1 bg-transparent border-none outline-none resize-none",
3714
- "text-muted-foreground focus:text-foreground min-h-[40px]",
3715
- "border-b border-dashed border-primary/50 focus:border-primary",
3716
- 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
3717
3640
  ),
3718
- placeholder,
3719
- rows
3641
+ tabIndex: -1,
3642
+ "aria-label": "Increase value",
3643
+ children: /* @__PURE__ */ jsx(Plus, { className: sizes.icon })
3720
3644
  }
3721
- ),
3722
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground mt-1" })
3723
- ] });
3645
+ )
3646
+ ]
3724
3647
  }
3725
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
3726
- /* @__PURE__ */ jsx(
3727
- "input",
3728
- {
3729
- ref: inputRef,
3730
- value: editValue,
3731
- onChange: (e) => setEditValue(e.target.value),
3732
- onKeyDown: handleKeyDown,
3733
- onBlur: handleSave,
3734
- disabled: isLoading,
3735
- maxLength,
3736
- className: cn(
3737
- "bg-transparent border-none outline-none",
3738
- "border-b border-dashed border-primary/50 focus:border-primary",
3739
- 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
+ }
3740
3725
  ),
3741
- placeholder,
3742
- style: {
3743
- width: `${Math.max(editValue.length, placeholder.length) + 2}ch`
3744
- }
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" })
3745
3750
  }
3746
- ),
3747
- 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 })
3748
3788
  ] });
3749
3789
  }
3750
- return /* @__PURE__ */ jsx(
3751
- "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,
3752
3881
  {
3753
- type: "button",
3754
- onClick: () => setIsEditing(true),
3755
- className: cn(
3756
- "text-left hover:text-primary transition-colors cursor-pointer",
3757
- "border-b border-transparent hover:border-dashed hover:border-primary/30",
3758
- !value && "text-muted-foreground/60 italic text-sm",
3759
- className
3760
- ),
3761
- 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
+ ]
3762
3888
  }
3763
3889
  );
3764
3890
  }
3765
- function InlineEditableDate({
3766
- value,
3767
- onSave,
3768
- isLoading,
3769
- placeholder = "Select date...",
3770
- className,
3771
- formatDisplay
3891
+ function StatCardValueContent({
3892
+ isCompact,
3893
+ displayValue,
3894
+ description,
3895
+ trend,
3896
+ footer
3772
3897
  }) {
3773
- const [isEditing, setIsEditing] = useState(false);
3774
- const handleDateChange = (date) => {
3775
- if (date) {
3776
- const newValue = date.toISOString().split("T")[0];
3777
- if (newValue !== value) {
3778
- onSave(newValue);
3779
- }
3780
- }
3781
- setIsEditing(false);
3782
- };
3783
- const displayDate = () => {
3784
- if (!value) return placeholder;
3785
- const date = new Date(value);
3786
- if (formatDisplay) return formatDisplay(date);
3787
- return date.toLocaleDateString();
3788
- };
3789
- if (isEditing) {
3790
- return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
3791
- /* @__PURE__ */ jsx(
3792
- DatePicker,
3793
- {
3794
- value: value ? new Date(value) : void 0,
3795
- onChange: handleDateChange
3796
- }
3797
- ),
3798
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }),
3799
- /* @__PURE__ */ jsx(
3800
- Button,
3801
- {
3802
- variant: "ghost",
3803
- size: "icon",
3804
- className: "h-6 w-6 hover:bg-transparent hover:text-primary",
3805
- onClick: () => setIsEditing(false),
3806
- children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
3807
- }
3808
- )
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 })
3809
3907
  ] });
3810
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 }) {
3811
3920
  return /* @__PURE__ */ jsxs(
3812
- "button",
3921
+ "div",
3813
3922
  {
3814
- type: "button",
3815
- onClick: () => setIsEditing(true),
3816
- className: cn(
3817
- "flex items-center gap-1 text-sm text-muted-foreground",
3818
- "hover:text-foreground transition-colors cursor-pointer",
3819
- className
3820
- ),
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",
3821
3925
  children: [
3822
- /* @__PURE__ */ jsx(Calendar, { className: "h-4 w-4" }),
3823
- 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
+ )
3824
3944
  ]
3825
3945
  }
3826
3946
  );
3827
3947
  }
3828
- 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,
3829
4056
  value,
3830
- options,
3831
- onSave,
3832
- isLoading,
3833
- placeholder = "Select...",
3834
- 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"
3835
4072
  }) {
3836
- const [isEditing, setIsEditing] = useState(false);
3837
- const selectRef = useRef(null);
3838
- useEffect(() => {
3839
- if (isEditing && selectRef.current) {
3840
- selectRef.current.focus();
3841
- }
3842
- }, [isEditing]);
3843
- const handleChange = (e) => {
3844
- const selectedValue = e.target.value;
3845
- if (selectedValue !== value) {
3846
- onSave(selectedValue);
3847
- }
3848
- 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"
3849
4084
  };
3850
- const handleBlur = () => {
3851
- 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");
3852
4090
  };
3853
- const handleKeyDown = (e) => {
3854
- if (e.key === "Escape") {
3855
- setIsEditing(false);
4091
+ const handleBodyClick = (e) => {
4092
+ e.stopPropagation();
4093
+ if (hasChart) {
4094
+ handleFlip();
4095
+ } else if (onClick) {
4096
+ onClick();
3856
4097
  }
3857
4098
  };
3858
- const currentLabel = options.find((opt) => opt.value === value)?.label || placeholder;
3859
- if (isEditing) {
3860
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
3861
- /* @__PURE__ */ jsx(
3862
- "select",
3863
- {
3864
- ref: selectRef,
3865
- value,
3866
- onChange: handleChange,
3867
- onBlur: handleBlur,
3868
- onKeyDown: handleKeyDown,
3869
- disabled: isLoading,
3870
- className: cn(
3871
- "bg-transparent border-none outline-none cursor-pointer",
3872
- "border-b border-dashed border-primary/50 focus:border-primary",
3873
- "text-foreground",
3874
- className
3875
- ),
3876
- children: options.map((option) => /* @__PURE__ */ jsx("option", { value: String(option.value), children: option.label }, String(option.value)))
3877
- }
3878
- ),
3879
- isLoading && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" })
3880
- ] });
3881
- }
3882
- return /* @__PURE__ */ jsx(
3883
- "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,
3884
4118
  {
3885
- type: "button",
3886
- onClick: () => setIsEditing(true),
3887
4119
  className: cn(
3888
- "text-left hover:text-primary transition-colors cursor-pointer",
3889
- "border-b border-transparent hover:border-dashed hover:border-primary/30",
3890
- !value && "text-muted-foreground/60 italic text-sm",
3891
- className
4120
+ "flex flex-row items-center justify-between space-y-0 py-0",
4121
+ isCompact ? "px-0" : "px-4"
3892
4122
  ),
3893
- 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
+ ]
3894
4157
  }
3895
4158
  );
3896
- }
3897
- var sizeClasses = {
3898
- sm: {
3899
- wrapper: "h-7",
3900
- button: "h-7 w-7",
3901
- input: "h-7 w-12 text-xs",
3902
- icon: "h-3 w-3"
3903
- },
3904
- md: {
3905
- wrapper: "h-8",
3906
- button: "h-8 w-8",
3907
- input: "h-8 w-14 text-sm",
3908
- icon: "h-3.5 w-3.5"
3909
- },
3910
- lg: {
3911
- wrapper: "h-10",
3912
- button: "h-10 w-10",
3913
- input: "h-10 w-16 text-base",
3914
- 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
+ );
3915
4191
  }
3916
- };
3917
- function NumberStepper({
3918
- value,
3919
- onChange,
3920
- min = 0,
3921
- max = Number.MAX_SAFE_INTEGER,
3922
- step = 1,
3923
- size = "md",
3924
- disabled,
3925
- className,
3926
- ...props
3927
- }) {
3928
- const sizes = sizeClasses[size];
3929
- const [inputValue, setInputValue] = React.useState(value.toString());
3930
- const [isFocused, setIsFocused] = React.useState(false);
3931
- React.useEffect(() => {
3932
- if (!isFocused) {
3933
- setInputValue(value.toString());
3934
- }
3935
- }, [value, isFocused]);
3936
- const handleDecrement = () => {
3937
- const newValue = Math.max(min, value - step);
3938
- onChange(newValue);
3939
- setInputValue(newValue.toString());
3940
- };
3941
- const handleIncrement = () => {
3942
- const newValue = Math.min(max, value + step);
3943
- onChange(newValue);
3944
- setInputValue(newValue.toString());
3945
- };
3946
- const handleInputChange = (e) => {
3947
- const inputVal = e.target.value;
3948
- if (inputVal === "" || /^[0-9]*$/.test(inputVal)) {
3949
- 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
+ )
3950
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"
3951
4271
  };
3952
- const handleFocus = () => {
3953
- 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"
3954
4277
  };
3955
- const handleBlur = () => {
3956
- setIsFocused(false);
3957
- if (inputValue === "") {
3958
- onChange(min);
3959
- setInputValue(min.toString());
3960
- return;
3961
- }
3962
- const numValue = Number.parseInt(inputValue, 10);
3963
- if (Number.isNaN(numValue)) {
3964
- onChange(min);
3965
- setInputValue(min.toString());
3966
- } else {
3967
- const clampedValue = Math.min(max, Math.max(min, numValue));
3968
- onChange(clampedValue);
3969
- setInputValue(clampedValue.toString());
3970
- }
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"
3971
4283
  };
3972
- const handleKeyDown = (e) => {
3973
- if (e.key === "ArrowUp") {
3974
- e.preventDefault();
3975
- handleIncrement();
3976
- } else if (e.key === "ArrowDown") {
3977
- e.preventDefault();
3978
- handleDecrement();
3979
- }
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"
3980
4289
  };
3981
- const canDecrement = !disabled && value > min;
3982
- const canIncrement = !disabled && value < max;
3983
- return /* @__PURE__ */ jsxs(
4290
+ return /* @__PURE__ */ jsx(
3984
4291
  "div",
3985
4292
  {
3986
4293
  className: cn(
3987
- "inline-flex items-center rounded-box border border-input bg-transparent dark:bg-input/30",
3988
- disabled && "opacity-50",
3989
- 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],
3990
4299
  className
3991
4300
  ),
3992
- children: [
3993
- /* @__PURE__ */ jsx(
3994
- "button",
3995
- {
3996
- type: "button",
3997
- onClick: handleDecrement,
3998
- disabled: !canDecrement,
3999
- className: cn(
4000
- "inline-flex items-center justify-center border-r border-input",
4001
- "text-muted-foreground hover:text-foreground hover:bg-muted/50",
4002
- "transition-colors disabled:opacity-50 disabled:pointer-events-none",
4003
- "rounded-l-md",
4004
- sizes.button
4005
- ),
4006
- tabIndex: -1,
4007
- "aria-label": "Decrease value",
4008
- children: /* @__PURE__ */ jsx(Minus, { className: sizes.icon })
4009
- }
4010
- ),
4011
- /* @__PURE__ */ jsx(
4012
- "input",
4013
- {
4014
- type: "text",
4015
- inputMode: "numeric",
4016
- pattern: "[0-9]*",
4017
- value: inputValue,
4018
- onChange: handleInputChange,
4019
- onKeyDown: handleKeyDown,
4020
- onFocus: handleFocus,
4021
- onBlur: handleBlur,
4022
- disabled,
4023
- className: cn(
4024
- "border-0 bg-transparent text-center focus:outline-none focus:ring-0 selection:bg-primary selection:text-primary-foreground",
4025
- "[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
4026
- sizes.input
4027
- ),
4028
- ...props
4029
- }
4030
- ),
4031
- /* @__PURE__ */ jsx(
4032
- "button",
4033
- {
4034
- type: "button",
4035
- onClick: handleIncrement,
4036
- disabled: !canIncrement,
4037
- className: cn(
4038
- "inline-flex items-center justify-center border-l border-input",
4039
- "text-muted-foreground hover:text-foreground hover:bg-muted/50",
4040
- "transition-colors disabled:opacity-50 disabled:pointer-events-none",
4041
- "rounded-r-md",
4042
- sizes.button
4043
- ),
4044
- tabIndex: -1,
4045
- "aria-label": "Increase value",
4046
- children: /* @__PURE__ */ jsx(Plus, { className: sizes.icon })
4047
- }
4048
- )
4049
- ]
4301
+ children
4050
4302
  }
4051
4303
  );
4052
4304
  }
4053
- function PageLoader({ className, message, ...props }) {
4054
- return /* @__PURE__ */ jsxs(
4055
- "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",
4056
4319
  {
4320
+ "data-slot": "text-highlight",
4321
+ "data-animated": !disableAnimation,
4057
4322
  className: cn(
4058
- "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,
4059
4326
  className
4060
4327
  ),
4061
- ...props,
4062
- children: [
4063
- /* @__PURE__ */ jsx(Spinner, { size: "lg" }),
4064
- message && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: message })
4065
- ]
4328
+ style: {
4329
+ backgroundPosition: "left center",
4330
+ ...animationStyle
4331
+ },
4332
+ children
4066
4333
  }
4067
4334
  );
4068
4335
  }
4069
- function PageSection({ children, className }) {
4070
- 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)) });
4071
4400
  }
4072
- function PageSections({
4073
- children,
4074
- separator: defaultSeparator = true,
4075
- separatorClassName,
4076
- className
4401
+ function HelpArticleView({
4402
+ article,
4403
+ onNavigate,
4404
+ onBackToIndex,
4405
+ relatedArticles = [],
4406
+ isLoading = false,
4407
+ children
4077
4408
  }) {
4078
- const sections = React.Children.toArray(children).filter(
4079
- React.isValidElement
4080
- );
4081
- return /* @__PURE__ */ jsx("div", { className: cn(className), children: sections.map((child, index) => {
4082
- const isLast = index === sections.length - 1;
4083
- const showSeparator = child.props.separator ?? defaultSeparator;
4084
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
4085
- child,
4086
- !isLast && showSeparator && /* @__PURE__ */ jsx(Separator, { className: cn("w-full", separatorClassName) })
4087
- ] }, index);
4088
- }) });
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
+ ] });
4089
4455
  }
4090
- function ProfileSection({
4091
- title,
4092
- description,
4456
+ var HelpContext = createContext(null);
4457
+ function HelpProvider({
4093
4458
  children,
4094
- icon: Icon,
4095
- isEditing,
4096
- onEdit,
4097
- onCancel,
4098
- onSave,
4099
- isSaving,
4100
- editDisabled,
4101
- editLabel,
4102
- action,
4103
- collapsible = false,
4104
- defaultCollapsed = false,
4105
- className,
4106
- contentClassName,
4107
- variant = "card"
4459
+ getArticle,
4460
+ searchArticles,
4461
+ getArticleForFeature,
4462
+ getArticleForRoute,
4463
+ getContextForRoute,
4464
+ pathname,
4465
+ isAdmin = false
4108
4466
  }) {
4109
- const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
4110
- const renderActions = () => {
4111
- if (action) {
4112
- 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();
4113
4508
  }
4114
- if (onEdit) {
4115
- if (isEditing) {
4116
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
4117
- onCancel && /* @__PURE__ */ jsx(
4118
- Button,
4119
- {
4120
- variant: "ghost",
4121
- size: "icon",
4122
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-destructive",
4123
- onClick: onCancel,
4124
- disabled: isSaving,
4125
- "aria-label": "Cancel",
4126
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
4127
- }
4128
- ),
4129
- onSave && /* @__PURE__ */ jsx(
4130
- Button,
4131
- {
4132
- variant: "ghost",
4133
- size: "icon",
4134
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-green-600",
4135
- onClick: onSave,
4136
- disabled: isSaving,
4137
- "aria-label": "Save",
4138
- children: isSaving ? /* @__PURE__ */ jsx(Spinner, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
4139
- }
4140
- )
4141
- ] });
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("");
4142
4527
  }
4143
- return /* @__PURE__ */ jsx(
4144
- Button,
4145
- {
4146
- variant: "ghost",
4147
- size: "icon",
4148
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent hover:text-primary",
4149
- onClick: onEdit,
4150
- disabled: editDisabled,
4151
- "aria-label": editLabel ?? `Edit ${title}`,
4152
- children: /* @__PURE__ */ jsx(Pencil, { className: "h-4 w-4" })
4153
- }
4154
- );
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);
4155
4547
  }
4156
- if (collapsible) {
4157
- return /* @__PURE__ */ jsx(
4158
- Button,
4159
- {
4160
- variant: "ghost",
4161
- size: "icon",
4162
- className: "h-8 w-8 text-muted-foreground/60 hover:bg-transparent",
4163
- onClick: () => setIsCollapsed(!isCollapsed),
4164
- "aria-expanded": !isCollapsed,
4165
- "aria-label": isCollapsed ? "Expand" : "Collapse",
4166
- children: /* @__PURE__ */ jsx(
4167
- ChevronDown,
4168
- {
4169
- className: cn(
4170
- "h-4 w-4 transition-transform duration-200",
4171
- isCollapsed && "-rotate-90"
4172
- )
4173
- }
4174
- )
4175
- }
4176
- );
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
+ }
4177
4573
  }
4178
- 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
4179
4594
  };
4180
- if (variant === "simple") {
4181
- return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", className), children: [
4182
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-1", children: [
4183
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4184
- Icon && /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-muted-foreground" }),
4185
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold tracking-tight", children: title })
4186
- ] }),
4187
- renderActions()
4188
- ] }),
4189
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground px-1", children: description }),
4190
- (!collapsible || !isCollapsed) && /* @__PURE__ */ jsx("div", { className: contentClassName, children })
4191
- ] });
4192
- }
4193
- return /* @__PURE__ */ jsxs(Card, { className, children: [
4194
- /* @__PURE__ */ jsxs(CardHeader, { className: "flex flex-row items-start justify-between space-y-0 pb-2", children: [
4195
- /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
4196
- /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2", children: [
4197
- Icon && /* @__PURE__ */ jsx(Icon, { className: "size-5" }),
4198
- title
4199
- ] }),
4200
- description && /* @__PURE__ */ jsx(CardDescription, { children: description })
4201
- ] }),
4202
- renderActions()
4203
- ] }),
4204
- (!collapsible || !isCollapsed) && /* @__PURE__ */ jsx(CardContent, { className: contentClassName, children })
4205
- ] });
4595
+ return /* @__PURE__ */ jsx(HelpContext.Provider, { value, children });
4206
4596
  }
4207
- var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
4208
- ProgressPrimitive.Root,
4209
- {
4210
- ref,
4211
- className: cn(
4212
- "relative h-2 w-full overflow-hidden rounded-full bg-muted",
4213
- className
4214
- ),
4215
- ...props,
4216
- children: /* @__PURE__ */ jsx(
4217
- ProgressPrimitive.Indicator,
4218
- {
4219
- className: "h-full w-full flex-1 bg-primary transition-all duration-300 ease-out",
4220
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
4221
- }
4222
- )
4597
+ function useHelp() {
4598
+ const context = useContext(HelpContext);
4599
+ if (!context) {
4600
+ throw new Error("useHelp must be used within a HelpProvider");
4223
4601
  }
4224
- ));
4225
- Progress.displayName = ProgressPrimitive.Root.displayName;
4226
- var RadioGroup = ({
4602
+ return context;
4603
+ }
4604
+ function HelpButton({
4605
+ featureKey,
4606
+ variant = "ghost",
4607
+ size = "icon",
4227
4608
  className,
4228
- ...props
4229
- }) => {
4230
- return /* @__PURE__ */ jsx(
4231
- RadioGroupPrimitive.Root,
4232
- {
4233
- className: cn("grid gap-2", className),
4234
- ...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();
4235
4618
  }
4236
- );
4237
- };
4238
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
4239
- var RadioGroupItem = ({
4240
- className,
4241
- ...props
4242
- }) => {
4243
- return /* @__PURE__ */ jsx(
4244
- RadioGroupPrimitive.Item,
4619
+ };
4620
+ return /* @__PURE__ */ jsxs(
4621
+ Button,
4245
4622
  {
4246
- className: cn(
4247
- "aspect-square h-4 w-4 rounded-full border-2 border-muted-foreground/50 text-primary shadow-sm transition-all",
4248
- "outline-none focus:border-primary focus:shadow-[0_0_0_3px_hsl(var(--primary)/0.3)]",
4249
- "disabled:cursor-not-allowed disabled:opacity-50",
4250
- "data-[state=checked]:border-primary data-[state=checked]:bg-primary",
4251
- className
4252
- ),
4253
- ...props,
4254
- 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
+ ]
4255
4632
  }
4256
4633
  );
4257
- };
4258
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
4259
- var spacingClasses = {
4260
- sm: "py-8",
4261
- // 32px
4262
- md: "py-16",
4263
- // 64px
4264
- lg: "py-24",
4265
- // 96px
4266
- xl: "py-32"
4267
- // 128px
4268
- };
4269
- var Section = React.forwardRef(
4270
- ({
4271
- className,
4272
- spacing: spacing2 = "md",
4273
- as: Component = "section",
4274
- children,
4275
- ...props
4276
- }, ref) => {
4277
- return /* @__PURE__ */ jsx(
4278
- Component,
4279
- {
4280
- ref,
4281
- className: cn(spacingClasses[spacing2], className),
4282
- ...props,
4283
- children
4284
- }
4285
- );
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
+ ] });
4286
4651
  }
4287
- );
4288
- Section.displayName = "Section";
4289
- var Slider = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(
4290
- SliderPrimitive.Root,
4291
- {
4292
- ref,
4293
- className: cn(
4294
- "relative flex w-full touch-none select-none items-center",
4295
- className
4296
- ),
4297
- ...props,
4298
- children: [
4299
- /* @__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" }) }),
4300
- (props.defaultValue ?? props.value ?? [0]).map((_, index) => /* @__PURE__ */ jsx(
4301
- 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",
4302
4665
  {
4303
- 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
+ ] })
4304
4677
  },
4305
- index
4306
- ))
4307
- ]
4308
- }
4309
- ));
4310
- Slider.displayName = SliderPrimitive.Root.displayName;
4311
- function formatTrendValue(value, isPercentage = true) {
4312
- const sign = value >= 0 ? "+" : "";
4313
- return isPercentage ? `${sign}${value}%` : `${sign}${value}`;
4678
+ result.slug
4679
+ );
4680
+ })
4681
+ ] });
4314
4682
  }
4315
- function formatStatValue(value, format, options) {
4316
- if (typeof value === "string") {
4317
- return value;
4318
- }
4319
- const num = value;
4320
- switch (format) {
4321
- case "currency":
4322
- return new Intl.NumberFormat("en-US", {
4323
- style: "currency",
4324
- currency: options?.currencyCode ?? "USD",
4325
- minimumFractionDigits: 0,
4326
- maximumFractionDigits: num >= 1e3 ? 0 : 2
4327
- }).format(num);
4328
- case "percent":
4329
- return new Intl.NumberFormat("en-US", {
4330
- style: "percent",
4331
- minimumFractionDigits: 0,
4332
- maximumFractionDigits: options?.percentDecimals ?? 1
4333
- }).format(num / 100);
4334
- case "compact":
4335
- return new Intl.NumberFormat("en-US", {
4336
- notation: "compact",
4337
- compactDisplay: "short",
4338
- maximumFractionDigits: 1
4339
- }).format(num);
4340
- case "number":
4341
- if (Math.abs(num) >= 1e6) {
4342
- return new Intl.NumberFormat("en-US", {
4343
- notation: "compact",
4344
- compactDisplay: "short",
4345
- maximumFractionDigits: 1
4346
- }).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 })
4347
4707
  }
4348
- return new Intl.NumberFormat("en-US").format(num);
4349
- default:
4350
- 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
+ }
4351
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
+ );
4352
4747
  }
4353
- function TrendBadge({ trend }) {
4354
- const Icon = trend.direction === "up" ? TrendingUp : trend.direction === "down" ? TrendingDown : null;
4355
- const colorClass = trend.direction === "up" ? "text-emerald-600 dark:text-emerald-400" : trend.direction === "down" ? "text-destructive" : "text-muted-foreground";
4356
- return /* @__PURE__ */ jsxs(
4357
- Badge,
4748
+ function ButtonGroupText({
4749
+ className,
4750
+ asChild = false,
4751
+ ...props
4752
+ }) {
4753
+ const Comp = asChild ? Slot : "div";
4754
+ return /* @__PURE__ */ jsx(
4755
+ Comp,
4358
4756
  {
4359
- variant: "outline",
4360
- className: cn("gap-1 rounded-md text-xs", colorClass),
4361
- children: [
4362
- Icon && /* @__PURE__ */ jsx(Icon, { className: "size-3" }),
4363
- formatTrendValue(trend.value, trend.isPercentage ?? true)
4364
- ]
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
4365
4762
  }
4366
4763
  );
4367
4764
  }
4368
- function StatCardValueContent({
4369
- isCompact,
4370
- displayValue,
4371
- description,
4372
- trend,
4373
- footer
4765
+ function ButtonGroupSeparator({
4766
+ className,
4767
+ orientation = "vertical",
4768
+ ...props
4374
4769
  }) {
4375
- if (isCompact) {
4376
- return /* @__PURE__ */ jsxs(Fragment, { children: [
4377
- /* @__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 }) }),
4378
- (description || trend) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex items-center gap-2 min-w-0", children: [
4379
- trend && /* @__PURE__ */ jsx(TrendBadge, { trend }),
4380
- description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate", children: description })
4381
- ] }),
4382
- trend?.label && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: trend.label }),
4383
- footer && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: footer })
4384
- ] });
4385
- }
4386
- return /* @__PURE__ */ jsxs(Fragment, { children: [
4387
- /* @__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 }) }),
4388
- (description || trend) && /* @__PURE__ */ jsxs("div", { className: "-mt-6 flex items-center gap-2 min-w-0", children: [
4389
- trend && /* @__PURE__ */ jsx(TrendBadge, { trend }),
4390
- description && /* @__PURE__ */ jsx("p", { className: "text-xs text-foreground/80 truncate", children: description })
4391
- ] }),
4392
- footer && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1 truncate", children: footer }),
4393
- trend?.label && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5 truncate", children: trend.label })
4394
- ] });
4395
- }
4396
- function FlipIndicator({ activeSide }) {
4397
- return /* @__PURE__ */ jsxs(
4398
- "div",
4770
+ return /* @__PURE__ */ jsx(
4771
+ Separator,
4399
4772
  {
4400
- className: "absolute bottom-2 left-1/2 -translate-x-1/2 flex items-center gap-1.5 z-10 pointer-events-none",
4401
- "aria-hidden": "true",
4402
- children: [
4403
- /* @__PURE__ */ jsx(
4404
- "span",
4405
- {
4406
- className: cn(
4407
- "h-1.5 w-1.5 rounded-full transition-colors",
4408
- activeSide === "stat" ? "bg-foreground/60" : "bg-foreground/20"
4409
- )
4410
- }
4411
- ),
4412
- /* @__PURE__ */ jsx(
4413
- "span",
4414
- {
4415
- className: cn(
4416
- "h-1.5 w-1.5 rounded-full transition-colors",
4417
- activeSide === "chart" ? "bg-foreground/60" : "bg-foreground/20"
4418
- )
4419
- }
4420
- )
4421
- ]
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
4422
4780
  }
4423
4781
  );
4424
4782
  }
4425
- function MiniChart({ data, type = "area", periodLabel }) {
4426
- if (!data || data.length === 0) return null;
4427
- const values = data.map((d) => d.value);
4428
- const maxValue = Math.max(...values);
4429
- const minValue = Math.min(...values);
4430
- const range = maxValue - minValue || 1;
4431
- const width = 100;
4432
- const height = 40;
4433
- const paddingX = 0;
4434
- const paddingY = 4;
4435
- const points = data.map((d, i) => {
4436
- const normalizedX = data.length > 1 ? i / (data.length - 1) : 0.5;
4437
- const x = paddingX + normalizedX * (width - paddingX * 2);
4438
- const y = height - paddingY - (d.value - minValue) / range * (height - paddingY * 2);
4439
- return { x, y, ...d };
4440
- });
4441
- const createSmoothPath = (pts) => {
4442
- if (pts.length < 2) return "";
4443
- let path = `M ${pts[0].x} ${pts[0].y}`;
4444
- for (let i = 0; i < pts.length - 1; i++) {
4445
- const p0 = pts[Math.max(0, i - 1)];
4446
- const p1 = pts[i];
4447
- const p2 = pts[i + 1];
4448
- const p3 = pts[Math.min(pts.length - 1, i + 2)];
4449
- const tension = 0.3;
4450
- const cp1x = p1.x + (p2.x - p0.x) * tension;
4451
- const cp1y = p1.y + (p2.y - p0.y) * tension;
4452
- const cp2x = p2.x - (p3.x - p1.x) * tension;
4453
- const cp2y = p2.y - (p3.y - p1.y) * tension;
4454
- 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
4455
4793
  }
4456
- return path;
4457
- };
4458
- const smoothPath = createSmoothPath(points);
4459
- const areaPath = `${smoothPath} L ${points[points.length - 1].x} ${height} L ${points[0].x} ${height} Z`;
4460
- const barWidth = (width - paddingX * 2) / data.length - 2;
4461
- const gradientId = `miniChartGradient-${Math.random().toString(36).substring(2, 11)}`;
4462
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full justify-center px-1", children: [
4463
- periodLabel && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-2", children: periodLabel }),
4464
- /* @__PURE__ */ jsxs(
4465
- "svg",
4466
- {
4467
- viewBox: `0 0 ${width} ${height}`,
4468
- className: "w-full h-20",
4469
- preserveAspectRatio: "none",
4470
- "aria-label": "Chart showing trend data",
4471
- role: "img",
4472
- children: [
4473
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
4474
- /* @__PURE__ */ jsx(
4475
- "stop",
4476
- {
4477
- offset: "5%",
4478
- className: "[stop-color:hsl(var(--primary))]",
4479
- stopOpacity: 0.8
4480
- }
4481
- ),
4482
- /* @__PURE__ */ jsx(
4483
- "stop",
4484
- {
4485
- offset: "95%",
4486
- className: "[stop-color:hsl(var(--primary))]",
4487
- stopOpacity: 0.1
4488
- }
4489
- )
4490
- ] }) }),
4491
- type === "bar" ? (
4492
- // Bar chart
4493
- /* @__PURE__ */ jsx("g", { children: points.map((p, i) => /* @__PURE__ */ jsx(
4494
- "rect",
4495
- {
4496
- x: paddingX + i * (width - paddingX * 2) / data.length + 1,
4497
- y: p.y,
4498
- width: barWidth,
4499
- height: height - p.y,
4500
- className: "fill-primary/30",
4501
- rx: 1
4502
- },
4503
- p.label
4504
- )) })
4505
- ) : (
4506
- // Line/Area chart - matching NewUsersChart style
4507
- /* @__PURE__ */ jsxs("g", { children: [
4508
- type === "area" && /* @__PURE__ */ jsx("path", { d: areaPath, fill: `url(#${gradientId})` }),
4509
- /* @__PURE__ */ jsx(
4510
- "path",
4511
- {
4512
- d: smoothPath,
4513
- fill: "none",
4514
- className: "stroke-primary",
4515
- strokeWidth: 1.5,
4516
- strokeLinecap: "round",
4517
- strokeLinejoin: "round"
4518
- }
4519
- )
4520
- ] })
4521
- )
4522
- ]
4523
- }
4524
- ),
4525
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between text-[10px] text-muted-foreground mt-1", children: [
4526
- /* @__PURE__ */ jsx("span", { children: data[0]?.label }),
4527
- /* @__PURE__ */ jsx("span", { children: data[data.length - 1]?.label })
4528
- ] })
4529
- ] });
4794
+ );
4530
4795
  }
4531
- function StatCard({
4532
- title,
4533
- value,
4534
- description,
4535
- footer,
4536
- icon,
4537
- trend,
4538
- 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({
4539
4824
  className,
4540
- size = "default",
4541
- format,
4542
- currencyCode,
4543
- percentDecimals,
4544
- formatValue = false,
4545
- onClick,
4546
- href,
4547
- chart,
4548
- defaultSide = "stat"
4825
+ variant = "default",
4826
+ ...props
4549
4827
  }) {
4550
- const [activeSide, setActiveSide] = useState(defaultSide);
4551
- const effectiveFormat = format ?? (formatValue ? "number" : typeof value === "number" ? "number" : "none");
4552
- const displayValue = formatStatValue(value, effectiveFormat, {
4553
- currencyCode,
4554
- percentDecimals
4555
- });
4556
- const variantStyles = {
4557
- default: "",
4558
- muted: "bg-linear-to-t from-muted/60 to-muted/20 hover:from-muted/70 hover:to-muted/30 transition-colors",
4559
- gradient: "bg-gradient-to-t from-primary/5 to-card dark:bg-card",
4560
- outline: "border-2"
4561
- };
4562
- const isInteractive = onClick || href;
4563
- const hasChart = !!chart;
4564
- const isCompact = size === "compact";
4565
- const handleFlip = () => {
4566
- setActiveSide((prev) => prev === "stat" ? "chart" : "stat");
4567
- };
4568
- const handleBodyClick = (e) => {
4569
- e.stopPropagation();
4570
- if (hasChart) {
4571
- handleFlip();
4572
- } else if (onClick) {
4573
- 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
4574
4835
  }
4575
- };
4576
- const handleHeaderClick = (e) => {
4577
- e.stopPropagation();
4578
- if (href) {
4579
- 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
4580
4845
  }
4581
- if (onClick) {
4582
- onClick();
4583
- } else if (hasChart) {
4584
- 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
4585
4858
  }
4586
- };
4587
- const cardBaseStyles = cn(
4588
- "h-full relative overflow-hidden gap-0",
4589
- isCompact ? "min-h-[112px] p-3 md:min-h-[120px] md:p-4" : "py-3",
4590
- variantStyles[variant],
4591
- hasChart && "pb-6"
4592
4859
  );
4593
- const renderHeader = (showIcon = true) => /* @__PURE__ */ jsxs(
4594
- CardHeader,
4860
+ }
4861
+ function EmptyContent({ className, ...props }) {
4862
+ return /* @__PURE__ */ jsx(
4863
+ "div",
4595
4864
  {
4865
+ "data-slot": "empty-content",
4596
4866
  className: cn(
4597
- "flex flex-row items-center justify-between space-y-0 py-0",
4598
- 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
4599
4869
  ),
4600
- children: [
4601
- href ? /* @__PURE__ */ jsxs(
4602
- "a",
4603
- {
4604
- href,
4605
- className: "flex items-center gap-2 hover:text-primary transition-colors z-10",
4606
- onClick: (e) => e.stopPropagation(),
4607
- children: [
4608
- /* @__PURE__ */ jsx(
4609
- CardTitle,
4610
- {
4611
- className: cn(
4612
- isCompact ? "text-xs md:text-sm font-medium text-muted-foreground" : "text-sm font-medium"
4613
- ),
4614
- children: title
4615
- }
4616
- ),
4617
- /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-4 w-4 opacity-0 group-hover:opacity-100 transition-opacity" })
4618
- ]
4619
- }
4620
- ) : /* @__PURE__ */ jsx(
4621
- CardTitle,
4622
- {
4623
- className: cn(
4624
- isCompact ? "text-xs md:text-sm font-medium text-muted-foreground" : "text-sm font-medium",
4625
- "flex items-center gap-2",
4626
- onClick && "cursor-pointer hover:text-primary transition-colors"
4627
- ),
4628
- onClick: handleHeaderClick,
4629
- children: title
4630
- }
4631
- ),
4632
- showIcon && icon && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: icon })
4633
- ]
4870
+ ...props
4634
4871
  }
4635
4872
  );
4636
- if (!hasChart) {
4637
- return /* @__PURE__ */ jsxs(
4638
- 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",
4639
4879
  {
4640
- className: cn(
4641
- cardBaseStyles,
4642
- "group",
4643
- isInteractive && "cursor-pointer transition-colors hover:border-primary/50",
4644
- className
4645
- ),
4646
- onClick,
4647
- children: [
4648
- renderHeader(),
4649
- /* @__PURE__ */ jsx(
4650
- CardContent,
4651
- {
4652
- className: cn("relative py-0", isCompact ? "px-0" : "px-4"),
4653
- children: /* @__PURE__ */ jsx(
4654
- StatCardValueContent,
4655
- {
4656
- isCompact,
4657
- displayValue,
4658
- description,
4659
- trend,
4660
- footer
4661
- }
4662
- )
4663
- }
4664
- )
4665
- ]
4880
+ role: "list",
4881
+ "data-slot": "item-group",
4882
+ className: cn("group/item-group flex flex-col", className),
4883
+ ...props
4666
4884
  }
4667
- );
4668
- }
4885
+ )
4886
+ );
4887
+ }
4888
+ function ItemSeparator({
4889
+ className,
4890
+ ...props
4891
+ }) {
4669
4892
  return /* @__PURE__ */ jsx(
4670
- "div",
4893
+ Separator,
4671
4894
  {
4672
- className: cn("group h-full min-h-[160px]", className),
4673
- style: { perspective: "1000px" },
4674
- children: /* @__PURE__ */ jsxs(
4675
- "button",
4676
- {
4677
- type: "button",
4678
- className: cn(
4679
- "relative h-full w-full transition-transform duration-500 cursor-pointer text-left",
4680
- "[transform-style:preserve-3d]",
4681
- activeSide === "chart" && "[transform:rotateY(180deg)]"
4682
- ),
4683
- onClick: handleBodyClick,
4684
- "aria-label": activeSide === "chart" ? "Show statistic view" : "Show chart view",
4685
- "aria-pressed": activeSide === "chart",
4686
- children: [
4687
- /* @__PURE__ */ jsxs(
4688
- Card,
4689
- {
4690
- className: cn(
4691
- cardBaseStyles,
4692
- "absolute inset-0 [backface-visibility:hidden] [transform-style:preserve-3d] [transform:rotateY(0deg)]",
4693
- "transition-colors hover:border-primary/50"
4694
- ),
4695
- children: [
4696
- renderHeader(),
4697
- /* @__PURE__ */ jsx(
4698
- CardContent,
4699
- {
4700
- className: cn("relative py-0", isCompact ? "px-0" : "px-4"),
4701
- children: /* @__PURE__ */ jsx(
4702
- StatCardValueContent,
4703
- {
4704
- isCompact,
4705
- displayValue,
4706
- description,
4707
- trend,
4708
- footer
4709
- }
4710
- )
4711
- }
4712
- ),
4713
- /* @__PURE__ */ jsx(FlipIndicator, { activeSide })
4714
- ]
4715
- }
4716
- ),
4717
- /* @__PURE__ */ jsxs(
4718
- Card,
4719
- {
4720
- className: cn(
4721
- cardBaseStyles,
4722
- "absolute inset-0 [backface-visibility:hidden] [transform-style:preserve-3d] [transform:rotateY(180deg)]",
4723
- "transition-colors hover:border-primary/50"
4724
- ),
4725
- children: [
4726
- renderHeader(false),
4727
- /* @__PURE__ */ jsx(CardContent, { className: "relative px-4 py-0 h-full", children: /* @__PURE__ */ jsx(MiniChart, { ...chart }) }),
4728
- /* @__PURE__ */ jsx(FlipIndicator, { activeSide })
4729
- ]
4730
- }
4731
- )
4732
- ]
4733
- }
4734
- )
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
4735
4938
  }
4736
4939
  );
4737
4940
  }
4738
- function StatCardsContainer({
4739
- children,
4740
- columns = { default: 1, sm: 2, lg: 4 },
4741
- 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
4742
4960
  }) {
4743
- const colClasses = {
4744
- 1: "grid-cols-1",
4745
- 2: "grid-cols-2",
4746
- 3: "grid-cols-3",
4747
- 4: "grid-cols-4"
4748
- };
4749
- const smColClasses = {
4750
- 1: "sm:grid-cols-1",
4751
- 2: "sm:grid-cols-2",
4752
- 3: "sm:grid-cols-3",
4753
- 4: "sm:grid-cols-4"
4754
- };
4755
- const mdColClasses = {
4756
- 1: "md:grid-cols-1",
4757
- 2: "md:grid-cols-2",
4758
- 3: "md:grid-cols-3",
4759
- 4: "md:grid-cols-4"
4760
- };
4761
- const lgColClasses = {
4762
- 1: "lg:grid-cols-1",
4763
- 2: "lg:grid-cols-2",
4764
- 3: "lg:grid-cols-3",
4765
- 4: "lg:grid-cols-4"
4766
- };
4767
4961
  return /* @__PURE__ */ jsx(
4768
4962
  "div",
4769
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",
4770
4976
  className: cn(
4771
- "grid gap-4",
4772
- columns.default && colClasses[columns.default],
4773
- columns.sm && smColClasses[columns.sm],
4774
- columns.md && mdColClasses[columns.md],
4775
- columns.lg && lgColClasses[columns.lg],
4977
+ "flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none",
4776
4978
  className
4777
4979
  ),
4778
- children
4980
+ ...props
4779
4981
  }
4780
4982
  );
4781
4983
  }
4782
- function TextHighlight({
4783
- children,
4784
- className,
4785
- duration = 2,
4786
- delay = 0.5,
4787
- gradient = "from-indigo-300 to-purple-300 dark:from-indigo-500 dark:to-purple-500",
4788
- disableAnimation = false
4789
- }) {
4790
- const animationStyle = disableAnimation ? { backgroundSize: "100% 100%" } : {
4791
- "--highlight-duration": `${duration}s`,
4792
- "--highlight-delay": `${delay}s`
4793
- };
4984
+ function ItemTitle({ className, ...props }) {
4794
4985
  return /* @__PURE__ */ jsx(
4795
- "span",
4986
+ "div",
4796
4987
  {
4797
- "data-slot": "text-highlight",
4798
- "data-animated": !disableAnimation,
4988
+ "data-slot": "item-title",
4799
4989
  className: cn(
4800
- "relative inline-block rounded-lg bg-gradient-to-r bg-no-repeat px-1 pb-1",
4801
- !disableAnimation && "text-highlight-animated",
4802
- gradient,
4990
+ "flex w-fit items-center gap-2 text-sm leading-snug font-medium",
4803
4991
  className
4804
4992
  ),
4805
- style: {
4806
- backgroundPosition: "left center",
4807
- ...animationStyle
4808
- },
4809
- 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
4810
5044
  }
4811
5045
  );
4812
5046
  }
4813
- var ToggleGroup = React.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(
4814
- ToggleGroupPrimitive.Root,
5047
+ var Progress = React.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ jsx(
5048
+ ProgressPrimitive.Root,
4815
5049
  {
4816
5050
  ref,
4817
- 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
+ ),
4818
5055
  ...props,
4819
- 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
+ )
4820
5063
  }
4821
5064
  ));
4822
- 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
+ }
4823
5134
  var ToggleGroupContext = React.createContext({
4824
- size: void 0,
4825
- variant: void 0
5135
+ size: "default",
5136
+ variant: "default",
5137
+ spacing: 0
4826
5138
  });
4827
- 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
+ }) {
4828
5171
  const context = React.useContext(ToggleGroupContext);
4829
- const resolvedVariant = variant || context.variant || "default";
4830
- const resolvedSize = size || context.size || "default";
4831
5172
  return /* @__PURE__ */ jsx(
4832
5173
  ToggleGroupPrimitive.Item,
4833
5174
  {
4834
- ref,
5175
+ "data-slot": "toggle-group-item",
5176
+ "data-variant": context.variant || variant,
5177
+ "data-size": context.size || size,
5178
+ "data-spacing": context.spacing,
4835
5179
  className: cn(
4836
- "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",
4837
- resolvedVariant === "outline" && "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
4838
- resolvedSize === "default" && "h-10 px-3",
4839
- resolvedSize === "sm" && "h-9 px-2.5",
4840
- 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",
4841
5186
  className
4842
5187
  ),
4843
5188
  ...props,
4844
5189
  children
4845
5190
  }
4846
5191
  );
4847
- });
4848
- ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
4849
- function TooltipCard({
4850
- children,
4851
- className,
4852
- containerClassName,
4853
- content,
4854
- triggerClassName,
4855
- delayDuration = 150,
4856
- side = "top",
4857
- align = "center",
4858
- sideOffset = 10,
4859
- ...tooltipProps
4860
- }) {
4861
- return /* @__PURE__ */ jsxs(Tooltip, { delayDuration, ...tooltipProps, children: [
4862
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
4863
- "button",
4864
- {
4865
- type: "button",
4866
- className: cn(
4867
- "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",
4868
- "hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
4869
- className,
4870
- triggerClassName
4871
- ),
4872
- "data-slot": "tooltip-card-trigger",
4873
- children
4874
- }
4875
- ) }),
4876
- /* @__PURE__ */ jsx(
4877
- TooltipContent,
4878
- {
4879
- align,
4880
- className: cn(
4881
- "max-w-sm rounded-box border border-border bg-popover px-4 py-3 text-popover-foreground shadow-xl",
4882
- "text-sm leading-6 font-normal",
4883
- containerClassName
4884
- ),
4885
- "data-slot": "tooltip-card-content",
4886
- side,
4887
- sideOffset,
4888
- children: typeof content === "string" ? /* @__PURE__ */ jsx("p", { "data-slot": "tooltip-card-text", children: content }) : content
4889
- }
4890
- )
4891
- ] });
4892
5192
  }
4893
5193
 
4894
5194
  // src/config/theme.ts
@@ -5874,4 +6174,4 @@ function NoWidowProvider({
5874
6174
  return children ?? null;
5875
6175
  }
5876
6176
 
5877
- 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 };