@olwiba/ui 0.2.3 → 0.2.4

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,6 +1,6 @@
1
1
  import { cn } from './chunk-AMWLSHD6.js';
2
2
  export { MdxContent, cn } from './chunk-AMWLSHD6.js';
3
- import * as React32 from 'react';
3
+ import * as React33 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';
@@ -13,7 +13,7 @@ import { CSS } from '@dnd-kit/utilities';
13
13
  import { PieChart, Pie, Cell, BarChart, XAxis, YAxis, Bar, AreaChart, Area, LineChart, Line, ResponsiveContainer, Tooltip as Tooltip$1, CartesianGrid } from 'recharts';
14
14
  import { toast } from 'sonner';
15
15
 
16
- var OlwibaUIContext = React32.createContext({
16
+ var OlwibaUIContext = React33.createContext({
17
17
  isMobile: false,
18
18
  mode: "default",
19
19
  setMode: () => {
@@ -22,17 +22,17 @@ var OlwibaUIContext = React32.createContext({
22
22
  function OlwibaUIProvider({ children, isMobile: isMobileProp, mode: initialMode = "default" }) {
23
23
  const detectedMobile = useIsMobile();
24
24
  const isMobile = isMobileProp ?? detectedMobile;
25
- const [mode, setMode] = React32.useState(initialMode);
25
+ const [mode, setMode] = React33.useState(initialMode);
26
26
  const variant = mode !== "default" ? mode : void 0;
27
27
  return /* @__PURE__ */ jsx(OlwibaUIContext.Provider, { value: { isMobile, mode, setMode }, children: /* @__PURE__ */ jsx(UIVariantProvider, { mode: variant, children }) });
28
28
  }
29
29
  function useOlwibaUI() {
30
- return React32.useContext(OlwibaUIContext);
30
+ return React33.useContext(OlwibaUIContext);
31
31
  }
32
32
  function useUIMode() {
33
- return React32.useContext(OlwibaUIContext).mode;
33
+ return React33.useContext(OlwibaUIContext).mode;
34
34
  }
35
- var Button = React32.forwardRef(
35
+ var Button = React33.forwardRef(
36
36
  ({ mode, ...props }, ref) => {
37
37
  const ctxMode = useUIMode();
38
38
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -40,7 +40,7 @@ var Button = React32.forwardRef(
40
40
  }
41
41
  );
42
42
  Button.displayName = "Button";
43
- var Card = React32.forwardRef(
43
+ var Card = React33.forwardRef(
44
44
  ({ mode, ...props }, ref) => {
45
45
  const ctxMode = useUIMode();
46
46
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -51,7 +51,7 @@ Card.displayName = "Card";
51
51
  function Badge(props) {
52
52
  return /* @__PURE__ */ jsx(Badge$1, { ...props });
53
53
  }
54
- var Input = React32.forwardRef(
54
+ var Input = React33.forwardRef(
55
55
  ({ mode, ...props }, ref) => {
56
56
  const ctxMode = useUIMode();
57
57
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -59,7 +59,7 @@ var Input = React32.forwardRef(
59
59
  }
60
60
  );
61
61
  Input.displayName = "Input";
62
- var Textarea = React32.forwardRef(
62
+ var Textarea = React33.forwardRef(
63
63
  ({ mode, ...props }, ref) => {
64
64
  const ctxMode = useUIMode();
65
65
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
@@ -67,13 +67,13 @@ var Textarea = React32.forwardRef(
67
67
  }
68
68
  );
69
69
  Textarea.displayName = "Textarea";
70
- var Checkbox = React32.forwardRef(({ mode, ...props }, ref) => {
70
+ var Checkbox = React33.forwardRef(({ mode, ...props }, ref) => {
71
71
  const ctxMode = useUIMode();
72
72
  const resolvedMode = mode ?? (ctxMode !== "default" ? ctxMode : void 0);
73
73
  return /* @__PURE__ */ jsx(Checkbox$1, { mode: resolvedMode, ...props, ref });
74
74
  });
75
75
  Checkbox.displayName = "Checkbox";
76
- var Switch = React32.forwardRef(({ mode: _mode, ...props }, ref) => {
76
+ var Switch = React33.forwardRef(({ mode: _mode, ...props }, ref) => {
77
77
  return /* @__PURE__ */ jsx(Switch$1, { ...props, ref });
78
78
  });
79
79
  Switch.displayName = "Switch";
@@ -530,7 +530,7 @@ function DefaultForm({
530
530
  const isForgotPassword = mode === "forgot-password";
531
531
  const isResetPassword = mode === "reset-password";
532
532
  const isVerify = mode === "verify";
533
- const [code, setCode] = React32.useState("");
533
+ const [code, setCode] = React33.useState("");
534
534
  const hasPrefill = !!(defaultEmail || defaultPassword);
535
535
  const prefillStyle = (active) => active ? { animation: "auth-prefill 1.6s ease-out 0.35s 1 both" } : void 0;
536
536
  const copy = authCopy[mode];
@@ -690,10 +690,10 @@ function DataTable({
690
690
  emptyMessage = "No results.",
691
691
  className
692
692
  }) {
693
- const [sorting, setSorting] = React32.useState([]);
694
- const [rowSelection, setRowSelection] = React32.useState({});
695
- const [globalFilter, setGlobalFilter] = React32.useState("");
696
- const allColumns = React32.useMemo(
693
+ const [sorting, setSorting] = React33.useState([]);
694
+ const [rowSelection, setRowSelection] = React33.useState({});
695
+ const [globalFilter, setGlobalFilter] = React33.useState("");
696
+ const allColumns = React33.useMemo(
697
697
  () => selectable ? [selectColumn, ...columns] : columns,
698
698
  [selectable, columns]
699
699
  );
@@ -715,7 +715,7 @@ function DataTable({
715
715
  initialState: pageSize > 0 ? { pagination: { pageSize } } : void 0,
716
716
  enableRowSelection: selectable
717
717
  });
718
- React32.useEffect(() => {
718
+ React33.useEffect(() => {
719
719
  if (!onSelectionChange) return;
720
720
  onSelectionChange(table.getSelectedRowModel().rows.map((r) => r.original));
721
721
  }, [rowSelection]);
@@ -795,8 +795,8 @@ function DataTable({
795
795
  ] });
796
796
  }
797
797
  function InviteDialog({ roles, onInvite, onClose }) {
798
- const [email, setEmail] = React32.useState("");
799
- const [role, setRole] = React32.useState(roles[roles.length - 1] ?? roles[0]);
798
+ const [email, setEmail] = React33.useState("");
799
+ const [role, setRole] = React33.useState(roles[roles.length - 1] ?? roles[0]);
800
800
  return /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(
801
801
  "form",
802
802
  {
@@ -840,8 +840,8 @@ function TeamMembersPanel({
840
840
  title = "Team members",
841
841
  description = "Manage who has access to this workspace."
842
842
  }) {
843
- const [inviteOpen, setInviteOpen] = React32.useState(false);
844
- const columns = React32.useMemo(() => [
843
+ const [inviteOpen, setInviteOpen] = React33.useState(false);
844
+ const columns = React33.useMemo(() => [
845
845
  {
846
846
  accessorKey: "name",
847
847
  header: "Name",
@@ -910,7 +910,7 @@ function BillingPanel({
910
910
  onUpdatePaymentMethod,
911
911
  className
912
912
  }) {
913
- const invoiceColumns = React32.useMemo(() => [
913
+ const invoiceColumns = React33.useMemo(() => [
914
914
  { accessorKey: "date", header: "Date", enableSorting: false },
915
915
  { accessorKey: "amount", header: "Amount", enableSorting: false },
916
916
  {
@@ -989,9 +989,9 @@ function OnboardingWizard({
989
989
  completeLabel = "Finish",
990
990
  className
991
991
  }) {
992
- const [internalStep, setInternalStep] = React32.useState(0);
993
- const [error, setError] = React32.useState(null);
994
- const [pending, setPending] = React32.useState(false);
992
+ const [internalStep, setInternalStep] = React33.useState(0);
993
+ const [error, setError] = React33.useState(null);
994
+ const [pending, setPending] = React33.useState(false);
995
995
  const index = stepProp ?? internalStep;
996
996
  const current = steps[index];
997
997
  const isLast = index === steps.length - 1;
@@ -1325,9 +1325,9 @@ function FadeIn({
1325
1325
  style,
1326
1326
  ...props
1327
1327
  }) {
1328
- const ref = React32.useRef(null);
1329
- const [visible, setVisible] = React32.useState(false);
1330
- React32.useEffect(() => {
1328
+ const ref = React33.useRef(null);
1329
+ const [visible, setVisible] = React33.useState(false);
1330
+ React33.useEffect(() => {
1331
1331
  const el = ref.current;
1332
1332
  if (!el) return;
1333
1333
  const observer = new IntersectionObserver(
@@ -1522,16 +1522,16 @@ function Carousel({
1522
1522
  className
1523
1523
  }) {
1524
1524
  const mode = useUIVariant();
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(() => {
1525
+ const trackRef = React33.useRef(null);
1526
+ const [canPrev, setCanPrev] = React33.useState(false);
1527
+ const [canNext, setCanNext] = React33.useState(true);
1528
+ const updateScrollState = React33.useCallback(() => {
1529
1529
  const track = trackRef.current;
1530
1530
  if (!track) return;
1531
1531
  setCanPrev(track.scrollLeft > 8);
1532
1532
  setCanNext(track.scrollLeft < track.scrollWidth - track.clientWidth - 8);
1533
1533
  }, []);
1534
- React32.useEffect(() => {
1534
+ React33.useEffect(() => {
1535
1535
  const track = trackRef.current;
1536
1536
  if (!track) return;
1537
1537
  updateScrollState();
@@ -1588,7 +1588,7 @@ function Carousel({
1588
1588
  role: "region",
1589
1589
  "aria-label": ariaLabel,
1590
1590
  className: "flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1591
- children: React32.Children.map(
1591
+ children: React33.Children.map(
1592
1592
  children,
1593
1593
  (child) => child == null ? null : /* @__PURE__ */ jsx("div", { "data-carousel-item": true, className: cn$1("shrink-0 snap-start", itemClassName), children: child })
1594
1594
  )
@@ -1613,9 +1613,9 @@ function StaggerChildren({
1613
1613
  className,
1614
1614
  ...props
1615
1615
  }) {
1616
- const ref = React32.useRef(null);
1617
- const [visible, setVisible] = React32.useState(false);
1618
- React32.useEffect(() => {
1616
+ const ref = React33.useRef(null);
1617
+ const [visible, setVisible] = React33.useState(false);
1618
+ React33.useEffect(() => {
1619
1619
  const el = ref.current;
1620
1620
  if (!el) return;
1621
1621
  const observer = new IntersectionObserver(
@@ -1633,7 +1633,7 @@ function StaggerChildren({
1633
1633
  return () => observer.disconnect();
1634
1634
  }, [once]);
1635
1635
  const [tx, ty] = translateMap2[direction];
1636
- return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React32.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1636
+ return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React33.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
1637
1637
  "div",
1638
1638
  {
1639
1639
  className: "h-full",
@@ -1709,11 +1709,56 @@ function GroupedFeaturesSection({
1709
1709
  ] }, group.label)) })
1710
1710
  ] }) }) });
1711
1711
  }
1712
+ function TimelineGroup({
1713
+ steps,
1714
+ startNumber,
1715
+ fadeIn
1716
+ }) {
1717
+ const fadePx = 48;
1718
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1719
+ fadeIn && /* @__PURE__ */ jsx(
1720
+ "div",
1721
+ {
1722
+ "aria-hidden": "true",
1723
+ className: "absolute left-[19px] w-1 bg-gradient-to-b from-transparent to-primary",
1724
+ style: { top: 0, height: fadePx }
1725
+ }
1726
+ ),
1727
+ /* @__PURE__ */ jsx(
1728
+ "div",
1729
+ {
1730
+ "aria-hidden": "true",
1731
+ className: "absolute left-[19px] w-1 bg-primary",
1732
+ style: {
1733
+ top: fadeIn ? fadePx : 20,
1734
+ height: fadeIn ? `calc(100% - ${fadePx}px)` : "calc(100% - 20px)"
1735
+ }
1736
+ }
1737
+ ),
1738
+ /* @__PURE__ */ jsx(
1739
+ "div",
1740
+ {
1741
+ "aria-hidden": "true",
1742
+ className: "absolute left-[19px] w-1 bg-gradient-to-b from-primary to-transparent",
1743
+ style: { top: "100%", height: fadePx }
1744
+ }
1745
+ ),
1746
+ /* @__PURE__ */ jsx("div", { className: "space-y-10", style: fadeIn ? { paddingTop: fadePx } : void 0, children: steps.map((step, i) => /* @__PURE__ */ jsx(FadeIn, { direction: "up", delay: i * 80, children: /* @__PURE__ */ jsxs("div", { className: "relative flex gap-5", children: [
1747
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full border-2 border-primary bg-primary text-lg font-bold text-primary-foreground", children: step.emoji ?? startNumber + i }),
1748
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 pt-1 pb-2", children: [
1749
+ /* @__PURE__ */ jsx("h3", { className: "mb-2 text-xl font-semibold text-foreground", children: step.title }),
1750
+ /* @__PURE__ */ jsx("div", { className: "text-sm leading-relaxed text-muted-foreground", children: step.description })
1751
+ ] })
1752
+ ] }) }, step.title)) })
1753
+ ] });
1754
+ }
1712
1755
  function StepsSection({
1713
1756
  badge = "How it works",
1714
1757
  title = "From zero to shipped",
1715
1758
  description,
1716
- steps
1759
+ steps,
1760
+ variant = "default",
1761
+ groups
1717
1762
  }) {
1718
1763
  const mode = useUIVariant();
1719
1764
  const sectionClasses = cn$1(
@@ -1722,11 +1767,27 @@ function StepsSection({
1722
1767
  mode === "playful" && "rounded-2xl border-primary/25 border",
1723
1768
  !mode && "rounded-2xl border"
1724
1769
  );
1770
+ if (variant === "timeline") {
1771
+ const resolvedGroups = groups ?? (steps ? [{ steps }] : []);
1772
+ let nextNumber = 1;
1773
+ return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-3xl", children: [
1774
+ /* @__PURE__ */ jsx(SectionTitle, { badge, title, description, className: "text-left [&>p]:mx-0" }),
1775
+ /* @__PURE__ */ jsx("div", { className: "mt-12", children: resolvedGroups.map((group, groupIndex) => {
1776
+ const startNumber = nextNumber;
1777
+ nextNumber += group.steps.length;
1778
+ return /* @__PURE__ */ jsxs(React33.Fragment, { children: [
1779
+ /* @__PURE__ */ jsx("div", { className: cn$1(groupIndex > 0 && "mt-10"), children: /* @__PURE__ */ jsx(TimelineGroup, { steps: group.steps, startNumber, fadeIn: groupIndex > 0 }) }),
1780
+ group.after && /* @__PURE__ */ jsx("div", { className: "mt-16", children: group.after })
1781
+ ] }, groupIndex);
1782
+ }) })
1783
+ ] }) }) });
1784
+ }
1785
+ const resolvedSteps = steps ?? [];
1725
1786
  return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsx("div", { className: "px-6 py-14 sm:px-10 sm:py-20", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl", children: [
1726
1787
  /* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
1727
1788
  /* @__PURE__ */ jsxs("div", { className: "mt-12", children: [
1728
- /* @__PURE__ */ jsx("div", { className: "hidden sm:grid", style: { gridTemplateColumns: `repeat(${steps.length}, 1fr)` }, children: steps.map((step, i) => /* @__PURE__ */ jsx(FadeIn, { direction: "up", delay: i * 80, children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col items-center text-center px-4", children: [
1729
- i < steps.length - 1 && /* @__PURE__ */ jsx(
1789
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:grid", style: { gridTemplateColumns: `repeat(${resolvedSteps.length}, 1fr)` }, children: resolvedSteps.map((step, i) => /* @__PURE__ */ jsx(FadeIn, { direction: "up", delay: i * 80, children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col items-center text-center px-4", children: [
1790
+ i < resolvedSteps.length - 1 && /* @__PURE__ */ jsx(
1730
1791
  "div",
1731
1792
  {
1732
1793
  "aria-hidden": "true",
@@ -1735,10 +1796,10 @@ function StepsSection({
1735
1796
  ),
1736
1797
  /* @__PURE__ */ jsx("div", { className: "relative z-10 mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-muted text-2xl", children: step.emoji ?? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-primary", children: i + 1 }) }),
1737
1798
  /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: step.title }),
1738
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: step.description })
1799
+ /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm leading-relaxed text-muted-foreground", children: step.description })
1739
1800
  ] }) }, step.title)) }),
1740
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0 sm:hidden", children: steps.map((step, i) => /* @__PURE__ */ jsx(FadeIn, { direction: "up", delay: i * 80, children: /* @__PURE__ */ jsxs("div", { className: "relative flex gap-4 pb-8 last:pb-0", children: [
1741
- i < steps.length - 1 && /* @__PURE__ */ jsx(
1801
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0 sm:hidden", children: resolvedSteps.map((step, i) => /* @__PURE__ */ jsx(FadeIn, { direction: "up", delay: i * 80, children: /* @__PURE__ */ jsxs("div", { className: "relative flex gap-4 pb-8 last:pb-0", children: [
1802
+ i < resolvedSteps.length - 1 && /* @__PURE__ */ jsx(
1742
1803
  "div",
1743
1804
  {
1744
1805
  "aria-hidden": "true",
@@ -1748,7 +1809,7 @@ function StepsSection({
1748
1809
  /* @__PURE__ */ jsx("div", { className: "relative z-10 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-muted text-2xl", children: step.emoji ?? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-primary", children: i + 1 }) }),
1749
1810
  /* @__PURE__ */ jsxs("div", { className: "pt-3", children: [
1750
1811
  /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: step.title }),
1751
- /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm leading-relaxed text-muted-foreground", children: step.description })
1812
+ /* @__PURE__ */ jsx("div", { className: "mt-1.5 text-sm leading-relaxed text-muted-foreground", children: step.description })
1752
1813
  ] })
1753
1814
  ] }) }, step.title)) })
1754
1815
  ] })
@@ -1884,9 +1945,9 @@ function FeatureMarqueeSection({
1884
1945
  ] });
1885
1946
  }
1886
1947
  function useIntersectionObserver(options) {
1887
- const ref = React32.useRef(null);
1888
- const [isIntersecting, setIsIntersecting] = React32.useState(false);
1889
- React32.useEffect(() => {
1948
+ const ref = React33.useRef(null);
1949
+ const [isIntersecting, setIsIntersecting] = React33.useState(false);
1950
+ React33.useEffect(() => {
1890
1951
  const el = ref.current;
1891
1952
  if (!el) return;
1892
1953
  const observer = new IntersectionObserver(([entry]) => {
@@ -1908,8 +1969,8 @@ function ShowcaseCta({
1908
1969
  sectionClasses
1909
1970
  }) {
1910
1971
  const [ref, intersecting] = useIntersectionObserver({ threshold: 0.15 });
1911
- const [visible, setVisible] = React32.useState(false);
1912
- React32.useEffect(() => {
1972
+ const [visible, setVisible] = React33.useState(false);
1973
+ React33.useEffect(() => {
1913
1974
  if (intersecting) setVisible(true);
1914
1975
  }, [intersecting]);
1915
1976
  return /* @__PURE__ */ jsxs(
@@ -2086,8 +2147,8 @@ function CountdownTimer({
2086
2147
  className,
2087
2148
  compact = false
2088
2149
  }) {
2089
- const [timeLeft, setTimeLeft] = React32.useState(() => getTimeLeft(deadline));
2090
- React32.useEffect(() => {
2150
+ const [timeLeft, setTimeLeft] = React33.useState(() => getTimeLeft(deadline));
2151
+ React33.useEffect(() => {
2091
2152
  setTimeLeft(getTimeLeft(deadline));
2092
2153
  const id = setInterval(() => setTimeLeft(getTimeLeft(deadline)), 1e3);
2093
2154
  return () => clearInterval(id);
@@ -2113,7 +2174,7 @@ function CountdownTimer({
2113
2174
  ];
2114
2175
  return /* @__PURE__ */ jsxs("div", { className: cn$1("flex items-center justify-center gap-2 text-sm", className), children: [
2115
2176
  /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
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: [
2177
+ /* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(React33.Fragment, { children: [
2117
2178
  /* @__PURE__ */ jsxs("span", { children: [
2118
2179
  String(value).padStart(2, "0"),
2119
2180
  /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: unit })
@@ -2138,7 +2199,7 @@ function PricingSection({
2138
2199
  highlightedBadgeLabel = "Founding member",
2139
2200
  renderPlanFooter
2140
2201
  }) {
2141
- const [annual, setAnnual] = React32.useState(false);
2202
+ const [annual, setAnnual] = React33.useState(false);
2142
2203
  const isOneTime = mode === "one-time";
2143
2204
  const uiMode = useUIVariant();
2144
2205
  const sectionClasses = cn$1(
@@ -2407,10 +2468,10 @@ function CountUp({
2407
2468
  className,
2408
2469
  ...props
2409
2470
  }) {
2410
- const ref = React32.useRef(null);
2411
- const [value, setValue] = React32.useState(from);
2412
- const hasStarted = React32.useRef(false);
2413
- React32.useEffect(() => {
2471
+ const ref = React33.useRef(null);
2472
+ const [value, setValue] = React33.useState(from);
2473
+ const hasStarted = React33.useRef(false);
2474
+ React33.useEffect(() => {
2414
2475
  const el = ref.current;
2415
2476
  if (!el) return;
2416
2477
  const observer = new IntersectionObserver(
@@ -2503,8 +2564,8 @@ function NewsletterSection({
2503
2564
  successDescription = defaults.successDescription,
2504
2565
  onSubscribe
2505
2566
  } = {}) {
2506
- const [email, setEmail] = React32.useState("");
2507
- const [submitted, setSubmitted] = React32.useState(false);
2567
+ const [email, setEmail] = React33.useState("");
2568
+ const [submitted, setSubmitted] = React33.useState(false);
2508
2569
  const mode = useUIVariant();
2509
2570
  const sectionClasses = cn$1(
2510
2571
  "overflow-hidden bg-card",
@@ -2595,7 +2656,7 @@ function ContactSection({
2595
2656
  sendAnotherLabel = defaults2.sendAnotherLabel,
2596
2657
  onSubmit
2597
2658
  } = {}) {
2598
- const [submitted, setSubmitted] = React32.useState(false);
2659
+ const [submitted, setSubmitted] = React33.useState(false);
2599
2660
  const mode = useUIVariant();
2600
2661
  const sectionClasses = cn$1(
2601
2662
  "overflow-hidden bg-card",
@@ -2893,7 +2954,7 @@ function Navbar({
2893
2954
  controls,
2894
2955
  renderLink = defaultRenderLink7
2895
2956
  }) {
2896
- const [open, setOpen] = React32.useState(false);
2957
+ const [open, setOpen] = React33.useState(false);
2897
2958
  const brandHref = brand.href ?? "/";
2898
2959
  const hasRightContent = controls?.length || cta?.primary || cta?.secondary;
2899
2960
  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: [
@@ -2910,7 +2971,7 @@ function Navbar({
2910
2971
  children: link.label
2911
2972
  }) }, link.label)) }),
2912
2973
  hasRightContent && /* @__PURE__ */ jsxs("div", { className: "hidden items-center justify-end gap-2 md:flex", children: [
2913
- controls?.map((control, i) => /* @__PURE__ */ jsx(React32.Fragment, { children: control }, i)),
2974
+ controls?.map((control, i) => /* @__PURE__ */ jsx(React33.Fragment, { children: control }, i)),
2914
2975
  (cta?.secondary || cta?.primary) && controls?.length ? /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-border" }) : null,
2915
2976
  cta?.secondary && renderLink({
2916
2977
  href: cta.secondary.href,
@@ -2934,7 +2995,7 @@ function Navbar({
2934
2995
  /* @__PURE__ */ jsx("span", { children: brand.name })
2935
2996
  ] })
2936
2997
  }) }) }),
2937
- 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,
2998
+ controls?.length ? /* @__PURE__ */ jsx("div", { className: "mb-4 flex w-full items-center justify-between gap-1", children: controls.map((control, i) => /* @__PURE__ */ jsx(React33.Fragment, { children: control }, i)) }) : null,
2938
2999
  /* @__PURE__ */ jsx(Separator, {}),
2939
3000
  /* @__PURE__ */ jsx("nav", { className: "mt-4 flex flex-col gap-1", children: navLinks.map((link) => /* @__PURE__ */ jsx("span", { onClick: () => setOpen(false), children: renderLink({
2940
3001
  href: link.href,
@@ -3083,7 +3144,7 @@ function LogoStrip({
3083
3144
  ] });
3084
3145
  }
3085
3146
  function GridUnderlay({ variant, size = 24, className, ...props }) {
3086
- const id = React32.useId();
3147
+ const id = React33.useId();
3087
3148
  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: [
3088
3149
  /* @__PURE__ */ jsx("line", { x1: size / 2, y1: 0, x2: size / 2, y2: size, stroke: "currentColor", strokeWidth: 0.5 }),
3089
3150
  /* @__PURE__ */ jsx("line", { x1: 0, y1: size / 2, x2: size, y2: size / 2, stroke: "currentColor", strokeWidth: 0.5 })
@@ -3111,9 +3172,9 @@ function GlowUnderlay({
3111
3172
  style,
3112
3173
  ...props
3113
3174
  }) {
3114
- const [pos, setPos] = React32.useState({ x: "50%", y: "50%" });
3115
- const containerRef = React32.useRef(null);
3116
- React32.useEffect(() => {
3175
+ const [pos, setPos] = React33.useState({ x: "50%", y: "50%" });
3176
+ const containerRef = React33.useRef(null);
3177
+ React33.useEffect(() => {
3117
3178
  if (!followCursor) return;
3118
3179
  const handleMouseMove = (e) => {
3119
3180
  const el = containerRef.current;
@@ -3252,8 +3313,8 @@ function PageTransition({
3252
3313
  style,
3253
3314
  ...props
3254
3315
  }) {
3255
- const [mounted, setMounted] = React32.useState(false);
3256
- React32.useEffect(() => {
3316
+ const [mounted, setMounted] = React33.useState(false);
3317
+ React33.useEffect(() => {
3257
3318
  const id = requestAnimationFrame(() => setMounted(true));
3258
3319
  return () => cancelAnimationFrame(id);
3259
3320
  }, []);
@@ -3328,7 +3389,7 @@ function Sortable({
3328
3389
  if (oldIndex === -1 || newIndex === -1) return;
3329
3390
  onReorder(arrayMove(items, oldIndex, newIndex));
3330
3391
  };
3331
- const childArray = React32.Children.toArray(children);
3392
+ const childArray = React33.Children.toArray(children);
3332
3393
  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(
3333
3394
  (child, i) => items[i] === void 0 ? null : /* @__PURE__ */ jsx(SortableItem, { id: items[i], disabled, className: itemClassName, children: child }, items[i])
3334
3395
  ) }) }) });
@@ -3340,8 +3401,8 @@ function Spotlight({
3340
3401
  triggerClassName,
3341
3402
  shortcut = "\u2318K"
3342
3403
  }) {
3343
- const [open, setOpen] = React32.useState(false);
3344
- React32.useEffect(() => {
3404
+ const [open, setOpen] = React33.useState(false);
3405
+ React33.useEffect(() => {
3345
3406
  const down = (e) => {
3346
3407
  if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
3347
3408
  e.preventDefault();
@@ -3371,7 +3432,7 @@ function Spotlight({
3371
3432
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3372
3433
  /* @__PURE__ */ jsxs(CommandList, { children: [
3373
3434
  /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
3374
- groups.map((group, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
3435
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React33.Fragment, { children: [
3375
3436
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3376
3437
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3377
3438
  CommandItem,
@@ -3396,8 +3457,8 @@ function Spotlight({
3396
3457
  var BASE = 40;
3397
3458
  var MAGNIFY_RADIUS = 80;
3398
3459
  function Dock({ items, iconSize = BASE, magnification = 1.7, className, ...props }) {
3399
- const [mouseX, setMouseX] = React32.useState(null);
3400
- const containerRef = React32.useRef(null);
3460
+ const [mouseX, setMouseX] = React33.useState(null);
3461
+ const containerRef = React33.useRef(null);
3401
3462
  function getScale(index) {
3402
3463
  if (mouseX === null || !containerRef.current) return 1;
3403
3464
  const container = containerRef.current;
@@ -3496,7 +3557,7 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
3496
3557
  ] }) });
3497
3558
  }
3498
3559
  function RegisterHotkeys({ hotkeys }) {
3499
- React32.useEffect(() => {
3560
+ React33.useEffect(() => {
3500
3561
  const handleKeyDown = (event) => {
3501
3562
  for (const hotkey of hotkeys) {
3502
3563
  const matches = event.key.toLowerCase() === hotkey.key.toLowerCase() && !!event.ctrlKey === !!hotkey.ctrl && !!event.metaKey === !!hotkey.meta && !!event.shiftKey === !!hotkey.shift && !!event.altKey === !!hotkey.alt;
@@ -3513,10 +3574,10 @@ function RegisterHotkeys({ hotkeys }) {
3513
3574
  return null;
3514
3575
  }
3515
3576
  function useControlledOpen(defaultOpen = false) {
3516
- const [isOpen, setIsOpen] = React32.useState(defaultOpen);
3517
- const open = React32.useCallback(() => setIsOpen(true), []);
3518
- const close = React32.useCallback(() => setIsOpen(false), []);
3519
- const toggle = React32.useCallback(() => setIsOpen((prev) => !prev), []);
3577
+ const [isOpen, setIsOpen] = React33.useState(defaultOpen);
3578
+ const open = React33.useCallback(() => setIsOpen(true), []);
3579
+ const close = React33.useCallback(() => setIsOpen(false), []);
3580
+ const toggle = React33.useCallback(() => setIsOpen((prev) => !prev), []);
3520
3581
  return { isOpen, open, close, toggle, setIsOpen };
3521
3582
  }
3522
3583
  function CommandMenu({
@@ -3529,7 +3590,7 @@ function CommandMenu({
3529
3590
  }) {
3530
3591
  const internal = useControlledOpen(false);
3531
3592
  const isOpen = openProp ?? internal.isOpen;
3532
- const setOpen = React32.useCallback(
3593
+ const setOpen = React33.useCallback(
3533
3594
  (next) => {
3534
3595
  if (openProp === void 0) internal.setIsOpen(next);
3535
3596
  onOpenChange?.(next);
@@ -3554,7 +3615,7 @@ function CommandMenu({
3554
3615
  /* @__PURE__ */ jsx(CommandInput, { placeholder }),
3555
3616
  /* @__PURE__ */ jsxs(CommandList, { children: [
3556
3617
  /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
3557
- groups.map((group, i) => /* @__PURE__ */ jsxs(React32.Fragment, { children: [
3618
+ groups.map((group, i) => /* @__PURE__ */ jsxs(React33.Fragment, { children: [
3558
3619
  i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
3559
3620
  /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
3560
3621
  CommandItem,
@@ -3746,20 +3807,20 @@ function FileUpload({
3746
3807
  hint,
3747
3808
  className
3748
3809
  }) {
3749
- const [internalFiles, setInternalFiles] = React32.useState(defaultFiles ?? []);
3750
- const [isDragging, setIsDragging] = React32.useState(false);
3751
- const [validationError, setValidationError] = React32.useState(null);
3752
- const inputRef = React32.useRef(null);
3753
- const dragDepth = React32.useRef(0);
3810
+ const [internalFiles, setInternalFiles] = React33.useState(defaultFiles ?? []);
3811
+ const [isDragging, setIsDragging] = React33.useState(false);
3812
+ const [validationError, setValidationError] = React33.useState(null);
3813
+ const inputRef = React33.useRef(null);
3814
+ const dragDepth = React33.useRef(0);
3754
3815
  const files = filesProp ?? internalFiles;
3755
- const setFiles = React32.useCallback(
3816
+ const setFiles = React33.useCallback(
3756
3817
  (next) => {
3757
3818
  if (!filesProp) setInternalFiles(next);
3758
3819
  onFilesChange?.(next);
3759
3820
  },
3760
3821
  [filesProp, onFilesChange]
3761
3822
  );
3762
- const acceptList = React32.useMemo(
3823
+ const acceptList = React33.useMemo(
3763
3824
  () => accept?.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean) ?? [],
3764
3825
  [accept]
3765
3826
  );
@@ -4426,7 +4487,7 @@ function PageHeader({
4426
4487
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 pb-6", className), children: [
4427
4488
  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) => {
4428
4489
  const isLast = i === breadcrumbs.length - 1;
4429
- return /* @__PURE__ */ jsxs(React32.Fragment, { children: [
4490
+ return /* @__PURE__ */ jsxs(React33.Fragment, { children: [
4430
4491
  i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0" }),
4431
4492
  isLast || !crumb.href ? /* @__PURE__ */ jsx("span", { className: cn(isLast && "text-foreground font-medium"), children: crumb.label }) : renderLink({
4432
4493
  href: crumb.href,
@@ -4462,7 +4523,7 @@ function PageHeader({
4462
4523
  ] });
4463
4524
  }
4464
4525
  function Suspensed({ children, fallback }) {
4465
- return /* @__PURE__ */ jsx(React32.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4526
+ return /* @__PURE__ */ jsx(React33.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
4466
4527
  }
4467
4528
  function getInitialTheme() {
4468
4529
  if (typeof document === "undefined") return "dark";
@@ -4470,7 +4531,7 @@ function getInitialTheme() {
4470
4531
  return stored ?? (document.documentElement.classList.contains("dark") ? "dark" : "light");
4471
4532
  }
4472
4533
  function ThemeSwitchMinimal() {
4473
- const [theme, setThemeState] = React32.useState(getInitialTheme);
4534
+ const [theme, setThemeState] = React33.useState(getInitialTheme);
4474
4535
  const toggle = () => {
4475
4536
  const next = theme === "dark" ? "light" : "dark";
4476
4537
  setThemeState(next);
@@ -4596,9 +4657,9 @@ function getInitialColorName() {
4596
4657
  return localStorage.getItem(STORAGE_KEY) ?? "emerald";
4597
4658
  }
4598
4659
  function BrandColorSwitchMinimal() {
4599
- const [active, setActive] = React32.useState(getInitialColorName);
4600
- const [open, setOpen] = React32.useState(false);
4601
- React32.useEffect(() => {
4660
+ const [active, setActive] = React33.useState(getInitialColorName);
4661
+ const [open, setOpen] = React33.useState(false);
4662
+ React33.useEffect(() => {
4602
4663
  const saved = localStorage.getItem(STORAGE_KEY) ?? "emerald";
4603
4664
  const color = BRAND_COLORS.find((c) => c.name === saved);
4604
4665
  if (color) applyColor(color);
@@ -4659,7 +4720,7 @@ function BrandColorSwitchMinimal() {
4659
4720
  ] });
4660
4721
  }
4661
4722
  function ThemeColorUpdater({ colorTheme }) {
4662
- React32.useEffect(() => {
4723
+ React33.useEffect(() => {
4663
4724
  if (colorTheme) {
4664
4725
  document.documentElement.setAttribute("data-theme", colorTheme);
4665
4726
  } else {
@@ -4669,7 +4730,7 @@ function ThemeColorUpdater({ colorTheme }) {
4669
4730
  return null;
4670
4731
  }
4671
4732
  function VersionBanner({ version, message, className, onDismiss }) {
4672
- const [dismissed, setDismissed] = React32.useState(false);
4733
+ const [dismissed, setDismissed] = React33.useState(false);
4673
4734
  if (dismissed) return null;
4674
4735
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-4 bg-primary/10 px-4 py-2 text-sm", className), children: [
4675
4736
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
@@ -4926,29 +4987,29 @@ function useMounted() {
4926
4987
  return mounted;
4927
4988
  }
4928
4989
  function useConfirm() {
4929
- const [isOpen, setIsOpen] = React32.useState(false);
4930
- const [options, setOptions] = React32.useState({});
4931
- const resolveRef = React32.useRef(null);
4932
- const confirm = React32.useCallback((opts = {}) => {
4990
+ const [isOpen, setIsOpen] = React33.useState(false);
4991
+ const [options, setOptions] = React33.useState({});
4992
+ const resolveRef = React33.useRef(null);
4993
+ const confirm = React33.useCallback((opts = {}) => {
4933
4994
  setOptions(opts);
4934
4995
  setIsOpen(true);
4935
4996
  return new Promise((resolve) => {
4936
4997
  resolveRef.current = resolve;
4937
4998
  });
4938
4999
  }, []);
4939
- const handleConfirm = React32.useCallback(() => {
5000
+ const handleConfirm = React33.useCallback(() => {
4940
5001
  resolveRef.current?.(true);
4941
5002
  setIsOpen(false);
4942
5003
  }, []);
4943
- const handleCancel = React32.useCallback(() => {
5004
+ const handleCancel = React33.useCallback(() => {
4944
5005
  resolveRef.current?.(false);
4945
5006
  setIsOpen(false);
4946
5007
  }, []);
4947
5008
  return { confirm, isOpen, options, handleConfirm, handleCancel };
4948
5009
  }
4949
5010
  function useScrolledPast(threshold) {
4950
- const [scrolledPast, setScrolledPast] = React32.useState(false);
4951
- React32.useEffect(() => {
5011
+ const [scrolledPast, setScrolledPast] = React33.useState(false);
5012
+ React33.useEffect(() => {
4952
5013
  const handleScroll = () => {
4953
5014
  setScrolledPast(window.scrollY > threshold);
4954
5015
  };
@@ -4959,28 +5020,28 @@ function useScrolledPast(threshold) {
4959
5020
  return scrolledPast;
4960
5021
  }
4961
5022
  function useCopyToClipboard() {
4962
- const [copied, setCopied] = React32.useState(false);
4963
- const timeoutRef = React32.useRef(void 0);
4964
- const copy = React32.useCallback((text) => {
5023
+ const [copied, setCopied] = React33.useState(false);
5024
+ const timeoutRef = React33.useRef(void 0);
5025
+ const copy = React33.useCallback((text) => {
4965
5026
  navigator.clipboard.writeText(text).then(() => {
4966
5027
  setCopied(true);
4967
5028
  clearTimeout(timeoutRef.current);
4968
5029
  timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
4969
5030
  });
4970
5031
  }, []);
4971
- React32.useEffect(() => () => clearTimeout(timeoutRef.current), []);
5032
+ React33.useEffect(() => () => clearTimeout(timeoutRef.current), []);
4972
5033
  return [copied, copy];
4973
5034
  }
4974
5035
  function useDebounce(value, delay) {
4975
- const [debounced, setDebounced] = React32.useState(value);
4976
- React32.useEffect(() => {
5036
+ const [debounced, setDebounced] = React33.useState(value);
5037
+ React33.useEffect(() => {
4977
5038
  const timer = setTimeout(() => setDebounced(value), delay);
4978
5039
  return () => clearTimeout(timer);
4979
5040
  }, [value, delay]);
4980
5041
  return debounced;
4981
5042
  }
4982
5043
  function useLocalStorage(key, initialValue) {
4983
- const [storedValue, setStoredValue] = React32.useState(() => {
5044
+ const [storedValue, setStoredValue] = React33.useState(() => {
4984
5045
  if (typeof window === "undefined") return initialValue;
4985
5046
  try {
4986
5047
  const item = window.localStorage.getItem(key);
@@ -4989,7 +5050,7 @@ function useLocalStorage(key, initialValue) {
4989
5050
  return initialValue;
4990
5051
  }
4991
5052
  });
4992
- const setValue = React32.useCallback(
5053
+ const setValue = React33.useCallback(
4993
5054
  (value) => {
4994
5055
  try {
4995
5056
  setStoredValue(value);
@@ -5004,11 +5065,11 @@ function useLocalStorage(key, initialValue) {
5004
5065
  return [storedValue, setValue];
5005
5066
  }
5006
5067
  function useMediaQuery(query) {
5007
- const [matches, setMatches] = React32.useState(() => {
5068
+ const [matches, setMatches] = React33.useState(() => {
5008
5069
  if (typeof window === "undefined") return false;
5009
5070
  return window.matchMedia(query).matches;
5010
5071
  });
5011
- React32.useEffect(() => {
5072
+ React33.useEffect(() => {
5012
5073
  if (typeof window === "undefined") return;
5013
5074
  const mql = window.matchMedia(query);
5014
5075
  setMatches(mql.matches);
@@ -5019,15 +5080,15 @@ function useMediaQuery(query) {
5019
5080
  return matches;
5020
5081
  }
5021
5082
  function usePagination(total, pageSize) {
5022
- const [page, setPage] = React32.useState(1);
5083
+ const [page, setPage] = React33.useState(1);
5023
5084
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
5024
5085
  const offset = (page - 1) * pageSize;
5025
- const goTo = React32.useCallback(
5086
+ const goTo = React33.useCallback(
5026
5087
  (p) => setPage(Math.min(Math.max(1, p), totalPages)),
5027
5088
  [totalPages]
5028
5089
  );
5029
- const next = React32.useCallback(() => goTo(page + 1), [page, goTo]);
5030
- const prev = React32.useCallback(() => goTo(page - 1), [page, goTo]);
5090
+ const next = React33.useCallback(() => goTo(page + 1), [page, goTo]);
5091
+ const prev = React33.useCallback(() => goTo(page - 1), [page, goTo]);
5031
5092
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
5032
5093
  }
5033
5094