@geomak/ui 7.7.4 → 7.9.0
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.cjs +1270 -317
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +148 -1
- package/dist/index.d.ts +148 -1
- package/dist/index.js +975 -25
- package/dist/index.js.map +1 -1
- package/dist/styles.css +19 -0
- package/package.json +5 -2
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunk4V4U2W7K_cjs = require('./chunk-4V4U2W7K.cjs');
|
|
4
4
|
var chunkCNUDNGJM_cjs = require('./chunk-CNUDNGJM.cjs');
|
|
5
|
-
var
|
|
5
|
+
var React34 = require('react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
8
|
var AvatarPrimitive = require('@radix-ui/react-avatar');
|
|
@@ -41,7 +41,7 @@ function _interopNamespace(e) {
|
|
|
41
41
|
return Object.freeze(n);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
var
|
|
44
|
+
var React34__default = /*#__PURE__*/_interopDefault(React34);
|
|
45
45
|
var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
|
|
46
46
|
var DropdownMenu2__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu2);
|
|
47
47
|
var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
|
|
@@ -67,8 +67,8 @@ function cx(...values) {
|
|
|
67
67
|
return out;
|
|
68
68
|
}
|
|
69
69
|
function Portal({ children, target }) {
|
|
70
|
-
const [resolved, setResolved] =
|
|
71
|
-
|
|
70
|
+
const [resolved, setResolved] = React34.useState(null);
|
|
71
|
+
React34.useEffect(() => {
|
|
72
72
|
if (target === null) {
|
|
73
73
|
setResolved(null);
|
|
74
74
|
return;
|
|
@@ -489,7 +489,7 @@ function Typography({
|
|
|
489
489
|
}
|
|
490
490
|
);
|
|
491
491
|
}
|
|
492
|
-
var IconButton =
|
|
492
|
+
var IconButton = React34__default.default.forwardRef(function IconButton2({
|
|
493
493
|
icon,
|
|
494
494
|
onClick,
|
|
495
495
|
type = "primary",
|
|
@@ -502,7 +502,7 @@ var IconButton = React31__default.default.forwardRef(function IconButton2({
|
|
|
502
502
|
className = "",
|
|
503
503
|
style
|
|
504
504
|
}, ref) {
|
|
505
|
-
const colorScheme =
|
|
505
|
+
const colorScheme = React34.useMemo(() => {
|
|
506
506
|
if (type === "primary") {
|
|
507
507
|
return "bg-accent text-accent-fg hover:bg-accent-hover";
|
|
508
508
|
}
|
|
@@ -598,7 +598,7 @@ var SIZE_CLASSES = {
|
|
|
598
598
|
md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
|
|
599
599
|
lg: "h-11 px-5 text-sm gap-2 rounded-xl"
|
|
600
600
|
};
|
|
601
|
-
var Button =
|
|
601
|
+
var Button = React34__default.default.forwardRef(function Button2({
|
|
602
602
|
content,
|
|
603
603
|
variant = "primary",
|
|
604
604
|
size = "md",
|
|
@@ -706,7 +706,7 @@ function MenuButton({
|
|
|
706
706
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
707
707
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
708
708
|
].join(" "),
|
|
709
|
-
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
709
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React34__default.default.Fragment, { children: [
|
|
710
710
|
item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu2__namespace.Separator, { className: "my-1 h-px bg-border" }),
|
|
711
711
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
712
712
|
DropdownMenu2__namespace.Item,
|
|
@@ -955,9 +955,9 @@ function Tooltip({
|
|
|
955
955
|
] }) });
|
|
956
956
|
}
|
|
957
957
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
958
|
-
var TabsContext =
|
|
958
|
+
var TabsContext = React34.createContext(null);
|
|
959
959
|
function useTabsContext() {
|
|
960
|
-
const ctx =
|
|
960
|
+
const ctx = React34.useContext(TabsContext);
|
|
961
961
|
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
|
|
962
962
|
return ctx;
|
|
963
963
|
}
|
|
@@ -979,26 +979,26 @@ function Tabs({
|
|
|
979
979
|
children
|
|
980
980
|
}) {
|
|
981
981
|
const isControlled = value !== void 0;
|
|
982
|
-
const [internal, setInternal] =
|
|
982
|
+
const [internal, setInternal] = React34.useState(defaultValue);
|
|
983
983
|
const current = isControlled ? value : internal;
|
|
984
984
|
const reduced = !!framerMotion.useReducedMotion();
|
|
985
|
-
const indicatorId =
|
|
986
|
-
const select =
|
|
985
|
+
const indicatorId = React34.useId();
|
|
986
|
+
const select = React34.useCallback((next) => {
|
|
987
987
|
if (!isControlled) setInternal(next);
|
|
988
988
|
onChange?.(next);
|
|
989
989
|
}, [isControlled, onChange]);
|
|
990
|
-
const registry =
|
|
991
|
-
const orderRef =
|
|
992
|
-
const [, bump] =
|
|
993
|
-
const registerTab =
|
|
990
|
+
const registry = React34.useRef(/* @__PURE__ */ new Map());
|
|
991
|
+
const orderRef = React34.useRef(0);
|
|
992
|
+
const [, bump] = React34.useState(0);
|
|
993
|
+
const registerTab = React34.useCallback((val, meta) => {
|
|
994
994
|
const existing = registry.current.get(val);
|
|
995
995
|
registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
|
|
996
996
|
if (!existing) bump((v) => v + 1);
|
|
997
997
|
}, []);
|
|
998
|
-
const unregisterTab =
|
|
998
|
+
const unregisterTab = React34.useCallback((val) => {
|
|
999
999
|
if (registry.current.delete(val)) bump((v) => v + 1);
|
|
1000
1000
|
}, []);
|
|
1001
|
-
const getTabs =
|
|
1001
|
+
const getTabs = React34.useCallback(() => [...registry.current.entries()].sort((a, b) => a[1].order - b[1].order).map(([val, m]) => ({ value: val, label: m.label, icon: m.icon, disabled: m.disabled })), []);
|
|
1002
1002
|
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1003
1003
|
TabsPrimitive__namespace.Root,
|
|
1004
1004
|
{
|
|
@@ -1018,10 +1018,10 @@ function Tabs({
|
|
|
1018
1018
|
function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
1019
1019
|
const { variant, orientation, reduced, value } = useTabsContext();
|
|
1020
1020
|
const horizontal = orientation === "horizontal";
|
|
1021
|
-
const scrollRef =
|
|
1022
|
-
const [edges, setEdges] =
|
|
1021
|
+
const scrollRef = React34.useRef(null);
|
|
1022
|
+
const [edges, setEdges] = React34.useState({ start: false, end: false });
|
|
1023
1023
|
const scrollable = variant !== "segmented";
|
|
1024
|
-
|
|
1024
|
+
React34.useLayoutEffect(() => {
|
|
1025
1025
|
const el = scrollRef.current;
|
|
1026
1026
|
if (!el || !scrollable) return;
|
|
1027
1027
|
const update = () => {
|
|
@@ -1046,13 +1046,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
|
1046
1046
|
ro.disconnect();
|
|
1047
1047
|
};
|
|
1048
1048
|
}, [horizontal, scrollable, children]);
|
|
1049
|
-
const nudge =
|
|
1049
|
+
const nudge = React34.useCallback((dir) => {
|
|
1050
1050
|
const el = scrollRef.current;
|
|
1051
1051
|
if (!el) return;
|
|
1052
1052
|
const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
|
|
1053
1053
|
el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
|
|
1054
1054
|
}, [horizontal, reduced]);
|
|
1055
|
-
|
|
1055
|
+
React34.useLayoutEffect(() => {
|
|
1056
1056
|
const el = scrollRef.current;
|
|
1057
1057
|
if (!el || !scrollable) return;
|
|
1058
1058
|
const active = el.querySelector("[role=tab][data-state=active]");
|
|
@@ -1110,9 +1110,9 @@ function Chevron2({ side, orientation, onClick }) {
|
|
|
1110
1110
|
function OverflowMenu() {
|
|
1111
1111
|
const { getTabs, value, select, orientation } = useTabsContext();
|
|
1112
1112
|
const horizontal = orientation === "horizontal";
|
|
1113
|
-
const [open, setOpen] =
|
|
1114
|
-
const wrapRef =
|
|
1115
|
-
const timer =
|
|
1113
|
+
const [open, setOpen] = React34.useState(false);
|
|
1114
|
+
const wrapRef = React34.useRef(null);
|
|
1115
|
+
const timer = React34.useRef(null);
|
|
1116
1116
|
const openNow = () => {
|
|
1117
1117
|
if (timer.current) clearTimeout(timer.current);
|
|
1118
1118
|
setOpen(true);
|
|
@@ -1120,7 +1120,7 @@ function OverflowMenu() {
|
|
|
1120
1120
|
const closeSoon = () => {
|
|
1121
1121
|
timer.current = setTimeout(() => setOpen(false), 160);
|
|
1122
1122
|
};
|
|
1123
|
-
|
|
1123
|
+
React34.useLayoutEffect(() => {
|
|
1124
1124
|
if (!open) return;
|
|
1125
1125
|
const onDoc = (e) => {
|
|
1126
1126
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1201,7 +1201,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
|
|
|
1201
1201
|
const isActive = active === value;
|
|
1202
1202
|
const horizontal = orientation === "horizontal";
|
|
1203
1203
|
const sz = SIZE[size];
|
|
1204
|
-
|
|
1204
|
+
React34.useLayoutEffect(() => {
|
|
1205
1205
|
registerTab(value, { label: children, icon, disabled });
|
|
1206
1206
|
return () => unregisterTab(value);
|
|
1207
1207
|
}, [value, children, icon, disabled, registerTab, unregisterTab]);
|
|
@@ -1400,7 +1400,7 @@ function Tree({
|
|
|
1400
1400
|
item.key
|
|
1401
1401
|
)) });
|
|
1402
1402
|
}
|
|
1403
|
-
var AccordionCtx =
|
|
1403
|
+
var AccordionCtx = React34.createContext({ variant: "separated" });
|
|
1404
1404
|
function Accordion2({
|
|
1405
1405
|
children,
|
|
1406
1406
|
type = "single",
|
|
@@ -1459,7 +1459,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
1459
1459
|
}
|
|
1460
1460
|
);
|
|
1461
1461
|
function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
|
|
1462
|
-
const { variant } =
|
|
1462
|
+
const { variant } = React34.useContext(AccordionCtx);
|
|
1463
1463
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1464
1464
|
AccordionPrimitive__namespace.Item,
|
|
1465
1465
|
{
|
|
@@ -1518,7 +1518,7 @@ function Breadcrumbs({
|
|
|
1518
1518
|
className = "",
|
|
1519
1519
|
style
|
|
1520
1520
|
}) {
|
|
1521
|
-
const [expanded, setExpanded] =
|
|
1521
|
+
const [expanded, setExpanded] = React34.useState(false);
|
|
1522
1522
|
const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
|
|
1523
1523
|
const visible = [];
|
|
1524
1524
|
if (shouldCollapse) {
|
|
@@ -1743,8 +1743,8 @@ function Stepper({
|
|
|
1743
1743
|
className = ""
|
|
1744
1744
|
}) {
|
|
1745
1745
|
const reduced = framerMotion.useReducedMotion();
|
|
1746
|
-
const [forcedVertical, setForcedVertical] =
|
|
1747
|
-
|
|
1746
|
+
const [forcedVertical, setForcedVertical] = React34.useState(false);
|
|
1747
|
+
React34.useEffect(() => {
|
|
1748
1748
|
if (!responsive || orientation === "vertical") return;
|
|
1749
1749
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1750
1750
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
@@ -1853,7 +1853,7 @@ function Kbd({
|
|
|
1853
1853
|
style
|
|
1854
1854
|
}) {
|
|
1855
1855
|
if (keys && keys.length > 0) {
|
|
1856
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1856
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React34__default.default.Fragment, { children: [
|
|
1857
1857
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
|
|
1858
1858
|
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
|
|
1859
1859
|
] }, `${k}-${i}`)) });
|
|
@@ -1944,13 +1944,13 @@ function FlatCarousel({
|
|
|
1944
1944
|
className = "",
|
|
1945
1945
|
style
|
|
1946
1946
|
}) {
|
|
1947
|
-
const scrollerRef =
|
|
1948
|
-
const slides =
|
|
1949
|
-
const [active, setActive] =
|
|
1950
|
-
const [atStart, setAtStart] =
|
|
1951
|
-
const [atEnd, setAtEnd] =
|
|
1947
|
+
const scrollerRef = React34.useRef(null);
|
|
1948
|
+
const slides = React34__default.default.Children.toArray(children);
|
|
1949
|
+
const [active, setActive] = React34.useState(0);
|
|
1950
|
+
const [atStart, setAtStart] = React34.useState(true);
|
|
1951
|
+
const [atEnd, setAtEnd] = React34.useState(false);
|
|
1952
1952
|
const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
|
|
1953
|
-
const update =
|
|
1953
|
+
const update = React34.useCallback(() => {
|
|
1954
1954
|
const el = scrollerRef.current;
|
|
1955
1955
|
if (!el) return;
|
|
1956
1956
|
setAtStart(el.scrollLeft <= 1);
|
|
@@ -1959,7 +1959,7 @@ function FlatCarousel({
|
|
|
1959
1959
|
const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
|
|
1960
1960
|
setActive(Math.round(el.scrollLeft / slideW));
|
|
1961
1961
|
}, [gap]);
|
|
1962
|
-
|
|
1962
|
+
React34.useEffect(() => {
|
|
1963
1963
|
update();
|
|
1964
1964
|
const el = scrollerRef.current;
|
|
1965
1965
|
if (!el) return;
|
|
@@ -2000,9 +2000,9 @@ function RotatingCarousel({
|
|
|
2000
2000
|
className = "",
|
|
2001
2001
|
style
|
|
2002
2002
|
}) {
|
|
2003
|
-
const slides =
|
|
2003
|
+
const slides = React34__default.default.Children.toArray(children);
|
|
2004
2004
|
const count = slides.length;
|
|
2005
|
-
const [active, setActive] =
|
|
2005
|
+
const [active, setActive] = React34.useState(0);
|
|
2006
2006
|
const reduced = framerMotion.useReducedMotion();
|
|
2007
2007
|
const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
|
|
2008
2008
|
const idx = wrap(active);
|
|
@@ -2240,13 +2240,13 @@ function Chat({
|
|
|
2240
2240
|
className = "",
|
|
2241
2241
|
style
|
|
2242
2242
|
}) {
|
|
2243
|
-
const listRef =
|
|
2244
|
-
const atBottomRef =
|
|
2245
|
-
const [showJump, setShowJump] =
|
|
2246
|
-
const [draft, setDraft] =
|
|
2243
|
+
const listRef = React34.useRef(null);
|
|
2244
|
+
const atBottomRef = React34.useRef(true);
|
|
2245
|
+
const [showJump, setShowJump] = React34.useState(false);
|
|
2246
|
+
const [draft, setDraft] = React34.useState("");
|
|
2247
2247
|
const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
|
|
2248
2248
|
const isTyping = typingNames.length > 0;
|
|
2249
|
-
const scrollToBottom =
|
|
2249
|
+
const scrollToBottom = React34.useCallback((smooth = true) => {
|
|
2250
2250
|
const el = listRef.current;
|
|
2251
2251
|
if (!el) return;
|
|
2252
2252
|
if (typeof el.scrollTo === "function") el.scrollTo({ top: el.scrollHeight, behavior: smooth ? "smooth" : "auto" });
|
|
@@ -2259,10 +2259,10 @@ function Chat({
|
|
|
2259
2259
|
atBottomRef.current = near;
|
|
2260
2260
|
setShowJump(!near);
|
|
2261
2261
|
};
|
|
2262
|
-
|
|
2262
|
+
React34.useEffect(() => {
|
|
2263
2263
|
if (atBottomRef.current) scrollToBottom(messages.length > 0);
|
|
2264
2264
|
}, [messages.length, isTyping]);
|
|
2265
|
-
|
|
2265
|
+
React34.useEffect(() => {
|
|
2266
2266
|
scrollToBottom(false);
|
|
2267
2267
|
}, [scrollToBottom]);
|
|
2268
2268
|
const send = () => {
|
|
@@ -2452,7 +2452,7 @@ function FAB({
|
|
|
2452
2452
|
className = "",
|
|
2453
2453
|
style
|
|
2454
2454
|
}) {
|
|
2455
|
-
const [open, setOpen] =
|
|
2455
|
+
const [open, setOpen] = React34.useState(false);
|
|
2456
2456
|
const reduced = framerMotion.useReducedMotion();
|
|
2457
2457
|
const hasDial = !!actions && actions.length > 0;
|
|
2458
2458
|
const bottom = position.startsWith("bottom");
|
|
@@ -2554,8 +2554,8 @@ function PopConfirm({
|
|
|
2554
2554
|
onOpenChange,
|
|
2555
2555
|
className = ""
|
|
2556
2556
|
}) {
|
|
2557
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
2558
|
-
const [loading, setLoading] =
|
|
2557
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React34.useState(false);
|
|
2558
|
+
const [loading, setLoading] = React34.useState(false);
|
|
2559
2559
|
const isOpen = open ?? uncontrolledOpen;
|
|
2560
2560
|
const setOpen = (next) => {
|
|
2561
2561
|
onOpenChange?.(next);
|
|
@@ -2658,16 +2658,16 @@ function LogoutTimer({
|
|
|
2658
2658
|
logoutLabel = "Sign out now"
|
|
2659
2659
|
}) {
|
|
2660
2660
|
const reduced = framerMotion.useReducedMotion();
|
|
2661
|
-
const [warning, setWarning] =
|
|
2662
|
-
const [remaining, setRemaining] =
|
|
2663
|
-
const idleTimer =
|
|
2664
|
-
const tick =
|
|
2665
|
-
const deadline =
|
|
2666
|
-
const warningRef =
|
|
2667
|
-
const lastReset =
|
|
2668
|
-
const cbs =
|
|
2661
|
+
const [warning, setWarning] = React34.useState(false);
|
|
2662
|
+
const [remaining, setRemaining] = React34.useState(countdown);
|
|
2663
|
+
const idleTimer = React34.useRef(null);
|
|
2664
|
+
const tick = React34.useRef(null);
|
|
2665
|
+
const deadline = React34.useRef(0);
|
|
2666
|
+
const warningRef = React34.useRef(false);
|
|
2667
|
+
const lastReset = React34.useRef(0);
|
|
2668
|
+
const cbs = React34.useRef({ onLogout, onContinue, onWarning });
|
|
2669
2669
|
cbs.current = { onLogout, onContinue, onWarning };
|
|
2670
|
-
const clearTimers =
|
|
2670
|
+
const clearTimers = React34.useCallback(() => {
|
|
2671
2671
|
if (idleTimer.current) {
|
|
2672
2672
|
clearTimeout(idleTimer.current);
|
|
2673
2673
|
idleTimer.current = null;
|
|
@@ -2677,13 +2677,13 @@ function LogoutTimer({
|
|
|
2677
2677
|
tick.current = null;
|
|
2678
2678
|
}
|
|
2679
2679
|
}, []);
|
|
2680
|
-
const logout =
|
|
2680
|
+
const logout = React34.useCallback(() => {
|
|
2681
2681
|
clearTimers();
|
|
2682
2682
|
warningRef.current = false;
|
|
2683
2683
|
setWarning(false);
|
|
2684
2684
|
cbs.current.onLogout();
|
|
2685
2685
|
}, [clearTimers]);
|
|
2686
|
-
const startIdle =
|
|
2686
|
+
const startIdle = React34.useCallback(() => {
|
|
2687
2687
|
if (idleTimer.current) clearTimeout(idleTimer.current);
|
|
2688
2688
|
idleTimer.current = setTimeout(() => {
|
|
2689
2689
|
warningRef.current = true;
|
|
@@ -2698,7 +2698,7 @@ function LogoutTimer({
|
|
|
2698
2698
|
}, 250);
|
|
2699
2699
|
}, timeout);
|
|
2700
2700
|
}, [timeout, countdown, logout]);
|
|
2701
|
-
const stay =
|
|
2701
|
+
const stay = React34.useCallback(() => {
|
|
2702
2702
|
if (tick.current) {
|
|
2703
2703
|
clearInterval(tick.current);
|
|
2704
2704
|
tick.current = null;
|
|
@@ -2708,7 +2708,7 @@ function LogoutTimer({
|
|
|
2708
2708
|
cbs.current.onContinue?.();
|
|
2709
2709
|
startIdle();
|
|
2710
2710
|
}, [startIdle]);
|
|
2711
|
-
|
|
2711
|
+
React34.useEffect(() => {
|
|
2712
2712
|
if (!enabled) {
|
|
2713
2713
|
clearTimers();
|
|
2714
2714
|
warningRef.current = false;
|
|
@@ -2773,11 +2773,11 @@ function SegmentedControl({
|
|
|
2773
2773
|
"aria-label": ariaLabel
|
|
2774
2774
|
}) {
|
|
2775
2775
|
const sz = SIZE5[size];
|
|
2776
|
-
const groupId =
|
|
2777
|
-
const errorId =
|
|
2776
|
+
const groupId = React34.useId();
|
|
2777
|
+
const errorId = React34.useId();
|
|
2778
2778
|
const hasError = errorMessage != null;
|
|
2779
2779
|
const isControlled = value !== void 0;
|
|
2780
|
-
const [internal, setInternal] =
|
|
2780
|
+
const [internal, setInternal] = React34.useState(defaultValue);
|
|
2781
2781
|
const current = isControlled ? value : internal;
|
|
2782
2782
|
const handle = (v) => {
|
|
2783
2783
|
if (!v) return;
|
|
@@ -2938,22 +2938,22 @@ function Scheduler({
|
|
|
2938
2938
|
style
|
|
2939
2939
|
}) {
|
|
2940
2940
|
const reduced = framerMotion.useReducedMotion();
|
|
2941
|
-
const [view, setView] =
|
|
2942
|
-
const [cursor, setCursor] =
|
|
2943
|
-
const [loaded, setLoaded] =
|
|
2944
|
-
const [loading, setLoading] =
|
|
2945
|
-
const [error, setError] =
|
|
2946
|
-
const [reloadKey, setReloadKey] =
|
|
2947
|
-
const [dir, setDir] =
|
|
2948
|
-
const cbRef =
|
|
2941
|
+
const [view, setView] = React34.useState(defaultView);
|
|
2942
|
+
const [cursor, setCursor] = React34.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
2943
|
+
const [loaded, setLoaded] = React34.useState([]);
|
|
2944
|
+
const [loading, setLoading] = React34.useState(false);
|
|
2945
|
+
const [error, setError] = React34.useState(null);
|
|
2946
|
+
const [reloadKey, setReloadKey] = React34.useState(0);
|
|
2947
|
+
const [dir, setDir] = React34.useState(0);
|
|
2948
|
+
const cbRef = React34.useRef({ loadEvents, onError });
|
|
2949
2949
|
cbRef.current = { loadEvents, onError };
|
|
2950
|
-
const range =
|
|
2950
|
+
const range = React34.useMemo(
|
|
2951
2951
|
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2952
2952
|
[view, cursor, weekStartsOn]
|
|
2953
2953
|
);
|
|
2954
2954
|
const fromKey = range.from.getTime();
|
|
2955
2955
|
const toKey = range.to.getTime();
|
|
2956
|
-
|
|
2956
|
+
React34.useEffect(() => {
|
|
2957
2957
|
const { loadEvents: loader, onError: onErr } = cbRef.current;
|
|
2958
2958
|
if (!loader) return;
|
|
2959
2959
|
let cancelled = false;
|
|
@@ -2973,16 +2973,16 @@ function Scheduler({
|
|
|
2973
2973
|
cancelled = true;
|
|
2974
2974
|
};
|
|
2975
2975
|
}, [fromKey, toKey, view, reloadKey]);
|
|
2976
|
-
const retry =
|
|
2977
|
-
const events =
|
|
2976
|
+
const retry = React34.useCallback(() => setReloadKey((k) => k + 1), []);
|
|
2977
|
+
const events = React34.useMemo(
|
|
2978
2978
|
() => (controlledEvents ?? loaded).map(normalize),
|
|
2979
2979
|
[controlledEvents, loaded]
|
|
2980
2980
|
);
|
|
2981
|
-
const go =
|
|
2981
|
+
const go = React34.useCallback((delta) => {
|
|
2982
2982
|
setDir(delta);
|
|
2983
2983
|
setCursor((c) => view === "month" ? addMonths(c, delta) : addDays(c, delta * 7));
|
|
2984
2984
|
}, [view]);
|
|
2985
|
-
const goToday =
|
|
2985
|
+
const goToday = React34.useCallback(() => {
|
|
2986
2986
|
setDir(0);
|
|
2987
2987
|
setCursor(/* @__PURE__ */ new Date());
|
|
2988
2988
|
}, []);
|
|
@@ -3092,9 +3092,9 @@ function SchedulerError({ onRetry }) {
|
|
|
3092
3092
|
] });
|
|
3093
3093
|
}
|
|
3094
3094
|
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3095
|
-
const [open, setOpen] =
|
|
3096
|
-
const [viewYear, setViewYear] =
|
|
3097
|
-
|
|
3095
|
+
const [open, setOpen] = React34.useState(false);
|
|
3096
|
+
const [viewYear, setViewYear] = React34.useState(cursor.getFullYear());
|
|
3097
|
+
React34.useEffect(() => {
|
|
3098
3098
|
if (open) setViewYear(cursor.getFullYear());
|
|
3099
3099
|
}, [open, cursor]);
|
|
3100
3100
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open, onOpenChange: setOpen, children: [
|
|
@@ -3168,8 +3168,8 @@ function MonthView({
|
|
|
3168
3168
|
onSelectSlot,
|
|
3169
3169
|
onSelectEvent
|
|
3170
3170
|
}) {
|
|
3171
|
-
const grid =
|
|
3172
|
-
const eventsByDay =
|
|
3171
|
+
const grid = React34.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3172
|
+
const eventsByDay = React34.useMemo(() => bucketByDay(events), [events]);
|
|
3173
3173
|
const labels = weekdayLabels(weekStartsOn);
|
|
3174
3174
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3175
3175
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 border-b border-border", children: labels.map((l) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-center text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: l }, l)) }),
|
|
@@ -3243,12 +3243,12 @@ function WeekView({
|
|
|
3243
3243
|
onSelectSlot,
|
|
3244
3244
|
onSelectEvent
|
|
3245
3245
|
}) {
|
|
3246
|
-
const days =
|
|
3247
|
-
const eventsByDay =
|
|
3248
|
-
const labels =
|
|
3246
|
+
const days = React34.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3247
|
+
const eventsByDay = React34.useMemo(() => bucketByDay(events), [events]);
|
|
3248
|
+
const labels = React34.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
|
|
3249
3249
|
const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
|
|
3250
3250
|
const [startHour, endHour] = dayHours;
|
|
3251
|
-
const hours =
|
|
3251
|
+
const hours = React34.useMemo(
|
|
3252
3252
|
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3253
3253
|
[startHour, endHour]
|
|
3254
3254
|
);
|
|
@@ -3439,17 +3439,17 @@ function Cart({
|
|
|
3439
3439
|
] })
|
|
3440
3440
|
] });
|
|
3441
3441
|
}
|
|
3442
|
-
var CartContext =
|
|
3442
|
+
var CartContext = React34.createContext(null);
|
|
3443
3443
|
var clampQty = (qty, max) => {
|
|
3444
3444
|
const lower = Math.max(1, Math.round(qty));
|
|
3445
3445
|
return max != null ? Math.min(lower, max) : lower;
|
|
3446
3446
|
};
|
|
3447
3447
|
function CartProvider({ children, initialItems = [], onChange }) {
|
|
3448
|
-
const [items, setItems] =
|
|
3449
|
-
|
|
3448
|
+
const [items, setItems] = React34.useState(initialItems);
|
|
3449
|
+
React34.useEffect(() => {
|
|
3450
3450
|
onChange?.(items);
|
|
3451
3451
|
}, [items]);
|
|
3452
|
-
const addToCart =
|
|
3452
|
+
const addToCart = React34.useCallback((item, quantity) => {
|
|
3453
3453
|
const addQty = quantity ?? item.quantity ?? 1;
|
|
3454
3454
|
setItems((prev) => {
|
|
3455
3455
|
const existing = prev.find((it) => it.id === item.id);
|
|
@@ -3462,29 +3462,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
|
|
|
3462
3462
|
return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
|
|
3463
3463
|
});
|
|
3464
3464
|
}, []);
|
|
3465
|
-
const removeFromCart =
|
|
3465
|
+
const removeFromCart = React34.useCallback((id) => {
|
|
3466
3466
|
setItems((prev) => prev.filter((it) => it.id !== id));
|
|
3467
3467
|
}, []);
|
|
3468
|
-
const updateQuantity =
|
|
3468
|
+
const updateQuantity = React34.useCallback((id, quantity) => {
|
|
3469
3469
|
setItems(
|
|
3470
3470
|
(prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
|
|
3471
3471
|
);
|
|
3472
3472
|
}, []);
|
|
3473
|
-
const clearCart =
|
|
3474
|
-
const isInCart =
|
|
3475
|
-
const getItemCount =
|
|
3476
|
-
const getCartTotal =
|
|
3473
|
+
const clearCart = React34.useCallback(() => setItems([]), []);
|
|
3474
|
+
const isInCart = React34.useCallback((id) => items.some((it) => it.id === id), [items]);
|
|
3475
|
+
const getItemCount = React34.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
|
|
3476
|
+
const getCartTotal = React34.useCallback(
|
|
3477
3477
|
() => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
|
|
3478
3478
|
[items]
|
|
3479
3479
|
);
|
|
3480
|
-
const value =
|
|
3480
|
+
const value = React34.useMemo(
|
|
3481
3481
|
() => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
|
|
3482
3482
|
[items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
|
|
3483
3483
|
);
|
|
3484
3484
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
3485
3485
|
}
|
|
3486
3486
|
function useCart() {
|
|
3487
|
-
const ctx =
|
|
3487
|
+
const ctx = React34.useContext(CartContext);
|
|
3488
3488
|
if (!ctx) {
|
|
3489
3489
|
throw new Error("useCart must be used within a <CartProvider>.");
|
|
3490
3490
|
}
|
|
@@ -3826,11 +3826,11 @@ function buildBindings(store, name, kind, snap) {
|
|
|
3826
3826
|
|
|
3827
3827
|
// src/form/useForm.ts
|
|
3828
3828
|
function useForm(options = {}) {
|
|
3829
|
-
const ref =
|
|
3829
|
+
const ref = React34.useRef(null);
|
|
3830
3830
|
if (ref.current === null) ref.current = new FormStore(options);
|
|
3831
3831
|
const store = ref.current;
|
|
3832
|
-
|
|
3833
|
-
const make =
|
|
3832
|
+
React34.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3833
|
+
const make = React34.useCallback(
|
|
3834
3834
|
(kind) => (name, rules) => {
|
|
3835
3835
|
if (rules !== void 0) store.setRule(name, rules);
|
|
3836
3836
|
return buildBindings(store, name, kind, store.getFieldSnapshot(name));
|
|
@@ -3860,9 +3860,9 @@ function useForm(options = {}) {
|
|
|
3860
3860
|
fieldTarget: make("target")
|
|
3861
3861
|
};
|
|
3862
3862
|
}
|
|
3863
|
-
var FormContext =
|
|
3863
|
+
var FormContext = React34.createContext(null);
|
|
3864
3864
|
function useFormStore() {
|
|
3865
|
-
const store =
|
|
3865
|
+
const store = React34.useContext(FormContext);
|
|
3866
3866
|
if (!store) {
|
|
3867
3867
|
throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
|
|
3868
3868
|
}
|
|
@@ -3876,8 +3876,8 @@ function Form({
|
|
|
3876
3876
|
children,
|
|
3877
3877
|
...rest
|
|
3878
3878
|
}) {
|
|
3879
|
-
const ref =
|
|
3880
|
-
const bypass =
|
|
3879
|
+
const ref = React34.useRef(null);
|
|
3880
|
+
const bypass = React34.useRef(false);
|
|
3881
3881
|
const handleSubmit = async (e) => {
|
|
3882
3882
|
if (bypass.current) {
|
|
3883
3883
|
bypass.current = false;
|
|
@@ -3934,12 +3934,12 @@ function useFormField(name, options = {}) {
|
|
|
3934
3934
|
const store = useFormStore();
|
|
3935
3935
|
const { kind = "value", rules } = options;
|
|
3936
3936
|
if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
|
|
3937
|
-
|
|
3937
|
+
React34.useEffect(() => {
|
|
3938
3938
|
return () => {
|
|
3939
3939
|
if (rules !== void 0) store.removeRule(name);
|
|
3940
3940
|
};
|
|
3941
3941
|
}, [store, name]);
|
|
3942
|
-
const snap =
|
|
3942
|
+
const snap = React34.useSyncExternalStore(
|
|
3943
3943
|
store.subscribe,
|
|
3944
3944
|
() => store.getFieldSnapshot(name)
|
|
3945
3945
|
);
|
|
@@ -3951,7 +3951,7 @@ function FormField({ name, kind, rules, children }) {
|
|
|
3951
3951
|
}
|
|
3952
3952
|
function useFieldArray(name) {
|
|
3953
3953
|
const store = useFormStore();
|
|
3954
|
-
|
|
3954
|
+
React34.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3955
3955
|
const arr = store.getValue(name) ?? [];
|
|
3956
3956
|
const keys = store.getKeys(name);
|
|
3957
3957
|
return {
|
|
@@ -3984,7 +3984,7 @@ function TextInput({
|
|
|
3984
3984
|
suffix,
|
|
3985
3985
|
id
|
|
3986
3986
|
}) {
|
|
3987
|
-
const errorId =
|
|
3987
|
+
const errorId = React34.useId();
|
|
3988
3988
|
const hasError = errorMessage != null;
|
|
3989
3989
|
const hasAdornment = prefix != null || suffix != null;
|
|
3990
3990
|
const inputId = htmlFor ?? id;
|
|
@@ -4145,7 +4145,7 @@ function CreditCardForm({
|
|
|
4145
4145
|
className = "",
|
|
4146
4146
|
style
|
|
4147
4147
|
}) {
|
|
4148
|
-
const initial =
|
|
4148
|
+
const initial = React34.useRef({
|
|
4149
4149
|
number: formatCardNumber(defaultValue?.number ?? ""),
|
|
4150
4150
|
name: defaultValue?.name ?? "",
|
|
4151
4151
|
expiry: formatExpiry(defaultValue?.expiry ?? ""),
|
|
@@ -4154,7 +4154,7 @@ function CreditCardForm({
|
|
|
4154
4154
|
const form = useForm({ initialValues: initial });
|
|
4155
4155
|
const numberStr = String(form.values.number ?? "");
|
|
4156
4156
|
const brand = detectBrand(numberStr);
|
|
4157
|
-
|
|
4157
|
+
React34.useEffect(() => {
|
|
4158
4158
|
onChange?.(toCard(form.values));
|
|
4159
4159
|
}, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
|
|
4160
4160
|
const numberBind = form.fieldNative("number", {
|
|
@@ -4277,7 +4277,7 @@ function Checkout({
|
|
|
4277
4277
|
] })
|
|
4278
4278
|
] });
|
|
4279
4279
|
}
|
|
4280
|
-
var NotificationContext =
|
|
4280
|
+
var NotificationContext = React34.createContext({
|
|
4281
4281
|
open: () => void 0,
|
|
4282
4282
|
close: () => void 0
|
|
4283
4283
|
});
|
|
@@ -4335,26 +4335,26 @@ function NotificationItem({
|
|
|
4335
4335
|
onClose,
|
|
4336
4336
|
reduced
|
|
4337
4337
|
}) {
|
|
4338
|
-
const [paused, setPaused] =
|
|
4338
|
+
const [paused, setPaused] = React34.useState(false);
|
|
4339
4339
|
const duration = n.duration ?? 4e3;
|
|
4340
4340
|
const isAutoDismissing = isFinite(duration) && duration > 0;
|
|
4341
4341
|
const showProgress = !reduced && isAutoDismissing;
|
|
4342
|
-
const timerRef =
|
|
4343
|
-
const startTimeRef =
|
|
4344
|
-
const remainingRef =
|
|
4345
|
-
const clearTimer =
|
|
4342
|
+
const timerRef = React34.useRef(null);
|
|
4343
|
+
const startTimeRef = React34.useRef(0);
|
|
4344
|
+
const remainingRef = React34.useRef(duration);
|
|
4345
|
+
const clearTimer = React34.useCallback(() => {
|
|
4346
4346
|
if (timerRef.current !== null) {
|
|
4347
4347
|
clearTimeout(timerRef.current);
|
|
4348
4348
|
timerRef.current = null;
|
|
4349
4349
|
}
|
|
4350
4350
|
}, []);
|
|
4351
|
-
const scheduleDismiss =
|
|
4351
|
+
const scheduleDismiss = React34.useCallback((ms) => {
|
|
4352
4352
|
clearTimer();
|
|
4353
4353
|
if (!isAutoDismissing) return;
|
|
4354
4354
|
startTimeRef.current = Date.now();
|
|
4355
4355
|
timerRef.current = setTimeout(() => onClose(n.id), ms);
|
|
4356
4356
|
}, [clearTimer, isAutoDismissing, n.id, onClose]);
|
|
4357
|
-
|
|
4357
|
+
React34.useEffect(() => {
|
|
4358
4358
|
if (paused || !isAutoDismissing) return;
|
|
4359
4359
|
scheduleDismiss(remainingRef.current);
|
|
4360
4360
|
return clearTimer;
|
|
@@ -4437,15 +4437,15 @@ function NotificationProvider({
|
|
|
4437
4437
|
children,
|
|
4438
4438
|
position = "top-right"
|
|
4439
4439
|
}) {
|
|
4440
|
-
const [notifications, setNotifications] =
|
|
4440
|
+
const [notifications, setNotifications] = React34.useState([]);
|
|
4441
4441
|
const reduced = framerMotion.useReducedMotion();
|
|
4442
|
-
const open =
|
|
4442
|
+
const open = React34.useCallback((payload) => {
|
|
4443
4443
|
setNotifications((prev) => [
|
|
4444
4444
|
...prev,
|
|
4445
4445
|
{ duration: 4e3, ...payload, id: Date.now() + Math.random() }
|
|
4446
4446
|
]);
|
|
4447
4447
|
}, []);
|
|
4448
|
-
const close =
|
|
4448
|
+
const close = React34.useCallback((id) => {
|
|
4449
4449
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
4450
4450
|
}, []);
|
|
4451
4451
|
return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
|
|
@@ -4474,7 +4474,7 @@ function NotificationProvider({
|
|
|
4474
4474
|
] });
|
|
4475
4475
|
}
|
|
4476
4476
|
function useNotification() {
|
|
4477
|
-
const { open } =
|
|
4477
|
+
const { open } = React34.useContext(NotificationContext);
|
|
4478
4478
|
return {
|
|
4479
4479
|
info: (props) => open({ type: "info", ...props }),
|
|
4480
4480
|
success: (props) => open({ type: "success", ...props }),
|
|
@@ -4591,10 +4591,10 @@ function FadingBase({
|
|
|
4591
4591
|
isMounted = false,
|
|
4592
4592
|
children
|
|
4593
4593
|
}) {
|
|
4594
|
-
const [shouldRender, setShouldRender] =
|
|
4595
|
-
const [visible, setVisible] =
|
|
4596
|
-
const timerRef =
|
|
4597
|
-
|
|
4594
|
+
const [shouldRender, setShouldRender] = React34.useState(isMounted);
|
|
4595
|
+
const [visible, setVisible] = React34.useState(false);
|
|
4596
|
+
const timerRef = React34.useRef(null);
|
|
4597
|
+
React34.useEffect(() => {
|
|
4598
4598
|
if (isMounted) {
|
|
4599
4599
|
setShouldRender(true);
|
|
4600
4600
|
const rafId = requestAnimationFrame(() => setVisible(true));
|
|
@@ -4706,14 +4706,14 @@ function ScalableContainer({
|
|
|
4706
4706
|
togglePosition = "top-right",
|
|
4707
4707
|
className = ""
|
|
4708
4708
|
}) {
|
|
4709
|
-
const containerRef =
|
|
4710
|
-
const [internalScaled, setInternalScaled] =
|
|
4709
|
+
const containerRef = React34.useRef(null);
|
|
4710
|
+
const [internalScaled, setInternalScaled] = React34.useState(false);
|
|
4711
4711
|
const isScaled = expanded ?? internalScaled;
|
|
4712
4712
|
const reduced = framerMotion.useReducedMotion();
|
|
4713
|
-
const prevScaled =
|
|
4713
|
+
const prevScaled = React34.useRef(isScaled);
|
|
4714
4714
|
const expandW = targetWidth ?? expandedWidth;
|
|
4715
4715
|
const expandH = targetHeight ?? expandedHeight;
|
|
4716
|
-
|
|
4716
|
+
React34.useEffect(() => {
|
|
4717
4717
|
if (isScaled === prevScaled.current) return;
|
|
4718
4718
|
prevScaled.current = isScaled;
|
|
4719
4719
|
if (typeof window === "undefined") return;
|
|
@@ -4860,17 +4860,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
|
|
|
4860
4860
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap gap-2 ${className}`.trim(), children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(GridCard, { item, buttonText, onOpen }, item.key)) });
|
|
4861
4861
|
}
|
|
4862
4862
|
function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
|
|
4863
|
-
const [activeIndex, setActiveIndex] =
|
|
4864
|
-
const [indexPool, setIndexPool] =
|
|
4865
|
-
const cardRefs =
|
|
4866
|
-
const getIndexes =
|
|
4863
|
+
const [activeIndex, setActiveIndex] = React34.useState(0);
|
|
4864
|
+
const [indexPool, setIndexPool] = React34.useState([]);
|
|
4865
|
+
const cardRefs = React34.useRef([]);
|
|
4866
|
+
const getIndexes = React34.useMemo(() => {
|
|
4867
4867
|
let nextIndex = activeIndex + 1;
|
|
4868
4868
|
let previousIndex = activeIndex - 1;
|
|
4869
4869
|
if (activeIndex === 0) previousIndex = items.length - 1;
|
|
4870
4870
|
if (activeIndex === items.length - 1) nextIndex = 0;
|
|
4871
4871
|
return { previousIndex, nextIndex };
|
|
4872
4872
|
}, [activeIndex, items.length]);
|
|
4873
|
-
|
|
4873
|
+
React34.useEffect(() => {
|
|
4874
4874
|
const { nextIndex, previousIndex } = getIndexes;
|
|
4875
4875
|
let indexes = [previousIndex, activeIndex, nextIndex];
|
|
4876
4876
|
if (activeIndex !== 0 && activeIndex !== items.length - 1) {
|
|
@@ -5043,8 +5043,8 @@ function writeDismissed(key) {
|
|
|
5043
5043
|
}
|
|
5044
5044
|
}
|
|
5045
5045
|
function useTargetBbox(ref) {
|
|
5046
|
-
const [bbox, setBbox] =
|
|
5047
|
-
|
|
5046
|
+
const [bbox, setBbox] = React34.useState(null);
|
|
5047
|
+
React34.useLayoutEffect(() => {
|
|
5048
5048
|
const el = ref?.current;
|
|
5049
5049
|
if (!el) {
|
|
5050
5050
|
setBbox(null);
|
|
@@ -5074,7 +5074,7 @@ function tooltipStyleFor(bbox, placement) {
|
|
|
5074
5074
|
return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
|
|
5075
5075
|
}
|
|
5076
5076
|
function useFocusTrap(containerRef, active) {
|
|
5077
|
-
|
|
5077
|
+
React34.useEffect(() => {
|
|
5078
5078
|
if (!active) return;
|
|
5079
5079
|
const el = containerRef.current;
|
|
5080
5080
|
if (!el) return;
|
|
@@ -5113,16 +5113,16 @@ function Wizard({
|
|
|
5113
5113
|
onComplete,
|
|
5114
5114
|
onSkip
|
|
5115
5115
|
}) {
|
|
5116
|
-
const tooltipRef =
|
|
5117
|
-
const tooltipTitleId =
|
|
5118
|
-
const tooltipBodyId =
|
|
5116
|
+
const tooltipRef = React34.useRef(null);
|
|
5117
|
+
const tooltipTitleId = React34.useId();
|
|
5118
|
+
const tooltipBodyId = React34.useId();
|
|
5119
5119
|
const reduced = framerMotion.useReducedMotion();
|
|
5120
|
-
const [open, setOpen] =
|
|
5121
|
-
const [activeIndex, setActiveIndex] =
|
|
5120
|
+
const [open, setOpen] = React34.useState(() => steps.length > 0 && !readDismissed(storageKey));
|
|
5121
|
+
const [activeIndex, setActiveIndex] = React34.useState(0);
|
|
5122
5122
|
const step = steps[activeIndex];
|
|
5123
5123
|
const bbox = useTargetBbox(step?.stepRef);
|
|
5124
5124
|
useFocusTrap(tooltipRef, open);
|
|
5125
|
-
|
|
5125
|
+
React34.useEffect(() => {
|
|
5126
5126
|
if (!open || !dismissible) return;
|
|
5127
5127
|
const onKey = (e) => {
|
|
5128
5128
|
if (e.key === "Escape") {
|
|
@@ -5133,12 +5133,12 @@ function Wizard({
|
|
|
5133
5133
|
document.addEventListener("keydown", onKey);
|
|
5134
5134
|
return () => document.removeEventListener("keydown", onKey);
|
|
5135
5135
|
}, [open, dismissible]);
|
|
5136
|
-
const handleSkip =
|
|
5136
|
+
const handleSkip = React34.useCallback(() => {
|
|
5137
5137
|
writeDismissed(storageKey);
|
|
5138
5138
|
setOpen(false);
|
|
5139
5139
|
onSkip?.();
|
|
5140
5140
|
}, [storageKey, onSkip]);
|
|
5141
|
-
const handleComplete =
|
|
5141
|
+
const handleComplete = React34.useCallback(() => {
|
|
5142
5142
|
writeDismissed(storageKey);
|
|
5143
5143
|
setOpen(false);
|
|
5144
5144
|
onComplete?.();
|
|
@@ -5281,7 +5281,7 @@ function Wizard({
|
|
|
5281
5281
|
] });
|
|
5282
5282
|
}
|
|
5283
5283
|
var SearchIcon = /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) });
|
|
5284
|
-
var SearchInput =
|
|
5284
|
+
var SearchInput = React34__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
|
|
5285
5285
|
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5286
5286
|
"div",
|
|
5287
5287
|
{
|
|
@@ -5516,15 +5516,15 @@ function EditableCell({
|
|
|
5516
5516
|
rowIndex,
|
|
5517
5517
|
onCellEdit
|
|
5518
5518
|
}) {
|
|
5519
|
-
const [editing, setEditing] =
|
|
5520
|
-
const editRef =
|
|
5519
|
+
const [editing, setEditing] = React34.useState(false);
|
|
5520
|
+
const editRef = React34.useRef(null);
|
|
5521
5521
|
const value = row[col.keyBind];
|
|
5522
5522
|
const commit = (next) => {
|
|
5523
5523
|
setEditing(false);
|
|
5524
5524
|
onCellEdit?.({ row, key: col.keyBind, value: next, rowIndex });
|
|
5525
5525
|
};
|
|
5526
5526
|
const cancel = () => setEditing(false);
|
|
5527
|
-
|
|
5527
|
+
React34.useEffect(() => {
|
|
5528
5528
|
if (!editing || !col.editor) return;
|
|
5529
5529
|
const onMouseDown = (e) => {
|
|
5530
5530
|
const target = e.target;
|
|
@@ -5583,7 +5583,7 @@ function TableBody({
|
|
|
5583
5583
|
getRowKey,
|
|
5584
5584
|
onCellEdit
|
|
5585
5585
|
}) {
|
|
5586
|
-
const [expanded, setExpanded] =
|
|
5586
|
+
const [expanded, setExpanded] = React34.useState(() => /* @__PURE__ */ new Set());
|
|
5587
5587
|
const reduced = framerMotion.useReducedMotion();
|
|
5588
5588
|
const toggleRow = (rowKey) => {
|
|
5589
5589
|
setExpanded((prev) => {
|
|
@@ -5598,7 +5598,7 @@ function TableBody({
|
|
|
5598
5598
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
|
|
5599
5599
|
const rowKey = getRowKey(row, i);
|
|
5600
5600
|
const isExpanded = expanded.has(rowKey);
|
|
5601
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5601
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React34__default.default.Fragment, { children: [
|
|
5602
5602
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5603
5603
|
"tr",
|
|
5604
5604
|
{
|
|
@@ -5710,13 +5710,13 @@ function Table({
|
|
|
5710
5710
|
className = "",
|
|
5711
5711
|
style
|
|
5712
5712
|
}) {
|
|
5713
|
-
const searchRef =
|
|
5714
|
-
const [searchTerm, setSearchTerm] =
|
|
5715
|
-
const [perPage, setPerPage] =
|
|
5713
|
+
const searchRef = React34.useRef(null);
|
|
5714
|
+
const [searchTerm, setSearchTerm] = React34.useState("");
|
|
5715
|
+
const [perPage, setPerPage] = React34.useState(
|
|
5716
5716
|
typeof pagination.perPage === "number" ? pagination.perPage : 15
|
|
5717
5717
|
);
|
|
5718
|
-
const [activePage, setActivePage] =
|
|
5719
|
-
const [sortState, setSortState] =
|
|
5718
|
+
const [activePage, setActivePage] = React34.useState(0);
|
|
5719
|
+
const [sortState, setSortState] = React34.useState(defaultSort);
|
|
5720
5720
|
const isServerSide = !!(pagination.enabled && pagination.serverSide);
|
|
5721
5721
|
const handleSort = (col) => {
|
|
5722
5722
|
const key = col.keyBind;
|
|
@@ -5728,8 +5728,8 @@ function Table({
|
|
|
5728
5728
|
onSortChange?.(next);
|
|
5729
5729
|
};
|
|
5730
5730
|
const debounceMs = search?.debounceMs ?? 0;
|
|
5731
|
-
const [debouncedTerm, setDebouncedTerm] =
|
|
5732
|
-
|
|
5731
|
+
const [debouncedTerm, setDebouncedTerm] = React34.useState("");
|
|
5732
|
+
React34.useEffect(() => {
|
|
5733
5733
|
if (debounceMs <= 0) {
|
|
5734
5734
|
setDebouncedTerm(searchTerm);
|
|
5735
5735
|
return;
|
|
@@ -5738,7 +5738,7 @@ function Table({
|
|
|
5738
5738
|
return () => clearTimeout(t);
|
|
5739
5739
|
}, [searchTerm, debounceMs]);
|
|
5740
5740
|
const term = debounceMs > 0 ? debouncedTerm : searchTerm;
|
|
5741
|
-
const filteredRows =
|
|
5741
|
+
const filteredRows = React34.useMemo(() => {
|
|
5742
5742
|
if (isServerSide || !term) return rows;
|
|
5743
5743
|
if (search?.predicate) return rows.filter((row) => search.predicate(row, term));
|
|
5744
5744
|
const cs = !!search?.caseSensitive;
|
|
@@ -5752,7 +5752,7 @@ function Table({
|
|
|
5752
5752
|
};
|
|
5753
5753
|
return rows.filter((row) => keys ? keys.some((k) => test(row[k])) : Object.values(row).some(test));
|
|
5754
5754
|
}, [rows, term, isServerSide, search?.predicate, search?.caseSensitive, search?.matchMode, search?.keys]);
|
|
5755
|
-
const sortedRows =
|
|
5755
|
+
const sortedRows = React34.useMemo(() => {
|
|
5756
5756
|
if (isServerSide || !sortState) return filteredRows;
|
|
5757
5757
|
const col = columns.find((c) => c.keyBind === sortState.key);
|
|
5758
5758
|
const accessor = col?.sortAccessor ?? ((r) => r[sortState.key]);
|
|
@@ -5760,29 +5760,29 @@ function Table({
|
|
|
5760
5760
|
if (sortState.direction === "desc") out.reverse();
|
|
5761
5761
|
return out;
|
|
5762
5762
|
}, [filteredRows, sortState, isServerSide, columns]);
|
|
5763
|
-
const datasets =
|
|
5763
|
+
const datasets = React34.useMemo(() => {
|
|
5764
5764
|
if (isServerSide) return [rows];
|
|
5765
5765
|
return createDatasets(sortedRows, pagination.enabled ? perPage : null);
|
|
5766
5766
|
}, [sortedRows, perPage, pagination.enabled, isServerSide, rows]);
|
|
5767
|
-
const MAX_PAGE =
|
|
5767
|
+
const MAX_PAGE = React34.useMemo(() => {
|
|
5768
5768
|
if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
|
|
5769
5769
|
if (isServerSide && typeof pagination.totalCount === "number")
|
|
5770
5770
|
return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
|
|
5771
5771
|
return datasets.length ? datasets.length - 1 : 0;
|
|
5772
5772
|
}, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
|
|
5773
|
-
const currentPageRows =
|
|
5773
|
+
const currentPageRows = React34.useMemo(() => {
|
|
5774
5774
|
if (isServerSide) return rows;
|
|
5775
5775
|
return datasets[activePage] ?? [];
|
|
5776
5776
|
}, [isServerSide, rows, datasets, activePage]);
|
|
5777
|
-
|
|
5777
|
+
React34.useEffect(() => {
|
|
5778
5778
|
if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
|
|
5779
5779
|
setPerPage(pagination.perPage);
|
|
5780
5780
|
}
|
|
5781
5781
|
}, [pagination.enabled, pagination.perPage, isServerSide]);
|
|
5782
|
-
|
|
5782
|
+
React34.useEffect(() => {
|
|
5783
5783
|
if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
|
|
5784
5784
|
}, [isServerSide, pagination.perPage]);
|
|
5785
|
-
|
|
5785
|
+
React34.useEffect(() => {
|
|
5786
5786
|
if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
|
|
5787
5787
|
setActivePage(pagination.page - 1);
|
|
5788
5788
|
}, [isServerSide, pagination.page]);
|
|
@@ -5871,7 +5871,7 @@ function TableSkeletonBody({
|
|
|
5871
5871
|
i
|
|
5872
5872
|
)) });
|
|
5873
5873
|
}
|
|
5874
|
-
var useIsoLayoutEffect = typeof window !== "undefined" ?
|
|
5874
|
+
var useIsoLayoutEffect = typeof window !== "undefined" ? React34.useLayoutEffect : React34.useEffect;
|
|
5875
5875
|
function VirtualList({
|
|
5876
5876
|
items,
|
|
5877
5877
|
rowHeight,
|
|
@@ -5888,10 +5888,10 @@ function VirtualList({
|
|
|
5888
5888
|
className = "",
|
|
5889
5889
|
style
|
|
5890
5890
|
}) {
|
|
5891
|
-
const scrollRef =
|
|
5892
|
-
const [scrollTop, setScrollTop] =
|
|
5893
|
-
const [viewport, setViewport] =
|
|
5894
|
-
const [term, setTerm] =
|
|
5891
|
+
const scrollRef = React34.useRef(null);
|
|
5892
|
+
const [scrollTop, setScrollTop] = React34.useState(0);
|
|
5893
|
+
const [viewport, setViewport] = React34.useState(typeof height === "number" ? height : 400);
|
|
5894
|
+
const [term, setTerm] = React34.useState("");
|
|
5895
5895
|
useIsoLayoutEffect(() => {
|
|
5896
5896
|
const el = scrollRef.current;
|
|
5897
5897
|
if (!el) return;
|
|
@@ -5902,7 +5902,7 @@ function VirtualList({
|
|
|
5902
5902
|
ro.observe(el);
|
|
5903
5903
|
return () => ro.disconnect();
|
|
5904
5904
|
}, []);
|
|
5905
|
-
const filtered =
|
|
5905
|
+
const filtered = React34.useMemo(() => {
|
|
5906
5906
|
if (!searchable || !term) return items;
|
|
5907
5907
|
if (filter) return items.filter((it) => filter(it, term));
|
|
5908
5908
|
const needle = term.toLowerCase();
|
|
@@ -5949,8 +5949,958 @@ function VirtualList({
|
|
|
5949
5949
|
)
|
|
5950
5950
|
] });
|
|
5951
5951
|
}
|
|
5952
|
+
|
|
5953
|
+
// src/utils/fileSource.ts
|
|
5954
|
+
function isUrlSource(source) {
|
|
5955
|
+
return typeof source === "string" || source instanceof URL;
|
|
5956
|
+
}
|
|
5957
|
+
function urlHref(source) {
|
|
5958
|
+
return typeof source === "string" ? source : source.href;
|
|
5959
|
+
}
|
|
5960
|
+
async function sourceToBytes(source, remote) {
|
|
5961
|
+
if (source instanceof Uint8Array) return source;
|
|
5962
|
+
if (source instanceof ArrayBuffer) return new Uint8Array(source);
|
|
5963
|
+
if (typeof Blob !== "undefined" && source instanceof Blob) {
|
|
5964
|
+
return new Uint8Array(await source.arrayBuffer());
|
|
5965
|
+
}
|
|
5966
|
+
if (isUrlSource(source)) {
|
|
5967
|
+
const res = await fetch(urlHref(source), {
|
|
5968
|
+
headers: remote?.httpHeaders,
|
|
5969
|
+
credentials: remote?.withCredentials ? "include" : "same-origin"
|
|
5970
|
+
});
|
|
5971
|
+
if (!res.ok) throw new Error(`Failed to fetch (${res.status} ${res.statusText})`);
|
|
5972
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
5973
|
+
}
|
|
5974
|
+
throw new Error("Unsupported source type");
|
|
5975
|
+
}
|
|
5976
|
+
function downloadBlob(blob, name) {
|
|
5977
|
+
if (typeof document === "undefined") return;
|
|
5978
|
+
const url = URL.createObjectURL(blob);
|
|
5979
|
+
const a = document.createElement("a");
|
|
5980
|
+
a.href = url;
|
|
5981
|
+
a.download = name;
|
|
5982
|
+
a.click();
|
|
5983
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
5984
|
+
}
|
|
5985
|
+
function sourceName(source) {
|
|
5986
|
+
if (typeof File !== "undefined" && source instanceof File) return source.name;
|
|
5987
|
+
if (isUrlSource(source)) {
|
|
5988
|
+
const href = urlHref(source);
|
|
5989
|
+
const last = href.split("?")[0].split("#")[0].split("/").filter(Boolean).pop();
|
|
5990
|
+
return last || void 0;
|
|
5991
|
+
}
|
|
5992
|
+
return void 0;
|
|
5993
|
+
}
|
|
5994
|
+
var pdfjsPromise = null;
|
|
5995
|
+
function loadPdfjs(workerSrc) {
|
|
5996
|
+
if (pdfjsPromise) return pdfjsPromise;
|
|
5997
|
+
pdfjsPromise = import('pdfjs-dist').then((pdfjs) => {
|
|
5998
|
+
if (!pdfjs.GlobalWorkerOptions.workerSrc) {
|
|
5999
|
+
pdfjs.GlobalWorkerOptions.workerSrc = workerSrc ?? `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
|
|
6000
|
+
}
|
|
6001
|
+
return pdfjs;
|
|
6002
|
+
});
|
|
6003
|
+
return pdfjsPromise;
|
|
6004
|
+
}
|
|
6005
|
+
var GAP = 12;
|
|
6006
|
+
var SEARCH_DEBOUNCE = 220;
|
|
6007
|
+
var TEXT_LAYER_STYLE_ID = "oxygen-pdf-textlayer";
|
|
6008
|
+
var TEXT_LAYER_CSS = `
|
|
6009
|
+
.oxy-textLayer{position:absolute;inset:0;overflow:clip;line-height:1;text-size-adjust:none;forced-color-adjust:none;transform-origin:0 0}
|
|
6010
|
+
.oxy-textLayer span,.oxy-textLayer br{color:transparent;position:absolute;white-space:pre;cursor:text;transform-origin:0 0}
|
|
6011
|
+
.oxy-textLayer span.markedContent{top:0;height:0}
|
|
6012
|
+
.oxy-textLayer ::selection{background:color-mix(in srgb, var(--color-accent) 35%, transparent)}
|
|
6013
|
+
`;
|
|
6014
|
+
function ensureTextLayerStyles() {
|
|
6015
|
+
if (typeof document === "undefined" || document.getElementById(TEXT_LAYER_STYLE_ID)) return;
|
|
6016
|
+
const el = document.createElement("style");
|
|
6017
|
+
el.id = TEXT_LAYER_STYLE_ID;
|
|
6018
|
+
el.textContent = TEXT_LAYER_CSS;
|
|
6019
|
+
document.head.appendChild(el);
|
|
6020
|
+
}
|
|
6021
|
+
function pageIndexAt(offsets, y) {
|
|
6022
|
+
let lo = 0;
|
|
6023
|
+
let hi = offsets.length - 1;
|
|
6024
|
+
let ans = 0;
|
|
6025
|
+
while (lo <= hi) {
|
|
6026
|
+
const mid = lo + hi >> 1;
|
|
6027
|
+
if (offsets[mid] <= y) {
|
|
6028
|
+
ans = mid;
|
|
6029
|
+
lo = mid + 1;
|
|
6030
|
+
} else hi = mid - 1;
|
|
6031
|
+
}
|
|
6032
|
+
return ans;
|
|
6033
|
+
}
|
|
6034
|
+
function PdfViewer({
|
|
6035
|
+
source,
|
|
6036
|
+
remote,
|
|
6037
|
+
initialPage = 1,
|
|
6038
|
+
zoom = "page-width",
|
|
6039
|
+
toolbar = true,
|
|
6040
|
+
thumbnails = false,
|
|
6041
|
+
textLayer = true,
|
|
6042
|
+
workerSrc,
|
|
6043
|
+
onLoad,
|
|
6044
|
+
onError,
|
|
6045
|
+
onPageChange,
|
|
6046
|
+
className = "",
|
|
6047
|
+
style
|
|
6048
|
+
}) {
|
|
6049
|
+
const [pdfjs, setPdfjs] = React34.useState(null);
|
|
6050
|
+
const [doc, setDoc] = React34.useState(null);
|
|
6051
|
+
const [numPages, setNumPages] = React34.useState(0);
|
|
6052
|
+
const [baseSize, setBaseSize] = React34.useState(null);
|
|
6053
|
+
const [sizes, setSizes] = React34.useState([]);
|
|
6054
|
+
const [status, setStatus] = React34.useState("loading");
|
|
6055
|
+
const [error, setError] = React34.useState(null);
|
|
6056
|
+
const [reloadKey, setReloadKey] = React34.useState(0);
|
|
6057
|
+
const scrollRef = React34.useRef(null);
|
|
6058
|
+
const [scrollTop, setScrollTop] = React34.useState(0);
|
|
6059
|
+
const [viewport, setViewport] = React34.useState({ w: 0, h: 0 });
|
|
6060
|
+
const [zoomMode, setZoomMode] = React34.useState(zoom);
|
|
6061
|
+
const [page, setPage] = React34.useState(initialPage);
|
|
6062
|
+
const [showSearch, setShowSearch] = React34.useState(false);
|
|
6063
|
+
const [query, setQuery] = React34.useState("");
|
|
6064
|
+
const [matchPages, setMatchPages] = React34.useState(null);
|
|
6065
|
+
const [matchIdx, setMatchIdx] = React34.useState(0);
|
|
6066
|
+
const [searching, setSearching] = React34.useState(false);
|
|
6067
|
+
const [pageDraft, setPageDraft] = React34.useState("");
|
|
6068
|
+
const pageEditing = React34.useRef(false);
|
|
6069
|
+
const pageText = React34.useRef(/* @__PURE__ */ new Map());
|
|
6070
|
+
const searchSeq = React34.useRef(0);
|
|
6071
|
+
const searchTimer = React34.useRef(null);
|
|
6072
|
+
const measured = React34.useRef(/* @__PURE__ */ new Set());
|
|
6073
|
+
const tb = toolbar === true ? { zoom: true, pager: true, download: true, print: true, search: true } : toolbar || {};
|
|
6074
|
+
React34.useEffect(() => {
|
|
6075
|
+
let cancelled = false;
|
|
6076
|
+
let task;
|
|
6077
|
+
setStatus("loading");
|
|
6078
|
+
setError(null);
|
|
6079
|
+
setDoc(null);
|
|
6080
|
+
setBaseSize(null);
|
|
6081
|
+
setSizes([]);
|
|
6082
|
+
pageText.current.clear();
|
|
6083
|
+
measured.current = /* @__PURE__ */ new Set();
|
|
6084
|
+
setMatchPages(null);
|
|
6085
|
+
setMatchIdx(0);
|
|
6086
|
+
loadPdfjs(workerSrc).then(async (pdfjs2) => {
|
|
6087
|
+
if (cancelled) return;
|
|
6088
|
+
setPdfjs(pdfjs2);
|
|
6089
|
+
const params = isUrlSource(source) ? { url: urlHref(source), httpHeaders: remote?.httpHeaders, withCredentials: remote?.withCredentials } : { data: source instanceof Uint8Array || source instanceof ArrayBuffer ? source : new Uint8Array(await source.arrayBuffer()) };
|
|
6090
|
+
task = pdfjs2.getDocument(params);
|
|
6091
|
+
const pdf = await task.promise;
|
|
6092
|
+
if (cancelled) {
|
|
6093
|
+
pdf.destroy?.();
|
|
6094
|
+
return;
|
|
6095
|
+
}
|
|
6096
|
+
const first = await pdf.getPage(1);
|
|
6097
|
+
const vp = first.getViewport({ scale: 1 });
|
|
6098
|
+
if (cancelled) return;
|
|
6099
|
+
const base = { width: vp.width, height: vp.height };
|
|
6100
|
+
setDoc(pdf);
|
|
6101
|
+
setNumPages(pdf.numPages);
|
|
6102
|
+
setBaseSize(base);
|
|
6103
|
+
setSizes(Array.from({ length: pdf.numPages }, () => base));
|
|
6104
|
+
measured.current.add(1);
|
|
6105
|
+
setStatus("ready");
|
|
6106
|
+
onLoad?.({ numPages: pdf.numPages });
|
|
6107
|
+
}).catch((err) => {
|
|
6108
|
+
if (cancelled) return;
|
|
6109
|
+
setStatus("error");
|
|
6110
|
+
setError(err);
|
|
6111
|
+
onError?.(err);
|
|
6112
|
+
});
|
|
6113
|
+
return () => {
|
|
6114
|
+
cancelled = true;
|
|
6115
|
+
task?.destroy?.();
|
|
6116
|
+
};
|
|
6117
|
+
}, [source, remote, reloadKey, workerSrc]);
|
|
6118
|
+
React34.useEffect(() => () => {
|
|
6119
|
+
doc?.destroy?.();
|
|
6120
|
+
}, [doc]);
|
|
6121
|
+
React34.useEffect(() => {
|
|
6122
|
+
const el = scrollRef.current;
|
|
6123
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
6124
|
+
const measure = () => setViewport({ w: el.clientWidth, h: el.clientHeight });
|
|
6125
|
+
measure();
|
|
6126
|
+
const ro = new ResizeObserver(measure);
|
|
6127
|
+
ro.observe(el);
|
|
6128
|
+
return () => ro.disconnect();
|
|
6129
|
+
}, [status]);
|
|
6130
|
+
const handleMeasure = React34.useCallback((p, size) => {
|
|
6131
|
+
setSizes((prev) => {
|
|
6132
|
+
const cur = prev[p - 1];
|
|
6133
|
+
if (cur && Math.abs(cur.width - size.width) < 0.5 && Math.abs(cur.height - size.height) < 0.5) return prev;
|
|
6134
|
+
const next = prev.slice();
|
|
6135
|
+
next[p - 1] = size;
|
|
6136
|
+
return next;
|
|
6137
|
+
});
|
|
6138
|
+
}, []);
|
|
6139
|
+
const scale = React34.useMemo(() => {
|
|
6140
|
+
if (!baseSize) return 1;
|
|
6141
|
+
if (typeof zoomMode === "number") return zoomMode;
|
|
6142
|
+
const avail = Math.max(1, (viewport.w || baseSize.width) - 32);
|
|
6143
|
+
if (zoomMode === "page-width" || zoomMode === "auto") return avail / baseSize.width;
|
|
6144
|
+
if (zoomMode === "page-fit") {
|
|
6145
|
+
const availH = Math.max(1, (viewport.h || baseSize.height) - 32);
|
|
6146
|
+
return Math.min(avail / baseSize.width, availH / baseSize.height);
|
|
6147
|
+
}
|
|
6148
|
+
return 1;
|
|
6149
|
+
}, [zoomMode, baseSize, viewport]);
|
|
6150
|
+
const { offsets, total } = React34.useMemo(() => {
|
|
6151
|
+
const offs = new Array(sizes.length);
|
|
6152
|
+
let acc = 0;
|
|
6153
|
+
for (let i = 0; i < sizes.length; i++) {
|
|
6154
|
+
offs[i] = acc;
|
|
6155
|
+
acc += sizes[i].height * scale + GAP;
|
|
6156
|
+
}
|
|
6157
|
+
return { offsets: offs, total: acc };
|
|
6158
|
+
}, [sizes, scale]);
|
|
6159
|
+
const overscan = 1;
|
|
6160
|
+
const hasLayout = offsets.length > 0 && total > 0;
|
|
6161
|
+
const startIdx = hasLayout ? Math.max(0, pageIndexAt(offsets, scrollTop) - overscan) : 0;
|
|
6162
|
+
const endIdx = hasLayout ? Math.min(numPages, pageIndexAt(offsets, scrollTop + viewport.h) + 1 + overscan) : 0;
|
|
6163
|
+
const visiblePages = Array.from({ length: Math.max(0, endIdx - startIdx) }, (_, i) => startIdx + i + 1);
|
|
6164
|
+
const scrollToPage = React34.useCallback((p) => {
|
|
6165
|
+
const el = scrollRef.current;
|
|
6166
|
+
if (!el || !offsets.length) return;
|
|
6167
|
+
const clamped = Math.min(offsets.length, Math.max(1, p));
|
|
6168
|
+
el.scrollTo({ top: offsets[clamped - 1] ?? 0, behavior: "smooth" });
|
|
6169
|
+
}, [offsets]);
|
|
6170
|
+
React34.useEffect(() => {
|
|
6171
|
+
if (!hasLayout) return;
|
|
6172
|
+
const cur = pageIndexAt(offsets, scrollTop + viewport.h / 2) + 1;
|
|
6173
|
+
if (cur !== page) {
|
|
6174
|
+
setPage(cur);
|
|
6175
|
+
onPageChange?.(cur);
|
|
6176
|
+
}
|
|
6177
|
+
}, [scrollTop, offsets, viewport.h, numPages]);
|
|
6178
|
+
React34.useEffect(() => {
|
|
6179
|
+
if (status === "ready" && initialPage > 1) scrollToPage(initialPage);
|
|
6180
|
+
}, [status, initialPage]);
|
|
6181
|
+
const runSearch = React34.useCallback(async (q) => {
|
|
6182
|
+
const needle = q.trim().toLowerCase();
|
|
6183
|
+
if (!doc || !needle) {
|
|
6184
|
+
setMatchPages(null);
|
|
6185
|
+
setMatchIdx(0);
|
|
6186
|
+
setSearching(false);
|
|
6187
|
+
return;
|
|
6188
|
+
}
|
|
6189
|
+
const seq = ++searchSeq.current;
|
|
6190
|
+
setSearching(true);
|
|
6191
|
+
const hits = [];
|
|
6192
|
+
for (let p = 1; p <= numPages; p++) {
|
|
6193
|
+
let text = pageText.current.get(p);
|
|
6194
|
+
if (text === void 0) {
|
|
6195
|
+
const pg = await doc.getPage(p);
|
|
6196
|
+
const tc = await pg.getTextContent();
|
|
6197
|
+
const built = tc.items.map((it) => "str" in it ? it.str : "").join(" ").toLowerCase();
|
|
6198
|
+
pageText.current.set(p, built);
|
|
6199
|
+
text = built;
|
|
6200
|
+
}
|
|
6201
|
+
if (seq !== searchSeq.current) return;
|
|
6202
|
+
if (text.includes(needle)) hits.push(p);
|
|
6203
|
+
}
|
|
6204
|
+
if (seq !== searchSeq.current) return;
|
|
6205
|
+
setMatchPages(hits);
|
|
6206
|
+
setMatchIdx(0);
|
|
6207
|
+
setSearching(false);
|
|
6208
|
+
if (hits.length) scrollToPage(hits[0]);
|
|
6209
|
+
}, [doc, numPages, scrollToPage]);
|
|
6210
|
+
const onQueryChange = React34.useCallback((v) => {
|
|
6211
|
+
setQuery(v);
|
|
6212
|
+
if (searchTimer.current) clearTimeout(searchTimer.current);
|
|
6213
|
+
if (!v.trim()) {
|
|
6214
|
+
searchSeq.current++;
|
|
6215
|
+
setMatchPages(null);
|
|
6216
|
+
setMatchIdx(0);
|
|
6217
|
+
setSearching(false);
|
|
6218
|
+
return;
|
|
6219
|
+
}
|
|
6220
|
+
searchTimer.current = setTimeout(() => runSearch(v), SEARCH_DEBOUNCE);
|
|
6221
|
+
}, [runSearch]);
|
|
6222
|
+
React34.useEffect(() => () => {
|
|
6223
|
+
if (searchTimer.current) clearTimeout(searchTimer.current);
|
|
6224
|
+
}, []);
|
|
6225
|
+
const gotoMatch = (dir) => {
|
|
6226
|
+
if (!matchPages?.length) return;
|
|
6227
|
+
const next = (matchIdx + dir + matchPages.length) % matchPages.length;
|
|
6228
|
+
setMatchIdx(next);
|
|
6229
|
+
scrollToPage(matchPages[next]);
|
|
6230
|
+
};
|
|
6231
|
+
const getBytes = React34.useCallback(async () => {
|
|
6232
|
+
if (doc?.getData) return doc.getData();
|
|
6233
|
+
if (source instanceof Uint8Array) return source;
|
|
6234
|
+
if (source instanceof ArrayBuffer) return new Uint8Array(source);
|
|
6235
|
+
if (typeof Blob !== "undefined" && source instanceof Blob) return new Uint8Array(await source.arrayBuffer());
|
|
6236
|
+
throw new Error("No bytes available");
|
|
6237
|
+
}, [doc, source]);
|
|
6238
|
+
const download = React34.useCallback(async () => {
|
|
6239
|
+
const bytes = await getBytes();
|
|
6240
|
+
downloadBlob(new Blob([bytes], { type: "application/pdf" }), sourceName(source) || "document.pdf");
|
|
6241
|
+
}, [getBytes, source]);
|
|
6242
|
+
const print = React34.useCallback(async () => {
|
|
6243
|
+
const bytes = await getBytes();
|
|
6244
|
+
const blob = new Blob([bytes], { type: "application/pdf" });
|
|
6245
|
+
const url = URL.createObjectURL(blob);
|
|
6246
|
+
const iframe = document.createElement("iframe");
|
|
6247
|
+
iframe.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0";
|
|
6248
|
+
iframe.src = url;
|
|
6249
|
+
iframe.onload = () => {
|
|
6250
|
+
try {
|
|
6251
|
+
iframe.contentWindow?.focus();
|
|
6252
|
+
iframe.contentWindow?.print();
|
|
6253
|
+
} catch {
|
|
6254
|
+
}
|
|
6255
|
+
};
|
|
6256
|
+
document.body.appendChild(iframe);
|
|
6257
|
+
setTimeout(() => {
|
|
6258
|
+
document.body.removeChild(iframe);
|
|
6259
|
+
URL.revokeObjectURL(url);
|
|
6260
|
+
}, 6e4);
|
|
6261
|
+
}, [getBytes]);
|
|
6262
|
+
const setZoomNum = (factor) => {
|
|
6263
|
+
const cur = typeof zoomMode === "number" ? zoomMode : scale;
|
|
6264
|
+
setZoomMode(Math.min(5, Math.max(0.25, +(cur * factor).toFixed(2))));
|
|
6265
|
+
};
|
|
6266
|
+
const zoomPct = Math.round(scale * 100);
|
|
6267
|
+
const commitPageDraft = () => {
|
|
6268
|
+
pageEditing.current = false;
|
|
6269
|
+
const n = parseInt(pageDraft, 10);
|
|
6270
|
+
if (Number.isFinite(n)) scrollToPage(n);
|
|
6271
|
+
};
|
|
6272
|
+
if (status === "error") {
|
|
6273
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col items-center justify-center gap-3 rounded-lg border border-border bg-surface p-8 text-center", className), style, children: [
|
|
6274
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-status-error", children: "Couldn\u2019t load the PDF" }),
|
|
6275
|
+
error?.message && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-xs text-foreground-muted", children: error.message }),
|
|
6276
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { content: "Retry", size: "sm", variant: "outline", onClick: () => setReloadKey((k) => k + 1) })
|
|
6277
|
+
] });
|
|
6278
|
+
}
|
|
6279
|
+
const ready = status === "ready";
|
|
6280
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col overflow-hidden rounded-lg border border-border bg-surface-raised", className), style: { height: 600, ...style }, children: [
|
|
6281
|
+
toolbar !== false && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 flex-col border-b border-border bg-surface", children: [
|
|
6282
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 px-2 py-1.5", children: [
|
|
6283
|
+
tb.pager && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
6284
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Previous page", onClick: () => scrollToPage(page - 1), icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron5, { dir: "up" }), disabled: !ready || page <= 1 }),
|
|
6285
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 text-xs text-foreground-secondary select-none", children: [
|
|
6286
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6287
|
+
"input",
|
|
6288
|
+
{
|
|
6289
|
+
value: pageEditing.current ? pageDraft : ready ? String(page) : "\u2013",
|
|
6290
|
+
onFocus: () => {
|
|
6291
|
+
pageEditing.current = true;
|
|
6292
|
+
setPageDraft(String(page));
|
|
6293
|
+
},
|
|
6294
|
+
onChange: (e) => setPageDraft(e.target.value.replace(/[^\d]/g, "")),
|
|
6295
|
+
onBlur: commitPageDraft,
|
|
6296
|
+
onKeyDown: (e) => {
|
|
6297
|
+
if (e.key === "Enter") e.target.blur();
|
|
6298
|
+
},
|
|
6299
|
+
disabled: !ready,
|
|
6300
|
+
"aria-label": "Page number",
|
|
6301
|
+
className: "h-6 w-9 rounded border border-border bg-surface-raised text-center tabular-nums text-foreground outline-none focus:border-accent disabled:opacity-50"
|
|
6302
|
+
}
|
|
6303
|
+
),
|
|
6304
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums", children: [
|
|
6305
|
+
"/ ",
|
|
6306
|
+
numPages || "\u2013"
|
|
6307
|
+
] })
|
|
6308
|
+
] }),
|
|
6309
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Next page", onClick: () => scrollToPage(page + 1), icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron5, { dir: "down" }), disabled: !ready || page >= numPages })
|
|
6310
|
+
] }),
|
|
6311
|
+
tb.pager && tb.zoom && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mx-1 h-5 w-px bg-border", "aria-hidden": "true" }),
|
|
6312
|
+
tb.zoom && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
6313
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Zoom out", onClick: () => setZoomNum(1 / 1.2), icon: /* @__PURE__ */ jsxRuntime.jsx(MinusIcon, {}), disabled: !ready }),
|
|
6314
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-10 text-center text-xs tabular-nums text-foreground-secondary select-none", children: ready ? `${zoomPct}%` : "\u2013" }),
|
|
6315
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Zoom in", onClick: () => setZoomNum(1.2), icon: /* @__PURE__ */ jsxRuntime.jsx(PlusIcon, {}), disabled: !ready }),
|
|
6316
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Fit width", onClick: () => setZoomMode("page-width"), icon: /* @__PURE__ */ jsxRuntime.jsx(FitWidthIcon, {}), disabled: !ready }),
|
|
6317
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Fit page", onClick: () => setZoomMode("page-fit"), icon: /* @__PURE__ */ jsxRuntime.jsx(FitPageIcon, {}), disabled: !ready })
|
|
6318
|
+
] }),
|
|
6319
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
6320
|
+
tb.search && /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: showSearch ? "bordered" : "ghost", size: "sm", title: "Search", onClick: () => setShowSearch((s) => !s), icon: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon2, {}), disabled: !ready }),
|
|
6321
|
+
tb.search && (tb.download || tb.print) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mx-1 h-5 w-px bg-border", "aria-hidden": "true" }),
|
|
6322
|
+
tb.download && /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Download", onClick: download, icon: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {}), disabled: !ready }),
|
|
6323
|
+
tb.print && /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Print", onClick: print, icon: /* @__PURE__ */ jsxRuntime.jsx(PrintIcon, {}), disabled: !ready })
|
|
6324
|
+
] })
|
|
6325
|
+
] }),
|
|
6326
|
+
tb.search && showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 border-t border-border px-2 py-1.5", children: [
|
|
6327
|
+
/* @__PURE__ */ jsxRuntime.jsx(SearchIcon2, {}),
|
|
6328
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6329
|
+
"input",
|
|
6330
|
+
{
|
|
6331
|
+
autoFocus: true,
|
|
6332
|
+
value: query,
|
|
6333
|
+
onChange: (e) => onQueryChange(e.target.value),
|
|
6334
|
+
onKeyDown: (e) => {
|
|
6335
|
+
if (e.key === "Enter") gotoMatch(e.shiftKey ? -1 : 1);
|
|
6336
|
+
},
|
|
6337
|
+
placeholder: "Find in document\u2026",
|
|
6338
|
+
className: "h-7 flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-foreground-muted"
|
|
6339
|
+
}
|
|
6340
|
+
),
|
|
6341
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs tabular-nums text-foreground-muted", children: searching ? "Searching\u2026" : matchPages == null ? "" : matchPages.length ? `${matchIdx + 1} of ${matchPages.length}` : "No matches" }),
|
|
6342
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Previous match", onClick: () => gotoMatch(-1), icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron5, { dir: "up" }), disabled: !matchPages?.length }),
|
|
6343
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Next match", onClick: () => gotoMatch(1), icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron5, { dir: "down" }), disabled: !matchPages?.length }),
|
|
6344
|
+
/* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Close search", onClick: () => {
|
|
6345
|
+
setShowSearch(false);
|
|
6346
|
+
onQueryChange("");
|
|
6347
|
+
}, icon: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {}) })
|
|
6348
|
+
] })
|
|
6349
|
+
] }),
|
|
6350
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1", children: [
|
|
6351
|
+
thumbnails && ready && doc && baseSize && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-32 flex-shrink-0 overflow-y-auto border-r border-border bg-surface p-2", children: Array.from({ length: numPages }, (_, i) => i + 1).map((p) => {
|
|
6352
|
+
const s = sizes[p - 1] ?? baseSize;
|
|
6353
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6354
|
+
"button",
|
|
6355
|
+
{
|
|
6356
|
+
type: "button",
|
|
6357
|
+
onClick: () => scrollToPage(p),
|
|
6358
|
+
className: cx(
|
|
6359
|
+
"mb-2 block w-full overflow-hidden rounded border bg-surface-raised transition-colors",
|
|
6360
|
+
p === page ? "border-accent ring-1 ring-accent" : "border-border hover:border-border-strong"
|
|
6361
|
+
),
|
|
6362
|
+
style: { aspectRatio: `${s.width} / ${s.height}` },
|
|
6363
|
+
"aria-label": `Page ${p}`,
|
|
6364
|
+
"aria-current": p === page,
|
|
6365
|
+
children: Math.abs(p - page) <= 8 ? /* @__PURE__ */ jsxRuntime.jsx(PdfPage, { pdfjs, doc, page: p, scale: 112 / s.width, textLayer: false }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block py-4 text-center text-xs text-foreground-muted", children: p })
|
|
6366
|
+
},
|
|
6367
|
+
p
|
|
6368
|
+
);
|
|
6369
|
+
}) }),
|
|
6370
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6371
|
+
"div",
|
|
6372
|
+
{
|
|
6373
|
+
ref: scrollRef,
|
|
6374
|
+
onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
|
|
6375
|
+
className: "relative flex-1 overflow-auto bg-background",
|
|
6376
|
+
children: !ready || !baseSize ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center gap-3 p-6", children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { width: Math.min((viewport.w || 528) - 48, 560), height: 680, className: "rounded" }) }) : numPages === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center text-sm text-foreground-muted", children: "Empty document" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: total, position: "relative" }, children: visiblePages.map((p) => {
|
|
6377
|
+
const s = sizes[p - 1] ?? baseSize;
|
|
6378
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6379
|
+
"div",
|
|
6380
|
+
{
|
|
6381
|
+
style: { position: "absolute", top: offsets[p - 1], left: 0, right: 0, display: "flex", justifyContent: "center", paddingTop: GAP / 2 },
|
|
6382
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative shadow-md", style: { width: s.width * scale, height: s.height * scale }, children: /* @__PURE__ */ jsxRuntime.jsx(PdfPage, { pdfjs, doc, page: p, scale, textLayer, onMeasure: handleMeasure }) })
|
|
6383
|
+
},
|
|
6384
|
+
p
|
|
6385
|
+
);
|
|
6386
|
+
}) })
|
|
6387
|
+
}
|
|
6388
|
+
)
|
|
6389
|
+
] })
|
|
6390
|
+
] });
|
|
6391
|
+
}
|
|
6392
|
+
function PdfPage({
|
|
6393
|
+
pdfjs,
|
|
6394
|
+
doc,
|
|
6395
|
+
page,
|
|
6396
|
+
scale,
|
|
6397
|
+
textLayer,
|
|
6398
|
+
onMeasure
|
|
6399
|
+
}) {
|
|
6400
|
+
const canvasRef = React34.useRef(null);
|
|
6401
|
+
const textRef = React34.useRef(null);
|
|
6402
|
+
React34.useEffect(() => {
|
|
6403
|
+
let cancelled = false;
|
|
6404
|
+
let renderTask;
|
|
6405
|
+
(async () => {
|
|
6406
|
+
const pg = await doc.getPage(page);
|
|
6407
|
+
if (cancelled) return;
|
|
6408
|
+
const viewport = pg.getViewport({ scale });
|
|
6409
|
+
onMeasure?.(page, { width: viewport.width / scale, height: viewport.height / scale });
|
|
6410
|
+
const canvas = canvasRef.current;
|
|
6411
|
+
if (!canvas) return;
|
|
6412
|
+
const ratio = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
6413
|
+
canvas.width = Math.floor(viewport.width * ratio);
|
|
6414
|
+
canvas.height = Math.floor(viewport.height * ratio);
|
|
6415
|
+
canvas.style.width = `${Math.floor(viewport.width)}px`;
|
|
6416
|
+
canvas.style.height = `${Math.floor(viewport.height)}px`;
|
|
6417
|
+
const ctx = canvas.getContext("2d");
|
|
6418
|
+
renderTask = pg.render({ canvasContext: ctx, viewport, transform: ratio !== 1 ? [ratio, 0, 0, ratio, 0, 0] : void 0 });
|
|
6419
|
+
try {
|
|
6420
|
+
await renderTask.promise;
|
|
6421
|
+
} catch {
|
|
6422
|
+
return;
|
|
6423
|
+
}
|
|
6424
|
+
if (cancelled || !textLayer || !textRef.current || !pdfjs?.TextLayer) return;
|
|
6425
|
+
try {
|
|
6426
|
+
ensureTextLayerStyles();
|
|
6427
|
+
textRef.current.innerHTML = "";
|
|
6428
|
+
textRef.current.style.setProperty("--scale-factor", String(scale));
|
|
6429
|
+
const tl = new pdfjs.TextLayer({ textContentSource: pg.streamTextContent(), container: textRef.current, viewport });
|
|
6430
|
+
await tl.render();
|
|
6431
|
+
} catch {
|
|
6432
|
+
}
|
|
6433
|
+
})();
|
|
6434
|
+
return () => {
|
|
6435
|
+
cancelled = true;
|
|
6436
|
+
renderTask?.cancel?.();
|
|
6437
|
+
};
|
|
6438
|
+
}, [pdfjs, doc, page, scale, textLayer, onMeasure]);
|
|
6439
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6440
|
+
/* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, className: "block bg-white" }),
|
|
6441
|
+
textLayer && /* @__PURE__ */ jsxRuntime.jsx("div", { ref: textRef, className: "oxy-textLayer", "aria-hidden": "true" })
|
|
6442
|
+
] });
|
|
6443
|
+
}
|
|
6444
|
+
var Chevron5 = ({ dir }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: dir === "up" ? "m6 15 6-6 6 6" : "m6 9 6 6 6-6" }) });
|
|
6445
|
+
var MinusIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M5 12h14" }) });
|
|
6446
|
+
var PlusIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M12 5v14M5 12h14" }) });
|
|
6447
|
+
var SearchIcon2 = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4 text-foreground-muted", "aria-hidden": "true", children: [
|
|
6448
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
6449
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "m21 21-4.3-4.3" })
|
|
6450
|
+
] });
|
|
6451
|
+
var CloseIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M6 6l12 12M18 6 6 18" }) });
|
|
6452
|
+
var DownloadIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 3v12m0 0 4-4m-4 4-4-4M4 21h16" }) });
|
|
6453
|
+
var PrintIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9V3h12v6M6 18H4v-7h16v7h-2M8 14h8v7H8z" }) });
|
|
6454
|
+
var FitWidthIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 12h18m0 0-4-4m4 4-4 4M3 12l4-4m-4 4 4 4" }) });
|
|
6455
|
+
var FitPageIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: [
|
|
6456
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", y: "3", width: "14", height: "18", rx: "1" }),
|
|
6457
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 8h6M9 12h6M9 16h4" })
|
|
6458
|
+
] });
|
|
6459
|
+
var DEFAULT_COL_WIDTH = 140;
|
|
6460
|
+
var GUTTER = 52;
|
|
6461
|
+
function resolveWidth(w) {
|
|
6462
|
+
if (typeof w === "number" && Number.isFinite(w)) return w;
|
|
6463
|
+
if (typeof w === "string") {
|
|
6464
|
+
const m = /^\s*(\d+(?:\.\d+)?)(px)?\s*$/.exec(w);
|
|
6465
|
+
if (m) return parseFloat(m[1]);
|
|
6466
|
+
}
|
|
6467
|
+
return DEFAULT_COL_WIDTH;
|
|
6468
|
+
}
|
|
6469
|
+
function displayValue(v) {
|
|
6470
|
+
if (v == null) return "";
|
|
6471
|
+
return String(v);
|
|
6472
|
+
}
|
|
6473
|
+
function DataGrid({
|
|
6474
|
+
columns,
|
|
6475
|
+
rows,
|
|
6476
|
+
rowHeight = 34,
|
|
6477
|
+
headerHeight = 38,
|
|
6478
|
+
height = 480,
|
|
6479
|
+
editable = false,
|
|
6480
|
+
virtualize = true,
|
|
6481
|
+
overscan = 4,
|
|
6482
|
+
rowNumbers = true,
|
|
6483
|
+
onCellEdit,
|
|
6484
|
+
className = "",
|
|
6485
|
+
style,
|
|
6486
|
+
emptyState = "No data"
|
|
6487
|
+
}) {
|
|
6488
|
+
const scrollRef = React34.useRef(null);
|
|
6489
|
+
const [scroll, setScroll] = React34.useState({ top: 0, left: 0 });
|
|
6490
|
+
const [viewport, setViewport] = React34.useState({ w: 0, h: 0 });
|
|
6491
|
+
const [editing, setEditing] = React34.useState(null);
|
|
6492
|
+
const [draft, setDraft] = React34.useState("");
|
|
6493
|
+
const gutter = rowNumbers ? GUTTER : 0;
|
|
6494
|
+
const { widths, offsets, totalWidth } = React34.useMemo(() => {
|
|
6495
|
+
const widths2 = columns.map((c) => resolveWidth(c.width));
|
|
6496
|
+
const offsets2 = [];
|
|
6497
|
+
let acc = 0;
|
|
6498
|
+
for (const w of widths2) {
|
|
6499
|
+
offsets2.push(acc);
|
|
6500
|
+
acc += w;
|
|
6501
|
+
}
|
|
6502
|
+
return { widths: widths2, offsets: offsets2, totalWidth: acc };
|
|
6503
|
+
}, [columns]);
|
|
6504
|
+
const totalHeight = rows.length * rowHeight;
|
|
6505
|
+
React34.useEffect(() => {
|
|
6506
|
+
const el = scrollRef.current;
|
|
6507
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
6508
|
+
const measure = () => setViewport({ w: el.clientWidth, h: el.clientHeight });
|
|
6509
|
+
measure();
|
|
6510
|
+
const ro = new ResizeObserver(measure);
|
|
6511
|
+
ro.observe(el);
|
|
6512
|
+
return () => ro.disconnect();
|
|
6513
|
+
}, []);
|
|
6514
|
+
const bodyH = (viewport.h || (typeof height === "number" ? height : 480)) - headerHeight;
|
|
6515
|
+
const rowStart = virtualize ? Math.max(0, Math.floor(scroll.top / rowHeight) - overscan) : 0;
|
|
6516
|
+
const rowEnd = virtualize ? Math.min(rows.length, Math.ceil((scroll.top + bodyH) / rowHeight) + overscan) : rows.length;
|
|
6517
|
+
let colStart = 0;
|
|
6518
|
+
let colEnd = columns.length;
|
|
6519
|
+
if (virtualize && viewport.w) {
|
|
6520
|
+
const viewLeft = scroll.left;
|
|
6521
|
+
const viewRight = scroll.left + (viewport.w - gutter);
|
|
6522
|
+
colStart = Math.max(0, offsets.findIndex((o, i) => o + widths[i] > viewLeft));
|
|
6523
|
+
if (colStart < 0) colStart = 0;
|
|
6524
|
+
colEnd = offsets.findIndex((o) => o > viewRight);
|
|
6525
|
+
colEnd = colEnd === -1 ? columns.length : Math.min(columns.length, colEnd + 1);
|
|
6526
|
+
colStart = Math.max(0, colStart - overscan);
|
|
6527
|
+
colEnd = Math.min(columns.length, colEnd + overscan);
|
|
6528
|
+
}
|
|
6529
|
+
const visibleRows = Array.from({ length: Math.max(0, rowEnd - rowStart) }, (_, i) => rowStart + i);
|
|
6530
|
+
const visibleCols = Array.from({ length: Math.max(0, colEnd - colStart) }, (_, i) => colStart + i);
|
|
6531
|
+
const commit = React34.useCallback(() => {
|
|
6532
|
+
if (!editing) return;
|
|
6533
|
+
const col = columns[editing.col];
|
|
6534
|
+
onCellEdit?.({ row: editing.row, column: col.key, value: draft });
|
|
6535
|
+
setEditing(null);
|
|
6536
|
+
}, [editing, columns, draft, onCellEdit]);
|
|
6537
|
+
const startEdit = (row, col) => {
|
|
6538
|
+
const c = columns[col];
|
|
6539
|
+
if (!(c.editable ?? editable)) return;
|
|
6540
|
+
setDraft(displayValue(rows[row]?.[c.key] ?? ""));
|
|
6541
|
+
setEditing({ row, col });
|
|
6542
|
+
};
|
|
6543
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6544
|
+
"div",
|
|
6545
|
+
{
|
|
6546
|
+
ref: scrollRef,
|
|
6547
|
+
onScroll: (e) => setScroll({ top: e.currentTarget.scrollTop, left: e.currentTarget.scrollLeft }),
|
|
6548
|
+
className: cx("relative overflow-auto rounded-lg border border-border bg-surface-raised text-sm", className),
|
|
6549
|
+
style: { height, ...style },
|
|
6550
|
+
role: "grid",
|
|
6551
|
+
"aria-rowcount": rows.length,
|
|
6552
|
+
"aria-colcount": columns.length,
|
|
6553
|
+
children: [
|
|
6554
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: gutter + totalWidth, height: headerHeight + totalHeight }, children: [
|
|
6555
|
+
rowNumbers && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6556
|
+
"div",
|
|
6557
|
+
{
|
|
6558
|
+
className: "border-b border-r border-border bg-surface",
|
|
6559
|
+
style: { position: "absolute", top: scroll.top, left: scroll.left, width: gutter, height: headerHeight, zIndex: 3 }
|
|
6560
|
+
}
|
|
6561
|
+
),
|
|
6562
|
+
visibleCols.map((ci) => {
|
|
6563
|
+
const c = columns[ci];
|
|
6564
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6565
|
+
"div",
|
|
6566
|
+
{
|
|
6567
|
+
role: "columnheader",
|
|
6568
|
+
className: "flex items-center border-b border-r border-border bg-surface px-3 font-medium text-foreground-secondary",
|
|
6569
|
+
style: {
|
|
6570
|
+
position: "absolute",
|
|
6571
|
+
top: scroll.top,
|
|
6572
|
+
left: gutter + offsets[ci],
|
|
6573
|
+
width: widths[ci],
|
|
6574
|
+
height: headerHeight,
|
|
6575
|
+
zIndex: 2,
|
|
6576
|
+
justifyContent: c.align === "right" ? "flex-end" : c.align === "center" ? "center" : "flex-start"
|
|
6577
|
+
},
|
|
6578
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: c.label ?? c.key })
|
|
6579
|
+
},
|
|
6580
|
+
`h-${c.key}`
|
|
6581
|
+
);
|
|
6582
|
+
}),
|
|
6583
|
+
rowNumbers && visibleRows.map((ri) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6584
|
+
"div",
|
|
6585
|
+
{
|
|
6586
|
+
className: "flex items-center justify-center border-b border-r border-border bg-surface text-xs tabular-nums text-foreground-muted",
|
|
6587
|
+
style: { position: "absolute", left: scroll.left, top: headerHeight + ri * rowHeight, width: gutter, height: rowHeight, zIndex: 1 },
|
|
6588
|
+
children: ri + 1
|
|
6589
|
+
},
|
|
6590
|
+
`g-${ri}`
|
|
6591
|
+
)),
|
|
6592
|
+
visibleRows.map(
|
|
6593
|
+
(ri) => visibleCols.map((ci) => {
|
|
6594
|
+
const c = columns[ci];
|
|
6595
|
+
const isEditing = editing?.row === ri && editing?.col === ci;
|
|
6596
|
+
const canEdit = c.editable ?? editable;
|
|
6597
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6598
|
+
"div",
|
|
6599
|
+
{
|
|
6600
|
+
role: "gridcell",
|
|
6601
|
+
onDoubleClick: () => startEdit(ri, ci),
|
|
6602
|
+
className: cx(
|
|
6603
|
+
"flex items-center border-b border-r border-border px-3",
|
|
6604
|
+
ri % 2 ? "bg-surface-raised" : "bg-surface",
|
|
6605
|
+
canEdit && "cursor-text"
|
|
6606
|
+
),
|
|
6607
|
+
style: {
|
|
6608
|
+
position: "absolute",
|
|
6609
|
+
top: headerHeight + ri * rowHeight,
|
|
6610
|
+
left: gutter + offsets[ci],
|
|
6611
|
+
width: widths[ci],
|
|
6612
|
+
height: rowHeight,
|
|
6613
|
+
justifyContent: c.align === "right" ? "flex-end" : c.align === "center" ? "center" : "flex-start"
|
|
6614
|
+
},
|
|
6615
|
+
children: isEditing ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6616
|
+
"input",
|
|
6617
|
+
{
|
|
6618
|
+
autoFocus: true,
|
|
6619
|
+
value: draft,
|
|
6620
|
+
onChange: (e) => setDraft(e.target.value),
|
|
6621
|
+
onBlur: commit,
|
|
6622
|
+
onKeyDown: (e) => {
|
|
6623
|
+
if (e.key === "Enter") commit();
|
|
6624
|
+
else if (e.key === "Escape") setEditing(null);
|
|
6625
|
+
},
|
|
6626
|
+
className: "h-full w-full bg-transparent text-foreground outline-none"
|
|
6627
|
+
}
|
|
6628
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: displayValue(rows[ri]?.[c.key] ?? "") })
|
|
6629
|
+
},
|
|
6630
|
+
`${ri}-${c.key}`
|
|
6631
|
+
);
|
|
6632
|
+
})
|
|
6633
|
+
)
|
|
6634
|
+
] }),
|
|
6635
|
+
rows.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center text-foreground-muted", style: { top: headerHeight }, children: emptyState })
|
|
6636
|
+
]
|
|
6637
|
+
}
|
|
6638
|
+
);
|
|
6639
|
+
}
|
|
6640
|
+
function toColumns(cols) {
|
|
6641
|
+
return cols.map((c) => typeof c === "string" ? { key: c, label: c } : { ...c, label: c.label ?? c.key });
|
|
6642
|
+
}
|
|
6643
|
+
function cellValue(v) {
|
|
6644
|
+
if (v != null && typeof v === "object" && "value" in v) return v.value;
|
|
6645
|
+
return v;
|
|
6646
|
+
}
|
|
6647
|
+
function toPlainRows(sheet, columns) {
|
|
6648
|
+
return sheet.rows.map((row) => {
|
|
6649
|
+
const out = {};
|
|
6650
|
+
for (const c of columns) out[c.key] = cellValue(row[c.key]);
|
|
6651
|
+
return out;
|
|
6652
|
+
});
|
|
6653
|
+
}
|
|
6654
|
+
var xlsxPromise = null;
|
|
6655
|
+
var loadXlsx = () => xlsxPromise ??= import('xlsx');
|
|
6656
|
+
var jspdfPromise = null;
|
|
6657
|
+
var loadJspdf = () => jspdfPromise ??= import('jspdf');
|
|
6658
|
+
function coerceToCellType(prev, next) {
|
|
6659
|
+
if (typeof prev === "number") {
|
|
6660
|
+
const n = Number(next);
|
|
6661
|
+
return next.trim() !== "" && Number.isFinite(n) ? n : next;
|
|
6662
|
+
}
|
|
6663
|
+
if (typeof prev === "boolean") {
|
|
6664
|
+
if (/^(true|false)$/i.test(next.trim())) return next.trim().toLowerCase() === "true";
|
|
6665
|
+
return next;
|
|
6666
|
+
}
|
|
6667
|
+
return next;
|
|
6668
|
+
}
|
|
6669
|
+
function Spreadsheet({
|
|
6670
|
+
source,
|
|
6671
|
+
remote,
|
|
6672
|
+
editable = false,
|
|
6673
|
+
onCellEdit,
|
|
6674
|
+
onChange,
|
|
6675
|
+
export: exportFormats = ["xlsx", "csv", "pdf"],
|
|
6676
|
+
fileName,
|
|
6677
|
+
virtualize = true,
|
|
6678
|
+
className = "",
|
|
6679
|
+
style
|
|
6680
|
+
}) {
|
|
6681
|
+
const [sheets, setSheets] = React34.useState(Array.isArray(source) ? source : null);
|
|
6682
|
+
const [active, setActive] = React34.useState(0);
|
|
6683
|
+
const [status, setStatus] = React34.useState(Array.isArray(source) ? "ready" : "loading");
|
|
6684
|
+
const [error, setError] = React34.useState(null);
|
|
6685
|
+
const [reloadKey, setReloadKey] = React34.useState(0);
|
|
6686
|
+
React34.useEffect(() => {
|
|
6687
|
+
if (Array.isArray(source)) {
|
|
6688
|
+
setSheets(source);
|
|
6689
|
+
setStatus("ready");
|
|
6690
|
+
return;
|
|
6691
|
+
}
|
|
6692
|
+
let cancelled = false;
|
|
6693
|
+
setStatus("loading");
|
|
6694
|
+
setError(null);
|
|
6695
|
+
(async () => {
|
|
6696
|
+
try {
|
|
6697
|
+
const bytes = await sourceToBytes(source, remote);
|
|
6698
|
+
const XLSX = await loadXlsx();
|
|
6699
|
+
const wb = XLSX.read(bytes, { type: "array" });
|
|
6700
|
+
const parsed = wb.SheetNames.map((name) => {
|
|
6701
|
+
const ws = wb.Sheets[name];
|
|
6702
|
+
const aoa = XLSX.utils.sheet_to_json(ws, { header: 1, blankrows: false, defval: null });
|
|
6703
|
+
const headerRow = aoa[0] ?? [];
|
|
6704
|
+
const columns2 = headerRow.map((h, i) => ({
|
|
6705
|
+
key: h != null && String(h).length ? String(h) : `col_${i}`,
|
|
6706
|
+
label: h != null && String(h).length ? String(h) : `Column ${i + 1}`
|
|
6707
|
+
}));
|
|
6708
|
+
const rows = aoa.slice(1).map((r) => {
|
|
6709
|
+
const rec = {};
|
|
6710
|
+
columns2.forEach((c, i) => {
|
|
6711
|
+
rec[c.key] = r[i] ?? null;
|
|
6712
|
+
});
|
|
6713
|
+
return rec;
|
|
6714
|
+
});
|
|
6715
|
+
return { name, columns: columns2, rows };
|
|
6716
|
+
});
|
|
6717
|
+
if (cancelled) return;
|
|
6718
|
+
setSheets(parsed);
|
|
6719
|
+
setActive(0);
|
|
6720
|
+
setStatus("ready");
|
|
6721
|
+
} catch (err) {
|
|
6722
|
+
if (cancelled) return;
|
|
6723
|
+
setError(err);
|
|
6724
|
+
setStatus("error");
|
|
6725
|
+
}
|
|
6726
|
+
})();
|
|
6727
|
+
return () => {
|
|
6728
|
+
cancelled = true;
|
|
6729
|
+
};
|
|
6730
|
+
}, [source, remote, reloadKey]);
|
|
6731
|
+
const sheet = sheets?.[active];
|
|
6732
|
+
const columns = React34.useMemo(() => sheet ? toColumns(sheet.columns) : [], [sheet]);
|
|
6733
|
+
const plainRows = React34.useMemo(() => sheet ? toPlainRows(sheet, columns) : [], [sheet, columns]);
|
|
6734
|
+
const handleCellEdit = React34.useCallback(({ row, column, value }) => {
|
|
6735
|
+
let coerced = value;
|
|
6736
|
+
setSheets((prev) => {
|
|
6737
|
+
if (!prev) return prev;
|
|
6738
|
+
const next = prev.map((s, i) => i === active ? { ...s, rows: s.rows.map((r) => ({ ...r })) } : s);
|
|
6739
|
+
const target = next[active];
|
|
6740
|
+
const existing = target.rows[row]?.[column];
|
|
6741
|
+
const prevValue = cellValue(existing);
|
|
6742
|
+
coerced = coerceToCellType(prevValue, value);
|
|
6743
|
+
if (existing != null && typeof existing === "object" && "value" in existing) {
|
|
6744
|
+
target.rows[row][column] = { ...existing, value: coerced };
|
|
6745
|
+
} else {
|
|
6746
|
+
target.rows[row][column] = coerced;
|
|
6747
|
+
}
|
|
6748
|
+
onChange?.(next);
|
|
6749
|
+
return next;
|
|
6750
|
+
});
|
|
6751
|
+
onCellEdit?.({ sheet: sheets?.[active]?.name ?? "", row, column, value: coerced });
|
|
6752
|
+
}, [active, onCellEdit, onChange, sheets]);
|
|
6753
|
+
const baseName = React34.useMemo(
|
|
6754
|
+
() => (fileName || (typeof source === "object" && "name" in source ? sourceName(source) : null) || "spreadsheet").replace(/\.[^.]+$/, ""),
|
|
6755
|
+
[fileName, source]
|
|
6756
|
+
);
|
|
6757
|
+
const sheetAoa = React34.useCallback((s) => {
|
|
6758
|
+
const cols = toColumns(s.columns);
|
|
6759
|
+
const header = cols.map((c) => typeof c.label === "string" ? c.label : c.key);
|
|
6760
|
+
const body = s.rows.map((r) => cols.map((c) => cellValue(r[c.key])));
|
|
6761
|
+
return [header, ...body];
|
|
6762
|
+
}, []);
|
|
6763
|
+
const exportXlsx = React34.useCallback(async () => {
|
|
6764
|
+
if (!sheets) return;
|
|
6765
|
+
const XLSX = await loadXlsx();
|
|
6766
|
+
const wb = XLSX.utils.book_new();
|
|
6767
|
+
sheets.forEach((s) => {
|
|
6768
|
+
const ws = XLSX.utils.aoa_to_sheet(sheetAoa(s));
|
|
6769
|
+
XLSX.utils.book_append_sheet(wb, ws, (s.name || "Sheet").slice(0, 31));
|
|
6770
|
+
});
|
|
6771
|
+
const out = XLSX.write(wb, { bookType: "xlsx", type: "array" });
|
|
6772
|
+
downloadBlob(new Blob([out], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), `${baseName}.xlsx`);
|
|
6773
|
+
}, [sheets, sheetAoa, baseName]);
|
|
6774
|
+
const exportCsv = React34.useCallback(() => {
|
|
6775
|
+
if (!sheet) return;
|
|
6776
|
+
const aoa = sheetAoa(sheet);
|
|
6777
|
+
const esc = (v) => {
|
|
6778
|
+
const s = v == null ? "" : String(v);
|
|
6779
|
+
return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
|
6780
|
+
};
|
|
6781
|
+
const csv = aoa.map((row) => row.map(esc).join(",")).join("\r\n");
|
|
6782
|
+
downloadBlob(new Blob([`\uFEFF${csv}`], { type: "text/csv;charset=utf-8" }), `${baseName}.csv`);
|
|
6783
|
+
}, [sheet, sheetAoa, baseName]);
|
|
6784
|
+
const exportPdf = React34.useCallback(async () => {
|
|
6785
|
+
if (!sheet) return;
|
|
6786
|
+
const { jsPDF } = await loadJspdf();
|
|
6787
|
+
const doc = new jsPDF({ orientation: "landscape", unit: "pt", format: "a4" });
|
|
6788
|
+
const aoa = sheetAoa(sheet);
|
|
6789
|
+
const margin2 = 32;
|
|
6790
|
+
const pageW = doc.internal.pageSize.getWidth();
|
|
6791
|
+
const pageH = doc.internal.pageSize.getHeight();
|
|
6792
|
+
const cols = aoa[0]?.length || 1;
|
|
6793
|
+
const colW = (pageW - margin2 * 2) / cols;
|
|
6794
|
+
const rowH = 18;
|
|
6795
|
+
let y = margin2;
|
|
6796
|
+
doc.setFontSize(9);
|
|
6797
|
+
const drawRow = (row, header) => {
|
|
6798
|
+
if (y + rowH > pageH - margin2) {
|
|
6799
|
+
doc.addPage();
|
|
6800
|
+
y = margin2;
|
|
6801
|
+
}
|
|
6802
|
+
doc.setFont("helvetica", header ? "bold" : "normal");
|
|
6803
|
+
row.forEach((cell, i) => {
|
|
6804
|
+
const text = cell == null ? "" : String(cell);
|
|
6805
|
+
doc.text(text.length > 24 ? `${text.slice(0, 23)}\u2026` : text, margin2 + i * colW + 2, y + 12);
|
|
6806
|
+
});
|
|
6807
|
+
doc.setDrawColor(210);
|
|
6808
|
+
doc.line(margin2, y + rowH, pageW - margin2, y + rowH);
|
|
6809
|
+
y += rowH;
|
|
6810
|
+
};
|
|
6811
|
+
doc.setFont("helvetica", "bold");
|
|
6812
|
+
doc.setFontSize(12);
|
|
6813
|
+
doc.text(sheet.name || baseName, margin2, y);
|
|
6814
|
+
y += 22;
|
|
6815
|
+
doc.setFontSize(9);
|
|
6816
|
+
aoa.forEach((row, i) => drawRow(row, i === 0));
|
|
6817
|
+
doc.save(`${baseName}.pdf`);
|
|
6818
|
+
}, [sheet, sheetAoa, baseName]);
|
|
6819
|
+
const runExport = (fmt) => {
|
|
6820
|
+
if (fmt === "xlsx") void exportXlsx();
|
|
6821
|
+
else if (fmt === "csv") exportCsv();
|
|
6822
|
+
else void exportPdf();
|
|
6823
|
+
};
|
|
6824
|
+
if (status === "error") {
|
|
6825
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col items-center justify-center gap-3 rounded-lg border border-border bg-surface p-8 text-center", className), style, children: [
|
|
6826
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-status-error", children: "Couldn\u2019t load the spreadsheet" }),
|
|
6827
|
+
error?.message && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-xs text-foreground-muted", children: error.message }),
|
|
6828
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button_default, { content: "Retry", size: "sm", variant: "outline", onClick: () => setReloadKey((k) => k + 1) })
|
|
6829
|
+
] });
|
|
6830
|
+
}
|
|
6831
|
+
if (status === "loading" || !sheets) {
|
|
6832
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("rounded-lg border border-border bg-surface-raised p-4", className), style, children: [
|
|
6833
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 32, className: "mb-3 rounded" }),
|
|
6834
|
+
/* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 360, className: "rounded" })
|
|
6835
|
+
] });
|
|
6836
|
+
}
|
|
6837
|
+
const formats = exportFormats || [];
|
|
6838
|
+
const exportLabels = {
|
|
6839
|
+
xlsx: "Excel workbook (.xlsx)",
|
|
6840
|
+
csv: "CSV \u2014 this sheet (.csv)",
|
|
6841
|
+
pdf: "PDF table (.pdf)"
|
|
6842
|
+
};
|
|
6843
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col overflow-hidden rounded-lg border border-border bg-surface-raised", className), style, children: [
|
|
6844
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 items-center gap-2 border-b border-border bg-surface px-2 py-1.5", children: [
|
|
6845
|
+
sheets.length > 1 ? /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", "aria-label": "Sheets", className: "flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto", children: sheets.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
6846
|
+
"button",
|
|
6847
|
+
{
|
|
6848
|
+
role: "tab",
|
|
6849
|
+
type: "button",
|
|
6850
|
+
"aria-selected": i === active,
|
|
6851
|
+
onClick: () => setActive(i),
|
|
6852
|
+
className: cx(
|
|
6853
|
+
"flex-shrink-0 rounded-md px-3 py-1 text-sm font-medium transition-colors",
|
|
6854
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
6855
|
+
i === active ? "bg-accent text-accent-fg shadow-sm" : "text-foreground-secondary hover:bg-surface-raised hover:text-foreground"
|
|
6856
|
+
),
|
|
6857
|
+
children: s.name || `Sheet ${i + 1}`
|
|
6858
|
+
},
|
|
6859
|
+
`${s.name}-${i}`
|
|
6860
|
+
)) }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate px-1 text-sm font-medium text-foreground", children: sheet?.name || "Sheet 1" }),
|
|
6861
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "hidden flex-shrink-0 px-1 text-xs tabular-nums text-foreground-muted sm:inline", children: [
|
|
6862
|
+
plainRows.length.toLocaleString(),
|
|
6863
|
+
" ",
|
|
6864
|
+
plainRows.length === 1 ? "row" : "rows",
|
|
6865
|
+
" \xB7 ",
|
|
6866
|
+
columns.length,
|
|
6867
|
+
" cols"
|
|
6868
|
+
] }),
|
|
6869
|
+
formats.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6870
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-5 w-px flex-shrink-0 bg-border", "aria-hidden": "true" }),
|
|
6871
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6872
|
+
MenuButton,
|
|
6873
|
+
{
|
|
6874
|
+
label: "Export",
|
|
6875
|
+
size: "sm",
|
|
6876
|
+
variant: "outline",
|
|
6877
|
+
align: "end",
|
|
6878
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon2, {}),
|
|
6879
|
+
items: formats.map((fmt) => ({
|
|
6880
|
+
key: fmt,
|
|
6881
|
+
label: exportLabels[fmt],
|
|
6882
|
+
onSelect: () => runExport(fmt)
|
|
6883
|
+
}))
|
|
6884
|
+
}
|
|
6885
|
+
)
|
|
6886
|
+
] })
|
|
6887
|
+
] }),
|
|
6888
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6889
|
+
DataGrid,
|
|
6890
|
+
{
|
|
6891
|
+
columns,
|
|
6892
|
+
rows: plainRows,
|
|
6893
|
+
editable,
|
|
6894
|
+
virtualize,
|
|
6895
|
+
onCellEdit: handleCellEdit,
|
|
6896
|
+
className: "!rounded-none !border-0"
|
|
6897
|
+
}
|
|
6898
|
+
)
|
|
6899
|
+
] });
|
|
6900
|
+
}
|
|
6901
|
+
var DownloadIcon2 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 3v12m0 0 4-4m-4 4-4-4M4 21h16" }) });
|
|
5952
6902
|
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
|
|
5953
|
-
const id =
|
|
6903
|
+
const id = React34.useId();
|
|
5954
6904
|
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5955
6905
|
SwitchPrimitive__namespace.Root,
|
|
5956
6906
|
{
|
|
@@ -6048,8 +6998,8 @@ function FlyoutItems({ items }) {
|
|
|
6048
6998
|
}) });
|
|
6049
6999
|
}
|
|
6050
7000
|
function CollapsedFlyout({ item, trigger }) {
|
|
6051
|
-
const [open, setOpen] =
|
|
6052
|
-
const closeTimer =
|
|
7001
|
+
const [open, setOpen] = React34.useState(false);
|
|
7002
|
+
const closeTimer = React34__default.default.useRef(void 0);
|
|
6053
7003
|
const openNow = () => {
|
|
6054
7004
|
window.clearTimeout(closeTimer.current);
|
|
6055
7005
|
setOpen(true);
|
|
@@ -6058,7 +7008,7 @@ function CollapsedFlyout({ item, trigger }) {
|
|
|
6058
7008
|
window.clearTimeout(closeTimer.current);
|
|
6059
7009
|
closeTimer.current = window.setTimeout(() => setOpen(false), 150);
|
|
6060
7010
|
};
|
|
6061
|
-
|
|
7011
|
+
React34__default.default.useEffect(() => () => window.clearTimeout(closeTimer.current), []);
|
|
6062
7012
|
return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu2__namespace.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
6063
7013
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6064
7014
|
DropdownMenu2__namespace.Trigger,
|
|
@@ -6096,7 +7046,7 @@ function NavItem({
|
|
|
6096
7046
|
depth = 0
|
|
6097
7047
|
}) {
|
|
6098
7048
|
const hasChildren = !!(item.items && item.items.length);
|
|
6099
|
-
const [open, setOpen] =
|
|
7049
|
+
const [open, setOpen] = React34.useState(item.defaultOpen ?? (hasChildren && hasActiveDescendant(item)));
|
|
6100
7050
|
const handleClick = () => {
|
|
6101
7051
|
if (hasChildren && isExpanded) setOpen((o) => !o);
|
|
6102
7052
|
item.onClick?.();
|
|
@@ -6234,7 +7184,7 @@ function Sidebar({
|
|
|
6234
7184
|
}
|
|
6235
7185
|
) });
|
|
6236
7186
|
}
|
|
6237
|
-
var MegaMenuContext =
|
|
7187
|
+
var MegaMenuContext = React34.createContext({ align: "start" });
|
|
6238
7188
|
function MegaMenu({
|
|
6239
7189
|
children,
|
|
6240
7190
|
align = "start",
|
|
@@ -6265,7 +7215,7 @@ function MegaMenu({
|
|
|
6265
7215
|
}
|
|
6266
7216
|
var TOP_ITEM = "group/top inline-flex items-center gap-1.5 h-10 px-3 rounded-md text-sm font-medium select-none text-foreground-secondary hover:text-foreground hover:bg-surface-raised data-[state=open]:text-accent data-[active]:text-accent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent";
|
|
6267
7217
|
function MegaMenuItem({ label, icon, href, children, className = "" }) {
|
|
6268
|
-
const { align } =
|
|
7218
|
+
const { align } = React34.useContext(MegaMenuContext);
|
|
6269
7219
|
const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
|
|
6270
7220
|
if (!children) {
|
|
6271
7221
|
return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: cx(TOP_ITEM, className), children: [
|
|
@@ -6350,8 +7300,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
6350
7300
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
6351
7301
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className), children });
|
|
6352
7302
|
}
|
|
6353
|
-
var elementsOfType = (children, type) =>
|
|
6354
|
-
(c) =>
|
|
7303
|
+
var elementsOfType = (children, type) => React34__default.default.Children.toArray(children).filter(
|
|
7304
|
+
(c) => React34__default.default.isValidElement(c) && c.type === type
|
|
6355
7305
|
);
|
|
6356
7306
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6357
7307
|
"svg",
|
|
@@ -6388,9 +7338,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
6388
7338
|
);
|
|
6389
7339
|
}
|
|
6390
7340
|
function MobilePanel({ panel, onNavigate }) {
|
|
6391
|
-
const nodes =
|
|
7341
|
+
const nodes = React34__default.default.Children.toArray(panel.props.children);
|
|
6392
7342
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
6393
|
-
if (!
|
|
7343
|
+
if (!React34__default.default.isValidElement(node)) return null;
|
|
6394
7344
|
const el = node;
|
|
6395
7345
|
if (el.type === MegaMenuSection) {
|
|
6396
7346
|
const { title, children } = el.props;
|
|
@@ -6409,8 +7359,8 @@ function MegaMenuMobile({
|
|
|
6409
7359
|
children,
|
|
6410
7360
|
label
|
|
6411
7361
|
}) {
|
|
6412
|
-
const [open, setOpen] =
|
|
6413
|
-
const [expanded, setExpanded] =
|
|
7362
|
+
const [open, setOpen] = React34.useState(false);
|
|
7363
|
+
const [expanded, setExpanded] = React34.useState(null);
|
|
6414
7364
|
const items = elementsOfType(children, MegaMenuItem);
|
|
6415
7365
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
|
|
6416
7366
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6483,17 +7433,17 @@ function AppShell({
|
|
|
6483
7433
|
children,
|
|
6484
7434
|
className = ""
|
|
6485
7435
|
}) {
|
|
6486
|
-
const [expanded, setExpanded] =
|
|
6487
|
-
const [isMobile, setIsMobile] =
|
|
6488
|
-
const [mobileOpen, setMobileOpen] =
|
|
6489
|
-
|
|
7436
|
+
const [expanded, setExpanded] = React34.useState(sidebarDefaultExpanded);
|
|
7437
|
+
const [isMobile, setIsMobile] = React34.useState(false);
|
|
7438
|
+
const [mobileOpen, setMobileOpen] = React34.useState(false);
|
|
7439
|
+
React34.useEffect(() => {
|
|
6490
7440
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
6491
7441
|
const update = (e) => setIsMobile(e.matches);
|
|
6492
7442
|
update(mq);
|
|
6493
7443
|
mq.addEventListener("change", update);
|
|
6494
7444
|
return () => mq.removeEventListener("change", update);
|
|
6495
7445
|
}, []);
|
|
6496
|
-
|
|
7446
|
+
React34.useEffect(() => {
|
|
6497
7447
|
if (!isMobile) setMobileOpen(false);
|
|
6498
7448
|
}, [isMobile]);
|
|
6499
7449
|
const hasSidebar = sidebarSections.length > 0;
|
|
@@ -6620,7 +7570,7 @@ function SecureLayout({
|
|
|
6620
7570
|
className = ""
|
|
6621
7571
|
}) {
|
|
6622
7572
|
const reduced = framerMotion.useReducedMotion();
|
|
6623
|
-
const cbs =
|
|
7573
|
+
const cbs = React34.useRef({ canAccess, onGranted, onDeny });
|
|
6624
7574
|
cbs.current = { canAccess, onGranted, onDeny };
|
|
6625
7575
|
const rolesKey = JSON.stringify(roles);
|
|
6626
7576
|
const requiredRolesKey = JSON.stringify(requiredRoles);
|
|
@@ -6635,10 +7585,10 @@ function SecureLayout({
|
|
|
6635
7585
|
if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
|
|
6636
7586
|
return true;
|
|
6637
7587
|
};
|
|
6638
|
-
const [state, setState] =
|
|
7588
|
+
const [state, setState] = React34.useState(
|
|
6639
7589
|
() => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
|
|
6640
7590
|
);
|
|
6641
|
-
|
|
7591
|
+
React34.useEffect(() => {
|
|
6642
7592
|
let cancelled = false;
|
|
6643
7593
|
const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
|
|
6644
7594
|
const finish = (ok) => {
|
|
@@ -6799,10 +7749,10 @@ function ThemeProvider({
|
|
|
6799
7749
|
className = "",
|
|
6800
7750
|
style
|
|
6801
7751
|
}) {
|
|
6802
|
-
const id =
|
|
7752
|
+
const id = React34__default.default.useId().replace(/:/g, "");
|
|
6803
7753
|
const scopeClass = `geo-th-${id}`;
|
|
6804
|
-
const divRef =
|
|
6805
|
-
|
|
7754
|
+
const divRef = React34.useRef(null);
|
|
7755
|
+
React34.useEffect(() => {
|
|
6806
7756
|
const el = divRef.current;
|
|
6807
7757
|
if (!el) return;
|
|
6808
7758
|
if (colorScheme === "auto") return;
|
|
@@ -6817,8 +7767,8 @@ function ThemeProvider({
|
|
|
6817
7767
|
}
|
|
6818
7768
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
6819
7769
|
}, [colorScheme]);
|
|
6820
|
-
const lightVars =
|
|
6821
|
-
const darkVarStr =
|
|
7770
|
+
const lightVars = React34.useMemo(() => toCssVars(theme), [theme]);
|
|
7771
|
+
const darkVarStr = React34.useMemo(() => {
|
|
6822
7772
|
if (!darkTheme) return "";
|
|
6823
7773
|
const dvars = toCssVars(darkTheme);
|
|
6824
7774
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -6860,7 +7810,7 @@ function NumberInput({
|
|
|
6860
7810
|
readOnly = false,
|
|
6861
7811
|
precision
|
|
6862
7812
|
}) {
|
|
6863
|
-
const errorId =
|
|
7813
|
+
const errorId = React34.useId();
|
|
6864
7814
|
const hasError = errorMessage != null;
|
|
6865
7815
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
6866
7816
|
const round = (n) => {
|
|
@@ -6991,8 +7941,8 @@ function Password({
|
|
|
6991
7941
|
showIcon,
|
|
6992
7942
|
hideIcon
|
|
6993
7943
|
}) {
|
|
6994
|
-
const [visible, setVisible] =
|
|
6995
|
-
const errorId =
|
|
7944
|
+
const [visible, setVisible] = React34.useState(false);
|
|
7945
|
+
const errorId = React34.useId();
|
|
6996
7946
|
const hasError = errorMessage != null;
|
|
6997
7947
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6998
7948
|
Field,
|
|
@@ -7092,7 +8042,7 @@ function PasswordStrength({
|
|
|
7092
8042
|
className = "",
|
|
7093
8043
|
style
|
|
7094
8044
|
}) {
|
|
7095
|
-
const { score, label } =
|
|
8045
|
+
const { score, label } = React34.useMemo(() => scorer(value), [scorer, value]);
|
|
7096
8046
|
const showMatch = confirmValue != null && (value.length > 0 || confirmValue.length > 0);
|
|
7097
8047
|
const matches = value.length > 0 && value === confirmValue;
|
|
7098
8048
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col gap-2", className), style, "aria-live": "polite", children: [
|
|
@@ -7151,8 +8101,8 @@ function RadioTile({
|
|
|
7151
8101
|
errorMessage,
|
|
7152
8102
|
className
|
|
7153
8103
|
}) {
|
|
7154
|
-
const groupId =
|
|
7155
|
-
const errorId =
|
|
8104
|
+
const groupId = React34.useId();
|
|
8105
|
+
const errorId = React34.useId();
|
|
7156
8106
|
const hasError = errorMessage != null;
|
|
7157
8107
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7158
8108
|
Field,
|
|
@@ -7227,7 +8177,7 @@ function Checkbox({
|
|
|
7227
8177
|
}) {
|
|
7228
8178
|
const isChecked = checked ?? value ?? false;
|
|
7229
8179
|
const labelFirst = labelPosition === "left";
|
|
7230
|
-
const errorId =
|
|
8180
|
+
const errorId = React34.useId();
|
|
7231
8181
|
const hasError = errorMessage != null;
|
|
7232
8182
|
const box = /* @__PURE__ */ jsxRuntime.jsx(
|
|
7233
8183
|
CheckboxPrimitive__namespace.Root,
|
|
@@ -7335,8 +8285,8 @@ function RadioGroup({
|
|
|
7335
8285
|
className,
|
|
7336
8286
|
errorMessage
|
|
7337
8287
|
}) {
|
|
7338
|
-
const errorId =
|
|
7339
|
-
const groupId =
|
|
8288
|
+
const errorId = React34.useId();
|
|
8289
|
+
const groupId = React34.useId();
|
|
7340
8290
|
const hasError = errorMessage != null;
|
|
7341
8291
|
const labelFirst = labelPosition === "left";
|
|
7342
8292
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7436,11 +8386,11 @@ function Switch({
|
|
|
7436
8386
|
disabled,
|
|
7437
8387
|
errorMessage
|
|
7438
8388
|
}) {
|
|
7439
|
-
const id =
|
|
7440
|
-
const errorId =
|
|
8389
|
+
const id = React34.useId();
|
|
8390
|
+
const errorId = React34.useId();
|
|
7441
8391
|
const hasError = errorMessage != null;
|
|
7442
8392
|
const isControlled = checked !== void 0;
|
|
7443
|
-
const [internal, setInternal] =
|
|
8393
|
+
const [internal, setInternal] = React34.useState(defaultChecked);
|
|
7444
8394
|
const isOn = isControlled ? checked : internal;
|
|
7445
8395
|
const handle = (c) => {
|
|
7446
8396
|
if (!isControlled) setInternal(c);
|
|
@@ -7516,15 +8466,15 @@ function MultiTagRow({
|
|
|
7516
8466
|
labelFor,
|
|
7517
8467
|
onRemove
|
|
7518
8468
|
}) {
|
|
7519
|
-
const wrapRef =
|
|
7520
|
-
const measureRef =
|
|
7521
|
-
const [visibleCount, setVisibleCount] =
|
|
8469
|
+
const wrapRef = React34.useRef(null);
|
|
8470
|
+
const measureRef = React34.useRef(null);
|
|
8471
|
+
const [visibleCount, setVisibleCount] = React34.useState(values.length);
|
|
7522
8472
|
const key = values.map(String).join("|");
|
|
7523
|
-
|
|
8473
|
+
React34.useLayoutEffect(() => {
|
|
7524
8474
|
const wrap = wrapRef.current;
|
|
7525
8475
|
const measure = measureRef.current;
|
|
7526
8476
|
if (!wrap || !measure) return;
|
|
7527
|
-
const
|
|
8477
|
+
const GAP2 = 6;
|
|
7528
8478
|
const recompute = () => {
|
|
7529
8479
|
const avail = wrap.clientWidth;
|
|
7530
8480
|
const tagEls = Array.from(measure.querySelectorAll("[data-mt]"));
|
|
@@ -7538,7 +8488,7 @@ function MultiTagRow({
|
|
|
7538
8488
|
let used = 0;
|
|
7539
8489
|
let count = 0;
|
|
7540
8490
|
for (let i = 0; i < widths.length; i++) {
|
|
7541
|
-
const w = widths[i] + (i > 0 ?
|
|
8491
|
+
const w = widths[i] + (i > 0 ? GAP2 : 0);
|
|
7542
8492
|
if (used + w <= avail) {
|
|
7543
8493
|
used += w;
|
|
7544
8494
|
count++;
|
|
@@ -7547,8 +8497,8 @@ function MultiTagRow({
|
|
|
7547
8497
|
if (count < widths.length) {
|
|
7548
8498
|
while (count > 0) {
|
|
7549
8499
|
let t = 0;
|
|
7550
|
-
for (let i = 0; i < count; i++) t += widths[i] + (i > 0 ?
|
|
7551
|
-
t +=
|
|
8500
|
+
for (let i = 0; i < count; i++) t += widths[i] + (i > 0 ? GAP2 : 0);
|
|
8501
|
+
t += GAP2 + moreW;
|
|
7552
8502
|
if (t <= avail) break;
|
|
7553
8503
|
count--;
|
|
7554
8504
|
}
|
|
@@ -7614,16 +8564,16 @@ function Dropdown({
|
|
|
7614
8564
|
size = "md",
|
|
7615
8565
|
className = ""
|
|
7616
8566
|
}) {
|
|
7617
|
-
const [open, setOpen] =
|
|
7618
|
-
const [selectedItems, setSelectedItems] =
|
|
7619
|
-
const [searchTerm, setSearchTerm] =
|
|
7620
|
-
const [innerItems, setInnerItems] =
|
|
7621
|
-
const errorId =
|
|
8567
|
+
const [open, setOpen] = React34.useState(false);
|
|
8568
|
+
const [selectedItems, setSelectedItems] = React34.useState([]);
|
|
8569
|
+
const [searchTerm, setSearchTerm] = React34.useState("");
|
|
8570
|
+
const [innerItems, setInnerItems] = React34.useState([]);
|
|
8571
|
+
const errorId = React34.useId();
|
|
7622
8572
|
const hasError = errorMessage != null;
|
|
7623
|
-
|
|
8573
|
+
React34.useEffect(() => {
|
|
7624
8574
|
setInnerItems(items);
|
|
7625
8575
|
}, [items]);
|
|
7626
|
-
|
|
8576
|
+
React34.useEffect(() => {
|
|
7627
8577
|
if (isMultiselect && Array.isArray(value)) {
|
|
7628
8578
|
setSelectedItems(value);
|
|
7629
8579
|
}
|
|
@@ -7816,19 +8766,19 @@ function AutoComplete({
|
|
|
7816
8766
|
required,
|
|
7817
8767
|
htmlFor
|
|
7818
8768
|
}) {
|
|
7819
|
-
const errorId =
|
|
8769
|
+
const errorId = React34.useId();
|
|
7820
8770
|
const hasError = errorMessage != null;
|
|
7821
|
-
const [term, setTerm] =
|
|
7822
|
-
const [open, setOpen] =
|
|
7823
|
-
const [asyncItems, setAsyncItems] =
|
|
7824
|
-
const [loading, setLoading] =
|
|
8771
|
+
const [term, setTerm] = React34.useState("");
|
|
8772
|
+
const [open, setOpen] = React34.useState(false);
|
|
8773
|
+
const [asyncItems, setAsyncItems] = React34.useState([]);
|
|
8774
|
+
const [loading, setLoading] = React34.useState(false);
|
|
7825
8775
|
const isAsync = typeof onSearch === "function";
|
|
7826
|
-
const debounceRef =
|
|
7827
|
-
const requestIdRef =
|
|
8776
|
+
const debounceRef = React34.useRef(null);
|
|
8777
|
+
const requestIdRef = React34.useRef(0);
|
|
7828
8778
|
const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
|
|
7829
8779
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
7830
8780
|
) : [];
|
|
7831
|
-
|
|
8781
|
+
React34.useEffect(() => {
|
|
7832
8782
|
if (!isAsync) return;
|
|
7833
8783
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
7834
8784
|
if (!term.trim()) {
|
|
@@ -7985,15 +8935,15 @@ function TreeSelect({
|
|
|
7985
8935
|
defaultExpandedKeys = [],
|
|
7986
8936
|
size = "md"
|
|
7987
8937
|
}) {
|
|
7988
|
-
const errorId =
|
|
8938
|
+
const errorId = React34.useId();
|
|
7989
8939
|
const hasError = errorMessage != null;
|
|
7990
|
-
const [open, setOpen] =
|
|
7991
|
-
const [expanded, setExpanded] =
|
|
7992
|
-
const [activeIndex, setActiveIndex] =
|
|
7993
|
-
const listRef =
|
|
7994
|
-
const visible =
|
|
7995
|
-
const didSyncOnOpenRef =
|
|
7996
|
-
|
|
8940
|
+
const [open, setOpen] = React34.useState(false);
|
|
8941
|
+
const [expanded, setExpanded] = React34.useState(() => new Set(defaultExpandedKeys));
|
|
8942
|
+
const [activeIndex, setActiveIndex] = React34.useState(0);
|
|
8943
|
+
const listRef = React34.useRef(null);
|
|
8944
|
+
const visible = React34.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
|
|
8945
|
+
const didSyncOnOpenRef = React34.useRef(false);
|
|
8946
|
+
React34.useEffect(() => {
|
|
7997
8947
|
if (!open) {
|
|
7998
8948
|
didSyncOnOpenRef.current = false;
|
|
7999
8949
|
return;
|
|
@@ -8003,7 +8953,7 @@ function TreeSelect({
|
|
|
8003
8953
|
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
8004
8954
|
didSyncOnOpenRef.current = true;
|
|
8005
8955
|
}, [open, value]);
|
|
8006
|
-
const selectedNode =
|
|
8956
|
+
const selectedNode = React34.useMemo(
|
|
8007
8957
|
() => value != null ? findNodeByKey(items, value) : null,
|
|
8008
8958
|
[items, value]
|
|
8009
8959
|
);
|
|
@@ -8235,11 +9185,11 @@ function FileInput({
|
|
|
8235
9185
|
required,
|
|
8236
9186
|
icon
|
|
8237
9187
|
}) {
|
|
8238
|
-
const inputRef =
|
|
8239
|
-
const errorId =
|
|
8240
|
-
const [files, setFiles] =
|
|
8241
|
-
const [dragging, setDragging] =
|
|
8242
|
-
const [sizeError, setSizeError] =
|
|
9188
|
+
const inputRef = React34.useRef(null);
|
|
9189
|
+
const errorId = React34.useId();
|
|
9190
|
+
const [files, setFiles] = React34.useState([]);
|
|
9191
|
+
const [dragging, setDragging] = React34.useState(false);
|
|
9192
|
+
const [sizeError, setSizeError] = React34.useState(null);
|
|
8243
9193
|
const effectiveError = errorMessage ?? sizeError ?? void 0;
|
|
8244
9194
|
const openPicker = () => {
|
|
8245
9195
|
if (!disabled) inputRef.current?.click();
|
|
@@ -8430,30 +9380,30 @@ function DatePicker({
|
|
|
8430
9380
|
size = "md",
|
|
8431
9381
|
className = ""
|
|
8432
9382
|
}) {
|
|
8433
|
-
const errorId =
|
|
9383
|
+
const errorId = React34.useId();
|
|
8434
9384
|
const hasError = errorMessage != null;
|
|
8435
|
-
const [open, setOpen] =
|
|
8436
|
-
const [viewMonth, setViewMonth] =
|
|
8437
|
-
const [focusDate, setFocusDate] =
|
|
8438
|
-
const [view, setView] =
|
|
8439
|
-
const gridRef =
|
|
8440
|
-
|
|
9385
|
+
const [open, setOpen] = React34.useState(false);
|
|
9386
|
+
const [viewMonth, setViewMonth] = React34.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
9387
|
+
const [focusDate, setFocusDate] = React34.useState(() => value ?? /* @__PURE__ */ new Date());
|
|
9388
|
+
const [view, setView] = React34.useState("days");
|
|
9389
|
+
const gridRef = React34.useRef(null);
|
|
9390
|
+
React34.useEffect(() => {
|
|
8441
9391
|
if (!open) return;
|
|
8442
9392
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
8443
9393
|
setViewMonth(startOfMonth2(target));
|
|
8444
9394
|
setFocusDate(target);
|
|
8445
9395
|
setView("days");
|
|
8446
9396
|
}, [open, value]);
|
|
8447
|
-
|
|
9397
|
+
React34.useEffect(() => {
|
|
8448
9398
|
if (!open) return;
|
|
8449
9399
|
const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
|
|
8450
9400
|
cell?.focus();
|
|
8451
9401
|
}, [open, focusDate]);
|
|
8452
|
-
const weekdays =
|
|
9402
|
+
const weekdays = React34.useMemo(() => {
|
|
8453
9403
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
8454
9404
|
return ordered;
|
|
8455
9405
|
}, [weekStartsOn]);
|
|
8456
|
-
const grid =
|
|
9406
|
+
const grid = React34.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
8457
9407
|
const isDisabled = (d) => {
|
|
8458
9408
|
if (min && d < min) return true;
|
|
8459
9409
|
if (max && d > max) return true;
|
|
@@ -8508,7 +9458,7 @@ function DatePicker({
|
|
|
8508
9458
|
setOpen(false);
|
|
8509
9459
|
}
|
|
8510
9460
|
};
|
|
8511
|
-
const
|
|
9461
|
+
const displayValue2 = value ? format(value) : "";
|
|
8512
9462
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1 ${className}`.trim(), children: [
|
|
8513
9463
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex ${layout === "vertical" ? "flex-col gap-1.5" : "flex-row items-start gap-3"}`, children: [
|
|
8514
9464
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8535,7 +9485,7 @@ function DatePicker({
|
|
|
8535
9485
|
"aria-expanded": open,
|
|
8536
9486
|
className: `flex items-center justify-between cursor-pointer select-none ${!style?.width ? "min-w-[200px]" : ""} ${fieldShell({ size, hasError, disabled })}`,
|
|
8537
9487
|
children: [
|
|
8538
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm truncate ${
|
|
9488
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm truncate ${displayValue2 ? "" : "text-foreground-muted"}`, children: displayValue2 || placeholder }),
|
|
8539
9489
|
/* @__PURE__ */ jsxRuntime.jsx(CalendarIcon, {})
|
|
8540
9490
|
]
|
|
8541
9491
|
}
|
|
@@ -8744,10 +9694,10 @@ function TextArea({
|
|
|
8744
9694
|
style,
|
|
8745
9695
|
inputStyle
|
|
8746
9696
|
}) {
|
|
8747
|
-
const errorId =
|
|
9697
|
+
const errorId = React34.useId();
|
|
8748
9698
|
const hasError = errorMessage != null;
|
|
8749
|
-
const ref =
|
|
8750
|
-
|
|
9699
|
+
const ref = React34.useRef(null);
|
|
9700
|
+
React34.useLayoutEffect(() => {
|
|
8751
9701
|
if (!autoGrow) return;
|
|
8752
9702
|
const el = ref.current;
|
|
8753
9703
|
if (!el) return;
|
|
@@ -8819,14 +9769,14 @@ function Slider({
|
|
|
8819
9769
|
name,
|
|
8820
9770
|
htmlFor
|
|
8821
9771
|
}) {
|
|
8822
|
-
const errorId =
|
|
9772
|
+
const errorId = React34.useId();
|
|
8823
9773
|
const hasError = errorMessage != null;
|
|
8824
9774
|
const isRange = Array.isArray(value ?? defaultValue);
|
|
8825
|
-
const [internal, setInternal] =
|
|
9775
|
+
const [internal, setInternal] = React34.useState(
|
|
8826
9776
|
() => toArray(value) ?? toArray(defaultValue) ?? [min]
|
|
8827
9777
|
);
|
|
8828
9778
|
const current = toArray(value) ?? internal;
|
|
8829
|
-
const [dragging, setDragging] =
|
|
9779
|
+
const [dragging, setDragging] = React34.useState(false);
|
|
8830
9780
|
const emit = (arr) => {
|
|
8831
9781
|
setInternal(arr);
|
|
8832
9782
|
const next = isRange ? [arr[0], arr[1]] : arr[0];
|
|
@@ -8921,11 +9871,11 @@ function TagsInput({
|
|
|
8921
9871
|
validate,
|
|
8922
9872
|
separators = ["Enter", ","]
|
|
8923
9873
|
}) {
|
|
8924
|
-
const errorId =
|
|
8925
|
-
const inputRef =
|
|
8926
|
-
const [internal, setInternal] =
|
|
8927
|
-
const [draft, setDraft] =
|
|
8928
|
-
const [localError, setLocalError] =
|
|
9874
|
+
const errorId = React34.useId();
|
|
9875
|
+
const inputRef = React34.useRef(null);
|
|
9876
|
+
const [internal, setInternal] = React34.useState(defaultValue ?? []);
|
|
9877
|
+
const [draft, setDraft] = React34.useState("");
|
|
9878
|
+
const [localError, setLocalError] = React34.useState(null);
|
|
8929
9879
|
const tags = value ?? internal;
|
|
8930
9880
|
const hasError = errorMessage != null || localError != null;
|
|
8931
9881
|
const errorText = errorMessage ?? localError ?? void 0;
|
|
@@ -9056,9 +10006,9 @@ function OtpInput({
|
|
|
9056
10006
|
className,
|
|
9057
10007
|
groupAfter
|
|
9058
10008
|
}) {
|
|
9059
|
-
const errorId =
|
|
10009
|
+
const errorId = React34.useId();
|
|
9060
10010
|
const hasError = errorMessage != null;
|
|
9061
|
-
const refs =
|
|
10011
|
+
const refs = React34.useRef([]);
|
|
9062
10012
|
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
9063
10013
|
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
9064
10014
|
const emit = (next) => {
|
|
@@ -9107,7 +10057,7 @@ function OtpInput({
|
|
|
9107
10057
|
emit(valid.join(""));
|
|
9108
10058
|
focusBox(valid.length);
|
|
9109
10059
|
};
|
|
9110
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10060
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React34__default.default.Fragment, { children: [
|
|
9111
10061
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9112
10062
|
"input",
|
|
9113
10063
|
{
|
|
@@ -9165,9 +10115,9 @@ function Rating({
|
|
|
9165
10115
|
className,
|
|
9166
10116
|
required
|
|
9167
10117
|
}) {
|
|
9168
|
-
const errorId =
|
|
9169
|
-
const [internal, setInternal] =
|
|
9170
|
-
const [hover, setHover] =
|
|
10118
|
+
const errorId = React34.useId();
|
|
10119
|
+
const [internal, setInternal] = React34.useState(defaultValue);
|
|
10120
|
+
const [hover, setHover] = React34.useState(null);
|
|
9171
10121
|
const current = value ?? internal;
|
|
9172
10122
|
const display2 = hover ?? current;
|
|
9173
10123
|
const interactive = !readOnly && !disabled;
|
|
@@ -9290,9 +10240,9 @@ function TimePicker({
|
|
|
9290
10240
|
required,
|
|
9291
10241
|
style
|
|
9292
10242
|
}) {
|
|
9293
|
-
const errorId =
|
|
10243
|
+
const errorId = React34.useId();
|
|
9294
10244
|
const hasError = errorMessage != null;
|
|
9295
|
-
const [open, setOpen] =
|
|
10245
|
+
const [open, setOpen] = React34.useState(false);
|
|
9296
10246
|
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
9297
10247
|
const update = (next) => {
|
|
9298
10248
|
const merged = { ...parsed, ...next };
|
|
@@ -9417,13 +10367,13 @@ function DateRangePicker({
|
|
|
9417
10367
|
required,
|
|
9418
10368
|
style
|
|
9419
10369
|
}) {
|
|
9420
|
-
const errorId =
|
|
10370
|
+
const errorId = React34.useId();
|
|
9421
10371
|
const hasError = errorMessage != null;
|
|
9422
|
-
const [open, setOpen] =
|
|
9423
|
-
const [leftMonth, setLeftMonth] =
|
|
9424
|
-
const [pendingStart, setPendingStart] =
|
|
9425
|
-
const [hoverDate, setHoverDate] =
|
|
9426
|
-
const weekdays =
|
|
10372
|
+
const [open, setOpen] = React34.useState(false);
|
|
10373
|
+
const [leftMonth, setLeftMonth] = React34.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
10374
|
+
const [pendingStart, setPendingStart] = React34.useState(null);
|
|
10375
|
+
const [hoverDate, setHoverDate] = React34.useState(null);
|
|
10376
|
+
const weekdays = React34.useMemo(
|
|
9427
10377
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
9428
10378
|
[weekStartsOn]
|
|
9429
10379
|
);
|
|
@@ -9600,10 +10550,10 @@ function ColorPicker({
|
|
|
9600
10550
|
required,
|
|
9601
10551
|
placeholder = "Pick a colour\u2026"
|
|
9602
10552
|
}) {
|
|
9603
|
-
const errorId =
|
|
10553
|
+
const errorId = React34.useId();
|
|
9604
10554
|
const hasError = errorMessage != null;
|
|
9605
|
-
const [open, setOpen] =
|
|
9606
|
-
const [draft, setDraft] =
|
|
10555
|
+
const [open, setOpen] = React34.useState(false);
|
|
10556
|
+
const [draft, setDraft] = React34.useState(value);
|
|
9607
10557
|
const valid = HEX_RE.test(value);
|
|
9608
10558
|
const pick = (hex) => {
|
|
9609
10559
|
onChange?.(hex);
|
|
@@ -9691,7 +10641,7 @@ function ColorPicker({
|
|
|
9691
10641
|
}
|
|
9692
10642
|
var CUSTOM_EVENT = "oxy-local-storage";
|
|
9693
10643
|
function useLocalStorage(key, initialValue) {
|
|
9694
|
-
const read =
|
|
10644
|
+
const read = React34.useCallback(() => {
|
|
9695
10645
|
if (typeof window === "undefined") return initialValue;
|
|
9696
10646
|
try {
|
|
9697
10647
|
const item = window.localStorage.getItem(key);
|
|
@@ -9700,8 +10650,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
9700
10650
|
return initialValue;
|
|
9701
10651
|
}
|
|
9702
10652
|
}, [key]);
|
|
9703
|
-
const [stored, setStored] =
|
|
9704
|
-
const setValue =
|
|
10653
|
+
const [stored, setStored] = React34.useState(read);
|
|
10654
|
+
const setValue = React34.useCallback((value) => {
|
|
9705
10655
|
setStored((prev) => {
|
|
9706
10656
|
const next = value instanceof Function ? value(prev) : value;
|
|
9707
10657
|
try {
|
|
@@ -9714,7 +10664,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
9714
10664
|
return next;
|
|
9715
10665
|
});
|
|
9716
10666
|
}, [key]);
|
|
9717
|
-
const remove =
|
|
10667
|
+
const remove = React34.useCallback(() => {
|
|
9718
10668
|
try {
|
|
9719
10669
|
if (typeof window !== "undefined") {
|
|
9720
10670
|
window.localStorage.removeItem(key);
|
|
@@ -9724,10 +10674,10 @@ function useLocalStorage(key, initialValue) {
|
|
|
9724
10674
|
}
|
|
9725
10675
|
setStored(initialValue);
|
|
9726
10676
|
}, [key]);
|
|
9727
|
-
|
|
10677
|
+
React34.useEffect(() => {
|
|
9728
10678
|
setStored(read());
|
|
9729
10679
|
}, [key, read]);
|
|
9730
|
-
|
|
10680
|
+
React34.useEffect(() => {
|
|
9731
10681
|
if (typeof window === "undefined") return;
|
|
9732
10682
|
const onStorage = (e) => {
|
|
9733
10683
|
if (e.key === null || e.key === key) setStored(read());
|
|
@@ -9746,8 +10696,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
9746
10696
|
}
|
|
9747
10697
|
function useMediaQuery(query) {
|
|
9748
10698
|
const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
|
|
9749
|
-
const [matches, setMatches] =
|
|
9750
|
-
|
|
10699
|
+
const [matches, setMatches] = React34.useState(get);
|
|
10700
|
+
React34.useEffect(() => {
|
|
9751
10701
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
9752
10702
|
const mql = window.matchMedia(query);
|
|
9753
10703
|
const onChange = () => setMatches(mql.matches);
|
|
@@ -9778,8 +10728,8 @@ function decodeSegment(seg) {
|
|
|
9778
10728
|
}
|
|
9779
10729
|
}
|
|
9780
10730
|
function useJwt(token) {
|
|
9781
|
-
const [, tick] =
|
|
9782
|
-
const decoded =
|
|
10731
|
+
const [, tick] = React34.useState(0);
|
|
10732
|
+
const decoded = React34.useMemo(() => {
|
|
9783
10733
|
if (!token) return { payload: null, header: null, exp: null };
|
|
9784
10734
|
const [h, p] = token.split(".");
|
|
9785
10735
|
const header = decodeSegment(h);
|
|
@@ -9787,7 +10737,7 @@ function useJwt(token) {
|
|
|
9787
10737
|
const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
|
|
9788
10738
|
return { payload, header, exp };
|
|
9789
10739
|
}, [token]);
|
|
9790
|
-
|
|
10740
|
+
React34.useEffect(() => {
|
|
9791
10741
|
if (decoded.exp == null) return;
|
|
9792
10742
|
const ms = decoded.exp * 1e3 - Date.now();
|
|
9793
10743
|
if (ms <= 0) return;
|
|
@@ -9961,13 +10911,13 @@ function SlideShow({
|
|
|
9961
10911
|
style
|
|
9962
10912
|
}) {
|
|
9963
10913
|
const reduced = framerMotion.useReducedMotion();
|
|
9964
|
-
const [index, setIndex] =
|
|
9965
|
-
const [paused, setPaused] =
|
|
10914
|
+
const [index, setIndex] = React34.useState(0);
|
|
10915
|
+
const [paused, setPaused] = React34.useState(false);
|
|
9966
10916
|
const count = slides.length;
|
|
9967
10917
|
const idx = count ? (index % count + count) % count : 0;
|
|
9968
|
-
const go =
|
|
9969
|
-
const timer =
|
|
9970
|
-
|
|
10918
|
+
const go = React34.useCallback((d) => setIndex((i) => i + d), []);
|
|
10919
|
+
const timer = React34.useRef(null);
|
|
10920
|
+
React34.useEffect(() => {
|
|
9971
10921
|
if (!autoPlay || paused || count <= 1) return;
|
|
9972
10922
|
timer.current = setInterval(() => setIndex((i) => i + 1), interval);
|
|
9973
10923
|
return () => {
|
|
@@ -10043,7 +10993,7 @@ function Video({
|
|
|
10043
10993
|
className = "",
|
|
10044
10994
|
style
|
|
10045
10995
|
}) {
|
|
10046
|
-
const [playing, setPlaying] =
|
|
10996
|
+
const [playing, setPlaying] = React34.useState(autoPlay);
|
|
10047
10997
|
const frame = cx("relative w-full overflow-hidden bg-backdrop", framed ? "rounded-2xl border border-border shadow-sm" : "", className);
|
|
10048
10998
|
const ratio = aspect.replace("/", " / ");
|
|
10049
10999
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frame, style: { aspectRatio: ratio, ...style }, children: embedUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10098,7 +11048,7 @@ function Parallax({
|
|
|
10098
11048
|
style
|
|
10099
11049
|
}) {
|
|
10100
11050
|
const reduced = framerMotion.useReducedMotion();
|
|
10101
|
-
const ref =
|
|
11051
|
+
const ref = React34.useRef(null);
|
|
10102
11052
|
const { scrollYProgress } = framerMotion.useScroll({ target: ref, offset: ["start end", "end start"] });
|
|
10103
11053
|
const shift = Math.max(0, Math.min(1, speed)) * 100;
|
|
10104
11054
|
const y = framerMotion.useTransform(scrollYProgress, [0, 1], reduced ? ["0%", "0%"] : [`-${shift / 2}%`, `${shift / 2}%`]);
|
|
@@ -10166,7 +11116,7 @@ function Blog({
|
|
|
10166
11116
|
post.tag != null && !post.image && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "accent", variant: "soft", size: "sm", children: post.tag }) }),
|
|
10167
11117
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold leading-snug text-foreground transition-colors group-hover:text-accent", children: post.title }),
|
|
10168
11118
|
post.excerpt != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-foreground-secondary", children: post.excerpt }),
|
|
10169
|
-
meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-wrap items-center gap-x-2 gap-y-1 pt-3 text-xs text-foreground-muted", children: meta.map((m, j) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11119
|
+
meta.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto flex flex-wrap items-center gap-x-2 gap-y-1 pt-3 text-xs text-foreground-muted", children: meta.map((m, j) => /* @__PURE__ */ jsxRuntime.jsxs(React34__default.default.Fragment, { children: [
|
|
10170
11120
|
j > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
10171
11121
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: m })
|
|
10172
11122
|
] }, j)) })
|
|
@@ -10295,8 +11245,8 @@ function LeadCapture({
|
|
|
10295
11245
|
className = "",
|
|
10296
11246
|
style
|
|
10297
11247
|
}) {
|
|
10298
|
-
const [email, setEmail] =
|
|
10299
|
-
const [done, setDone] =
|
|
11248
|
+
const [email, setEmail] = React34.useState("");
|
|
11249
|
+
const [done, setDone] = React34.useState(false);
|
|
10300
11250
|
const submit = (e) => {
|
|
10301
11251
|
e.preventDefault();
|
|
10302
11252
|
const value = email.trim();
|
|
@@ -10389,6 +11339,7 @@ exports.ColorPicker = ColorPicker;
|
|
|
10389
11339
|
exports.ContextMenu = ContextMenu;
|
|
10390
11340
|
exports.CookieConsent = CookieConsent;
|
|
10391
11341
|
exports.CreditCardForm = CreditCardForm;
|
|
11342
|
+
exports.DataGrid = DataGrid;
|
|
10392
11343
|
exports.DateRangePicker = DateRangePicker;
|
|
10393
11344
|
exports.Drawer = Drawer;
|
|
10394
11345
|
exports.Dropdown = Dropdown;
|
|
@@ -10424,6 +11375,7 @@ exports.OtpInput = OtpInput;
|
|
|
10424
11375
|
exports.Parallax = Parallax;
|
|
10425
11376
|
exports.Password = Password;
|
|
10426
11377
|
exports.PasswordStrength = PasswordStrength;
|
|
11378
|
+
exports.PdfViewer = PdfViewer;
|
|
10427
11379
|
exports.PopConfirm = PopConfirm;
|
|
10428
11380
|
exports.Portal = Portal;
|
|
10429
11381
|
exports.PricingPlans = PricingPlans;
|
|
@@ -10443,6 +11395,7 @@ exports.SkeletonText = SkeletonText;
|
|
|
10443
11395
|
exports.SlideShow = SlideShow;
|
|
10444
11396
|
exports.Slider = Slider;
|
|
10445
11397
|
exports.Socials = Socials;
|
|
11398
|
+
exports.Spreadsheet = Spreadsheet;
|
|
10446
11399
|
exports.Statistic = Statistic;
|
|
10447
11400
|
exports.Stepper = Stepper;
|
|
10448
11401
|
exports.Switch = Switch;
|