@camstack/ui-library 0.1.35 → 0.1.37
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 +316 -192
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +403 -279
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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,
|
|
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,
|
|
1098
|
+
const [uncontrolledOpen, setUncontrolledOpen] = (0, import_react19.useState)(false);
|
|
1019
1099
|
const open = controlledOpen ?? uncontrolledOpen;
|
|
1020
|
-
const triggerId = (0,
|
|
1021
|
-
const contentId = (0,
|
|
1022
|
-
const setOpen = (0,
|
|
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,
|
|
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,
|
|
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
|
|
1050
|
-
(0,
|
|
1051
|
-
|
|
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
|
-
|
|
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
|
|
1089
|
-
var
|
|
1090
|
-
var TabsContext = (0,
|
|
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,
|
|
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,
|
|
1187
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, import_react20.useState)(defaultValue);
|
|
1104
1188
|
const value = controlledValue ?? uncontrolledValue;
|
|
1105
|
-
const setValue = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
1162
|
-
var
|
|
1163
|
-
var ScrollArea = (0,
|
|
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,
|
|
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
|
|
1182
|
-
var
|
|
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,
|
|
1216
|
-
const [size, setSize] = (0,
|
|
1217
|
-
const [minimized, setMinimized] = (0,
|
|
1218
|
-
const dragging = (0,
|
|
1219
|
-
const resizing = (0,
|
|
1220
|
-
const offset = (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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
1265
|
-
/* @__PURE__ */ (0,
|
|
1266
|
-
/* @__PURE__ */ (0,
|
|
1267
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
1306
|
-
/* @__PURE__ */ (0,
|
|
1307
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
1310
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
1350
|
-
var
|
|
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,
|
|
1353
|
-
(0,
|
|
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,
|
|
1366
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
2629
|
-
const schemaMap = (0,
|
|
2630
|
-
const [warnings, setWarnings] = (0,
|
|
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
|
|
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,
|
|
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,
|
|
3138
|
-
(0,
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
3667
|
-
const [password, setPassword] = (0,
|
|
3668
|
-
const [showPassword, setShowPassword] = (0,
|
|
3669
|
-
const [submitting, setSubmitting] = (0,
|
|
3670
|
-
const [internalError, setInternalError] = (0,
|
|
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,
|
|
3890
|
+
var DevShellContext = (0, import_react32.createContext)(null);
|
|
3767
3891
|
function useDevShell() {
|
|
3768
|
-
const ctx = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
3896
|
-
const handleLogin = (0,
|
|
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,
|
|
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,
|
|
4069
|
+
(0, import_react33.createElement)(DevShell, {
|
|
3946
4070
|
serverUrl,
|
|
3947
4071
|
title,
|
|
3948
|
-
children: ({ trpc, theme }) => (0,
|
|
4072
|
+
children: ({ trpc, theme }) => (0, import_react33.createElement)(PageComponent, {
|
|
3949
4073
|
trpc,
|
|
3950
4074
|
theme: { isDark: theme.resolvedMode === "dark" },
|
|
3951
4075
|
navigate: (path) => {
|