@geomak/ui 7.1.0 → 7.2.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 chunkOAV4TA4B_cjs = require('./chunk-OAV4TA4B.cjs');
5
- var React28 = require('react');
5
+ var React29 = 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');
@@ -17,8 +17,8 @@ var ToggleGroup = require('@radix-ui/react-toggle-group');
17
17
  var ContextMenuPrimitive = require('@radix-ui/react-context-menu');
18
18
  var SwitchPrimitive = require('@radix-ui/react-switch');
19
19
  var NavigationMenu = require('@radix-ui/react-navigation-menu');
20
- var CheckboxPrimitive = require('@radix-ui/react-checkbox');
21
20
  var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
21
+ var CheckboxPrimitive = require('@radix-ui/react-checkbox');
22
22
  var SliderPrimitive = require('@radix-ui/react-slider');
23
23
 
24
24
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -41,7 +41,7 @@ function _interopNamespace(e) {
41
41
  return Object.freeze(n);
42
42
  }
43
43
 
44
- var React28__default = /*#__PURE__*/_interopDefault(React28);
44
+ var React29__default = /*#__PURE__*/_interopDefault(React29);
45
45
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
46
46
  var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
47
47
  var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
@@ -53,8 +53,8 @@ var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
53
53
  var ContextMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(ContextMenuPrimitive);
54
54
  var SwitchPrimitive__namespace = /*#__PURE__*/_interopNamespace(SwitchPrimitive);
55
55
  var NavigationMenu__namespace = /*#__PURE__*/_interopNamespace(NavigationMenu);
56
- var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
57
56
  var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
57
+ var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
58
58
  var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
59
59
 
60
60
  // src/utils/cx.ts
@@ -67,8 +67,8 @@ function cx(...values) {
67
67
  return out;
68
68
  }
