@olwiba/ui 0.2.0 → 0.2.1

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";
@@ -513,7 +517,7 @@ function DefaultForm({
513
517
  const isForgotPassword = mode === "forgot-password";
514
518
  const isResetPassword = mode === "reset-password";
515
519
  const isVerify = mode === "verify";
516
- const [code, setCode] = React31.useState("");
520
+ const [code, setCode] = React32.useState("");
517
521
  const hasPrefill = !!(defaultEmail || defaultPassword);
518
522
  const prefillStyle = (active) => active ? { animation: "auth-prefill 1.6s ease-out 0.35s 1 both" } : void 0;
519
523
  const copy = authCopy[mode];
@@ -673,10 +677,10 @@ function DataTable({
673
677
  emptyMessage = "No results.",
674
678
  className
675
679
  }) {
676
- const [sorting, setSorting] = React31.useState([]);
677
- const [rowSelection, setRowSelection] = React31.useState({});
678
- const [globalFilter, setGlobalFilter] = React31.useState("");
679
- const allColumns = React31.useMemo(
680
+ const [sorting, setSorting] = React32.useState([]);
681
+ const [rowSelection, setRowSelection] = React32.useState({});
682
+ const [globalFilter, setGlobalFilter] = React32.useState("");
683
+ const allColumns = React32.useMemo(
680
684
  () => selectable ? [selectColumn, ...columns] : columns,
681
685
  [selectable, columns]
682
686
  );
@@ -698,7 +702,7 @@ function DataTable({
698
702
  initialState: pageSize > 0 ? { pagination: { pageSize } } : void 0,
699
703
  enableRowSelection: selectable
700
704
  });
701
- React31.useEffect(() => {
705
+ React32.useEffect(() => {
702
706
  if (!onSelectionChange) return;
703
707
  onSelectionChange(table.getSelectedRowModel().rows.map((r) => r.original));
704
708
  }, [rowSelection]);
@@ -778,8 +782,8 @@ function DataTable({
778
782
  ] });
779
783
  }
780
784
  function InviteDialog({ roles, onInvite, onClose }) {
781
- const [email, setEmail] = React31.useState("");
782
- const [role, setRole] = React31.useState(roles[roles.length - 1] ?? roles[0]);
785
+ const [email, setEmail] = React32.useState("");
786
+ const [role, setRole] = React32.useState(roles[roles.length - 1] ?? roles[0]);
783
787
  return /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(
784
788
  "form",
785
789
  {
@@ -823,8 +827,8 @@ function TeamMembersPanel({
823
827
  title = "Team members",
824
828
  description = "Manage who has access to this workspace."
825
829
  }) {
826
- const [inviteOpen, setInviteOpen] = React31.useState(false);
827
- const columns = React31.useMemo(() => [
830
+ const [inviteOpen, setInviteOpen] = React32.useState(false);
831
+ const columns = React32.useMemo(() => [
828
832
  {
829
833
  accessorKey: "name",
830
834
  header: "Name",
@@ -893,7 +897,7 @@ function BillingPanel({
893
897
  onUpdatePaymentMethod,
894
898
  className
895
899
  }) {
896
- const invoiceColumns = React31.useMemo(() => [
900
+ const invoiceColumns = React32.useMemo(() => [
897
901
  { accessorKey: "date", header: "Date", enableSorting: false },
898
902
  { accessorKey: "amount", header: "Amount", enableSorting: false },
899
903
  {
@@ -972,9 +976,9 @@ function OnboardingWizard({
972
976
  completeLabel = "Finish",
973
977
  className
974
978
  }) {
975
- const [internalStep, setInternalStep] = React31.useState(0);
976
- const [error, setError] = React31.useState(null);
977
- const [pending, setPending] = React31.useState(false);
979
+ const [internalStep, setInternalStep] = React32.useState(0);
980
+ const [error, setError] = React32.useState(null);
981
+ const [pending, setPending] = React32.useState(false);
978
982
  const index = stepProp ?? internalStep;
979
983
  const current = steps[index];
980
984
  const isLast = index === steps.length - 1;
@@ -1308,9 +1312,9 @@ function FadeIn({
1308
1312
  style,
1309
1313
  ...props
1310
1314
  }) {
1311
- const ref = React31.useRef(null);
1312
- const [visible, setVisible] = React31.useState(false);
1313
- React31.useEffect(() => {
1315
+ const ref = React32.useRef(null);
1316
+ const [visible, setVisible] = React32.useState(false);
1317
+ React32.useEffect(() => {
1314
1318
  const el = ref.current;
1315
1319
  if (!el) return;
1316
1320
  const observer = new IntersectionObserver(
@@ -1505,16 +1509,16 @@ function Carousel({
1505
1509
  className
1506
1510
  }) {
1507
1511
  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(() => {
1512
+ const trackRef = React32.useRef(null);
1513
+ const [canPrev, setCanPrev] = React32.useState(false);
1514
+ const [canNext, setCanNext] = React32.useState(true);
1515
+ const updateScrollState = React32.useCallback(() => {
1512
1516
  const track = trackRef.current;
1513
1517
  if (!track) return;
1514
1518
  setCanPrev(track.scrollLeft > 8);
1515
1519
  setCanNext(track.scrollLeft < track.scrollWidth - track.clientWidth - 8);
1516
1520
  }, []);
1517
- React31.useEffect(() => {
1521
+ React32.useEffect(() => {
1518
1522
  const track = trackRef.current;
1519
1523
  if (!track) return;
1520
1524
  updateScrollState();
@@ -1571,7 +1575,7 @@ function Carousel({
1571
1575
  role: "region",
1572
1576
  "aria-label": ariaLabel,
1573
1577
  className: "flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1574
- children: React31.Children.map(
1578
+ children: React32.Children.map(
1575
1579
  children,
1576
1580
  (child) => child == null ? null : /* @__PURE__ */ jsx("div", { "data-carousel-item": true, className: cn$1("shrink-0 snap-start", itemClassName), children: child })
1577
1581
  )
@@ -1596,9 +1600,9 @@ function StaggerChildren({
1596
1600
  className,
1597
1601
  ...props
1598
1602
  }) {
1599
- const ref = React31.useRef(null);
1600
- const [visible, setVisible] = React31.useState(false);
1601
- React31.useEffect(() => {
1603
+ const ref = React32.useRef(null);
1604
+ const [visible, setVisible] = React32.useState(false);
1605
+ React32.useEffect(() => {
1602
1606
  const el = ref.current;
1603
1607
  if (!el) return;
1604
1608
  const observer = new IntersectionObserver(
@@ -1616,7 +1620,7 @@ function StaggerChildren({
1616
1620
  return () => observer.disconnect();
1617
1621
  }, [once]);
1618
1622
  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(
1623
+ return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React32.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1620
1624
  "div",
1621
1625
  {
1622
1626
  className: "h-full",
@@ -1867,9 +1871,9 @@ function FeatureMarqueeSection({
1867
1871
  ] });
1868
1872
  }
1869
1873
  function useIntersectionObserver(options) {
1870
- const ref = React31.useRef(null);
1871
- const [isIntersecting, setIsIntersecting] = React31.useState(false);
1872
- React31.useEffect(() => {
1874
+ const ref = React32.useRef(null);
1875
+ const [isIntersecting, setIsIntersecting] = React32.useState(false);
1876
+ React32.useEffect(() => {
1873
1877
  const el = ref.current;
1874
1878
  if (!el) return;
1875
1879
  const observer = new IntersectionObserver(([entry]) => {
@@ -1891,8 +1895,8 @@ function ShowcaseCta({
1891
1895
  sectionClasses
1892
1896
  }) {
1893
1897
  const [ref, intersecting] = useIntersectionObserver({ threshold: 0.15 });
1894
- const [visible, setVisible] = React31.useState(false);
1895
- React31.useEffect(() => {
1898
+ const [visible, setVisible] = React32.useState(false);
1899
+ React32.useEffect(() => {
1896
1900
  if (intersecting) setVisible(true);
1897
1901
  }, [intersecting]);
1898
1902
  return /* @__PURE__ */ jsxs(
@@ -2069,8 +2073,8 @@ function CountdownTimer({
2069
2073
  className,
2070
2074
  compact = false
2071
2075
  }) {
2072
- const [timeLeft, setTimeLeft] = React31.useState(() => getTimeLeft(deadline));
2073
- React31.useEffect(() => {
2076
+ const [timeLeft, setTimeLeft] = React32.useState(() => getTimeLeft(deadline));
2077
+ React32.useEffect(() => {
2074
2078
  setTimeLeft(getTimeLeft(deadline));
2075
2079
  const id = setInterval(() => setTimeLeft(getTimeLeft(deadline)), 1e3);
2076
2080
  return () => clearInterval(id);
@@ -2096,7 +2100,7 @@ function CountdownTimer({
2096
2100
  ];
2097
2101
  return /* @__PURE__ */ jsxs("div", { className: cn$1("flex items-center justify-center gap-2 text-sm", className), children: [
2098
2102
  /* @__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: [
2103
+ /* @__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
2104
  /* @__PURE__ */ jsxs("span", { children: [
2101
2105
  String(value).padStart(2, "0"),
2102
2106
  /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: unit })
@@ -2119,7 +2123,7 @@ function PricingSection({
2119
2123
  foundingDeadline,
2120
2124
  renderPlanFooter
2121
2125
  }) {
2122
- const [annual, setAnnual] = React31.useState(false);
2126
+ const [annual, setAnnual] = React32.useState(false);
2123
2127
  const isOneTime = mode === "one-time";
2124
2128
  const uiMode = useUIVariant();
2125
2129
  const sectionClasses = cn$1(
@@ -2388,10 +2392,10 @@ function CountUp({
2388
2392
  className,
2389
2393
  ...props
2390
2394
  }) {
2391
- const ref = React31.useRef(null);
2392
- const [value, setValue] = React31.useState(from);
2393
- const hasStarted = React31.useRef(false);
2394
- React31.useEffect(() => {
2395
+ const ref = React32.useRef(null);
2396
+ const [value, setValue] = React32.useState(from);
2397
+ const hasStarted = React32.useRef(false);
2398
+ React32.useEffect(() => {
2395
2399
  const el = ref.current;
2396
2400
  if (!el) return;
2397
2401
  const observer = new IntersectionObserver(
@@ -2484,8 +2488,8 @@ function NewsletterSection({
2484
2488
  successDescription = defaults.successDescription,
2485
2489
  onSubscribe
2486
2490
  } = {}) {
2487
- const [email, setEmail] = React31.useState("");
2488
- const [submitted, setSubmitted] = React31.useState(false);
2491
+ const [email, setEmail] = React32.useState("");
2492
+ const [submitted, setSubmitted] = React32.useState(false);
2489
2493
  const mode = useUIVariant();
2490
2494
  const sectionClasses = cn$1(
2491
2495
  "overflow-hidden bg-card",
@@ -2576,7 +2580,7 @@ function ContactSection({
2576
2580
  sendAnotherLabel = defaults2.sendAnotherLabel,
2577
2581
  onSubmit
2578
2582
  } = {}) {
2579
- const [submitted, setSubmitted] = React31.useState(false);
2583
+ const [submitted, setSubmitted] = React32.useState(false);
2580
2584
  const mode = useUIVariant();
2581
2585
  const sectionClasses = cn$1(
2582
2586
  "overflow-hidden bg-card",
@@ -2874,7 +2878,7 @@ function Navbar({
2874
2878
  controls,
2875
2879
  renderLink = defaultRenderLink7
2876
2880
  }) {
2877
- const [open, setOpen] = React31.useState(false);
2881
+ const [open, setOpen] = React32.useState(false);
2878
2882
  const brandHref = brand.href ?? "/";
2879
2883
  const hasRightContent = controls?.length || cta?.primary || cta?.secondary;
2880
2884
  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 +2895,7 @@ function Navbar({
2891
2895
  children: link.label
2892
2896
  }) }, link.label)) }),
2893
2897
  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)),
2898
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React32.Fragment, { children: control }, i)),
2895
2899
  (cta?.secondary || cta?.primary) && controls?.length ? /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-border" }) : null,
2896
2900
  cta?.secondary && renderLink({
2897
2901
  href: cta.secondary.href,
@@ -2915,7 +2919,7 @@ function Navbar({
2915
2919
  /* @__PURE__ */ jsx("span", { children: brand.name })
2916
2920
  ] })
2917
2921
  }) }) }),
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,
2922
+ 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
2923
  /* @__PURE__ */ jsx(Separator, {}),
2920
2924
  /* @__PURE__ */ jsx("nav", { className: "mt-4 flex flex-col gap-1", children: navLinks.map((link) => /* @__PURE__ */ jsx("span", { onClick: () => setOpen(false), children: renderLink({
2921
2925
  href: link.href,
@@ -3064,7 +3068,7 @@ function LogoStrip({
3064
3068
  ] });
3065
3069
  }
3066
3070
  function GridUnderlay({ variant, size = 24, className, ...props }) {
3067
- const id = React31.useId();
3071
+ const id = React32.useId();
3068
3072
  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
3073
  /* @__PURE__ */ jsx("line", { x1: size / 2, y1: 0, x2: size / 2, y2: size, stroke: "currentColor", strokeWidth: 0.5 }),
3070
3074
  /* @__PURE__ */ jsx("line", { x1: 0, y1: size / 2, x2: size, y2: size / 2, stroke: "currentColor", strokeWidth: 0.5 })
@@ -3092,9 +3096,9 @@ function GlowUnderlay({
3092
3096
  style,
3093
3097
  ...props
3094
3098
  }) {
3095
- const [pos, setPos] = React31.useState({ x: "50%", y: "50%" });
3096
- const containerRef = React31.useRef(null);
3097
- React31.useEffect(() => {
3099
+ const [pos, setPos] = React32.useState({ x: "50%", y: "50%" });
3100
+ const containerRef = React32.useRef(null);
3101
+ React32.useEffect(() => {
3098
3102
  if (!followCursor) return;
3099
3103
  const handleMouseMove = (e) => {
3100
3104
  const el = containerRef.current;
@@ -3233,8 +3237,8 @@ function PageTransition({
3233
3237
  style,
3234
3238
  ...props
3235
3239
  }) {
3236
- const [mounted, setMounted] = React31.useState(false);
3237
- React31.useEffect(() => {
3240
+ const [mounted, setMounted] = React32.useState(false);
3241
+ React32.useEffect(() => {
3238
3242
  const id = requestAnimationFrame(() => setMounted(true));
3239
3243
  return () => cancelAnimationFrame(id);
3240
3244
  }, []);
@@ -3254,6 +3258,66 @@ function PageTransition({
3254
3258
  }
3255
3259
  );
3256
3260
  }
3261
+ var strategies = {
3262
+ vertical: verticalListSortingStrategy,
3263
+ horizontal: horizontalListSortingStrategy,
3264
+ grid: rectSortingStrategy
3265
+ };
3266
+ var containerClasses = {
3267
+ vertical: "flex flex-col gap-2",
3268
+ horizontal: "flex gap-2",
3269
+ grid: "grid gap-2"
3270
+ };
3271
+ function SortableItem({
3272
+ id,
3273
+ disabled,
3274
+ className,
3275
+ children
3276
+ }) {
3277
+ const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id, disabled });
3278
+ return /* @__PURE__ */ jsx(
3279
+ "div",
3280
+ {
3281
+ ref: setNodeRef,
3282
+ style: { transform: CSS.Transform.toString(transform), transition },
3283
+ className: cn$1(
3284
+ "touch-none",
3285
+ !disabled && "cursor-grab active:cursor-grabbing",
3286
+ isDragging && "relative z-10 opacity-80",
3287
+ className
3288
+ ),
3289
+ ...attributes,
3290
+ ...listeners,
3291
+ children
3292
+ }
3293
+ );
3294
+ }
3295
+ function Sortable({
3296
+ items,
3297
+ onReorder,
3298
+ children,
3299
+ direction = "vertical",
3300
+ disabled,
3301
+ className,
3302
+ itemClassName
3303
+ }) {
3304
+ const sensors = useSensors(
3305
+ useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
3306
+ useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
3307
+ );
3308
+ const handleDragEnd = (event) => {
3309
+ const { active, over } = event;
3310
+ if (!over || active.id === over.id) return;
3311
+ const oldIndex = items.indexOf(String(active.id));
3312
+ const newIndex = items.indexOf(String(over.id));
3313
+ if (oldIndex === -1 || newIndex === -1) return;
3314
+ onReorder(arrayMove(items, oldIndex, newIndex));
3315
+ };
3316
+ const childArray = React32.Children.toArray(children);
3317
+ 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(
3318
+ (child, i) => items[i] === void 0 ? null : /* @__PURE__ */ jsx(SortableItem, { id: items[i], disabled, className: itemClassName, children: child }, items[i])
3319
+ ) }) }) });
3320
+ }
3257
3321
  function Spotlight({
3258
3322
  groups,
3259
3323
  placeholder = "Search anything...",
@@ -3261,8 +3325,8 @@ function Spotlight({
3261
3325
  triggerClassName,
3262
3326
  shortcut = "\u2318K"
3263
3327
  }) {
3264
- const [open, setOpen] = React31.useState(false);
3265
- React31.useEffect(() => {
3328
+ const [open, setOpen] = React32.useState(false);
3329
+ React32.useEffect(() => {
3266
3330
  const down = (e) => {
3267
3331
  if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
3268
3332
  e.preventDefault();
@@ -3292,7 +3356,7 @@ function Spotlight({
3292
3356
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3293
3357
  /* @__PURE__ */ jsxs(CommandList, { children: [
3294
3358
  /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
3295
- groups.map((group, i) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
3359
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
3296
3360
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3297
3361
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3298
3362
  CommandItem,
@@ -3317,8 +3381,8 @@ function Spotlight({
3317
3381
  var BASE = 40;
3318
3382
  var MAGNIFY_RADIUS = 80;
3319
3383
  function Dock({ items, iconSize = BASE, magnification = 1.7, className, ...props }) {
3320
- const [mouseX, setMouseX] = React31.useState(null);
3321
- const containerRef = React31.useRef(null);
3384
+ const [mouseX, setMouseX] = React32.useState(null);
3385
+ const containerRef = React32.useRef(null);
3322
3386
  function getScale(index) {
3323
3387
  if (mouseX === null || !containerRef.current) return 1;
3324
3388
  const container = containerRef.current;
@@ -3417,7 +3481,7 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
3417
3481
  ] }) });
3418
3482
  }
3419
3483
  function RegisterHotkeys({ hotkeys }) {
3420
- React31.useEffect(() => {
3484
+ React32.useEffect(() => {
3421
3485
  const handleKeyDown = (event) => {
3422
3486
  for (const hotkey of hotkeys) {
3423
3487
  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 +3498,10 @@ function RegisterHotkeys({ hotkeys }) {
3434
3498
  return null;
3435
3499
  }
3436
3500
  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), []);
3501
+ const [isOpen, setIsOpen] = React32.useState(defaultOpen);
3502
+ const open = React32.useCallback(() => setIsOpen(true), []);
3503
+ const close = React32.useCallback(() => setIsOpen(false), []);
3504
+ const toggle = React32.useCallback(() => setIsOpen((prev) => !prev), []);
3441
3505
  return { isOpen, open, close, toggle, setIsOpen };
3442
3506
  }
3443
3507
  function CommandMenu({
@@ -3450,7 +3514,7 @@ function CommandMenu({
3450
3514
  }) {
3451
3515
  const internal = useControlledOpen(false);
3452
3516
  const isOpen = openProp ?? internal.isOpen;
3453
- const setOpen = React31.useCallback(
3517
+ const setOpen = React32.useCallback(
3454
3518
  (next) => {
3455
3519
  if (openProp === void 0) internal.setIsOpen(next);
3456
3520
  onOpenChange?.(next);
@@ -3475,7 +3539,7 @@ function CommandMenu({
3475
3539
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3476
3540
  /* @__PURE__ */ jsxs(CommandList, { children: [
3477
3541
  /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
3478
- groups.map((group, i) => /* @__PURE__ */ jsxs(React31.Fragment, { children: [
3542
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
3479
3543
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3480
3544
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3481
3545
  CommandItem,
@@ -3495,6 +3559,157 @@ function CommandMenu({
3495
3559
  ] })
3496
3560
  ] });
3497
3561
  }
3562
+ var TOKEN_COLORS = ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
3563
+ var seriesColor = (s, i) => s.color ?? TOKEN_COLORS[i % TOKEN_COLORS.length];
3564
+ function ChartTooltip({
3565
+ active,
3566
+ payload,
3567
+ label,
3568
+ valueFormatter
3569
+ }) {
3570
+ if (!active || !payload?.length) return null;
3571
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-popover px-3 py-2 text-xs text-popover-foreground shadow-md", children: [
3572
+ label !== void 0 && /* @__PURE__ */ jsx("p", { className: "mb-1 font-medium", children: label }),
3573
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: payload.map((entry, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
3574
+ /* @__PURE__ */ jsx(
3575
+ "span",
3576
+ {
3577
+ "aria-hidden": true,
3578
+ className: "size-2 shrink-0 rounded-full",
3579
+ style: { background: entry.color ?? entry.payload?.fill }
3580
+ }
3581
+ ),
3582
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: entry.name }),
3583
+ /* @__PURE__ */ jsx("span", { className: "ml-auto pl-3 font-medium tabular-nums", children: typeof entry.value === "number" ? valueFormatter(entry.value) : entry.value })
3584
+ ] }, i)) })
3585
+ ] });
3586
+ }
3587
+ function ChartLegend({ entries }) {
3588
+ 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: [
3589
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "size-2 rounded-full", style: { background: entry.color } }),
3590
+ entry.label
3591
+ ] }, entry.label)) });
3592
+ }
3593
+ var axisProps = {
3594
+ tickLine: false,
3595
+ axisLine: false,
3596
+ tick: { fill: "var(--muted-foreground)", fontSize: 12 },
3597
+ tickMargin: 8
3598
+ };
3599
+ function Chart({
3600
+ type = "line",
3601
+ data,
3602
+ xKey,
3603
+ series,
3604
+ height = 300,
3605
+ grid = true,
3606
+ legend,
3607
+ valueFormatter = (v) => String(v),
3608
+ className
3609
+ }) {
3610
+ const showLegend = legend ?? (type === "donut" || series.length > 1);
3611
+ const tooltip = /* @__PURE__ */ jsx(
3612
+ Tooltip$1,
3613
+ {
3614
+ cursor: type === "bar" ? { fill: "var(--muted)", opacity: 0.4 } : { stroke: "var(--border)" },
3615
+ content: /* @__PURE__ */ jsx(ChartTooltip, { valueFormatter })
3616
+ }
3617
+ );
3618
+ const gridEl = grid ? /* @__PURE__ */ jsx(CartesianGrid, { vertical: false, stroke: "var(--border)", strokeOpacity: 0.6 }) : null;
3619
+ let chart;
3620
+ let legendEntries;
3621
+ if (type === "donut") {
3622
+ const valueKey = series[0]?.key;
3623
+ legendEntries = data.map((row, i) => ({
3624
+ label: String(row[xKey]),
3625
+ color: TOKEN_COLORS[i % TOKEN_COLORS.length]
3626
+ }));
3627
+ chart = /* @__PURE__ */ jsxs(PieChart, { children: [
3628
+ /* @__PURE__ */ jsx(
3629
+ Pie,
3630
+ {
3631
+ data,
3632
+ dataKey: valueKey,
3633
+ nameKey: xKey,
3634
+ innerRadius: "60%",
3635
+ outerRadius: "85%",
3636
+ paddingAngle: 2,
3637
+ stroke: "var(--card)",
3638
+ strokeWidth: 2,
3639
+ children: data.map((row, i) => /* @__PURE__ */ jsx(Cell, { fill: TOKEN_COLORS[i % TOKEN_COLORS.length] }, String(row[xKey])))
3640
+ }
3641
+ ),
3642
+ tooltip
3643
+ ] });
3644
+ } else {
3645
+ legendEntries = series.map((s, i) => ({ label: s.label ?? s.key, color: seriesColor(s, i) }));
3646
+ if (type === "bar") {
3647
+ chart = /* @__PURE__ */ jsxs(BarChart, { data, barCategoryGap: "25%", children: [
3648
+ gridEl,
3649
+ /* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
3650
+ /* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
3651
+ tooltip,
3652
+ series.map((s, i) => /* @__PURE__ */ jsx(
3653
+ Bar,
3654
+ {
3655
+ dataKey: s.key,
3656
+ name: s.label ?? s.key,
3657
+ fill: seriesColor(s, i),
3658
+ radius: [4, 4, 0, 0],
3659
+ maxBarSize: 40
3660
+ },
3661
+ s.key
3662
+ ))
3663
+ ] });
3664
+ } else if (type === "area") {
3665
+ chart = /* @__PURE__ */ jsxs(AreaChart, { data, children: [
3666
+ gridEl,
3667
+ /* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
3668
+ /* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
3669
+ tooltip,
3670
+ series.map((s, i) => /* @__PURE__ */ jsx(
3671
+ Area,
3672
+ {
3673
+ type: "monotone",
3674
+ dataKey: s.key,
3675
+ name: s.label ?? s.key,
3676
+ stroke: seriesColor(s, i),
3677
+ strokeWidth: 2,
3678
+ fill: seriesColor(s, i),
3679
+ fillOpacity: 0.12,
3680
+ dot: false,
3681
+ activeDot: { r: 4 }
3682
+ },
3683
+ s.key
3684
+ ))
3685
+ ] });
3686
+ } else {
3687
+ chart = /* @__PURE__ */ jsxs(LineChart, { data, children: [
3688
+ gridEl,
3689
+ /* @__PURE__ */ jsx(XAxis, { dataKey: xKey, ...axisProps }),
3690
+ /* @__PURE__ */ jsx(YAxis, { ...axisProps, width: 48, tickFormatter: valueFormatter }),
3691
+ tooltip,
3692
+ series.map((s, i) => /* @__PURE__ */ jsx(
3693
+ Line,
3694
+ {
3695
+ type: "monotone",
3696
+ dataKey: s.key,
3697
+ name: s.label ?? s.key,
3698
+ stroke: seriesColor(s, i),
3699
+ strokeWidth: 2,
3700
+ dot: false,
3701
+ activeDot: { r: 4 }
3702
+ },
3703
+ s.key
3704
+ ))
3705
+ ] });
3706
+ }
3707
+ }
3708
+ return /* @__PURE__ */ jsxs("div", { className: cn$1("w-full", className), children: [
3709
+ /* @__PURE__ */ jsx("div", { style: { height }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: chart }) }),
3710
+ showLegend && /* @__PURE__ */ jsx(ChartLegend, { entries: legendEntries })
3711
+ ] });
3712
+ }
3498
3713
  function formatBytes(bytes) {
3499
3714
  if (bytes < 1024) return `${bytes} B`;
3500
3715
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
@@ -3516,20 +3731,20 @@ function FileUpload({
3516
3731
  hint,
3517
3732
  className
3518
3733
  }) {
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);
3734
+ const [internalFiles, setInternalFiles] = React32.useState(defaultFiles ?? []);
3735
+ const [isDragging, setIsDragging] = React32.useState(false);
3736
+ const [validationError, setValidationError] = React32.useState(null);
3737
+ const inputRef = React32.useRef(null);
3738
+ const dragDepth = React32.useRef(0);
3524
3739
  const files = filesProp ?? internalFiles;
3525
- const setFiles = React31.useCallback(
3740
+ const setFiles = React32.useCallback(
3526
3741
  (next) => {
3527
3742
  if (!filesProp) setInternalFiles(next);
3528
3743
  onFilesChange?.(next);
3529
3744
  },
3530
3745
  [filesProp, onFilesChange]
3531
3746
  );
3532
- const acceptList = React31.useMemo(
3747
+ const acceptList = React32.useMemo(
3533
3748
  () => accept?.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean) ?? [],
3534
3749
  [accept]
3535
3750
  );
@@ -4196,7 +4411,7 @@ function PageHeader({
4196
4411
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 pb-6", className), children: [
4197
4412
  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
4413
  const isLast = i === breadcrumbs.length - 1;
4199
- return /* @__PURE__ */ jsxs(React31.Fragment, { children: [
4414
+ return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
4200
4415
  i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0" }),
4201
4416
  isLast || !crumb.href ? /* @__PURE__ */ jsx("span", { className: cn(isLast && "text-foreground font-medium"), children: crumb.label }) : renderLink({
4202
4417
  href: crumb.href,
@@ -4232,7 +4447,7 @@ function PageHeader({
4232
4447
  ] });
4233
4448
  }
4234
4449
  function Suspensed({ children, fallback }) {
4235
- return /* @__PURE__ */ jsx(React31.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4450
+ return /* @__PURE__ */ jsx(React32.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4236
4451
  }
4237
4452
  function getInitialTheme() {
4238
4453
  if (typeof document === "undefined") return "dark";
@@ -4240,7 +4455,7 @@ function getInitialTheme() {
4240
4455
  return stored ?? (document.documentElement.classList.contains("dark") ? "dark" : "light");
4241
4456
  }
4242
4457
  function ThemeSwitchMinimal() {
4243
- const [theme, setThemeState] = React31.useState(getInitialTheme);
4458
+ const [theme, setThemeState] = React32.useState(getInitialTheme);
4244
4459
  const toggle = () => {
4245
4460
  const next = theme === "dark" ? "light" : "dark";
4246
4461
  setThemeState(next);
@@ -4366,9 +4581,9 @@ function getInitialColorName() {
4366
4581
  return localStorage.getItem(STORAGE_KEY) ?? "emerald";
4367
4582
  }
4368
4583
  function BrandColorSwitchMinimal() {
4369
- const [active, setActive] = React31.useState(getInitialColorName);
4370
- const [open, setOpen] = React31.useState(false);
4371
- React31.useEffect(() => {
4584
+ const [active, setActive] = React32.useState(getInitialColorName);
4585
+ const [open, setOpen] = React32.useState(false);
4586
+ React32.useEffect(() => {
4372
4587
  const saved = localStorage.getItem(STORAGE_KEY) ?? "emerald";
4373
4588
  const color = BRAND_COLORS.find((c) => c.name === saved);
4374
4589
  if (color) applyColor(color);
@@ -4429,7 +4644,7 @@ function BrandColorSwitchMinimal() {
4429
4644
  ] });
4430
4645
  }
4431
4646
  function ThemeColorUpdater({ colorTheme }) {
4432
- React31.useEffect(() => {
4647
+ React32.useEffect(() => {
4433
4648
  if (colorTheme) {
4434
4649
  document.documentElement.setAttribute("data-theme", colorTheme);
4435
4650
  } else {
@@ -4439,7 +4654,7 @@ function ThemeColorUpdater({ colorTheme }) {
4439
4654
  return null;
4440
4655
  }
4441
4656
  function VersionBanner({ version, message, className, onDismiss }) {
4442
- const [dismissed, setDismissed] = React31.useState(false);
4657
+ const [dismissed, setDismissed] = React32.useState(false);
4443
4658
  if (dismissed) return null;
4444
4659
  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
4660
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -4696,29 +4911,29 @@ function useMounted() {
4696
4911
  return mounted;
4697
4912
  }
4698
4913
  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 = {}) => {
4914
+ const [isOpen, setIsOpen] = React32.useState(false);
4915
+ const [options, setOptions] = React32.useState({});
4916
+ const resolveRef = React32.useRef(null);
4917
+ const confirm = React32.useCallback((opts = {}) => {
4703
4918
  setOptions(opts);
4704
4919
  setIsOpen(true);
4705
4920
  return new Promise((resolve) => {
4706
4921
  resolveRef.current = resolve;
4707
4922
  });
4708
4923
  }, []);
4709
- const handleConfirm = React31.useCallback(() => {
4924
+ const handleConfirm = React32.useCallback(() => {
4710
4925
  resolveRef.current?.(true);
4711
4926
  setIsOpen(false);
4712
4927
  }, []);
4713
- const handleCancel = React31.useCallback(() => {
4928
+ const handleCancel = React32.useCallback(() => {
4714
4929
  resolveRef.current?.(false);
4715
4930
  setIsOpen(false);
4716
4931
  }, []);
4717
4932
  return { confirm, isOpen, options, handleConfirm, handleCancel };
4718
4933
  }
4719
4934
  function useScrolledPast(threshold) {
4720
- const [scrolledPast, setScrolledPast] = React31.useState(false);
4721
- React31.useEffect(() => {
4935
+ const [scrolledPast, setScrolledPast] = React32.useState(false);
4936
+ React32.useEffect(() => {
4722
4937
  const handleScroll = () => {
4723
4938
  setScrolledPast(window.scrollY > threshold);
4724
4939
  };
@@ -4729,28 +4944,28 @@ function useScrolledPast(threshold) {
4729
4944
  return scrolledPast;
4730
4945
  }
4731
4946
  function useCopyToClipboard() {
4732
- const [copied, setCopied] = React31.useState(false);
4733
- const timeoutRef = React31.useRef(void 0);
4734
- const copy = React31.useCallback((text) => {
4947
+ const [copied, setCopied] = React32.useState(false);
4948
+ const timeoutRef = React32.useRef(void 0);
4949
+ const copy = React32.useCallback((text) => {
4735
4950
  navigator.clipboard.writeText(text).then(() => {
4736
4951
  setCopied(true);
4737
4952
  clearTimeout(timeoutRef.current);
4738
4953
  timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
4739
4954
  });
4740
4955
  }, []);
4741
- React31.useEffect(() => () => clearTimeout(timeoutRef.current), []);
4956
+ React32.useEffect(() => () => clearTimeout(timeoutRef.current), []);
4742
4957
  return [copied, copy];
4743
4958
  }
4744
4959
  function useDebounce(value, delay) {
4745
- const [debounced, setDebounced] = React31.useState(value);
4746
- React31.useEffect(() => {
4960
+ const [debounced, setDebounced] = React32.useState(value);
4961
+ React32.useEffect(() => {
4747
4962
  const timer = setTimeout(() => setDebounced(value), delay);
4748
4963
  return () => clearTimeout(timer);
4749
4964
  }, [value, delay]);
4750
4965
  return debounced;
4751
4966
  }
4752
4967
  function useLocalStorage(key, initialValue) {
4753
- const [storedValue, setStoredValue] = React31.useState(() => {
4968
+ const [storedValue, setStoredValue] = React32.useState(() => {
4754
4969
  if (typeof window === "undefined") return initialValue;
4755
4970
  try {
4756
4971
  const item = window.localStorage.getItem(key);
@@ -4759,7 +4974,7 @@ function useLocalStorage(key, initialValue) {
4759
4974
  return initialValue;
4760
4975
  }
4761
4976
  });
4762
- const setValue = React31.useCallback(
4977
+ const setValue = React32.useCallback(
4763
4978
  (value) => {
4764
4979
  try {
4765
4980
  setStoredValue(value);
@@ -4774,11 +4989,11 @@ function useLocalStorage(key, initialValue) {
4774
4989
  return [storedValue, setValue];
4775
4990
  }
4776
4991
  function useMediaQuery(query) {
4777
- const [matches, setMatches] = React31.useState(() => {
4992
+ const [matches, setMatches] = React32.useState(() => {
4778
4993
  if (typeof window === "undefined") return false;
4779
4994
  return window.matchMedia(query).matches;
4780
4995
  });
4781
- React31.useEffect(() => {
4996
+ React32.useEffect(() => {
4782
4997
  if (typeof window === "undefined") return;
4783
4998
  const mql = window.matchMedia(query);
4784
4999
  setMatches(mql.matches);
@@ -4789,18 +5004,18 @@ function useMediaQuery(query) {
4789
5004
  return matches;
4790
5005
  }
4791
5006
  function usePagination(total, pageSize) {
4792
- const [page, setPage] = React31.useState(1);
5007
+ const [page, setPage] = React32.useState(1);
4793
5008
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
4794
5009
  const offset = (page - 1) * pageSize;
4795
- const goTo = React31.useCallback(
5010
+ const goTo = React32.useCallback(
4796
5011
  (p) => setPage(Math.min(Math.max(1, p), totalPages)),
4797
5012
  [totalPages]
4798
5013
  );
4799
- const next = React31.useCallback(() => goTo(page + 1), [page, goTo]);
4800
- const prev = React31.useCallback(() => goTo(page - 1), [page, goTo]);
5014
+ const next = React32.useCallback(() => goTo(page + 1), [page, goTo]);
5015
+ const prev = React32.useCallback(() => goTo(page - 1), [page, goTo]);
4801
5016
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
4802
5017
  }
4803
5018
 
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 };
5019
+ 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
5020
  //# sourceMappingURL=index.js.map
4806
5021
  //# sourceMappingURL=index.js.map