@geomak/ui 6.28.0 → 6.29.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 chunkOAV4TA4B_cjs = require('./chunk-OAV4TA4B.cjs');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
- var React28 = require('react');
5
+ var React29 = require('react');
6
6
  var reactDom = require('react-dom');
7
7
  var AvatarPrimitive = require('@radix-ui/react-avatar');
8
8
  var DropdownMenu = require('@radix-ui/react-dropdown-menu');
@@ -40,7 +40,7 @@ function _interopNamespace(e) {
40
40
  return Object.freeze(n);
41
41
  }
42
42
 
43
- var React28__default = /*#__PURE__*/_interopDefault(React28);
43
+ var React29__default = /*#__PURE__*/_interopDefault(React29);
44
44
  var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
45
45
  var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
46
46
  var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
@@ -216,8 +216,8 @@ Icon.Copy = Copy;
216
216
  Icon.CircleStack = CircleStack;
217
217
  var icons_default = Icon;
218
218
  function Portal({ children, target }) {
219
- const [resolved, setResolved] = React28.useState(null);
220
- React28.useEffect(() => {
219
+ const [resolved, setResolved] = React29.useState(null);
220
+ React29.useEffect(() => {
221
221
  if (target === null) {
222
222
  setResolved(null);
223
223
  return;
@@ -507,8 +507,8 @@ function Avatar({
507
507
  if (fallback) return fallback;
508
508
  if (alt) {
509
509
  const parts = alt.trim().split(/\s+/).slice(0, 2);
510
- const initials = parts.map((p) => p[0]?.toUpperCase() ?? "").join("");
511
- if (initials) return initials;
510
+ const initials2 = parts.map((p) => p[0]?.toUpperCase() ?? "").join("");
511
+ if (initials2) return initials2;
512
512
  }
513
513
  return /* @__PURE__ */ jsxRuntime.jsx(PersonSilhouette, {});
514
514
  })();
@@ -651,7 +651,7 @@ function IconButton({
651
651
  className = "",
652
652
  style
653
653
  }) {
654
- const colorScheme = React28.useMemo(() => {
654
+ const colorScheme = React29.useMemo(() => {
655
655
  if (type === "primary") {
656
656
  return "bg-accent text-accent-fg hover:bg-accent-hover";
657
657
  }
@@ -741,7 +741,7 @@ var SIZE_CLASSES = {
741
741
  md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
742
742
  lg: "h-11 px-5 text-sm gap-2 rounded-xl"
743
743
  };
744
- var Button = React28__default.default.forwardRef(function Button2({
744
+ var Button = React29__default.default.forwardRef(function Button2({
745
745
  content,
746
746
  variant = "primary",
747
747
  size = "md",
@@ -849,7 +849,7 @@ function MenuButton({
849
849
  "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
850
850
  "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
851
851
  ].join(" "),
852
- children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
852
+ children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
853
853
  item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border" }),
854
854
  /* @__PURE__ */ jsxRuntime.jsxs(
855
855
  DropdownMenu__namespace.Item,
@@ -1092,9 +1092,9 @@ function Tooltip({
1092
1092
  ] }) });
1093
1093
  }
1094
1094
  var TooltipProvider = TooltipPrimitive__namespace.Provider;
1095
- var TabsContext = React28.createContext(null);
1095
+ var TabsContext = React29.createContext(null);
1096
1096
  function useTabsContext() {
1097
- const ctx = React28.useContext(TabsContext);
1097
+ const ctx = React29.useContext(TabsContext);
1098
1098
  if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
1099
1099
  return ctx;
1100
1100
  }
@@ -1116,26 +1116,26 @@ function Tabs({
1116
1116
  children
1117
1117
  }) {
1118
1118
  const isControlled = value !== void 0;
1119
- const [internal, setInternal] = React28.useState(defaultValue);
1119
+ const [internal, setInternal] = React29.useState(defaultValue);
1120
1120
  const current = isControlled ? value : internal;
1121
1121
  const reduced = !!framerMotion.useReducedMotion();
1122
- const indicatorId = React28.useId();
1123
- const select = React28.useCallback((next) => {
1122
+ const indicatorId = React29.useId();
1123
+ const select = React29.useCallback((next) => {
1124
1124
  if (!isControlled) setInternal(next);
1125
1125
  onValueChange?.(next);
1126
1126
  }, [isControlled, onValueChange]);
1127
- const registry = React28.useRef(/* @__PURE__ */ new Map());
1128
- const orderRef = React28.useRef(0);
1129
- const [, bump] = React28.useState(0);
1130
- const registerTab = React28.useCallback((val, meta) => {
1127
+ const registry = React29.useRef(/* @__PURE__ */ new Map());
1128
+ const orderRef = React29.useRef(0);
1129
+ const [, bump] = React29.useState(0);
1130
+ const registerTab = React29.useCallback((val, meta) => {
1131
1131
  const existing = registry.current.get(val);
1132
1132
  registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
1133
1133
  if (!existing) bump((v) => v + 1);
1134
1134
  }, []);
1135
- const unregisterTab = React28.useCallback((val) => {
1135
+ const unregisterTab = React29.useCallback((val) => {
1136
1136
  if (registry.current.delete(val)) bump((v) => v + 1);
1137
1137
  }, []);
1138
- 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 })), []);
1138
+ 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 })), []);
1139
1139
  return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
1140
1140
  TabsPrimitive__namespace.Root,
1141
1141
  {
@@ -1155,10 +1155,10 @@ function Tabs({
1155
1155
  function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
1156
1156
  const { variant, orientation, reduced, value } = useTabsContext();
1157
1157
  const horizontal = orientation === "horizontal";
1158
- const scrollRef = React28.useRef(null);
1159
- const [edges, setEdges] = React28.useState({ start: false, end: false });
1158
+ const scrollRef = React29.useRef(null);
1159
+ const [edges, setEdges] = React29.useState({ start: false, end: false });
1160
1160
  const scrollable = variant !== "segmented";
1161
- React28.useLayoutEffect(() => {
1161
+ React29.useLayoutEffect(() => {
1162
1162
  const el = scrollRef.current;
1163
1163
  if (!el || !scrollable) return;
1164
1164
  const update = () => {
@@ -1183,13 +1183,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
1183
1183
  ro.disconnect();
1184
1184
  };
1185
1185
  }, [horizontal, scrollable, children]);
1186
- const nudge = React28.useCallback((dir) => {
1186
+ const nudge = React29.useCallback((dir) => {
1187
1187
  const el = scrollRef.current;
1188
1188
  if (!el) return;
1189
1189
  const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
1190
1190
  el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
1191
1191
  }, [horizontal, reduced]);
1192
- React28.useLayoutEffect(() => {
1192
+ React29.useLayoutEffect(() => {
1193
1193
  const el = scrollRef.current;
1194
1194
  if (!el || !scrollable) return;
1195
1195
  const active = el.querySelector("[role=tab][data-state=active]");
@@ -1247,9 +1247,9 @@ function Chevron2({ side, orientation, onClick }) {
1247
1247
  function OverflowMenu() {
1248
1248
  const { getTabs, value, select, orientation } = useTabsContext();
1249
1249
  const horizontal = orientation === "horizontal";
1250
- const [open, setOpen] = React28.useState(false);
1251
- const wrapRef = React28.useRef(null);
1252
- const timer = React28.useRef(null);
1250
+ const [open, setOpen] = React29.useState(false);
1251
+ const wrapRef = React29.useRef(null);
1252
+ const timer = React29.useRef(null);
1253
1253
  const openNow = () => {
1254
1254
  if (timer.current) clearTimeout(timer.current);
1255
1255
  setOpen(true);
@@ -1257,7 +1257,7 @@ function OverflowMenu() {
1257
1257
  const closeSoon = () => {
1258
1258
  timer.current = setTimeout(() => setOpen(false), 160);
1259
1259
  };
1260
- React28.useLayoutEffect(() => {
1260
+ React29.useLayoutEffect(() => {
1261
1261
  if (!open) return;
1262
1262
  const onDoc = (e) => {
1263
1263
  if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
@@ -1338,7 +1338,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
1338
1338
  const isActive = active === value;
1339
1339
  const horizontal = orientation === "horizontal";
1340
1340
  const sz = SIZE[size];
1341
- React28.useLayoutEffect(() => {
1341
+ React29.useLayoutEffect(() => {
1342
1342
  registerTab(value, { label: children, icon, disabled });
1343
1343
  return () => unregisterTab(value);
1344
1344
  }, [value, children, icon, disabled, registerTab, unregisterTab]);
@@ -1536,7 +1536,7 @@ function Tree({
1536
1536
  item.key
1537
1537
  )) });
1538
1538
  }
1539
- var AccordionCtx = React28.createContext({ variant: "separated" });
1539
+ var AccordionCtx = React29.createContext({ variant: "separated" });
1540
1540
  function Accordion2({
1541
1541
  children,
1542
1542
  type = "single",
@@ -1595,7 +1595,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
1595
1595
  }
1596
1596
  );
1597
1597
  function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
1598
- const { variant } = React28.useContext(AccordionCtx);
1598
+ const { variant } = React29.useContext(AccordionCtx);
1599
1599
  return /* @__PURE__ */ jsxRuntime.jsxs(
1600
1600
  AccordionPrimitive__namespace.Item,
1601
1601
  {
@@ -1654,7 +1654,7 @@ function Breadcrumbs({
1654
1654
  className = "",
1655
1655
  style
1656
1656
  }) {
1657
- const [expanded, setExpanded] = React28.useState(false);
1657
+ const [expanded, setExpanded] = React29.useState(false);
1658
1658
  const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
1659
1659
  const visible = [];
1660
1660
  if (shouldCollapse) {
@@ -1838,8 +1838,8 @@ function Stepper({
1838
1838
  className = ""
1839
1839
  }) {
1840
1840
  const reduced = framerMotion.useReducedMotion();
1841
- const [forcedVertical, setForcedVertical] = React28.useState(false);
1842
- React28.useEffect(() => {
1841
+ const [forcedVertical, setForcedVertical] = React29.useState(false);
1842
+ React29.useEffect(() => {
1843
1843
  if (!responsive || orientation === "vertical") return;
1844
1844
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
1845
1845
  const mq = window.matchMedia("(max-width: 767px)");
@@ -1948,7 +1948,7 @@ function Kbd({
1948
1948
  style
1949
1949
  }) {
1950
1950
  if (keys && keys.length > 0) {
1951
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
1951
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
1952
1952
  i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
1953
1953
  /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
1954
1954
  ] }, `${k}-${i}`)) });
@@ -2039,13 +2039,13 @@ function FlatCarousel({
2039
2039
  className = "",
2040
2040
  style
2041
2041
  }) {
2042
- const scrollerRef = React28.useRef(null);
2043
- const slides = React28__default.default.Children.toArray(children);
2044
- const [active, setActive] = React28.useState(0);
2045
- const [atStart, setAtStart] = React28.useState(true);
2046
- const [atEnd, setAtEnd] = React28.useState(false);
2042
+ const scrollerRef = React29.useRef(null);
2043
+ const slides = React29__default.default.Children.toArray(children);
2044
+ const [active, setActive] = React29.useState(0);
2045
+ const [atStart, setAtStart] = React29.useState(true);
2046
+ const [atEnd, setAtEnd] = React29.useState(false);
2047
2047
  const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
2048
- const update = React28.useCallback(() => {
2048
+ const update = React29.useCallback(() => {
2049
2049
  const el = scrollerRef.current;
2050
2050
  if (!el) return;
2051
2051
  setAtStart(el.scrollLeft <= 1);
@@ -2054,7 +2054,7 @@ function FlatCarousel({
2054
2054
  const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
2055
2055
  setActive(Math.round(el.scrollLeft / slideW));
2056
2056
  }, [gap]);
2057
- React28.useEffect(() => {
2057
+ React29.useEffect(() => {
2058
2058
  update();
2059
2059
  const el = scrollerRef.current;
2060
2060
  if (!el) return;
@@ -2095,9 +2095,9 @@ function RotatingCarousel({
2095
2095
  className = "",
2096
2096
  style
2097
2097
  }) {
2098
- const slides = React28__default.default.Children.toArray(children);
2098
+ const slides = React29__default.default.Children.toArray(children);
2099
2099
  const count = slides.length;
2100
- const [active, setActive] = React28.useState(0);
2100
+ const [active, setActive] = React29.useState(0);
2101
2101
  const reduced = framerMotion.useReducedMotion();
2102
2102
  const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
2103
2103
  const idx = wrap(active);
@@ -2168,6 +2168,300 @@ function RotatingCarousel({
2168
2168
  }
2169
2169
  );
2170
2170
  }
2171
+ var FIELD_SIZE = {
2172
+ sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
2173
+ md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
2174
+ lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
2175
+ };
2176
+ var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
2177
+ var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
2178
+ var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
2179
+ var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
2180
+ function fieldShell({
2181
+ size = "md",
2182
+ hasError = false,
2183
+ disabled = false,
2184
+ focusWithin = false,
2185
+ sized = true
2186
+ } = {}) {
2187
+ const s = FIELD_SIZE[size];
2188
+ return [
2189
+ "w-full rounded-lg border bg-surface text-foreground",
2190
+ "transition-[color,box-shadow,border-color] duration-150",
2191
+ s.text,
2192
+ sized ? `${s.control} ${s.padX}` : "",
2193
+ // resting border
2194
+ hasError ? "border-status-error" : "border-border",
2195
+ // hover (only when interactive + no error)
2196
+ disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
2197
+ // focus
2198
+ focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
2199
+ hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
2200
+ // placeholder colour for native inputs
2201
+ "placeholder:text-foreground-muted"
2202
+ ].filter(Boolean).join(" ");
2203
+ }
2204
+ function FieldHelpIcon({ text }) {
2205
+ return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
2206
+ "button",
2207
+ {
2208
+ type: "button",
2209
+ "aria-label": "More information",
2210
+ className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
2211
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 16 16", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
2212
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
2213
+ /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
2214
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
2215
+ ] })
2216
+ }
2217
+ ) });
2218
+ }
2219
+ function FieldLabel({
2220
+ label,
2221
+ htmlFor,
2222
+ required,
2223
+ helperText,
2224
+ horizontal = false,
2225
+ align = "start",
2226
+ style,
2227
+ width,
2228
+ className = ""
2229
+ }) {
2230
+ if (label == null && helperText == null) return null;
2231
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2232
+ "div",
2233
+ {
2234
+ style: { width: horizontal ? width : void 0, ...style },
2235
+ className: [
2236
+ "flex items-center gap-1",
2237
+ horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
2238
+ // Only the 'start' alignment needs the top nudge; 'center' relies
2239
+ // on the row's items-center to line up with a short control.
2240
+ horizontal && align === "start" ? "mt-2" : "",
2241
+ className
2242
+ ].filter(Boolean).join(" "),
2243
+ children: [
2244
+ label != null && /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
2245
+ label,
2246
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
2247
+ ] }),
2248
+ helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
2249
+ ]
2250
+ }
2251
+ );
2252
+ }
2253
+ function Field({
2254
+ label,
2255
+ htmlFor,
2256
+ errorId,
2257
+ errorMessage,
2258
+ layout = "vertical",
2259
+ required,
2260
+ helperText,
2261
+ labelAlign = "start",
2262
+ labelStyle,
2263
+ labelWidth,
2264
+ className = "",
2265
+ children
2266
+ }) {
2267
+ const hasError = errorMessage != null;
2268
+ const horizontal = layout === "horizontal";
2269
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2270
+ "div",
2271
+ {
2272
+ className: [
2273
+ "flex",
2274
+ horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
2275
+ className
2276
+ ].filter(Boolean).join(" "),
2277
+ children: [
2278
+ /* @__PURE__ */ jsxRuntime.jsx(
2279
+ FieldLabel,
2280
+ {
2281
+ label,
2282
+ htmlFor,
2283
+ required,
2284
+ helperText,
2285
+ horizontal,
2286
+ align: labelAlign,
2287
+ style: labelStyle,
2288
+ width: labelWidth
2289
+ }
2290
+ ),
2291
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
2292
+ children,
2293
+ hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
2294
+ ] })
2295
+ ]
2296
+ }
2297
+ );
2298
+ }
2299
+ var toDate = (d) => d instanceof Date ? d : new Date(d);
2300
+ var timeLabel = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
2301
+ var initials = (name) => (name ?? "").trim().split(/\s+/).slice(0, 2).map((w) => w[0]?.toUpperCase() ?? "").join("") || void 0;
2302
+ var SendIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" }) });
2303
+ var ArrowDown = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12l7 7 7-7" }) });
2304
+ function TypingDots() {
2305
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center gap-1", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-foreground-muted", style: { animationDelay: `${i * 0.15}s` } }, i)) });
2306
+ }
2307
+ function Chat({
2308
+ messages,
2309
+ currentUserId,
2310
+ onSend,
2311
+ typingNames = [],
2312
+ title,
2313
+ subtitle,
2314
+ avatar,
2315
+ headerActions,
2316
+ placeholder = "Write a message\u2026",
2317
+ disabled = false,
2318
+ hideComposer = false,
2319
+ emptyState,
2320
+ height = 480,
2321
+ className = "",
2322
+ style
2323
+ }) {
2324
+ const listRef = React29.useRef(null);
2325
+ const atBottomRef = React29.useRef(true);
2326
+ const [showJump, setShowJump] = React29.useState(false);
2327
+ const [draft, setDraft] = React29.useState("");
2328
+ const taRef = React29.useRef(null);
2329
+ const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
2330
+ const isTyping = typingNames.length > 0;
2331
+ const scrollToBottom = React29.useCallback((smooth = true) => {
2332
+ const el = listRef.current;
2333
+ if (!el) return;
2334
+ if (typeof el.scrollTo === "function") el.scrollTo({ top: el.scrollHeight, behavior: smooth ? "smooth" : "auto" });
2335
+ else el.scrollTop = el.scrollHeight;
2336
+ }, []);
2337
+ const onScroll = () => {
2338
+ const el = listRef.current;
2339
+ if (!el) return;
2340
+ const near = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
2341
+ atBottomRef.current = near;
2342
+ setShowJump(!near);
2343
+ };
2344
+ React29.useEffect(() => {
2345
+ if (atBottomRef.current) scrollToBottom(messages.length > 0);
2346
+ }, [messages.length, isTyping]);
2347
+ React29.useEffect(() => {
2348
+ scrollToBottom(false);
2349
+ }, [scrollToBottom]);
2350
+ React29.useLayoutEffect(() => {
2351
+ const ta = taRef.current;
2352
+ if (!ta) return;
2353
+ ta.style.height = "auto";
2354
+ ta.style.height = `${Math.min(ta.scrollHeight, 120)}px`;
2355
+ }, [draft]);
2356
+ const send = () => {
2357
+ const text = draft.trim();
2358
+ if (!text || disabled) return;
2359
+ onSend?.(text);
2360
+ setDraft("");
2361
+ };
2362
+ const onKeyDown = (e) => {
2363
+ if (e.key === "Enter" && !e.shiftKey) {
2364
+ e.preventDefault();
2365
+ send();
2366
+ }
2367
+ };
2368
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2369
+ "div",
2370
+ {
2371
+ className: ["flex flex-col overflow-hidden rounded-xl border border-border bg-surface", className].filter(Boolean).join(" "),
2372
+ style: { height, ...style },
2373
+ children: [
2374
+ hasHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 items-center gap-3 border-b border-border px-4 py-3", children: [
2375
+ avatar != null && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatar, alt: typeof title === "string" ? title : "Conversation", size: "sm" }),
2376
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
2377
+ title != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: title }),
2378
+ subtitle != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-foreground-muted", children: subtitle })
2379
+ ] }),
2380
+ headerActions != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-shrink-0 items-center gap-1", children: headerActions })
2381
+ ] }),
2382
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 overflow-hidden", children: [
2383
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: listRef, onScroll, className: "flex h-full flex-col gap-1 overflow-y-auto bg-background px-4 py-3", children: [
2384
+ messages.length === 0 && !isTyping ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center text-center text-sm text-foreground-muted", children: emptyState ?? "No messages yet. Say hello \u{1F44B}" }) : messages.map((m, i) => {
2385
+ const own = m.authorId === currentUserId;
2386
+ const prev = messages[i - 1];
2387
+ const next = messages[i + 1];
2388
+ const firstOfGroup = !prev || prev.authorId !== m.authorId;
2389
+ const lastOfGroup = !next || next.authorId !== m.authorId;
2390
+ const ts = m.timestamp ? toDate(m.timestamp) : null;
2391
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ["flex items-end gap-2", own ? "flex-row-reverse" : "", firstOfGroup ? "mt-2 first:mt-0" : ""].filter(Boolean).join(" "), children: [
2392
+ !own && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7 flex-shrink-0", children: lastOfGroup && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: m.avatar, alt: m.authorName ?? "User", fallback: initials(m.authorName), size: "xs" }) }),
2393
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ["flex max-w-[78%] flex-col", own ? "items-end" : "items-start"].join(" "), children: [
2394
+ firstOfGroup && !own && m.authorName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-0.5 px-1 text-[11px] font-medium text-foreground-muted", children: m.authorName }),
2395
+ /* @__PURE__ */ jsxRuntime.jsx(
2396
+ "div",
2397
+ {
2398
+ className: [
2399
+ "whitespace-pre-wrap break-words px-3 py-1.5 text-sm leading-snug",
2400
+ own ? "rounded-2xl bg-accent text-accent-fg" : "rounded-2xl border border-border bg-surface text-foreground",
2401
+ lastOfGroup ? own ? "rounded-br-md" : "rounded-bl-md" : ""
2402
+ ].filter(Boolean).join(" "),
2403
+ children: m.text
2404
+ }
2405
+ ),
2406
+ lastOfGroup && (ts || own && m.status) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-0.5 px-1 text-[10px] text-foreground-muted", children: [
2407
+ ts && timeLabel(ts),
2408
+ own && m.status && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-1 capitalize", children: [
2409
+ "\xB7 ",
2410
+ m.status
2411
+ ] })
2412
+ ] })
2413
+ ] })
2414
+ ] }, m.id);
2415
+ }),
2416
+ isTyping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex items-end gap-2", children: [
2417
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7 flex-shrink-0" }),
2418
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 rounded-2xl rounded-bl-md border border-border bg-surface px-3 py-2", children: [
2419
+ /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}),
2420
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-foreground-muted", children: typingNames.length === 1 ? `${typingNames[0]} is typing` : `${typingNames.length} people are typing` })
2421
+ ] })
2422
+ ] })
2423
+ ] }),
2424
+ showJump && /* @__PURE__ */ jsxRuntime.jsx(
2425
+ "button",
2426
+ {
2427
+ type: "button",
2428
+ onClick: () => scrollToBottom(true),
2429
+ "aria-label": "Jump to latest",
2430
+ className: "absolute bottom-3 left-1/2 flex h-8 w-8 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-surface text-foreground-secondary shadow-md transition-colors hover:bg-surface-raised hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
2431
+ children: /* @__PURE__ */ jsxRuntime.jsx(ArrowDown, {})
2432
+ }
2433
+ )
2434
+ ] }),
2435
+ !hideComposer && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 items-end gap-2 border-t border-border p-3", children: [
2436
+ /* @__PURE__ */ jsxRuntime.jsx(
2437
+ "textarea",
2438
+ {
2439
+ ref: taRef,
2440
+ rows: 1,
2441
+ value: draft,
2442
+ disabled,
2443
+ placeholder,
2444
+ onChange: (e) => setDraft(e.target.value),
2445
+ onKeyDown,
2446
+ "aria-label": "Message",
2447
+ className: `${fieldShell({ size: "md", hasError: false, disabled, sized: false })} max-h-[120px] flex-1 resize-none px-3 py-2 leading-snug`
2448
+ }
2449
+ ),
2450
+ /* @__PURE__ */ jsxRuntime.jsx(
2451
+ IconButton,
2452
+ {
2453
+ type: "primary",
2454
+ icon: /* @__PURE__ */ jsxRuntime.jsx(SendIcon, {}),
2455
+ title: "Send",
2456
+ disabled: disabled || draft.trim().length === 0,
2457
+ onClick: send
2458
+ }
2459
+ )
2460
+ ] })
2461
+ ]
2462
+ }
2463
+ );
2464
+ }
2171
2465
  var VALUE_SIZE = {
2172
2466
  sm: "text-xl",
2173
2467
  md: "text-3xl",
@@ -2179,7 +2473,7 @@ var TONE2 = {
2179
2473
  neutral: "text-foreground-muted"
2180
2474
  };
2181
2475
  var ArrowUp = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, "aria-hidden": "true", className: "h-3.5 w-3.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 19V5M5 12l7-7 7 7" }) });