69
69
  function Portal({ children, target }) {
70
- const [resolved, setResolved] = React28.useState(null);
71
- React28.useEffect(() => {
70
+ const [resolved, setResolved] = React29.useState(null);
71
+ React29.useEffect(() => {
72
72
  if (target === null) {
73
73
  setResolved(null);
74
74
  return;
@@ -502,7 +502,7 @@ function IconButton({
502
502
  className = "",
503
503
  style
504
504
  }) {
505
- const colorScheme = React28.useMemo(() => {
505
+ const colorScheme = React29.useMemo(() => {
506
506
  if (type === "primary") {
507
507
  return "bg-accent text-accent-fg hover:bg-accent-hover";
508
508
  }
@@ -592,7 +592,7 @@ var SIZE_CLASSES = {
592
592
  md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
593
593
  lg: "h-11 px-5 text-sm gap-2 rounded-xl"
594
594
  };
595
- var Button = React28__default.default.forwardRef(function Button2({
595
+ var Button = React29__default.default.forwardRef(function Button2({
596
596
  content,
597
597
  variant = "primary",
598
598
  size = "md",
@@ -700,7 +700,7 @@ function MenuButton({
700
700
  "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
701
701
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
702
702
  ].join(" "),
703
- children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
703
+ children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
704
704
  item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border" }),
705
705
  /* @__PURE__ */ jsxRuntime.jsxs(
706
706
  DropdownMenu__namespace.Item,
@@ -943,9 +943,9 @@ function Tooltip({
943
943
  ] }) });
944
944
  }
945
945
  var TooltipProvider = TooltipPrimitive__namespace.Provider;
946
- var TabsContext = React28.createContext(null);
946
+ var TabsContext = React29.createContext(null);
947
947
  function useTabsContext() {
948
- const ctx = React28.useContext(TabsContext);
948
+ const ctx = React29.useContext(TabsContext);
949
949
  if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
950
950
  return ctx;
951
951
  }
@@ -967,26 +967,26 @@ function Tabs({
967
967
  children
968
968
  }) {
969
969
  const isControlled = value !== void 0;
970
- const [internal, setInternal] = React28.useState(defaultValue);
970
+ const [internal, setInternal] = React29.useState(defaultValue);
971
971
  const current = isControlled ? value : internal;
972
972
  const reduced = !!framerMotion.useReducedMotion();
973
- const indicatorId = React28.useId();
974
- const select = React28.useCallback((next) => {
973
+ const indicatorId = React29.useId();
974
+ const select = React29.useCallback((next) => {
975
975
  if (!isControlled) setInternal(next);
976
976
  onChange?.(next);
977
977
  }, [isControlled, onChange]);
978
- const registry = React28.useRef(/* @__PURE__ */ new Map());
979
- const orderRef = React28.useRef(0);
980
- const [, bump] = React28.useState(0);
981
- const registerTab = React28.useCallback((val, meta) => {
978
+ const registry = React29.useRef(/* @__PURE__ */ new Map());
979
+ const orderRef = React29.useRef(0);
980
+ const [, bump] = React29.useState(0);
981
+ const registerTab = React29.useCallback((val, meta) => {
982
982
  const existing = registry.current.get(val);
983
983
  registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
984
984
  if (!existing) bump((v) => v + 1);
985
985
  }, []);
986
- const unregisterTab = React28.useCallback((val) => {
986
+ const unregisterTab = React29.useCallback((val) => {
987
987
  if (registry.current.delete(val)) bump((v) => v + 1);
988
988
  }, []);
989
- const getTabs = React28.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 })), []);
989
+ const getTabs = React29.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 })), []);
990
990
  return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
991
991
  TabsPrimitive__namespace.Root,
992
992
  {
@@ -1006,10 +1006,10 @@ function Tabs({
1006
1006
  function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
1007
1007
  const { variant, orientation, reduced, value } = useTabsContext();
1008
1008
  const horizontal = orientation === "horizontal";
1009
- const scrollRef = React28.useRef(null);
1010
- const [edges, setEdges] = React28.useState({ start: false, end: false });
1009
+ const scrollRef = React29.useRef(null);
1010
+ const [edges, setEdges] = React29.useState({ start: false, end: false });
1011
1011
  const scrollable = variant !== "segmented";
1012
- React28.useLayoutEffect(() => {
1012
+ React29.useLayoutEffect(() => {
1013
1013
  const el = scrollRef.current;
1014
1014
  if (!el || !scrollable) return;
1015
1015
  const update = () => {
@@ -1034,13 +1034,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
1034
1034
  ro.disconnect();
1035
1035
  };
1036
1036
  }, [horizontal, scrollable, children]);
1037
- const nudge = React28.useCallback((dir) => {
1037
+ const nudge = React29.useCallback((dir) => {
1038
1038
  const el = scrollRef.current;
1039
1039
  if (!el) return;
1040
1040
  const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
1041
1041
  el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
1042
1042
  }, [horizontal, reduced]);
1043
- React28.useLayoutEffect(() => {
1043
+ React29.useLayoutEffect(() => {
1044
1044
  const el = scrollRef.current;
1045
1045
  if (!el || !scrollable) return;
1046
1046
  const active = el.querySelector("[role=tab][data-state=active]");
@@ -1098,9 +1098,9 @@ function Chevron2({ side, orientation, onClick }) {
1098
1098
  function OverflowMenu() {
1099
1099
  const { getTabs, value, select, orientation } = useTabsContext();
1100
1100
  const horizontal = orientation === "horizontal";
1101
- const [open, setOpen] = React28.useState(false);
1102
- const wrapRef = React28.useRef(null);
1103
- const timer = React28.useRef(null);
1101
+ const [open, setOpen] = React29.useState(false);
1102
+ const wrapRef = React29.useRef(null);
1103
+ const timer = React29.useRef(null);
1104
1104
  const openNow = () => {
1105
1105
  if (timer.current) clearTimeout(timer.current);
1106
1106
  setOpen(true);
@@ -1108,7 +1108,7 @@ function OverflowMenu() {
1108
1108
  const closeSoon = () => {
1109
1109
  timer.current = setTimeout(() => setOpen(false), 160);
1110
1110
  };
1111
- React28.useLayoutEffect(() => {
1111
+ React29.useLayoutEffect(() => {
1112
1112
  if (!open) return;
1113
1113
  const onDoc = (e) => {
1114
1114
  if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
@@ -1189,7 +1189,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
1189
1189
  const isActive = active === value;
1190
1190
  const horizontal = orientation === "horizontal";
1191
1191
  const sz = SIZE[size];
1192
- React28.useLayoutEffect(() => {
1192
+ React29.useLayoutEffect(() => {
1193
1193
  registerTab(value, { label: children, icon, disabled });
1194
1194
  return () => unregisterTab(value);
1195
1195
  }, [value, children, icon, disabled, registerTab, unregisterTab]);
@@ -1387,7 +1387,7 @@ function Tree({
1387
1387
  item.key
1388
1388
  )) });
1389
1389
  }
1390
- var AccordionCtx = React28.createContext({ variant: "separated" });
1390
+ var AccordionCtx = React29.createContext({ variant: "separated" });
1391
1391
  function Accordion2({
1392
1392
  children,
1393
1393
  type = "single",
@@ -1446,7 +1446,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
1446
1446
  }
1447
1447
  );
1448
1448
  function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
1449
- const { variant } = React28.useContext(AccordionCtx);
1449
+ const { variant } = React29.useContext(AccordionCtx);
1450
1450
  return /* @__PURE__ */ jsxRuntime.jsxs(
1451
1451
  AccordionPrimitive__namespace.Item,
1452
1452
  {
@@ -1505,7 +1505,7 @@ function Breadcrumbs({
1505
1505
  className = "",
1506
1506
  style
1507
1507
  }) {
1508
- const [expanded, setExpanded] = React28.useState(false);
1508
+ const [expanded, setExpanded] = React29.useState(false);
1509
1509
  const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
1510
1510
  const visible = [];
1511
1511
  if (shouldCollapse) {
@@ -1689,8 +1689,8 @@ function Stepper({
1689
1689
  className = ""
1690
1690
  }) {
1691
1691
  const reduced = framerMotion.useReducedMotion();
1692
- const [forcedVertical, setForcedVertical] = React28.useState(false);
1693
- React28.useEffect(() => {
1692
+ const [forcedVertical, setForcedVertical] = React29.useState(false);
1693
+ React29.useEffect(() => {
1694
1694
  if (!responsive || orientation === "vertical") return;
1695
1695
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1696
1696
  const mq = window.matchMedia("(max-width: 767px)");
@@ -1799,7 +1799,7 @@ function Kbd({
1799
1799
  style
1800
1800
  }) {
1801
1801
  if (keys && keys.length > 0) {
1802
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
1802
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("inline-flex items-center gap-1", className), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
1803
1803
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
1804
1804
  /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
1805
1805
  ] }, `${k}-${i}`)) });
@@ -1890,13 +1890,13 @@ function FlatCarousel({
1890
1890
  className = "",
1891
1891
  style
1892
1892
  }) {
1893
- const scrollerRef = React28.useRef(null);
1894
- const slides = React28__default.default.Children.toArray(children);
1895
- const [active, setActive] = React28.useState(0);
1896
- const [atStart, setAtStart] = React28.useState(true);
1897
- const [atEnd, setAtEnd] = React28.useState(false);
1893
+ const scrollerRef = React29.useRef(null);
1894
+ const slides = React29__default.default.Children.toArray(children);
1895
+ const [active, setActive] = React29.useState(0);
1896
+ const [atStart, setAtStart] = React29.useState(true);
1897
+ const [atEnd, setAtEnd] = React29.useState(false);
1898
1898
  const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
1899
- const update = React28.useCallback(() => {
1899
+ const update = React29.useCallback(() => {
1900
1900
  const el = scrollerRef.current;
1901
1901
  if (!el) return;
1902
1902
  setAtStart(el.scrollLeft <= 1);
@@ -1905,7 +1905,7 @@ function FlatCarousel({
1905
1905
  const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
1906
1906
  setActive(Math.round(el.scrollLeft / slideW));
1907
1907
  }, [gap]);
1908
- React28.useEffect(() => {
1908
+ React29.useEffect(() => {
1909
1909
  update();
1910
1910
  const el = scrollerRef.current;
1911
1911
  if (!el) return;
@@ -1946,9 +1946,9 @@ function RotatingCarousel({
1946
1946
  className = "",
1947
1947
  style
1948
1948
  }) {
1949
- const slides = React28__default.default.Children.toArray(children);
1949
+ const slides = React29__default.default.Children.toArray(children);
1950
1950
  const count = slides.length;
1951
- const [active, setActive] = React28.useState(0);
1951
+ const [active, setActive] = React29.useState(0);
1952
1952
  const reduced = framerMotion.useReducedMotion();
1953
1953
  const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
1954
1954
  const idx = wrap(active);
@@ -2186,13 +2186,13 @@ function Chat({
2186
2186
  className = "",
2187
2187
  style
2188
2188
  }) {
2189
- const listRef = React28.useRef(null);
2190
- const atBottomRef = React28.useRef(true);
2191
- const [showJump, setShowJump] = React28.useState(false);
2192
- const [draft, setDraft] = React28.useState("");
2189
+ const listRef = React29.useRef(null);
2190
+ const atBottomRef = React29.useRef(true);
2191
+ const [showJump, setShowJump] = React29.useState(false);
2192
+ const [draft, setDraft] = React29.useState("");
2193
2193
  const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
2194
2194
  const isTyping = typingNames.length > 0;
2195
- const scrollToBottom = React28.useCallback((smooth = true) => {
2195
+ const scrollToBottom = React29.useCallback((smooth = true) => {
2196
2196
  const el = listRef.current;
2197
2197
  if (!el) return;
2198
2198
  if (typeof el.scrollTo === "function") el.scrollTo({ top: el.scrollHeight, behavior: smooth ? "smooth" : "auto" });
@@ -2205,10 +2205,10 @@ function Chat({
2205
2205
  atBottomRef.current = near;
2206
2206
  setShowJump(!near);
2207
2207
  };
2208
- React28.useEffect(() => {
2208
+ React29.useEffect(() => {
2209
2209
  if (atBottomRef.current) scrollToBottom(messages.length > 0);
2210
2210
  }, [messages.length, isTyping]);
2211
- React28.useEffect(() => {
2211
+ React29.useEffect(() => {
2212
2212
  scrollToBottom(false);
2213
2213
  }, [scrollToBottom]);
2214
2214
  const send = () => {
@@ -2398,7 +2398,7 @@ function FAB({
2398
2398
  className = "",
2399
2399
  style
2400
2400
  }) {
2401
- const [open, setOpen] = React28.useState(false);
2401
+ const [open, setOpen] = React29.useState(false);
2402
2402
  const reduced = framerMotion.useReducedMotion();
2403
2403
  const hasDial = !!actions && actions.length > 0;
2404
2404
  const bottom = position.startsWith("bottom");
@@ -2500,8 +2500,8 @@ function PopConfirm({
2500
2500
  onOpenChange,
2501
2501
  className = ""
2502
2502
  }) {
2503
- const [uncontrolledOpen, setUncontrolledOpen] = React28.useState(false);
2504
- const [loading, setLoading] = React28.useState(false);
2503
+ const [uncontrolledOpen, setUncontrolledOpen] = React29.useState(false);
2504
+ const [loading, setLoading] = React29.useState(false);
2505
2505
  const isOpen = open ?? uncontrolledOpen;
2506
2506
  const setOpen = (next) => {
2507
2507
  onOpenChange?.(next);
@@ -2588,16 +2588,16 @@ function LogoutTimer({
2588
2588
  logoutLabel = "Sign out now"
2589
2589
  }) {
2590
2590
  const reduced = framerMotion.useReducedMotion();
2591
- const [warning, setWarning] = React28.useState(false);
2592
- const [remaining, setRemaining] = React28.useState(countdown);
2593
- const idleTimer = React28.useRef(null);
2594
- const tick = React28.useRef(null);
2595
- const deadline = React28.useRef(0);
2596
- const warningRef = React28.useRef(false);
2597
- const lastReset = React28.useRef(0);
2598
- const cbs = React28.useRef({ onLogout, onContinue, onWarning });
2591
+ const [warning, setWarning] = React29.useState(false);
2592
+ const [remaining, setRemaining] = React29.useState(countdown);
2593
+ const idleTimer = React29.useRef(null);
2594
+ const tick = React29.useRef(null);
2595
+ const deadline = React29.useRef(0);
2596
+ const warningRef = React29.useRef(false);
2597
+ const lastReset = React29.useRef(0);
2598
+ const cbs = React29.useRef({ onLogout, onContinue, onWarning });
2599
2599
  cbs.current = { onLogout, onContinue, onWarning };
2600
- const clearTimers = React28.useCallback(() => {
2600
+ const clearTimers = React29.useCallback(() => {
2601
2601
  if (idleTimer.current) {
2602
2602
  clearTimeout(idleTimer.current);
2603
2603
  idleTimer.current = null;
@@ -2607,13 +2607,13 @@ function LogoutTimer({
2607
2607
  tick.current = null;
2608
2608
  }
2609
2609
  }, []);
2610
- const logout = React28.useCallback(() => {
2610
+ const logout = React29.useCallback(() => {
2611
2611
  clearTimers();
2612
2612
  warningRef.current = false;
2613
2613
  setWarning(false);
2614
2614
  cbs.current.onLogout();
2615
2615
  }, [clearTimers]);
2616
- const startIdle = React28.useCallback(() => {
2616
+ const startIdle = React29.useCallback(() => {
2617
2617
  if (idleTimer.current) clearTimeout(idleTimer.current);
2618
2618
  idleTimer.current = setTimeout(() => {
2619
2619
  warningRef.current = true;
@@ -2628,7 +2628,7 @@ function LogoutTimer({
2628
2628
  }, 250);
2629
2629
  }, timeout);
2630
2630
  }, [timeout, countdown, logout]);
2631
- const stay = React28.useCallback(() => {
2631
+ const stay = React29.useCallback(() => {
2632
2632
  if (tick.current) {
2633
2633
  clearInterval(tick.current);
2634
2634
  tick.current = null;
@@ -2638,7 +2638,7 @@ function LogoutTimer({
2638
2638
  cbs.current.onContinue?.();
2639
2639
  startIdle();
2640
2640
  }, [startIdle]);
2641
- React28.useEffect(() => {
2641
+ React29.useEffect(() => {
2642
2642
  if (!enabled) {
2643
2643
  clearTimers();
2644
2644
  warningRef.current = false;
@@ -2703,11 +2703,11 @@ function SegmentedControl({
2703
2703
  "aria-label": ariaLabel
2704
2704
  }) {
2705
2705
  const sz = SIZE5[size];
2706
- const groupId = React28.useId();
2707
- const errorId = React28.useId();
2706
+ const groupId = React29.useId();
2707
+ const errorId = React29.useId();
2708
2708
  const hasError = errorMessage != null;
2709
2709
  const isControlled = value !== void 0;
2710
- const [internal, setInternal] = React28.useState(defaultValue);
2710
+ const [internal, setInternal] = React29.useState(defaultValue);
2711
2711
  const current = isControlled ? value : internal;
2712
2712
  const handle = (v) => {
2713
2713
  if (!v) return;
@@ -2868,22 +2868,22 @@ function Scheduler({
2868
2868
  style
2869
2869
  }) {
2870
2870
  const reduced = framerMotion.useReducedMotion();
2871
- const [view, setView] = React28.useState(defaultView);
2872
- const [cursor, setCursor] = React28.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
2873
- const [loaded, setLoaded] = React28.useState([]);
2874
- const [loading, setLoading] = React28.useState(false);
2875
- const [error, setError] = React28.useState(null);
2876
- const [reloadKey, setReloadKey] = React28.useState(0);
2877
- const [dir, setDir] = React28.useState(0);
2878
- const cbRef = React28.useRef({ loadEvents, onError });
2871
+ const [view, setView] = React29.useState(defaultView);
2872
+ const [cursor, setCursor] = React29.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
2873
+ const [loaded, setLoaded] = React29.useState([]);
2874
+ const [loading, setLoading] = React29.useState(false);
2875
+ const [error, setError] = React29.useState(null);
2876
+ const [reloadKey, setReloadKey] = React29.useState(0);
2877
+ const [dir, setDir] = React29.useState(0);
2878
+ const cbRef = React29.useRef({ loadEvents, onError });
2879
2879
  cbRef.current = { loadEvents, onError };
2880
- const range = React28.useMemo(
2880
+ const range = React29.useMemo(
2881
2881
  () => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
2882
2882
  [view, cursor, weekStartsOn]
2883
2883
  );
2884
2884
  const fromKey = range.from.getTime();
2885
2885
  const toKey = range.to.getTime();
2886
- React28.useEffect(() => {
2886
+ React29.useEffect(() => {
2887
2887
  const { loadEvents: loader, onError: onErr } = cbRef.current;
2888
2888
  if (!loader) return;
2889
2889
  let cancelled = false;
@@ -2903,16 +2903,16 @@ function Scheduler({
2903
2903
  cancelled = true;
2904
2904
  };
2905
2905
  }, [fromKey, toKey, view, reloadKey]);
2906
- const retry = React28.useCallback(() => setReloadKey((k) => k + 1), []);
2907
- const events = React28.useMemo(
2906
+ const retry = React29.useCallback(() => setReloadKey((k) => k + 1), []);
2907
+ const events = React29.useMemo(
2908
2908
  () => (controlledEvents ?? loaded).map(normalize),
2909
2909
  [controlledEvents, loaded]
2910
2910
  );
2911
- const go = React28.useCallback((delta) => {
2911
+ const go = React29.useCallback((delta) => {
2912
2912
  setDir(delta);
2913
2913
  setCursor((c) => view === "month" ? addMonths(c, delta) : addDays(c, delta * 7));
2914
2914
  }, [view]);
2915
- const goToday = React28.useCallback(() => {
2915
+ const goToday = React29.useCallback(() => {
2916
2916
  setDir(0);
2917
2917
  setCursor(/* @__PURE__ */ new Date());
2918
2918
  }, []);
@@ -3022,9 +3022,9 @@ function SchedulerError({ onRetry }) {
3022
3022
  ] });
3023
3023
  }
3024
3024
  function MonthYearPicker({ label, cursor, onPick }) {
3025
- const [open, setOpen] = React28.useState(false);
3026
- const [viewYear, setViewYear] = React28.useState(cursor.getFullYear());
3027
- React28.useEffect(() => {
3025
+ const [open, setOpen] = React29.useState(false);
3026
+ const [viewYear, setViewYear] = React29.useState(cursor.getFullYear());
3027
+ React29.useEffect(() => {
3028
3028
  if (open) setViewYear(cursor.getFullYear());
3029
3029
  }, [open, cursor]);
3030
3030
  return /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open, onOpenChange: setOpen, children: [
@@ -3098,8 +3098,8 @@ function MonthView({
3098
3098
  onSelectSlot,
3099
3099
  onSelectEvent
3100
3100
  }) {
3101
- const grid = React28.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
3102
- const eventsByDay = React28.useMemo(() => bucketByDay(events), [events]);
3101
+ const grid = React29.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
3102
+ const eventsByDay = React29.useMemo(() => bucketByDay(events), [events]);
3103
3103
  const labels = weekdayLabels(weekStartsOn);
3104
3104
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
3105
3105
  /* @__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)) }),
@@ -3173,12 +3173,12 @@ function WeekView({
3173
3173
  onSelectSlot,
3174
3174
  onSelectEvent
3175
3175
  }) {
3176
- const days = React28.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
3177
- const eventsByDay = React28.useMemo(() => bucketByDay(events), [events]);
3178
- const labels = React28.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
3176
+ const days = React29.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
3177
+ const eventsByDay = React29.useMemo(() => bucketByDay(events), [events]);
3178
+ const labels = React29.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
3179
3179
  const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
3180
3180
  const [startHour, endHour] = dayHours;
3181
- const hours = React28.useMemo(
3181
+ const hours = React29.useMemo(
3182
3182
  () => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
3183
3183
  [startHour, endHour]
3184
3184
  );
@@ -3369,17 +3369,17 @@ function Cart({
3369
3369
  ] })
3370
3370
  ] });
3371
3371
  }
3372
- var CartContext = React28.createContext(null);
3372
+ var CartContext = React29.createContext(null);
3373
3373
  var clampQty = (qty, max) => {
3374
3374
  const lower = Math.max(1, Math.round(qty));
3375
3375
  return max != null ? Math.min(lower, max) : lower;
3376
3376
  };
3377
3377
  function CartProvider({ children, initialItems = [], onChange }) {
3378
- const [items, setItems] = React28.useState(initialItems);
3379
- React28.useEffect(() => {
3378
+ const [items, setItems] = React29.useState(initialItems);
3379
+ React29.useEffect(() => {
3380
3380
  onChange?.(items);
3381
3381
  }, [items]);
3382
- const addToCart = React28.useCallback((item, quantity) => {
3382
+ const addToCart = React29.useCallback((item, quantity) => {
3383
3383
  const addQty = quantity ?? item.quantity ?? 1;
3384
3384
  setItems((prev) => {
3385
3385
  const existing = prev.find((it) => it.id === item.id);
@@ -3392,29 +3392,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
3392
3392
  return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
3393
3393
  });
3394
3394
  }, []);
3395
- const removeFromCart = React28.useCallback((id) => {
3395
+ const removeFromCart = React29.useCallback((id) => {
3396
3396
  setItems((prev) => prev.filter((it) => it.id !== id));
3397
3397
  }, []);
3398
- const updateQuantity = React28.useCallback((id, quantity) => {
3398
+ const updateQuantity = React29.useCallback((id, quantity) => {
3399
3399
  setItems(
3400
3400
  (prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
3401
3401
  );
3402
3402
  }, []);
3403
- const clearCart = React28.useCallback(() => setItems([]), []);
3404
- const isInCart = React28.useCallback((id) => items.some((it) => it.id === id), [items]);
3405
- const getItemCount = React28.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
3406
- const getCartTotal = React28.useCallback(
3403
+ const clearCart = React29.useCallback(() => setItems([]), []);
3404
+ const isInCart = React29.useCallback((id) => items.some((it) => it.id === id), [items]);
3405
+ const getItemCount = React29.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
3406
+ const getCartTotal = React29.useCallback(
3407
3407
  () => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
3408
3408
  [items]
3409
3409
  );
3410
- const value = React28.useMemo(
3410
+ const value = React29.useMemo(
3411
3411
  () => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
3412
3412
  [items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
3413
3413
  );
3414
3414
  return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
3415
3415
  }
3416
3416
  function useCart() {
3417
- const ctx = React28.useContext(CartContext);
3417
+ const ctx = React29.useContext(CartContext);
3418
3418
  if (!ctx) {
3419
3419
  throw new Error("useCart must be used within a <CartProvider>.");
3420
3420
  }
@@ -3748,11 +3748,11 @@ function buildBindings(store, name, kind, snap) {
3748
3748
 
3749
3749
  // src/form/useForm.ts
3750
3750
  function useForm(options = {}) {
3751
- const ref = React28.useRef(null);
3751
+ const ref = React29.useRef(null);
3752
3752
  if (ref.current === null) ref.current = new FormStore(options);
3753
3753
  const store = ref.current;
3754
- React28.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3755
- const make = React28.useCallback(
3754
+ React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3755
+ const make = React29.useCallback(
3756
3756
  (kind) => (name, rules) => {
3757
3757
  if (rules !== void 0) store.setRule(name, rules);
3758
3758
  return buildBindings(store, name, kind, store.getFieldSnapshot(name));
@@ -3781,9 +3781,9 @@ function useForm(options = {}) {
3781
3781
  fieldTarget: make("target")
3782
3782
  };
3783
3783
  }
3784
- var FormContext = React28.createContext(null);
3784
+ var FormContext = React29.createContext(null);
3785
3785
  function useFormStore() {
3786
- const store = React28.useContext(FormContext);
3786
+ const store = React29.useContext(FormContext);
3787
3787
  if (!store) {
3788
3788
  throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
3789
3789
  }
@@ -3797,8 +3797,8 @@ function Form({
3797
3797
  children,
3798
3798
  ...rest
3799
3799
  }) {
3800
- const ref = React28.useRef(null);
3801
- const bypass = React28.useRef(false);
3800
+ const ref = React29.useRef(null);
3801
+ const bypass = React29.useRef(false);
3802
3802
  const handleSubmit = async (e) => {
3803
3803
  if (bypass.current) {
3804
3804
  bypass.current = false;
@@ -3850,12 +3850,12 @@ function useFormField(name, options = {}) {
3850
3850
  const store = useFormStore();
3851
3851
  const { kind = "value", rules } = options;
3852
3852
  if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
3853
- React28.useEffect(() => {
3853
+ React29.useEffect(() => {
3854
3854
  return () => {
3855
3855
  if (rules !== void 0) store.removeRule(name);
3856
3856
  };
3857
3857
  }, [store, name]);
3858
- const snap = React28.useSyncExternalStore(
3858
+ const snap = React29.useSyncExternalStore(
3859
3859
  store.subscribe,
3860
3860
  () => store.getFieldSnapshot(name)
3861
3861
  );
@@ -3867,7 +3867,7 @@ function FormField({ name, kind, rules, children }) {
3867
3867
  }
3868
3868
  function useFieldArray(name) {
3869
3869
  const store = useFormStore();
3870
- React28.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3870
+ React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3871
3871
  const arr = store.getValue(name) ?? [];
3872
3872
  const keys = store.getKeys(name);
3873
3873
  return {
@@ -3900,7 +3900,7 @@ function TextInput({
3900
3900
  suffix,
3901
3901
  id
3902
3902
  }) {
3903
- const errorId = React28.useId();
3903
+ const errorId = React29.useId();
3904
3904
  const hasError = errorMessage != null;
3905
3905
  const hasAdornment = prefix != null || suffix != null;
3906
3906
  const inputId = htmlFor ?? id;
@@ -4061,7 +4061,7 @@ function CreditCardForm({
4061
4061
  className = "",
4062
4062
  style
4063
4063
  }) {
4064
- const initial = React28.useRef({
4064
+ const initial = React29.useRef({
4065
4065
  number: formatCardNumber(defaultValue?.number ?? ""),
4066
4066
  name: defaultValue?.name ?? "",
4067
4067
  expiry: formatExpiry(defaultValue?.expiry ?? ""),
@@ -4070,7 +4070,7 @@ function CreditCardForm({
4070
4070
  const form = useForm({ initialValues: initial });
4071
4071
  const numberStr = String(form.values.number ?? "");
4072
4072
  const brand = detectBrand(numberStr);
4073
- React28.useEffect(() => {
4073
+ React29.useEffect(() => {
4074
4074
  onChange?.(toCard(form.values));
4075
4075
  }, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
4076
4076
  const numberBind = form.fieldNative("number", {
@@ -4193,7 +4193,7 @@ function Checkout({
4193
4193
  ] })
4194
4194
  ] });
4195
4195
  }
4196
- var NotificationContext = React28.createContext({
4196
+ var NotificationContext = React29.createContext({
4197
4197
  open: () => void 0,
4198
4198
  close: () => void 0
4199
4199
  });
@@ -4251,26 +4251,26 @@ function NotificationItem({
4251
4251
  onClose,
4252
4252
  reduced
4253
4253
  }) {
4254
- const [paused, setPaused] = React28.useState(false);
4254
+ const [paused, setPaused] = React29.useState(false);
4255
4255
  const duration = n.duration ?? 4e3;
4256
4256
  const isAutoDismissing = isFinite(duration) && duration > 0;
4257
4257
  const showProgress = !reduced && isAutoDismissing;
4258
- const timerRef = React28.useRef(null);
4259
- const startTimeRef = React28.useRef(0);
4260
- const remainingRef = React28.useRef(duration);
4261
- const clearTimer = React28.useCallback(() => {
4258
+ const timerRef = React29.useRef(null);
4259
+ const startTimeRef = React29.useRef(0);
4260
+ const remainingRef = React29.useRef(duration);
4261
+ const clearTimer = React29.useCallback(() => {
4262
4262
  if (timerRef.current !== null) {
4263
4263
  clearTimeout(timerRef.current);
4264
4264
  timerRef.current = null;
4265
4265
  }
4266
4266
  }, []);
4267
- const scheduleDismiss = React28.useCallback((ms) => {
4267
+ const scheduleDismiss = React29.useCallback((ms) => {
4268
4268
  clearTimer();
4269
4269
  if (!isAutoDismissing) return;
4270
4270
  startTimeRef.current = Date.now();
4271
4271
  timerRef.current = setTimeout(() => onClose(n.id), ms);
4272
4272
  }, [clearTimer, isAutoDismissing, n.id, onClose]);
4273
- React28.useEffect(() => {
4273
+ React29.useEffect(() => {
4274
4274
  if (paused || !isAutoDismissing) return;
4275
4275
  scheduleDismiss(remainingRef.current);
4276
4276
  return clearTimer;
@@ -4353,15 +4353,15 @@ function NotificationProvider({
4353
4353
  children,
4354
4354
  position = "top-right"
4355
4355
  }) {
4356
- const [notifications, setNotifications] = React28.useState([]);
4356
+ const [notifications, setNotifications] = React29.useState([]);
4357
4357
  const reduced = framerMotion.useReducedMotion();
4358
- const open = React28.useCallback((payload) => {
4358
+ const open = React29.useCallback((payload) => {
4359
4359
  setNotifications((prev) => [
4360
4360
  ...prev,
4361
4361
  { duration: 4e3, ...payload, id: Date.now() + Math.random() }
4362
4362
  ]);
4363
4363
  }, []);
4364
- const close = React28.useCallback((id) => {
4364
+ const close = React29.useCallback((id) => {
4365
4365
  setNotifications((prev) => prev.filter((n) => n.id !== id));
4366
4366
  }, []);
4367
4367
  return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
@@ -4390,7 +4390,7 @@ function NotificationProvider({
4390
4390
  ] });
4391
4391
  }
4392
4392
  function useNotification() {
4393
- const { open } = React28.useContext(NotificationContext);
4393
+ const { open } = React29.useContext(NotificationContext);
4394
4394
  return {
4395
4395
  info: (props) => open({ type: "info", ...props }),
4396
4396
  success: (props) => open({ type: "success", ...props }),
@@ -4507,10 +4507,10 @@ function FadingBase({
4507
4507
  isMounted = false,
4508
4508
  children
4509
4509
  }) {
4510
- const [shouldRender, setShouldRender] = React28.useState(isMounted);
4511
- const [visible, setVisible] = React28.useState(false);
4512
- const timerRef = React28.useRef(null);
4513
- React28.useEffect(() => {
4510
+ const [shouldRender, setShouldRender] = React29.useState(isMounted);
4511
+ const [visible, setVisible] = React29.useState(false);
4512
+ const timerRef = React29.useRef(null);
4513
+ React29.useEffect(() => {
4514
4514
  if (isMounted) {
4515
4515
  setShouldRender(true);
4516
4516
  const rafId = requestAnimationFrame(() => setVisible(true));
@@ -4608,8 +4608,8 @@ function ScalableContainer({
4608
4608
  togglePosition = "top-right",
4609
4609
  className = ""
4610
4610
  }) {
4611
- const containerRef = React28.useRef(null);
4612
- const [internalScaled, setInternalScaled] = React28.useState(false);
4611
+ const containerRef = React29.useRef(null);
4612
+ const [internalScaled, setInternalScaled] = React29.useState(false);
4613
4613
  const isScaled = expanded ?? internalScaled;
4614
4614
  const reduced = framerMotion.useReducedMotion();
4615
4615
  const onToggle = () => {
@@ -4747,17 +4747,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
4747
4747
  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)) });
4748
4748
  }
4749
4749
  function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
4750
- const [activeIndex, setActiveIndex] = React28.useState(0);
4751
- const [indexPool, setIndexPool] = React28.useState([]);
4752
- const cardRefs = React28.useRef([]);
4753
- const getIndexes = React28.useMemo(() => {
4750
+ const [activeIndex, setActiveIndex] = React29.useState(0);
4751
+ const [indexPool, setIndexPool] = React29.useState([]);
4752
+ const cardRefs = React29.useRef([]);
4753
+ const getIndexes = React29.useMemo(() => {
4754
4754
  let nextIndex = activeIndex + 1;
4755
4755
  let previousIndex = activeIndex - 1;
4756
4756
  if (activeIndex === 0) previousIndex = items.length - 1;
4757
4757
  if (activeIndex === items.length - 1) nextIndex = 0;
4758
4758
  return { previousIndex, nextIndex };
4759
4759
  }, [activeIndex, items.length]);
4760
- React28.useEffect(() => {
4760
+ React29.useEffect(() => {
4761
4761
  const { nextIndex, previousIndex } = getIndexes;
4762
4762
  let indexes = [previousIndex, activeIndex, nextIndex];
4763
4763
  if (activeIndex !== 0 && activeIndex !== items.length - 1) {
@@ -4930,8 +4930,8 @@ function writeDismissed(key) {
4930
4930
  }
4931
4931
  }
4932
4932
  function useTargetBbox(ref) {
4933
- const [bbox, setBbox] = React28.useState(null);
4934
- React28.useLayoutEffect(() => {
4933
+ const [bbox, setBbox] = React29.useState(null);
4934
+ React29.useLayoutEffect(() => {
4935
4935
  const el = ref?.current;
4936
4936
  if (!el) {
4937
4937
  setBbox(null);
@@ -4961,7 +4961,7 @@ function tooltipStyleFor(bbox, placement) {
4961
4961
  return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
4962
4962
  }
4963
4963
  function useFocusTrap(containerRef, active) {
4964
- React28.useEffect(() => {
4964
+ React29.useEffect(() => {
4965
4965
  if (!active) return;
4966
4966
  const el = containerRef.current;
4967
4967
  if (!el) return;
@@ -5000,16 +5000,16 @@ function Wizard({
5000
5000
  onComplete,
5001
5001
  onSkip
5002
5002
  }) {
5003
- const tooltipRef = React28.useRef(null);
5004
- const tooltipTitleId = React28.useId();
5005
- const tooltipBodyId = React28.useId();
5003
+ const tooltipRef = React29.useRef(null);
5004
+ const tooltipTitleId = React29.useId();
5005
+ const tooltipBodyId = React29.useId();
5006
5006
  const reduced = framerMotion.useReducedMotion();
5007
- const [open, setOpen] = React28.useState(() => steps.length > 0 && !readDismissed(storageKey));
5008
- const [activeIndex, setActiveIndex] = React28.useState(0);
5007
+ const [open, setOpen] = React29.useState(() => steps.length > 0 && !readDismissed(storageKey));
5008
+ const [activeIndex, setActiveIndex] = React29.useState(0);
5009
5009
  const step = steps[activeIndex];
5010
5010
  const bbox = useTargetBbox(step?.stepRef);
5011
5011
  useFocusTrap(tooltipRef, open);
5012
- React28.useEffect(() => {
5012
+ React29.useEffect(() => {
5013
5013
  if (!open || !dismissible) return;
5014
5014
  const onKey = (e) => {
5015
5015
  if (e.key === "Escape") {
@@ -5020,12 +5020,12 @@ function Wizard({
5020
5020
  document.addEventListener("keydown", onKey);
5021
5021
  return () => document.removeEventListener("keydown", onKey);
5022
5022
  }, [open, dismissible]);
5023
- const handleSkip = React28.useCallback(() => {
5023
+ const handleSkip = React29.useCallback(() => {
5024
5024
  writeDismissed(storageKey);
5025
5025
  setOpen(false);
5026
5026
  onSkip?.();
5027
5027
  }, [storageKey, onSkip]);
5028
- const handleComplete = React28.useCallback(() => {
5028
+ const handleComplete = React29.useCallback(() => {
5029
5029
  writeDismissed(storageKey);
5030
5030
  setOpen(false);
5031
5031
  onComplete?.();
@@ -5168,7 +5168,7 @@ function Wizard({
5168
5168
  ] });
5169
5169
  }
5170
5170
  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" }) });
5171
- var SearchInput = React28__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
5171
+ var SearchInput = React29__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
5172
5172
  return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
5173
5173
  "div",
5174
5174
  {
@@ -5403,7 +5403,7 @@ function EditableCell({
5403
5403
  rowIndex,
5404
5404
  onCellEdit
5405
5405
  }) {
5406
- const [editing, setEditing] = React28.useState(false);
5406
+ const [editing, setEditing] = React29.useState(false);
5407
5407
  const value = row[col.keyBind];
5408
5408
  const commit = (next) => {
5409
5409
  setEditing(false);
@@ -5450,7 +5450,7 @@ function TableBody({
5450
5450
  getRowKey,
5451
5451
  onCellEdit
5452
5452
  }) {
5453
- const [expanded, setExpanded] = React28.useState(() => /* @__PURE__ */ new Set());
5453
+ const [expanded, setExpanded] = React29.useState(() => /* @__PURE__ */ new Set());
5454
5454
  const reduced = framerMotion.useReducedMotion();
5455
5455
  const toggleRow = (rowKey) => {
5456
5456
  setExpanded((prev) => {
@@ -5465,7 +5465,7 @@ function TableBody({
5465
5465
  return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
5466
5466
  const rowKey = getRowKey(row, i);
5467
5467
  const isExpanded = expanded.has(rowKey);
5468
- return /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
5468
+ return /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
5469
5469
  /* @__PURE__ */ jsxRuntime.jsxs(
5470
5470
  "tr",
5471
5471
  {
@@ -5521,9 +5521,9 @@ function Pagination({
5521
5521
  const matchedOption = picker.find(
5522
5522
  (o) => o.label === options.perPage || o.value === options.perPage
5523
5523
  );
5524
- const [perPageKey, setPerPageKey] = React28.useState(() => matchedOption?.key ?? picker[0]?.key);
5524
+ const [perPageKey, setPerPageKey] = React29.useState(() => matchedOption?.key ?? picker[0]?.key);
5525
5525
  const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
5526
- React28.useEffect(() => {
5526
+ React29.useEffect(() => {
5527
5527
  if (serverSide && options.perPage != null) {
5528
5528
  const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
5529
5529
  if (next) setPerPageKey(next.key);
@@ -5591,13 +5591,13 @@ function Table({
5591
5591
  className = "",
5592
5592
  style
5593
5593
  }) {
5594
- const searchRef = React28.useRef(null);
5595
- const [searchTerm, setSearchTerm] = React28.useState("");
5596
- const [perPage, setPerPage] = React28.useState(
5594
+ const searchRef = React29.useRef(null);
5595
+ const [searchTerm, setSearchTerm] = React29.useState("");
5596
+ const [perPage, setPerPage] = React29.useState(
5597
5597
  typeof pagination.perPage === "number" ? pagination.perPage : 15
5598
5598
  );
5599
- const [activePage, setActivePage] = React28.useState(0);
5600
- const [sortState, setSortState] = React28.useState(defaultSort);
5599
+ const [activePage, setActivePage] = React29.useState(0);
5600
+ const [sortState, setSortState] = React29.useState(defaultSort);
5601
5601
  const isServerSide = !!(pagination.enabled && pagination.serverSide);
5602
5602
  const handleSort = (col) => {
5603
5603
  const key = col.keyBind;
@@ -5609,8 +5609,8 @@ function Table({
5609
5609
  onSortChange?.(next);
5610
5610
  };
5611
5611
  const debounceMs = search?.debounceMs ?? 0;
5612
- const [debouncedTerm, setDebouncedTerm] = React28.useState("");
5613
- React28.useEffect(() => {
5612
+ const [debouncedTerm, setDebouncedTerm] = React29.useState("");
5613
+ React29.useEffect(() => {
5614
5614
  if (debounceMs <= 0) {
5615
5615
  setDebouncedTerm(searchTerm);
5616
5616
  return;
@@ -5619,7 +5619,7 @@ function Table({
5619
5619
  return () => clearTimeout(t);
5620
5620
  }, [searchTerm, debounceMs]);
5621
5621
  const term = debounceMs > 0 ? debouncedTerm : searchTerm;
5622
- const filteredRows = React28.useMemo(() => {
5622
+ const filteredRows = React29.useMemo(() => {
5623
5623
  if (isServerSide || !term) return rows;
5624
5624
  if (search?.predicate) return rows.filter((row) => search.predicate(row, term));
5625
5625
  const cs = !!search?.caseSensitive;
@@ -5633,7 +5633,7 @@ function Table({
5633
5633
  };
5634
5634
  return rows.filter((row) => keys ? keys.some((k) => test(row[k])) : Object.values(row).some(test));
5635
5635
  }, [rows, term, isServerSide, search?.predicate, search?.caseSensitive, search?.matchMode, search?.keys]);
5636
- const sortedRows = React28.useMemo(() => {
5636
+ const sortedRows = React29.useMemo(() => {
5637
5637
  if (isServerSide || !sortState) return filteredRows;
5638
5638
  const col = columns.find((c) => c.keyBind === sortState.key);
5639
5639
  const accessor = col?.sortAccessor ?? ((r) => r[sortState.key]);
@@ -5641,29 +5641,29 @@ function Table({
5641
5641
  if (sortState.direction === "desc") out.reverse();
5642
5642
  return out;
5643
5643
  }, [filteredRows, sortState, isServerSide, columns]);
5644
- const datasets = React28.useMemo(() => {
5644
+ const datasets = React29.useMemo(() => {
5645
5645
  if (isServerSide) return [rows];
5646
5646
  return createDatasets(sortedRows, pagination.enabled ? perPage : null);
5647
5647
  }, [sortedRows, perPage, pagination.enabled, isServerSide, rows]);
5648
- const MAX_PAGE = React28.useMemo(() => {
5648
+ const MAX_PAGE = React29.useMemo(() => {
5649
5649
  if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
5650
5650
  if (isServerSide && typeof pagination.totalCount === "number")
5651
5651
  return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
5652
5652
  return datasets.length ? datasets.length - 1 : 0;
5653
5653
  }, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
5654
- const currentPageRows = React28.useMemo(() => {
5654
+ const currentPageRows = React29.useMemo(() => {
5655
5655
  if (isServerSide) return rows;
5656
5656
  return datasets[activePage] ?? [];
5657
5657
  }, [isServerSide, rows, datasets, activePage]);
5658
- React28.useEffect(() => {
5658
+ React29.useEffect(() => {
5659
5659
  if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
5660
5660
  setPerPage(pagination.perPage);
5661
5661
  }
5662
5662
  }, [pagination.enabled, pagination.perPage, isServerSide]);
5663
- React28.useEffect(() => {
5663
+ React29.useEffect(() => {
5664
5664
  if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
5665
5665
  }, [isServerSide, pagination.perPage]);
5666
- React28.useEffect(() => {
5666
+ React29.useEffect(() => {
5667
5667
  if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
5668
5668
  setActivePage(pagination.page - 1);
5669
5669
  }, [isServerSide, pagination.page]);
@@ -5752,8 +5752,86 @@ function TableSkeletonBody({
5752
5752
  i
5753
5753
  )) });
5754
5754
  }
5755
+ var useIsoLayoutEffect = typeof window !== "undefined" ? React29.useLayoutEffect : React29.useEffect;
5756
+ function VirtualList({
5757
+ items,
5758
+ rowHeight,
5759
+ renderItem: renderItem2,
5760
+ height = 400,
5761
+ getKey,
5762
+ overscan = 6,
5763
+ searchable = false,
5764
+ searchKeys,
5765
+ filter,
5766
+ searchPlaceholder = "Search\u2026",
5767
+ emptyState = "No results",
5768
+ "aria-label": ariaLabel = "List",
5769
+ className = "",
5770
+ style
5771
+ }) {
5772
+ const scrollRef = React29.useRef(null);
5773
+ const [scrollTop, setScrollTop] = React29.useState(0);
5774
+ const [viewport, setViewport] = React29.useState(typeof height === "number" ? height : 400);
5775
+ const [term, setTerm] = React29.useState("");
5776
+ useIsoLayoutEffect(() => {
5777
+ const el = scrollRef.current;
5778
+ if (!el) return;
5779
+ const measure = () => setViewport(el.clientHeight);
5780
+ measure();
5781
+ if (typeof ResizeObserver === "undefined") return;
5782
+ const ro = new ResizeObserver(measure);
5783
+ ro.observe(el);
5784
+ return () => ro.disconnect();
5785
+ }, []);
5786
+ const filtered = React29.useMemo(() => {
5787
+ if (!searchable || !term) return items;
5788
+ if (filter) return items.filter((it) => filter(it, term));
5789
+ const needle = term.toLowerCase();
5790
+ return items.filter((it) => {
5791
+ if (searchKeys) return searchKeys.some((k) => String(it[k] ?? "").toLowerCase().includes(needle));
5792
+ return String(it).toLowerCase().includes(needle);
5793
+ });
5794
+ }, [items, searchable, term, filter, searchKeys]);
5795
+ const total = filtered.length * rowHeight;
5796
+ const startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
5797
+ const endIndex = Math.min(filtered.length, Math.ceil((scrollTop + viewport) / rowHeight) + overscan);
5798
+ const offsetY = startIndex * rowHeight;
5799
+ const visible = filtered.slice(startIndex, endIndex);
5800
+ const onSearch = (e) => {
5801
+ setTerm(e.target.value);
5802
+ setScrollTop(0);
5803
+ if (scrollRef.current) scrollRef.current.scrollTop = 0;
5804
+ };
5805
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex w-full flex-col gap-2", className), style, children: [
5806
+ searchable && /* @__PURE__ */ jsxRuntime.jsx(SearchInput_default, { value: term, onChange: onSearch, placeholder: searchPlaceholder }),
5807
+ /* @__PURE__ */ jsxRuntime.jsx(
5808
+ "div",
5809
+ {
5810
+ ref: scrollRef,
5811
+ onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
5812
+ role: "list",
5813
+ "aria-label": ariaLabel,
5814
+ className: "relative overflow-y-auto rounded-lg border border-border bg-surface",
5815
+ style: { height },
5816
+ children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center justify-center p-6 text-sm text-foreground-muted", children: emptyState }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: total, position: "relative" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { transform: `translateY(${offsetY}px)` }, children: visible.map((item, i) => {
5817
+ const index = startIndex + i;
5818
+ return /* @__PURE__ */ jsxRuntime.jsx(
5819
+ "div",
5820
+ {
5821
+ role: "listitem",
5822
+ style: { height: rowHeight },
5823
+ className: "box-border",
5824
+ children: renderItem2(item, index)
5825
+ },
5826
+ getKey ? getKey(item, index) : index
5827
+ );
5828
+ }) }) })
5829
+ }
5830
+ )
5831
+ ] });
5832
+ }
5755
5833
  function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
5756
- const id = React28.useId();
5834
+ const id = React29.useId();
5757
5835
  return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
5758
5836
  SwitchPrimitive__namespace.Root,
5759
5837
  {
@@ -5937,7 +6015,7 @@ function Sidebar({
5937
6015
  }
5938
6016
  ) });
5939
6017
  }
5940
- var MegaMenuContext = React28.createContext({ align: "start" });
6018
+ var MegaMenuContext = React29.createContext({ align: "start" });
5941
6019
  function MegaMenu({
5942
6020
  children,
5943
6021
  align = "start",
@@ -5968,7 +6046,7 @@ function MegaMenu({
5968
6046
  }
5969
6047
  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";
5970
6048
  function MegaMenuItem({ label, icon, href, children, className = "" }) {
5971
- const { align } = React28.useContext(MegaMenuContext);
6049
+ const { align } = React29.useContext(MegaMenuContext);
5972
6050
  const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
5973
6051
  if (!children) {
5974
6052
  return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: cx(TOP_ITEM, className), children: [
@@ -6053,8 +6131,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
6053
6131
  function MegaMenuFeatured({ children, className = "" }) {
6054
6132
  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 });
6055
6133
  }
6056
- var elementsOfType = (children, type) => React28__default.default.Children.toArray(children).filter(
6057
- (c) => React28__default.default.isValidElement(c) && c.type === type
6134
+ var elementsOfType = (children, type) => React29__default.default.Children.toArray(children).filter(
6135
+ (c) => React29__default.default.isValidElement(c) && c.type === type
6058
6136
  );
6059
6137
  var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
6060
6138
  "svg",
@@ -6091,9 +6169,9 @@ function MobileLinkRow({ link, onNavigate }) {
6091
6169
  );
6092
6170
  }
6093
6171
  function MobilePanel({ panel, onNavigate }) {
6094
- const nodes = React28__default.default.Children.toArray(panel.props.children);
6172
+ const nodes = React29__default.default.Children.toArray(panel.props.children);
6095
6173
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
6096
- if (!React28__default.default.isValidElement(node)) return null;
6174
+ if (!React29__default.default.isValidElement(node)) return null;
6097
6175
  const el = node;
6098
6176
  if (el.type === MegaMenuSection) {
6099
6177
  const { title, children } = el.props;
@@ -6112,8 +6190,8 @@ function MegaMenuMobile({
6112
6190
  children,
6113
6191
  label
6114
6192
  }) {
6115
- const [open, setOpen] = React28.useState(false);
6116
- const [expanded, setExpanded] = React28.useState(null);
6193
+ const [open, setOpen] = React29.useState(false);
6194
+ const [expanded, setExpanded] = React29.useState(null);
6117
6195
  const items = elementsOfType(children, MegaMenuItem);
6118
6196
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
6119
6197
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6186,17 +6264,17 @@ function AppShell({
6186
6264
  children,
6187
6265
  className = ""
6188
6266
  }) {
6189
- const [expanded, setExpanded] = React28.useState(sidebarDefaultExpanded);
6190
- const [isMobile, setIsMobile] = React28.useState(false);
6191
- const [mobileOpen, setMobileOpen] = React28.useState(false);
6192
- React28.useEffect(() => {
6267
+ const [expanded, setExpanded] = React29.useState(sidebarDefaultExpanded);
6268
+ const [isMobile, setIsMobile] = React29.useState(false);
6269
+ const [mobileOpen, setMobileOpen] = React29.useState(false);
6270
+ React29.useEffect(() => {
6193
6271
  const mq = window.matchMedia("(max-width: 767px)");
6194
6272
  const update = (e) => setIsMobile(e.matches);
6195
6273
  update(mq);
6196
6274
  mq.addEventListener("change", update);
6197
6275
  return () => mq.removeEventListener("change", update);
6198
6276
  }, []);
6199
- React28.useEffect(() => {
6277
+ React29.useEffect(() => {
6200
6278
  if (!isMobile) setMobileOpen(false);
6201
6279
  }, [isMobile]);
6202
6280
  const hasSidebar = sidebarSections.length > 0;
@@ -6323,7 +6401,7 @@ function SecureLayout({
6323
6401
  className = ""
6324
6402
  }) {
6325
6403
  const reduced = framerMotion.useReducedMotion();
6326
- const cbs = React28.useRef({ canAccess, onGranted, onDeny });
6404
+ const cbs = React29.useRef({ canAccess, onGranted, onDeny });
6327
6405
  cbs.current = { canAccess, onGranted, onDeny };
6328
6406
  const rolesKey = JSON.stringify(roles);
6329
6407
  const requiredRolesKey = JSON.stringify(requiredRoles);
@@ -6338,10 +6416,10 @@ function SecureLayout({
6338
6416
  if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
6339
6417
  return true;
6340
6418
  };
6341
- const [state, setState] = React28.useState(
6419
+ const [state, setState] = React29.useState(
6342
6420
  () => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
6343
6421
  );
6344
- React28.useEffect(() => {
6422
+ React29.useEffect(() => {
6345
6423
  let cancelled = false;
6346
6424
  const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
6347
6425
  const finish = (ok) => {
@@ -6502,10 +6580,10 @@ function ThemeProvider({
6502
6580
  className = "",
6503
6581
  style
6504
6582
  }) {
6505
- const id = React28__default.default.useId().replace(/:/g, "");
6583
+ const id = React29__default.default.useId().replace(/:/g, "");
6506
6584
  const scopeClass = `geo-th-${id}`;
6507
- const divRef = React28.useRef(null);
6508
- React28.useEffect(() => {
6585
+ const divRef = React29.useRef(null);
6586
+ React29.useEffect(() => {
6509
6587
  const el = divRef.current;
6510
6588
  if (!el) return;
6511
6589
  if (colorScheme === "auto") return;
@@ -6520,8 +6598,8 @@ function ThemeProvider({
6520
6598
  }
6521
6599
  el.classList.toggle("dark", colorScheme === "dark");
6522
6600
  }, [colorScheme]);
6523
- const lightVars = React28.useMemo(() => toCssVars(theme), [theme]);
6524
- const darkVarStr = React28.useMemo(() => {
6601
+ const lightVars = React29.useMemo(() => toCssVars(theme), [theme]);
6602
+ const darkVarStr = React29.useMemo(() => {
6525
6603
  if (!darkTheme) return "";
6526
6604
  const dvars = toCssVars(darkTheme);
6527
6605
  if (!Object.keys(dvars).length) return "";
@@ -6563,7 +6641,7 @@ function NumberInput({
6563
6641
  readOnly = false,
6564
6642
  precision
6565
6643
  }) {
6566
- const errorId = React28.useId();
6644
+ const errorId = React29.useId();
6567
6645
  const hasError = errorMessage != null;
6568
6646
  const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
6569
6647
  const round = (n) => {
@@ -6694,8 +6772,8 @@ function Password({
6694
6772
  showIcon,
6695
6773
  hideIcon
6696
6774
  }) {
6697
- const [visible, setVisible] = React28.useState(false);
6698
- const errorId = React28.useId();
6775
+ const [visible, setVisible] = React29.useState(false);
6776
+ const errorId = React29.useId();
6699
6777
  const hasError = errorMessage != null;
6700
6778
  return /* @__PURE__ */ jsxRuntime.jsx(
6701
6779
  Field,
@@ -6749,6 +6827,161 @@ function Password({
6749
6827
  }
6750
6828
  );
6751
6829
  }
6830
+ var defaultPasswordRules = [
6831
+ { label: "At least 8 characters", test: (p) => p.length >= 8 },
6832
+ { label: "A lowercase letter", test: (p) => /[a-z]/.test(p) },
6833
+ { label: "An uppercase letter", test: (p) => /[A-Z]/.test(p) },
6834
+ { label: "A number", test: (p) => /\d/.test(p) },
6835
+ { label: "A symbol", test: (p) => /[^A-Za-z0-9]/.test(p) }
6836
+ ];
6837
+ var LABELS = ["", "Weak", "Fair", "Good", "Strong"];
6838
+ function scorePassword(password) {
6839
+ if (!password) return { score: 0, label: "" };
6840
+ let s = 0;
6841
+ if (password.length >= 8) s++;
6842
+ if (/[a-z]/.test(password) && /[A-Z]/.test(password)) s++;
6843
+ if (/\d/.test(password)) s++;
6844
+ if (/[^A-Za-z0-9]/.test(password)) s++;
6845
+ if (password.length >= 12) s++;
6846
+ const lowEntropy = /^(.)\1+$/.test(password) || /^(?:0123456789|abcdefghijklmnopqrstuvwxyz|qwertyuiop)/i.test(password);
6847
+ if (lowEntropy) s = Math.min(s, 1);
6848
+ const score = Math.max(1, Math.min(4, s));
6849
+ return { score, label: LABELS[score] };
6850
+ }
6851
+ var BAR_COLOR = {
6852
+ 0: "bg-border",
6853
+ 1: "bg-status-error",
6854
+ 2: "bg-status-warning",
6855
+ 3: "bg-accent",
6856
+ 4: "bg-status-success"
6857
+ };
6858
+ var TEXT_COLOR = {
6859
+ 0: "text-foreground-muted",
6860
+ 1: "text-status-error",
6861
+ 2: "text-status-warning",
6862
+ 3: "text-accent",
6863
+ 4: "text-status-success"
6864
+ };
6865
+ var Tick = ({ ok }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 20 20", "aria-hidden": "true", className: cx("h-3.5 w-3.5 shrink-0", ok ? "text-status-success" : "text-foreground-muted"), children: ok ? /* @__PURE__ */ jsxRuntime.jsx("path", { fill: "currentColor", fillRule: "evenodd", clipRule: "evenodd", d: "M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm3.7 6.3a1 1 0 0 0-1.4-1.4L9 10.18 7.7 8.88a1 1 0 0 0-1.4 1.42l2 2a1 1 0 0 0 1.4 0l4-4Z" }) : /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "10", cy: "10", r: "2.5", fill: "currentColor" }) });
6866
+ function PasswordStrength({
6867
+ value,
6868
+ scorer = scorePassword,
6869
+ showRequirements = false,
6870
+ rules = defaultPasswordRules,
6871
+ confirmValue,
6872
+ hideMeter = false,
6873
+ className = "",
6874
+ style
6875
+ }) {
6876
+ const { score, label } = React29.useMemo(() => scorer(value), [scorer, value]);
6877
+ const showMatch = confirmValue != null && (value.length > 0 || confirmValue.length > 0);
6878
+ const matches = value.length > 0 && value === confirmValue;
6879
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("flex flex-col gap-2", className), style, "aria-live": "polite", children: [
6880
+ !hideMeter && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6881
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", role: "meter", "aria-valuemin": 0, "aria-valuemax": 4, "aria-valuenow": score, "aria-label": "Password strength", children: [1, 2, 3, 4].map((seg) => /* @__PURE__ */ jsxRuntime.jsx(
6882
+ "span",
6883
+ {
6884
+ className: cx("h-1.5 flex-1 rounded-full transition-colors duration-200", seg <= score ? BAR_COLOR[score] : "bg-border")
6885
+ },
6886
+ seg
6887
+ )) }),
6888
+ label && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs", children: [
6889
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted", children: "Strength: " }),
6890
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("font-medium", TEXT_COLOR[score]), children: label })
6891
+ ] })
6892
+ ] }),
6893
+ showRequirements && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-0.5 flex flex-col gap-1", children: rules.map((rule, i) => {
6894
+ const ok = rule.test(value);
6895
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: cx("flex items-center gap-1.5 text-xs", ok ? "text-foreground-secondary" : "text-foreground-muted"), children: [
6896
+ /* @__PURE__ */ jsxRuntime.jsx(Tick, { ok }),
6897
+ rule.label
6898
+ ] }, i);
6899
+ }) }),
6900
+ showMatch && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: cx("flex items-center gap-1.5 text-xs font-medium", matches ? "text-status-success" : "text-status-error"), children: [
6901
+ /* @__PURE__ */ jsxRuntime.jsx(Tick, { ok: matches }),
6902
+ matches ? "Passwords match" : "Passwords don\u2019t match"
6903
+ ] })
6904
+ ] });
6905
+ }
6906
+ var COLS = {
6907
+ 1: "grid-cols-1",
6908
+ 2: "grid-cols-1 sm:grid-cols-2",
6909
+ 3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"
6910
+ };
6911
+ var PAD2 = { sm: "p-3", md: "p-4", lg: "p-5" };
6912
+ var TITLE = { sm: "text-sm", md: "text-sm", lg: "text-base" };
6913
+ var CheckMark = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-5 w-5 text-accent", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M12 2.25a9.75 9.75 0 1 0 0 19.5 9.75 9.75 0 0 0 0-19.5Zm4.28 7.53a.75.75 0 0 0-1.06-1.06l-4.97 4.97-1.97-1.97a.75.75 0 1 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l5.5-5.5Z" }) });
6914
+ function RadioTile({
6915
+ options,
6916
+ value,
6917
+ defaultValue,
6918
+ onChange,
6919
+ name,
6920
+ label,
6921
+ columns = 2,
6922
+ size = "md",
6923
+ disabled,
6924
+ required,
6925
+ helperText,
6926
+ errorMessage,
6927
+ className
6928
+ }) {
6929
+ const groupId = React29.useId();
6930
+ const errorId = React29.useId();
6931
+ const hasError = errorMessage != null;
6932
+ return /* @__PURE__ */ jsxRuntime.jsx(
6933
+ Field,
6934
+ {
6935
+ className,
6936
+ label,
6937
+ htmlFor: groupId,
6938
+ errorId,
6939
+ errorMessage,
6940
+ required,
6941
+ helperText,
6942
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6943
+ RadioGroupPrimitive__namespace.Root,
6944
+ {
6945
+ id: groupId,
6946
+ name,
6947
+ value,
6948
+ defaultValue,
6949
+ onValueChange: onChange,
6950
+ disabled,
6951
+ required,
6952
+ "aria-invalid": hasError || void 0,
6953
+ "aria-describedby": hasError ? errorId : void 0,
6954
+ className: cx("grid gap-3", COLS[columns]),
6955
+ children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
6956
+ RadioGroupPrimitive__namespace.Item,
6957
+ {
6958
+ value: opt.value,
6959
+ disabled: opt.disabled,
6960
+ className: cx(
6961
+ "group relative flex flex-col gap-1 rounded-xl border bg-surface text-left transition-all duration-150",
6962
+ PAD2[size],
6963
+ "border-border hover:border-border-strong",
6964
+ "data-[state=checked]:border-accent data-[state=checked]:ring-1 data-[state=checked]:ring-accent",
6965
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
6966
+ "disabled:cursor-not-allowed disabled:opacity-50"
6967
+ ),
6968
+ children: [
6969
+ /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "absolute right-3 top-3", children: CheckMark }),
6970
+ opt.icon != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 text-accent [&>svg]:h-6 [&>svg]:w-6", children: opt.icon }),
6971
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2 pr-6", children: [
6972
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("font-semibold text-foreground", TITLE[size]), children: opt.label }),
6973
+ opt.badge != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-border bg-surface-raised px-2 py-0.5 text-[11px] font-medium text-foreground-secondary", children: opt.badge })
6974
+ ] }),
6975
+ opt.description != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs leading-relaxed text-foreground-secondary", children: opt.description })
6976
+ ]
6977
+ },
6978
+ opt.value
6979
+ ))
6980
+ }
6981
+ )
6982
+ }
6983
+ );
6984
+ }
6752
6985
  function Checkbox({
6753
6986
  checked,
6754
6987
  value,
@@ -6768,7 +7001,7 @@ function Checkbox({
6768
7001
  }) {
6769
7002
  const isChecked = checked ?? value ?? false;
6770
7003
  const labelFirst = labelPosition === "left";
6771
- const errorId = React28.useId();
7004
+ const errorId = React29.useId();
6772
7005
  const hasError = errorMessage != null;
6773
7006
  const box = /* @__PURE__ */ jsxRuntime.jsx(
6774
7007
  CheckboxPrimitive__namespace.Root,
@@ -6876,8 +7109,8 @@ function RadioGroup({
6876
7109
  className,
6877
7110
  errorMessage
6878
7111
  }) {
6879
- const errorId = React28.useId();
6880
- const groupId = React28.useId();
7112
+ const errorId = React29.useId();
7113
+ const groupId = React29.useId();
6881
7114
  const hasError = errorMessage != null;
6882
7115
  const labelFirst = labelPosition === "left";
6883
7116
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -6977,11 +7210,11 @@ function Switch({
6977
7210
  disabled,
6978
7211
  errorMessage
6979
7212
  }) {
6980
- const id = React28.useId();
6981
- const errorId = React28.useId();
7213
+ const id = React29.useId();
7214
+ const errorId = React29.useId();
6982
7215
  const hasError = errorMessage != null;
6983
7216
  const isControlled = checked !== void 0;
6984
- const [internal, setInternal] = React28.useState(defaultChecked);
7217
+ const [internal, setInternal] = React29.useState(defaultChecked);
6985
7218
  const isOn = isControlled ? checked : internal;
6986
7219
  const handle = (c) => {
6987
7220
  if (!isControlled) setInternal(c);
@@ -7057,11 +7290,11 @@ function MultiTagRow({
7057
7290
  labelFor,
7058
7291
  onRemove
7059
7292
  }) {
7060
- const wrapRef = React28.useRef(null);
7061
- const measureRef = React28.useRef(null);
7062
- const [visibleCount, setVisibleCount] = React28.useState(values.length);
7293
+ const wrapRef = React29.useRef(null);
7294
+ const measureRef = React29.useRef(null);
7295
+ const [visibleCount, setVisibleCount] = React29.useState(values.length);
7063
7296
  const key = values.map(String).join("|");
7064
- React28.useLayoutEffect(() => {
7297
+ React29.useLayoutEffect(() => {
7065
7298
  const wrap = wrapRef.current;
7066
7299
  const measure = measureRef.current;
7067
7300
  if (!wrap || !measure) return;
@@ -7155,16 +7388,16 @@ function Dropdown({
7155
7388
  size = "md",
7156
7389
  className = ""
7157
7390
  }) {
7158
- const [open, setOpen] = React28.useState(false);
7159
- const [selectedItems, setSelectedItems] = React28.useState([]);
7160
- const [searchTerm, setSearchTerm] = React28.useState("");
7161
- const [innerItems, setInnerItems] = React28.useState([]);
7162
- const errorId = React28.useId();
7391
+ const [open, setOpen] = React29.useState(false);
7392
+ const [selectedItems, setSelectedItems] = React29.useState([]);
7393
+ const [searchTerm, setSearchTerm] = React29.useState("");
7394
+ const [innerItems, setInnerItems] = React29.useState([]);
7395
+ const errorId = React29.useId();
7163
7396
  const hasError = errorMessage != null;
7164
- React28.useEffect(() => {
7397
+ React29.useEffect(() => {
7165
7398
  setInnerItems(items);
7166
7399
  }, [items]);
7167
- React28.useEffect(() => {
7400
+ React29.useEffect(() => {
7168
7401
  if (isMultiselect && Array.isArray(value)) {
7169
7402
  setSelectedItems(value);
7170
7403
  }
@@ -7356,19 +7589,19 @@ function AutoComplete({
7356
7589
  required,
7357
7590
  htmlFor
7358
7591
  }) {
7359
- const errorId = React28.useId();
7592
+ const errorId = React29.useId();
7360
7593
  const hasError = errorMessage != null;
7361
- const [term, setTerm] = React28.useState("");
7362
- const [open, setOpen] = React28.useState(false);
7363
- const [asyncItems, setAsyncItems] = React28.useState([]);
7364
- const [loading, setLoading] = React28.useState(false);
7594
+ const [term, setTerm] = React29.useState("");
7595
+ const [open, setOpen] = React29.useState(false);
7596
+ const [asyncItems, setAsyncItems] = React29.useState([]);
7597
+ const [loading, setLoading] = React29.useState(false);
7365
7598
  const isAsync = typeof onSearch === "function";
7366
- const debounceRef = React28.useRef(null);
7367
- const requestIdRef = React28.useRef(0);
7599
+ const debounceRef = React29.useRef(null);
7600
+ const requestIdRef = React29.useRef(0);
7368
7601
  const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
7369
7602
  ({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
7370
7603
  ) : [];
7371
- React28.useEffect(() => {
7604
+ React29.useEffect(() => {
7372
7605
  if (!isAsync) return;
7373
7606
  if (debounceRef.current) clearTimeout(debounceRef.current);
7374
7607
  if (!term.trim()) {
@@ -7524,15 +7757,15 @@ function TreeSelect({
7524
7757
  defaultExpandedKeys = [],
7525
7758
  size = "md"
7526
7759
  }) {
7527
- const errorId = React28.useId();
7760
+ const errorId = React29.useId();
7528
7761
  const hasError = errorMessage != null;
7529
- const [open, setOpen] = React28.useState(false);
7530
- const [expanded, setExpanded] = React28.useState(() => new Set(defaultExpandedKeys));
7531
- const [activeIndex, setActiveIndex] = React28.useState(0);
7532
- const listRef = React28.useRef(null);
7533
- const visible = React28.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
7534
- const didSyncOnOpenRef = React28.useRef(false);
7535
- React28.useEffect(() => {
7762
+ const [open, setOpen] = React29.useState(false);
7763
+ const [expanded, setExpanded] = React29.useState(() => new Set(defaultExpandedKeys));
7764
+ const [activeIndex, setActiveIndex] = React29.useState(0);
7765
+ const listRef = React29.useRef(null);
7766
+ const visible = React29.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
7767
+ const didSyncOnOpenRef = React29.useRef(false);
7768
+ React29.useEffect(() => {
7536
7769
  if (!open) {
7537
7770
  didSyncOnOpenRef.current = false;
7538
7771
  return;
@@ -7542,7 +7775,7 @@ function TreeSelect({
7542
7775
  setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
7543
7776
  didSyncOnOpenRef.current = true;
7544
7777
  }, [open, value]);
7545
- const selectedNode = React28.useMemo(
7778
+ const selectedNode = React29.useMemo(
7546
7779
  () => value != null ? findNodeByKey(items, value) : null,
7547
7780
  [items, value]
7548
7781
  );
@@ -7773,11 +8006,11 @@ function FileInput({
7773
8006
  required,
7774
8007
  icon
7775
8008
  }) {
7776
- const inputRef = React28.useRef(null);
7777
- const errorId = React28.useId();
7778
- const [files, setFiles] = React28.useState([]);
7779
- const [dragging, setDragging] = React28.useState(false);
7780
- const [sizeError, setSizeError] = React28.useState(null);
8009
+ const inputRef = React29.useRef(null);
8010
+ const errorId = React29.useId();
8011
+ const [files, setFiles] = React29.useState([]);
8012
+ const [dragging, setDragging] = React29.useState(false);
8013
+ const [sizeError, setSizeError] = React29.useState(null);
7781
8014
  const effectiveError = errorMessage ?? sizeError ?? void 0;
7782
8015
  const openPicker = () => {
7783
8016
  if (!disabled) inputRef.current?.click();
@@ -7968,30 +8201,30 @@ function DatePicker({
7968
8201
  size = "md",
7969
8202
  className = ""
7970
8203
  }) {
7971
- const errorId = React28.useId();
8204
+ const errorId = React29.useId();
7972
8205
  const hasError = errorMessage != null;
7973
- const [open, setOpen] = React28.useState(false);
7974
- const [viewMonth, setViewMonth] = React28.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
7975
- const [focusDate, setFocusDate] = React28.useState(() => value ?? /* @__PURE__ */ new Date());
7976
- const [view, setView] = React28.useState("days");
7977
- const gridRef = React28.useRef(null);
7978
- React28.useEffect(() => {
8206
+ const [open, setOpen] = React29.useState(false);
8207
+ const [viewMonth, setViewMonth] = React29.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
8208
+ const [focusDate, setFocusDate] = React29.useState(() => value ?? /* @__PURE__ */ new Date());
8209
+ const [view, setView] = React29.useState("days");
8210
+ const gridRef = React29.useRef(null);
8211
+ React29.useEffect(() => {
7979
8212
  if (!open) return;
7980
8213
  const target = value ?? /* @__PURE__ */ new Date();
7981
8214
  setViewMonth(startOfMonth2(target));
7982
8215
  setFocusDate(target);
7983
8216
  setView("days");
7984
8217
  }, [open, value]);
7985
- React28.useEffect(() => {
8218
+ React29.useEffect(() => {
7986
8219
  if (!open) return;
7987
8220
  const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
7988
8221
  cell?.focus();
7989
8222
  }, [open, focusDate]);
7990
- const weekdays = React28.useMemo(() => {
8223
+ const weekdays = React29.useMemo(() => {
7991
8224
  const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
7992
8225
  return ordered;
7993
8226
  }, [weekStartsOn]);
7994
- const grid = React28.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
8227
+ const grid = React29.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
7995
8228
  const isDisabled = (d) => {
7996
8229
  if (min && d < min) return true;
7997
8230
  if (max && d > max) return true;
@@ -8281,10 +8514,10 @@ function TextArea({
8281
8514
  style,
8282
8515
  inputStyle
8283
8516
  }) {
8284
- const errorId = React28.useId();
8517
+ const errorId = React29.useId();
8285
8518
  const hasError = errorMessage != null;
8286
- const ref = React28.useRef(null);
8287
- React28.useLayoutEffect(() => {
8519
+ const ref = React29.useRef(null);
8520
+ React29.useLayoutEffect(() => {
8288
8521
  if (!autoGrow) return;
8289
8522
  const el = ref.current;
8290
8523
  if (!el) return;
@@ -8356,14 +8589,14 @@ function Slider({
8356
8589
  name,
8357
8590
  htmlFor
8358
8591
  }) {
8359
- const errorId = React28.useId();
8592
+ const errorId = React29.useId();
8360
8593
  const hasError = errorMessage != null;
8361
8594
  const isRange = Array.isArray(value ?? defaultValue);
8362
- const [internal, setInternal] = React28.useState(
8595
+ const [internal, setInternal] = React29.useState(
8363
8596
  () => toArray(value) ?? toArray(defaultValue) ?? [min]
8364
8597
  );
8365
8598
  const current = toArray(value) ?? internal;
8366
- const [dragging, setDragging] = React28.useState(false);
8599
+ const [dragging, setDragging] = React29.useState(false);
8367
8600
  const emit = (arr) => {
8368
8601
  setInternal(arr);
8369
8602
  const next = isRange ? [arr[0], arr[1]] : arr[0];
@@ -8458,11 +8691,11 @@ function TagsInput({
8458
8691
  validate,
8459
8692
  separators = ["Enter", ","]
8460
8693
  }) {
8461
- const errorId = React28.useId();
8462
- const inputRef = React28.useRef(null);
8463
- const [internal, setInternal] = React28.useState(defaultValue ?? []);
8464
- const [draft, setDraft] = React28.useState("");
8465
- const [localError, setLocalError] = React28.useState(null);
8694
+ const errorId = React29.useId();
8695
+ const inputRef = React29.useRef(null);
8696
+ const [internal, setInternal] = React29.useState(defaultValue ?? []);
8697
+ const [draft, setDraft] = React29.useState("");
8698
+ const [localError, setLocalError] = React29.useState(null);
8466
8699
  const tags = value ?? internal;
8467
8700
  const hasError = errorMessage != null || localError != null;
8468
8701
  const errorText = errorMessage ?? localError ?? void 0;
@@ -8593,9 +8826,9 @@ function OtpInput({
8593
8826
  className,
8594
8827
  groupAfter
8595
8828
  }) {
8596
- const errorId = React28.useId();
8829
+ const errorId = React29.useId();
8597
8830
  const hasError = errorMessage != null;
8598
- const refs = React28.useRef([]);
8831
+ const refs = React29.useRef([]);
8599
8832
  const chars = Array.from({ length }, (_, i) => value[i] ?? "");
8600
8833
  const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
8601
8834
  const emit = (next) => {
@@ -8644,7 +8877,7 @@ function OtpInput({
8644
8877
  emit(valid.join(""));
8645
8878
  focusBox(valid.length);
8646
8879
  };
8647
- 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(React28__default.default.Fragment, { children: [
8880
+ 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(React29__default.default.Fragment, { children: [
8648
8881
  /* @__PURE__ */ jsxRuntime.jsx(
8649
8882
  "input",
8650
8883
  {
@@ -8702,9 +8935,9 @@ function Rating({
8702
8935
  className,
8703
8936
  required
8704
8937
  }) {
8705
- const errorId = React28.useId();
8706
- const [internal, setInternal] = React28.useState(defaultValue);
8707
- const [hover, setHover] = React28.useState(null);
8938
+ const errorId = React29.useId();
8939
+ const [internal, setInternal] = React29.useState(defaultValue);
8940
+ const [hover, setHover] = React29.useState(null);
8708
8941
  const current = value ?? internal;
8709
8942
  const display2 = hover ?? current;
8710
8943
  const interactive = !readOnly && !disabled;
@@ -8827,9 +9060,9 @@ function TimePicker({
8827
9060
  required,
8828
9061
  style
8829
9062
  }) {
8830
- const errorId = React28.useId();
9063
+ const errorId = React29.useId();
8831
9064
  const hasError = errorMessage != null;
8832
- const [open, setOpen] = React28.useState(false);
9065
+ const [open, setOpen] = React29.useState(false);
8833
9066
  const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
8834
9067
  const update = (next) => {
8835
9068
  const merged = { ...parsed, ...next };
@@ -8953,13 +9186,13 @@ function DateRangePicker({
8953
9186
  required,
8954
9187
  style
8955
9188
  }) {
8956
- const errorId = React28.useId();
9189
+ const errorId = React29.useId();
8957
9190
  const hasError = errorMessage != null;
8958
- const [open, setOpen] = React28.useState(false);
8959
- const [leftMonth, setLeftMonth] = React28.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
8960
- const [pendingStart, setPendingStart] = React28.useState(null);
8961
- const [hoverDate, setHoverDate] = React28.useState(null);
8962
- const weekdays = React28.useMemo(
9191
+ const [open, setOpen] = React29.useState(false);
9192
+ const [leftMonth, setLeftMonth] = React29.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
9193
+ const [pendingStart, setPendingStart] = React29.useState(null);
9194
+ const [hoverDate, setHoverDate] = React29.useState(null);
9195
+ const weekdays = React29.useMemo(
8963
9196
  () => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
8964
9197
  [weekStartsOn]
8965
9198
  );
@@ -9135,10 +9368,10 @@ function ColorPicker({
9135
9368
  required,
9136
9369
  placeholder = "Pick a colour\u2026"
9137
9370
  }) {
9138
- const errorId = React28.useId();
9371
+ const errorId = React29.useId();
9139
9372
  const hasError = errorMessage != null;
9140
- const [open, setOpen] = React28.useState(false);
9141
- const [draft, setDraft] = React28.useState(value);
9373
+ const [open, setOpen] = React29.useState(false);
9374
+ const [draft, setDraft] = React29.useState(value);
9142
9375
  const valid = HEX_RE.test(value);
9143
9376
  const pick = (hex) => {
9144
9377
  onChange?.(hex);
@@ -9225,7 +9458,7 @@ function ColorPicker({
9225
9458
  }
9226
9459
  var CUSTOM_EVENT = "oxy-local-storage";
9227
9460
  function useLocalStorage(key, initialValue) {
9228
- const read = React28.useCallback(() => {
9461
+ const read = React29.useCallback(() => {
9229
9462
  if (typeof window === "undefined") return initialValue;
9230
9463
  try {
9231
9464
  const item = window.localStorage.getItem(key);
@@ -9234,8 +9467,8 @@ function useLocalStorage(key, initialValue) {
9234
9467
  return initialValue;
9235
9468
  }
9236
9469
  }, [key]);
9237
- const [stored, setStored] = React28.useState(read);
9238
- const setValue = React28.useCallback((value) => {
9470
+ const [stored, setStored] = React29.useState(read);
9471
+ const setValue = React29.useCallback((value) => {
9239
9472
  setStored((prev) => {
9240
9473
  const next = value instanceof Function ? value(prev) : value;
9241
9474
  try {
@@ -9248,7 +9481,7 @@ function useLocalStorage(key, initialValue) {
9248
9481
  return next;
9249
9482
  });
9250
9483
  }, [key]);
9251
- const remove = React28.useCallback(() => {
9484
+ const remove = React29.useCallback(() => {
9252
9485
  try {
9253
9486
  if (typeof window !== "undefined") {
9254
9487
  window.localStorage.removeItem(key);
@@ -9258,10 +9491,10 @@ function useLocalStorage(key, initialValue) {
9258
9491
  }
9259
9492
  setStored(initialValue);
9260
9493
  }, [key]);
9261
- React28.useEffect(() => {
9494
+ React29.useEffect(() => {
9262
9495
  setStored(read());
9263
9496
  }, [key, read]);
9264
- React28.useEffect(() => {
9497
+ React29.useEffect(() => {
9265
9498
  if (typeof window === "undefined") return;
9266
9499
  const onStorage = (e) => {
9267
9500
  if (e.key === null || e.key === key) setStored(read());
@@ -9280,8 +9513,8 @@ function useLocalStorage(key, initialValue) {
9280
9513
  }
9281
9514
  function useMediaQuery(query) {
9282
9515
  const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
9283
- const [matches, setMatches] = React28.useState(get);
9284
- React28.useEffect(() => {
9516
+ const [matches, setMatches] = React29.useState(get);
9517
+ React29.useEffect(() => {
9285
9518
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9286
9519
  const mql = window.matchMedia(query);
9287
9520
  const onChange = () => setMatches(mql.matches);
@@ -9312,8 +9545,8 @@ function decodeSegment(seg) {
9312
9545
  }
9313
9546
  }
9314
9547
  function useJwt(token) {
9315
- const [, tick] = React28.useState(0);
9316
- const decoded = React28.useMemo(() => {
9548
+ const [, tick] = React29.useState(0);
9549
+ const decoded = React29.useMemo(() => {
9317
9550
  if (!token) return { payload: null, header: null, exp: null };
9318
9551
  const [h, p] = token.split(".");
9319
9552
  const header = decodeSegment(h);
@@ -9321,7 +9554,7 @@ function useJwt(token) {
9321
9554
  const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
9322
9555
  return { payload, header, exp };
9323
9556
  }, [token]);
9324
- React28.useEffect(() => {
9557
+ React29.useEffect(() => {
9325
9558
  if (decoded.exp == null) return;
9326
9559
  const ms = decoded.exp * 1e3 - Date.now();
9327
9560
  if (ms <= 0) return;
@@ -9368,7 +9601,7 @@ function Jumbotron({
9368
9601
  }
9369
9602
  );
9370
9603
  }
9371
- var COLS = {
9604
+ var COLS2 = {
9372
9605
  2: "sm:grid-cols-2",
9373
9606
  3: "sm:grid-cols-2 lg:grid-cols-3",
9374
9607
  4: "sm:grid-cols-2 lg:grid-cols-4"
@@ -9390,7 +9623,7 @@ function FeatureGrid({
9390
9623
  title != null && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
9391
9624
  description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9392
9625
  ] }),
9393
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS[columns]].join(" "), children: features.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border bg-surface p-5", children: [
9626
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS2[columns]].join(" "), children: features.map((f, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border bg-surface p-5", children: [
9394
9627
  f.icon != null && /* @__PURE__ */ jsxRuntime.jsx(
9395
9628
  "span",
9396
9629
  {
@@ -9447,7 +9680,7 @@ function PricingPlans({ plans, eyebrow, title, description, className = "", styl
9447
9680
  )) })
9448
9681
  ] });
9449
9682
  }
9450
- var COLS2 = {
9683
+ var COLS3 = {
9451
9684
  1: "mx-auto max-w-2xl",
9452
9685
  2: "sm:grid-cols-2",
9453
9686
  3: "sm:grid-cols-2 lg:grid-cols-3"
@@ -9464,7 +9697,7 @@ function Testimonials({ testimonials, eyebrow, title, description, columns = 3,
9464
9697
  title != null && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: title }),
9465
9698
  description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9466
9699
  ] }),
9467
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS2[columns]].join(" "), children: testimonials.map((tm, i) => /* @__PURE__ */ jsxRuntime.jsxs("figure", { className: "flex flex-col gap-4 rounded-xl border border-border bg-surface p-6", children: [
9700
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS3[columns]].join(" "), children: testimonials.map((tm, i) => /* @__PURE__ */ jsxRuntime.jsxs("figure", { className: "flex flex-col gap-4 rounded-xl border border-border bg-surface p-6", children: [
9468
9701
  tm.rating != null && /* @__PURE__ */ jsxRuntime.jsx(Stars, { value: tm.rating }),
9469
9702
  /* @__PURE__ */ jsxRuntime.jsxs("blockquote", { className: "flex-1 text-sm leading-relaxed text-foreground", children: [
9470
9703
  "\u201C",
@@ -9495,13 +9728,13 @@ function SlideShow({
9495
9728
  style
9496
9729
  }) {
9497
9730
  const reduced = framerMotion.useReducedMotion();
9498
- const [index, setIndex] = React28.useState(0);
9499
- const [paused, setPaused] = React28.useState(false);
9731
+ const [index, setIndex] = React29.useState(0);
9732
+ const [paused, setPaused] = React29.useState(false);
9500
9733
  const count = slides.length;
9501
9734
  const idx = count ? (index % count + count) % count : 0;
9502
- const go = React28.useCallback((d) => setIndex((i) => i + d), []);
9503
- const timer = React28.useRef(null);
9504
- React28.useEffect(() => {
9735
+ const go = React29.useCallback((d) => setIndex((i) => i + d), []);
9736
+ const timer = React29.useRef(null);
9737
+ React29.useEffect(() => {
9505
9738
  if (!autoPlay || paused || count <= 1) return;
9506
9739
  timer.current = setInterval(() => setIndex((i) => i + 1), interval);
9507
9740
  return () => {
@@ -9577,7 +9810,7 @@ function Video({
9577
9810
  className = "",
9578
9811
  style
9579
9812
  }) {
9580
- const [playing, setPlaying] = React28.useState(autoPlay);
9813
+ const [playing, setPlaying] = React29.useState(autoPlay);
9581
9814
  const frame = cx("relative w-full overflow-hidden bg-backdrop", framed ? "rounded-2xl border border-border shadow-sm" : "", className);
9582
9815
  const ratio = aspect.replace("/", " / ");
9583
9816
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: frame, style: { aspectRatio: ratio, ...style }, children: embedUrl ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -9632,7 +9865,7 @@ function Parallax({
9632
9865
  style
9633
9866
  }) {
9634
9867
  const reduced = framerMotion.useReducedMotion();
9635
- const ref = React28.useRef(null);
9868
+ const ref = React29.useRef(null);
9636
9869
  const { scrollYProgress } = framerMotion.useScroll({ target: ref, offset: ["start end", "end start"] });
9637
9870
  const shift = Math.max(0, Math.min(1, speed)) * 100;
9638
9871
  const y = framerMotion.useTransform(scrollYProgress, [0, 1], reduced ? ["0%", "0%"] : [`-${shift / 2}%`, `${shift / 2}%`]);
@@ -9668,7 +9901,7 @@ function Parallax({
9668
9901
  }
9669
9902
  );
9670
9903
  }
9671
- var COLS3 = {
9904
+ var COLS4 = {
9672
9905
  2: "sm:grid-cols-2",
9673
9906
  3: "sm:grid-cols-2 lg:grid-cols-3"
9674
9907
  };
@@ -9689,7 +9922,7 @@ function Blog({
9689
9922
  title != null && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-bold tracking-tight text-foreground sm:text-3xl", children: title }),
9690
9923
  description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-2xl text-base leading-relaxed text-foreground-secondary", children: description })
9691
9924
  ] }),
9692
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS3[columns]].join(" "), children: posts.map((post, i) => {
9925
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["grid grid-cols-1 gap-6", COLS4[columns]].join(" "), children: posts.map((post, i) => {
9693
9926
  const meta = [post.author, post.date, post.readTime].filter((m) => m != null);
9694
9927
  const inner = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9695
9928
  post.image && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative aspect-video overflow-hidden bg-backdrop", children: [
@@ -9700,7 +9933,7 @@ function Blog({
9700
9933
  post.tag != null && !post.image && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: "accent", variant: "soft", size: "sm", children: post.tag }) }),
9701
9934
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-semibold leading-snug text-foreground transition-colors group-hover:text-accent", children: post.title }),
9702
9935
  post.excerpt != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "line-clamp-3 text-sm leading-relaxed text-foreground-secondary", children: post.excerpt }),
9703
- 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(React28__default.default.Fragment, { children: [
9936
+ 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(React29__default.default.Fragment, { children: [
9704
9937
  j > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }),
9705
9938
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: m })
9706
9939
  ] }, j)) })
@@ -9829,8 +10062,8 @@ function LeadCapture({
9829
10062
  className = "",
9830
10063
  style
9831
10064
  }) {
9832
- const [email, setEmail] = React28.useState("");
9833
- const [done, setDone] = React28.useState(false);
10065
+ const [email, setEmail] = React29.useState("");
10066
+ const [done, setDone] = React29.useState(false);
9834
10067
  const submit = (e) => {
9835
10068
  e.preventDefault();
9836
10069
  const value = email.trim();
@@ -9956,10 +10189,12 @@ exports.OpaqueGridCard = OpaqueGridCard;
9956
10189
  exports.OtpInput = OtpInput;
9957
10190
  exports.Parallax = Parallax;
9958
10191
  exports.Password = Password;
10192
+ exports.PasswordStrength = PasswordStrength;
9959
10193
  exports.PopConfirm = PopConfirm;
9960
10194
  exports.Portal = Portal;
9961
10195
  exports.PricingPlans = PricingPlans;
9962
10196
  exports.RadioGroup = RadioGroup;
10197
+ exports.RadioTile = RadioTile;
9963
10198
  exports.Rating = Rating;
9964
10199
  exports.ScalableContainer = ScalableContainer;
9965
10200
  exports.Scheduler = Scheduler;
@@ -9995,10 +10230,12 @@ exports.Tree = Tree;
9995
10230
  exports.TreeSelect = TreeSelect;
9996
10231
  exports.Typography = Typography;
9997
10232
  exports.Video = Video;
10233
+ exports.VirtualList = VirtualList;
9998
10234
  exports.Wizard = Wizard;
9999
10235
  exports.cardNumberError = cardNumberError;
10000
10236
  exports.cvvError = cvvError;
10001
10237
  exports.cx = cx;
10238
+ exports.defaultPasswordRules = defaultPasswordRules;
10002
10239
  exports.detectBrand = detectBrand;
10003
10240
  exports.expiryError = expiryError;
10004
10241
  exports.fieldShell = fieldShell;
@@ -10009,6 +10246,7 @@ exports.luhnValid = luhnValid;
10009
10246
  exports.onlyDigits = onlyDigits;
10010
10247
  exports.patterns = patterns;
10011
10248
  exports.runFieldRules = runFieldRules;
10249
+ exports.scorePassword = scorePassword;
10012
10250
  exports.useBreakpoint = useBreakpoint;
10013
10251
  exports.useCart = useCart;
10014
10252
  exports.useFieldArray = useFieldArray;