@camstack/ui-library 0.1.35 → 0.1.36

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
@@ -1006,31 +1006,111 @@ function TooltipContent({ className, children, ...props }) {
1006
1006
  }
1007
1007
 
1008
1008
  // src/primitives/popover.tsx
1009
+ var import_react19 = require("react");
1010
+
1011
+ // src/hooks/use-is-mobile.ts
1009
1012
  var import_react17 = require("react");
1013
+ var MOBILE_QUERY = "(max-width: 767px)";
1014
+ function subscribe(callback) {
1015
+ const mql = window.matchMedia(MOBILE_QUERY);
1016
+ mql.addEventListener("change", callback);
1017
+ return () => mql.removeEventListener("change", callback);
1018
+ }
1019
+ function getSnapshot() {
1020
+ return window.matchMedia(MOBILE_QUERY).matches;
1021
+ }
1022
+ function getServerSnapshot() {
1023
+ return false;
1024
+ }
1025
+ function useIsMobile() {
1026
+ return (0, import_react17.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
1027
+ }
1028
+
1029
+ // src/primitives/bottom-sheet.tsx
1030
+ var import_react18 = require("react");
1031
+ var import_lucide_react4 = require("lucide-react");
1010
1032
  var import_jsx_runtime16 = require("react/jsx-runtime");
1011
- var PopoverContext = (0, import_react17.createContext)(null);
1033
+ function BottomSheet({ open, onClose, title, children, className }) {
1034
+ (0, import_react18.useEffect)(() => {
1035
+ if (!open) return;
1036
+ const handleKeyDown = (e) => {
1037
+ if (e.key === "Escape") onClose();
1038
+ };
1039
+ document.addEventListener("keydown", handleKeyDown);
1040
+ document.body.style.overflow = "hidden";
1041
+ return () => {
1042
+ document.removeEventListener("keydown", handleKeyDown);
1043
+ document.body.style.overflow = "";
1044
+ };
1045
+ }, [open, onClose]);
1046
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1047
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1048
+ "div",
1049
+ {
1050
+ className: cn(
1051
+ "fixed inset-0 z-40 bg-black/50 transition-opacity duration-200",
1052
+ open ? "opacity-100" : "pointer-events-none opacity-0"
1053
+ ),
1054
+ onClick: onClose,
1055
+ "aria-hidden": "true"
1056
+ }
1057
+ ),
1058
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1059
+ "div",
1060
+ {
1061
+ role: "dialog",
1062
+ "aria-modal": "true",
1063
+ className: cn(
1064
+ "fixed inset-x-0 bottom-0 z-50 flex flex-col bg-background-elevated border-t border-border rounded-t-xl shadow-2xl transition-transform duration-200 ease-out",
1065
+ "max-h-[80dvh]",
1066
+ open ? "translate-y-0" : "translate-y-full",
1067
+ className
1068
+ ),
1069
+ children: [
1070
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex justify-center pt-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-1 w-8 rounded-full bg-foreground-subtle/30" }) }),
1071
+ title && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-center justify-between px-4 pb-2", children: [
1072
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
1073
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1074
+ "button",
1075
+ {
1076
+ onClick: onClose,
1077
+ className: "p-1 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
1078
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react4.X, { className: "h-4 w-4" })
1079
+ }
1080
+ )
1081
+ ] }),
1082
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children })
1083
+ ]
1084
+ }
1085
+ )
1086
+ ] });
1087
+ }
1088
+
1089
+ // src/primitives/popover.tsx
1090
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1091
+ var PopoverContext = (0, import_react19.createContext)(null);
1012
1092
  function usePopoverContext() {
1013
- const ctx = (0, import_react17.useContext)(PopoverContext);
1093
+ const ctx = (0, import_react19.useContext)(PopoverContext);
1014
1094
  if (!ctx) throw new Error("Popover compound components must be used within <Popover>");
1015
1095
  return ctx;
1016
1096
  }
1017
1097
  function Popover({ children, open: controlledOpen, onOpenChange }) {
1018
- const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react17.useState)(false);
1098
+ const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react19.useState)(false);
1019
1099
  const open = controlledOpen ?? uncontrolledOpen;
1020
- const triggerId = (0, import_react17.useId)();
1021
- const contentId = (0, import_react17.useId)();
1022
- const setOpen = (0, import_react17.useCallback)(
1100
+ const triggerId = (0, import_react19.useId)();
1101
+ const contentId = (0, import_react19.useId)();
1102
+ const setOpen = (0, import_react19.useCallback)(
1023
1103
  (next) => {
1024
1104
  onOpenChange?.(next);
1025
1105
  if (controlledOpen === void 0) setUncontrolledOpen(next);
1026
1106
  },
1027
1107
  [controlledOpen, onOpenChange]
1028
1108
  );
1029
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PopoverContext.Provider, { value: { open, setOpen, triggerId, contentId }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "relative inline-block", children }) });
1109
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PopoverContext.Provider, { value: { open, setOpen, triggerId, contentId }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "relative inline-block", children }) });
1030
1110
  }
