@olwiba/ui 0.2.18 → 0.2.20
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.d.ts +114 -17
- package/dist/index.js +230 -263
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +6 -0
- package/src/marketing/ComparisonSection.tsx +6 -8
- package/src/marketing/ContactSection.tsx +6 -8
- package/src/marketing/CtaSection.tsx +7 -7
- package/src/marketing/FaqSection.tsx +6 -8
- package/src/marketing/FeatureMarqueeSection.tsx +6 -9
- package/src/marketing/FeaturesSection.tsx +6 -8
- package/src/marketing/GroupedFeaturesSection.tsx +5 -8
- package/src/marketing/HeroSection.tsx +35 -11
- package/src/marketing/NewsletterSection.tsx +6 -8
- package/src/marketing/PricingSection.tsx +12 -8
- package/src/marketing/QualificationSection.tsx +6 -8
- package/src/marketing/StatsSection.tsx +6 -8
- package/src/marketing/StepsSection.tsx +6 -8
- package/src/marketing/TeamSection.tsx +6 -8
- package/src/marketing/TechStackSection.tsx +6 -6
- package/src/marketing/TestimonialsSection.tsx +5 -8
- package/src/marketing/section-surface.tsx +88 -0
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
|
|
3
|
+
import * as React21 from 'react';
|
|
4
4
|
import { useRef, useEffect, useState, useCallback } 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, useSidebar, Sidebar, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarMenuButton, SidebarFooter, SidebarTrigger, 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 =
|
|
16
|
+
var OlwibaUIContext = React21.createContext({
|
|
17
17
|
isMobile: false,
|
|
18
18
|
mode: "default",
|
|
19
19
|
setMode: () => {
|
|
@@ -22,17 +22,17 @@ var OlwibaUIContext = React20.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] =
|
|
25
|
+
const [mode, setMode] = React21.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
|
|
30
|
+
return React21.useContext(OlwibaUIContext);
|
|
31
31
|
}
|
|
32
32
|
function useUIMode() {
|
|
33
|
-
return
|
|
33
|
+
return React21.useContext(OlwibaUIContext).mode;
|
|
34
34
|
}
|
|
35
|
-
var Button =
|
|
35
|
+
var Button = React21.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 = React20.forwardRef(
|
|
|
40
40
|
}
|
|
41
41
|
);
|
|
42
42
|
Button.displayName = "Button";
|
|
43
|
-
var Card =
|
|
43
|
+
var Card = React21.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 =
|
|
54
|
+
var Input = React21.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 = React20.forwardRef(
|
|
|
59
59
|
}
|
|
60
60
|
);
|
|
61
61
|
Input.displayName = "Input";
|
|
62
|
-
var Textarea =
|
|
62
|
+
var Textarea = React21.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 = React20.forwardRef(
|
|
|
67
67
|
}
|
|
68
68
|
);
|
|
69
69
|
Textarea.displayName = "Textarea";
|
|
70
|
-
var Checkbox =
|
|
70
|
+
var Checkbox = React21.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 =
|
|
76
|
+
var Switch = React21.forwardRef(({ mode: _mode, ...props }, ref) => {
|
|
77
77
|
return /* @__PURE__ */ jsx(Switch$1, { ...props, ref });
|
|
78
78
|
});
|
|
79
79
|
Switch.displayName = "Switch";
|
|
@@ -626,7 +626,7 @@ function DefaultForm({
|
|
|
626
626
|
const isForgotPassword = mode === "forgot-password";
|
|
627
627
|
const isResetPassword = mode === "reset-password";
|
|
628
628
|
const isVerify = mode === "verify";
|
|
629
|
-
const [code, setCode] =
|
|
629
|
+
const [code, setCode] = React21.useState("");
|
|
630
630
|
const hasPrefill = !!(defaultEmail || defaultPassword);
|
|
631
631
|
const prefillStyle = (active) => active ? { animation: "auth-prefill 1.6s ease-out 0.35s 1 both" } : void 0;
|
|
632
632
|
const copy = authCopy[mode];
|
|
@@ -787,10 +787,10 @@ function DataTable({
|
|
|
787
787
|
emptyMessage = "No results.",
|
|
788
788
|
className
|
|
789
789
|
}) {
|
|
790
|
-
const [sorting, setSorting] =
|
|
791
|
-
const [rowSelection, setRowSelection] =
|
|
792
|
-
const [globalFilter, setGlobalFilter] =
|
|
793
|
-
const allColumns =
|
|
790
|
+
const [sorting, setSorting] = React21.useState([]);
|
|
791
|
+
const [rowSelection, setRowSelection] = React21.useState({});
|
|
792
|
+
const [globalFilter, setGlobalFilter] = React21.useState("");
|
|
793
|
+
const allColumns = React21.useMemo(
|
|
794
794
|
() => selectable ? [selectColumn, ...columns] : columns,
|
|
795
795
|
[selectable, columns]
|
|
796
796
|
);
|
|
@@ -812,7 +812,7 @@ function DataTable({
|
|
|
812
812
|
initialState: pageSize > 0 ? { pagination: { pageSize } } : void 0,
|
|
813
813
|
enableRowSelection: selectable
|
|
814
814
|
});
|
|
815
|
-
|
|
815
|
+
React21.useEffect(() => {
|
|
816
816
|
if (!onSelectionChange) return;
|
|
817
817
|
onSelectionChange(table.getSelectedRowModel().rows.map((r) => r.original));
|
|
818
818
|
}, [rowSelection]);
|
|
@@ -892,8 +892,8 @@ function DataTable({
|
|
|
892
892
|
] });
|
|
893
893
|
}
|
|
894
894
|
function InviteDialog({ roles, onInvite, onClose }) {
|
|
895
|
-
const [email, setEmail] =
|
|
896
|
-
const [role, setRole] =
|
|
895
|
+
const [email, setEmail] = React21.useState("");
|
|
896
|
+
const [role, setRole] = React21.useState(roles[roles.length - 1] ?? roles[0]);
|
|
897
897
|
return /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs(
|
|
898
898
|
"form",
|
|
899
899
|
{
|
|
@@ -937,8 +937,8 @@ function TeamMembersPanel({
|
|
|
937
937
|
title = "Team members",
|
|
938
938
|
description = "Manage who has access to this workspace."
|
|
939
939
|
}) {
|
|
940
|
-
const [inviteOpen, setInviteOpen] =
|
|
941
|
-
const columns =
|
|
940
|
+
const [inviteOpen, setInviteOpen] = React21.useState(false);
|
|
941
|
+
const columns = React21.useMemo(() => [
|
|
942
942
|
{
|
|
943
943
|
accessorKey: "name",
|
|
944
944
|
header: "Name",
|
|
@@ -1007,7 +1007,7 @@ function BillingPanel({
|
|
|
1007
1007
|
onUpdatePaymentMethod,
|
|
1008
1008
|
className
|
|
1009
1009
|
}) {
|
|
1010
|
-
const invoiceColumns =
|
|
1010
|
+
const invoiceColumns = React21.useMemo(() => [
|
|
1011
1011
|
{ accessorKey: "date", header: "Date", enableSorting: false },
|
|
1012
1012
|
{ accessorKey: "amount", header: "Amount", enableSorting: false },
|
|
1013
1013
|
{
|
|
@@ -1086,9 +1086,9 @@ function OnboardingWizard({
|
|
|
1086
1086
|
completeLabel = "Finish",
|
|
1087
1087
|
className
|
|
1088
1088
|
}) {
|
|
1089
|
-
const [internalStep, setInternalStep] =
|
|
1090
|
-
const [error, setError] =
|
|
1091
|
-
const [pending, setPending] =
|
|
1089
|
+
const [internalStep, setInternalStep] = React21.useState(0);
|
|
1090
|
+
const [error, setError] = React21.useState(null);
|
|
1091
|
+
const [pending, setPending] = React21.useState(false);
|
|
1092
1092
|
const index = stepProp ?? internalStep;
|
|
1093
1093
|
const current = steps[index];
|
|
1094
1094
|
const isLast = index === steps.length - 1;
|
|
@@ -1418,10 +1418,10 @@ function UpdateBanner({
|
|
|
1418
1418
|
buttonLabel = "Refresh now",
|
|
1419
1419
|
className
|
|
1420
1420
|
}) {
|
|
1421
|
-
const [show, setShow] =
|
|
1422
|
-
const [entered, setEntered] =
|
|
1423
|
-
const [refreshing, setRefreshing] =
|
|
1424
|
-
|
|
1421
|
+
const [show, setShow] = React21.useState(forceShow);
|
|
1422
|
+
const [entered, setEntered] = React21.useState(false);
|
|
1423
|
+
const [refreshing, setRefreshing] = React21.useState(false);
|
|
1424
|
+
React21.useEffect(() => {
|
|
1425
1425
|
if (forceShow) {
|
|
1426
1426
|
setShow(true);
|
|
1427
1427
|
return;
|
|
@@ -1444,7 +1444,7 @@ function UpdateBanner({
|
|
|
1444
1444
|
clearInterval(id);
|
|
1445
1445
|
};
|
|
1446
1446
|
}, [currentVersion, fetchVersion, forceShow, intervalMs]);
|
|
1447
|
-
|
|
1447
|
+
React21.useEffect(() => {
|
|
1448
1448
|
if (!show) {
|
|
1449
1449
|
setEntered(false);
|
|
1450
1450
|
return;
|
|
@@ -1517,9 +1517,9 @@ function FadeIn({
|
|
|
1517
1517
|
style,
|
|
1518
1518
|
...props
|
|
1519
1519
|
}) {
|
|
1520
|
-
const ref =
|
|
1521
|
-
const [visible, setVisible] =
|
|
1522
|
-
|
|
1520
|
+
const ref = React21.useRef(null);
|
|
1521
|
+
const [visible, setVisible] = React21.useState(false);
|
|
1522
|
+
React21.useEffect(() => {
|
|
1523
1523
|
const el = ref.current;
|
|
1524
1524
|
if (!el) return;
|
|
1525
1525
|
const observer = new IntersectionObserver(
|
|
@@ -1564,6 +1564,36 @@ var marketingSectionSpacing = {
|
|
|
1564
1564
|
standard: "px-6 py-14 sm:px-10 sm:py-20",
|
|
1565
1565
|
hero: "px-6 pb-14 pt-10 sm:px-10 sm:py-20"
|
|
1566
1566
|
};
|
|
1567
|
+
var MarketingSurfaceContext = React21.createContext(void 0);
|
|
1568
|
+
function MarketingSurfaceProvider({
|
|
1569
|
+
surface,
|
|
1570
|
+
children
|
|
1571
|
+
}) {
|
|
1572
|
+
return /* @__PURE__ */ jsx(MarketingSurfaceContext.Provider, { value: surface, children });
|
|
1573
|
+
}
|
|
1574
|
+
function useMarketingSurface() {
|
|
1575
|
+
return React21.useContext(MarketingSurfaceContext);
|
|
1576
|
+
}
|
|
1577
|
+
function useSectionSurface(override) {
|
|
1578
|
+
const mode = useUIVariant();
|
|
1579
|
+
const contextSurface = useMarketingSurface();
|
|
1580
|
+
const surface = override ?? contextSurface ?? "card";
|
|
1581
|
+
if (surface === "plain") return "overflow-hidden";
|
|
1582
|
+
if (surface === "soft") {
|
|
1583
|
+
return cn$1(
|
|
1584
|
+
"overflow-hidden border backdrop-blur-md",
|
|
1585
|
+
mode === "smooth" && "rounded-[2rem] border-border/40 bg-card/40",
|
|
1586
|
+
mode === "playful" && "rounded-3xl border-primary/20 bg-card/50",
|
|
1587
|
+
!mode && "rounded-3xl border-border/50 bg-card/45"
|
|
1588
|
+
);
|
|
1589
|
+
}
|
|
1590
|
+
return cn$1(
|
|
1591
|
+
"overflow-hidden bg-card",
|
|
1592
|
+
mode === "smooth" && "rounded-3xl border",
|
|
1593
|
+
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
1594
|
+
!mode && "rounded-2xl border"
|
|
1595
|
+
);
|
|
1596
|
+
}
|
|
1567
1597
|
var sizes = {
|
|
1568
1598
|
sm: { outer: "w-44", height: "h-80", notch: "w-16 h-4", border: "rounded-[2rem]", screen: "rounded-[1.75rem]" },
|
|
1569
1599
|
md: { outer: "w-56", height: "h-[26rem]", notch: "w-20 h-5", border: "rounded-[2.5rem]", screen: "rounded-[2.25rem]" },
|
|
@@ -1619,6 +1649,7 @@ function HeroSection({
|
|
|
1619
1649
|
description,
|
|
1620
1650
|
primaryCta,
|
|
1621
1651
|
secondaryCta,
|
|
1652
|
+
primarySlot,
|
|
1622
1653
|
heroImage,
|
|
1623
1654
|
media = "image",
|
|
1624
1655
|
phoneSize = "lg",
|
|
@@ -1633,19 +1664,28 @@ function HeroSection({
|
|
|
1633
1664
|
badge && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: badge }) }),
|
|
1634
1665
|
/* @__PURE__ */ jsx("h1", { className: "text-balance text-4xl font-semibold tracking-tight sm:text-5xl lg:text-6xl", children: heading }),
|
|
1635
1666
|
/* @__PURE__ */ jsx("p", { className: "max-w-lg text-pretty text-lg text-muted-foreground", children: description }),
|
|
1636
|
-
/* @__PURE__ */ jsxs(
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1667
|
+
/* @__PURE__ */ jsxs(
|
|
1668
|
+
"div",
|
|
1669
|
+
{
|
|
1670
|
+
className: cn$1(
|
|
1671
|
+
"flex gap-3",
|
|
1672
|
+
primarySlot ? "flex-col items-stretch sm:flex-row sm:items-center" : "flex-wrap items-center"
|
|
1673
|
+
),
|
|
1674
|
+
children: [
|
|
1675
|
+
primarySlot ?? (primaryCta && renderLink({
|
|
1676
|
+
href: primaryCta.href,
|
|
1677
|
+
children: /* @__PURE__ */ jsxs(Button, { size: "lg", children: [
|
|
1678
|
+
primaryCta.label,
|
|
1679
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "ml-2 size-4" })
|
|
1680
|
+
] })
|
|
1681
|
+
})),
|
|
1682
|
+
secondaryCta && renderLink({
|
|
1683
|
+
href: secondaryCta.href,
|
|
1684
|
+
children: /* @__PURE__ */ jsx(Button, { size: "lg", variant: "outline", children: secondaryCta.label })
|
|
1685
|
+
})
|
|
1686
|
+
]
|
|
1687
|
+
}
|
|
1688
|
+
)
|
|
1649
1689
|
] }) }),
|
|
1650
1690
|
media !== "none" && /* @__PURE__ */ jsx(FadeIn, { direction: "right", delay: 200, children: media === "phone" ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(PhoneFrame, { size: phoneSize, children: heroImage }) }) : /* @__PURE__ */ jsx("div", { className: cn$1("overflow-hidden", mode === "smooth" ? "rounded-3xl" : "rounded-2xl"), children: heroImage }) })
|
|
1651
1691
|
] }),
|
|
@@ -1714,16 +1754,16 @@ function Carousel({
|
|
|
1714
1754
|
className
|
|
1715
1755
|
}) {
|
|
1716
1756
|
const mode = useUIVariant();
|
|
1717
|
-
const trackRef =
|
|
1718
|
-
const [canPrev, setCanPrev] =
|
|
1719
|
-
const [canNext, setCanNext] =
|
|
1720
|
-
const updateScrollState =
|
|
1757
|
+
const trackRef = React21.useRef(null);
|
|
1758
|
+
const [canPrev, setCanPrev] = React21.useState(false);
|
|
1759
|
+
const [canNext, setCanNext] = React21.useState(true);
|
|
1760
|
+
const updateScrollState = React21.useCallback(() => {
|
|
1721
1761
|
const track = trackRef.current;
|
|
1722
1762
|
if (!track) return;
|
|
1723
1763
|
setCanPrev(track.scrollLeft > 8);
|
|
1724
1764
|
setCanNext(track.scrollLeft < track.scrollWidth - track.clientWidth - 8);
|
|
1725
1765
|
}, []);
|
|
1726
|
-
|
|
1766
|
+
React21.useEffect(() => {
|
|
1727
1767
|
const track = trackRef.current;
|
|
1728
1768
|
if (!track) return;
|
|
1729
1769
|
updateScrollState();
|
|
@@ -1780,7 +1820,7 @@ function Carousel({
|
|
|
1780
1820
|
role: "region",
|
|
1781
1821
|
"aria-label": ariaLabel,
|
|
1782
1822
|
className: "flex snap-x snap-mandatory gap-6 overflow-x-auto pb-4 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
1783
|
-
children:
|
|
1823
|
+
children: React21.Children.map(
|
|
1784
1824
|
children,
|
|
1785
1825
|
(child) => child == null ? null : /* @__PURE__ */ jsx("div", { "data-carousel-item": true, className: cn$1("shrink-0 snap-start", itemClassName), children: child })
|
|
1786
1826
|
)
|
|
@@ -1805,9 +1845,9 @@ function StaggerChildren({
|
|
|
1805
1845
|
className,
|
|
1806
1846
|
...props
|
|
1807
1847
|
}) {
|
|
1808
|
-
const ref =
|
|
1809
|
-
const [visible, setVisible] =
|
|
1810
|
-
|
|
1848
|
+
const ref = React21.useRef(null);
|
|
1849
|
+
const [visible, setVisible] = React21.useState(false);
|
|
1850
|
+
React21.useEffect(() => {
|
|
1811
1851
|
const el = ref.current;
|
|
1812
1852
|
if (!el) return;
|
|
1813
1853
|
const observer = new IntersectionObserver(
|
|
@@ -1825,7 +1865,7 @@ function StaggerChildren({
|
|
|
1825
1865
|
return () => observer.disconnect();
|
|
1826
1866
|
}, [once]);
|
|
1827
1867
|
const [tx, ty] = translateMap2[direction];
|
|
1828
|
-
return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children:
|
|
1868
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn$1(className), ...props, children: React21.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
|
|
1829
1869
|
"div",
|
|
1830
1870
|
{
|
|
1831
1871
|
className: "h-full",
|
|
@@ -1844,15 +1884,10 @@ function FeaturesSection({
|
|
|
1844
1884
|
description = "A complete system of components, blocks, and hooks designed to work together - and get out of your way.",
|
|
1845
1885
|
badge = "Features",
|
|
1846
1886
|
features,
|
|
1847
|
-
layout = "grid"
|
|
1887
|
+
layout = "grid",
|
|
1888
|
+
surface
|
|
1848
1889
|
}) {
|
|
1849
|
-
const
|
|
1850
|
-
const sectionClasses = cn$1(
|
|
1851
|
-
"overflow-hidden bg-card",
|
|
1852
|
-
mode === "smooth" && "rounded-3xl border",
|
|
1853
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
1854
|
-
!mode && "rounded-2xl border"
|
|
1855
|
-
);
|
|
1890
|
+
const sectionClasses = useSectionSurface(surface);
|
|
1856
1891
|
const cards = features.map((feature) => /* @__PURE__ */ jsx(
|
|
1857
1892
|
FeatureCard,
|
|
1858
1893
|
{
|
|
@@ -1872,15 +1907,10 @@ function GroupedFeaturesSection({
|
|
|
1872
1907
|
badge = "Features",
|
|
1873
1908
|
title = "Everything you need to ship",
|
|
1874
1909
|
description,
|
|
1875
|
-
groups
|
|
1910
|
+
groups,
|
|
1911
|
+
surface
|
|
1876
1912
|
}) {
|
|
1877
|
-
const
|
|
1878
|
-
const sectionClasses = cn$1(
|
|
1879
|
-
"overflow-hidden bg-card",
|
|
1880
|
-
mode === "smooth" && "rounded-3xl border",
|
|
1881
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
1882
|
-
!mode && "rounded-2xl border"
|
|
1883
|
-
);
|
|
1913
|
+
const sectionClasses = useSectionSurface(surface);
|
|
1884
1914
|
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: [
|
|
1885
1915
|
/* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
|
|
1886
1916
|
/* @__PURE__ */ jsx("div", { className: "mt-14 space-y-14", children: groups.map((group, i) => /* @__PURE__ */ jsxs("div", { children: [
|
|
@@ -1950,15 +1980,10 @@ function StepsSection({
|
|
|
1950
1980
|
description,
|
|
1951
1981
|
steps,
|
|
1952
1982
|
variant = "default",
|
|
1953
|
-
groups
|
|
1983
|
+
groups,
|
|
1984
|
+
surface
|
|
1954
1985
|
}) {
|
|
1955
|
-
const
|
|
1956
|
-
const sectionClasses = cn$1(
|
|
1957
|
-
"overflow-hidden bg-card",
|
|
1958
|
-
mode === "smooth" && "rounded-3xl border",
|
|
1959
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
1960
|
-
!mode && "rounded-2xl border"
|
|
1961
|
-
);
|
|
1986
|
+
const sectionClasses = useSectionSurface(surface);
|
|
1962
1987
|
if (variant === "timeline") {
|
|
1963
1988
|
const resolvedGroups = groups ?? (steps ? [{ steps }] : []);
|
|
1964
1989
|
let nextNumber = 1;
|
|
@@ -1967,7 +1992,7 @@ function StepsSection({
|
|
|
1967
1992
|
/* @__PURE__ */ jsx("div", { className: "mt-12", children: resolvedGroups.map((group, groupIndex) => {
|
|
1968
1993
|
const startNumber = nextNumber;
|
|
1969
1994
|
nextNumber += group.steps.length;
|
|
1970
|
-
return /* @__PURE__ */ jsxs(
|
|
1995
|
+
return /* @__PURE__ */ jsxs(React21.Fragment, { children: [
|
|
1971
1996
|
/* @__PURE__ */ jsx("div", { className: cn$1(groupIndex > 0 && "mt-10"), children: /* @__PURE__ */ jsx(TimelineGroup, { steps: group.steps, startNumber, fadeIn: groupIndex > 0 }) }),
|
|
1972
1997
|
group.after && /* @__PURE__ */ jsx("div", { className: "mt-16", children: group.after })
|
|
1973
1998
|
] }, groupIndex);
|
|
@@ -2011,15 +2036,11 @@ function TechStackSection({
|
|
|
2011
2036
|
badge = "Built on",
|
|
2012
2037
|
title = "The stack",
|
|
2013
2038
|
description,
|
|
2014
|
-
items
|
|
2039
|
+
items,
|
|
2040
|
+
surface
|
|
2015
2041
|
}) {
|
|
2016
2042
|
const mode = useUIVariant();
|
|
2017
|
-
const sectionClasses =
|
|
2018
|
-
"overflow-hidden bg-card",
|
|
2019
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2020
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2021
|
-
!mode && "rounded-2xl border"
|
|
2022
|
-
);
|
|
2043
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2023
2044
|
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: [
|
|
2024
2045
|
/* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
|
|
2025
2046
|
/* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-4", children: items.map((item) => {
|
|
@@ -2067,16 +2088,11 @@ function FeatureMarqueeSection({
|
|
|
2067
2088
|
description,
|
|
2068
2089
|
rows,
|
|
2069
2090
|
speed = "normal",
|
|
2070
|
-
pauseOnHover = true
|
|
2091
|
+
pauseOnHover = true,
|
|
2092
|
+
surface
|
|
2071
2093
|
}) {
|
|
2072
|
-
const mode = useUIVariant();
|
|
2073
2094
|
const duration = speedDuration[speed];
|
|
2074
|
-
const sectionClasses =
|
|
2075
|
-
"overflow-hidden bg-card",
|
|
2076
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2077
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2078
|
-
!mode && "rounded-2xl border"
|
|
2079
|
-
);
|
|
2095
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2080
2096
|
return /* @__PURE__ */ jsxs("section", { className: sectionClasses, children: [
|
|
2081
2097
|
/* @__PURE__ */ jsxs("div", { className: "py-14 sm:py-20", children: [
|
|
2082
2098
|
(title || badge || description) && /* @__PURE__ */ jsx(FadeIn, { direction: "up", children: /* @__PURE__ */ jsx("div", { className: "mx-auto mb-10 max-w-4xl px-6 sm:px-10", children: /* @__PURE__ */ jsx(SectionTitle, { title: title ?? "", description, badge }) }) }),
|
|
@@ -2137,9 +2153,9 @@ function FeatureMarqueeSection({
|
|
|
2137
2153
|
] });
|
|
2138
2154
|
}
|
|
2139
2155
|
function useIntersectionObserver(options) {
|
|
2140
|
-
const ref =
|
|
2141
|
-
const [isIntersecting, setIsIntersecting] =
|
|
2142
|
-
|
|
2156
|
+
const ref = React21.useRef(null);
|
|
2157
|
+
const [isIntersecting, setIsIntersecting] = React21.useState(false);
|
|
2158
|
+
React21.useEffect(() => {
|
|
2143
2159
|
const el = ref.current;
|
|
2144
2160
|
if (!el) return;
|
|
2145
2161
|
const observer = new IntersectionObserver(([entry]) => {
|
|
@@ -2161,8 +2177,8 @@ function ShowcaseCta({
|
|
|
2161
2177
|
sectionClasses
|
|
2162
2178
|
}) {
|
|
2163
2179
|
const [ref, intersecting] = useIntersectionObserver({ threshold: 0.15 });
|
|
2164
|
-
const [visible, setVisible] =
|
|
2165
|
-
|
|
2180
|
+
const [visible, setVisible] = React21.useState(false);
|
|
2181
|
+
React21.useEffect(() => {
|
|
2166
2182
|
if (intersecting) setVisible(true);
|
|
2167
2183
|
}, [intersecting]);
|
|
2168
2184
|
return /* @__PURE__ */ jsxs(
|
|
@@ -2211,15 +2227,11 @@ function CtaSection(props) {
|
|
|
2211
2227
|
secondaryCta,
|
|
2212
2228
|
footnote,
|
|
2213
2229
|
variant = "default",
|
|
2214
|
-
renderLink = defaultRenderLink5
|
|
2230
|
+
renderLink = defaultRenderLink5,
|
|
2231
|
+
surface
|
|
2215
2232
|
} = props;
|
|
2216
2233
|
const mode = useUIVariant();
|
|
2217
|
-
const sectionClasses =
|
|
2218
|
-
"overflow-hidden bg-card",
|
|
2219
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2220
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2221
|
-
!mode && "rounded-2xl border"
|
|
2222
|
-
);
|
|
2234
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2223
2235
|
if (variant === "showcase") {
|
|
2224
2236
|
return /* @__PURE__ */ jsx(ShowcaseCta, { ...props, sectionClasses });
|
|
2225
2237
|
}
|
|
@@ -2303,25 +2315,25 @@ function AnimatedSwap({
|
|
|
2303
2315
|
const ms = duration ?? spec?.duration ?? 0;
|
|
2304
2316
|
const reduced = usePrefersReducedMotion();
|
|
2305
2317
|
const animated = spec !== null && !reduced;
|
|
2306
|
-
const previous =
|
|
2307
|
-
const seenKey =
|
|
2308
|
-
const [swap, setSwap] =
|
|
2318
|
+
const previous = React21.useRef(children);
|
|
2319
|
+
const seenKey = React21.useRef(swapKey);
|
|
2320
|
+
const [swap, setSwap] = React21.useState(null);
|
|
2309
2321
|
if (seenKey.current !== swapKey) {
|
|
2310
2322
|
const out = previous.current;
|
|
2311
2323
|
seenKey.current = swapKey;
|
|
2312
2324
|
if (animated) setSwap({ key: swapKey, out, running: false });
|
|
2313
2325
|
}
|
|
2314
|
-
|
|
2326
|
+
React21.useEffect(() => {
|
|
2315
2327
|
previous.current = children;
|
|
2316
2328
|
});
|
|
2317
|
-
|
|
2329
|
+
React21.useEffect(() => {
|
|
2318
2330
|
if (!swap || swap.running) return;
|
|
2319
2331
|
const raf = requestAnimationFrame(() => {
|
|
2320
2332
|
setSwap((s) => s && s.key === swap.key ? { ...s, running: true } : s);
|
|
2321
2333
|
});
|
|
2322
2334
|
return () => cancelAnimationFrame(raf);
|
|
2323
2335
|
}, [swap]);
|
|
2324
|
-
|
|
2336
|
+
React21.useEffect(() => {
|
|
2325
2337
|
if (!swap?.running) return;
|
|
2326
2338
|
const done = setTimeout(() => {
|
|
2327
2339
|
setSwap((s) => s && s.key === swap.key ? null : s);
|
|
@@ -2351,8 +2363,8 @@ function AnimatedSwap({
|
|
|
2351
2363
|
);
|
|
2352
2364
|
}
|
|
2353
2365
|
function usePrefersReducedMotion() {
|
|
2354
|
-
const [reduced, setReduced] =
|
|
2355
|
-
|
|
2366
|
+
const [reduced, setReduced] = React21.useState(false);
|
|
2367
|
+
React21.useEffect(() => {
|
|
2356
2368
|
const query = window.matchMedia?.("(prefers-reduced-motion: reduce)");
|
|
2357
2369
|
if (!query) return;
|
|
2358
2370
|
setReduced(query.matches);
|
|
@@ -2464,8 +2476,8 @@ function CountdownTimer({
|
|
|
2464
2476
|
className,
|
|
2465
2477
|
compact = false
|
|
2466
2478
|
}) {
|
|
2467
|
-
const [timeLeft, setTimeLeft] =
|
|
2468
|
-
|
|
2479
|
+
const [timeLeft, setTimeLeft] = React21.useState(() => getTimeLeft(deadline));
|
|
2480
|
+
React21.useEffect(() => {
|
|
2469
2481
|
setTimeLeft(getTimeLeft(deadline));
|
|
2470
2482
|
const id = setInterval(() => setTimeLeft(getTimeLeft(deadline)), 1e3);
|
|
2471
2483
|
return () => clearInterval(id);
|
|
@@ -2491,7 +2503,7 @@ function CountdownTimer({
|
|
|
2491
2503
|
];
|
|
2492
2504
|
return /* @__PURE__ */ jsxs("div", { className: cn$1("flex items-center justify-center gap-2 text-sm", className), children: [
|
|
2493
2505
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label }),
|
|
2494
|
-
/* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(
|
|
2506
|
+
/* @__PURE__ */ jsx("span", { className: "flex items-center gap-1 font-mono font-semibold tabular-nums", children: units.map(({ value, unit }, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
|
|
2495
2507
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
2496
2508
|
String(value).padStart(2, "0"),
|
|
2497
2509
|
/* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: unit })
|
|
@@ -2545,26 +2557,21 @@ function PricingSection({
|
|
|
2545
2557
|
defaultCadence,
|
|
2546
2558
|
onSelectPlan,
|
|
2547
2559
|
pendingPlanName,
|
|
2548
|
-
priceEffect
|
|
2560
|
+
priceEffect,
|
|
2561
|
+
surface
|
|
2549
2562
|
}) {
|
|
2550
|
-
const [annual, setAnnual] =
|
|
2563
|
+
const [annual, setAnnual] = React21.useState(false);
|
|
2551
2564
|
const isOneTime = mode === "one-time";
|
|
2552
2565
|
const useCadences = !!cadences?.length;
|
|
2553
2566
|
const initialCadence = (defaultCadence && cadences?.some((c) => c.key === defaultCadence) ? defaultCadence : null) ?? cadences?.[0]?.key ?? "";
|
|
2554
|
-
const [activeCadence, setActiveCadence] =
|
|
2567
|
+
const [activeCadence, setActiveCadence] = React21.useState(initialCadence);
|
|
2555
2568
|
const cadence = cadences?.find((c) => c.key === activeCadence);
|
|
2556
|
-
const saveBadges =
|
|
2569
|
+
const saveBadges = React21.useMemo(
|
|
2557
2570
|
() => useCadences ? computeSaveBadges(plans, cadences, initialCadence) : {},
|
|
2558
2571
|
[useCadences, plans, cadences, initialCadence]
|
|
2559
2572
|
);
|
|
2560
2573
|
const showToggle = useCadences ? cadences.length > 1 : !isOneTime;
|
|
2561
|
-
const
|
|
2562
|
-
const sectionClasses = cn$1(
|
|
2563
|
-
"overflow-hidden bg-card",
|
|
2564
|
-
uiMode === "smooth" && "rounded-3xl border",
|
|
2565
|
-
uiMode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2566
|
-
!uiMode && "rounded-2xl border"
|
|
2567
|
-
);
|
|
2574
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2568
2575
|
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-5xl", children: [
|
|
2569
2576
|
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2570
2577
|
badge && (typeof badge === "string" ? /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "mb-4", children: badge }) : /* @__PURE__ */ jsx("div", { className: "mb-4", children: badge })),
|
|
@@ -2719,15 +2726,10 @@ function TestimonialsSection({
|
|
|
2719
2726
|
title = "Trusted by teams shipping real products",
|
|
2720
2727
|
description = "Here's what engineers and product teams say after using Olwiba in production.",
|
|
2721
2728
|
badge = "Testimonials",
|
|
2722
|
-
testimonials
|
|
2729
|
+
testimonials,
|
|
2730
|
+
surface
|
|
2723
2731
|
}) {
|
|
2724
|
-
const
|
|
2725
|
-
const sectionClasses = cn$1(
|
|
2726
|
-
"overflow-hidden bg-card",
|
|
2727
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2728
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2729
|
-
!mode && "rounded-2xl border"
|
|
2730
|
-
);
|
|
2732
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2731
2733
|
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-5xl", children: [
|
|
2732
2734
|
/* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
|
|
2733
2735
|
/* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 columns-1 gap-4 sm:columns-2 lg:columns-3", children: testimonials.map((t) => /* @__PURE__ */ jsx(
|
|
@@ -2781,15 +2783,10 @@ function TeamSection({
|
|
|
2781
2783
|
members = defaultTeam,
|
|
2782
2784
|
badge = "Team",
|
|
2783
2785
|
title = "The people behind Olwiba",
|
|
2784
|
-
description = "A small team with deep experience in design systems, open source, and developer tooling."
|
|
2786
|
+
description = "A small team with deep experience in design systems, open source, and developer tooling.",
|
|
2787
|
+
surface
|
|
2785
2788
|
}) {
|
|
2786
|
-
const
|
|
2787
|
-
const sectionClasses = cn$1(
|
|
2788
|
-
"overflow-hidden bg-card",
|
|
2789
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2790
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2791
|
-
!mode && "rounded-2xl border"
|
|
2792
|
-
);
|
|
2789
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2793
2790
|
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-5xl", children: [
|
|
2794
2791
|
/* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
2795
2792
|
/* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "mb-4", children: badge }),
|
|
@@ -2820,15 +2817,10 @@ function FaqSection({
|
|
|
2820
2817
|
title = "Frequently asked questions",
|
|
2821
2818
|
description = "Everything you need to know before getting started.",
|
|
2822
2819
|
badge = "FAQ",
|
|
2823
|
-
items
|
|
2820
|
+
items,
|
|
2821
|
+
surface
|
|
2824
2822
|
}) {
|
|
2825
|
-
const
|
|
2826
|
-
const sectionClasses = cn$1(
|
|
2827
|
-
"overflow-hidden bg-card",
|
|
2828
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2829
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2830
|
-
!mode && "rounded-2xl border"
|
|
2831
|
-
);
|
|
2823
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2832
2824
|
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: [
|
|
2833
2825
|
/* @__PURE__ */ jsx(SectionTitle, { title, description, badge }),
|
|
2834
2826
|
/* @__PURE__ */ jsx(FadeIn, { direction: "up", children: /* @__PURE__ */ jsx(Accordion, { type: "single", collapsible: true, className: "mt-10 w-full", children: items.map((item, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `item-${i}`, children: [
|
|
@@ -2848,10 +2840,10 @@ function CountUp({
|
|
|
2848
2840
|
className,
|
|
2849
2841
|
...props
|
|
2850
2842
|
}) {
|
|
2851
|
-
const ref =
|
|
2852
|
-
const [value, setValue] =
|
|
2853
|
-
const hasStarted =
|
|
2854
|
-
|
|
2843
|
+
const ref = React21.useRef(null);
|
|
2844
|
+
const [value, setValue] = React21.useState(from);
|
|
2845
|
+
const hasStarted = React21.useRef(false);
|
|
2846
|
+
React21.useEffect(() => {
|
|
2855
2847
|
const el = ref.current;
|
|
2856
2848
|
if (!el) return;
|
|
2857
2849
|
const observer = new IntersectionObserver(
|
|
@@ -2897,15 +2889,10 @@ function StatsSection({
|
|
|
2897
2889
|
title = "Built for scale, used in production",
|
|
2898
2890
|
description,
|
|
2899
2891
|
badge = "By the numbers",
|
|
2900
|
-
stats
|
|
2892
|
+
stats,
|
|
2893
|
+
surface
|
|
2901
2894
|
}) {
|
|
2902
|
-
const
|
|
2903
|
-
const sectionClasses = cn$1(
|
|
2904
|
-
"overflow-hidden bg-card",
|
|
2905
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2906
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2907
|
-
!mode && "rounded-2xl border"
|
|
2908
|
-
);
|
|
2895
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2909
2896
|
return /* @__PURE__ */ jsx("section", { className: sectionClasses, children: /* @__PURE__ */ jsxs("div", { className: "relative px-6 py-14 sm:px-10 sm:py-20", children: [
|
|
2910
2897
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(ellipse_at_bottom,hsl(var(--primary)/0.08),transparent_60%)]" }),
|
|
2911
2898
|
/* @__PURE__ */ jsxs("div", { className: "relative mx-auto max-w-4xl", children: [
|
|
@@ -2942,17 +2929,12 @@ function NewsletterSection({
|
|
|
2942
2929
|
privacyLabel = defaults.privacyLabel,
|
|
2943
2930
|
successTitle = defaults.successTitle,
|
|
2944
2931
|
successDescription = defaults.successDescription,
|
|
2945
|
-
onSubscribe
|
|
2932
|
+
onSubscribe,
|
|
2933
|
+
surface
|
|
2946
2934
|
} = {}) {
|
|
2947
|
-
const [email, setEmail] =
|
|
2948
|
-
const [submitted, setSubmitted] =
|
|
2949
|
-
const
|
|
2950
|
-
const sectionClasses = cn$1(
|
|
2951
|
-
"overflow-hidden bg-card",
|
|
2952
|
-
mode === "smooth" && "rounded-3xl border",
|
|
2953
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
2954
|
-
!mode && "rounded-2xl border"
|
|
2955
|
-
);
|
|
2935
|
+
const [email, setEmail] = React21.useState("");
|
|
2936
|
+
const [submitted, setSubmitted] = React21.useState(false);
|
|
2937
|
+
const sectionClasses = useSectionSurface(surface);
|
|
2956
2938
|
async function handleSubmit(e) {
|
|
2957
2939
|
e.preventDefault();
|
|
2958
2940
|
if (!email) return;
|
|
@@ -3034,16 +3016,11 @@ function ContactSection({
|
|
|
3034
3016
|
successTitle = defaults2.successTitle,
|
|
3035
3017
|
successDescription = defaults2.successDescription,
|
|
3036
3018
|
sendAnotherLabel = defaults2.sendAnotherLabel,
|
|
3037
|
-
onSubmit
|
|
3019
|
+
onSubmit,
|
|
3020
|
+
surface
|
|
3038
3021
|
} = {}) {
|
|
3039
|
-
const [submitted, setSubmitted] =
|
|
3040
|
-
const
|
|
3041
|
-
const sectionClasses = cn$1(
|
|
3042
|
-
"overflow-hidden bg-card",
|
|
3043
|
-
mode === "smooth" && "rounded-3xl border",
|
|
3044
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
3045
|
-
!mode && "rounded-2xl border"
|
|
3046
|
-
);
|
|
3022
|
+
const [submitted, setSubmitted] = React21.useState(false);
|
|
3023
|
+
const sectionClasses = useSectionSurface(surface);
|
|
3047
3024
|
async function handleSubmit(e) {
|
|
3048
3025
|
e.preventDefault();
|
|
3049
3026
|
await onSubmit?.(e);
|
|
@@ -3227,15 +3204,10 @@ function ComparisonSection({
|
|
|
3227
3204
|
badge = "The math",
|
|
3228
3205
|
title = "The math is simple",
|
|
3229
3206
|
description,
|
|
3230
|
-
columns
|
|
3207
|
+
columns,
|
|
3208
|
+
surface
|
|
3231
3209
|
}) {
|
|
3232
|
-
const
|
|
3233
|
-
const sectionClasses = cn$1(
|
|
3234
|
-
"overflow-hidden bg-card",
|
|
3235
|
-
mode === "smooth" && "rounded-3xl border",
|
|
3236
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
3237
|
-
!mode && "rounded-2xl border"
|
|
3238
|
-
);
|
|
3210
|
+
const sectionClasses = useSectionSurface(surface);
|
|
3239
3211
|
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: [
|
|
3240
3212
|
/* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
|
|
3241
3213
|
/* @__PURE__ */ jsx(StaggerChildren, { className: "mt-12 grid gap-4 sm:grid-cols-3", children: columns.map((col) => /* @__PURE__ */ jsxs(
|
|
@@ -3283,15 +3255,10 @@ function QualificationSection({
|
|
|
3283
3255
|
badge = "Who it is for",
|
|
3284
3256
|
title = "Is this for you?",
|
|
3285
3257
|
description,
|
|
3286
|
-
columns
|
|
3258
|
+
columns,
|
|
3259
|
+
surface
|
|
3287
3260
|
}) {
|
|
3288
|
-
const
|
|
3289
|
-
const sectionClasses = cn$1(
|
|
3290
|
-
"overflow-hidden bg-card",
|
|
3291
|
-
mode === "smooth" && "rounded-3xl border",
|
|
3292
|
-
mode === "playful" && "rounded-2xl border-primary/25 border",
|
|
3293
|
-
!mode && "rounded-2xl border"
|
|
3294
|
-
);
|
|
3261
|
+
const sectionClasses = useSectionSurface(surface);
|
|
3295
3262
|
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: [
|
|
3296
3263
|
/* @__PURE__ */ jsx(SectionTitle, { badge, title, description }),
|
|
3297
3264
|
/* @__PURE__ */ jsx(FadeIn, { direction: "up", className: "mt-12 grid gap-6 sm:grid-cols-2", children: columns.map((col) => {
|
|
@@ -3334,10 +3301,10 @@ function Navbar({
|
|
|
3334
3301
|
controls,
|
|
3335
3302
|
renderLink = defaultRenderLink7
|
|
3336
3303
|
}) {
|
|
3337
|
-
const [open, setOpen] =
|
|
3304
|
+
const [open, setOpen] = React21.useState(false);
|
|
3338
3305
|
const brandHref = brand.href ?? "/";
|
|
3339
3306
|
const hasRightContent = controls?.length || cta?.primary || cta?.secondary;
|
|
3340
|
-
const closeMobileMenu =
|
|
3307
|
+
const closeMobileMenu = React21.useCallback(() => setOpen(false), []);
|
|
3341
3308
|
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: [
|
|
3342
3309
|
renderLink({
|
|
3343
3310
|
href: brandHref,
|
|
@@ -3352,7 +3319,7 @@ function Navbar({
|
|
|
3352
3319
|
children: link.label
|
|
3353
3320
|
}) }, link.label)) }),
|
|
3354
3321
|
hasRightContent && /* @__PURE__ */ jsxs("div", { className: "hidden items-center justify-end gap-2 md:flex", children: [
|
|
3355
|
-
controls?.map((control, i) => /* @__PURE__ */ jsx(
|
|
3322
|
+
controls?.map((control, i) => /* @__PURE__ */ jsx(React21.Fragment, { children: control }, i)),
|
|
3356
3323
|
(cta?.secondary || cta?.primary) && controls?.length ? /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-border" }) : null,
|
|
3357
3324
|
cta?.secondary && renderLink({
|
|
3358
3325
|
href: cta.secondary.href,
|
|
@@ -3365,7 +3332,7 @@ function Navbar({
|
|
|
3365
3332
|
] }),
|
|
3366
3333
|
/* @__PURE__ */ jsxs(Sheet, { open, onOpenChange: setOpen, children: [
|
|
3367
3334
|
/* @__PURE__ */ jsxs("div", { className: "col-start-3 flex items-center justify-end gap-1 md:hidden", children: [
|
|
3368
|
-
controls?.map((control, i) => /* @__PURE__ */ jsx(
|
|
3335
|
+
controls?.map((control, i) => /* @__PURE__ */ jsx(React21.Fragment, { children: control }, i)),
|
|
3369
3336
|
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "ghost", size: "icon", children: [
|
|
3370
3337
|
/* @__PURE__ */ jsx(Menu, { className: "size-5" }),
|
|
3371
3338
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Open menu" })
|
|
@@ -3527,7 +3494,7 @@ function LogoStrip({
|
|
|
3527
3494
|
] });
|
|
3528
3495
|
}
|
|
3529
3496
|
function GridUnderlay({ variant, size = 24, className, ...props }) {
|
|
3530
|
-
const id =
|
|
3497
|
+
const id = React21.useId();
|
|
3531
3498
|
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: [
|
|
3532
3499
|
/* @__PURE__ */ jsx("line", { x1: size / 2, y1: 0, x2: size / 2, y2: size, stroke: "currentColor", strokeWidth: 0.5 }),
|
|
3533
3500
|
/* @__PURE__ */ jsx("line", { x1: 0, y1: size / 2, x2: size, y2: size / 2, stroke: "currentColor", strokeWidth: 0.5 })
|
|
@@ -3555,9 +3522,9 @@ function GlowUnderlay({
|
|
|
3555
3522
|
style,
|
|
3556
3523
|
...props
|
|
3557
3524
|
}) {
|
|
3558
|
-
const [pos, setPos] =
|
|
3559
|
-
const containerRef =
|
|
3560
|
-
|
|
3525
|
+
const [pos, setPos] = React21.useState({ x: "50%", y: "50%" });
|
|
3526
|
+
const containerRef = React21.useRef(null);
|
|
3527
|
+
React21.useEffect(() => {
|
|
3561
3528
|
if (!followCursor) return;
|
|
3562
3529
|
const handleMouseMove = (e) => {
|
|
3563
3530
|
const el = containerRef.current;
|
|
@@ -3696,8 +3663,8 @@ function PageTransition({
|
|
|
3696
3663
|
style,
|
|
3697
3664
|
...props
|
|
3698
3665
|
}) {
|
|
3699
|
-
const [mounted, setMounted] =
|
|
3700
|
-
|
|
3666
|
+
const [mounted, setMounted] = React21.useState(false);
|
|
3667
|
+
React21.useEffect(() => {
|
|
3701
3668
|
const id = requestAnimationFrame(() => setMounted(true));
|
|
3702
3669
|
return () => cancelAnimationFrame(id);
|
|
3703
3670
|
}, []);
|
|
@@ -3772,7 +3739,7 @@ function Sortable({
|
|
|
3772
3739
|
if (oldIndex === -1 || newIndex === -1) return;
|
|
3773
3740
|
onReorder(arrayMove(items, oldIndex, newIndex));
|
|
3774
3741
|
};
|
|
3775
|
-
const childArray =
|
|
3742
|
+
const childArray = React21.Children.toArray(children);
|
|
3776
3743
|
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(
|
|
3777
3744
|
(child, i) => items[i] === void 0 ? null : /* @__PURE__ */ jsx(SortableItem, { id: items[i], disabled, className: itemClassName, children: child }, items[i])
|
|
3778
3745
|
) }) }) });
|
|
@@ -3784,8 +3751,8 @@ function Spotlight({
|
|
|
3784
3751
|
triggerClassName,
|
|
3785
3752
|
shortcut = "\u2318K"
|
|
3786
3753
|
}) {
|
|
3787
|
-
const [open, setOpen] =
|
|
3788
|
-
|
|
3754
|
+
const [open, setOpen] = React21.useState(false);
|
|
3755
|
+
React21.useEffect(() => {
|
|
3789
3756
|
const down = (e) => {
|
|
3790
3757
|
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
|
3791
3758
|
e.preventDefault();
|
|
@@ -3815,7 +3782,7 @@ function Spotlight({
|
|
|
3815
3782
|
/* @__PURE__ */ jsx(CommandInput, { placeholder }),
|
|
3816
3783
|
/* @__PURE__ */ jsxs(CommandList, { children: [
|
|
3817
3784
|
/* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
|
|
3818
|
-
groups.map((group, i) => /* @__PURE__ */ jsxs(
|
|
3785
|
+
groups.map((group, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
|
|
3819
3786
|
i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
|
|
3820
3787
|
/* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
|
|
3821
3788
|
CommandItem,
|
|
@@ -3840,8 +3807,8 @@ function Spotlight({
|
|
|
3840
3807
|
var BASE = 40;
|
|
3841
3808
|
var MAGNIFY_RADIUS = 80;
|
|
3842
3809
|
function Dock({ items, iconSize = BASE, magnification = 1.7, className, ...props }) {
|
|
3843
|
-
const [mouseX, setMouseX] =
|
|
3844
|
-
const containerRef =
|
|
3810
|
+
const [mouseX, setMouseX] = React21.useState(null);
|
|
3811
|
+
const containerRef = React21.useRef(null);
|
|
3845
3812
|
function getScale(index) {
|
|
3846
3813
|
if (mouseX === null || !containerRef.current) return 1;
|
|
3847
3814
|
const container = containerRef.current;
|
|
@@ -3940,7 +3907,7 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
|
|
|
3940
3907
|
] }) });
|
|
3941
3908
|
}
|
|
3942
3909
|
function RegisterHotkeys({ hotkeys }) {
|
|
3943
|
-
|
|
3910
|
+
React21.useEffect(() => {
|
|
3944
3911
|
const handleKeyDown = (event) => {
|
|
3945
3912
|
for (const hotkey of hotkeys) {
|
|
3946
3913
|
const matches = event.key.toLowerCase() === hotkey.key.toLowerCase() && !!event.ctrlKey === !!hotkey.ctrl && !!event.metaKey === !!hotkey.meta && !!event.shiftKey === !!hotkey.shift && !!event.altKey === !!hotkey.alt;
|
|
@@ -3957,10 +3924,10 @@ function RegisterHotkeys({ hotkeys }) {
|
|
|
3957
3924
|
return null;
|
|
3958
3925
|
}
|
|
3959
3926
|
function useControlledOpen(defaultOpen = false) {
|
|
3960
|
-
const [isOpen, setIsOpen] =
|
|
3961
|
-
const open =
|
|
3962
|
-
const close =
|
|
3963
|
-
const toggle =
|
|
3927
|
+
const [isOpen, setIsOpen] = React21.useState(defaultOpen);
|
|
3928
|
+
const open = React21.useCallback(() => setIsOpen(true), []);
|
|
3929
|
+
const close = React21.useCallback(() => setIsOpen(false), []);
|
|
3930
|
+
const toggle = React21.useCallback(() => setIsOpen((prev) => !prev), []);
|
|
3964
3931
|
return { isOpen, open, close, toggle, setIsOpen };
|
|
3965
3932
|
}
|
|
3966
3933
|
function CommandMenu({
|
|
@@ -3973,7 +3940,7 @@ function CommandMenu({
|
|
|
3973
3940
|
}) {
|
|
3974
3941
|
const internal = useControlledOpen(false);
|
|
3975
3942
|
const isOpen = openProp ?? internal.isOpen;
|
|
3976
|
-
const setOpen =
|
|
3943
|
+
const setOpen = React21.useCallback(
|
|
3977
3944
|
(next) => {
|
|
3978
3945
|
if (openProp === void 0) internal.setIsOpen(next);
|
|
3979
3946
|
onOpenChange?.(next);
|
|
@@ -3998,7 +3965,7 @@ function CommandMenu({
|
|
|
3998
3965
|
/* @__PURE__ */ jsx(CommandInput, { placeholder }),
|
|
3999
3966
|
/* @__PURE__ */ jsxs(CommandList, { children: [
|
|
4000
3967
|
/* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
|
|
4001
|
-
groups.map((group, i) => /* @__PURE__ */ jsxs(
|
|
3968
|
+
groups.map((group, i) => /* @__PURE__ */ jsxs(React21.Fragment, { children: [
|
|
4002
3969
|
i > 0 && /* @__PURE__ */ jsx(CommandSeparator, {}),
|
|
4003
3970
|
/* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsxs(
|
|
4004
3971
|
CommandItem,
|
|
@@ -4053,7 +4020,7 @@ function DataView({
|
|
|
4053
4020
|
}
|
|
4054
4021
|
);
|
|
4055
4022
|
}
|
|
4056
|
-
return /* @__PURE__ */ jsx(AppGrid, { columns: gridColumns, gap, className: cn$1(className), children: items.map((item) => /* @__PURE__ */ jsx(
|
|
4023
|
+
return /* @__PURE__ */ jsx(AppGrid, { columns: gridColumns, gap, className: cn$1(className), children: items.map((item) => /* @__PURE__ */ jsx(React21.Fragment, { children: renderCard(item) }, getRowId(item))) });
|
|
4057
4024
|
}
|
|
4058
4025
|
var TOKEN_COLORS = ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
|
|
4059
4026
|
var seriesColor = (s, i) => s.color ?? TOKEN_COLORS[i % TOKEN_COLORS.length];
|
|
@@ -4227,20 +4194,20 @@ function FileUpload({
|
|
|
4227
4194
|
hint,
|
|
4228
4195
|
className
|
|
4229
4196
|
}) {
|
|
4230
|
-
const [internalFiles, setInternalFiles] =
|
|
4231
|
-
const [isDragging, setIsDragging] =
|
|
4232
|
-
const [validationError, setValidationError] =
|
|
4233
|
-
const inputRef =
|
|
4234
|
-
const dragDepth =
|
|
4197
|
+
const [internalFiles, setInternalFiles] = React21.useState(defaultFiles ?? []);
|
|
4198
|
+
const [isDragging, setIsDragging] = React21.useState(false);
|
|
4199
|
+
const [validationError, setValidationError] = React21.useState(null);
|
|
4200
|
+
const inputRef = React21.useRef(null);
|
|
4201
|
+
const dragDepth = React21.useRef(0);
|
|
4235
4202
|
const files = filesProp ?? internalFiles;
|
|
4236
|
-
const setFiles =
|
|
4203
|
+
const setFiles = React21.useCallback(
|
|
4237
4204
|
(next) => {
|
|
4238
4205
|
if (!filesProp) setInternalFiles(next);
|
|
4239
4206
|
onFilesChange?.(next);
|
|
4240
4207
|
},
|
|
4241
4208
|
[filesProp, onFilesChange]
|
|
4242
4209
|
);
|
|
4243
|
-
const acceptList =
|
|
4210
|
+
const acceptList = React21.useMemo(
|
|
4244
4211
|
() => accept?.split(",").map((a) => a.trim().toLowerCase()).filter(Boolean) ?? [],
|
|
4245
4212
|
[accept]
|
|
4246
4213
|
);
|
|
@@ -4964,7 +4931,7 @@ function PageHeader({
|
|
|
4964
4931
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1 pb-6", className), children: [
|
|
4965
4932
|
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) => {
|
|
4966
4933
|
const isLast = i === breadcrumbs.length - 1;
|
|
4967
|
-
return /* @__PURE__ */ jsxs(
|
|
4934
|
+
return /* @__PURE__ */ jsxs(React21.Fragment, { children: [
|
|
4968
4935
|
i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3.5 shrink-0" }),
|
|
4969
4936
|
isLast || !crumb.href ? /* @__PURE__ */ jsx("span", { className: cn(isLast && "text-foreground font-medium"), children: crumb.label }) : renderLink({
|
|
4970
4937
|
href: crumb.href,
|
|
@@ -5000,7 +4967,7 @@ function PageHeader({
|
|
|
5000
4967
|
] });
|
|
5001
4968
|
}
|
|
5002
4969
|
function Suspensed({ children, fallback }) {
|
|
5003
|
-
return /* @__PURE__ */ jsx(
|
|
4970
|
+
return /* @__PURE__ */ jsx(React21.Suspense, { fallback: fallback ?? /* @__PURE__ */ jsx(Spinner, {}), children });
|
|
5004
4971
|
}
|
|
5005
4972
|
function getInitialTheme() {
|
|
5006
4973
|
if (typeof document === "undefined") return "dark";
|
|
@@ -5008,7 +4975,7 @@ function getInitialTheme() {
|
|
|
5008
4975
|
return stored ?? (document.documentElement.classList.contains("dark") ? "dark" : "light");
|
|
5009
4976
|
}
|
|
5010
4977
|
function ThemeSwitchMinimal() {
|
|
5011
|
-
const [theme, setThemeState] =
|
|
4978
|
+
const [theme, setThemeState] = React21.useState(getInitialTheme);
|
|
5012
4979
|
const toggle = () => {
|
|
5013
4980
|
const next = theme === "dark" ? "light" : "dark";
|
|
5014
4981
|
setThemeState(next);
|
|
@@ -5134,9 +5101,9 @@ function getInitialColorName() {
|
|
|
5134
5101
|
return localStorage.getItem(STORAGE_KEY) ?? "emerald";
|
|
5135
5102
|
}
|
|
5136
5103
|
function BrandColorSwitchMinimal() {
|
|
5137
|
-
const [active, setActive] =
|
|
5138
|
-
const [open, setOpen] =
|
|
5139
|
-
|
|
5104
|
+
const [active, setActive] = React21.useState(getInitialColorName);
|
|
5105
|
+
const [open, setOpen] = React21.useState(false);
|
|
5106
|
+
React21.useEffect(() => {
|
|
5140
5107
|
const saved = localStorage.getItem(STORAGE_KEY) ?? "emerald";
|
|
5141
5108
|
const color = BRAND_COLORS.find((c) => c.name === saved);
|
|
5142
5109
|
if (color) applyColor(color);
|
|
@@ -5197,7 +5164,7 @@ function BrandColorSwitchMinimal() {
|
|
|
5197
5164
|
] });
|
|
5198
5165
|
}
|
|
5199
5166
|
function ThemeColorUpdater({ colorTheme }) {
|
|
5200
|
-
|
|
5167
|
+
React21.useEffect(() => {
|
|
5201
5168
|
if (colorTheme) {
|
|
5202
5169
|
document.documentElement.setAttribute("data-theme", colorTheme);
|
|
5203
5170
|
} else {
|
|
@@ -5207,7 +5174,7 @@ function ThemeColorUpdater({ colorTheme }) {
|
|
|
5207
5174
|
return null;
|
|
5208
5175
|
}
|
|
5209
5176
|
function VersionBanner({ version, message, className, onDismiss }) {
|
|
5210
|
-
const [dismissed, setDismissed] =
|
|
5177
|
+
const [dismissed, setDismissed] = React21.useState(false);
|
|
5211
5178
|
if (dismissed) return null;
|
|
5212
5179
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-4 bg-primary/10 px-4 py-2 text-sm", className), children: [
|
|
5213
5180
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -5464,29 +5431,29 @@ function useMounted() {
|
|
|
5464
5431
|
return mounted;
|
|
5465
5432
|
}
|
|
5466
5433
|
function useConfirm() {
|
|
5467
|
-
const [isOpen, setIsOpen] =
|
|
5468
|
-
const [options, setOptions] =
|
|
5469
|
-
const resolveRef =
|
|
5470
|
-
const confirm =
|
|
5434
|
+
const [isOpen, setIsOpen] = React21.useState(false);
|
|
5435
|
+
const [options, setOptions] = React21.useState({});
|
|
5436
|
+
const resolveRef = React21.useRef(null);
|
|
5437
|
+
const confirm = React21.useCallback((opts = {}) => {
|
|
5471
5438
|
setOptions(opts);
|
|
5472
5439
|
setIsOpen(true);
|
|
5473
5440
|
return new Promise((resolve) => {
|
|
5474
5441
|
resolveRef.current = resolve;
|
|
5475
5442
|
});
|
|
5476
5443
|
}, []);
|
|
5477
|
-
const handleConfirm =
|
|
5444
|
+
const handleConfirm = React21.useCallback(() => {
|
|
5478
5445
|
resolveRef.current?.(true);
|
|
5479
5446
|
setIsOpen(false);
|
|
5480
5447
|
}, []);
|
|
5481
|
-
const handleCancel =
|
|
5448
|
+
const handleCancel = React21.useCallback(() => {
|
|
5482
5449
|
resolveRef.current?.(false);
|
|
5483
5450
|
setIsOpen(false);
|
|
5484
5451
|
}, []);
|
|
5485
5452
|
return { confirm, isOpen, options, handleConfirm, handleCancel };
|
|
5486
5453
|
}
|
|
5487
5454
|
function useScrolledPast(threshold) {
|
|
5488
|
-
const [scrolledPast, setScrolledPast] =
|
|
5489
|
-
|
|
5455
|
+
const [scrolledPast, setScrolledPast] = React21.useState(false);
|
|
5456
|
+
React21.useEffect(() => {
|
|
5490
5457
|
const handleScroll = () => {
|
|
5491
5458
|
setScrolledPast(window.scrollY > threshold);
|
|
5492
5459
|
};
|
|
@@ -5497,28 +5464,28 @@ function useScrolledPast(threshold) {
|
|
|
5497
5464
|
return scrolledPast;
|
|
5498
5465
|
}
|
|
5499
5466
|
function useCopyToClipboard() {
|
|
5500
|
-
const [copied, setCopied] =
|
|
5501
|
-
const timeoutRef =
|
|
5502
|
-
const copy =
|
|
5467
|
+
const [copied, setCopied] = React21.useState(false);
|
|
5468
|
+
const timeoutRef = React21.useRef(void 0);
|
|
5469
|
+
const copy = React21.useCallback((text) => {
|
|
5503
5470
|
navigator.clipboard.writeText(text).then(() => {
|
|
5504
5471
|
setCopied(true);
|
|
5505
5472
|
clearTimeout(timeoutRef.current);
|
|
5506
5473
|
timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
|
|
5507
5474
|
});
|
|
5508
5475
|
}, []);
|
|
5509
|
-
|
|
5476
|
+
React21.useEffect(() => () => clearTimeout(timeoutRef.current), []);
|
|
5510
5477
|
return [copied, copy];
|
|
5511
5478
|
}
|
|
5512
5479
|
function useDebounce(value, delay) {
|
|
5513
|
-
const [debounced, setDebounced] =
|
|
5514
|
-
|
|
5480
|
+
const [debounced, setDebounced] = React21.useState(value);
|
|
5481
|
+
React21.useEffect(() => {
|
|
5515
5482
|
const timer = setTimeout(() => setDebounced(value), delay);
|
|
5516
5483
|
return () => clearTimeout(timer);
|
|
5517
5484
|
}, [value, delay]);
|
|
5518
5485
|
return debounced;
|
|
5519
5486
|
}
|
|
5520
5487
|
function useLocalStorage(key, initialValue) {
|
|
5521
|
-
const [storedValue, setStoredValue] =
|
|
5488
|
+
const [storedValue, setStoredValue] = React21.useState(() => {
|
|
5522
5489
|
if (typeof window === "undefined") return initialValue;
|
|
5523
5490
|
try {
|
|
5524
5491
|
const item = window.localStorage.getItem(key);
|
|
@@ -5527,7 +5494,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
5527
5494
|
return initialValue;
|
|
5528
5495
|
}
|
|
5529
5496
|
});
|
|
5530
|
-
const setValue =
|
|
5497
|
+
const setValue = React21.useCallback(
|
|
5531
5498
|
(value) => {
|
|
5532
5499
|
try {
|
|
5533
5500
|
setStoredValue(value);
|
|
@@ -5549,11 +5516,11 @@ function useViewMode(key = "view-mode", fallback = "cards") {
|
|
|
5549
5516
|
return { view: mounted ? stored : fallback, setView: setStored, ready: mounted };
|
|
5550
5517
|
}
|
|
5551
5518
|
function useMediaQuery(query) {
|
|
5552
|
-
const [matches, setMatches] =
|
|
5519
|
+
const [matches, setMatches] = React21.useState(() => {
|
|
5553
5520
|
if (typeof window === "undefined") return false;
|
|
5554
5521
|
return window.matchMedia(query).matches;
|
|
5555
5522
|
});
|
|
5556
|
-
|
|
5523
|
+
React21.useEffect(() => {
|
|
5557
5524
|
if (typeof window === "undefined") return;
|
|
5558
5525
|
const mql = window.matchMedia(query);
|
|
5559
5526
|
setMatches(mql.matches);
|
|
@@ -5564,18 +5531,18 @@ function useMediaQuery(query) {
|
|
|
5564
5531
|
return matches;
|
|
5565
5532
|
}
|
|
5566
5533
|
function usePagination(total, pageSize) {
|
|
5567
|
-
const [page, setPage] =
|
|
5534
|
+
const [page, setPage] = React21.useState(1);
|
|
5568
5535
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
5569
5536
|
const offset = (page - 1) * pageSize;
|
|
5570
|
-
const goTo =
|
|
5537
|
+
const goTo = React21.useCallback(
|
|
5571
5538
|
(p) => setPage(Math.min(Math.max(1, p), totalPages)),
|
|
5572
5539
|
[totalPages]
|
|
5573
5540
|
);
|
|
5574
|
-
const next =
|
|
5575
|
-
const prev =
|
|
5541
|
+
const next = React21.useCallback(() => goTo(page + 1), [page, goTo]);
|
|
5542
|
+
const prev = React21.useCallback(() => goTo(page - 1), [page, goTo]);
|
|
5576
5543
|
return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
|
|
5577
5544
|
}
|
|
5578
5545
|
|
|
5579
|
-
export { ActivityFeed, AnimatedPill, AnimatedSwap, AppContent, AppGrid, AppGridCell, AppPageHero, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DataView, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, MediaCard, 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, UpdateBanner, UpgradePrompt, VersionBanner, ViewToggle, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode, useViewMode };
|
|
5546
|
+
export { ActivityFeed, AnimatedPill, AnimatedSwap, AppContent, AppGrid, AppGridCell, AppPageHero, AppScreen, AppShell, AuthSection, Badge, BillingPanel, BrandColorSwitchMinimal, Button, Card, Carousel, ChangelogCard, ChangelogList, Chart, Checkbox, CommandMenu, ComparisonSection, ConfirmDialog, ContactSection, ContextMenu, CountUp, CountdownTimer, CtaSection, DataTable, DataView, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeatureMarqueeSection, FeaturesSection, FileUpload, FlowBracket, FlowConnector, Footer, FullPageSpinner, GlassCard, Grid, GridItem, GroupedFeaturesSection, HeroSection, ImageCard, Input, LogoStrip, MarketingSurfaceProvider, MediaCard, 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, UpdateBanner, UpgradePrompt, VersionBanner, ViewToggle, marketingSectionSpacing, notify, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMarketingSurface, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useSectionSurface, useUIMode, useViewMode };
|
|
5580
5547
|
//# sourceMappingURL=index.js.map
|
|
5581
5548
|
//# sourceMappingURL=index.js.map
|