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