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