1031
1111
  function PopoverTrigger({ children, ...props }) {
1032
1112
  const { open, setOpen, triggerId, contentId } = usePopoverContext();
1033
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1113
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1034
1114
  "button",
1035
1115
  {
1036
1116
  type: "button",
@@ -1046,9 +1126,10 @@ function PopoverTrigger({ children, ...props }) {
1046
1126
  }
1047
1127
  function PopoverContent({ className, children, ...props }) {
1048
1128
  const { open, setOpen, contentId, triggerId } = usePopoverContext();
1049
- const ref = (0, import_react17.useRef)(null);
1050
- (0, import_react17.useEffect)(() => {
1051
- if (!open) return;
1129
+ const isMobile = useIsMobile();
1130
+ const ref = (0, import_react19.useRef)(null);
1131
+ (0, import_react19.useEffect)(() => {
1132
+ if (!open || isMobile) return;
1052
1133
  const handler = (e) => {
1053
1134
  const el = ref.current;
1054
1135
  const trigger = document.getElementById(triggerId);
@@ -1065,9 +1146,12 @@ function PopoverContent({ className, children, ...props }) {
1065
1146
  document.removeEventListener("mousedown", handler);
1066
1147
  document.removeEventListener("keydown", escHandler);
1067
1148
  };
1068
- }, [open, setOpen, triggerId]);
1149
+ }, [open, setOpen, triggerId, isMobile]);
1069
1150
  if (!open) return null;
1070
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1151
+ if (isMobile) {
1152
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(BottomSheet, { open, onClose: () => setOpen(false), children });
1153
+ }
1154
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1071
1155
  "div",
1072
1156
  {
1073
1157
  ref,
@@ -1085,11 +1169,11 @@ function PopoverContent({ className, children, ...props }) {
1085
1169
  }
1086
1170
 
1087
1171
  // src/primitives/tabs.tsx
1088
- var import_react18 = require("react");
1089
- var import_jsx_runtime17 = require("react/jsx-runtime");
1090
- var TabsContext = (0, import_react18.createContext)(null);
1172
+ var import_react20 = require("react");
1173
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1174
+ var TabsContext = (0, import_react20.createContext)(null);
1091
1175
  function useTabsContext() {
1092
- const ctx = (0, import_react18.useContext)(TabsContext);
1176
+ const ctx = (0, import_react20.useContext)(TabsContext);
1093
1177
  if (!ctx) throw new Error("Tabs compound components must be used within <Tabs>");
1094
1178
  return ctx;
1095
1179
  }
@@ -1100,19 +1184,19 @@ function Tabs({
1100
1184
  className,
1101
1185
  ...props
1102
1186
  }) {
1103
- const [uncontrolledValue, setUncontrolledValue] = (0, import_react18.useState)(defaultValue);
1187
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(defaultValue);
1104
1188
  const value = controlledValue ?? uncontrolledValue;
1105
- const setValue = (0, import_react18.useCallback)(
1189
+ const setValue = (0, import_react20.useCallback)(
1106
1190
  (next) => {
1107
1191
  onValueChange?.(next);
1108
1192
  if (controlledValue === void 0) setUncontrolledValue(next);
1109
1193
  },
1110
1194
  [controlledValue, onValueChange]
1111
1195
  );
1112
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabsContext.Provider, { value: { value, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className, ...props }) });
1196
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabsContext.Provider, { value: { value, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className, ...props }) });
1113
1197
  }
1114
1198
  function TabsList({ className, ...props }) {
1115
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1199
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1116
1200
  "div",
1117
1201
  {
1118
1202
  role: "tablist",
@@ -1125,7 +1209,7 @@ function TabsTrigger({ value, className, ...props }) {
1125
1209
  const { value: activeValue, setValue } = useTabsContext();
1126
1210
  const isActive = value === activeValue;
1127
1211
  const panelId = `tabpanel-${value}`;
1128
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1212
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1129
1213
  "button",
1130
1214
  {
1131
1215
  type: "button",
@@ -1146,7 +1230,7 @@ function TabsTrigger({ value, className, ...props }) {
1146
1230
  function TabsContent({ value, className, ...props }) {
1147
1231
  const { value: activeValue } = useTabsContext();
1148
1232
  if (value !== activeValue) return null;
1149
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1233
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1150
1234
  "div",
1151
1235
  {
1152
1236
  role: "tabpanel",
@@ -1158,11 +1242,11 @@ function TabsContent({ value, className, ...props }) {
1158
1242
  }
1159
1243
 
1160
1244
  // src/primitives/scroll-area.tsx
1161
- var import_react19 = require("react");
1162
- var import_jsx_runtime18 = require("react/jsx-runtime");
1163
- var ScrollArea = (0, import_react19.forwardRef)(
1245
+ var import_react21 = require("react");
1246
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1247
+ var ScrollArea = (0, import_react21.forwardRef)(
1164
1248
  ({ className, ...props }, ref) => {
1165
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1249
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1166
1250
  "div",
1167
1251
  {
1168
1252
  ref,
@@ -1178,29 +1262,9 @@ var ScrollArea = (0, import_react19.forwardRef)(
1178
1262
  ScrollArea.displayName = "ScrollArea";
1179
1263
 
1180
1264
  // src/primitives/floating-panel.tsx
1181
- var import_react21 = require("react");
1182
- var import_lucide_react4 = require("lucide-react");
1183
-
1184
- // src/hooks/use-is-mobile.ts
1185
- var import_react20 = require("react");
1186
- var MOBILE_QUERY = "(max-width: 767px)";
1187
- function subscribe(callback) {
1188
- const mql = window.matchMedia(MOBILE_QUERY);
1189
- mql.addEventListener("change", callback);
1190
- return () => mql.removeEventListener("change", callback);
1191
- }
1192
- function getSnapshot() {
1193
- return window.matchMedia(MOBILE_QUERY).matches;
1194
- }
1195
- function getServerSnapshot() {
1196
- return false;
1197
- }
1198
- function useIsMobile() {
1199
- return (0, import_react20.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
1200
- }
1201
-
1202
- // src/primitives/floating-panel.tsx
1203
- var import_jsx_runtime19 = require("react/jsx-runtime");
1265
+ var import_react22 = require("react");
1266
+ var import_lucide_react5 = require("lucide-react");
1267
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1204
1268
  function FloatingPanel({
1205
1269
  title,
1206
1270
  onClose,
@@ -1212,25 +1276,25 @@ function FloatingPanel({
1212
1276
  offsetIndex = 0,
1213
1277
  className
1214
1278
  }) {
1215
- const [pos, setPos] = (0, import_react21.useState)({ x: 80 + offsetIndex * 30, y: 80 + offsetIndex * 30 });
1216
- const [size, setSize] = (0, import_react21.useState)({ w: defaultWidth, h: defaultHeight });
1217
- const [minimized, setMinimized] = (0, import_react21.useState)(false);
1218
- const dragging = (0, import_react21.useRef)(false);
1219
- const resizing = (0, import_react21.useRef)(false);
1220
- const offset = (0, import_react21.useRef)({ x: 0, y: 0 });
1279
+ const [pos, setPos] = (0, import_react22.useState)({ x: 80 + offsetIndex * 30, y: 80 + offsetIndex * 30 });
1280
+ const [size, setSize] = (0, import_react22.useState)({ w: defaultWidth, h: defaultHeight });
1281
+ const [minimized, setMinimized] = (0, import_react22.useState)(false);
1282
+ const dragging = (0, import_react22.useRef)(false);
1283
+ const resizing = (0, import_react22.useRef)(false);
1284
+ const offset = (0, import_react22.useRef)({ x: 0, y: 0 });
1221
1285
  const isMobile = useIsMobile();
1222
- const onDragStart = (0, import_react21.useCallback)((e) => {
1286
+ const onDragStart = (0, import_react22.useCallback)((e) => {
1223
1287
  e.preventDefault();
1224
1288
  dragging.current = true;
1225
1289
  offset.current = { x: e.clientX - pos.x, y: e.clientY - pos.y };
1226
1290
  }, [pos]);
1227
- const onResizeStart = (0, import_react21.useCallback)((e) => {
1291
+ const onResizeStart = (0, import_react22.useCallback)((e) => {
1228
1292
  e.preventDefault();
1229
1293
  e.stopPropagation();
1230
1294
  resizing.current = true;
1231
1295
  offset.current = { x: e.clientX, y: e.clientY };
1232
1296
  }, []);
1233
- (0, import_react21.useEffect)(() => {
1297
+ (0, import_react22.useEffect)(() => {
1234
1298
  const onMouseMove = (e) => {
1235
1299
  if (dragging.current) setPos({ x: e.clientX - offset.current.x, y: e.clientY - offset.current.y });
1236
1300
  if (resizing.current) {
@@ -1252,7 +1316,7 @@ function FloatingPanel({
1252
1316
  };
1253
1317
  }, [minWidth, minHeight]);
1254
1318
  if (isMobile) {
1255
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1319
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1256
1320
  "div",
1257
1321
  {
1258
1322
  className: cn(
@@ -1261,33 +1325,33 @@ function FloatingPanel({
1261
1325
  ),
1262
1326
  style: { maxHeight: "60dvh" },
1263
1327
  children: [
1264
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-surface", children: [
1265
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[11px] font-medium truncate", children: title }),
1266
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
1267
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1328
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-surface", children: [
1329
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-medium truncate", children: title }),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
1331
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1268
1332
  "button",
1269
1333
  {
1270
1334
  onClick: () => setMinimized(!minimized),
1271
1335
  className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
1272
- children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.Minimize2, { size: 12 })
1336
+ children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Minimize2, { size: 12 })
1273
1337
  }
1274
1338
  ),
1275
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1339
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1276
1340
  "button",
1277
1341
  {
1278
1342
  onClick: onClose,
1279
1343
  className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
1280
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.X, { size: 12 })
1344
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.X, { size: 12 })
1281
1345
  }
1282
1346
  )
1283
1347
  ] })
1284
1348
  ] }),
1285
- !minimized && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto", children })
1349
+ !minimized && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-h-0 overflow-y-auto", children })
1286
1350
  ]
1287
1351
  }
1288
1352
  );
1289
1353
  }
1290
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1354
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1291
1355
  "div",
1292
1356
  {
1293
1357
  className: cn(
@@ -1296,42 +1360,42 @@ function FloatingPanel({
1296
1360
  ),
1297
1361
  style: { left: pos.x, top: pos.y, width: minimized ? 280 : size.w, height: minimized ? "auto" : size.h },
1298
1362
  children: [
1299
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1363
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1300
1364
  "div",
1301
1365
  {
1302
1366
  onMouseDown: onDragStart,
1303
1367
  className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border cursor-move select-none shrink-0 bg-surface",
1304
1368
  children: [
1305
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
1306
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.GripHorizontal, { size: 12, className: "text-foreground-subtle shrink-0" }),
1307
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-[11px] font-medium truncate", children: title })
1369
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.GripHorizontal, { size: 12, className: "text-foreground-subtle shrink-0" }),
1371
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-medium truncate", children: title })
1308
1372
  ] }),
1309
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
1310
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1373
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 shrink-0", children: [
1374
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1311
1375
  "button",
1312
1376
  {
1313
1377
  onClick: () => setMinimized(!minimized),
1314
1378
  className: "p-0.5 rounded hover:bg-surface-hover text-foreground-muted transition-colors",
1315
1379
  title: minimized ? "Restore" : "Minimize",
1316
- children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.Minimize2, { size: 12 })
1380
+ children: minimized ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Maximize2, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.Minimize2, { size: 12 })
1317
1381
  }
1318
1382
  ),
1319
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1383
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1320
1384
  "button",
1321
1385
  {
1322
1386
  onClick: onClose,
1323
1387
  className: "p-0.5 rounded hover:bg-danger/20 text-foreground-muted hover:text-danger transition-colors",
1324
1388
  title: "Close",
1325
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react4.X, { size: 12 })
1389
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react5.X, { size: 12 })
1326
1390
  }
1327
1391
  )
1328
1392
  ] })
1329
1393
  ]
1330
1394
  }
1331
1395
  ),
1332
- !minimized && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex-1 min-h-0 overflow-y-auto relative", children: [
1396
+ !minimized && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex-1 min-h-0 overflow-y-auto relative", children: [
1333
1397
  children,
1334
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1398
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1335
1399
  "div",
1336
1400
  {
1337
1401
  onMouseDown: onResizeStart,
@@ -1346,11 +1410,11 @@ function FloatingPanel({
1346
1410
  }
1347
1411
 
1348
1412
  // src/primitives/mobile-drawer.tsx
1349
- var import_react22 = require("react");
1350
- var import_jsx_runtime20 = require("react/jsx-runtime");
1413
+ var import_react23 = require("react");
1414
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1351
1415
  function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
1352
- const drawerRef = (0, import_react22.useRef)(null);
1353
- (0, import_react22.useEffect)(() => {
1416
+ const drawerRef = (0, import_react23.useRef)(null);
1417
+ (0, import_react23.useEffect)(() => {
1354
1418
  if (!open) return;
1355
1419
  const handleKeyDown = (e) => {
1356
1420
  if (e.key === "Escape") onClose();
@@ -1362,8 +1426,8 @@ function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
1362
1426
  document.body.style.overflow = "";
1363
1427
  };
1364
1428
  }, [open, onClose]);
1365
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
1366
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1429
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1430
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1367
1431
  "div",
1368
1432
  {
1369
1433
  className: cn(
@@ -1374,7 +1438,7 @@ function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
1374
1438
  "aria-hidden": "true"
1375
1439
  }
1376
1440
  ),
1377
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1441
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1378
1442
  "div",
1379
1443
  {
1380
1444
  ref: drawerRef,
@@ -1392,66 +1456,6 @@ function MobileDrawer({ open, onClose, children, className, width = "w-64" }) {
1392
1456
  ] });
1393
1457
  }
1394
1458
 
1395
- // src/primitives/bottom-sheet.tsx
1396
- var import_react23 = require("react");
1397
- var import_lucide_react5 = require("lucide-react");
1398
- var import_jsx_runtime21 = require("react/jsx-runtime");
1399
- function BottomSheet({ open, onClose, title, children, className }) {
1400
- (0, import_react23.useEffect)(() => {
1401
- if (!open) return;
1402
- const handleKeyDown = (e) => {
1403
- if (e.key === "Escape") onClose();
1404
- };
1405
- document.addEventListener("keydown", handleKeyDown);
1406
- document.body.style.overflow = "hidden";
1407
- return () => {
1408
- document.removeEventListener("keydown", handleKeyDown);
1409
- document.body.style.overflow = "";
1410
- };
1411
- }, [open, onClose]);
1412
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1413
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1414
- "div",
1415
- {
1416
- className: cn(
1417
- "fixed inset-0 z-40 bg-black/50 transition-opacity duration-200",
1418
- open ? "opacity-100" : "pointer-events-none opacity-0"
1419
- ),
1420
- onClick: onClose,
1421
- "aria-hidden": "true"
1422
- }
1423
- ),
1424
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
1425
- "div",
1426
- {
1427
- role: "dialog",
1428
- "aria-modal": "true",
1429
- className: cn(
1430
- "fixed inset-x-0 bottom-0 z-50 flex flex-col bg-background-elevated border-t border-border rounded-t-xl shadow-2xl transition-transform duration-200 ease-out",
1431
- "max-h-[80dvh]",
1432
- open ? "translate-y-0" : "translate-y-full",
1433
- className
1434
- ),
1435
- children: [
1436
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex justify-center pt-2 pb-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-1 w-8 rounded-full bg-foreground-subtle/30" }) }),
1437
- title && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between px-4 pb-2", children: [
1438
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm font-medium text-foreground", children: title }),
1439
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1440
- "button",
1441
- {
1442
- onClick: onClose,
1443
- className: "p-1 rounded-md hover:bg-surface-hover text-foreground-muted transition-colors",
1444
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react5.X, { className: "h-4 w-4" })
1445
- }
1446
- )
1447
- ] }),
1448
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 overflow-y-auto px-4 pb-4", children })
1449
- ]
1450
- }
1451
- )
1452
- ] });
1453
- }
1454
-
1455
1459
  // src/composites/status-badge.tsx
