@olwiba/ui 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,15 +1,19 @@
1
1
  import { cn } from './chunk-AMWLSHD6.js';
2
2
  export { MdxContent, cn } from './chunk-AMWLSHD6.js';
3
- import * as React31 from 'react';
3
+ import * as React32 from 'react';
4
4
  import { useRef, useEffect, useState } from 'react';
5
5
  import { Button as Button$1, Card as Card$1, Input as Input$1, Textarea as Textarea$1, Checkbox as Checkbox$1, Switch as Switch$1, useIsMobile, UIVariantProvider, Badge as Badge$1, cn as cn$1, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, Avatar, AvatarImage, AvatarFallback, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Dialog, DialogTrigger, Progress, useUIVariant, Separator, Accordion, AccordionItem, AccordionTrigger, AccordionContent, Label, Sheet, SheetTrigger, SheetContent, StatusIndicator, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandSeparator, CommandGroup, CommandItem, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, ContextMenu as ContextMenu$1, ContextMenuTrigger, ContextMenuContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, CommandShortcut, Popover, PopoverTrigger, PopoverContent, Spinner, SidebarProvider, SidebarInset, CardHeader, CardTitle, CardDescription, CardContent, InputOTP, InputOTPGroup, InputOTPSlot, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, ContextMenuSeparator, ContextMenuLabel, ContextMenuSub, ContextMenuSubTrigger, ContextMenuSubContent, ContextMenuItem, ContextMenuShortcut, Sidebar, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarFooter, SidebarTrigger, useSidebar, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup } from '@olwiba/cn';
6
6
  export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Enchanted } from '@olwiba/cn';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { Search, ArrowUp, ArrowDown, ArrowUpDown, ChevronLeft, ChevronRight, MoreHorizontal, UserPlus, Download, CreditCard, Check, Loader2, ArrowLeft, ArrowUpRight, X, ArrowRight, Sparkles, Minus, Quote, Star, Twitter, Github, Linkedin, Mail, MessageSquare, ChevronDown, Send, Menu, UploadCloud, File, CheckCircle2, AlertCircle, Bell, Inbox, Activity, TrendingUp, TrendingDown, Sun, Moon, Palette, AlertTriangle, Rocket, Info, Layers, LayoutGrid, ShieldCheck, Building2, MoreVerticalIcon, CreditCardIcon, BellIcon, LogOutIcon } from 'lucide-react';