2182
- var ArrowDown = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, "aria-hidden": "true", className: "h-3.5 w-3.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12l7 7 7-7" }) });
2476
+ var ArrowDown2 = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, "aria-hidden": "true", className: "h-3.5 w-3.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12l7 7 7-7" }) });
2183
2477
  function Statistic({
2184
2478
  label,
2185
2479
  value,
@@ -2211,7 +2505,7 @@ function Statistic({
2211
2505
  suffix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-[0.5em] font-medium self-center", children: suffix })
2212
2506
  ] }),
2213
2507
  delta && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `mt-1.5 flex items-center gap-1 text-sm font-medium ${align === "center" ? "justify-center" : ""} ${TONE2[deltaTone]}`, children: [
2214
- dir === "up" ? ArrowUp : dir === "down" ? ArrowDown : null,
2508
+ dir === "up" ? ArrowUp : dir === "down" ? ArrowDown2 : null,
2215
2509
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: delta.value }),
2216
2510
  delta.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted font-normal", children: delta.label })
2217
2511
  ] }),
@@ -2247,7 +2541,7 @@ function FAB({
2247
2541
  className = "",
2248
2542
  style
2249
2543
  }) {
2250
- const [open, setOpen] = React28.useState(false);
2544
+ const [open, setOpen] = React29.useState(false);
2251
2545
  const reduced = framerMotion.useReducedMotion();
2252
2546
  const hasDial = !!actions && actions.length > 0;
2253
2547
  const bottom = position.startsWith("bottom");
@@ -2349,8 +2643,8 @@ function PopConfirm({
2349
2643
  onOpenChange,
2350
2644
  className = ""
2351
2645
  }) {
2352
- const [uncontrolledOpen, setUncontrolledOpen] = React28.useState(false);
2353
- const [loading, setLoading] = React28.useState(false);
2646
+ const [uncontrolledOpen, setUncontrolledOpen] = React29.useState(false);
2647
+ const [loading, setLoading] = React29.useState(false);
2354
2648
  const isOpen = open ?? uncontrolledOpen;
2355
2649
  const setOpen = (next) => {
2356
2650
  onOpenChange?.(next);
@@ -2437,16 +2731,16 @@ function LogoutTimer({
2437
2731
  logoutLabel = "Sign out now"
2438
2732
  }) {
2439
2733
  const reduced = framerMotion.useReducedMotion();
2440
- const [warning, setWarning] = React28.useState(false);
2441
- const [remaining, setRemaining] = React28.useState(countdown);
2442
- const idleTimer = React28.useRef(null);
2443
- const tick = React28.useRef(null);
2444
- const deadline = React28.useRef(0);
2445
- const warningRef = React28.useRef(false);
2446
- const lastReset = React28.useRef(0);
2447
- const cbs = React28.useRef({ onLogout, onContinue, onWarning });
2734
+ const [warning, setWarning] = React29.useState(false);
2735
+ const [remaining, setRemaining] = React29.useState(countdown);
2736
+ const idleTimer = React29.useRef(null);
2737
+ const tick = React29.useRef(null);
2738
+ const deadline = React29.useRef(0);
2739
+ const warningRef = React29.useRef(false);
2740
+ const lastReset = React29.useRef(0);
2741
+ const cbs = React29.useRef({ onLogout, onContinue, onWarning });
2448
2742
  cbs.current = { onLogout, onContinue, onWarning };
2449
- const clearTimers = React28.useCallback(() => {
2743
+ const clearTimers = React29.useCallback(() => {
2450
2744
  if (idleTimer.current) {
2451
2745
  clearTimeout(idleTimer.current);
2452
2746
  idleTimer.current = null;
@@ -2456,13 +2750,13 @@ function LogoutTimer({
2456
2750
  tick.current = null;
2457
2751
  }
2458
2752
  }, []);
2459
- const logout = React28.useCallback(() => {
2753
+ const logout = React29.useCallback(() => {
2460
2754
  clearTimers();
2461
2755
  warningRef.current = false;
2462
2756
  setWarning(false);
2463
2757
  cbs.current.onLogout();
2464
2758
  }, [clearTimers]);
2465
- const startIdle = React28.useCallback(() => {
2759
+ const startIdle = React29.useCallback(() => {
2466
2760
  if (idleTimer.current) clearTimeout(idleTimer.current);
2467
2761
  idleTimer.current = setTimeout(() => {
2468
2762
  warningRef.current = true;
@@ -2477,7 +2771,7 @@ function LogoutTimer({
2477
2771
  }, 250);
2478
2772
  }, timeout);
2479
2773
  }, [timeout, countdown, logout]);
2480
- const stay = React28.useCallback(() => {
2774
+ const stay = React29.useCallback(() => {
2481
2775
  if (tick.current) {
2482
2776
  clearInterval(tick.current);
2483
2777
  tick.current = null;
@@ -2487,7 +2781,7 @@ function LogoutTimer({
2487
2781
  cbs.current.onContinue?.();
2488
2782
  startIdle();
2489
2783
  }, [startIdle]);
2490
- React28.useEffect(() => {
2784
+ React29.useEffect(() => {
2491
2785
  if (!enabled) {
2492
2786
  clearTimers();
2493
2787
  warningRef.current = false;
@@ -2559,16 +2853,16 @@ function Calendar2({
2559
2853
  className = "",
2560
2854
  style
2561
2855
  }) {
2562
- const today = React28.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
2563
- const [internalMonth, setInternalMonth] = React28.useState(() => month ?? defaultMonth ?? value ?? today);
2856
+ const today = React29.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
2857
+ const [internalMonth, setInternalMonth] = React29.useState(() => month ?? defaultMonth ?? value ?? today);
2564
2858
  const visible = month ?? internalMonth;
2565
2859
  const setMonth = (next) => {
2566
2860
  onMonthChange?.(next);
2567
2861
  if (month === void 0) setInternalMonth(next);
2568
2862
  };
2569
- const grid = React28.useMemo(() => buildGrid(visible, weekStartsOn), [visible, weekStartsOn]);
2570
- const weekdays = React28.useMemo(() => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]), [weekStartsOn]);
2571
- const eventsByDay = React28.useMemo(() => {
2863
+ const grid = React29.useMemo(() => buildGrid(visible, weekStartsOn), [visible, weekStartsOn]);
2864
+ const weekdays = React29.useMemo(() => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]), [weekStartsOn]);
2865
+ const eventsByDay = React29.useMemo(() => {
2572
2866
  const map = /* @__PURE__ */ new Map();
2573
2867
  for (const ev of events ?? []) {
2574
2868
  const key = startOfDay(ev.date).toDateString();
@@ -2648,134 +2942,6 @@ function Calendar2({
2648
2942
  }) })
2649
2943
  ] });
2650
2944
  }
2651
- var FIELD_SIZE = {
2652
- sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
2653
- md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
2654
- lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
2655
- };
2656
- var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
2657
- var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
2658
- var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
2659
- var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
2660
- function fieldShell({
2661
- size = "md",
2662
- hasError = false,
2663
- disabled = false,
2664
- focusWithin = false,
2665
- sized = true
2666
- } = {}) {
2667
- const s = FIELD_SIZE[size];
2668
- return [
2669
- "w-full rounded-lg border bg-surface text-foreground",
2670
- "transition-[color,box-shadow,border-color] duration-150",
2671
- s.text,
2672
- sized ? `${s.control} ${s.padX}` : "",
2673
- // resting border
2674
- hasError ? "border-status-error" : "border-border",
2675
- // hover (only when interactive + no error)
2676
- disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
2677
- // focus
2678
- focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
2679
- hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
2680
- // placeholder colour for native inputs
2681
- "placeholder:text-foreground-muted"
2682
- ].filter(Boolean).join(" ");
2683
- }
2684
- function FieldHelpIcon({ text }) {
2685
- return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
2686
- "button",
2687
- {
2688
- type: "button",
2689
- "aria-label": "More information",
2690
- className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
2691
- children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 16 16", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
2692
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
2693
- /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
2694
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
2695
- ] })
2696
- }
2697
- ) });
2698
- }
2699
- function FieldLabel({
2700
- label,
2701
- htmlFor,
2702
- required,
2703
- helperText,
2704
- horizontal = false,
2705
- align = "start",
2706
- style,
2707
- width,
2708
- className = ""
2709
- }) {
2710
- if (label == null && helperText == null) return null;
2711
- return /* @__PURE__ */ jsxRuntime.jsxs(
2712
- "div",
2713
- {
2714
- style: { width: horizontal ? width : void 0, ...style },
2715
- className: [
2716
- "flex items-center gap-1",
2717
- horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
2718
- // Only the 'start' alignment needs the top nudge; 'center' relies
2719
- // on the row's items-center to line up with a short control.
2720
- horizontal && align === "start" ? "mt-2" : "",
2721
- className
2722
- ].filter(Boolean).join(" "),
2723
- children: [
2724
- label != null && /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
2725
- label,
2726
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
2727
- ] }),
2728
- helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
2729
- ]
2730
- }
2731
- );
2732
- }
2733
- function Field({
2734
- label,
2735
- htmlFor,
2736
- errorId,
2737
- errorMessage,
2738
- layout = "vertical",
2739
- required,
2740
- helperText,
2741
- labelAlign = "start",
2742
- labelStyle,
2743
- labelWidth,
2744
- className = "",
2745
- children
2746
- }) {
2747
- const hasError = errorMessage != null;
2748
- const horizontal = layout === "horizontal";
2749
- return /* @__PURE__ */ jsxRuntime.jsxs(
2750
- "div",
2751
- {
2752
- className: [
2753
- "flex",
2754
- horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
2755
- className
2756
- ].filter(Boolean).join(" "),
2757
- children: [
2758
- /* @__PURE__ */ jsxRuntime.jsx(
2759
- FieldLabel,
2760
- {
2761
- label,
2762
- htmlFor,
2763
- required,
2764
- helperText,
2765
- horizontal,
2766
- align: labelAlign,
2767
- style: labelStyle,
2768
- width: labelWidth
2769
- }
2770
- ),
2771
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
2772
- children,
2773
- hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
2774
- ] })
2775
- ]
2776
- }
2777
- );
2778
- }
2779
2945
  var SIZE5 = {
2780
2946
  sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
2781
2947
  md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
@@ -2799,11 +2965,11 @@ function SegmentedControl({
2799
2965
  "aria-label": ariaLabel
2800
2966
  }) {
2801
2967
  const sz = SIZE5[size];
2802
- const groupId = React28.useId();
2803
- const errorId = React28.useId();
2968
+ const groupId = React29.useId();
2969
+ const errorId = React29.useId();
2804
2970
  const hasError = errorMessage != null;
2805
2971
  const isControlled = value !== void 0;
2806
- const [internal, setInternal] = React28.useState(defaultValue);
2972
+ const [internal, setInternal] = React29.useState(defaultValue);
2807
2973
  const current = isControlled ? value : internal;
2808
2974
  const handle = (v) => {
2809
2975
  if (!v) return;
@@ -2890,7 +3056,7 @@ var MONTHS2 = [
2890
3056
  ];
2891
3057
  var MONTHS_SHORT = MONTHS2.map((m) => m.slice(0, 3));
2892
3058
  var WEEKDAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2893
- var toDate = (d) => d instanceof Date ? d : new Date(d);
3059
+ var toDate2 = (d) => d instanceof Date ? d : new Date(d);
2894
3060
  var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
2895
3061
  var addDays = (d, n) => {
2896
3062
  const x = new Date(d);
@@ -2938,10 +3104,10 @@ var weekLabel = (cursor, weekStartsOn) => {
2938
3104
  };
2939
3105
  var minutesIntoDay = (d) => d.getHours() * 60 + d.getMinutes();
2940
3106
  var hourLabel = (hour) => `${String(hour).padStart(2, "0")}:00`;
2941
- var timeLabel = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
3107
+ var timeLabel2 = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
2942
3108
  var normalize = (e) => {
2943
- const start = toDate(e.start);
2944
- const end = e.end ? toDate(e.end) : new Date(start.getTime() + 36e5);
3109
+ const start = toDate2(e.start);
3110
+ const end = e.end ? toDate2(e.end) : new Date(start.getTime() + 36e5);
2945
3111
  return { ...e, start, end };
2946
3112
  };
2947
3113
  var Spinner2 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-5 w-5 animate-spin text-accent", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.755 10.059a7.5 7.5 0 0112.548-3.364l1.903 1.903h-3.183a.75.75 0 100 1.5h4.992a.75.75 0 00.75-.75V4.356a.75.75 0 00-1.5 0v3.18l-1.9-1.9A9 9 0 003.306 9.67a.75.75 0 101.45.388zm15.408 3.352a.75.75 0 00-.919.53 7.5 7.5 0 01-12.548 3.364l-1.902-1.903h3.183a.75.75 0 000-1.5H2.984a.75.75 0 00-.75.75v4.992a.75.75 0 001.5 0v-3.18l1.9 1.9a9 9 0 0015.059-4.035.75.75 0 00-.53-.918z" }) });
@@ -2963,22 +3129,22 @@ function Scheduler({
2963
3129
  style
2964
3130
  }) {
2965
3131
  const reduced = framerMotion.useReducedMotion();
2966
- const [view, setView] = React28.useState(defaultView);
2967
- const [cursor, setCursor] = React28.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
2968
- const [loaded, setLoaded] = React28.useState([]);
2969
- const [loading, setLoading] = React28.useState(false);
2970
- const [error, setError] = React28.useState(null);
2971
- const [reloadKey, setReloadKey] = React28.useState(0);
2972
- const [dir, setDir] = React28.useState(0);
2973
- const cbRef = React28.useRef({ loadEvents, onError });
3132
+ const [view, setView] = React29.useState(defaultView);
3133
+ const [cursor, setCursor] = React29.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
3134
+ const [loaded, setLoaded] = React29.useState([]);
3135
+ const [loading, setLoading] = React29.useState(false);
3136
+ const [error, setError] = React29.useState(null);
3137
+ const [reloadKey, setReloadKey] = React29.useState(0);
3138
+ const [dir, setDir] = React29.useState(0);
3139
+ const cbRef = React29.useRef({ loadEvents, onError });
2974
3140
  cbRef.current = { loadEvents, onError };
2975
- const range = React28.useMemo(
3141
+ const range = React29.useMemo(
2976
3142
  () => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
2977
3143
  [view, cursor, weekStartsOn]
2978
3144
  );
2979
3145
  const fromKey = range.from.getTime();
2980
3146
  const toKey = range.to.getTime();
2981
- React28.useEffect(() => {
3147
+ React29.useEffect(() => {
2982
3148
  const { loadEvents: loader, onError: onErr } = cbRef.current;
2983
3149
  if (!loader) return;
2984
3150
  let cancelled = false;
@@ -2998,16 +3164,16 @@ function Scheduler({
2998
3164
  cancelled = true;
2999
3165
  };
3000
3166
  }, [fromKey, toKey, view, reloadKey]);
3001
- const retry = React28.useCallback(() => setReloadKey((k) => k + 1), []);
3002
- const events = React28.useMemo(
3167
+ const retry = React29.useCallback(() => setReloadKey((k) => k + 1), []);
3168
+ const events = React29.useMemo(
3003
3169
  () => (controlledEvents ?? loaded).map(normalize),
3004
3170
  [controlledEvents, loaded]
3005
3171
  );
3006
- const go = React28.useCallback((delta) => {
3172
+ const go = React29.useCallback((delta) => {
3007
3173
  setDir(delta);
3008
3174
  setCursor((c) => view === "month" ? addMonths2(c, delta) : addDays(c, delta * 7));
3009
3175
  }, [view]);
3010
- const goToday = React28.useCallback(() => {
3176
+ const goToday = React29.useCallback(() => {
3011
3177
  setDir(0);
3012
3178
  setCursor(/* @__PURE__ */ new Date());
3013
3179
  }, []);
@@ -3117,9 +3283,9 @@ function SchedulerError({ onRetry }) {
3117
3283
  ] });
3118
3284
  }
3119
3285
  function MonthYearPicker({ label, cursor, onPick }) {
3120
- const [open, setOpen] = React28.useState(false);
3121
- const [viewYear, setViewYear] = React28.useState(cursor.getFullYear());
3122
- React28.useEffect(() => {
3286
+ const [open, setOpen] = React29.useState(false);
3287
+ const [viewYear, setViewYear] = React29.useState(cursor.getFullYear());
3288
+ React29.useEffect(() => {
3123
3289
  if (open) setViewYear(cursor.getFullYear());
3124
3290
  }, [open, cursor]);
3125
3291
  return /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open, onOpenChange: setOpen, children: [
@@ -3182,7 +3348,7 @@ function MonthView({
3182
3348
  onSelectSlot,
3183
3349
  onSelectEvent
3184
3350
  }) {
3185
- const grid = React28.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
3351
+ const grid = React29.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
3186
3352
  const labels = weekdayLabels(weekStartsOn);
3187
3353
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
3188
3354
  /* @__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)) }),
@@ -3238,7 +3404,7 @@ function EventChip({ event, onSelect }) {
3238
3404
  e.stopPropagation();
3239
3405
  onSelect?.(event);
3240
3406
  },
3241
- title: `${event.title} \xB7 ${timeLabel(event.start)}`,
3407
+ title: `${event.title} \xB7 ${timeLabel2(event.start)}`,
3242
3408
  className: "flex items-center gap-1.5 truncate rounded px-1 py-0.5 text-left text-[11px] font-medium text-foreground hover:opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
3243
3409
  children: [
3244
3410
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-full", style: { backgroundColor: color } }),
@@ -3256,11 +3422,11 @@ function WeekView({
3256
3422
  onSelectSlot,
3257
3423
  onSelectEvent
3258
3424
  }) {
3259
- const days = React28.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
3260
- const labels = React28.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
3425
+ const days = React29.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
3426
+ const labels = React29.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
3261
3427
  const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
3262
3428
  const [startHour, endHour] = dayHours;
3263
- const hours = React28.useMemo(
3429
+ const hours = React29.useMemo(
3264
3430
  () => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
3265
3431
  [startHour, endHour]
3266
3432
  );
@@ -3303,7 +3469,7 @@ function WeekView({
3303
3469
  ev.stopPropagation();
3304
3470
  onSelectEvent?.(e);
3305
3471
  },
3306
- title: `${e.title} \xB7 ${timeLabel(e.start)}\u2013${timeLabel(e.end)}`,
3472
+ title: `${e.title} \xB7 ${timeLabel2(e.start)}\u2013${timeLabel2(e.end)}`,
3307
3473
  className: "absolute left-0.5 right-0.5 overflow-hidden rounded-md border px-1.5 py-0.5 text-left text-[11px] leading-tight text-foreground shadow-sm transition-shadow hover:shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
3308
3474
  style: {
3309
3475
  top: Math.max(0, top),
@@ -3313,7 +3479,7 @@ function WeekView({
3313
3479
  },
3314
3480
  children: [
3315
3481
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate font-medium", children: e.title }),
3316
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate", style: { color }, children: timeLabel(e.start) })
3482
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate", style: { color }, children: timeLabel2(e.start) })
3317
3483
  ]
3318
3484
  },
3319
3485
  e.id
@@ -3451,17 +3617,17 @@ function Cart({
3451
3617
  ] })
3452
3618
  ] });
3453
3619
  }
3454
- var CartContext = React28.createContext(null);
3620
+ var CartContext = React29.createContext(null);
3455
3621
  var clampQty = (qty, max) => {
3456
3622
  const lower = Math.max(1, Math.round(qty));
3457
3623
  return max != null ? Math.min(lower, max) : lower;
3458
3624
  };
3459
3625
  function CartProvider({ children, initialItems = [], onChange }) {
3460
- const [items, setItems] = React28.useState(initialItems);
3461
- React28.useEffect(() => {
3626
+ const [items, setItems] = React29.useState(initialItems);
3627
+ React29.useEffect(() => {
3462
3628
  onChange?.(items);
3463
3629
  }, [items]);
3464
- const addToCart = React28.useCallback((item, quantity) => {
3630
+ const addToCart = React29.useCallback((item, quantity) => {
3465
3631
  const addQty = quantity ?? item.quantity ?? 1;
3466
3632
  setItems((prev) => {
3467
3633
  const existing = prev.find((it) => it.id === item.id);
@@ -3474,29 +3640,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
3474
3640
  return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
3475
3641
  });
3476
3642
  }, []);
3477
- const removeFromCart = React28.useCallback((id) => {
3643
+ const removeFromCart = React29.useCallback((id) => {
3478
3644
  setItems((prev) => prev.filter((it) => it.id !== id));
3479
3645
  }, []);
3480
- const updateQuantity = React28.useCallback((id, quantity) => {
3646
+ const updateQuantity = React29.useCallback((id, quantity) => {
3481
3647
  setItems(
3482
3648
  (prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
3483
3649
  );
3484
3650
  }, []);
3485
- const clearCart = React28.useCallback(() => setItems([]), []);
3486
- const isInCart = React28.useCallback((id) => items.some((it) => it.id === id), [items]);
3487
- const getItemCount = React28.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
3488
- const getCartTotal = React28.useCallback(
3651
+ const clearCart = React29.useCallback(() => setItems([]), []);
3652
+ const isInCart = React29.useCallback((id) => items.some((it) => it.id === id), [items]);
3653
+ const getItemCount = React29.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
3654
+ const getCartTotal = React29.useCallback(
3489
3655
  () => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
3490
3656
  [items]
3491
3657
  );
3492
- const value = React28.useMemo(
3658
+ const value = React29.useMemo(
3493
3659
  () => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
3494
3660
  [items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
3495
3661
  );
3496
3662
  return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
3497
3663
  }
3498
3664
  function useCart() {
3499
- const ctx = React28.useContext(CartContext);
3665
+ const ctx = React29.useContext(CartContext);
3500
3666
  if (!ctx) {
3501
3667
  throw new Error("useCart must be used within a <CartProvider>.");
3502
3668
  }
@@ -3830,11 +3996,11 @@ function buildBindings(store, name, kind, snap) {
3830
3996
 
3831
3997
  // src/form/useForm.ts
3832
3998
  function useForm(options = {}) {
3833
- const ref = React28.useRef(null);
3999
+ const ref = React29.useRef(null);
3834
4000
  if (ref.current === null) ref.current = new FormStore(options);
3835
4001
  const store = ref.current;
3836
- React28.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3837
- const make = React28.useCallback(
4002
+ React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
4003
+ const make = React29.useCallback(
3838
4004
  (kind) => (name, rules) => {
3839
4005
  if (rules !== void 0) store.setRule(name, rules);
3840
4006
  return buildBindings(store, name, kind, store.getFieldSnapshot(name));
@@ -3863,9 +4029,9 @@ function useForm(options = {}) {
3863
4029
  fieldTarget: make("target")
3864
4030
  };
3865
4031
  }
3866
- var FormContext = React28.createContext(null);
4032
+ var FormContext = React29.createContext(null);
3867
4033
  function useFormStore() {
3868
- const store = React28.useContext(FormContext);
4034
+ const store = React29.useContext(FormContext);
3869
4035
  if (!store) {
3870
4036
  throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
3871
4037
  }
@@ -3879,8 +4045,8 @@ function Form({
3879
4045
  children,
3880
4046
  ...rest
3881
4047
  }) {
3882
- const ref = React28.useRef(null);
3883
- const bypass = React28.useRef(false);
4048
+ const ref = React29.useRef(null);
4049
+ const bypass = React29.useRef(false);
3884
4050
  const handleSubmit = async (e) => {
3885
4051
  if (bypass.current) {
3886
4052
  bypass.current = false;
@@ -3932,12 +4098,12 @@ function useFormField(name, options = {}) {
3932
4098
  const store = useFormStore();
3933
4099
  const { kind = "value", rules } = options;
3934
4100
  if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
3935
- React28.useEffect(() => {
4101
+ React29.useEffect(() => {
3936
4102
  return () => {
3937
4103
  if (rules !== void 0) store.removeRule(name);
3938
4104
  };
3939
4105
  }, [store, name]);
3940
- const snap = React28.useSyncExternalStore(
4106
+ const snap = React29.useSyncExternalStore(
3941
4107
  store.subscribe,
3942
4108
  () => store.getFieldSnapshot(name)
3943
4109
  );
@@ -3949,7 +4115,7 @@ function FormField({ name, kind, rules, children }) {
3949
4115
  }
3950
4116
  function useFieldArray(name) {
3951
4117
  const store = useFormStore();
3952
- React28.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
4118
+ React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
3953
4119
  const arr = store.getValue(name) ?? [];
3954
4120
  const keys = store.getKeys(name);
3955
4121
  return {
@@ -3982,7 +4148,7 @@ function TextInput({
3982
4148
  suffix,
3983
4149
  id
3984
4150
  }) {
3985
- const errorId = React28.useId();
4151
+ const errorId = React29.useId();
3986
4152
  const hasError = errorMessage != null;
3987
4153
  const hasAdornment = prefix != null || suffix != null;
3988
4154
  const inputId = htmlFor ?? id;
@@ -4143,7 +4309,7 @@ function CreditCardForm({
4143
4309
  className = "",
4144
4310
  style
4145
4311
  }) {
4146
- const initial = React28.useRef({
4312
+ const initial = React29.useRef({
4147
4313
  number: formatCardNumber(defaultValue?.number ?? ""),
4148
4314
  name: defaultValue?.name ?? "",
4149
4315
  expiry: formatExpiry(defaultValue?.expiry ?? ""),
@@ -4152,7 +4318,7 @@ function CreditCardForm({
4152
4318
  const form = useForm({ initialValues: initial });
4153
4319
  const numberStr = String(form.values.number ?? "");
4154
4320
  const brand = detectBrand(numberStr);
4155
- React28.useEffect(() => {
4321
+ React29.useEffect(() => {
4156
4322
  onChange?.(toCard(form.values));
4157
4323
  }, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
4158
4324
  const numberBind = form.fieldNative("number", {
@@ -4275,7 +4441,7 @@ function Checkout({
4275
4441
  ] })
4276
4442
  ] });
4277
4443
  }
4278
- var NotificationContext = React28.createContext({
4444
+ var NotificationContext = React29.createContext({
4279
4445
  open: () => void 0,
4280
4446
  close: () => void 0
4281
4447
  });
@@ -4333,26 +4499,26 @@ function NotificationItem({
4333
4499
  onClose,
4334
4500
  reduced
4335
4501
  }) {
4336
- const [paused, setPaused] = React28.useState(false);
4502
+ const [paused, setPaused] = React29.useState(false);
4337
4503
  const duration = n.duration ?? 4e3;
4338
4504
  const isAutoDismissing = isFinite(duration) && duration > 0;
4339
4505
  const showProgress = !reduced && isAutoDismissing;
4340
- const timerRef = React28.useRef(null);
4341
- const startTimeRef = React28.useRef(0);
4342
- const remainingRef = React28.useRef(duration);
4343
- const clearTimer = React28.useCallback(() => {
4506
+ const timerRef = React29.useRef(null);
4507
+ const startTimeRef = React29.useRef(0);
4508
+ const remainingRef = React29.useRef(duration);
4509
+ const clearTimer = React29.useCallback(() => {
4344
4510
  if (timerRef.current !== null) {
4345
4511
  clearTimeout(timerRef.current);
4346
4512
  timerRef.current = null;
4347
4513
  }
4348
4514
  }, []);
4349
- const scheduleDismiss = React28.useCallback((ms) => {
4515
+ const scheduleDismiss = React29.useCallback((ms) => {
4350
4516
  clearTimer();
4351
4517
  if (!isAutoDismissing) return;
4352
4518
  startTimeRef.current = Date.now();
4353
4519
  timerRef.current = setTimeout(() => onClose(n.id), ms);
4354
4520
  }, [clearTimer, isAutoDismissing, n.id, onClose]);
4355
- React28.useEffect(() => {
4521
+ React29.useEffect(() => {
4356
4522
  if (paused || !isAutoDismissing) return;
4357
4523
  scheduleDismiss(remainingRef.current);
4358
4524
  return clearTimer;
@@ -4435,15 +4601,15 @@ function NotificationProvider({
4435
4601
  children,
4436
4602
  position = "top-right"
4437
4603
  }) {
4438
- const [notifications, setNotifications] = React28.useState([]);
4604
+ const [notifications, setNotifications] = React29.useState([]);
4439
4605
  const reduced = framerMotion.useReducedMotion();
4440
- const open = React28.useCallback((payload) => {
4606
+ const open = React29.useCallback((payload) => {
4441
4607
  setNotifications((prev) => [
4442
4608
  ...prev,
4443
4609
  { duration: 4e3, ...payload, id: Date.now() + Math.random() }
4444
4610
  ]);
4445
4611
  }, []);
4446
- const close = React28.useCallback((id) => {
4612
+ const close = React29.useCallback((id) => {
4447
4613
  setNotifications((prev) => prev.filter((n) => n.id !== id));
4448
4614
  }, []);
4449
4615
  return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
@@ -4472,7 +4638,7 @@ function NotificationProvider({
4472
4638
  ] });
4473
4639
  }
4474
4640
  function useNotification() {
4475
- const { open } = React28.useContext(NotificationContext);
4641
+ const { open } = React29.useContext(NotificationContext);
4476
4642
  return {
4477
4643
  info: (props) => open({ type: "info", ...props }),
4478
4644
  success: (props) => open({ type: "success", ...props }),
@@ -4589,10 +4755,10 @@ function FadingBase({
4589
4755
  isMounted = false,
4590
4756
  children
4591
4757
  }) {
4592
- const [shouldRender, setShouldRender] = React28.useState(isMounted);
4593
- const [visible, setVisible] = React28.useState(false);
4594
- const timerRef = React28.useRef(null);
4595
- React28.useEffect(() => {
4758
+ const [shouldRender, setShouldRender] = React29.useState(isMounted);
4759
+ const [visible, setVisible] = React29.useState(false);
4760
+ const timerRef = React29.useRef(null);
4761
+ React29.useEffect(() => {
4596
4762
  if (isMounted) {
4597
4763
  setShouldRender(true);
4598
4764
  const rafId = requestAnimationFrame(() => setVisible(true));
@@ -4690,8 +4856,8 @@ function ScalableContainer({
4690
4856
  togglePosition = "top-right",
4691
4857
  className = ""
4692
4858
  }) {
4693
- const containerRef = React28.useRef(null);
4694
- const [internalScaled, setInternalScaled] = React28.useState(false);
4859
+ const containerRef = React29.useRef(null);
4860
+ const [internalScaled, setInternalScaled] = React29.useState(false);
4695
4861
  const isScaled = expanded ?? internalScaled;
4696
4862
  const reduced = framerMotion.useReducedMotion();
4697
4863
  const onToggle = () => {
@@ -4829,17 +4995,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
4829
4995
  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)) });
4830
4996
  }
4831
4997
  function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
4832
- const [activeIndex, setActiveIndex] = React28.useState(0);
4833
- const [indexPool, setIndexPool] = React28.useState([]);
4834
- const cardRefs = React28.useRef([]);
4835
- const getIndexes = React28.useMemo(() => {
4998
+ const [activeIndex, setActiveIndex] = React29.useState(0);
4999
+ const [indexPool, setIndexPool] = React29.useState([]);
5000
+ const cardRefs = React29.useRef([]);
5001
+ const getIndexes = React29.useMemo(() => {
4836
5002
  let nextIndex = activeIndex + 1;
4837
5003
  let previousIndex = activeIndex - 1;
4838
5004
  if (activeIndex === 0) previousIndex = items.length - 1;
4839
5005
  if (activeIndex === items.length - 1) nextIndex = 0;
4840
5006
  return { previousIndex, nextIndex };
4841
5007
  }, [activeIndex, items.length]);
4842
- React28.useEffect(() => {
5008
+ React29.useEffect(() => {
4843
5009
  const { nextIndex, previousIndex } = getIndexes;
4844
5010
  let indexes = [previousIndex, activeIndex, nextIndex];
4845
5011
  if (activeIndex !== 0 && activeIndex !== items.length - 1) {
@@ -5012,8 +5178,8 @@ function writeDismissed(key) {
5012
5178
  }
5013
5179
  }
5014
5180
  function useTargetBbox(ref) {
5015
- const [bbox, setBbox] = React28.useState(null);
5016
- React28.useLayoutEffect(() => {
5181
+ const [bbox, setBbox] = React29.useState(null);
5182
+ React29.useLayoutEffect(() => {
5017
5183
  const el = ref?.current;
5018
5184
  if (!el) {
5019
5185
  setBbox(null);
@@ -5043,7 +5209,7 @@ function tooltipStyleFor(bbox, placement) {
5043
5209
  return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
5044
5210
  }
5045
5211
  function useFocusTrap(containerRef, active) {
5046
- React28.useEffect(() => {
5212
+ React29.useEffect(() => {
5047
5213
  if (!active) return;
5048
5214
  const el = containerRef.current;
5049
5215
  if (!el) return;
@@ -5082,16 +5248,16 @@ function Wizard({
5082
5248
  onComplete,
5083
5249
  onSkip
5084
5250
  }) {
5085
- const tooltipRef = React28.useRef(null);
5086
- const tooltipTitleId = React28.useId();
5087
- const tooltipBodyId = React28.useId();
5251
+ const tooltipRef = React29.useRef(null);
5252
+ const tooltipTitleId = React29.useId();
5253
+ const tooltipBodyId = React29.useId();
5088
5254
  const reduced = framerMotion.useReducedMotion();
5089
- const [open, setOpen] = React28.useState(() => steps.length > 0 && !readDismissed(storageKey));
5090
- const [activeIndex, setActiveIndex] = React28.useState(0);
5255
+ const [open, setOpen] = React29.useState(() => steps.length > 0 && !readDismissed(storageKey));
5256
+ const [activeIndex, setActiveIndex] = React29.useState(0);
5091
5257
  const step = steps[activeIndex];
5092
5258
  const bbox = useTargetBbox(step?.stepRef);
5093
5259
  useFocusTrap(tooltipRef, open);
5094
- React28.useEffect(() => {
5260
+ React29.useEffect(() => {
5095
5261
  if (!open || !dismissible) return;
5096
5262
  const onKey = (e) => {
5097
5263
  if (e.key === "Escape") {
@@ -5102,12 +5268,12 @@ function Wizard({
5102
5268
  document.addEventListener("keydown", onKey);
5103
5269
  return () => document.removeEventListener("keydown", onKey);
5104
5270
  }, [open, dismissible]);
5105
- const handleSkip = React28.useCallback(() => {
5271
+ const handleSkip = React29.useCallback(() => {
5106
5272
  writeDismissed(storageKey);
5107
5273
  setOpen(false);
5108
5274
  onSkip?.();
5109
5275
  }, [storageKey, onSkip]);
5110
- const handleComplete = React28.useCallback(() => {
5276
+ const handleComplete = React29.useCallback(() => {
5111
5277
  writeDismissed(storageKey);
5112
5278
  setOpen(false);
5113
5279
  onComplete?.();
@@ -5250,7 +5416,7 @@ function Wizard({
5250
5416
  ] });
5251
5417
  }
5252
5418
  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" }) });
5253
- 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) {
5419
+ 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) {
5254
5420
  return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
5255
5421
  "div",
5256
5422
  {
@@ -5434,7 +5600,7 @@ function TableBody({
5434
5600
  expandRow,
5435
5601
  getRowKey
5436
5602
  }) {
5437
- const [expanded, setExpanded] = React28.useState(() => /* @__PURE__ */ new Set());
5603
+ const [expanded, setExpanded] = React29.useState(() => /* @__PURE__ */ new Set());
5438
5604
  const reduced = framerMotion.useReducedMotion();
5439
5605
  const toggleRow = (rowKey) => {
5440
5606
  setExpanded((prev) => {
@@ -5449,7 +5615,7 @@ function TableBody({
5449
5615
  return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
5450
5616
  const rowKey = getRowKey(row, i);
5451
5617
  const isExpanded = expanded.has(rowKey);
5452
- return /* @__PURE__ */ jsxRuntime.jsxs(React28__default.default.Fragment, { children: [
5618
+ return /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
5453
5619
  /* @__PURE__ */ jsxRuntime.jsxs(
5454
5620
  "tr",
5455
5621
  {
@@ -5505,9 +5671,9 @@ function Pagination({
5505
5671
  const matchedOption = picker.find(
5506
5672
  (o) => o.label === options.perPage || o.value === options.perPage
5507
5673
  );
5508
- const [perPageKey, setPerPageKey] = React28.useState(() => matchedOption?.key ?? picker[0]?.key);
5674
+ const [perPageKey, setPerPageKey] = React29.useState(() => matchedOption?.key ?? picker[0]?.key);
5509
5675
  const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
5510
- React28.useEffect(() => {
5676
+ React29.useEffect(() => {
5511
5677
  if (serverSide && options.perPage != null) {
5512
5678
  const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
5513
5679
  if (next) setPerPageKey(next.key);
@@ -5570,14 +5736,14 @@ function Table({
5570
5736
  className = "",
5571
5737
  style
5572
5738
  }) {
5573
- const searchRef = React28.useRef(null);
5574
- const [searchTerm, setSearchTerm] = React28.useState("");
5575
- const [perPage, setPerPage] = React28.useState(
5739
+ const searchRef = React29.useRef(null);
5740
+ const [searchTerm, setSearchTerm] = React29.useState("");
5741
+ const [perPage, setPerPage] = React29.useState(
5576
5742
  typeof pagination.perPage === "number" ? pagination.perPage : 15
5577
5743
  );
5578
- const [activePage, setActivePage] = React28.useState(0);
5744
+ const [activePage, setActivePage] = React29.useState(0);
5579
5745
  const isServerSide = !!(pagination.enabled && pagination.serverSide);
5580
- const filteredRows = React28.useMemo(() => {
5746
+ const filteredRows = React29.useMemo(() => {
5581
5747
  if (isServerSide || !searchTerm) return rows;
5582
5748
  const term = searchTerm.toLowerCase();
5583
5749
  return rows.filter(
@@ -5586,29 +5752,29 @@ function Table({
5586
5752
  )
5587
5753
  );
5588
5754
  }, [rows, searchTerm, isServerSide]);
5589
- const datasets = React28.useMemo(() => {
5755
+ const datasets = React29.useMemo(() => {
5590
5756
  if (isServerSide) return [rows];
5591
5757
  return createDatasets(filteredRows, pagination.enabled ? perPage : null);
5592
5758
  }, [filteredRows, perPage, pagination.enabled, isServerSide, rows]);
5593
- const MAX_PAGE = React28.useMemo(() => {
5759
+ const MAX_PAGE = React29.useMemo(() => {
5594
5760
  if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
5595
5761
  if (isServerSide && typeof pagination.totalCount === "number")
5596
5762
  return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
5597
5763
  return datasets.length ? datasets.length - 1 : 0;
5598
5764
  }, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
5599
- const currentPageRows = React28.useMemo(() => {
5765
+ const currentPageRows = React29.useMemo(() => {
5600
5766
  if (isServerSide) return rows;
5601
5767
  return datasets[activePage] ?? [];
5602
5768
  }, [isServerSide, rows, datasets, activePage]);
5603
- React28.useEffect(() => {
5769
+ React29.useEffect(() => {
5604
5770
  if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
5605
5771
  setPerPage(pagination.perPage);
5606
5772
  }
5607
5773
  }, [pagination.enabled, pagination.perPage, isServerSide]);
5608
- React28.useEffect(() => {
5774
+ React29.useEffect(() => {
5609
5775
  if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
5610
5776
  }, [isServerSide, pagination.perPage]);
5611
- React28.useEffect(() => {
5777
+ React29.useEffect(() => {
5612
5778
  if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
5613
5779
  setActivePage(pagination.page - 1);
5614
5780
  }, [isServerSide, pagination.page]);
@@ -5692,7 +5858,7 @@ function TableSkeletonBody({
5692
5858
  )) });
5693
5859
  }
5694
5860
  function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
5695
- const id = React28.useId();
5861
+ const id = React29.useId();
5696
5862
  return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
5697
5863
  SwitchPrimitive__namespace.Root,
5698
5864
  {
@@ -5876,7 +6042,7 @@ function Sidebar({
5876
6042
  }
5877
6043
  ) });
5878
6044
  }
5879
- var MegaMenuContext = React28.createContext({ align: "start" });
6045
+ var MegaMenuContext = React29.createContext({ align: "start" });
5880
6046
  function MegaMenu({
5881
6047
  children,
5882
6048
  align = "start",
@@ -5907,7 +6073,7 @@ function MegaMenu({
5907
6073
  }
5908
6074
  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";
5909
6075
  function MegaMenuItem({ label, icon, href, children, className = "" }) {
5910
- const { align } = React28.useContext(MegaMenuContext);
6076
+ const { align } = React29.useContext(MegaMenuContext);
5911
6077
  const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
5912
6078
  if (!children) {
5913
6079
  return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: [TOP_ITEM, className].filter(Boolean).join(" "), children: [
@@ -5992,8 +6158,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
5992
6158
  function MegaMenuFeatured({ children, className = "" }) {
5993
6159
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
5994
6160
  }
5995
- var elementsOfType = (children, type) => React28__default.default.Children.toArray(children).filter(
5996
- (c) => React28__default.default.isValidElement(c) && c.type === type
6161
+ var elementsOfType = (children, type) => React29__default.default.Children.toArray(children).filter(
6162
+ (c) => React29__default.default.isValidElement(c) && c.type === type
5997
6163
  );
5998
6164
  var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
5999
6165
  "svg",
@@ -6030,9 +6196,9 @@ function MobileLinkRow({ link, onNavigate }) {
6030
6196
  );
6031
6197
  }
6032
6198
  function MobilePanel({ panel, onNavigate }) {
6033
- const nodes = React28__default.default.Children.toArray(panel.props.children);
6199
+ const nodes = React29__default.default.Children.toArray(panel.props.children);
6034
6200
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
6035
- if (!React28__default.default.isValidElement(node)) return null;
6201
+ if (!React29__default.default.isValidElement(node)) return null;
6036
6202
  const el = node;
6037
6203
  if (el.type === MegaMenuSection) {
6038
6204
  const { title, children } = el.props;
@@ -6051,8 +6217,8 @@ function MegaMenuMobile({
6051
6217
  children,
6052
6218
  label
6053
6219
  }) {
6054
- const [open, setOpen] = React28.useState(false);
6055
- const [expanded, setExpanded] = React28.useState(null);
6220
+ const [open, setOpen] = React29.useState(false);
6221
+ const [expanded, setExpanded] = React29.useState(null);
6056
6222
  const items = elementsOfType(children, MegaMenuItem);
6057
6223
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
6058
6224
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6125,17 +6291,17 @@ function AppShell({
6125
6291
  children,
6126
6292
  className = ""
6127
6293
  }) {
6128
- const [expanded, setExpanded] = React28.useState(sidebarDefaultExpanded);
6129
- const [isMobile, setIsMobile] = React28.useState(false);
6130
- const [mobileOpen, setMobileOpen] = React28.useState(false);
6131
- React28.useEffect(() => {
6294
+ const [expanded, setExpanded] = React29.useState(sidebarDefaultExpanded);
6295
+ const [isMobile, setIsMobile] = React29.useState(false);
6296
+ const [mobileOpen, setMobileOpen] = React29.useState(false);
6297
+ React29.useEffect(() => {
6132
6298
  const mq = window.matchMedia("(max-width: 767px)");
6133
6299
  const update = (e) => setIsMobile(e.matches);
6134
6300
  update(mq);
6135
6301
  mq.addEventListener("change", update);
6136
6302
  return () => mq.removeEventListener("change", update);
6137
6303
  }, []);
6138
- React28.useEffect(() => {
6304
+ React29.useEffect(() => {
6139
6305
  if (!isMobile) setMobileOpen(false);
6140
6306
  }, [isMobile]);
6141
6307
  const hasSidebar = sidebarSections.length > 0;
@@ -6262,7 +6428,7 @@ function SecureLayout({
6262
6428
  className = ""
6263
6429
  }) {
6264
6430
  const reduced = framerMotion.useReducedMotion();
6265
- const cbs = React28.useRef({ canAccess, onGranted, onDeny });
6431
+ const cbs = React29.useRef({ canAccess, onGranted, onDeny });
6266
6432
  cbs.current = { canAccess, onGranted, onDeny };
6267
6433
  const rolesKey = JSON.stringify(roles);
6268
6434
  const requiredRolesKey = JSON.stringify(requiredRoles);
@@ -6277,10 +6443,10 @@ function SecureLayout({
6277
6443
  if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
6278
6444
  return true;
6279
6445
  };
6280
- const [state, setState] = React28.useState(
6446
+ const [state, setState] = React29.useState(
6281
6447
  () => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
6282
6448
  );
6283
- React28.useEffect(() => {
6449
+ React29.useEffect(() => {
6284
6450
  let cancelled = false;
6285
6451
  const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
6286
6452
  const finish = (ok) => {
@@ -6441,10 +6607,10 @@ function ThemeProvider({
6441
6607
  className = "",
6442
6608
  style
6443
6609
  }) {
6444
- const id = React28__default.default.useId().replace(/:/g, "");
6610
+ const id = React29__default.default.useId().replace(/:/g, "");
6445
6611
  const scopeClass = `geo-th-${id}`;
6446
- const divRef = React28.useRef(null);
6447
- React28.useEffect(() => {
6612
+ const divRef = React29.useRef(null);
6613
+ React29.useEffect(() => {
6448
6614
  const el = divRef.current;
6449
6615
  if (!el) return;
6450
6616
  if (colorScheme === "auto") return;
@@ -6459,8 +6625,8 @@ function ThemeProvider({
6459
6625
  }
6460
6626
  el.classList.toggle("dark", colorScheme === "dark");
6461
6627
  }, [colorScheme]);
6462
- const lightVars = React28.useMemo(() => toCssVars(theme), [theme]);
6463
- const darkVarStr = React28.useMemo(() => {
6628
+ const lightVars = React29.useMemo(() => toCssVars(theme), [theme]);
6629
+ const darkVarStr = React29.useMemo(() => {
6464
6630
  if (!darkTheme) return "";
6465
6631
  const dvars = toCssVars(darkTheme);
6466
6632
  if (!Object.keys(dvars).length) return "";
@@ -6502,7 +6668,7 @@ function NumberInput({
6502
6668
  readOnly = false,
6503
6669
  precision
6504
6670
  }) {
6505
- const errorId = React28.useId();
6671
+ const errorId = React29.useId();
6506
6672
  const hasError = errorMessage != null;
6507
6673
  const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
6508
6674
  const round = (n) => {
@@ -6633,8 +6799,8 @@ function Password({
6633
6799
  showIcon,
6634
6800
  hideIcon
6635
6801
  }) {
6636
- const [visible, setVisible] = React28.useState(false);
6637
- const errorId = React28.useId();
6802
+ const [visible, setVisible] = React29.useState(false);
6803
+ const errorId = React29.useId();
6638
6804
  const hasError = errorMessage != null;
6639
6805
  return /* @__PURE__ */ jsxRuntime.jsx(
6640
6806
  Field,
@@ -6707,7 +6873,7 @@ function Checkbox({
6707
6873
  }) {
6708
6874
  const isChecked = checked ?? value ?? false;
6709
6875
  const labelFirst = labelPosition === "left";
6710
- const errorId = React28.useId();
6876
+ const errorId = React29.useId();
6711
6877
  const hasError = errorMessage != null;
6712
6878
  const box = /* @__PURE__ */ jsxRuntime.jsx(
6713
6879
  CheckboxPrimitive__namespace.Root,
@@ -6815,8 +6981,8 @@ function RadioGroup({
6815
6981
  className,
6816
6982
  errorMessage
6817
6983
  }) {
6818
- const errorId = React28.useId();
6819
- const groupId = React28.useId();
6984
+ const errorId = React29.useId();
6985
+ const groupId = React29.useId();
6820
6986
  const hasError = errorMessage != null;
6821
6987
  const labelFirst = labelPosition === "left";
6822
6988
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -6916,11 +7082,11 @@ function Switch({
6916
7082
  disabled,
6917
7083
  errorMessage
6918
7084
  }) {
6919
- const id = React28.useId();
6920
- const errorId = React28.useId();
7085
+ const id = React29.useId();
7086
+ const errorId = React29.useId();
6921
7087
  const hasError = errorMessage != null;
6922
7088
  const isControlled = checked !== void 0;
6923
- const [internal, setInternal] = React28.useState(defaultChecked);
7089
+ const [internal, setInternal] = React29.useState(defaultChecked);
6924
7090
  const isOn = isControlled ? checked : internal;
6925
7091
  const handle = (c) => {
6926
7092
  if (!isControlled) setInternal(c);
@@ -6996,11 +7162,11 @@ function MultiTagRow({
6996
7162
  labelFor,
6997
7163
  onRemove
6998
7164
  }) {
6999
- const wrapRef = React28.useRef(null);
7000
- const measureRef = React28.useRef(null);
7001
- const [visibleCount, setVisibleCount] = React28.useState(values.length);
7165
+ const wrapRef = React29.useRef(null);
7166
+ const measureRef = React29.useRef(null);
7167
+ const [visibleCount, setVisibleCount] = React29.useState(values.length);
7002
7168
  const key = values.map(String).join("|");
7003
- React28.useLayoutEffect(() => {
7169
+ React29.useLayoutEffect(() => {
7004
7170
  const wrap = wrapRef.current;
7005
7171
  const measure = measureRef.current;
7006
7172
  if (!wrap || !measure) return;
@@ -7094,16 +7260,16 @@ function Dropdown({
7094
7260
  size = "md",
7095
7261
  className = ""
7096
7262
  }) {
7097
- const [open, setOpen] = React28.useState(false);
7098
- const [selectedItems, setSelectedItems] = React28.useState([]);
7099
- const [searchTerm, setSearchTerm] = React28.useState("");
7100
- const [innerItems, setInnerItems] = React28.useState([]);
7101
- const errorId = React28.useId();
7263
+ const [open, setOpen] = React29.useState(false);
7264
+ const [selectedItems, setSelectedItems] = React29.useState([]);
7265
+ const [searchTerm, setSearchTerm] = React29.useState("");
7266
+ const [innerItems, setInnerItems] = React29.useState([]);
7267
+ const errorId = React29.useId();
7102
7268
  const hasError = errorMessage != null;
7103
- React28.useEffect(() => {
7269
+ React29.useEffect(() => {
7104
7270
  setInnerItems(items);
7105
7271
  }, [items]);
7106
- React28.useEffect(() => {
7272
+ React29.useEffect(() => {
7107
7273
  if (isMultiselect && Array.isArray(value)) {
7108
7274
  setSelectedItems(value);
7109
7275
  }
@@ -7295,19 +7461,19 @@ function AutoComplete({
7295
7461
  required,
7296
7462
  htmlFor
7297
7463
  }) {
7298
- const errorId = React28.useId();
7464
+ const errorId = React29.useId();
7299
7465
  const hasError = errorMessage != null;
7300
- const [term, setTerm] = React28.useState("");
7301
- const [open, setOpen] = React28.useState(false);
7302
- const [asyncItems, setAsyncItems] = React28.useState([]);
7303
- const [loading, setLoading] = React28.useState(false);
7466
+ const [term, setTerm] = React29.useState("");
7467
+ const [open, setOpen] = React29.useState(false);
7468
+ const [asyncItems, setAsyncItems] = React29.useState([]);
7469
+ const [loading, setLoading] = React29.useState(false);
7304
7470
  const isAsync = typeof onSearch === "function";
7305
- const debounceRef = React28.useRef(null);
7306
- const requestIdRef = React28.useRef(0);
7471
+ const debounceRef = React29.useRef(null);
7472
+ const requestIdRef = React29.useRef(0);
7307
7473
  const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
7308
7474
  ({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
7309
7475
  ) : [];
7310
- React28.useEffect(() => {
7476
+ React29.useEffect(() => {
7311
7477
  if (!isAsync) return;
7312
7478
  if (debounceRef.current) clearTimeout(debounceRef.current);
7313
7479
  if (!term.trim()) {
@@ -7463,15 +7629,15 @@ function TreeSelect({
7463
7629
  defaultExpandedKeys = [],
7464
7630
  size = "md"
7465
7631
  }) {
7466
- const errorId = React28.useId();
7632
+ const errorId = React29.useId();
7467
7633
  const hasError = errorMessage != null;
7468
- const [open, setOpen] = React28.useState(false);
7469
- const [expanded, setExpanded] = React28.useState(() => new Set(defaultExpandedKeys));
7470
- const [activeIndex, setActiveIndex] = React28.useState(0);
7471
- const listRef = React28.useRef(null);
7472
- const visible = React28.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
7473
- const didSyncOnOpenRef = React28.useRef(false);
7474
- React28.useEffect(() => {
7634
+ const [open, setOpen] = React29.useState(false);
7635
+ const [expanded, setExpanded] = React29.useState(() => new Set(defaultExpandedKeys));
7636
+ const [activeIndex, setActiveIndex] = React29.useState(0);
7637
+ const listRef = React29.useRef(null);
7638
+ const visible = React29.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
7639
+ const didSyncOnOpenRef = React29.useRef(false);
7640
+ React29.useEffect(() => {
7475
7641
  if (!open) {
7476
7642
  didSyncOnOpenRef.current = false;
7477
7643
  return;
@@ -7481,7 +7647,7 @@ function TreeSelect({
7481
7647
  setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
7482
7648
  didSyncOnOpenRef.current = true;
7483
7649
  }, [open, value]);
7484
- const selectedNode = React28.useMemo(
7650
+ const selectedNode = React29.useMemo(
7485
7651
  () => value != null ? findNodeByKey(items, value) : null,
7486
7652
  [items, value]
7487
7653
  );
@@ -7712,11 +7878,11 @@ function FileInput({
7712
7878
  required,
7713
7879
  icon
7714
7880
  }) {
7715
- const inputRef = React28.useRef(null);
7716
- const errorId = React28.useId();
7717
- const [files, setFiles] = React28.useState([]);
7718
- const [dragging, setDragging] = React28.useState(false);
7719
- const [sizeError, setSizeError] = React28.useState(null);
7881
+ const inputRef = React29.useRef(null);
7882
+ const errorId = React29.useId();
7883
+ const [files, setFiles] = React29.useState([]);
7884
+ const [dragging, setDragging] = React29.useState(false);
7885
+ const [sizeError, setSizeError] = React29.useState(null);
7720
7886
  const effectiveError = errorMessage ?? sizeError ?? void 0;
7721
7887
  const openPicker = () => {
7722
7888
  if (!disabled) inputRef.current?.click();
@@ -7907,30 +8073,30 @@ function DatePicker({
7907
8073
  size = "md",
7908
8074
  className = ""
7909
8075
  }) {
7910
- const errorId = React28.useId();
8076
+ const errorId = React29.useId();
7911
8077
  const hasError = errorMessage != null;
7912
- const [open, setOpen] = React28.useState(false);
7913
- const [viewMonth, setViewMonth] = React28.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
7914
- const [focusDate, setFocusDate] = React28.useState(() => value ?? /* @__PURE__ */ new Date());
7915
- const [view, setView] = React28.useState("days");
7916
- const gridRef = React28.useRef(null);
7917
- React28.useEffect(() => {
8078
+ const [open, setOpen] = React29.useState(false);
8079
+ const [viewMonth, setViewMonth] = React29.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
8080
+ const [focusDate, setFocusDate] = React29.useState(() => value ?? /* @__PURE__ */ new Date());
8081
+ const [view, setView] = React29.useState("days");
8082
+ const gridRef = React29.useRef(null);
8083
+ React29.useEffect(() => {
7918
8084
  if (!open) return;
7919
8085
  const target = value ?? /* @__PURE__ */ new Date();
7920
8086
  setViewMonth(startOfMonth2(target));
7921
8087
  setFocusDate(target);
7922
8088
  setView("days");
7923
8089
  }, [open, value]);
7924
- React28.useEffect(() => {
8090
+ React29.useEffect(() => {
7925
8091
  if (!open) return;
7926
8092
  const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
7927
8093
  cell?.focus();
7928
8094
  }, [open, focusDate]);
7929
- const weekdays = React28.useMemo(() => {
8095
+ const weekdays = React29.useMemo(() => {
7930
8096
  const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
7931
8097
  return ordered;
7932
8098
  }, [weekStartsOn]);
7933
- const grid = React28.useMemo(() => buildGrid2(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
8099
+ const grid = React29.useMemo(() => buildGrid2(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
7934
8100
  const isDisabled = (d) => {
7935
8101
  if (min && d < min) return true;
7936
8102
  if (max && d > max) return true;
@@ -8220,10 +8386,10 @@ function TextArea({
8220
8386
  style,
8221
8387
  inputStyle
8222
8388
  }) {
8223
- const errorId = React28.useId();
8389
+ const errorId = React29.useId();
8224
8390
  const hasError = errorMessage != null;
8225
- const ref = React28.useRef(null);
8226
- React28.useLayoutEffect(() => {
8391
+ const ref = React29.useRef(null);
8392
+ React29.useLayoutEffect(() => {
8227
8393
  if (!autoGrow) return;
8228
8394
  const el = ref.current;
8229
8395
  if (!el) return;
@@ -8295,14 +8461,14 @@ function Slider({
8295
8461
  name,
8296
8462
  htmlFor
8297
8463
  }) {
8298
- const errorId = React28.useId();
8464
+ const errorId = React29.useId();
8299
8465
  const hasError = errorMessage != null;
8300
8466
  const isRange = Array.isArray(value ?? defaultValue);
8301
- const [internal, setInternal] = React28.useState(
8467
+ const [internal, setInternal] = React29.useState(
8302
8468
  () => toArray(value) ?? toArray(defaultValue) ?? [min]
8303
8469
  );
8304
8470
  const current = toArray(value) ?? internal;
8305
- const [dragging, setDragging] = React28.useState(false);
8471
+ const [dragging, setDragging] = React29.useState(false);
8306
8472
  const emit = (arr) => {
8307
8473
  setInternal(arr);
8308
8474
  const next = isRange ? [arr[0], arr[1]] : arr[0];
@@ -8397,11 +8563,11 @@ function TagsInput({
8397
8563
  validate,
8398
8564
  separators = ["Enter", ","]
8399
8565
  }) {
8400
- const errorId = React28.useId();
8401
- const inputRef = React28.useRef(null);
8402
- const [internal, setInternal] = React28.useState(defaultValue ?? []);
8403
- const [draft, setDraft] = React28.useState("");
8404
- const [localError, setLocalError] = React28.useState(null);
8566
+ const errorId = React29.useId();
8567
+ const inputRef = React29.useRef(null);
8568
+ const [internal, setInternal] = React29.useState(defaultValue ?? []);
8569
+ const [draft, setDraft] = React29.useState("");
8570
+ const [localError, setLocalError] = React29.useState(null);
8405
8571
  const tags = value ?? internal;
8406
8572
  const hasError = errorMessage != null || localError != null;
8407
8573
  const errorText = errorMessage ?? localError ?? void 0;
@@ -8532,9 +8698,9 @@ function OtpInput({
8532
8698
  className,
8533
8699
  groupAfter
8534
8700
  }) {
8535
- const errorId = React28.useId();
8701
+ const errorId = React29.useId();
8536
8702
  const hasError = errorMessage != null;
8537
- const refs = React28.useRef([]);
8703
+ const refs = React29.useRef([]);
8538
8704
  const chars = Array.from({ length }, (_, i) => value[i] ?? "");
8539
8705
  const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
8540
8706
  const emit = (next) => {
@@ -8583,7 +8749,7 @@ function OtpInput({
8583
8749
  emit(valid.join(""));
8584
8750
  focusBox(valid.length);
8585
8751
  };
8586
- 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: [
8752
+ 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: [
8587
8753
  /* @__PURE__ */ jsxRuntime.jsx(
8588
8754
  "input",
8589
8755
  {
@@ -8641,9 +8807,9 @@ function Rating({
8641
8807
  className,
8642
8808
  required
8643
8809
  }) {
8644
- const errorId = React28.useId();
8645
- const [internal, setInternal] = React28.useState(defaultValue);
8646
- const [hover, setHover] = React28.useState(null);
8810
+ const errorId = React29.useId();
8811
+ const [internal, setInternal] = React29.useState(defaultValue);
8812
+ const [hover, setHover] = React29.useState(null);
8647
8813
  const current = value ?? internal;
8648
8814
  const display2 = hover ?? current;
8649
8815
  const interactive = !readOnly && !disabled;
@@ -8766,9 +8932,9 @@ function TimePicker({
8766
8932
  required,
8767
8933
  style
8768
8934
  }) {
8769
- const errorId = React28.useId();
8935
+ const errorId = React29.useId();
8770
8936
  const hasError = errorMessage != null;
8771
- const [open, setOpen] = React28.useState(false);
8937
+ const [open, setOpen] = React29.useState(false);
8772
8938
  const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
8773
8939
  const update = (next) => {
8774
8940
  const merged = { ...parsed, ...next };
@@ -8892,13 +9058,13 @@ function DateRangePicker({
8892
9058
  required,
8893
9059
  style
8894
9060
  }) {
8895
- const errorId = React28.useId();
9061
+ const errorId = React29.useId();
8896
9062
  const hasError = errorMessage != null;
8897
- const [open, setOpen] = React28.useState(false);
8898
- const [leftMonth, setLeftMonth] = React28.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
8899
- const [pendingStart, setPendingStart] = React28.useState(null);
8900
- const [hoverDate, setHoverDate] = React28.useState(null);
8901
- const weekdays = React28.useMemo(
9063
+ const [open, setOpen] = React29.useState(false);
9064
+ const [leftMonth, setLeftMonth] = React29.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
9065
+ const [pendingStart, setPendingStart] = React29.useState(null);
9066
+ const [hoverDate, setHoverDate] = React29.useState(null);
9067
+ const weekdays = React29.useMemo(
8902
9068
  () => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
8903
9069
  [weekStartsOn]
8904
9070
  );
@@ -9074,10 +9240,10 @@ function ColorPicker({
9074
9240
  required,
9075
9241
  placeholder = "Pick a colour\u2026"
9076
9242
  }) {
9077
- const errorId = React28.useId();
9243
+ const errorId = React29.useId();
9078
9244
  const hasError = errorMessage != null;
9079
- const [open, setOpen] = React28.useState(false);
9080
- const [draft, setDraft] = React28.useState(value);
9245
+ const [open, setOpen] = React29.useState(false);
9246
+ const [draft, setDraft] = React29.useState(value);
9081
9247
  const valid = HEX_RE.test(value);
9082
9248
  const pick = (hex) => {
9083
9249
  onChange?.(hex);
@@ -9164,7 +9330,7 @@ function ColorPicker({
9164
9330
  }
9165
9331
  var CUSTOM_EVENT = "oxy-local-storage";
9166
9332
  function useLocalStorage(key, initialValue) {
9167
- const read = React28.useCallback(() => {
9333
+ const read = React29.useCallback(() => {
9168
9334
  if (typeof window === "undefined") return initialValue;
9169
9335
  try {
9170
9336
  const item = window.localStorage.getItem(key);
@@ -9173,8 +9339,8 @@ function useLocalStorage(key, initialValue) {
9173
9339
  return initialValue;
9174
9340
  }
9175
9341
  }, [key]);
9176
- const [stored, setStored] = React28.useState(read);
9177
- const setValue = React28.useCallback((value) => {
9342
+ const [stored, setStored] = React29.useState(read);
9343
+ const setValue = React29.useCallback((value) => {
9178
9344
  setStored((prev) => {
9179
9345
  const next = value instanceof Function ? value(prev) : value;
9180
9346
  try {
@@ -9187,7 +9353,7 @@ function useLocalStorage(key, initialValue) {
9187
9353
  return next;
9188
9354
  });
9189
9355
  }, [key]);
9190
- const remove = React28.useCallback(() => {
9356
+ const remove = React29.useCallback(() => {
9191
9357
  try {
9192
9358
  if (typeof window !== "undefined") {
9193
9359
  window.localStorage.removeItem(key);
@@ -9197,10 +9363,10 @@ function useLocalStorage(key, initialValue) {
9197
9363
  }
9198
9364
  setStored(initialValue);
9199
9365
  }, [key]);
9200
- React28.useEffect(() => {
9366
+ React29.useEffect(() => {
9201
9367
  setStored(read());
9202
9368
  }, [key, read]);
9203
- React28.useEffect(() => {
9369
+ React29.useEffect(() => {
9204
9370
  if (typeof window === "undefined") return;
9205
9371
  const onStorage = (e) => {
9206
9372
  if (e.key === null || e.key === key) setStored(read());
@@ -9219,8 +9385,8 @@ function useLocalStorage(key, initialValue) {
9219
9385
  }
9220
9386
  function useMediaQuery(query) {
9221
9387
  const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
9222
- const [matches, setMatches] = React28.useState(get);
9223
- React28.useEffect(() => {
9388
+ const [matches, setMatches] = React29.useState(get);
9389
+ React29.useEffect(() => {
9224
9390
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
9225
9391
  const mql = window.matchMedia(query);
9226
9392
  const onChange = () => setMatches(mql.matches);
@@ -9251,8 +9417,8 @@ function decodeSegment(seg) {
9251
9417
  }
9252
9418
  }
9253
9419
  function useJwt(token) {
9254
- const [, tick] = React28.useState(0);
9255
- const decoded = React28.useMemo(() => {
9420
+ const [, tick] = React29.useState(0);
9421
+ const decoded = React29.useMemo(() => {
9256
9422
  if (!token) return { payload: null, header: null, exp: null };
9257
9423
  const [h, p] = token.split(".");
9258
9424
  const header = decodeSegment(h);
@@ -9260,7 +9426,7 @@ function useJwt(token) {
9260
9426
  const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
9261
9427
  return { payload, header, exp };
9262
9428
  }, [token]);
9263
- React28.useEffect(() => {
9429
+ React29.useEffect(() => {
9264
9430
  if (decoded.exp == null) return;
9265
9431
  const ms = decoded.exp * 1e3 - Date.now();
9266
9432
  if (ms <= 0) return;
@@ -9307,6 +9473,7 @@ exports.CartProvider = CartProvider;
9307
9473
  exports.Catalog = Catalog;
9308
9474
  exports.CatalogCarousel = CatalogCarousel;
9309
9475
  exports.CatalogGrid = CatalogGrid;
9476
+ exports.Chat = Chat;
9310
9477
  exports.Checkbox = Checkbox;
9311
9478
  exports.Checkout = Checkout;
9312
9479
  exports.ColorPicker = ColorPicker;