1456
1460
  var import_jsx_runtime22 = require("react/jsx-runtime");
1457
1461
  var statusConfig = {
@@ -1707,12 +1711,79 @@ function CodeBlock({ children, maxHeight = 300, className }) {
1707
1711
  }
1708
1712
 
1709
1713
  // src/composites/filter-bar.tsx
1714
+ var import_react25 = require("react");
1710
1715
  var import_lucide_react8 = require("lucide-react");
1711
1716
  var import_jsx_runtime32 = require("react/jsx-runtime");
1712
1717
  function FilterBar({ filters, values, onChange, className }) {
1718
+ const isMobile = useIsMobile();
1719
+ const [sheetOpen, setSheetOpen] = (0, import_react25.useState)(false);
1713
1720
  const handleChange = (key, value) => {
1714
1721
  onChange({ ...values, [key]: value });
1715
1722
  };
1723
+ const activeCount = Object.values(values).filter((v) => v !== void 0 && v !== "").length;
1724
+ if (isMobile) {
1725
+ const searchFilter = filters.find((f) => f.type === "search");
1726
+ const hasNonSearchFilters = filters.some((f) => f.type !== "search");
1727
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cn("flex items-center gap-2", className), children: [
1728
+ searchFilter && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1729
+ Input,
1730
+ {
1731
+ placeholder: searchFilter.placeholder ?? "Search...",
1732
+ value: values[searchFilter.key] ?? "",
1733
+ onChange: (e) => handleChange(searchFilter.key, e.target.value),
1734
+ leftSlot: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.Search, { className: "h-3 w-3 text-foreground-subtle" }),
1735
+ className: "flex-1"
1736
+ }
1737
+ ),
1738
+ hasNonSearchFilters && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
1739
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
1740
+ "button",
1741
+ {
1742
+ onClick: () => setSheetOpen(true),
1743
+ className: "flex items-center gap-1.5 rounded-md border border-border px-2.5 py-1.5 text-xs text-foreground-muted hover:bg-surface-hover transition-colors shrink-0",
1744
+ children: [
1745
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react8.SlidersHorizontal, { className: "h-3.5 w-3.5" }),
1746
+ "Filters",
1747
+ activeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: "info", className: "ml-1 text-[10px] px-1 py-0", children: activeCount })
1748
+ ]
1749
+ }
1750
+ ),
1751
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(BottomSheet, { open: sheetOpen, onClose: () => setSheetOpen(false), title: "Filters", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-col gap-3", children: filters.filter((f) => f.type !== "search").map((filter) => {
1752
+ switch (filter.type) {
1753
+ case "select":
1754
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
1755
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("label", { className: "text-xs text-foreground-muted mb-1 block", children: filter.label }),
1756
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1757
+ Select,
1758
+ {
1759
+ options: filter.options,
1760
+ value: values[filter.key] ?? "",
1761
+ onChange: (e) => handleChange(filter.key, e.target.value),
1762
+ className: "w-full"
1763
+ }
1764
+ )
1765
+ ] }, filter.key);
1766
+ case "badge-toggle":
1767
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex items-center gap-1 flex-wrap", children: filter.options.map((option) => {
1768
+ const currentValue = values[filter.key];
1769
+ const isActive = currentValue === option.value;
1770
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1771
+ "button",
1772
+ {
1773
+ type: "button",
1774
+ onClick: () => handleChange(filter.key, isActive ? void 0 : option.value),
1775
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: isActive ? "info" : "default", className: "cursor-pointer", children: option.label })
1776
+ },
1777
+ option.value
1778
+ );
1779
+ }) }, filter.key);
1780
+ default:
1781
+ return null;
1782
+ }
1783
+ }) }) })
1784
+ ] })
1785
+ ] });
1786
+ }
1716
1787
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn("flex items-center gap-2 flex-wrap", className), children: filters.map((filter) => {
1717
1788
  switch (filter.type) {
1718
1789
  case "search":
@@ -1746,18 +1817,8 @@ function FilterBar({ filters, values, onChange, className }) {
1746
1817
  "button",
1747
1818
  {
1748
1819
  type: "button",
1749
- onClick: () => handleChange(
1750
- filter.key,
1751
- isActive ? void 0 : option.value
1752
- ),
1753
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
1754
- Badge,
1755
- {
1756
- variant: isActive ? "info" : "default",
1757
- className: "cursor-pointer",
1758
- children: option.label
1759
- }
1760
- )
1820
+ onClick: () => handleChange(filter.key, isActive ? void 0 : option.value),
1821
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Badge, { variant: isActive ? "info" : "default", className: "cursor-pointer", children: option.label })
1761
1822
  },
1762
1823
  option.value
1763
1824
  );
@@ -1822,12 +1883,12 @@ function Sidebar({ logo, sections, footer, onNavigate, className }) {
1822
1883
  }
1823
1884
 
1824
1885
  // src/composites/app-shell/app-shell.tsx
1825
- var import_react25 = require("react");
1886
+ var import_react26 = require("react");
1826
1887
  var import_lucide_react9 = require("lucide-react");
1827
1888
  var import_jsx_runtime35 = require("react/jsx-runtime");
1828
1889
  function AppShell({ sidebar, header, mobileLogo, mobileActions, children, className }) {
1829
1890
  const isMobile = useIsMobile();
1830
- const [drawerOpen, setDrawerOpen] = (0, import_react25.useState)(false);
1891
+ const [drawerOpen, setDrawerOpen] = (0, import_react26.useState)(false);
1831
1892
  return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: cn("flex h-screen", className), children: [
1832
1893
  !isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Sidebar, { ...sidebar, className: cn("w-44", sidebar.className) }),
1833
1894
  isMobile && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(MobileDrawer, { open: drawerOpen, onClose: () => setDrawerOpen(false), width: "w-64", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
@@ -1875,7 +1936,7 @@ function AppShell({ sidebar, header, mobileLogo, mobileActions, children, classN
1875
1936
  }
1876
1937
 
1877
1938
  // src/composites/data-table/data-table.tsx
1878
- var import_react26 = require("react");
1939
+ var import_react27 = require("react");
1879
1940
  var import_react_table = require("@tanstack/react-table");
1880
1941
 
1881
1942
  // src/composites/data-table/data-table-header.tsx
@@ -2059,9 +2120,10 @@ function DataTable({
2059
2120
  selectable = false,
2060
2121
  compact = true,
2061
2122
  stickyHeader = false,
2062
- className
2123
+ className,
2124
+ mobileMode = "scroll"
2063
2125
  }) {
2064
- const columns = (0, import_react26.useMemo)(() => {
2126
+ const columns = (0, import_react27.useMemo)(() => {
2065
2127
  if (!selectable) return userColumns;
2066
2128
  const selectColumn = {
2067
2129
  id: "__select",
@@ -2111,7 +2173,69 @@ function DataTable({
2111
2173
  pageCount: pagination ? Math.ceil(pagination.total / pagination.pageSize) : void 0
2112
2174
  });
2113
2175
  const hasActions = !!rowActions;
2114
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("overflow-auto", className), children: [
2176
+ const isMobile = useIsMobile();
2177
+ const showCards = isMobile && mobileMode === "cards";
2178
+ if (showCards) {
2179
+ const rows = table.getRowModel().rows;
2180
+ if (loading) {
2181
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("space-y-2", className), children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "rounded-lg border border-border bg-surface p-3 space-y-2", children: [
2182
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-3/4" }),
2183
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-1/2" }),
2184
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Skeleton, { className: "h-3 w-2/3" })
2185
+ ] }, i)) });
2186
+ }
2187
+ if (rows.length === 0) {
2188
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("text-center py-8 text-xs text-foreground-muted", className), children: emptyState ?? "No data" });
2189
+ }
2190
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("space-y-2", className), children: [
2191
+ rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2192
+ "div",
2193
+ {
2194
+ className: cn(
2195
+ "rounded-lg border border-border bg-surface p-3 space-y-1.5",
2196
+ onRowClick && "cursor-pointer hover:bg-surface-hover transition-colors"
2197
+ ),
2198
+ onClick: onRowClick ? () => onRowClick(row.original) : void 0,
2199
+ children: [
2200
+ row.getVisibleCells().filter((cell) => cell.column.id !== "__select").map((cell) => {
2201
+ const header = cell.column.columnDef.header;
2202
+ const label = typeof header === "string" ? header : cell.column.id;
2203
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-baseline justify-between gap-2 text-xs", children: [
2204
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-foreground-muted shrink-0", children: label }),
2205
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-foreground text-right truncate", children: (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext()) })
2206
+ ] }, cell.id);
2207
+ }),
2208
+ rowActions && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex items-center gap-1 pt-1 border-t border-border mt-1.5", children: rowActions(row.original).map((action, i) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2209
+ "button",
2210
+ {
2211
+ onClick: (e) => {
2212
+ e.stopPropagation();
2213
+ action.onClick();
2214
+ },
2215
+ className: cn(
2216
+ "text-[11px] px-2 py-1 rounded-md transition-colors",
2217
+ action.variant === "danger" ? "text-danger hover:bg-danger/10" : "text-foreground-muted hover:bg-surface-hover"
2218
+ ),
2219
+ children: action.label
2220
+ },
2221
+ i
2222
+ )) })
2223
+ ]
2224
+ },
2225
+ row.id
2226
+ )),
2227
+ pagination && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2228
+ DataTablePagination,
2229
+ {
2230
+ page: pagination.page,
2231
+ pageSize: pagination.pageSize,
2232
+ total: pagination.total,
2233
+ onPaginationChange
2234
+ }
2235
+ )
2236
+ ] });
2237
+ }
2238
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cn("overflow-x-auto", className), children: [
2115
2239
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("table", { className: "w-full border-collapse", children: [
2116
2240
  /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2117
2241
  DataTableHeader,
@@ -2263,7 +2387,7 @@ function DeviceGrid({
2263
2387
  }
2264
2388
 
2265
2389
  // src/composites/pipeline-step.tsx
2266
- var import_react27 = require("react");
2390
+ var import_react28 = require("react");
2267
2391
  var import_lucide_react13 = require("lucide-react");
2268
2392
  var import_jsx_runtime42 = require("react/jsx-runtime");
2269
2393
  var ADDON_COLORS = {
@@ -2341,7 +2465,7 @@ function PipelineStep({
2341
2465
  onDelete,
2342
2466
  readOnly = false
2343
2467
  }) {
2344
- const [expanded, setExpanded] = (0, import_react27.useState)(false);
2468
+ const [expanded, setExpanded] = (0, import_react28.useState)(false);
2345
2469
  const color = borderColor(step.addonId, step.slot);
2346
2470
  const backends = backendsForRuntime(step.runtime, capabilities, schema);
2347
2471
  const rtOptions = runtimeOptions(capabilities);
@@ -2529,7 +2653,7 @@ function PipelineRuntimeSelector({ options, value, onChange }) {
2529
2653
  }
2530
2654
 
2531
2655
  // src/composites/pipeline-builder.tsx
2532
- var import_react28 = require("react");
2656
+ var import_react29 = require("react");
2533
2657
  var import_lucide_react15 = require("lucide-react");
2534
2658
 
2535
2659
  // src/lib/validate-template.ts
@@ -2625,9 +2749,9 @@ function PipelineBuilder({
2625
2749
  readOnly = false,
2626
2750
  excludeAddons = []
2627
2751
  }) {
2628
- const excluded = (0, import_react28.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
2629
- const schemaMap = (0, import_react28.useMemo)(() => buildSchemaMap(schema), [schema]);
2630
- const [warnings, setWarnings] = (0, import_react28.useState)([]);
2752
+ const excluded = (0, import_react29.useMemo)(() => new Set(excludeAddons), [excludeAddons]);
2753
+ const schemaMap = (0, import_react29.useMemo)(() => buildSchemaMap(schema), [schema]);
2754
+ const [warnings, setWarnings] = (0, import_react29.useState)([]);
2631
2755
  const bestPlatformScore = capabilities.platformScores?.find((s) => s.available);
2632
2756
  const hasPython = capabilities.runtimes.python.available && capabilities.runtimes.python.backends.some((b) => b.available);
2633
2757
  const defaultRuntime = bestPlatformScore?.runtime ?? (hasPython ? "python" : "node");
@@ -2972,7 +3096,7 @@ function getClassColor(className, customColors) {
2972
3096
  }
2973
3097
 
2974
3098
  // src/composites/detection-canvas.tsx
2975
- var import_react29 = require("react");
3099
+ var import_react30 = require("react");
2976
3100
  var import_jsx_runtime45 = require("react/jsx-runtime");
2977
3101
  var DEFAULT_CLASS_COLORS = CLASS_COLORS;
2978
3102
  function DetectionCanvas({
@@ -3068,7 +3192,7 @@ function BoundingBox({
3068
3192
  const labelCount = 1 + (detection.labelsData?.length ?? 0);
3069
3193
  const labelHeightPx = labelCount * 16 + 4;
3070
3194
  const topPct = y1 / imageHeight * 100;
3071
- const containerRef = (0, import_react29.useRef)(null);
3195
+ const containerRef = (0, import_react30.useRef)(null);
3072
3196
  const showBelow = topPct < labelHeightPx / imageHeight * 100 * 1.5;
3073
3197
  const labelsElement = /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3074
3198
  "div",
@@ -3134,8 +3258,8 @@ function MaskOverlay({
3134
3258
  imageHeight,
3135
3259
  color
3136
3260
  }) {
3137
- const canvasRef = (0, import_react29.useRef)(null);
3138
- (0, import_react29.useEffect)(() => {
3261
+ const canvasRef = (0, import_react30.useRef)(null);
3262
+ (0, import_react30.useEffect)(() => {
3139
3263
  const canvas = canvasRef.current;
3140
3264
  if (!canvas) return;
3141
3265
  const ctx = canvas.getContext("2d");
@@ -3589,16 +3713,16 @@ function InferenceConfigSelector({
3589
3713
  }
3590
3714
 
3591
3715
  // src/composites/mount-addon-page.tsx
3592
- var import_react32 = require("react");
3716
+ var import_react33 = require("react");
3593
3717
  var import_client2 = require("react-dom/client");
3594
3718
 
3595
3719
  // src/composites/dev-shell.tsx
3596
- var import_react31 = require("react");
3720
+ var import_react32 = require("react");
3597
3721
  var import_client = require("@trpc/client");
3598
3722
  var import_superjson = __toESM(require("superjson"), 1);
3599
3723
 
3600
3724
  // src/composites/login-form.tsx
3601
- var import_react30 = require("react");
3725
+ var import_react31 = require("react");
3602
3726
  var import_jsx_runtime50 = require("react/jsx-runtime");
3603
3727
  function EyeIcon({ className }) {
3604
3728
  return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
@@ -3663,11 +3787,11 @@ function LoginForm({
3663
3787
  error: externalError,
3664
3788
  className
3665
3789
  }) {
3666
- const [username, setUsername] = (0, import_react30.useState)("");
3667
- const [password, setPassword] = (0, import_react30.useState)("");
3668
- const [showPassword, setShowPassword] = (0, import_react30.useState)(false);
3669
- const [submitting, setSubmitting] = (0, import_react30.useState)(false);
3670
- const [internalError, setInternalError] = (0, import_react30.useState)(null);
3790
+ const [username, setUsername] = (0, import_react31.useState)("");
3791
+ const [password, setPassword] = (0, import_react31.useState)("");
3792
+ const [showPassword, setShowPassword] = (0, import_react31.useState)(false);
3793
+ const [submitting, setSubmitting] = (0, import_react31.useState)(false);
3794
+ const [internalError, setInternalError] = (0, import_react31.useState)(null);
3671
3795
  const error = externalError ?? internalError;
3672
3796
  const handleSubmit = async (e) => {
3673
3797
  e.preventDefault();
@@ -3763,9 +3887,9 @@ function LoginForm({
3763
3887
  // src/composites/dev-shell.tsx
3764
3888
  var import_jsx_runtime51 = require("react/jsx-runtime");
3765
3889
  var STORAGE_KEY = "camstack_dev_token";
3766
- var DevShellContext = (0, import_react31.createContext)(null);
3890
+ var DevShellContext = (0, import_react32.createContext)(null);
3767
3891
  function useDevShell() {
3768
- const ctx = (0, import_react31.useContext)(DevShellContext);
3892
+ const ctx = (0, import_react32.useContext)(DevShellContext);
3769
3893
  if (!ctx) {
3770
3894
  throw new Error("useDevShell must be used within a DevShell");
3771
3895
  }
@@ -3825,7 +3949,7 @@ function DevShellInner({
3825
3949
  onLogout
3826
3950
  }) {
3827
3951
  const theme = useThemeMode();
3828
- const trpc = (0, import_react31.useMemo)(
3952
+ const trpc = (0, import_react32.useMemo)(
3829
3953
  () => {
3830
3954
  const wsUrl = serverUrl.replace(/^http/, "ws") + "/trpc";
3831
3955
  const wsClient = (0, import_client.createWSClient)({
@@ -3848,7 +3972,7 @@ function DevShellInner({
3848
3972
  },
3849
3973
  [serverUrl, token]
3850
3974
  );
3851
- const contextValue = (0, import_react31.useMemo)(
3975
+ const contextValue = (0, import_react32.useMemo)(
3852
3976
  () => ({ trpc, token, logout: onLogout }),
3853
3977
  [trpc, token, onLogout]
3854
3978
  );
@@ -3892,8 +4016,8 @@ function DevShell({
3892
4016
  serverUrl = "https://localhost:4443",
3893
4017
  title
3894
4018
  }) {
3895
- const [token, setToken] = (0, import_react31.useState)(getStoredToken);
3896
- const handleLogin = (0, import_react31.useCallback)(
4019
+ const [token, setToken] = (0, import_react32.useState)(getStoredToken);
4020
+ const handleLogin = (0, import_react32.useCallback)(
3897
4021
  async (username, password) => {
3898
4022
  const anonClient = (0, import_client.createTRPCClient)({
3899
4023
  links: [
@@ -3910,7 +4034,7 @@ function DevShell({
3910
4034
  },
3911
4035
  [serverUrl]
3912
4036
  );
3913
- const handleLogout = (0, import_react31.useCallback)(() => {
4037
+ const handleLogout = (0, import_react32.useCallback)(() => {
3914
4038
  localStorage.removeItem(STORAGE_KEY);
3915
4039
  setToken(null);
3916
4040
  }, []);
@@ -3942,10 +4066,10 @@ function mountAddonPage(PageComponent, options = {}) {
3942
4066
  return;
3943
4067
  }
3944
4068
  (0, import_client2.createRoot)(root).render(
3945
- (0, import_react32.createElement)(DevShell, {
4069
+ (0, import_react33.createElement)(DevShell, {
3946
4070
  serverUrl,
3947
4071
  title,
3948
- children: ({ trpc, theme }) => (0, import_react32.createElement)(PageComponent, {
4072
+ children: ({ trpc, theme }) => (0, import_react33.createElement)(PageComponent, {
3949
4073
  trpc,
3950
4074
  theme: { isDark: theme.resolvedMode === "dark" },
3951
4075
  navigate: (path) => {