9
9
  import { useReactTable, getPaginationRowModel, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
10
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
11
+ import { sortableKeyboardCoordinates, SortableContext, rectSortingStrategy, horizontalListSortingStrategy, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
12
+ import { CSS } from '@dnd-kit/utilities';
13
+ import { PieChart, Pie, Cell, BarChart, XAxis, YAxis, Bar, AreaChart, Area, LineChart, Line, ResponsiveContainer, Tooltip as Tooltip$1, CartesianGrid } from 'recharts';
10
14
  import { toast } from 'sonner';
11
15
 
12
- var OlwibaUIContext = React31.createContext({
16
+ var OlwibaUIContext = React32.createContext({
13
17
  isMobile: false,
14
18
  mode: "default",
15
19
  setMode: () => {
@@ -18,17 +22,17 @@ var OlwibaUIContext = React31.createContext({
18
22
  function OlwibaUIProvider({ children, isMobile: isMobileProp, mode: initialMode = "default" }) {
19
23
  const detectedMobile = useIsMobile();
20
24
  const isMobile = isMobileProp ?? detectedMobile;
21
- const [mode, setMode] = React31.useState(initialMode);
25
+ const [mode, setMode] = React32.useState(initialMode);
22
26
  const variant = mode !== "default" ? mode : void 0;
23
27
  return /* @__PURE__ */ jsx(OlwibaUIContext.Provider, { value: { isMobile, mode, setMode }, children: /* @__PURE__ */ jsx(UIVariantProvider, { mode: variant, children }) });
24
28
  }
25
29
  function useOlwibaUI() {
26
- return React31.useContext(OlwibaUIContext);
30
+ return React32.useContext(OlwibaUIContext);
27
31
  }
28
32
  function useUIMode() {
29
- return React31.useContext(OlwibaUIContext).mode;
33
+ return React32.useContext(OlwibaUIContext).mode;
30
34
  }
31
- var Button = React31.forwardRef(
35
+ var Button = React32.forwardRef(
32
36
  ({ mode, ...props }, ref) => {
33
37
  const ctxMode = useUIMode();
34
38
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -36,7 +40,7 @@ var Button = React31.forwardRef(
36
40
  }
37
41
  );
38
42
  Button.displayName = "Button";
39
- var Card = React31.forwardRef(
43
+ var Card = React32.forwardRef(
40
44
  ({ mode, ...props }, ref) => {
41
45
  const ctxMode = useUIMode();
42
46
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -47,7 +51,7 @@ Card.displayName = "Card";
47
51
  function Badge(props) {
48
52
  return /* @__PURE__ */ jsx(Badge$1, { ...props });
49
53
  }
50
- var Input = React31.forwardRef(
54
+ var Input = React32.forwardRef(
51
55
  ({ mode, ...props }, ref) => {
52
56
  const ctxMode = useUIMode();
53
57
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -55,7 +59,7 @@ var Input = React31.forwardRef(
55
59
  }
56
60
  );
57
61
  Input.displayName = "Input";
58
- var Textarea = React31.forwardRef(
62
+ var Textarea = React32.forwardRef(
59
63
  ({ mode, ...props }, ref) => {
60
64
  const ctxMode = useUIMode();
61
65
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -63,13 +67,13 @@ var Textarea = React31.forwardRef(
63
67
  }
64
68
  );
65
69
  Textarea.displayName = "Textarea";
66
- var Checkbox = React31.forwardRef(({ mode, ...props }, ref) => {
70
+ var Checkbox = React32.forwardRef(({ mode, ...props }, ref) => {
67
71
  const ctxMode = useUIMode();
68
72
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
69
73
  return /* @__PURE__ */ jsx(Checkbox$1, { mode: resolvedMode, ...props, ref });
70
74
  });
71
75
  Checkbox.displayName = "Checkbox";
72
- var Switch = React31.forwardRef(({ mode: _mode, ...props }, ref) => {
76
+ var Switch = React32.forwardRef(({ mode: _mode, ...props }, ref) => {
73
77
  return /* @__PURE__ */ jsx(Switch$1, { ...props, ref });
74
78
  });
75
79
  Switch.displayName = "Switch";
@@ -264,7 +268,7 @@ function NavUser({ user }) {
264
268
  SidebarMenuButton,
265
269
  {
266
270
  size: "lg",
267
- className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
271
+ className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!min-w-8 group-data-[collapsible=icon]:!max-w-8 group-data-[collapsible=icon]:!p-0",
268
272
  children: [
269
273
  /* @__PURE__ */ jsxs(Avatar, { mode: avatarMode, size: "sm", className: "grayscale", children: [
270
274
  user.avatar && /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
@@ -333,13 +337,26 @@ function ShellSidebar({
333
337
  }) {
334
338
  const fallbackLogo = typeof brand.name === "string" ? brand.name.slice(0, 1).toUpperCase() : null;
335
339
  return /* @__PURE__ */ jsxs(Sidebar, { side, collapsible, sidebarPosition, children: [
336
- /* @__PURE__ */ jsx(SidebarHeader, { children: /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(SidebarMenuButton, { asChild: true, tooltip: typeof brand.name === "string" ? brand.name : void 0, className: "data-[slot=sidebar-menu-button]:!p-1.5", children: renderLink({
337
- href: brand.href ?? "#",
338
- children: /* @__PURE__ */ jsxs(Fragment, { children: [
339
- brand.logo ? /* @__PURE__ */ jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary text-primary-foreground", children: brand.logo }) : /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center text-sm font-semibold", children: fallbackLogo }),
340
- /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-base font-semibold group-data-[collapsible=icon]:hidden", children: brand.name })
341
- ] })
342
- }) }) }) }) }),
340
+ /* @__PURE__ */ jsx(SidebarHeader, { className: "py-3", children: /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsx(
341
+ SidebarMenuButton,
342
+ {
343
+ asChild: true,
344
+ size: "lg",
345
+ tooltip: typeof brand.name === "string" ? brand.name : void 0,
346
+ className: "group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!min-w-8 group-data-[collapsible=icon]:!max-w-8 group-data-[collapsible=icon]:!p-0",
347
+ children: renderLink({
348
+ href: brand.href ?? "#",
349
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
350
+ brand.logo ? (
351
+ // Neutral slot: the consumer's logo owns its own chrome
352
+ // (background, radius). Sized to fill the collapsed icon rail.
353
+ /* @__PURE__ */ jsx("span", { className: "flex size-8 shrink-0 items-center justify-center [&>svg]:size-5", children: brand.logo })
354
+ ) : /* @__PURE__ */ jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-primary text-sm font-semibold text-primary-foreground", children: fallbackLogo }),
355
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-base font-semibold group-data-[collapsible=icon]:hidden", children: brand.name })
356
+ ] })
357
+ })
358
+ }
359
+ ) }) }) }),
343
360
  /* @__PURE__ */ jsx(SidebarContent, { children: /* @__PURE__ */ jsx(SidebarGroup, { children: /* @__PURE__ */ jsxs(SidebarGroupContent, { className: "flex flex-col gap-2", children: [
344
361
  action && /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: action.href ? /* @__PURE__ */ jsx(
345
362
  SidebarMenuButton,
@@ -513,7 +530,7 @@ function DefaultForm({
513
530
  const isForgotPassword = mode === "forgot-password";
514
531
  const isResetPassword = mode === "reset-password";
515
532
  const isVerify = mode === "verify";
516
- const [code, setCode] = React31.useState("");
533
+ const [code, setCode] = React32.useState("");
517
534
  const hasPrefill = !!(defaultEmail || defaultPassword);
518
535
  const prefillStyle = (active) => active ? { animation: "auth-prefill 1.6s ease-out 0.35s 1 both" } : void 0;
519
536
  const copy = authCopy[mode];
@@ -673,10 +690,10 @@ function DataTable({
673
690
  emptyMessage = "No results.",
674
691
  className
675
692
  }) {
676
- const [sorting, setSorting] = React31.useState([]);
677
- const [rowSelection, setRowSelection] = React31.useState({});
678
- const [globalFilter, setGlobalFilter] = React31.useState("");
679
- const allColumns = React31.useMemo(
693
+ const [sorting, setSorting] = React32.useState([]);
694
+ const [rowSelection, setRowSelection] = React32.useState({});
695
+ const [globalFilter, setGlobalFilter] = React32.useState("");
696
+ const allColumns = React32.useMemo(
680
697
  () => selectable ? [selectColumn, ...columns] : columns,
681
698
  [selectable, columns]
682
699
  );
@@ -698,7 +715,7 @@ function DataTable({
698
715
  initialState: pageSize > 0 ? { pagination: { pageSize } } : void 0,
699
716
  enableRowSelection: selectable
700
717
  });
701
- React31.useEffect(() => {
718
+ React32.useEffect(() => {
702
719
  if (!onSelectionChange) return;
703
720
  onSelectionChange(table.getSelectedRowModel().rows.map((r) => r.original));
704
721
  }, [rowSelection]);
@@ -778,8 +795,8 @@ function DataTable({
778
795
  ] });
779
796
  }
780
797
  function InviteDialog({ roles, onInvite, onClose }) {
781
- const [email, setEmail] = React31.useState("");
782
- const [role, setRole] = React31.useState(roles[roles.length - 1] ?? roles[0]);
798
+ const [email, setEmail] = React32.useState("");
799
+ const [role, setRole] = React32.useState(roles[roles.length - 1] ?? roles[0]);
783
800
  return /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(
784
801
  "form",
785
802
  {
@@ -823,8 +840,8 @@ function TeamMembersPanel({
823
840
  title = "Team members",
824
841
  description = "Manage who has access to this workspace."
825
842
  }) {
826
- const [inviteOpen, setInviteOpen] = React31.useState(false);
827
- const columns = React31.useMemo(() => [
843
+ const [inviteOpen, setInviteOpen] = React32.useState(false);
844
+ const columns = React32.useMemo(() => [
828
845
  {
829
846
  accessorKey: "name",
830
847
  header: "Name",
@@ -893,7 +910,7 @@ function BillingPanel({
893
910
  onUpdatePaymentMethod,
894
911
  className
895
912
  }) {
896
- const invoiceColumns = React31.useMemo(() => [
913
+ const invoiceColumns = React32.useMemo(() => [
897
914
  { accessorKey: "date", header: "Date", enableSorting: false },
898
915
  { accessorKey: "amount", header: "Amount", enableSorting: false },
899
916
  {
@@ -972,9 +989,9 @@ function OnboardingWizard({
972
989
  completeLabel = "Finish",
973
990
  className
974
991
  }) {
975
- const [internalStep, setInternalStep] = React31.useState(0);
976
- const [error, setError] = React31.useState(null);
977
- const [pending, setPending] = React31.useState(false);
992
+ const [internalStep, setInternalStep] = React32.useState(0);
993
+ const [error, setError] = React32.useState(null);
994
+ const [pending, setPending] = React32.useState(false);
978
995
  const index = stepProp ?? internalStep;
979
996
  const current = steps[index];
980
997
  const isLast = index === steps.length - 1;
@@ -1308,9 +1325,9 @@ function FadeIn({
1308
1325
  style,
1309
1326
  ...props
1310
1327
  }) {
1311
- const ref = React31.useRef(null);
1312
- const [visible, setVisible] = React31.useState(false);
1313
- React31.useEffect(() => {
1328
+ const ref = React32.useRef(null);
1329
+ const [visible, setVisible] = React32.useState(false);
1330
+ React32.useEffect(() => {
1314
1331
  const el = ref.current;
1315
1332
  if (!el) return;
1316
1333
  const observer = new IntersectionObserver(
@@ -1505,16 +1522,16 @@ function Carousel({
1505
1522
  className
1506
1523
  }) {
1507
1524
  const mode = useUIVariant();
1508
- const trackRef = React31.useRef(null);
1509
- const [canPrev, setCanPrev] = React31.useState(false);
1510
- const [canNext, setCanNext] = React31.useState(true);
1511
- const updateScrollState = React31.useCallback(() => {
1525
+ const trackRef = React32.useRef(null);
1526
+ const [canPrev, setCanPrev] = React32.useState(false);
1527
+ const [canNext, setCanNext] = React32.useState(true);
1528
+ const updateScrollState = React32.useCallback(() => {
1512
1529
  const track = trackRef.current;
1513
1530
  if (!track) return;
1514
1531
  setCanPrev(track.scrollLeft > 8);
1515
1532
  setCanNext(track.scrollLeft < track.scrollWidth - track.clientWidth - 8);
1516
1533
  }, []);
1517
- React31.useEffect(() => {
1534
+ React32.useEffect(() => {
1518
1535
  const track = trackRef.current;
1519
1536
  if (!track) return;
1520
1537
  updateScrollState();
@@ -1571,7 +1588,7 @@ function Carousel({
1571
1588
  role: "region",
1572
1589
  "aria-label": ariaLabel,
1573
1590
  className: "flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1574
- children: React31.Children.map(
1591
+ children: React32.Children.map(
1575
1592
  children,
1576
1593
  (child) => child == null ? null : /* @__PURE__ */ jsx("div", { "data-carousel-item": true, className: cn$1("shrink-0 snap-start", itemClassName), children: child })
1577
1594
  )
@@ -1596,9 +1613,9 @@ function StaggerChildren({
1596
1613
  className,
1597
1614
  ...props
1598
1615
  }) {
1599
- const ref = React31.useRef(null);
1600
- const [visible, setVisible] = React31.useState(false);
1601
- React31.useEffect(() => {
1616
+ const ref = React32.useRef(null);
1617
+ const [visible, setVisible] = React32.useState(false);
1618
+ React32.useEffect(() => {
1602
1619
  const el = ref.current;
1603
1620
  if (!el) return;
1604
1621
  const observer = new IntersectionObserver(
@@ -1616,7 +1633,7 @@ function StaggerChildren({
1616
1633
  return () => observer.disconnect();
1617
1634
  }, [once]);
1618
1635
  const [tx, ty] = translateMap2[direction];
1619
- return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React31.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1636
+ return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React32.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1620
1637
  "div",
1621
1638
  {
1622
1639
  className: "h-full",
@@ -1867,9 +1884,9 @@ function FeatureMarqueeSection({
1867
1884
  ] });
1868
1885
  }
1869
1886
  function useIntersectionObserver(options) {
1870
- const ref = React31.useRef(null);
1871
- const [isIntersecting, setIsIntersecting] = React31.useState(false);
1872
- React31.useEffect(() => {
1887
+ const ref = React32.useRef(null);
1888
+ const [isIntersecting, setIsIntersecting] = React32.useState(false);
1889
+ React32.useEffect(() => {
1873
1890
  const el = ref.current;
1874
1891
  if (!el) return;
1875
1892
  const observer = new IntersectionObserver(([entry]) => {
@@ -1891,8 +1908,8 @@ function ShowcaseCta({
1891
1908
  sectionClasses
1892
1909
  }) {
1893
1910
  const [ref, intersecting] = useIntersectionObserver({ threshold: 0.15 });
1894
- const [visible, setVisible] = React31.useState(false);
1895
- React31.useEffect(() => {
1911
+ const [visible, setVisible] = React32.useState(false);
1912
+ React32.useEffect(() => {
1896
1913
  if (intersecting) setVisible(true);
1897
1914
  }, [intersecting]);
1898
1915
  return /* @__PURE__ */ jsxs(
@@ -2069,8 +2086,8 @@ function CountdownTimer({
2069
2086
  className,
2070
2087
  compact = false
2071
2088
  }) {
2072
- const [timeLeft, setTimeLeft] = React31.useState(() => getTimeLeft(deadline));
2073
- React31.useEffect(() => {
2089
+ const [timeLeft, setTimeLeft] = React32.useState(() => getTimeLeft(deadline));
2090
+ React32.useEffect(() => {
2074
2091
  setTimeLeft(getTimeLeft(deadline));
2075
2092
  const id = setInterval(() => setTimeLeft(getTimeLeft(deadline)), 1e3);
2076
2093
  return () => clearInterval(id);
@@ -2096,7 +2113,7 @@ function CountdownTimer({
2096
2113
  ];
2097
2114
  return /* @__PURE__ */ jsxs("div", { className: cn$1("flex items-center justify-center gap-2 text-sm", className), children: [
2098
2115
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
2099
- /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
2116
+ /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
2100
2117
  /* @__PURE__ */ jsxs("span", { children: [
2101
2118
  String(value).padStart(2, "0"),
2102
2119
  /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: unit })
@@ -2119,7 +2136,7 @@ function PricingSection({
2119
2136
  foundingDeadline,
2120
2137
  renderPlanFooter
2121
2138
  }) {
2122
- const [annual, setAnnual] = React31.useState(false);
2139
+ const [annual, setAnnual] = React32.useState(false);
2123
2140
  const isOneTime = mode === "one-time";
2124
2141
  const uiMode = useUIVariant();
2125
2142
  const sectionClasses = cn$1(
@@ -2388,10 +2405,10 @@ function CountUp({
2388
2405
  className,
2389
2406
  ...props
2390
2407
  }) {
2391
- const ref = React31.useRef(null);
2392
- const [value, setValue] = React31.useState(from);
2393
- const hasStarted = React31.useRef(false);
2394
- React31.useEffect(() => {
2408
+ const ref = React32.useRef(null);
2409
+ const [value, setValue] = React32.useState(from);
2410
+ const hasStarted = React32.useRef(false);
2411
+ React32.useEffect(() => {
2395
2412
  const el = ref.current;
2396
2413
  if (!el) return;
2397
2414
  const observer = new IntersectionObserver(
@@ -2484,8 +2501,8 @@ function NewsletterSection({
2484
2501
  successDescription = defaults.successDescription,
2485
2502
  onSubscribe
2486
2503
  } = {}) {
2487
- const [email, setEmail] = React31.useState("");
2488
- const [submitted, setSubmitted] = React31.useState(false);
2504
+ const [email, setEmail] = React32.useState("");
2505
+ const [submitted, setSubmitted] = React32.useState(false);
2489
2506
  const mode = useUIVariant();
2490
2507
  const sectionClasses = cn$1(
2491
2508
  "overflow-hidden bg-card",
@@ -2576,7 +2593,7 @@ function ContactSection({
2576
2593
  sendAnotherLabel = defaults2.sendAnotherLabel,
2577
2594
  onSubmit
2578
2595
  } = {}) {
2579
- const [submitted, setSubmitted] = React31.useState(false);
2596
+ const [submitted, setSubmitted] = React32.useState(false);
2580
2597
  const mode = useUIVariant();
2581
2598
  const sectionClasses = cn$1(
2582
2599
  "overflow-hidden bg-card",
@@ -2874,7 +2891,7 @@ function Navbar({
2874
2891
  controls,
2875
2892
  renderLink = defaultRenderLink7
2876
2893
  }) {
2877
- const [open, setOpen] = React31.useState(false);
2894
+ const [open, setOpen] = React32.useState(false);
2878
2895
  const brandHref = brand.href ?? "/";
2879
2896
  const hasRightContent = controls?.length || cta?.primary || cta?.secondary;
2880
2897
  return /* @__PURE__ */ jsx("section", { className: "overflow-hidden rounded-2xl border bg-card", children: /* @__PURE__ */ jsxs("nav", { className: "grid h-16 grid-cols-[1fr_auto_1fr] items-center px-6", children: [
@@ -2891,7 +2908,7 @@ function Navbar({
2891
2908
  children: link.label
2892
2909
  }) }, link.label)) }),
2893
2910
  hasRightContent && /* @__PURE__ */ jsxs("div", { className: "hidden items-center justify-end gap-2 md:flex", children: [
2894
- controls?.map((control, i) => /* @__PURE__ */ jsx(React31.Fragment, { children: control }, i)),
2911
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React32.Fragment, { children: control }, i)),
2895
2912
  (cta?.secondary || cta?.primary) && controls?.length ? /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-border" }) : null,
2896
2913
  cta?.secondary && renderLink({
2897
2914
  href: cta.secondary.href,
@@ -2915,7 +2932,7 @@ function Navbar({
2915
2932
  /* @__PURE__ */ jsx("span", { children: brand.name })
2916
2933
  ] })
2917
2934
  }) }) }),
2918
- controls?.length ? /* @__PURE__ */ jsx("div", { className: "mb-4 flex w-full items-center justify-between gap-1", children: controls.map((control, i) => /* @__PURE__ */ jsx(React31.Fragment, { children: control }, i)) }) : null,
2935
+ controls?.length ? /* @__PURE__ */ jsx("div", { className: "mb-4 flex w-full items-center justify-between gap-1", children: controls.map((control, i) => /* @__PURE__ */ jsx(React32.Fragment, { children: control }, i)) }) : null,
2919
2936
  /* @__PURE__ */ jsx(Separator, {}),
2920
2937
  /* @__PURE__ */ jsx("nav", { className: "mt-4 flex flex-col gap-1", children: navLinks.map((link) => /* @__PURE__ */ jsx("span", { onClick: () => setOpen(false), children: renderLink({
2921
2938
  href: link.href,
@@ -3064,7 +3081,7 @@ function LogoStrip({
3064
3081
  ] });
3065
3082
  }
3066
3083
  function GridUnderlay({ variant, size = 24, className, ...props }) {
3067
- const id = React31.useId();
3084
+ const id = React32.useId();
3068
3085
  const pattern = variant === "dots" ? /* @__PURE__ */ jsx("circle", { cx: size / 2, cy: size / 2, r: 1, fill: "currentColor" }) : variant === "lines" ? /* @__PURE__ */ jsx("path", { d: `M ${size} 0 L 0 0 0 ${size}`, fill: "none", stroke: "currentColor", strokeWidth: 0.5 }) : /* @__PURE__ */ jsxs(Fragment, { children: [
3069
3086
  /* @__PURE__ */ jsx("line", { x1: size / 2, y1: 0, x2: size / 2, y2: size, stroke: "currentColor", strokeWidth: 0.5 }),
3070
3087
  /* @__PURE__ */ jsx("line", { x1: 0, y1: size / 2, x2: size, y2: size / 2, stroke: "currentColor", strokeWidth: 0.5 })
@@ -3092,9 +3109,9 @@ function GlowUnderlay({
3092
3109
  style,
3093
3110
  ...props
3094
3111
  }) {
3095
- const [pos, setPos] = React31.useState({ x: "50%", y: "50%" });
3096
- const containerRef = React31.useRef(null);
3097
- React31.useEffect(() => {
3112
+ const [pos, setPos] = React32.useState({ x: "50%", y: "50%" });
3113
+ const containerRef = React32.useRef(null);
3114
+ React32.useEffect(() => {
3098
3115
  if (!followCursor) return;
3099
3116
  const handleMouseMove = (e) => {
3100
3117
  const el = containerRef.current;
@@ -3233,8 +3250,8 @@ function PageTransition({
3233
3250
  style,
3234
3251
  ...props
3235
3252
  }) {
3236
- const [mounted, setMounted] = React31.useState(false);
3237
- React31.useEffect(() => {
3253
+ const [mounted, setMounted] = React32.useState(false);
3254
+ React32.useEffect(() => {
3238
3255
  const id = requestAnimationFrame(() => setMounted(true));
3239
3256
  return () => cancelAnimationFrame(id);
3240
3257
  }, []);
@@ -3254,6 +3271,66 @@ function PageTransition({
3254
3271
  }
3255
3272
  );
3256
3273
  }
3274
+ var strategies = {
3275
+ vertical: verticalListSortingStrategy,
3276
+ horizontal: horizontalListSortingStrategy,
3277
+ grid: rectSortingStrategy
3278
+ };
3279
+ var containerClasses = {
3280
+ vertical: "flex flex-col gap-2",
3281
+ horizontal: "flex gap-2",
3282
+ grid: "grid gap-2"
3283
+ };
3284
+ function SortableItem({
3285
+ id,
3286
+ disabled,
3287
+ className,
3288
+ children
3289
+ }) {
3290
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id, disabled });
3291
+ return /* @__PURE__ */ jsx(
3292
+ "div",
3293
+ {
3294
+ ref: setNodeRef,
3295
+ style: { transform: CSS.Transform.toString(transform), transition },
3296
+ className: cn$1(
3297
+ "touch-none",
3298
+ !disabled && "cursor-grab active:cursor-grabbing",
3299
+ isDragging && "relative z-10 opacity-80",
3300
+ className
3301
+ ),
3302
+ ...attributes,
3303
+ ...listeners,
3304
+ children
3305
+ }
3306
+ );
3307
+ }
3308
+ function Sortable({
3309
+ items,
3310
+ onReorder,
3311
+ children,
3312
+ direction = "vertical",
3313
+ disabled,
3314
+ className,
3315
+ itemClassName
3316
+ }) {
3317
+ const sensors = useSensors(
3318
+ useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
3319
+ useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
3320
+ );
3321
+ const handleDragEnd = (event) => {
3322
+ const { active, over } = event;
3323
+ if (!over || active.id === over.id) return;
3324
+ const oldIndex = items.indexOf(String(active.id));
3325
+ const newIndex = items.indexOf(String(over.id));
3326
+ if (oldIndex === -1 || newIndex === -1) return;
3327
+ onReorder(arrayMove(items, oldIndex, newIndex));
3328
+ };
3329
+ const childArray = React32.Children.toArray(children);
3330
+ return /* @__PURE__ */ jsx(DndContext, { sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(SortableContext, { items, strategy: strategies[direction], children: /* @__PURE__ */ jsx("div", { className: cn$1(containerClasses[direction], className), children: childArray.map(
3331
+ (child, i) => items[i] === void 0 ? null : /* @__PURE__ */ jsx(SortableItem, { id: items[i], disabled, className: itemClassName, children: child }, items[i])
3332
+ ) }) }) });
3333
+ }
3257
3334
  function Spotlight({
3258
3335
  groups,
3259
3336
  placeholder = "Search anything...",
@@ -3261,8 +3338,8 @@ function Spotlight({
3261
3338
  triggerClassName,
3262
3339
  shortcut = "\u2318K"
3263
3340
  }) {
3264
- const [open, setOpen] = React31.useState(false);
3265
- React31.useEffect(() => {
3341
+ const [open, setOpen] = React32.useState(false);
3342
+ React32.useEffect(() => {
3266
3343
  const down = (e) => {
3267
3344
  if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
3268
3345
  e.preventDefault();
@@ -3292,7 +3369,7 @@ function Spotlight({
3292
3369
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3293
3370
  /* @__PURE__ */ jsxs(CommandList, { children: [
3294
3371
  /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
3295
- groups.map((group, i) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
3372
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
3296
3373
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3297
3374
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3298
3375
  CommandItem,
@@ -3317,8 +3394,8 @@ function Spotlight({
3317
3394
  var BASE = 40;
3318
3395
  var MAGNIFY_RADIUS = 80;
3319
3396
  function Dock({ items, iconSize = BASE, magnification = 1.7, className, ...props }) {
3320
- const [mouseX, setMouseX] = React31.useState(null);
3321
- const containerRef = React31.useRef(null);
3397
+ const [mouseX, setMouseX] = React32.useState(null);
3398
+ const containerRef = React32.useRef(null);
3322
3399
  function getScale(index) {
3323
3400
  if (mouseX === null || !containerRef.current) return 1;
3324
3401
  const container = containerRef.current;
@@ -3417,7 +3494,7 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
3417
3494
  ] }) });
3418
3495
  }
3419
3496
  function RegisterHotkeys({ hotkeys }) {
3420
- React31.useEffect(() => {
3497
+ React32.useEffect(() => {
3421
3498
  const handleKeyDown = (event) => {
3422
3499
  for (const hotkey of hotkeys) {
3423
3500
  const matches = event.key.toLowerCase() === hotkey.key.toLowerCase() && !!event.ctrlKey === !!hotkey.ctrl && !!event.metaKey === !!hotkey.meta && !!event.shiftKey === !!hotkey.shift && !!event.altKey === !!hotkey.alt;
@@ -3434,10 +3511,10 @@ function RegisterHotkeys({ hotkeys }) {
3434
3511
  return null;
3435
3512
  }
3436
3513
  function useControlledOpen(defaultOpen = false) {
3437
- const [isOpen, setIsOpen] = React31.useState(defaultOpen);
3438
- const open = React31.useCallback(() => setIsOpen(true), []);
3439
- const close = React31.useCallback(() => setIsOpen(false), []);
3440
- const toggle = React31.useCallback(() => setIsOpen((prev) => !prev), []);
3514
+ const [isOpen, setIsOpen] = React32.useState(defaultOpen);
3515
+ const open = React32.useCallback(() => setIsOpen(true), []);
3516
+ const close = React32.useCallback(() => setIsOpen(false), []);
3517
+ const toggle = React32.useCallback(() => setIsOpen((prev) => !prev), []);
3441
3518
  return { isOpen, open, close, toggle, setIsOpen };
3442
3519
  }
3443
3520
  function CommandMenu({
@@ -3450,7 +3527,7 @@ function CommandMenu({
3450
3527
  }) {
3451
3528
  const internal = useControlledOpen(false);
3452
3529
  const isOpen = openProp ?? internal.isOpen;
3453
- const setOpen = React31.useCallback(
3530
+ const setOpen = React32.useCallback(
3454
3531
  (next) => {
3455
3532
  if (openProp === void 0) internal.setIsOpen(next);
3456
3533
  onOpenChange?.(next);
@@ -3475,7 +3552,7 @@ function CommandMenu({
3475
3552
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3476
3553
  /* @__PURE__ */ jsxs(CommandList, { children: [
3477
3554
  /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
3478
- groups.map((group, i) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
3555
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
3479
3556
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3480
3557
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3481
3558
  CommandItem,
@@ -3495,6 +3572,157 @@ function CommandMenu({
3495
3572
  ] })
3496
3573
  ] });
3497
3574
  }
3575
+ var TOKEN_COLORS = ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
3576
+ var seriesColor = (s, i) => s.color ?? TOKEN_COLORS[i % TOKEN_COLORS.length];
3577
+ function ChartTooltip({
3578
+ active,
3579
+ payload,
3580
+ label,
3581
+ valueFormatter
3582
+ }) {
3583
+ if (!active || !payload?.length) return null;
3584
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-popover px-3 py-2 text-xs text-popover-foreground shadow-md", children: [
3585
+ label !== void 0 && /* @__PURE__ */ jsx("p", { className: "mb-1 font-medium", children: label }),
3586
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: payload.map((entry, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
3587
+ /* @__PURE__ */ jsx(
3588
+ "span",
3589
+ {
3590
+ "aria-hidden": true,
3591
+ className: "size-2 shrink-0 rounded-full",
3592
+ style: { background: entry.color ?? entry.payload?.fill }
3593
+ }
3594
+ ),
3595
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: entry.name }),
3596
+ /* @__PURE__ */ jsx("span", { className: "ml-auto pl-3 font-medium tabular-nums", children: typeof entry.value === "number" ? valueFormatter(entry.value) : entry.value })
3597
+ ] }, i)) })
3598
+ ] });
3599
+ }
3600
+ function ChartLegend({ entries }) {
3601
+ return /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap items-center justify-center gap-x-4 gap-y-1", children: entries.map((entry) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
3602
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "size-2 rounded-full", style: { background: entry.color } }),
3603
+ entry.label
3604
+ ] }, entry.label)) });
3605
+ }
3606
+ var axisProps = {
3607
+ tickLine: false,
3608
+ axisLine: false,
3609
+ tick: { fill: "var(--muted-foreground)", fontSize: 12 },
3610
+ tickMargin: 8
3611
+ };
3612
+ function Chart({
3613
+ type = "line",
3614
+ data,
3615
+ xKey,
3616
+ series,
3617
+ height = 300,
3618
+ grid = true,
3619
+ legend,
3620
+ valueFormatter = (v) => String(v),
3621
+ className
3622
+ }) {
3623
+ const showLegend = legend ?? (type === "donut" || series.length > 1);
3624
+ const tooltip = /* @__PURE__ */ jsx(
3625
+ Tooltip$1,
3626
+ {
3627
+ cursor: type === "bar" ? { fill: "var(--muted)", opacity: 0.4 } : { stroke: "var(--border)" },
3628
+ content: /* @__PURE__ */ jsx(ChartTooltip, { valueFormatter })
3629
+ }
3630
+ );
3631
+ const gridEl = grid ? /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "var(--border)", strokeOpacity: 0.6 }) : null;
3632
+ let chart;
3633
+ let legendEntries;
3634
+ if (type === "donut") {
3635
+ const valueKey = series[0]?.key;
3636
+ legendEntries = data.map((row, i) => ({
3637
+ label: String(row[xKey]),
3638
+ color: TOKEN_COLORS[i % TOKEN_COLORS.length]
3639
+ }));
3640
+ chart = /* @__PURE__ */ jsxs(PieChart, { children: [
3641
+ /* @__PURE__ */ jsx(
3642
+ Pie,
3643
+ {
3644
+ data,
3645
+ dataKey: valueKey,
3646
+ nameKey: xKey,
3647
+ innerRadius: "60%",
3648
+ outerRadius: "85%",
3649
+ paddingAngle: 2,
3650
+ stroke: "var(--card)",
3651
+ strokeWidth: 2,
3652
+ children: data.map((row, i) => /* @__PURE__ */ jsx(Cell, { fill: TOKEN_COLORS[i % TOKEN_COLORS.length] }, String(row[xKey])))
3653
+ }
3654
+ ),
3655
+ tooltip
3656
+ ] });
3657
+ } else {
3658
+ legendEntries = series.map((s, i) => ({ label: s.label ?? s.key, color: seriesColor(s, i) }));
3659
+ if (type === "bar") {
3660
+ chart = /* @__PURE__ */ jsxs(BarChart, { data, barCategoryGap: "25%", children: [
3661
+ gridEl,
3662
+ /* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
3663
+ /* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
3664
+ tooltip,
3665
+ series.map((s, i) => /* @__PURE__ */ jsx(
3666
+ Bar,
3667
+ {
3668
+ dataKey: s.key,
3669
+ name: s.label ?? s.key,
3670
+ fill: seriesColor(s, i),
3671
+ radius: [4, 4, 0, 0],
3672
+ maxBarSize: 40
3673
+ },
3674
+ s.key
3675
+ ))
3676
+ ] });
3677
+ } else if (type === "area") {
3678
+ chart = /* @__PURE__ */ jsxs(AreaChart, { data, children: [
3679
+ gridEl,
3680
+ /* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
3681
+ /* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
3682
+ tooltip,
3683
+ series.map((s, i) => /* @__PURE__ */ jsx(
3684
+ Area,
3685
+ {
3686
+ type: "monotone",
3687
+ dataKey: s.key,
3688
+ name: s.label ?? s.key,
3689
+ stroke: seriesColor(s, i),
3690
+ strokeWidth: 2,
3691
+ fill: seriesColor(s, i),
3692
+ fillOpacity: 0.12,
3693
+ dot: false,
3694
+ activeDot: { r: 4 }
3695
+ },
3696
+ s.key
3697
+ ))
3698
+ ] });
3699
+ } else {
3700
+ chart = /* @__PURE__ */ jsxs(LineChart, { data, children: [
3701
+ gridEl,
3702
+ /* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
3703
+ /* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
3704
+ tooltip,
3705
+ series.map((s, i) => /* @__PURE__ */ jsx(
3706
+ Line,
3707
+ {
3708
+ type: "monotone",
3709
+ dataKey: s.key,
3710
+ name: s.label ?? s.key,
3711
+ stroke: seriesColor(s, i),
3712
+ strokeWidth: 2,
3713
+ dot: false,
3714
+ activeDot: { r: 4 }
3715
+ },
3716
+ s.key
3717
+ ))
3718
+ ] });
3719
+ }
3720
+ }
3721
+ return /* @__PURE__ */ jsxs("div", { className: cn$1("w-full", className), children: [
3722
+ /* @__PURE__ */ jsx("div", { style: { height }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: chart }) }),
3723
+ showLegend && /* @__PURE__ */ jsx(ChartLegend, { entries: legendEntries })
3724
+ ] });
3725
+ }
3498
3726
  function formatBytes(bytes) {
3499
3727
  if (bytes < 1024) return `${bytes} B`;
3500
3728
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
@@ -3516,20 +3744,20 @@ function FileUpload({
3516
3744
  hint,
3517
3745
  className
3518
3746
  }) {
3519
- const [internalFiles, setInternalFiles] = React31.useState(defaultFiles ?? []);
3520
- const [isDragging, setIsDragging] = React31.useState(false);
3521
- const [validationError, setValidationError] = React31.useState(null);
3522
- const inputRef = React31.useRef(null);
3523
- const dragDepth = React31.useRef(0);
3747
+ const [internalFiles, setInternalFiles] = React32.useState(defaultFiles ?? []);
3748
+ const [isDragging, setIsDragging] = React32.useState(false);
3749
+ const [validationError, setValidationError] = React32.useState(null);
3750
+ const inputRef = React32.useRef(null);
3751
+ const dragDepth = React32.useRef(0);
3524
3752
  const files = filesProp ?? internalFiles;
3525
- const setFiles = React31.useCallback(
3753
+ const setFiles = React32.useCallback(
3526
3754
  (next) => {
3527
3755
  if (!filesProp) setInternalFiles(next);
3528
3756
  onFilesChange?.(next);
3529
3757
  },
3530
3758
  [filesProp, onFilesChange]
3531
3759
  );
3532
- const acceptList = React31.useMemo(
3760
+ const acceptList = React32.useMemo(
3533
3761
  () => accept?.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean) ?? [],
3534
3762
  [accept]
3535
3763
  );
@@ -4196,7 +4424,7 @@ function PageHeader({
4196
4424
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 pb-6", className), children: [
4197
4425
  breadcrumbs && breadcrumbs.length > 0 && /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-2 flex items-center gap-1 text-sm text-muted-foreground", children: breadcrumbs.map((crumb, i) => {
4198
4426
  const isLast = i === breadcrumbs.length - 1;
4199
- return /* @__PURE__ */ jsxs(React31.Fragment, { children: [
4427
+ return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
4200
4428
  i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0" }),
4201
4429
  isLast || !crumb.href ? /* @__PURE__ */ jsx("span", { className: cn(isLast && "text-foreground font-medium"), children: crumb.label }) : renderLink({
4202
4430
  href: crumb.href,
@@ -4232,7 +4460,7 @@ function PageHeader({
4232
4460
  ] });
4233
4461
  }
4234
4462
  function Suspensed({ children, fallback }) {
4235
- return /* @__PURE__ */ jsx(React31.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4463
+ return /* @__PURE__ */ jsx(React32.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4236
4464
  }
4237
4465
  function getInitialTheme() {
4238
4466
  if (typeof document === "undefined") return "dark";
@@ -4240,7 +4468,7 @@ function getInitialTheme() {
4240
4468
  return stored ?? (document.documentElement.classList.contains("dark") ? "dark" : "light");
4241
4469
  }
4242
4470
  function ThemeSwitchMinimal() {
4243
- const [theme, setThemeState] = React31.useState(getInitialTheme);
4471
+ const [theme, setThemeState] = React32.useState(getInitialTheme);
4244
4472
  const toggle = () => {
4245
4473
  const next = theme === "dark" ? "light" : "dark";
4246
4474
  setThemeState(next);
@@ -4366,9 +4594,9 @@ function getInitialColorName() {
4366
4594
  return localStorage.getItem(STORAGE_KEY) ?? "emerald";
4367
4595
  }
4368
4596
  function BrandColorSwitchMinimal() {
4369
- const [active, setActive] = React31.useState(getInitialColorName);
4370
- const [open, setOpen] = React31.useState(false);
4371
- React31.useEffect(() => {
4597
+ const [active, setActive] = React32.useState(getInitialColorName);
4598
+ const [open, setOpen] = React32.useState(false);
4599
+ React32.useEffect(() => {
4372
4600
  const saved = localStorage.getItem(STORAGE_KEY) ?? "emerald";
4373
4601
  const color = BRAND_COLORS.find((c) => c.name === saved);
4374
4602
  if (color) applyColor(color);
@@ -4429,7 +4657,7 @@ function BrandColorSwitchMinimal() {
4429
4657
  ] });
4430
4658
  }
4431
4659
  function ThemeColorUpdater({ colorTheme }) {
4432
- React31.useEffect(() => {
4660
+ React32.useEffect(() => {
4433
4661
  if (colorTheme) {
4434
4662
  document.documentElement.setAttribute("data-theme", colorTheme);
4435
4663
  } else {
@@ -4439,7 +4667,7 @@ function ThemeColorUpdater({ colorTheme }) {
4439
4667
  return null;
4440
4668
  }
4441
4669
  function VersionBanner({ version, message, className, onDismiss }) {
4442
- const [dismissed, setDismissed] = React31.useState(false);
4670
+ const [dismissed, setDismissed] = React32.useState(false);
4443
4671
  if (dismissed) return null;
4444
4672
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-4 bg-primary/10 px-4 py-2 text-sm", className), children: [
4445
4673
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -4696,29 +4924,29 @@ function useMounted() {
4696
4924
  return mounted;
4697
4925
  }
4698
4926
  function useConfirm() {
4699
- const [isOpen, setIsOpen] = React31.useState(false);
4700
- const [options, setOptions] = React31.useState({});
4701
- const resolveRef = React31.useRef(null);
4702
- const confirm = React31.useCallback((opts = {}) => {
4927
+ const [isOpen, setIsOpen] = React32.useState(false);
4928
+ const [options, setOptions] = React32.useState({});
4929
+ const resolveRef = React32.useRef(null);
4930
+ const confirm = React32.useCallback((opts = {}) => {
4703
4931
  setOptions(opts);
4704
4932
  setIsOpen(true);
4705
4933
  return new Promise((resolve) => {
4706
4934
  resolveRef.current = resolve;
4707
4935
  });
4708
4936
  }, []);
4709
- const handleConfirm = React31.useCallback(() => {
4937
+ const handleConfirm = React32.useCallback(() => {
4710
4938
  resolveRef.current?.(true);
4711
4939
  setIsOpen(false);
4712
4940
  }, []);
4713
- const handleCancel = React31.useCallback(() => {
4941
+ const handleCancel = React32.useCallback(() => {
4714
4942
  resolveRef.current?.(false);
4715
4943
  setIsOpen(false);
4716
4944
  }, []);
4717
4945
  return { confirm, isOpen, options, handleConfirm, handleCancel };
4718
4946
  }
4719
4947
  function useScrolledPast(threshold) {
4720
- const [scrolledPast, setScrolledPast] = React31.useState(false);
4721
- React31.useEffect(() => {
4948
+ const [scrolledPast, setScrolledPast] = React32.useState(false);
4949
+ React32.useEffect(() => {
4722
4950
  const handleScroll = () => {
4723
4951
  setScrolledPast(window.scrollY > threshold);
4724
4952
  };
@@ -4729,28 +4957,28 @@ function useScrolledPast(threshold) {
4729
4957
  return scrolledPast;
4730
4958
  }
4731
4959
  function useCopyToClipboard() {
4732
- const [copied, setCopied] = React31.useState(false);
4733
- const timeoutRef = React31.useRef(void 0);
4734
- const copy = React31.useCallback((text) => {
4960
+ const [copied, setCopied] = React32.useState(false);
4961
+ const timeoutRef = React32.useRef(void 0);
4962
+ const copy = React32.useCallback((text) => {
4735
4963
  navigator.clipboard.writeText(text).then(() => {
4736
4964
  setCopied(true);
4737
4965
  clearTimeout(timeoutRef.current);
4738
4966
  timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
4739
4967
  });
4740
4968
  }, []);
4741
- React31.useEffect(() => () => clearTimeout(timeoutRef.current), []);
4969
+ React32.useEffect(() => () => clearTimeout(timeoutRef.current), []);
4742
4970
  return [copied, copy];
4743
4971
  }
4744
4972
  function useDebounce(value, delay) {
4745
- const [debounced, setDebounced] = React31.useState(value);
4746
- React31.useEffect(() => {
4973
+ const [debounced, setDebounced] = React32.useState(value);
4974
+ React32.useEffect(() => {
4747
4975
  const timer = setTimeout(() => setDebounced(value), delay);
4748
4976
  return () => clearTimeout(timer);
4749
4977
  }, [value, delay]);
4750
4978
  return debounced;
4751
4979
  }
4752
4980
  function useLocalStorage(key, initialValue) {
4753
- const [storedValue, setStoredValue] = React31.useState(() => {
4981
+ const [storedValue, setStoredValue] = React32.useState(() => {
4754
4982
  if (typeof window === "undefined") return initialValue;
4755
4983
  try {
4756
4984
  const item = window.localStorage.getItem(key);
@@ -4759,7 +4987,7 @@ function useLocalStorage(key, initialValue) {
4759
4987
  return initialValue;
4760
4988
  }
4761
4989
  });
4762
- const setValue = React31.useCallback(
4990
+ const setValue = React32.useCallback(
4763
4991
  (value) => {
4764
4992
  try {
4765
4993
  setStoredValue(value);
@@ -4774,11 +5002,11 @@ function useLocalStorage(key, initialValue) {
4774
5002
  return [storedValue, setValue];
4775
5003
  }
4776
5004
  function useMediaQuery(query) {
4777
- const [matches, setMatches] = React31.useState(() => {
5005
+ const [matches, setMatches] = React32.useState(() => {
4778
5006
  if (typeof window === "undefined") return false;
4779
5007
  return window.matchMedia(query).matches;
4780
5008
  });
4781
- React31.useEffect(() => {
5009
+ React32.useEffect(() => {
4782
5010
  if (typeof window === "undefined") return;
4783
5011
  const mql = window.matchMedia(query);
4784
5012
  setMatches(mql.matches);
@@ -4789,18 +5017,18 @@ function useMediaQuery(query) {
4789
5017
  return matches;
4790
5018
  }
4791
5019
  function usePagination(total, pageSize) {
4792
- const [page, setPage] = React31.useState(1);
5020
+ const [page, setPage] = React32.useState(1);
4793
5021
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
4794
5022
  const offset = (page - 1) * pageSize;
4795
- const goTo = React31.useCallback(
5023
+ const goTo = React32.useCallback(
4796
5024
  (p) => setPage(Math.min(Math.max(1, p), totalPages)),
4797
5025
  [totalPages]
4798
5026
  );
4799
- const next = React31.useCallback(() => goTo(page + 1), [page, goTo]);
4800
- const prev = React31.useCallback(() => goTo(page - 1), [page, goTo]);
5027
+ const next = React32.useCallback(() => goTo(page + 1), [page, goTo]);
5028
+ const prev = React32.useCallback(() => goTo(page - 1), [page, goTo]);
4801
5029
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
4802
5030
  }
4803
5031
 
4804
- export { ActivityFeed, AnimatedPill, AppContent, AppGrid, AppGridCell, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, ModeSwitchMinimal, Navbar, NewsletterSection, NotificationToast, NotificationsPopover, OlwibaUIProvider, OnboardingWizard, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, SettingsSection, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamMembersPanel, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpgradePrompt, VersionBanner, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
5032
+ export { ActivityFeed, AnimatedPill, AppContent, AppGrid, AppGridCell, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, ModeSwitchMinimal, Navbar, NewsletterSection, NotificationToast, NotificationsPopover, OlwibaUIProvider, OnboardingWizard, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, PublicPageFrame, QualificationSection, RegisterHotkeys, RootErrorFallback, Section, SectionTitle, SettingsSection, Sortable, Spotlight, Stack, StaggerChildren, StatCard, StatsSection, StepsSection, Suspensed, Switch, TeamMembersPanel, TeamSection, TechStackSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpgradePrompt, VersionBanner, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
4805
5033
  //# sourceMappingURL=index.js.map
4806
5034
  //# sourceMappingURL=index.js.map