@geomak/ui 7.7.3 → 7.8.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 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 React31 = require('react');
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 React31__default = /*#__PURE__*/_interopDefault(React31);
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] = React31.useState(null);
71
- React31.useEffect(() => {
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 = React31__default.default.forwardRef(function IconButton2({
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 = React31.useMemo(() => {
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 = React31__default.default.forwardRef(function Button2({
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(React31__default.default.Fragment, { children: [
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 = React31.createContext(null);
958
+ var TabsContext = React34.createContext(null);
959
959
  function useTabsContext() {
960
- const ctx = React31.useContext(TabsContext);
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] = React31.useState(defaultValue);
982
+ const [internal, setInternal] = React34.useState(defaultValue);
983
983
  const current = isControlled ? value : internal;
984
984
  const reduced = !!framerMotion.useReducedMotion();
985
- const indicatorId = React31.useId();
986
- const select = React31.useCallback((next) => {
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 = React31.useRef(/* @__PURE__ */ new Map());
991
- const orderRef = React31.useRef(0);
992
- const [, bump] = React31.useState(0);
993
- const registerTab = React31.useCallback((val, meta) => {
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 = React31.useCallback((val) => {
998
+ const unregisterTab = React34.useCallback((val) => {
999
999
  if (registry.current.delete(val)) bump((v) => v + 1);
1000
1000
  }, []);
1001
- const getTabs = React31.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 })), []);
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 = React31.useRef(null);
1022
- const [edges, setEdges] = React31.useState({ start: false, end: false });
1021
+ const scrollRef = React34.useRef(null);
1022
+ const [edges, setEdges] = React34.useState({ start: false, end: false });
1023
1023
  const scrollable = variant !== "segmented";
1024
- React31.useLayoutEffect(() => {
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 = React31.useCallback((dir) => {
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
- React31.useLayoutEffect(() => {
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] = React31.useState(false);
1114
- const wrapRef = React31.useRef(null);
1115
- const timer = React31.useRef(null);
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
- React31.useLayoutEffect(() => {
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
- React31.useLayoutEffect(() => {
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 = React31.createContext({ variant: "separated" });
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 } = React31.useContext(AccordionCtx);
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] = React31.useState(false);
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] = React31.useState(false);
1747
- React31.useEffect(() => {
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(React31__default.default.Fragment, { children: [
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 = React31.useRef(null);
1948
- const slides = React31__default.default.Children.toArray(children);
1949
- const [active, setActive] = React31.useState(0);
1950
- const [atStart, setAtStart] = React31.useState(true);
1951
- const [atEnd, setAtEnd] = React31.useState(false);
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 = React31.useCallback(() => {
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
- React31.useEffect(() => {
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 = React31__default.default.Children.toArray(children);
2003
+ const slides = React34__default.default.Children.toArray(children);
2004
2004
  const count = slides.length;
2005
- const [active, setActive] = React31.useState(0);
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 = React31.useRef(null);
2244
- const atBottomRef = React31.useRef(true);
2245
- const [showJump, setShowJump] = React31.useState(false);
2246
- const [draft, setDraft] = React31.useState("");
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 = React31.useCallback((smooth = true) => {
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
- React31.useEffect(() => {
2262
+ React34.useEffect(() => {
2263
2263
  if (atBottomRef.current) scrollToBottom(messages.length > 0);
2264
2264
  }, [messages.length, isTyping]);
2265
- React31.useEffect(() => {
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] = React31.useState(false);
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] = React31.useState(false);
2558
- const [loading, setLoading] = React31.useState(false);
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] = React31.useState(false);
2662
- const [remaining, setRemaining] = React31.useState(countdown);
2663
- const idleTimer = React31.useRef(null);
2664
- const tick = React31.useRef(null);
2665
- const deadline = React31.useRef(0);
2666
- const warningRef = React31.useRef(false);
2667
- const lastReset = React31.useRef(0);
2668
- const cbs = React31.useRef({ onLogout, onContinue, onWarning });
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 = React31.useCallback(() => {
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 = React31.useCallback(() => {
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 = React31.useCallback(() => {
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 = React31.useCallback(() => {
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
- React31.useEffect(() => {
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 = React31.useId();
2777
- const errorId = React31.useId();
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] = React31.useState(defaultValue);
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] = React31.useState(defaultView);
2942
- const [cursor, setCursor] = React31.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
2943
- const [loaded, setLoaded] = React31.useState([]);
2944
- const [loading, setLoading] = React31.useState(false);
2945
- const [error, setError] = React31.useState(null);
2946
- const [reloadKey, setReloadKey] = React31.useState(0);
2947
- const [dir, setDir] = React31.useState(0);
2948
- const cbRef = React31.useRef({ loadEvents, onError });
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 = React31.useMemo(
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
- React31.useEffect(() => {
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 = React31.useCallback(() => setReloadKey((k) => k + 1), []);
2977
- const events = React31.useMemo(
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 = React31.useCallback((delta) => {
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 = React31.useCallback(() => {
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] = React31.useState(false);
3096
- const [viewYear, setViewYear] = React31.useState(cursor.getFullYear());
3097
- React31.useEffect(() => {
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 = React31.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
3172
- const eventsByDay = React31.useMemo(() => bucketByDay(events), [events]);
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 = React31.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
3247
- const eventsByDay = React31.useMemo(() => bucketByDay(events), [events]);
3248
- const labels = React31.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
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 = React31.useMemo(
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 = React31.createContext(null);
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] = React31.useState(initialItems);
3449
- React31.useEffect(() => {
3448
+ const [items, setItems] = React34.useState(initialItems);
3449
+ React34.useEffect(() => {
3450
3450
  onChange?.(items);
3451
3451
  }, [items]);
3452
- const addToCart = React31.useCallback((item, quantity) => {
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 = React31.useCallback((id) => {
3465
+ const removeFromCart = React34.useCallback((id) => {
3466
3466
  setItems((prev) => prev.filter((it) => it.id !== id));
3467
3467
  }, []);
3468
- const updateQuantity = React31.useCallback((id, quantity) => {
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 = React31.useCallback(() => setItems([]), []);
3474
- const isInCart = React31.useCallback((id) => items.some((it) => it.id === id), [items]);
3475
- const getItemCount = React31.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
3476
- const getCartTotal = React31.useCallback(
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 = React31.useMemo(
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 = React31.useContext(CartContext);
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 = React31.useRef(null);
3829
+ const ref = React34.useRef(null);
3830
3830
  if (ref.current === null) ref.current = new FormStore(options);
3831
3831
  const store = ref.current;
3832
- React31.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3833
- const make = React31.useCallback(
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 = React31.createContext(null);
3863
+ var FormContext = React34.createContext(null);
3864
3864
  function useFormStore() {
3865
- const store = React31.useContext(FormContext);
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 = React31.useRef(null);
3880
- const bypass = React31.useRef(false);
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
- React31.useEffect(() => {
3937
+ React34.useEffect(() => {
3938
3938
  return () => {
3939
3939
  if (rules !== void 0) store.removeRule(name);
3940
3940
  };
3941
3941
  }, [store, name]);
3942
- const snap = React31.useSyncExternalStore(
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
- React31.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
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 = React31.useId();
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 = React31.useRef({
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
- React31.useEffect(() => {
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 = React31.createContext({
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] = React31.useState(false);
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 = React31.useRef(null);
4343
- const startTimeRef = React31.useRef(0);
4344
- const remainingRef = React31.useRef(duration);
4345
- const clearTimer = React31.useCallback(() => {
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 = React31.useCallback((ms) => {
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
- React31.useEffect(() => {
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] = React31.useState([]);
4440
+ const [notifications, setNotifications] = React34.useState([]);
4441
4441
  const reduced = framerMotion.useReducedMotion();
4442
- const open = React31.useCallback((payload) => {
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 = React31.useCallback((id) => {
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 } = React31.useContext(NotificationContext);
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] = React31.useState(isMounted);
4595
- const [visible, setVisible] = React31.useState(false);
4596
- const timerRef = React31.useRef(null);
4597
- React31.useEffect(() => {
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));
@@ -4691,8 +4691,8 @@ var TOGGLE_POSITION_CLASS = {
4691
4691
  "bottom-right": "bottom-2 right-2"
4692
4692
  };
4693
4693
  function ScalableContainer({
4694
- width = "100%",
4695
- height = "auto",
4694
+ width,
4695
+ height,
4696
4696
  targetWidth,
4697
4697
  targetHeight,
4698
4698
  expandedWidth = "100%",
@@ -4706,14 +4706,14 @@ function ScalableContainer({
4706
4706
  togglePosition = "top-right",
4707
4707
  className = ""
4708
4708
  }) {
4709
- const containerRef = React31.useRef(null);
4710
- const [internalScaled, setInternalScaled] = React31.useState(false);
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 = React31.useRef(isScaled);
4713
+ const prevScaled = React34.useRef(isScaled);
4714
4714
  const expandW = targetWidth ?? expandedWidth;
4715
4715
  const expandH = targetHeight ?? expandedHeight;
4716
- React31.useEffect(() => {
4716
+ React34.useEffect(() => {
4717
4717
  if (isScaled === prevScaled.current) return;
4718
4718
  prevScaled.current = isScaled;
4719
4719
  if (typeof window === "undefined") return;
@@ -4741,25 +4741,20 @@ function ScalableContainer({
4741
4741
  };
4742
4742
  const wrapperClass = isScaled ? assignClassOnClick : void 0;
4743
4743
  return /* @__PURE__ */ jsxRuntime.jsxs(
4744
- framerMotion.motion.div,
4744
+ "div",
4745
4745
  {
4746
4746
  ref: containerRef,
4747
4747
  style: {
4748
4748
  width: isScaled ? expandW : width,
4749
4749
  height: isScaled ? expandH : height,
4750
- flex: isScaled ? "none" : void 0
4751
- },
4752
- animate: { width: isScaled ? expandW : width, height: isScaled ? expandH : height },
4753
- transition: reduced ? { duration: 0 } : {
4754
- width: { type: "tween", duration: 0.32, ease: [0.16, 1, 0.3, 1] },
4755
- height: { type: "tween", duration: 0.32, ease: [0.16, 1, 0.3, 1] }
4750
+ ...isScaled ? { flex: "none" } : null
4756
4751
  },
4757
4752
  className: cx(
4758
4753
  "relative rounded-lg overflow-hidden",
4754
+ "transition-[width,height,box-shadow] duration-[320ms] ease-[cubic-bezier(0.16,1,0.3,1)] motion-reduce:transition-none",
4759
4755
  // OS-window aesthetic: subtle elevation at rest, lifted shadow +
4760
4756
  // raised stacking when expanded so it sits above neighbours.
4761
4757
  isScaled ? "z-raised shadow-2xl" : "shadow-md",
4762
- "transition-shadow duration-300",
4763
4758
  className
4764
4759
  ),
4765
4760
  children: [
@@ -4865,17 +4860,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
4865
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)) });
4866
4861
  }
4867
4862
  function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
4868
- const [activeIndex, setActiveIndex] = React31.useState(0);
4869
- const [indexPool, setIndexPool] = React31.useState([]);
4870
- const cardRefs = React31.useRef([]);
4871
- const getIndexes = React31.useMemo(() => {
4863
+ const [activeIndex, setActiveIndex] = React34.useState(0);
4864
+ const [indexPool, setIndexPool] = React34.useState([]);
4865
+ const cardRefs = React34.useRef([]);
4866
+ const getIndexes = React34.useMemo(() => {
4872
4867
  let nextIndex = activeIndex + 1;
4873
4868
  let previousIndex = activeIndex - 1;
4874
4869
  if (activeIndex === 0) previousIndex = items.length - 1;
4875
4870
  if (activeIndex === items.length - 1) nextIndex = 0;
4876
4871
  return { previousIndex, nextIndex };
4877
4872
  }, [activeIndex, items.length]);
4878
- React31.useEffect(() => {
4873
+ React34.useEffect(() => {
4879
4874
  const { nextIndex, previousIndex } = getIndexes;
4880
4875
  let indexes = [previousIndex, activeIndex, nextIndex];
4881
4876
  if (activeIndex !== 0 && activeIndex !== items.length - 1) {
@@ -5048,8 +5043,8 @@ function writeDismissed(key) {
5048
5043
  }
5049
5044
  }
5050
5045
  function useTargetBbox(ref) {
5051
- const [bbox, setBbox] = React31.useState(null);
5052
- React31.useLayoutEffect(() => {
5046
+ const [bbox, setBbox] = React34.useState(null);
5047
+ React34.useLayoutEffect(() => {
5053
5048
  const el = ref?.current;
5054
5049
  if (!el) {
5055
5050
  setBbox(null);
@@ -5079,7 +5074,7 @@ function tooltipStyleFor(bbox, placement) {
5079
5074
  return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
5080
5075
  }
5081
5076
  function useFocusTrap(containerRef, active) {
5082
- React31.useEffect(() => {
5077
+ React34.useEffect(() => {
5083
5078
  if (!active) return;
5084
5079
  const el = containerRef.current;
5085
5080
  if (!el) return;
@@ -5118,16 +5113,16 @@ function Wizard({
5118
5113
  onComplete,
5119
5114
  onSkip
5120
5115
  }) {
5121
- const tooltipRef = React31.useRef(null);
5122
- const tooltipTitleId = React31.useId();
5123
- const tooltipBodyId = React31.useId();
5116
+ const tooltipRef = React34.useRef(null);
5117
+ const tooltipTitleId = React34.useId();
5118
+ const tooltipBodyId = React34.useId();
5124
5119
  const reduced = framerMotion.useReducedMotion();
5125
- const [open, setOpen] = React31.useState(() => steps.length > 0 && !readDismissed(storageKey));
5126
- const [activeIndex, setActiveIndex] = React31.useState(0);
5120
+ const [open, setOpen] = React34.useState(() => steps.length > 0 && !readDismissed(storageKey));
5121
+ const [activeIndex, setActiveIndex] = React34.useState(0);
5127
5122
  const step = steps[activeIndex];
5128
5123
  const bbox = useTargetBbox(step?.stepRef);
5129
5124
  useFocusTrap(tooltipRef, open);
5130
- React31.useEffect(() => {
5125
+ React34.useEffect(() => {
5131
5126
  if (!open || !dismissible) return;
5132
5127
  const onKey = (e) => {
5133
5128
  if (e.key === "Escape") {
@@ -5138,12 +5133,12 @@ function Wizard({
5138
5133
  document.addEventListener("keydown", onKey);
5139
5134
  return () => document.removeEventListener("keydown", onKey);
5140
5135
  }, [open, dismissible]);
5141
- const handleSkip = React31.useCallback(() => {
5136
+ const handleSkip = React34.useCallback(() => {
5142
5137
  writeDismissed(storageKey);
5143
5138
  setOpen(false);
5144
5139
  onSkip?.();
5145
5140
  }, [storageKey, onSkip]);
5146
- const handleComplete = React31.useCallback(() => {
5141
+ const handleComplete = React34.useCallback(() => {
5147
5142
  writeDismissed(storageKey);
5148
5143
  setOpen(false);
5149
5144
  onComplete?.();
@@ -5286,7 +5281,7 @@ function Wizard({
5286
5281
  ] });
5287
5282
  }
5288
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" }) });
5289
- var SearchInput = React31__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
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) {
5290
5285
  return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
5291
5286
  "div",
5292
5287
  {
@@ -5521,15 +5516,15 @@ function EditableCell({
5521
5516
  rowIndex,
5522
5517
  onCellEdit
5523
5518
  }) {
5524
- const [editing, setEditing] = React31.useState(false);
5525
- const editRef = React31.useRef(null);
5519
+ const [editing, setEditing] = React34.useState(false);
5520
+ const editRef = React34.useRef(null);
5526
5521
  const value = row[col.keyBind];
5527
5522
  const commit = (next) => {
5528
5523
  setEditing(false);
5529
5524
  onCellEdit?.({ row, key: col.keyBind, value: next, rowIndex });
5530
5525
  };
5531
5526
  const cancel = () => setEditing(false);
5532
- React31.useEffect(() => {
5527
+ React34.useEffect(() => {
5533
5528
  if (!editing || !col.editor) return;
5534
5529
  const onMouseDown = (e) => {
5535
5530
  const target = e.target;
@@ -5588,7 +5583,7 @@ function TableBody({
5588
5583
  getRowKey,
5589
5584
  onCellEdit
5590
5585
  }) {
5591
- const [expanded, setExpanded] = React31.useState(() => /* @__PURE__ */ new Set());
5586
+ const [expanded, setExpanded] = React34.useState(() => /* @__PURE__ */ new Set());
5592
5587
  const reduced = framerMotion.useReducedMotion();
5593
5588
  const toggleRow = (rowKey) => {
5594
5589
  setExpanded((prev) => {
@@ -5603,7 +5598,7 @@ function TableBody({
5603
5598
  return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
5604
5599
  const rowKey = getRowKey(row, i);
5605
5600
  const isExpanded = expanded.has(rowKey);
5606
- return /* @__PURE__ */ jsxRuntime.jsxs(React31__default.default.Fragment, { children: [
5601
+ return /* @__PURE__ */ jsxRuntime.jsxs(React34__default.default.Fragment, { children: [
5607
5602
  /* @__PURE__ */ jsxRuntime.jsxs(
5608
5603
  "tr",
5609
5604
  {
@@ -5715,13 +5710,13 @@ function Table({
5715
5710
  className = "",
5716
5711
  style
5717
5712
  }) {
5718
- const searchRef = React31.useRef(null);
5719
- const [searchTerm, setSearchTerm] = React31.useState("");
5720
- const [perPage, setPerPage] = React31.useState(
5713
+ const searchRef = React34.useRef(null);
5714
+ const [searchTerm, setSearchTerm] = React34.useState("");
5715
+ const [perPage, setPerPage] = React34.useState(
5721
5716
  typeof pagination.perPage === "number" ? pagination.perPage : 15
5722
5717
  );
5723
- const [activePage, setActivePage] = React31.useState(0);
5724
- const [sortState, setSortState] = React31.useState(defaultSort);
5718
+ const [activePage, setActivePage] = React34.useState(0);
5719
+ const [sortState, setSortState] = React34.useState(defaultSort);
5725
5720
  const isServerSide = !!(pagination.enabled && pagination.serverSide);
5726
5721
  const handleSort = (col) => {
5727
5722
  const key = col.keyBind;
@@ -5733,8 +5728,8 @@ function Table({
5733
5728
  onSortChange?.(next);
5734
5729
  };
5735
5730
  const debounceMs = search?.debounceMs ?? 0;
5736
- const [debouncedTerm, setDebouncedTerm] = React31.useState("");
5737
- React31.useEffect(() => {
5731
+ const [debouncedTerm, setDebouncedTerm] = React34.useState("");
5732
+ React34.useEffect(() => {
5738
5733
  if (debounceMs <= 0) {
5739
5734
  setDebouncedTerm(searchTerm);
5740
5735
  return;
@@ -5743,7 +5738,7 @@ function Table({
5743
5738
  return () => clearTimeout(t);
5744
5739
  }, [searchTerm, debounceMs]);
5745
5740
  const term = debounceMs > 0 ? debouncedTerm : searchTerm;
5746
- const filteredRows = React31.useMemo(() => {
5741
+ const filteredRows = React34.useMemo(() => {
5747
5742
  if (isServerSide || !term) return rows;
5748
5743
  if (search?.predicate) return rows.filter((row) => search.predicate(row, term));
5749
5744
  const cs = !!search?.caseSensitive;
@@ -5757,7 +5752,7 @@ function Table({
5757
5752
  };
5758
5753
  return rows.filter((row) => keys ? keys.some((k) => test(row[k])) : Object.values(row).some(test));
5759
5754
  }, [rows, term, isServerSide, search?.predicate, search?.caseSensitive, search?.matchMode, search?.keys]);
5760
- const sortedRows = React31.useMemo(() => {
5755
+ const sortedRows = React34.useMemo(() => {
5761
5756
  if (isServerSide || !sortState) return filteredRows;
5762
5757
  const col = columns.find((c) => c.keyBind === sortState.key);
5763
5758
  const accessor = col?.sortAccessor ?? ((r) => r[sortState.key]);
@@ -5765,29 +5760,29 @@ function Table({
5765
5760
  if (sortState.direction === "desc") out.reverse();
5766
5761
  return out;
5767
5762
  }, [filteredRows, sortState, isServerSide, columns]);
5768
- const datasets = React31.useMemo(() => {
5763
+ const datasets = React34.useMemo(() => {
5769
5764
  if (isServerSide) return [rows];
5770
5765
  return createDatasets(sortedRows, pagination.enabled ? perPage : null);
5771
5766
  }, [sortedRows, perPage, pagination.enabled, isServerSide, rows]);
5772
- const MAX_PAGE = React31.useMemo(() => {
5767
+ const MAX_PAGE = React34.useMemo(() => {
5773
5768
  if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
5774
5769
  if (isServerSide && typeof pagination.totalCount === "number")
5775
5770
  return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
5776
5771
  return datasets.length ? datasets.length - 1 : 0;
5777
5772
  }, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
5778
- const currentPageRows = React31.useMemo(() => {
5773
+ const currentPageRows = React34.useMemo(() => {
5779
5774
  if (isServerSide) return rows;
5780
5775
  return datasets[activePage] ?? [];
5781
5776
  }, [isServerSide, rows, datasets, activePage]);
5782
- React31.useEffect(() => {
5777
+ React34.useEffect(() => {
5783
5778
  if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
5784
5779
  setPerPage(pagination.perPage);
5785
5780
  }
5786
5781
  }, [pagination.enabled, pagination.perPage, isServerSide]);
5787
- React31.useEffect(() => {
5782
+ React34.useEffect(() => {
5788
5783
  if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
5789
5784
  }, [isServerSide, pagination.perPage]);
5790
- React31.useEffect(() => {
5785
+ React34.useEffect(() => {
5791
5786
  if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
5792
5787
  setActivePage(pagination.page - 1);
5793
5788
  }, [isServerSide, pagination.page]);
@@ -5876,7 +5871,7 @@ function TableSkeletonBody({
5876
5871
  i
5877
5872
  )) });
5878
5873
  }
5879
- var useIsoLayoutEffect = typeof window !== "undefined" ? React31.useLayoutEffect : React31.useEffect;
5874
+ var useIsoLayoutEffect = typeof window !== "undefined" ? React34.useLayoutEffect : React34.useEffect;
5880
5875
  function VirtualList({
5881
5876
  items,
5882
5877
  rowHeight,
@@ -5893,10 +5888,10 @@ function VirtualList({
5893
5888
  className = "",
5894
5889
  style
5895
5890
  }) {
5896
- const scrollRef = React31.useRef(null);
5897
- const [scrollTop, setScrollTop] = React31.useState(0);
5898
- const [viewport, setViewport] = React31.useState(typeof height === "number" ? height : 400);
5899
- const [term, setTerm] = React31.useState("");
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("");
5900
5895
  useIsoLayoutEffect(() => {
5901
5896
  const el = scrollRef.current;
5902
5897
  if (!el) return;
@@ -5907,7 +5902,7 @@ function VirtualList({
5907
5902
  ro.observe(el);
5908
5903
  return () => ro.disconnect();
5909
5904
  }, []);
5910
- const filtered = React31.useMemo(() => {
5905
+ const filtered = React34.useMemo(() => {
5911
5906
  if (!searchable || !term) return items;
5912
5907
  if (filter) return items.filter((it) => filter(it, term));
5913
5908
  const needle = term.toLowerCase();
@@ -5954,8 +5949,771 @@ function VirtualList({
5954
5949
  )
5955
5950
  ] });
5956
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 sourceName(source) {
5977
+ if (typeof File !== "undefined" && source instanceof File) return source.name;
5978
+ if (isUrlSource(source)) {
5979
+ const href = urlHref(source);
5980
+ const last = href.split("?")[0].split("#")[0].split("/").filter(Boolean).pop();
5981
+ return last || void 0;
5982
+ }
5983
+ return void 0;
5984
+ }
5985
+ var pdfjsPromise = null;
5986
+ function loadPdfjs() {
5987
+ if (pdfjsPromise) return pdfjsPromise;
5988
+ pdfjsPromise = import('pdfjs-dist').then((pdfjs) => {
5989
+ if (!pdfjs.GlobalWorkerOptions.workerSrc) {
5990
+ pdfjs.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
5991
+ }
5992
+ return pdfjs;
5993
+ });
5994
+ return pdfjsPromise;
5995
+ }
5996
+ var GAP = 12;
5997
+ function PdfViewer({
5998
+ source,
5999
+ remote,
6000
+ initialPage = 1,
6001
+ zoom = "page-width",
6002
+ toolbar = true,
6003
+ thumbnails = false,
6004
+ textLayer = true,
6005
+ onLoad,
6006
+ onError,
6007
+ onPageChange,
6008
+ className = "",
6009
+ style
6010
+ }) {
6011
+ const [pdfjs, setPdfjs] = React34.useState(null);
6012
+ const [doc, setDoc] = React34.useState(null);
6013
+ const [numPages, setNumPages] = React34.useState(0);
6014
+ const [baseSize, setBaseSize] = React34.useState(null);
6015
+ const [status, setStatus] = React34.useState("loading");
6016
+ const [error, setError] = React34.useState(null);
6017
+ const [reloadKey, setReloadKey] = React34.useState(0);
6018
+ const scrollRef = React34.useRef(null);
6019
+ const [scrollTop, setScrollTop] = React34.useState(0);
6020
+ const [viewport, setViewport] = React34.useState({ w: 0, h: 0 });
6021
+ const [zoomMode, setZoomMode] = React34.useState(zoom);
6022
+ const [page, setPage] = React34.useState(initialPage);
6023
+ const [showSearch, setShowSearch] = React34.useState(false);
6024
+ const [query, setQuery] = React34.useState("");
6025
+ const [matchPages, setMatchPages] = React34.useState(null);
6026
+ const [matchIdx, setMatchIdx] = React34.useState(0);
6027
+ const tb = toolbar === true ? { zoom: true, pager: true, download: true, print: true, search: true } : toolbar || {};
6028
+ React34.useEffect(() => {
6029
+ let cancelled = false;
6030
+ let task;
6031
+ setStatus("loading");
6032
+ setError(null);
6033
+ setDoc(null);
6034
+ setBaseSize(null);
6035
+ loadPdfjs().then(async (pdfjs2) => {
6036
+ if (cancelled) return;
6037
+ setPdfjs(pdfjs2);
6038
+ 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()) };
6039
+ task = pdfjs2.getDocument(params);
6040
+ const pdf = await task.promise;
6041
+ if (cancelled) {
6042
+ pdf.destroy?.();
6043
+ return;
6044
+ }
6045
+ const first = await pdf.getPage(1);
6046
+ const vp = first.getViewport({ scale: 1 });
6047
+ if (cancelled) return;
6048
+ setDoc(pdf);
6049
+ setNumPages(pdf.numPages);
6050
+ setBaseSize({ width: vp.width, height: vp.height });
6051
+ setStatus("ready");
6052
+ onLoad?.({ numPages: pdf.numPages });
6053
+ }).catch((err) => {
6054
+ if (cancelled) return;
6055
+ setStatus("error");
6056
+ setError(err);
6057
+ onError?.(err);
6058
+ });
6059
+ return () => {
6060
+ cancelled = true;
6061
+ task?.destroy?.();
6062
+ };
6063
+ }, [source, remote, reloadKey]);
6064
+ React34.useEffect(() => () => {
6065
+ doc?.destroy?.();
6066
+ }, [doc]);
6067
+ React34.useEffect(() => {
6068
+ const el = scrollRef.current;
6069
+ if (!el || typeof ResizeObserver === "undefined") return;
6070
+ const measure = () => setViewport({ w: el.clientWidth, h: el.clientHeight });
6071
+ measure();
6072
+ const ro = new ResizeObserver(measure);
6073
+ ro.observe(el);
6074
+ return () => ro.disconnect();
6075
+ }, [status]);
6076
+ const scale = React34.useMemo(() => {
6077
+ if (!baseSize) return 1;
6078
+ if (typeof zoomMode === "number") return zoomMode;
6079
+ const avail = Math.max(0, (viewport.w || baseSize.width) - 32);
6080
+ if (zoomMode === "page-width" || zoomMode === "auto") return avail / baseSize.width;
6081
+ if (zoomMode === "page-fit") {
6082
+ const availH = Math.max(0, (viewport.h || baseSize.height) - 32);
6083
+ return Math.min(avail / baseSize.width, availH / baseSize.height);
6084
+ }
6085
+ return 1;
6086
+ }, [zoomMode, baseSize, viewport]);
6087
+ const pageH = baseSize ? baseSize.height * scale + GAP : 0;
6088
+ const pageW = baseSize ? baseSize.width * scale : 0;
6089
+ const total = numPages * pageH;
6090
+ const overscan = 1;
6091
+ const startIdx = pageH ? Math.max(0, Math.floor(scrollTop / pageH) - overscan) : 0;
6092
+ const endIdx = pageH ? Math.min(numPages, Math.ceil((scrollTop + viewport.h) / pageH) + overscan) : 0;
6093
+ const visiblePages = Array.from({ length: Math.max(0, endIdx - startIdx) }, (_, i) => startIdx + i + 1);
6094
+ React34.useEffect(() => {
6095
+ if (!pageH) return;
6096
+ const cur = Math.min(numPages, Math.max(1, Math.floor((scrollTop + viewport.h / 2) / pageH) + 1));
6097
+ if (cur !== page) {
6098
+ setPage(cur);
6099
+ onPageChange?.(cur);
6100
+ }
6101
+ }, [scrollTop, pageH, viewport.h, numPages]);
6102
+ const scrollToPage = React34.useCallback((p) => {
6103
+ const el = scrollRef.current;
6104
+ if (!el || !pageH) return;
6105
+ el.scrollTo({ top: (p - 1) * pageH, behavior: "smooth" });
6106
+ }, [pageH]);
6107
+ React34.useEffect(() => {
6108
+ if (status === "ready" && initialPage > 1) scrollToPage(initialPage);
6109
+ }, [status]);
6110
+ const runSearch = React34.useCallback(async (q) => {
6111
+ setQuery(q);
6112
+ if (!doc || !q.trim()) {
6113
+ setMatchPages(null);
6114
+ setMatchIdx(0);
6115
+ return;
6116
+ }
6117
+ const needle = q.toLowerCase();
6118
+ const hits = [];
6119
+ for (let p = 1; p <= numPages; p++) {
6120
+ const pg = await doc.getPage(p);
6121
+ const tc = await pg.getTextContent();
6122
+ const text = tc.items.map((it) => "str" in it ? it.str : "").join(" ").toLowerCase();
6123
+ if (text.includes(needle)) hits.push(p);
6124
+ }
6125
+ setMatchPages(hits);
6126
+ setMatchIdx(0);
6127
+ if (hits.length) scrollToPage(hits[0]);
6128
+ }, [doc, numPages, scrollToPage]);
6129
+ const gotoMatch = (dir) => {
6130
+ if (!matchPages?.length) return;
6131
+ const next = (matchIdx + dir + matchPages.length) % matchPages.length;
6132
+ setMatchIdx(next);
6133
+ scrollToPage(matchPages[next]);
6134
+ };
6135
+ const getBytes = React34.useCallback(async () => {
6136
+ if (doc?.getData) return doc.getData();
6137
+ if (source instanceof Uint8Array) return source;
6138
+ if (source instanceof ArrayBuffer) return new Uint8Array(source);
6139
+ if (typeof Blob !== "undefined" && source instanceof Blob) return new Uint8Array(await source.arrayBuffer());
6140
+ throw new Error("No bytes available");
6141
+ }, [doc, source]);
6142
+ const download2 = React34.useCallback(async () => {
6143
+ const bytes = await getBytes();
6144
+ const blob = new Blob([bytes], { type: "application/pdf" });
6145
+ const url = URL.createObjectURL(blob);
6146
+ const a = document.createElement("a");
6147
+ a.href = url;
6148
+ a.download = sourceName(source) || "document.pdf";
6149
+ a.click();
6150
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
6151
+ }, [getBytes, source]);
6152
+ const print = React34.useCallback(async () => {
6153
+ const bytes = await getBytes();
6154
+ const blob = new Blob([bytes], { type: "application/pdf" });
6155
+ const url = URL.createObjectURL(blob);
6156
+ const iframe = document.createElement("iframe");
6157
+ iframe.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0";
6158
+ iframe.src = url;
6159
+ iframe.onload = () => {
6160
+ try {
6161
+ iframe.contentWindow?.focus();
6162
+ iframe.contentWindow?.print();
6163
+ } catch {
6164
+ }
6165
+ };
6166
+ document.body.appendChild(iframe);
6167
+ setTimeout(() => {
6168
+ document.body.removeChild(iframe);
6169
+ URL.revokeObjectURL(url);
6170
+ }, 6e4);
6171
+ }, [getBytes]);
6172
+ const setZoomNum = (factor) => {
6173
+ const cur = typeof zoomMode === "number" ? zoomMode : scale;
6174
+ setZoomMode(Math.min(5, Math.max(0.25, +(cur * factor).toFixed(2))));
6175
+ };
6176
+ if (status === "error") {
6177
+ 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: [
6178
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-status-error", children: "Couldn\u2019t load the PDF" }),
6179
+ error?.message && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-xs text-foreground-muted", children: error.message }),
6180
+ /* @__PURE__ */ jsxRuntime.jsx(Button_default, { content: "Retry", size: "sm", variant: "outline", onClick: () => setReloadKey((k) => k + 1) })
6181
+ ] });
6182
+ }
6183
+ 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: [
6184
+ toolbar !== false && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 flex-wrap items-center gap-2 border-b border-border bg-surface px-2 py-1.5", children: [
6185
+ tb.pager && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
6186
+ /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Previous page", onClick: () => scrollToPage(Math.max(1, page - 1)), icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron5, { dir: "up" }), disabled: status !== "ready" }),
6187
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "px-1 text-xs tabular-nums text-foreground-secondary select-none", children: [
6188
+ status === "ready" ? page : "\u2013",
6189
+ " / ",
6190
+ numPages || "\u2013"
6191
+ ] }),
6192
+ /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Next page", onClick: () => scrollToPage(Math.min(numPages, page + 1)), icon: /* @__PURE__ */ jsxRuntime.jsx(Chevron5, { dir: "down" }), disabled: status !== "ready" })
6193
+ ] }),
6194
+ tb.zoom && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-1 flex items-center gap-1", children: [
6195
+ /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Zoom out", onClick: () => setZoomNum(1 / 1.2), icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base leading-none", children: "\u2212" }), disabled: status !== "ready" }),
6196
+ /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Zoom in", onClick: () => setZoomNum(1.2), icon: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base leading-none", children: "+" }), disabled: status !== "ready" }),
6197
+ /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Fit width", onClick: () => setZoomMode("page-width"), icon: /* @__PURE__ */ jsxRuntime.jsx(FitWidthIcon, {}), disabled: status !== "ready" }),
6198
+ /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Fit page", onClick: () => setZoomMode("page-fit"), icon: /* @__PURE__ */ jsxRuntime.jsx(FitPageIcon, {}), disabled: status !== "ready" })
6199
+ ] }),
6200
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-1", children: [
6201
+ tb.search && /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Search", onClick: () => setShowSearch((s) => !s), icon: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon2, {}), disabled: status !== "ready" }),
6202
+ tb.download && /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Download", onClick: download2, icon: /* @__PURE__ */ jsxRuntime.jsx(DownloadIcon, {}), disabled: status !== "ready" }),
6203
+ tb.print && /* @__PURE__ */ jsxRuntime.jsx(IconButton_default, { type: "ghost", size: "sm", title: "Print", onClick: print, icon: /* @__PURE__ */ jsxRuntime.jsx(PrintIcon, {}), disabled: status !== "ready" })
6204
+ ] }),
6205
+ tb.search && showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-center gap-2 pt-1", children: [
6206
+ /* @__PURE__ */ jsxRuntime.jsx(
6207
+ "input",
6208
+ {
6209
+ autoFocus: true,
6210
+ value: query,
6211
+ onChange: (e) => runSearch(e.target.value),
6212
+ placeholder: "Find in document\u2026",
6213
+ className: "h-7 flex-1 rounded-md border border-border bg-surface px-2 text-sm text-foreground outline-none focus:border-accent"
6214
+ }
6215
+ ),
6216
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs tabular-nums text-foreground-muted", children: matchPages == null ? "" : matchPages.length ? `${matchIdx + 1}/${matchPages.length} pages` : "no matches" }),
6217
+ /* @__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 }),
6218
+ /* @__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 })
6219
+ ] })
6220
+ ] }),
6221
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1", children: [
6222
+ thumbnails && status === "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) => /* @__PURE__ */ jsxRuntime.jsx(
6223
+ "button",
6224
+ {
6225
+ type: "button",
6226
+ onClick: () => scrollToPage(p),
6227
+ className: cx(
6228
+ "mb-2 block w-full overflow-hidden rounded border bg-surface-raised transition-colors",
6229
+ p === page ? "border-accent ring-1 ring-accent" : "border-border hover:border-border-strong"
6230
+ ),
6231
+ style: { aspectRatio: `${baseSize.width} / ${baseSize.height}` },
6232
+ "aria-label": `Page ${p}`,
6233
+ children: Math.abs(p - page) <= 8 ? /* @__PURE__ */ jsxRuntime.jsx(PdfPage, { pdfjs, doc, page: p, scale: 112 / baseSize.width, textLayer: false }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block py-4 text-center text-xs text-foreground-muted", children: p })
6234
+ },
6235
+ p
6236
+ )) }),
6237
+ /* @__PURE__ */ jsxRuntime.jsx(
6238
+ "div",
6239
+ {
6240
+ ref: scrollRef,
6241
+ onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
6242
+ className: "relative flex-1 overflow-auto bg-background",
6243
+ children: status === "loading" || !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 - 48, 560) || 480, 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) => /* @__PURE__ */ jsxRuntime.jsx(
6244
+ "div",
6245
+ {
6246
+ style: { position: "absolute", top: (p - 1) * pageH, left: 0, right: 0, height: pageH, display: "flex", justifyContent: "center", paddingTop: GAP / 2, paddingBottom: GAP / 2 },
6247
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative shadow-md", style: { width: pageW, height: baseSize.height * scale }, children: /* @__PURE__ */ jsxRuntime.jsx(PdfPage, { pdfjs, doc, page: p, scale, textLayer }) })
6248
+ },
6249
+ p
6250
+ )) })
6251
+ }
6252
+ )
6253
+ ] })
6254
+ ] });
6255
+ }
6256
+ function PdfPage({ pdfjs, doc, page, scale, textLayer }) {
6257
+ const canvasRef = React34.useRef(null);
6258
+ const textRef = React34.useRef(null);
6259
+ React34.useEffect(() => {
6260
+ let cancelled = false;
6261
+ let renderTask;
6262
+ (async () => {
6263
+ const pg = await doc.getPage(page);
6264
+ if (cancelled) return;
6265
+ const viewport = pg.getViewport({ scale });
6266
+ const canvas = canvasRef.current;
6267
+ if (!canvas) return;
6268
+ const ratio = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
6269
+ canvas.width = Math.floor(viewport.width * ratio);
6270
+ canvas.height = Math.floor(viewport.height * ratio);
6271
+ canvas.style.width = `${Math.floor(viewport.width)}px`;
6272
+ canvas.style.height = `${Math.floor(viewport.height)}px`;
6273
+ const ctx = canvas.getContext("2d");
6274
+ renderTask = pg.render({ canvasContext: ctx, viewport, transform: ratio !== 1 ? [ratio, 0, 0, ratio, 0, 0] : void 0 });
6275
+ try {
6276
+ await renderTask.promise;
6277
+ } catch {
6278
+ return;
6279
+ }
6280
+ if (cancelled || !textLayer || !textRef.current || !pdfjs?.TextLayer) return;
6281
+ try {
6282
+ textRef.current.innerHTML = "";
6283
+ textRef.current.style.setProperty("--scale-factor", String(scale));
6284
+ const tl = new pdfjs.TextLayer({ textContentSource: pg.streamTextContent(), container: textRef.current, viewport });
6285
+ await tl.render();
6286
+ } catch {
6287
+ }
6288
+ })();
6289
+ return () => {
6290
+ cancelled = true;
6291
+ renderTask?.cancel?.();
6292
+ };
6293
+ }, [pdfjs, doc, page, scale, textLayer]);
6294
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6295
+ /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef, className: "block bg-white" }),
6296
+ textLayer && /* @__PURE__ */ jsxRuntime.jsx("div", { ref: textRef, className: "textLayer pointer-events-auto absolute inset-0 overflow-hidden leading-none", style: { opacity: 0.25 }, "aria-hidden": "true" })
6297
+ ] });
6298
+ }
6299
+ 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" }) });
6300
+ var SearchIcon2 = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", "aria-hidden": "true", children: [
6301
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "7" }),
6302
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "m21 21-4.3-4.3" })
6303
+ ] });
6304
+ 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" }) });
6305
+ 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" }) });
6306
+ 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" }) });
6307
+ 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: [
6308
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", y: "3", width: "14", height: "18", rx: "1" }),
6309
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 8h6M9 12h6M9 16h4" })
6310
+ ] });
6311
+ var DEFAULT_COL_WIDTH = 140;
6312
+ var GUTTER = 52;
6313
+ function resolveWidth(w) {
6314
+ if (typeof w === "number") return w;
6315
+ if (typeof w === "string") {
6316
+ const n = parseFloat(w);
6317
+ if (!Number.isNaN(n) && /^\d/.test(w.trim())) return n;
6318
+ }
6319
+ return DEFAULT_COL_WIDTH;
6320
+ }
6321
+ function displayValue(v) {
6322
+ if (v == null) return "";
6323
+ return String(v);
6324
+ }
6325
+ function DataGrid({
6326
+ columns,
6327
+ rows,
6328
+ rowHeight = 34,
6329
+ headerHeight = 38,
6330
+ height = 480,
6331
+ editable = false,
6332
+ virtualize = true,
6333
+ overscan = 4,
6334
+ rowNumbers = true,
6335
+ onCellEdit,
6336
+ className = "",
6337
+ style,
6338
+ emptyState = "No data"
6339
+ }) {
6340
+ const scrollRef = React34.useRef(null);
6341
+ const [scroll, setScroll] = React34.useState({ top: 0, left: 0 });
6342
+ const [viewport, setViewport] = React34.useState({ w: 0, h: 0 });
6343
+ const [editing, setEditing] = React34.useState(null);
6344
+ const [draft, setDraft] = React34.useState("");
6345
+ const gutter = rowNumbers ? GUTTER : 0;
6346
+ const { widths, offsets, totalWidth } = React34.useMemo(() => {
6347
+ const widths2 = columns.map((c) => resolveWidth(c.width));
6348
+ const offsets2 = [];
6349
+ let acc = 0;
6350
+ for (const w of widths2) {
6351
+ offsets2.push(acc);
6352
+ acc += w;
6353
+ }
6354
+ return { widths: widths2, offsets: offsets2, totalWidth: acc };
6355
+ }, [columns]);
6356
+ const totalHeight = rows.length * rowHeight;
6357
+ React34.useEffect(() => {
6358
+ const el = scrollRef.current;
6359
+ if (!el || typeof ResizeObserver === "undefined") return;
6360
+ const measure = () => setViewport({ w: el.clientWidth, h: el.clientHeight });
6361
+ measure();
6362
+ const ro = new ResizeObserver(measure);
6363
+ ro.observe(el);
6364
+ return () => ro.disconnect();
6365
+ }, []);
6366
+ const bodyH = (viewport.h || (typeof height === "number" ? height : 480)) - headerHeight;
6367
+ const rowStart = virtualize ? Math.max(0, Math.floor(scroll.top / rowHeight) - overscan) : 0;
6368
+ const rowEnd = virtualize ? Math.min(rows.length, Math.ceil((scroll.top + bodyH) / rowHeight) + overscan) : rows.length;
6369
+ let colStart = 0;
6370
+ let colEnd = columns.length;
6371
+ if (virtualize && viewport.w) {
6372
+ const viewLeft = scroll.left;
6373
+ const viewRight = scroll.left + (viewport.w - gutter);
6374
+ colStart = Math.max(0, offsets.findIndex((o, i) => o + widths[i] > viewLeft));
6375
+ if (colStart < 0) colStart = 0;
6376
+ colEnd = offsets.findIndex((o) => o > viewRight);
6377
+ colEnd = colEnd === -1 ? columns.length : Math.min(columns.length, colEnd + 1);
6378
+ colStart = Math.max(0, colStart - overscan);
6379
+ colEnd = Math.min(columns.length, colEnd + overscan);
6380
+ }
6381
+ const visibleRows = Array.from({ length: Math.max(0, rowEnd - rowStart) }, (_, i) => rowStart + i);
6382
+ const visibleCols = Array.from({ length: Math.max(0, colEnd - colStart) }, (_, i) => colStart + i);
6383
+ const commit = React34.useCallback(() => {
6384
+ if (!editing) return;
6385
+ const col = columns[editing.col];
6386
+ onCellEdit?.({ row: editing.row, column: col.key, value: draft });
6387
+ setEditing(null);
6388
+ }, [editing, columns, draft, onCellEdit]);
6389
+ const startEdit = (row, col) => {
6390
+ const c = columns[col];
6391
+ if (!(c.editable ?? editable)) return;
6392
+ setDraft(displayValue(rows[row]?.[c.key] ?? ""));
6393
+ setEditing({ row, col });
6394
+ };
6395
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6396
+ "div",
6397
+ {
6398
+ ref: scrollRef,
6399
+ onScroll: (e) => setScroll({ top: e.currentTarget.scrollTop, left: e.currentTarget.scrollLeft }),
6400
+ className: cx("relative overflow-auto rounded-lg border border-border bg-surface-raised text-sm", className),
6401
+ style: { height, ...style },
6402
+ role: "grid",
6403
+ "aria-rowcount": rows.length,
6404
+ "aria-colcount": columns.length,
6405
+ children: [
6406
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", width: gutter + totalWidth, height: headerHeight + totalHeight }, children: [
6407
+ rowNumbers && /* @__PURE__ */ jsxRuntime.jsx(
6408
+ "div",
6409
+ {
6410
+ className: "border-b border-r border-border bg-surface",
6411
+ style: { position: "absolute", top: scroll.top, left: scroll.left, width: gutter, height: headerHeight, zIndex: 3 }
6412
+ }
6413
+ ),
6414
+ visibleCols.map((ci) => {
6415
+ const c = columns[ci];
6416
+ return /* @__PURE__ */ jsxRuntime.jsx(
6417
+ "div",
6418
+ {
6419
+ role: "columnheader",
6420
+ className: "flex items-center border-b border-r border-border bg-surface px-3 font-medium text-foreground-secondary",
6421
+ style: {
6422
+ position: "absolute",
6423
+ top: scroll.top,
6424
+ left: gutter + offsets[ci],
6425
+ width: widths[ci],
6426
+ height: headerHeight,
6427
+ zIndex: 2,
6428
+ justifyContent: c.align === "right" ? "flex-end" : c.align === "center" ? "center" : "flex-start"
6429
+ },
6430
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: c.label ?? c.key })
6431
+ },
6432
+ `h-${c.key}`
6433
+ );
6434
+ }),
6435
+ rowNumbers && visibleRows.map((ri) => /* @__PURE__ */ jsxRuntime.jsx(
6436
+ "div",
6437
+ {
6438
+ className: "flex items-center justify-center border-b border-r border-border bg-surface text-xs tabular-nums text-foreground-muted",
6439
+ style: { position: "absolute", left: scroll.left, top: headerHeight + ri * rowHeight, width: gutter, height: rowHeight, zIndex: 1 },
6440
+ children: ri + 1
6441
+ },
6442
+ `g-${ri}`
6443
+ )),
6444
+ visibleRows.map(
6445
+ (ri) => visibleCols.map((ci) => {
6446
+ const c = columns[ci];
6447
+ const isEditing = editing?.row === ri && editing?.col === ci;
6448
+ const canEdit = c.editable ?? editable;
6449
+ return /* @__PURE__ */ jsxRuntime.jsx(
6450
+ "div",
6451
+ {
6452
+ role: "gridcell",
6453
+ onDoubleClick: () => startEdit(ri, ci),
6454
+ className: cx(
6455
+ "flex items-center border-b border-r border-border px-3",
6456
+ ri % 2 ? "bg-surface-raised" : "bg-surface",
6457
+ canEdit && "cursor-text"
6458
+ ),
6459
+ style: {
6460
+ position: "absolute",
6461
+ top: headerHeight + ri * rowHeight,
6462
+ left: gutter + offsets[ci],
6463
+ width: widths[ci],
6464
+ height: rowHeight,
6465
+ justifyContent: c.align === "right" ? "flex-end" : c.align === "center" ? "center" : "flex-start"
6466
+ },
6467
+ children: isEditing ? /* @__PURE__ */ jsxRuntime.jsx(
6468
+ "input",
6469
+ {
6470
+ autoFocus: true,
6471
+ value: draft,
6472
+ onChange: (e) => setDraft(e.target.value),
6473
+ onBlur: commit,
6474
+ onKeyDown: (e) => {
6475
+ if (e.key === "Enter") commit();
6476
+ else if (e.key === "Escape") setEditing(null);
6477
+ },
6478
+ className: "h-full w-full bg-transparent text-foreground outline-none"
6479
+ }
6480
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-foreground", children: displayValue(rows[ri]?.[c.key] ?? "") })
6481
+ },
6482
+ `${ri}-${c.key}`
6483
+ );
6484
+ })
6485
+ )
6486
+ ] }),
6487
+ rows.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center text-foreground-muted", style: { top: headerHeight }, children: emptyState })
6488
+ ]
6489
+ }
6490
+ );
6491
+ }
6492
+ function toColumns(cols) {
6493
+ return cols.map((c) => typeof c === "string" ? { key: c, label: c } : { ...c, label: c.label ?? c.key });
6494
+ }
6495
+ function cellValue(v) {
6496
+ if (v != null && typeof v === "object" && "value" in v) return v.value;
6497
+ return v;
6498
+ }
6499
+ function toPlainRows(sheet, columns) {
6500
+ return sheet.rows.map((row) => {
6501
+ const out = {};
6502
+ for (const c of columns) out[c.key] = cellValue(row[c.key]);
6503
+ return out;
6504
+ });
6505
+ }
6506
+ var xlsxPromise = null;
6507
+ var loadXlsx = () => xlsxPromise ??= import('xlsx');
6508
+ var jspdfPromise = null;
6509
+ var loadJspdf = () => jspdfPromise ??= import('jspdf');
6510
+ function download(blob, name) {
6511
+ const url = URL.createObjectURL(blob);
6512
+ const a = document.createElement("a");
6513
+ a.href = url;
6514
+ a.download = name;
6515
+ a.click();
6516
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
6517
+ }
6518
+ function Spreadsheet({
6519
+ source,
6520
+ remote,
6521
+ editable = false,
6522
+ onCellEdit,
6523
+ onChange,
6524
+ export: exportFormats = ["xlsx", "csv", "pdf"],
6525
+ fileName,
6526
+ virtualize = true,
6527
+ className = "",
6528
+ style
6529
+ }) {
6530
+ const [sheets, setSheets] = React34.useState(Array.isArray(source) ? source : null);
6531
+ const [active, setActive] = React34.useState(0);
6532
+ const [status, setStatus] = React34.useState(Array.isArray(source) ? "ready" : "loading");
6533
+ const [error, setError] = React34.useState(null);
6534
+ const [reloadKey, setReloadKey] = React34.useState(0);
6535
+ React34.useEffect(() => {
6536
+ if (Array.isArray(source)) {
6537
+ setSheets(source);
6538
+ setStatus("ready");
6539
+ return;
6540
+ }
6541
+ let cancelled = false;
6542
+ setStatus("loading");
6543
+ setError(null);
6544
+ (async () => {
6545
+ try {
6546
+ const bytes = await sourceToBytes(source, remote);
6547
+ const XLSX = await loadXlsx();
6548
+ const wb = XLSX.read(bytes, { type: "array" });
6549
+ const parsed = wb.SheetNames.map((name) => {
6550
+ const ws = wb.Sheets[name];
6551
+ const aoa = XLSX.utils.sheet_to_json(ws, { header: 1, blankrows: false, defval: null });
6552
+ const headerRow = aoa[0] ?? [];
6553
+ const columns2 = headerRow.map((h, i) => ({
6554
+ key: h != null && String(h).length ? String(h) : `col_${i}`,
6555
+ label: h != null && String(h).length ? String(h) : `Column ${i + 1}`
6556
+ }));
6557
+ const rows = aoa.slice(1).map((r) => {
6558
+ const rec = {};
6559
+ columns2.forEach((c, i) => {
6560
+ rec[c.key] = r[i] ?? null;
6561
+ });
6562
+ return rec;
6563
+ });
6564
+ return { name, columns: columns2, rows };
6565
+ });
6566
+ if (cancelled) return;
6567
+ setSheets(parsed);
6568
+ setActive(0);
6569
+ setStatus("ready");
6570
+ } catch (err) {
6571
+ if (cancelled) return;
6572
+ setError(err);
6573
+ setStatus("error");
6574
+ }
6575
+ })();
6576
+ return () => {
6577
+ cancelled = true;
6578
+ };
6579
+ }, [source, remote, reloadKey]);
6580
+ const sheet = sheets?.[active];
6581
+ const columns = React34.useMemo(() => sheet ? toColumns(sheet.columns) : [], [sheet]);
6582
+ const plainRows = React34.useMemo(() => sheet ? toPlainRows(sheet, columns) : [], [sheet, columns]);
6583
+ const handleCellEdit = React34.useCallback(({ row, column, value }) => {
6584
+ setSheets((prev) => {
6585
+ if (!prev) return prev;
6586
+ const next = prev.map((s, i) => i === active ? { ...s, rows: s.rows.map((r) => ({ ...r })) } : s);
6587
+ const target = next[active];
6588
+ const existing = target.rows[row]?.[column];
6589
+ if (existing != null && typeof existing === "object" && "value" in existing) {
6590
+ target.rows[row][column] = { ...existing, value };
6591
+ } else {
6592
+ target.rows[row][column] = value;
6593
+ }
6594
+ onChange?.(next);
6595
+ return next;
6596
+ });
6597
+ onCellEdit?.({ sheet: sheets?.[active]?.name ?? "", row, column, value });
6598
+ }, [active, onCellEdit, onChange, sheets]);
6599
+ const baseName = React34.useMemo(
6600
+ () => (fileName || (typeof source === "object" && "name" in source ? sourceName(source) : null) || "spreadsheet").replace(/\.[^.]+$/, ""),
6601
+ [fileName, source]
6602
+ );
6603
+ const sheetAoa = React34.useCallback((s) => {
6604
+ const cols = toColumns(s.columns);
6605
+ const header = cols.map((c) => typeof c.label === "string" ? c.label : c.key);
6606
+ const body = s.rows.map((r) => cols.map((c) => cellValue(r[c.key])));
6607
+ return [header, ...body];
6608
+ }, []);
6609
+ const exportXlsx = React34.useCallback(async () => {
6610
+ if (!sheets) return;
6611
+ const XLSX = await loadXlsx();
6612
+ const wb = XLSX.utils.book_new();
6613
+ sheets.forEach((s) => {
6614
+ const ws = XLSX.utils.aoa_to_sheet(sheetAoa(s));
6615
+ XLSX.utils.book_append_sheet(wb, ws, (s.name || "Sheet").slice(0, 31));
6616
+ });
6617
+ const out = XLSX.write(wb, { bookType: "xlsx", type: "array" });
6618
+ download(new Blob([out], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }), `${baseName}.xlsx`);
6619
+ }, [sheets, sheetAoa, baseName]);
6620
+ const exportCsv = React34.useCallback(() => {
6621
+ if (!sheet) return;
6622
+ const aoa = sheetAoa(sheet);
6623
+ const esc = (v) => {
6624
+ const s = v == null ? "" : String(v);
6625
+ return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
6626
+ };
6627
+ const csv = aoa.map((row) => row.map(esc).join(",")).join("\r\n");
6628
+ download(new Blob([`\uFEFF${csv}`], { type: "text/csv;charset=utf-8" }), `${baseName}.csv`);
6629
+ }, [sheet, sheetAoa, baseName]);
6630
+ const exportPdf = React34.useCallback(async () => {
6631
+ if (!sheet) return;
6632
+ const { jsPDF } = await loadJspdf();
6633
+ const doc = new jsPDF({ orientation: "landscape", unit: "pt", format: "a4" });
6634
+ const aoa = sheetAoa(sheet);
6635
+ const margin2 = 32;
6636
+ const pageW = doc.internal.pageSize.getWidth();
6637
+ const pageH = doc.internal.pageSize.getHeight();
6638
+ const cols = aoa[0]?.length || 1;
6639
+ const colW = (pageW - margin2 * 2) / cols;
6640
+ const rowH = 18;
6641
+ let y = margin2;
6642
+ doc.setFontSize(9);
6643
+ const drawRow = (row, header) => {
6644
+ if (y + rowH > pageH - margin2) {
6645
+ doc.addPage();
6646
+ y = margin2;
6647
+ }
6648
+ doc.setFont("helvetica", header ? "bold" : "normal");
6649
+ row.forEach((cell, i) => {
6650
+ const text = cell == null ? "" : String(cell);
6651
+ doc.text(text.length > 24 ? `${text.slice(0, 23)}\u2026` : text, margin2 + i * colW + 2, y + 12);
6652
+ });
6653
+ doc.setDrawColor(210);
6654
+ doc.line(margin2, y + rowH, pageW - margin2, y + rowH);
6655
+ y += rowH;
6656
+ };
6657
+ doc.setFont("helvetica", "bold");
6658
+ doc.setFontSize(12);
6659
+ doc.text(sheet.name || baseName, margin2, y);
6660
+ y += 22;
6661
+ doc.setFontSize(9);
6662
+ aoa.forEach((row, i) => drawRow(row, i === 0));
6663
+ doc.save(`${baseName}.pdf`);
6664
+ }, [sheet, sheetAoa, baseName]);
6665
+ const runExport = (fmt) => {
6666
+ if (fmt === "xlsx") void exportXlsx();
6667
+ else if (fmt === "csv") exportCsv();
6668
+ else void exportPdf();
6669
+ };
6670
+ if (status === "error") {
6671
+ 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: [
6672
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-status-error", children: "Couldn\u2019t load the spreadsheet" }),
6673
+ error?.message && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-md text-xs text-foreground-muted", children: error.message }),
6674
+ /* @__PURE__ */ jsxRuntime.jsx(Button_default, { content: "Retry", size: "sm", variant: "outline", onClick: () => setReloadKey((k) => k + 1) })
6675
+ ] });
6676
+ }
6677
+ if (status === "loading" || !sheets) {
6678
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("rounded-lg border border-border bg-surface-raised p-4", className), style, children: [
6679
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 32, className: "mb-3 rounded" }),
6680
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonBox, { height: 360, className: "rounded" })
6681
+ ] });
6682
+ }
6683
+ const formats = exportFormats || [];
6684
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col gap-2", className), style, children: [
6685
+ (sheets.length > 1 || formats.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
6686
+ sheets.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "tablist", className: "flex flex-wrap items-center gap-1 rounded-lg border border-border bg-surface p-1", children: sheets.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
6687
+ "button",
6688
+ {
6689
+ role: "tab",
6690
+ type: "button",
6691
+ "aria-selected": i === active,
6692
+ onClick: () => setActive(i),
6693
+ className: cx(
6694
+ "rounded-md px-3 py-1 text-sm transition-colors",
6695
+ i === active ? "bg-accent text-accent-fg" : "text-foreground-secondary hover:bg-surface-raised hover:text-foreground"
6696
+ ),
6697
+ children: s.name || `Sheet ${i + 1}`
6698
+ },
6699
+ `${s.name}-${i}`
6700
+ )) }),
6701
+ formats.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center gap-1.5", children: formats.map((fmt) => /* @__PURE__ */ jsxRuntime.jsx(Button_default, { content: fmt.toUpperCase(), size: "sm", variant: "outline", onClick: () => runExport(fmt) }, fmt)) })
6702
+ ] }),
6703
+ /* @__PURE__ */ jsxRuntime.jsx(
6704
+ DataGrid,
6705
+ {
6706
+ columns,
6707
+ rows: plainRows,
6708
+ editable,
6709
+ virtualize,
6710
+ onCellEdit: handleCellEdit
6711
+ }
6712
+ )
6713
+ ] });
6714
+ }
5957
6715
  function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
5958
- const id = React31.useId();
6716
+ const id = React34.useId();
5959
6717
  return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
5960
6718
  SwitchPrimitive__namespace.Root,
5961
6719
  {
@@ -6053,8 +6811,8 @@ function FlyoutItems({ items }) {
6053
6811
  }) });
6054
6812
  }
6055
6813
  function CollapsedFlyout({ item, trigger }) {
6056
- const [open, setOpen] = React31.useState(false);
6057
- const closeTimer = React31__default.default.useRef(void 0);
6814
+ const [open, setOpen] = React34.useState(false);
6815
+ const closeTimer = React34__default.default.useRef(void 0);
6058
6816
  const openNow = () => {
6059
6817
  window.clearTimeout(closeTimer.current);
6060
6818
  setOpen(true);
@@ -6063,7 +6821,7 @@ function CollapsedFlyout({ item, trigger }) {
6063
6821
  window.clearTimeout(closeTimer.current);
6064
6822
  closeTimer.current = window.setTimeout(() => setOpen(false), 150);
6065
6823
  };
6066
- React31__default.default.useEffect(() => () => window.clearTimeout(closeTimer.current), []);
6824
+ React34__default.default.useEffect(() => () => window.clearTimeout(closeTimer.current), []);
6067
6825
  return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu2__namespace.Root, { open, onOpenChange: setOpen, modal: false, children: [
6068
6826
  /* @__PURE__ */ jsxRuntime.jsx(
6069
6827
  DropdownMenu2__namespace.Trigger,
@@ -6101,7 +6859,7 @@ function NavItem({
6101
6859
  depth = 0
6102
6860
  }) {
6103
6861
  const hasChildren = !!(item.items && item.items.length);
6104
- const [open, setOpen] = React31.useState(item.defaultOpen ?? (hasChildren && hasActiveDescendant(item)));
6862
+ const [open, setOpen] = React34.useState(item.defaultOpen ?? (hasChildren && hasActiveDescendant(item)));
6105
6863
  const handleClick = () => {
6106
6864
  if (hasChildren && isExpanded) setOpen((o) => !o);
6107
6865
  item.onClick?.();
@@ -6239,7 +6997,7 @@ function Sidebar({
6239
6997
  }
6240
6998
  ) });
6241
6999
  }
6242
- var MegaMenuContext = React31.createContext({ align: "start" });
7000
+ var MegaMenuContext = React34.createContext({ align: "start" });
6243
7001
  function MegaMenu({
6244
7002
  children,
6245
7003
  align = "start",
@@ -6270,7 +7028,7 @@ function MegaMenu({
6270
7028
  }
6271
7029
  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";
6272
7030
  function MegaMenuItem({ label, icon, href, children, className = "" }) {
6273
- const { align } = React31.useContext(MegaMenuContext);
7031
+ const { align } = React34.useContext(MegaMenuContext);
6274
7032
  const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
6275
7033
  if (!children) {
6276
7034
  return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: cx(TOP_ITEM, className), children: [
@@ -6355,8 +7113,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
6355
7113
  function MegaMenuFeatured({ children, className = "" }) {
6356
7114
  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 });
6357
7115
  }
6358
- var elementsOfType = (children, type) => React31__default.default.Children.toArray(children).filter(
6359
- (c) => React31__default.default.isValidElement(c) && c.type === type
7116
+ var elementsOfType = (children, type) => React34__default.default.Children.toArray(children).filter(
7117
+ (c) => React34__default.default.isValidElement(c) && c.type === type
6360
7118
  );
6361
7119
  var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
6362
7120
  "svg",
@@ -6393,9 +7151,9 @@ function MobileLinkRow({ link, onNavigate }) {
6393
7151
  );
6394
7152
  }
6395
7153
  function MobilePanel({ panel, onNavigate }) {
6396
- const nodes = React31__default.default.Children.toArray(panel.props.children);
7154
+ const nodes = React34__default.default.Children.toArray(panel.props.children);
6397
7155
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
6398
- if (!React31__default.default.isValidElement(node)) return null;
7156
+ if (!React34__default.default.isValidElement(node)) return null;
6399
7157
  const el = node;
6400
7158
  if (el.type === MegaMenuSection) {
6401
7159
  const { title, children } = el.props;
@@ -6414,8 +7172,8 @@ function MegaMenuMobile({
6414
7172
  children,
6415
7173
  label
6416
7174
  }) {
6417
- const [open, setOpen] = React31.useState(false);
6418
- const [expanded, setExpanded] = React31.useState(null);
7175
+ const [open, setOpen] = React34.useState(false);
7176
+ const [expanded, setExpanded] = React34.useState(null);
6419
7177
  const items = elementsOfType(children, MegaMenuItem);
6420
7178
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
6421
7179
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6488,17 +7246,17 @@ function AppShell({
6488
7246
  children,
6489
7247
  className = ""
6490
7248
  }) {
6491
- const [expanded, setExpanded] = React31.useState(sidebarDefaultExpanded);
6492
- const [isMobile, setIsMobile] = React31.useState(false);
6493
- const [mobileOpen, setMobileOpen] = React31.useState(false);
6494
- React31.useEffect(() => {
7249
+ const [expanded, setExpanded] = React34.useState(sidebarDefaultExpanded);
7250
+ const [isMobile, setIsMobile] = React34.useState(false);
7251
+ const [mobileOpen, setMobileOpen] = React34.useState(false);
7252
+ React34.useEffect(() => {
6495
7253
  const mq = window.matchMedia("(max-width: 767px)");
6496
7254
  const update = (e) => setIsMobile(e.matches);
6497
7255
  update(mq);
6498
7256
  mq.addEventListener("change", update);
6499
7257
  return () => mq.removeEventListener("change", update);
6500
7258
  }, []);
6501
- React31.useEffect(() => {
7259
+ React34.useEffect(() => {
6502
7260
  if (!isMobile) setMobileOpen(false);
6503
7261
  }, [isMobile]);
6504
7262
  const hasSidebar = sidebarSections.length > 0;
@@ -6625,7 +7383,7 @@ function SecureLayout({
6625
7383
  className = ""
6626
7384
  }) {
6627
7385
  const reduced = framerMotion.useReducedMotion();
6628
- const cbs = React31.useRef({ canAccess, onGranted, onDeny });
7386
+ const cbs = React34.useRef({ canAccess, onGranted, onDeny });
6629
7387
  cbs.current = { canAccess, onGranted, onDeny };
6630
7388
  const rolesKey = JSON.stringify(roles);
6631
7389
  const requiredRolesKey = JSON.stringify(requiredRoles);
@@ -6640,10 +7398,10 @@ function SecureLayout({
6640
7398
  if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
6641
7399
  return true;
6642
7400
  };
6643
- const [state, setState] = React31.useState(
7401
+ const [state, setState] = React34.useState(
6644
7402
  () => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
6645
7403
  );
6646
- React31.useEffect(() => {
7404
+ React34.useEffect(() => {
6647
7405
  let cancelled = false;
6648
7406
  const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
6649
7407
  const finish = (ok) => {
@@ -6804,10 +7562,10 @@ function ThemeProvider({
6804
7562
  className = "",
6805
7563
  style
6806
7564
  }) {
6807
- const id = React31__default.default.useId().replace(/:/g, "");
7565
+ const id = React34__default.default.useId().replace(/:/g, "");
6808
7566
  const scopeClass = `geo-th-${id}`;
6809
- const divRef = React31.useRef(null);
6810
- React31.useEffect(() => {
7567
+ const divRef = React34.useRef(null);
7568
+ React34.useEffect(() => {
6811
7569
  const el = divRef.current;
6812
7570
  if (!el) return;
6813
7571
  if (colorScheme === "auto") return;
@@ -6822,8 +7580,8 @@ function ThemeProvider({
6822
7580
  }
6823
7581
  el.classList.toggle("dark", colorScheme === "dark");
6824
7582
  }, [colorScheme]);
6825
- const lightVars = React31.useMemo(() => toCssVars(theme), [theme]);
6826
- const darkVarStr = React31.useMemo(() => {
7583
+ const lightVars = React34.useMemo(() => toCssVars(theme), [theme]);
7584
+ const darkVarStr = React34.useMemo(() => {
6827
7585
  if (!darkTheme) return "";
6828
7586
  const dvars = toCssVars(darkTheme);
6829
7587
  if (!Object.keys(dvars).length) return "";
@@ -6865,7 +7623,7 @@ function NumberInput({
6865
7623
  readOnly = false,
6866
7624
  precision
6867
7625
  }) {
6868
- const errorId = React31.useId();
7626
+ const errorId = React34.useId();
6869
7627
  const hasError = errorMessage != null;
6870
7628
  const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
6871
7629
  const round = (n) => {
@@ -6996,8 +7754,8 @@ function Password({
6996
7754
  showIcon,
6997
7755
  hideIcon
6998
7756
  }) {
6999
- const [visible, setVisible] = React31.useState(false);
7000
- const errorId = React31.useId();
7757
+ const [visible, setVisible] = React34.useState(false);
7758
+ const errorId = React34.useId();
7001
7759
  const hasError = errorMessage != null;
7002
7760
  return /* @__PURE__ */ jsxRuntime.jsx(
7003
7761
  Field,
@@ -7097,7 +7855,7 @@ function PasswordStrength({
7097
7855
  className = "",
7098
7856
  style
7099
7857
  }) {
7100
- const { score, label } = React31.useMemo(() => scorer(value), [scorer, value]);
7858
+ const { score, label } = React34.useMemo(() => scorer(value), [scorer, value]);
7101
7859
  const showMatch = confirmValue != null && (value.length > 0 || confirmValue.length > 0);
7102
7860
  const matches = value.length > 0 && value === confirmValue;
7103
7861
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col gap-2", className), style, "aria-live": "polite", children: [
@@ -7156,8 +7914,8 @@ function RadioTile({
7156
7914
  errorMessage,
7157
7915
  className
7158
7916
  }) {
7159
- const groupId = React31.useId();
7160
- const errorId = React31.useId();
7917
+ const groupId = React34.useId();
7918
+ const errorId = React34.useId();
7161
7919
  const hasError = errorMessage != null;
7162
7920
  return /* @__PURE__ */ jsxRuntime.jsx(
7163
7921
  Field,
@@ -7232,7 +7990,7 @@ function Checkbox({
7232
7990
  }) {
7233
7991
  const isChecked = checked ?? value ?? false;
7234
7992
  const labelFirst = labelPosition === "left";
7235
- const errorId = React31.useId();
7993
+ const errorId = React34.useId();
7236
7994
  const hasError = errorMessage != null;
7237
7995
  const box = /* @__PURE__ */ jsxRuntime.jsx(
7238
7996
  CheckboxPrimitive__namespace.Root,
@@ -7340,8 +8098,8 @@ function RadioGroup({
7340
8098
  className,
7341
8099
  errorMessage
7342
8100
  }) {
7343
- const errorId = React31.useId();
7344
- const groupId = React31.useId();
8101
+ const errorId = React34.useId();
8102
+ const groupId = React34.useId();
7345
8103
  const hasError = errorMessage != null;
7346
8104
  const labelFirst = labelPosition === "left";
7347
8105
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -7441,11 +8199,11 @@ function Switch({
7441
8199
  disabled,
7442
8200
  errorMessage
7443
8201
  }) {
7444
- const id = React31.useId();
7445
- const errorId = React31.useId();
8202
+ const id = React34.useId();
8203
+ const errorId = React34.useId();
7446
8204
  const hasError = errorMessage != null;
7447
8205
  const isControlled = checked !== void 0;
7448
- const [internal, setInternal] = React31.useState(defaultChecked);
8206
+ const [internal, setInternal] = React34.useState(defaultChecked);
7449
8207
  const isOn = isControlled ? checked : internal;
7450
8208
  const handle = (c) => {
7451
8209
  if (!isControlled) setInternal(c);
@@ -7521,15 +8279,15 @@ function MultiTagRow({
7521
8279
  labelFor,
7522
8280
  onRemove
7523
8281
  }) {
7524
- const wrapRef = React31.useRef(null);
7525
- const measureRef = React31.useRef(null);
7526
- const [visibleCount, setVisibleCount] = React31.useState(values.length);
8282
+ const wrapRef = React34.useRef(null);
8283
+ const measureRef = React34.useRef(null);
8284
+ const [visibleCount, setVisibleCount] = React34.useState(values.length);
7527
8285
  const key = values.map(String).join("|");
7528
- React31.useLayoutEffect(() => {
8286
+ React34.useLayoutEffect(() => {
7529
8287
  const wrap = wrapRef.current;
7530
8288
  const measure = measureRef.current;
7531
8289
  if (!wrap || !measure) return;
7532
- const GAP = 6;
8290
+ const GAP2 = 6;
7533
8291
  const recompute = () => {
7534
8292
  const avail = wrap.clientWidth;
7535
8293
  const tagEls = Array.from(measure.querySelectorAll("[data-mt]"));
@@ -7543,7 +8301,7 @@ function MultiTagRow({
7543
8301
  let used = 0;
7544
8302
  let count = 0;
7545
8303
  for (let i = 0; i < widths.length; i++) {
7546
- const w = widths[i] + (i > 0 ? GAP : 0);
8304
+ const w = widths[i] + (i > 0 ? GAP2 : 0);
7547
8305
  if (used + w <= avail) {
7548
8306
  used += w;
7549
8307
  count++;
@@ -7552,8 +8310,8 @@ function MultiTagRow({
7552
8310
  if (count < widths.length) {
7553
8311
  while (count > 0) {
7554
8312
  let t = 0;
7555
- for (let i = 0; i < count; i++) t += widths[i] + (i > 0 ? GAP : 0);
7556
- t += GAP + moreW;
8313
+ for (let i = 0; i < count; i++) t += widths[i] + (i > 0 ? GAP2 : 0);
8314
+ t += GAP2 + moreW;
7557
8315
  if (t <= avail) break;
7558
8316
  count--;
7559
8317
  }
@@ -7619,16 +8377,16 @@ function Dropdown({
7619
8377
  size = "md",
7620
8378
  className = ""
7621
8379
  }) {
7622
- const [open, setOpen] = React31.useState(false);
7623
- const [selectedItems, setSelectedItems] = React31.useState([]);
7624
- const [searchTerm, setSearchTerm] = React31.useState("");
7625
- const [innerItems, setInnerItems] = React31.useState([]);
7626
- const errorId = React31.useId();
8380
+ const [open, setOpen] = React34.useState(false);
8381
+ const [selectedItems, setSelectedItems] = React34.useState([]);
8382
+ const [searchTerm, setSearchTerm] = React34.useState("");
8383
+ const [innerItems, setInnerItems] = React34.useState([]);
8384
+ const errorId = React34.useId();
7627
8385
  const hasError = errorMessage != null;
7628
- React31.useEffect(() => {
8386
+ React34.useEffect(() => {
7629
8387
  setInnerItems(items);
7630
8388
  }, [items]);
7631
- React31.useEffect(() => {
8389
+ React34.useEffect(() => {
7632
8390
  if (isMultiselect && Array.isArray(value)) {
7633
8391
  setSelectedItems(value);
7634
8392
  }
@@ -7821,19 +8579,19 @@ function AutoComplete({
7821
8579
  required,
7822
8580
  htmlFor
7823
8581
  }) {
7824
- const errorId = React31.useId();
8582
+ const errorId = React34.useId();
7825
8583
  const hasError = errorMessage != null;
7826
- const [term, setTerm] = React31.useState("");
7827
- const [open, setOpen] = React31.useState(false);
7828
- const [asyncItems, setAsyncItems] = React31.useState([]);
7829
- const [loading, setLoading] = React31.useState(false);
8584
+ const [term, setTerm] = React34.useState("");
8585
+ const [open, setOpen] = React34.useState(false);
8586
+ const [asyncItems, setAsyncItems] = React34.useState([]);
8587
+ const [loading, setLoading] = React34.useState(false);
7830
8588
  const isAsync = typeof onSearch === "function";
7831
- const debounceRef = React31.useRef(null);
7832
- const requestIdRef = React31.useRef(0);
8589
+ const debounceRef = React34.useRef(null);
8590
+ const requestIdRef = React34.useRef(0);
7833
8591
  const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
7834
8592
  ({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
7835
8593
  ) : [];
7836
- React31.useEffect(() => {
8594
+ React34.useEffect(() => {
7837
8595
  if (!isAsync) return;
7838
8596
  if (debounceRef.current) clearTimeout(debounceRef.current);
7839
8597
  if (!term.trim()) {
@@ -7990,15 +8748,15 @@ function TreeSelect({
7990
8748
  defaultExpandedKeys = [],
7991
8749
  size = "md"
7992
8750
  }) {
7993
- const errorId = React31.useId();
8751
+ const errorId = React34.useId();
7994
8752
  const hasError = errorMessage != null;
7995
- const [open, setOpen] = React31.useState(false);
7996
- const [expanded, setExpanded] = React31.useState(() => new Set(defaultExpandedKeys));
7997
- const [activeIndex, setActiveIndex] = React31.useState(0);
7998
- const listRef = React31.useRef(null);
7999
- const visible = React31.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
8000
- const didSyncOnOpenRef = React31.useRef(false);
8001
- React31.useEffect(() => {
8753
+ const [open, setOpen] = React34.useState(false);
8754
+ const [expanded, setExpanded] = React34.useState(() => new Set(defaultExpandedKeys));
8755
+ const [activeIndex, setActiveIndex] = React34.useState(0);
8756
+ const listRef = React34.useRef(null);
8757
+ const visible = React34.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
8758
+ const didSyncOnOpenRef = React34.useRef(false);
8759
+ React34.useEffect(() => {
8002
8760
  if (!open) {
8003
8761
  didSyncOnOpenRef.current = false;
8004
8762
  return;
@@ -8008,7 +8766,7 @@ function TreeSelect({
8008
8766
  setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
8009
8767
  didSyncOnOpenRef.current = true;
8010
8768
  }, [open, value]);
8011
- const selectedNode = React31.useMemo(
8769
+ const selectedNode = React34.useMemo(
8012
8770
  () => value != null ? findNodeByKey(items, value) : null,
8013
8771
  [items, value]
8014
8772
  );
@@ -8240,11 +8998,11 @@ function FileInput({
8240
8998
  required,
8241
8999
  icon
8242
9000
  }) {
8243
- const inputRef = React31.useRef(null);
8244
- const errorId = React31.useId();
8245
- const [files, setFiles] = React31.useState([]);
8246
- const [dragging, setDragging] = React31.useState(false);
8247
- const [sizeError, setSizeError] = React31.useState(null);
9001
+ const inputRef = React34.useRef(null);
9002
+ const errorId = React34.useId();
9003
+ const [files, setFiles] = React34.useState([]);
9004
+ const [dragging, setDragging] = React34.useState(false);
9005
+ const [sizeError, setSizeError] = React34.useState(null);
8248
9006
  const effectiveError = errorMessage ?? sizeError ?? void 0;
8249
9007
  const openPicker = () => {
8250
9008
  if (!disabled) inputRef.current?.click();
@@ -8435,30 +9193,30 @@ function DatePicker({
8435
9193
  size = "md",
8436
9194
  className = ""
8437
9195
  }) {
8438
- const errorId = React31.useId();
9196
+ const errorId = React34.useId();
8439
9197
  const hasError = errorMessage != null;
8440
- const [open, setOpen] = React31.useState(false);
8441
- const [viewMonth, setViewMonth] = React31.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
8442
- const [focusDate, setFocusDate] = React31.useState(() => value ?? /* @__PURE__ */ new Date());
8443
- const [view, setView] = React31.useState("days");
8444
- const gridRef = React31.useRef(null);
8445
- React31.useEffect(() => {
9198
+ const [open, setOpen] = React34.useState(false);
9199
+ const [viewMonth, setViewMonth] = React34.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
9200
+ const [focusDate, setFocusDate] = React34.useState(() => value ?? /* @__PURE__ */ new Date());
9201
+ const [view, setView] = React34.useState("days");
9202
+ const gridRef = React34.useRef(null);
9203
+ React34.useEffect(() => {
8446
9204
  if (!open) return;
8447
9205
  const target = value ?? /* @__PURE__ */ new Date();
8448
9206
  setViewMonth(startOfMonth2(target));
8449
9207
  setFocusDate(target);
8450
9208
  setView("days");
8451
9209
  }, [open, value]);
8452
- React31.useEffect(() => {
9210
+ React34.useEffect(() => {
8453
9211
  if (!open) return;
8454
9212
  const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
8455
9213
  cell?.focus();
8456
9214
  }, [open, focusDate]);
8457
- const weekdays = React31.useMemo(() => {
9215
+ const weekdays = React34.useMemo(() => {
8458
9216
  const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
8459
9217
  return ordered;
8460
9218
  }, [weekStartsOn]);
8461
- const grid = React31.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
9219
+ const grid = React34.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
8462
9220
  const isDisabled = (d) => {
8463
9221
  if (min && d < min) return true;
8464
9222
  if (max && d > max) return true;
@@ -8513,7 +9271,7 @@ function DatePicker({
8513
9271
  setOpen(false);
8514
9272
  }
8515
9273
  };
8516
- const displayValue = value ? format(value) : "";
9274
+ const displayValue2 = value ? format(value) : "";
8517
9275
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1 ${className}`.trim(), children: [
8518
9276
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex ${layout === "vertical" ? "flex-col gap-1.5" : "flex-row items-start gap-3"}`, children: [
8519
9277
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -8540,7 +9298,7 @@ function DatePicker({
8540
9298
  "aria-expanded": open,
8541
9299
  className: `flex items-center justify-between cursor-pointer select-none ${!style?.width ? "min-w-[200px]" : ""} ${fieldShell({ size, hasError, disabled })}`,
8542
9300
  children: [
8543
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm truncate ${displayValue ? "" : "text-foreground-muted"}`, children: displayValue || placeholder }),
9301
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-sm truncate ${displayValue2 ? "" : "text-foreground-muted"}`, children: displayValue2 || placeholder }),
8544
9302
  /* @__PURE__ */ jsxRuntime.jsx(CalendarIcon, {})
8545
9303
  ]
8546
9304
  }
@@ -8749,10 +9507,10 @@ function TextArea({
8749
9507
  style,
8750
9508
  inputStyle
8751
9509
  }) {
8752
- const errorId = React31.useId();
9510
+ const errorId = React34.useId();
8753
9511
  const hasError = errorMessage != null;
8754
- const ref = React31.useRef(null);
8755
- React31.useLayoutEffect(() => {
9512
+ const ref = React34.useRef(null);
9513
+ React34.useLayoutEffect(() => {
8756
9514
  if (!autoGrow) return;
8757
9515
  const el = ref.current;
8758
9516
  if (!el) return;
@@ -8824,14 +9582,14 @@ function Slider({
8824
9582
  name,
8825
9583
  htmlFor
8826
9584
  }) {
8827
- const errorId = React31.useId();
9585
+ const errorId = React34.useId();
8828
9586
  const hasError = errorMessage != null;
8829
9587
  const isRange = Array.isArray(value ?? defaultValue);
8830
- const [internal, setInternal] = React31.useState(
9588
+ const [internal, setInternal] = React34.useState(
8831
9589
  () => toArray(value) ?? toArray(defaultValue) ?? [min]
8832
9590
  );
8833
9591
  const current = toArray(value) ?? internal;
8834
- const [dragging, setDragging] = React31.useState(false);
9592
+ const [dragging, setDragging] = React34.useState(false);
8835
9593
  const emit = (arr) => {
8836
9594
  setInternal(arr);
8837
9595
  const next = isRange ? [arr[0], arr[1]] : arr[0];
@@ -8926,11 +9684,11 @@ function TagsInput({
8926
9684
  validate,
8927
9685
  separators = ["Enter", ","]
8928
9686
  }) {
8929
- const errorId = React31.useId();
8930
- const inputRef = React31.useRef(null);
8931
- const [internal, setInternal] = React31.useState(defaultValue ?? []);
8932
- const [draft, setDraft] = React31.useState("");
8933
- const [localError, setLocalError] = React31.useState(null);
9687
+ const errorId = React34.useId();
9688
+ const inputRef = React34.useRef(null);
9689
+ const [internal, setInternal] = React34.useState(defaultValue ?? []);
9690
+ const [draft, setDraft] = React34.useState("");
9691
+ const [localError, setLocalError] = React34.useState(null);
8934
9692
  const tags = value ?? internal;
8935
9693
  const hasError = errorMessage != null || localError != null;
8936
9694
  const errorText = errorMessage ?? localError ?? void 0;
@@ -9061,9 +9819,9 @@ function OtpInput({
9061
9819
  className,
9062
9820
  groupAfter
9063
9821
  }) {
9064
- const errorId = React31.useId();
9822
+ const errorId = React34.useId();
9065
9823
  const hasError = errorMessage != null;
9066
- const refs = React31.useRef([]);
9824
+ const refs = React34.useRef([]);
9067
9825
  const chars = Array.from({ length }, (_, i) => value[i] ?? "");
9068
9826
  const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
9069
9827
  const emit = (next) => {
@@ -9112,7 +9870,7 @@ function OtpInput({
9112
9870
  emit(valid.join(""));
9113
9871
  focusBox(valid.length);
9114
9872
  };
9115
- 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(React31__default.default.Fragment, { children: [
9873
+ 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: [
9116
9874
  /* @__PURE__ */ jsxRuntime.jsx(
9117
9875
  "input",
9118
9876
  {
@@ -9170,9 +9928,9 @@ function Rating({
9170
9928
  className,
9171
9929
  required
9172
9930
  }) {
9173
- const errorId = React31.useId();
9174
- const [internal, setInternal] = React31.useState(defaultValue);
9175
- const [hover, setHover] = React31.useState(null);
9931
+ const errorId = React34.useId();
9932
+ const [internal, setInternal] = React34.useState(defaultValue);
9933
+ const [hover, setHover] = React34.useState(null);
9176
9934
  const current = value ?? internal;
9177
9935
  const display2 = hover ?? current;
9178
9936
  const interactive = !readOnly && !disabled;
@@ -9295,9 +10053,9 @@ function TimePicker({
9295
10053
  required,
9296
10054
  style
9297
10055
  }) {
9298
- const errorId = React31.useId();
10056
+ const errorId = React34.useId();
9299
10057
  const hasError = errorMessage != null;
9300
- const [open, setOpen] = React31.useState(false);
10058
+ const [open, setOpen] = React34.useState(false);
9301
10059
  const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
9302
10060
  const update = (next) => {
9303
10061
  const merged = { ...parsed, ...next };
@@ -9422,13 +10180,13 @@ function DateRangePicker({
9422
10180
  required,
9423
10181
  style
9424
10182
  }) {
9425
- const errorId = React31.useId();
10183
+ const errorId = React34.useId();
9426
10184
  const hasError = errorMessage != null;
9427
- const [open, setOpen] = React31.useState(false);
9428
- const [leftMonth, setLeftMonth] = React31.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
9429
- const [pendingStart, setPendingStart] = React31.useState(null);
9430
- const [hoverDate, setHoverDate] = React31.useState(null);
9431
- const weekdays = React31.useMemo(
10185
+ const [open, setOpen] = React34.useState(false);
10186
+ const [leftMonth, setLeftMonth] = React34.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
10187
+ const [pendingStart, setPendingStart] = React34.useState(null);
10188
+ const [hoverDate, setHoverDate] = React34.useState(null);
10189
+ const weekdays = React34.useMemo(
9432
10190
  () => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
9433
10191
  [weekStartsOn]
9434
10192
  );
@@ -9605,10 +10363,10 @@ function ColorPicker({
9605
10363
  required,
9606
10364
  placeholder = "Pick a colour\u2026"
9607
10365
  }) {
9608
- const errorId = React31.useId();
10366
+ const errorId = React34.useId();
9609
10367
  const hasError = errorMessage != null;
9610
- const [open, setOpen] = React31.useState(false);
9611
- const [draft, setDraft] = React31.useState(value);
10368
+ const [open, setOpen] = React34.useState(false);
10369
+ const [draft, setDraft] = React34.useState(value);
9612
10370
  const valid = HEX_RE.test(value);
9613
10371
  const pick = (hex) => {
9614
10372
  onChange?.(hex);
@@ -9696,7 +10454,7 @@ function ColorPicker({
9696
10454
  }
9697
10455
  var CUSTOM_EVENT = "oxy-local-storage";
9698
10456
  function useLocalStorage(key, initialValue) {
9699
- const read = React31.useCallback(() => {
10457
+ const read = React34.useCallback(() => {
9700
10458
  if (typeof window === "undefined") return initialValue;
9701
10459
  try {
9702
10460
  const item = window.localStorage.getItem(key);
@@ -9705,8 +10463,8 @@ function useLocalStorage(key, initialValue) {
9705
10463
  return initialValue;
9706
10464
  }
9707
10465
  }, [key]);
9708
- const [stored, setStored] = React31.useState(read);
9709
- const setValue = React31.useCallback((value) => {
10466
+ const [stored, setStored] = React34.useState(read);
10467
+ const setValue = React34.useCallback((value) => {
9710
10468
  setStored((prev) => {
9711
10469
  const next = value instanceof Function ? value(prev) : value;
9712
10470
  try {
@@ -9719,7 +10477,7 @@ function useLocalStorage(key, initialValue) {
9719
10477
  return next;
9720
10478
  });
9721
10479
  }, [key]);
9722
- const remove = React31.useCallback(() => {
10480
+ const remove = React34.useCallback(() => {
9723
10481
  try {
9724
10482
  if (typeof window !== "undefined") {
9725
10483
  window.localStorage.removeItem(key);
@@ -9729,10 +10487,10 @@ function useLocalStorage(key, initialValue) {
9729
10487
  }
9730
10488
  setStored(initialValue);
9731
10489
  }, [key]);
9732
- React31.useEffect(() => {
10490
+ React34.useEffect(() => {
9733
10491
  setStored(read());
9734
10492
  }, [key, read]);
9735
- React31.useEffect(() => {
10493
+ React34.useEffect(() => {
9736
10494
  if (typeof window === "undefined") return;
9737
10495
  const onStorage = (e) => {
9738
10496
  if (e.key === null || e.key === key) setStored(read());
@@ -9751,8 +10509,8 @@ function useLocalStorage(key, initialValue) {
9751
10509
  }
9752
10510
  function useMediaQuery(query) {
9753
10511
  const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
9754
- const [matches, setMatches] = React31.useState(get);
9755
- React31.useEffect(() => {
10512
+ const [matches, setMatches] = React34.useState(get);
10513
+ React34.useEffect(() => {
9756
10514
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9757
10515
  const mql = window.matchMedia(query);
9758
10516
  const onChange = () => setMatches(mql.matches);
@@ -9783,8 +10541,8 @@ function decodeSegment(seg) {
9783
10541
  }
9784
10542
  }
9785
10543
  function useJwt(token) {
9786
- const [, tick] = React31.useState(0);
9787
- const decoded = React31.useMemo(() => {
10544
+ const [, tick] = React34.useState(0);
10545
+ const decoded = React34.useMemo(() => {
9788
10546
  if (!token) return { payload: null, header: null, exp: null };
9789
10547
  const [h, p] = token.split(".");
9790
10548
  const header = decodeSegment(h);
@@ -9792,7 +10550,7 @@ function useJwt(token) {
9792
10550
  const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
9793
10551
  return { payload, header, exp };
9794
10552
  }, [token]);
9795
- React31.useEffect(() => {
10553
+ React34.useEffect(() => {
9796
10554
  if (decoded.exp == null) return;
9797
10555
  const ms = decoded.exp * 1e3 - Date.now();
9798
10556
  if (ms <= 0) return;
@@ -9966,13 +10724,13 @@ function SlideShow({
9966
10724
  style
9967
10725
  }) {
9968
10726
  const reduced = framerMotion.useReducedMotion();
9969
- const [index, setIndex] = React31.useState(0);
9970
- const [paused, setPaused] = React31.useState(false);
10727
+ const [index, setIndex] = React34.useState(0);
10728
+ const [paused, setPaused] = React34.useState(false);
9971
10729
  const count = slides.length;
9972
10730
  const idx = count ? (index % count + count) % count : 0;
9973
- const go = React31.useCallback((d) => setIndex((i) => i + d), []);
9974
- const timer = React31.useRef(null);
9975
- React31.useEffect(() => {
10731
+ const go = React34.useCallback((d) => setIndex((i) => i + d), []);
10732
+ const timer = React34.useRef(null);
10733
+ React34.useEffect(() => {
9976
10734
  if (!autoPlay || paused || count <= 1) return;
9977
10735
  timer.current = setInterval(() => setIndex((i) => i + 1), interval);
9978
10736
  return () => {
@@ -10048,7 +10806,7 @@ function Video({
10048
10806
  className = "",
10049
10807
  style
10050
10808
  }) {
10051
- const [playing, setPlaying] = React31.useState(autoPlay);
10809
+ const [playing, setPlaying] = React34.useState(autoPlay);
10052
10810
  const frame = cx("relative w-full overflow-hidden bg-backdrop", framed ? "rounded-2xl border border-border shadow-sm" : "", className);
10053
10811
  const ratio = aspect.replace("/", " / ");
10054
10812
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frame, style: { aspectRatio: ratio, ...style }, children: embedUrl ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -10103,7 +10861,7 @@ function Parallax({
10103
10861
  style
10104
10862
  }) {
10105
10863
  const reduced = framerMotion.useReducedMotion();
10106
- const ref = React31.useRef(null);
10864
+ const ref = React34.useRef(null);
10107
10865
  const { scrollYProgress } = framerMotion.useScroll({ target: ref, offset: ["start end", "end start"] });
10108
10866
  const shift = Math.max(0, Math.min(1, speed)) * 100;
10109
10867
  const y = framerMotion.useTransform(scrollYProgress, [0, 1], reduced ? ["0%", "0%"] : [`-${shift / 2}%`, `${shift / 2}%`]);
@@ -10171,7 +10929,7 @@ function Blog({
10171
10929
  post.tag != null && !post.image && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "accent", variant: "soft", size: "sm", children: post.tag }) }),
10172
10930
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold leading-snug text-foreground transition-colors group-hover:text-accent", children: post.title }),
10173
10931
  post.excerpt != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-foreground-secondary", children: post.excerpt }),
10174
- 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(React31__default.default.Fragment, { children: [
10932
+ 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: [
10175
10933
  j > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }),
10176
10934
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: m })
10177
10935
  ] }, j)) })
@@ -10300,8 +11058,8 @@ function LeadCapture({
10300
11058
  className = "",
10301
11059
  style
10302
11060
  }) {
10303
- const [email, setEmail] = React31.useState("");
10304
- const [done, setDone] = React31.useState(false);
11061
+ const [email, setEmail] = React34.useState("");
11062
+ const [done, setDone] = React34.useState(false);
10305
11063
  const submit = (e) => {
10306
11064
  e.preventDefault();
10307
11065
  const value = email.trim();
@@ -10394,6 +11152,7 @@ exports.ColorPicker = ColorPicker;
10394
11152
  exports.ContextMenu = ContextMenu;
10395
11153
  exports.CookieConsent = CookieConsent;
10396
11154
  exports.CreditCardForm = CreditCardForm;
11155
+ exports.DataGrid = DataGrid;
10397
11156
  exports.DateRangePicker = DateRangePicker;
10398
11157
  exports.Drawer = Drawer;
10399
11158
  exports.Dropdown = Dropdown;
@@ -10429,6 +11188,7 @@ exports.OtpInput = OtpInput;
10429
11188
  exports.Parallax = Parallax;
10430
11189
  exports.Password = Password;
10431
11190
  exports.PasswordStrength = PasswordStrength;
11191
+ exports.PdfViewer = PdfViewer;
10432
11192
  exports.PopConfirm = PopConfirm;
10433
11193
  exports.Portal = Portal;
10434
11194
  exports.PricingPlans = PricingPlans;
@@ -10448,6 +11208,7 @@ exports.SkeletonText = SkeletonText;
10448
11208
  exports.SlideShow = SlideShow;
10449
11209
  exports.Slider = Slider;
10450
11210
  exports.Socials = Socials;
11211
+ exports.Spreadsheet = Spreadsheet;
10451
11212
  exports.Statistic = Statistic;
10452
11213
  exports.Stepper = Stepper;
10453
11214
  exports.Switch = Switch;