@pactor-app/ui 1.2.0 → 1.3.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.
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/layout/index.ts
@@ -203,7 +213,7 @@ function PopoverContent({
203
213
  {
204
214
  "data-slot": "popover-content",
205
215
  className: cn(
206
- "z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none duration-200 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
216
+ "z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md shadow-(color:--shadow-color) outline-none duration-200 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
207
217
  className
208
218
  ),
209
219
  ...props
@@ -414,7 +424,7 @@ function navigateMenuItem(menu, bridge) {
414
424
  }
415
425
  bridge.push(menu.path);
416
426
  }
417
- var menuItemClass = "flex w-full cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-left text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50";
427
+ var menuItemClass = "flex w-full cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-left text-sm text-muted-foreground transition-colors hover:bg-(--menu-hover-background) hover:text-(--menu-hover-foreground) disabled:pointer-events-none disabled:opacity-50";
418
428
  function CollapsedGroupFlyout({
419
429
  menu,
420
430
  registry,
@@ -520,7 +530,7 @@ function MenuTree({
520
530
  className: cn(
521
531
  menuItemClass,
522
532
  "mx-auto size-10 justify-center px-0 font-semibold",
523
- menu.id === activeMenuId && "bg-accent font-semibold text-accent-foreground"
533
+ menu.id === activeMenuId && "bg-(--menu-active-background) font-semibold text-(--menu-active-foreground)"
524
534
  ),
525
535
  disabled: menu.disabled,
526
536
  title: menu.title,
@@ -583,7 +593,7 @@ function MenuTree({
583
593
  "data-active": menu.id === activeMenuId || void 0,
584
594
  className: cn(
585
595
  menuItemClass,
586
- menu.id === activeMenuId && "bg-accent font-semibold text-accent-foreground"
596
+ menu.id === activeMenuId && "bg-(--menu-active-background) font-semibold text-(--menu-active-foreground)"
587
597
  ),
588
598
  disabled: menu.disabled,
589
599
  title: menu.title,
@@ -689,7 +699,7 @@ function AdminLayout({
689
699
  {
690
700
  "data-slot": "admin-header",
691
701
  className: cn(
692
- "flex h-14 items-center gap-4 border-b border-border bg-background px-6",
702
+ "flex h-14 items-center gap-4 border-b border-border bg-card px-6",
693
703
  fixedHeader && "sticky top-0 z-20"
694
704
  ),
695
705
  children: [
@@ -716,7 +726,7 @@ function AdminLayout({
716
726
  className: cn(
717
727
  menuItemClass,
718
728
  "size-10 justify-center px-0 font-semibold",
719
- (menu.id === secondaryTopId || menu.id === activeTopId) && "bg-accent text-accent-foreground"
729
+ (menu.id === secondaryTopId || menu.id === activeTopId) && "bg-(--menu-active-background) text-(--menu-active-foreground)"
720
730
  ),
721
731
  disabled: menu.disabled,
722
732
  title: menu.title,
@@ -740,7 +750,7 @@ function AdminLayout({
740
750
  "data-slot": "admin-sidebar",
741
751
  "data-collapsed": effectiveCollapsed || void 0,
742
752
  className: cn(
743
- "shrink-0 overflow-auto border-r border-border bg-background py-2",
753
+ "shrink-0 overflow-auto border-r border-border bg-sidebar py-2",
744
754
  effectiveCollapsed ? "w-16 px-1.5" : "w-52",
745
755
  fixedSider && (mode === "side-full" ? "sticky top-0 h-screen" : "sticky top-14 h-[calc(100vh-3.5rem)]")
746
756
  ),
@@ -787,7 +797,7 @@ function AdminLayout({
787
797
  "data-slot": "admin-collapse-trigger",
788
798
  "aria-label": effectiveCollapsed ? t("pactor.layout.expandSidebar") : t("pactor.layout.collapseSidebar"),
789
799
  "aria-expanded": !effectiveCollapsed,
790
- className: "sticky bottom-0 flex w-full cursor-pointer items-center justify-center border-t border-border bg-background py-2 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
800
+ className: "sticky bottom-0 flex w-full cursor-pointer items-center justify-center border-t border-border bg-sidebar py-2 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
791
801
  onClick: () => setCollapsed((value) => !value),
792
802
  children: effectiveCollapsed ? "\xBB" : "\xAB"
793
803
  }
@@ -801,7 +811,7 @@ function AdminLayout({
801
811
  {
802
812
  "data-slot": "admin-tabs",
803
813
  role: "tablist",
804
- className: "flex items-center gap-1 border-b border-border bg-background px-4 pt-2",
814
+ className: "flex items-center gap-1 border-b border-border bg-card px-4 pt-2",
805
815
  children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
806
816
  "div",
807
817
  {
@@ -810,7 +820,7 @@ function AdminLayout({
810
820
  role: "presentation",
811
821
  className: cn(
812
822
  "inline-flex items-center gap-1 rounded-t-md border border-b-0 border-border px-3 py-1.5 text-sm",
813
- tab.key === currentPath ? "bg-background font-medium text-foreground" : "bg-muted text-muted-foreground"
823
+ tab.key === currentPath ? "bg-card font-medium text-foreground" : "bg-muted text-muted-foreground"
814
824
  ),
815
825
  children: [
816
826
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
@@ -921,7 +931,7 @@ function BlankLayout({ children }) {
921
931
 
922
932
  // src/layout/chat/ChatLayout.tsx
923
933
  var import_permission2 = require("@pactor-app/permission");
924
- var import_react4 = require("react");
934
+ var import_react5 = require("react");
925
935
 
926
936
  // src/ui/tooltip.tsx
927
937
  var import_tooltip = require("@base-ui/react/tooltip");
@@ -997,15 +1007,17 @@ function RailTooltip({
997
1007
 
998
1008
  // src/components/components/Sidebar/index.tsx
999
1009
  var import_runtime2 = require("@pactor-app/runtime");
1000
- var import_lucide_react3 = require("lucide-react");
1010
+ var import_react4 = require("react");
1011
+
1012
+ // src/ui/sidebar.tsx
1013
+ var React = __toESM(require("react"), 1);
1014
+ var import_class_variance_authority2 = require("class-variance-authority");
1015
+ var import_lucide_react4 = require("lucide-react");
1016
+
1017
+ // src/hooks/use-mobile.ts
1001
1018
  var import_react3 = require("react");
1002
- var import_jsx_runtime8 = require("react/jsx-runtime");
1003
- var SidebarDrawerContext = (0, import_react3.createContext)(null);
1004
- function useSidebarDrawer() {
1005
- return (0, import_react3.useContext)(SidebarDrawerContext);
1006
- }
1007
1019
  var MOBILE_MEDIA_QUERY = "(max-width: 767px)";
1008
- function useIsMobileViewport() {
1020
+ function useIsMobile() {
1009
1021
  const [isMobile, setIsMobile] = (0, import_react3.useState)(
1010
1022
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(MOBILE_MEDIA_QUERY).matches
1011
1023
  );
@@ -1023,6 +1035,476 @@ function useIsMobileViewport() {
1023
1035
  }, []);
1024
1036
  return isMobile;
1025
1037
  }
1038
+
1039
+ // src/ui/sheet.tsx
1040
+ var import_dialog = require("@base-ui/react/dialog");
1041
+ var import_lucide_react3 = require("lucide-react");
1042
+ var import_class_variance_authority = require("class-variance-authority");
1043
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1044
+ function Sheet({
1045
+ ...props
1046
+ }) {
1047
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog.Dialog.Root, { "data-slot": "sheet", ...props });
1048
+ }
1049
+ function SheetPortal({
1050
+ ...props
1051
+ }) {
1052
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog.Dialog.Portal, { "data-slot": "sheet-portal", ...props });
1053
+ }
1054
+ function SheetOverlay({
1055
+ className,
1056
+ ...props
1057
+ }) {
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1059
+ import_dialog.Dialog.Backdrop,
1060
+ {
1061
+ "data-slot": "sheet-overlay",
1062
+ className: cn(
1063
+ "fixed inset-0 z-50 bg-(--overlay-background) data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
1064
+ className
1065
+ ),
1066
+ ...props
1067
+ }
1068
+ );
1069
+ }
1070
+ var sheetVariants = (0, import_class_variance_authority.cva)(
1071
+ "fixed z-50 flex flex-col gap-4 border-border bg-popover shadow-lg shadow-(color:--shadow-color) transition ease-in-out data-open:animate-in data-open:duration-300 data-closed:animate-out data-closed:duration-200",
1072
+ {
1073
+ variants: {
1074
+ side: {
1075
+ right: "inset-y-0 right-0 h-full w-3/4 border-l data-open:slide-in-from-right data-closed:slide-out-to-right sm:max-w-sm",
1076
+ left: "inset-y-0 left-0 h-full w-3/4 border-r data-open:slide-in-from-left data-closed:slide-out-to-left sm:max-w-sm",
1077
+ top: "inset-x-0 top-0 border-b data-open:slide-in-from-top data-closed:slide-out-to-top",
1078
+ bottom: "inset-x-0 bottom-0 border-t data-open:slide-in-from-bottom data-closed:slide-out-to-bottom"
1079
+ }
1080
+ },
1081
+ defaultVariants: {
1082
+ side: "right"
1083
+ }
1084
+ }
1085
+ );
1086
+ function SheetContent({
1087
+ className,
1088
+ children,
1089
+ side = "right",
1090
+ ...props
1091
+ }) {
1092
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(SheetPortal, { "data-slot": "sheet-portal", children: [
1093
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SheetOverlay, {}),
1094
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1095
+ import_dialog.Dialog.Popup,
1096
+ {
1097
+ "data-slot": "sheet-content",
1098
+ className: cn(sheetVariants({ side }), className),
1099
+ ...props,
1100
+ children: [
1101
+ children,
1102
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1103
+ import_dialog.Dialog.Close,
1104
+ {
1105
+ "data-slot": "sheet-close",
1106
+ render: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1107
+ "button",
1108
+ {
1109
+ type: "button",
1110
+ className: "absolute top-4 right-4 cursor-pointer rounded-xs opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
1111
+ }
1112
+ ),
1113
+ children: [
1114
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.XIcon, {}),
1115
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "sr-only", children: "Close" })
1116
+ ]
1117
+ }
1118
+ )
1119
+ ]
1120
+ }
1121
+ )
1122
+ ] });
1123
+ }
1124
+ function SheetHeader({ className, ...props }) {
1125
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1126
+ "div",
1127
+ {
1128
+ "data-slot": "sheet-header",
1129
+ className: cn("flex flex-col gap-1.5 p-4", className),
1130
+ ...props
1131
+ }
1132
+ );
1133
+ }
1134
+ function SheetTitle({
1135
+ className,
1136
+ ...props
1137
+ }) {
1138
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1139
+ import_dialog.Dialog.Title,
1140
+ {
1141
+ "data-slot": "sheet-title",
1142
+ className: cn("font-semibold text-foreground", className),
1143
+ ...props
1144
+ }
1145
+ );
1146
+ }
1147
+ function SheetDescription({
1148
+ className,
1149
+ ...props
1150
+ }) {
1151
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1152
+ import_dialog.Dialog.Description,
1153
+ {
1154
+ "data-slot": "sheet-description",
1155
+ className: cn("text-sm text-muted-foreground", className),
1156
+ ...props
1157
+ }
1158
+ );
1159
+ }
1160
+
1161
+ // src/ui/sidebar.tsx
1162
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1163
+ var SIDEBAR_COOKIE_NAME = "sidebar_state";
1164
+ var SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
1165
+ var SIDEBAR_WIDTH = "16rem";
1166
+ var SIDEBAR_WIDTH_MOBILE = "18rem";
1167
+ var SIDEBAR_WIDTH_ICON = "3rem";
1168
+ var SIDEBAR_KEYBOARD_SHORTCUT = "b";
1169
+ var SidebarContext = React.createContext(null);
1170
+ function useSidebar() {
1171
+ const context = React.useContext(SidebarContext);
1172
+ if (!context) {
1173
+ throw new Error("useSidebar must be used within a SidebarProvider.");
1174
+ }
1175
+ return context;
1176
+ }
1177
+ function SidebarProvider({
1178
+ defaultOpen = true,
1179
+ open: openProp,
1180
+ onOpenChange: setOpenProp,
1181
+ className,
1182
+ style,
1183
+ children,
1184
+ ...props
1185
+ }) {
1186
+ const isMobile = useIsMobile();
1187
+ const [openMobile, setOpenMobile] = React.useState(false);
1188
+ const [_open, _setOpen] = React.useState(defaultOpen);
1189
+ const open = openProp ?? _open;
1190
+ const setOpen = React.useCallback(
1191
+ (value) => {
1192
+ const openState = typeof value === "function" ? value(open) : value;
1193
+ if (setOpenProp) {
1194
+ setOpenProp(openState);
1195
+ } else {
1196
+ _setOpen(openState);
1197
+ }
1198
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
1199
+ },
1200
+ [setOpenProp, open]
1201
+ );
1202
+ const toggleSidebar = React.useCallback(() => {
1203
+ return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
1204
+ }, [isMobile, setOpen, setOpenMobile]);
1205
+ React.useEffect(() => {
1206
+ const handleKeyDown = (event) => {
1207
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
1208
+ event.preventDefault();
1209
+ toggleSidebar();
1210
+ }
1211
+ };
1212
+ window.addEventListener("keydown", handleKeyDown);
1213
+ return () => window.removeEventListener("keydown", handleKeyDown);
1214
+ }, [toggleSidebar]);
1215
+ const state = open ? "expanded" : "collapsed";
1216
+ const contextValue = React.useMemo(
1217
+ () => ({
1218
+ state,
1219
+ open,
1220
+ setOpen,
1221
+ isMobile,
1222
+ openMobile,
1223
+ setOpenMobile,
1224
+ toggleSidebar
1225
+ }),
1226
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
1227
+ );
1228
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipProvider, { delay: 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1229
+ "div",
1230
+ {
1231
+ "data-slot": "sidebar-wrapper",
1232
+ style: {
1233
+ "--sidebar-width": SIDEBAR_WIDTH,
1234
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
1235
+ ...style
1236
+ },
1237
+ className: cn(
1238
+ "group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar",
1239
+ className
1240
+ ),
1241
+ ...props,
1242
+ children
1243
+ }
1244
+ ) }) });
1245
+ }
1246
+ function SidebarRoot({
1247
+ side = "left",
1248
+ variant = "sidebar",
1249
+ collapsible = "offcanvas",
1250
+ className,
1251
+ children,
1252
+ ...props
1253
+ }) {
1254
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
1255
+ if (collapsible === "none") {
1256
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1257
+ "div",
1258
+ {
1259
+ "data-slot": "sidebar",
1260
+ className: cn(
1261
+ "flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground",
1262
+ className
1263
+ ),
1264
+ ...props,
1265
+ children
1266
+ }
1267
+ );
1268
+ }
1269
+ if (isMobile) {
1270
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Sheet, { open: openMobile, onOpenChange: setOpenMobile, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1271
+ SheetContent,
1272
+ {
1273
+ "data-sidebar": "sidebar",
1274
+ "data-slot": "sidebar",
1275
+ "data-mobile": "true",
1276
+ className: "w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden",
1277
+ style: {
1278
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE
1279
+ },
1280
+ side,
1281
+ children: [
1282
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(SheetHeader, { className: "sr-only", children: [
1283
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SheetTitle, { children: "Sidebar" }),
1284
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SheetDescription, { children: "Displays the mobile sidebar." })
1285
+ ] }),
1286
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex h-full w-full flex-col", children })
1287
+ ]
1288
+ }
1289
+ ) });
1290
+ }
1291
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1292
+ "div",
1293
+ {
1294
+ className: "group peer hidden text-sidebar-foreground md:block",
1295
+ "data-state": state,
1296
+ "data-collapsible": state === "collapsed" ? collapsible : "",
1297
+ "data-variant": variant,
1298
+ "data-side": side,
1299
+ "data-slot": "sidebar",
1300
+ children: [
1301
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1302
+ "div",
1303
+ {
1304
+ "data-slot": "sidebar-gap",
1305
+ className: cn(
1306
+ "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear",
1307
+ "group-data-[collapsible=offcanvas]:w-0",
1308
+ "group-data-[side=right]:rotate-180",
1309
+ variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)"
1310
+ )
1311
+ }
1312
+ ),
1313
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1314
+ "div",
1315
+ {
1316
+ "data-slot": "sidebar-container",
1317
+ className: cn(
1318
+ "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex",
1319
+ side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
1320
+ variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
1321
+ className
1322
+ ),
1323
+ ...props,
1324
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1325
+ "div",
1326
+ {
1327
+ "data-sidebar": "sidebar",
1328
+ "data-slot": "sidebar-inner",
1329
+ className: "flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm",
1330
+ children
1331
+ }
1332
+ )
1333
+ }
1334
+ )
1335
+ ]
1336
+ }
1337
+ );
1338
+ }
1339
+ function SidebarInset({ className, ...props }) {
1340
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1341
+ "main",
1342
+ {
1343
+ "data-slot": "sidebar-inset",
1344
+ className: cn(
1345
+ "relative flex w-full flex-1 flex-col bg-background",
1346
+ "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
1347
+ className
1348
+ ),
1349
+ ...props
1350
+ }
1351
+ );
1352
+ }
1353
+ function SidebarHeader({ className, ...props }) {
1354
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1355
+ "div",
1356
+ {
1357
+ "data-slot": "sidebar-header",
1358
+ "data-sidebar": "header",
1359
+ className: cn("flex flex-col gap-2 p-2", className),
1360
+ ...props
1361
+ }
1362
+ );
1363
+ }
1364
+ function SidebarFooter({ className, ...props }) {
1365
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1366
+ "div",
1367
+ {
1368
+ "data-slot": "sidebar-footer",
1369
+ "data-sidebar": "footer",
1370
+ className: cn("flex flex-col gap-2 p-2", className),
1371
+ ...props
1372
+ }
1373
+ );
1374
+ }
1375
+ function SidebarContent({ className, ...props }) {
1376
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1377
+ "div",
1378
+ {
1379
+ "data-slot": "sidebar-content",
1380
+ "data-sidebar": "content",
1381
+ className: cn(
1382
+ "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
1383
+ className
1384
+ ),
1385
+ ...props
1386
+ }
1387
+ );
1388
+ }
1389
+ function renderAsChild(children, dataSlot, className, rest) {
1390
+ if (!React.isValidElement(children)) {
1391
+ return null;
1392
+ }
1393
+ return React.cloneElement(children, {
1394
+ "data-slot": dataSlot,
1395
+ className: cn(
1396
+ className,
1397
+ children.props.className
1398
+ ),
1399
+ ...rest
1400
+ });
1401
+ }
1402
+ function SidebarMenu({ className, ...props }) {
1403
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1404
+ "ul",
1405
+ {
1406
+ "data-slot": "sidebar-menu",
1407
+ "data-sidebar": "menu",
1408
+ className: cn("flex w-full min-w-0 flex-col gap-1", className),
1409
+ ...props
1410
+ }
1411
+ );
1412
+ }
1413
+ function SidebarMenuItem({ className, ...props }) {
1414
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1415
+ "li",
1416
+ {
1417
+ "data-slot": "sidebar-menu-item",
1418
+ "data-sidebar": "menu-item",
1419
+ className: cn("group/menu-item relative", className),
1420
+ ...props
1421
+ }
1422
+ );
1423
+ }
1424
+ var sidebarMenuButtonVariants = (0, import_class_variance_authority2.cva)(
1425
+ "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
1426
+ {
1427
+ variants: {
1428
+ variant: {
1429
+ default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
1430
+ outline: "bg-sidebar shadow-[0_0_0_1px_var(--sidebar-border)] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_var(--sidebar-accent)]"
1431
+ },
1432
+ size: {
1433
+ default: "h-8 text-sm",
1434
+ sm: "h-7 text-xs",
1435
+ lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!"
1436
+ }
1437
+ },
1438
+ defaultVariants: {
1439
+ variant: "default",
1440
+ size: "default"
1441
+ }
1442
+ }
1443
+ );
1444
+ function SidebarMenuButton({
1445
+ asChild = false,
1446
+ isActive = false,
1447
+ variant = "default",
1448
+ size = "default",
1449
+ tooltip,
1450
+ className,
1451
+ children,
1452
+ ...props
1453
+ }) {
1454
+ const { isMobile, state } = useSidebar();
1455
+ const cls = cn(sidebarMenuButtonVariants({ variant, size }), className);
1456
+ const button = asChild ? renderAsChild(children, "sidebar-menu-button", cls, {
1457
+ "data-sidebar": "menu-button",
1458
+ "data-size": size,
1459
+ "data-active": isActive,
1460
+ ...props
1461
+ }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1462
+ "button",
1463
+ {
1464
+ "data-slot": "sidebar-menu-button",
1465
+ "data-sidebar": "menu-button",
1466
+ "data-size": size,
1467
+ "data-active": isActive,
1468
+ className: cls,
1469
+ ...props,
1470
+ children
1471
+ }
1472
+ );
1473
+ if (!tooltip) {
1474
+ return button;
1475
+ }
1476
+ if (typeof tooltip === "string") {
1477
+ tooltip = {
1478
+ children: tooltip
1479
+ };
1480
+ }
1481
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
1482
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { render: button }),
1483
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1484
+ TooltipContent,
1485
+ {
1486
+ side: "right",
1487
+ align: "center",
1488
+ hidden: state !== "collapsed" || isMobile,
1489
+ ...tooltip
1490
+ }
1491
+ )
1492
+ ] });
1493
+ }
1494
+
1495
+ // src/components/components/Sidebar/index.tsx
1496
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1497
+ function useSidebarDrawer() {
1498
+ try {
1499
+ const ctx = useSidebar();
1500
+ return {
1501
+ close: () => ctx.setOpenMobile(false),
1502
+ collapsed: ctx.state === "collapsed"
1503
+ };
1504
+ } catch {
1505
+ return null;
1506
+ }
1507
+ }
1026
1508
  function useOptionalRenderer() {
1027
1509
  try {
1028
1510
  return (0, import_runtime2.useRenderer)();
@@ -1030,16 +1512,61 @@ function useOptionalRenderer() {
1030
1512
  return null;
1031
1513
  }
1032
1514
  }
1033
- function SidebarContent({ content }) {
1515
+ function SidebarContentSlot({ content }) {
1034
1516
  const renderer = useOptionalRenderer();
1035
1517
  if (renderer !== null && typeof content === "object" && content !== null && !("$$typeof" in content) && "type" in content) {
1036
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: renderer.renderChildren([content]) });
1518
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: renderer.renderChildren([content]) });
1037
1519
  }
1038
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: content });
1520
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: content });
1039
1521
  }
1040
1522
  function isBrandObject(brand) {
1041
1523
  return typeof brand === "object" && brand !== null && !("$$typeof" in brand) && "title" in brand;
1042
1524
  }
1525
+ function BrandNode({ brand, collapsed }) {
1526
+ if (brand === void 0 || brand === null) {
1527
+ return null;
1528
+ }
1529
+ if (isBrandObject(brand)) {
1530
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1531
+ brand.logo ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1532
+ "img",
1533
+ {
1534
+ "data-slot": "sidebar-brand-logo",
1535
+ src: brand.logo,
1536
+ alt: brand.title,
1537
+ className: "size-6 shrink-0"
1538
+ }
1539
+ ) : null,
1540
+ collapsed ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "truncate text-sm font-semibold", children: brand.title })
1541
+ ] });
1542
+ }
1543
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: brand });
1544
+ }
1545
+ function SidebarNavItems({ items }) {
1546
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarMenu, { children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarNavEntry, { item, depth: 0 }, item.href ?? item.label ?? index)) });
1547
+ }
1548
+ function SidebarNavEntry({ item, depth }) {
1549
+ const iconNode = item.icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: item.icon, size: "sm" }) : null;
1550
+ const labelNode = item.label;
1551
+ const button = item.href ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarMenuButton, { asChild: true, tooltip: item.label, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("a", { href: item.href, children: [
1552
+ iconNode,
1553
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: labelNode })
1554
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SidebarMenuButton, { tooltip: item.label, children: [
1555
+ iconNode,
1556
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: labelNode })
1557
+ ] });
1558
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SidebarMenuItem, { children: [
1559
+ button,
1560
+ item.children && item.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("ml-4"), children: item.children.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1561
+ SidebarNavEntry,
1562
+ {
1563
+ item: child,
1564
+ depth: depth + 1
1565
+ },
1566
+ child.href ?? child.label ?? index
1567
+ )) })
1568
+ ] });
1569
+ }
1043
1570
  function Sidebar({
1044
1571
  brand,
1045
1572
  items = [],
@@ -1052,222 +1579,125 @@ function Sidebar({
1052
1579
  className,
1053
1580
  style,
1054
1581
  children
1582
+ }) {
1583
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1584
+ SidebarProvider,
1585
+ {
1586
+ defaultOpen: true,
1587
+ className,
1588
+ style,
1589
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1590
+ SidebarInner,
1591
+ {
1592
+ brand,
1593
+ items,
1594
+ content,
1595
+ sidebarFooter,
1596
+ collapsible,
1597
+ onCollapse,
1598
+ locationKey,
1599
+ drawer,
1600
+ children
1601
+ }
1602
+ )
1603
+ }
1604
+ );
1605
+ }
1606
+ function SidebarInner({
1607
+ brand,
1608
+ items = [],
1609
+ content,
1610
+ sidebarFooter,
1611
+ collapsible,
1612
+ onCollapse,
1613
+ locationKey,
1614
+ drawer = true,
1615
+ children
1055
1616
  }) {
1056
1617
  const { t } = (0, import_runtime2.useI18n)();
1057
- const isMobile = useIsMobileViewport();
1058
- const [drawerOpen, setDrawerOpen] = (0, import_react3.useState)(false);
1059
- const [collapsed, setCollapsed] = (0, import_react3.useState)(false);
1060
- const collapsedEffective = collapsible === true && collapsed && !isMobile;
1061
- const close = (0, import_react3.useCallback)(() => setDrawerOpen(false), []);
1062
- const toggleCollapsed = () => {
1063
- const next = !collapsed;
1064
- setCollapsed(next);
1065
- onCollapse?.(next);
1066
- };
1067
- const [trackedLocationKey, setTrackedLocationKey] = (0, import_react3.useState)(locationKey);
1068
- if (trackedLocationKey !== locationKey) {
1069
- setTrackedLocationKey(locationKey);
1070
- setDrawerOpen(false);
1071
- }
1072
- (0, import_react3.useEffect)(() => {
1073
- if (!drawerOpen) {
1074
- return;
1618
+ const isMobile = useIsMobile();
1619
+ const { state, setOpenMobile, toggleSidebar } = useSidebar();
1620
+ const collapsed = state === "collapsed";
1621
+ const prevCollapsed = (0, import_react4.useRef)(collapsed);
1622
+ (0, import_react4.useEffect)(() => {
1623
+ if (prevCollapsed.current !== collapsed) {
1624
+ prevCollapsed.current = collapsed;
1625
+ onCollapse?.(collapsed);
1075
1626
  }
1076
- const onKeyDown = (event) => {
1077
- if (event.key === "Escape") {
1078
- setDrawerOpen(false);
1079
- }
1080
- };
1081
- window.addEventListener("keydown", onKeyDown);
1082
- return () => window.removeEventListener("keydown", onKeyDown);
1083
- }, [drawerOpen]);
1084
- const brandNode = isBrandObject(brand) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1085
- brand.logo ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1086
- "img",
1627
+ }, [collapsed, onCollapse]);
1628
+ (0, import_react4.useEffect)(() => {
1629
+ if (locationKey !== void 0) {
1630
+ setOpenMobile(false);
1631
+ }
1632
+ }, [locationKey, setOpenMobile]);
1633
+ const collapsedEffective = collapsible === true && collapsed && !isMobile;
1634
+ const brandNode = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(BrandNode, { brand, collapsed: collapsedEffective });
1635
+ const sidebarContent = content !== void 0 && content !== null ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarContentSlot, { content }) : items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarNavItems, { items }) : null;
1636
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
1637
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1638
+ SidebarRoot,
1087
1639
  {
1088
- "data-slot": "sidebar-brand-logo",
1089
- src: brand.logo,
1090
- alt: brand.title,
1091
- className: "size-6 shrink-0"
1640
+ collapsible: collapsible ? "icon" : "offcanvas",
1641
+ children: [
1642
+ (brand !== void 0 || collapsible) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1643
+ "div",
1644
+ {
1645
+ "data-slot": "sidebar-brand",
1646
+ className: cn(
1647
+ "flex h-14 shrink-0 items-center gap-2 px-2",
1648
+ collapsedEffective && "justify-center px-0"
1649
+ ),
1650
+ children: [
1651
+ collapsedEffective ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: brandNode }),
1652
+ collapsible && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1653
+ "button",
1654
+ {
1655
+ type: "button",
1656
+ "data-slot": "sidebar-collapse-trigger",
1657
+ "aria-label": collapsedEffective ? t("pactor.layout.expandSidebar") : t("pactor.layout.collapseSidebar"),
1658
+ "aria-expanded": !collapsedEffective,
1659
+ className: "flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-sidebar-foreground/60 transition-colors hover:bg-sidebar-accent hover:text-sidebar-foreground",
1660
+ onClick: toggleSidebar,
1661
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: collapsedEffective ? "chevron-right" : "chevron-left", size: 16 })
1662
+ }
1663
+ )
1664
+ ]
1665
+ }
1666
+ ) }),
1667
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarContent, { children: sidebarContent }),
1668
+ sidebarFooter !== void 0 && sidebarFooter !== null && !collapsedEffective && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SidebarFooter, { children: sidebarFooter })
1669
+ ]
1092
1670
  }
1093
- ) : null,
1094
- collapsedEffective ? null : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate text-sm font-semibold", children: brand.title })
1095
- ] }) : brand;
1096
- const collapseTrigger = collapsible && !isMobile ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1097
- "button",
1098
- {
1099
- type: "button",
1100
- "data-slot": "sidebar-collapse-trigger",
1101
- "aria-label": collapsedEffective ? t("pactor.layout.expandSidebar") : t("pactor.layout.collapseSidebar"),
1102
- "aria-expanded": !collapsedEffective,
1103
- title: collapsedEffective ? t("pactor.layout.expandSidebar") : t("pactor.layout.collapseSidebar"),
1104
- className: cn(
1105
- "cursor-pointer flex size-8 shrink-0 items-center justify-center rounded-md text-sidebar-foreground/60 transition-colors hover:bg-sidebar-accent hover:text-sidebar-foreground"
1106
- ),
1107
- onClick: toggleCollapsed,
1108
- children: collapsedEffective ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.ChevronRight, { "aria-hidden": true, className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react3.ChevronLeft, { "aria-hidden": true, className: "size-4" })
1109
- }
1110
- ) : null;
1111
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1112
- SidebarDrawerContext.Provider,
1113
- {
1114
- value: { close, collapsed: collapsedEffective },
1115
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1671
+ ),
1672
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SidebarInset, { children: [
1673
+ drawer && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1116
1674
  "div",
1117
1675
  {
1118
- "data-slot": "sidebar-layout",
1119
- className: cn("flex min-h-screen w-full", className),
1120
- style,
1676
+ "data-slot": "sidebar-topbar",
1677
+ className: "flex h-14 items-center gap-2 border-b border-sidebar-border bg-sidebar px-3 md:hidden",
1121
1678
  children: [
1122
- drawer && drawerOpen ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1123
- "div",
1124
- {
1125
- "data-slot": "sidebar-scrim",
1126
- "aria-hidden": true,
1127
- className: "fixed inset-0 z-40 bg-black/40 md:hidden",
1128
- onClick: close
1129
- }
1130
- ) : null,
1131
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1132
- "aside",
1679
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1680
+ "button",
1133
1681
  {
1134
- "data-slot": "sidebar",
1135
- "data-collapsed": collapsedEffective || void 0,
1136
- "data-open": drawerOpen ? "true" : "false",
1137
- inert: drawer && isMobile && !drawerOpen ? true : void 0,
1138
- className: cn(
1139
- "flex shrink-0 flex-col border-r border-sidebar-border bg-sidebar text-sidebar-foreground transition-[width,transform]",
1140
- collapsedEffective ? "w-16" : "w-60",
1141
- // 移动端覆盖抽屉:退出文档流,关闭时移出屏幕
1142
- drawer && "max-md:fixed max-md:inset-y-0 max-md:left-0 max-md:z-50 max-md:w-60 max-md:-translate-x-full max-md:data-[open=true]:translate-x-0"
1143
- ),
1144
- children: [
1145
- brand !== void 0 || collapseTrigger !== null ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1146
- "div",
1147
- {
1148
- "data-slot": "sidebar-brand",
1149
- className: cn(
1150
- "flex h-14 shrink-0 items-center gap-2 border-b border-sidebar-border px-4",
1151
- // 移动端品牌维持顶栏现状:抽屉内不重复渲染品牌行
1152
- "max-md:hidden",
1153
- collapsedEffective && "justify-center px-2"
1154
- ),
1155
- children: [
1156
- collapsedEffective ? null : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: brandNode }),
1157
- collapseTrigger
1158
- ]
1159
- }
1160
- ) : null,
1161
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1162
- "nav",
1163
- {
1164
- "data-slot": "sidebar-nav",
1165
- className: "min-h-0 flex-1 overflow-auto p-2",
1166
- children: content !== void 0 && content !== null ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SidebarContent, { content }) : items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1167
- SidebarEntry,
1168
- {
1169
- item,
1170
- depth: 0,
1171
- collapsed: collapsedEffective
1172
- },
1173
- item.href ?? item.label ?? index
1174
- ))
1175
- }
1176
- ),
1177
- sidebarFooter !== void 0 && sidebarFooter !== null && !collapsedEffective ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1178
- "div",
1179
- {
1180
- "data-slot": "sidebar-footer",
1181
- className: "shrink-0 border-t border-sidebar-border p-2",
1182
- children: sidebarFooter
1183
- }
1184
- ) : null
1185
- ]
1682
+ type: "button",
1683
+ "data-slot": "sidebar-menu-trigger",
1684
+ "aria-label": t("pactor.layout.openNavigation"),
1685
+ className: "flex size-8 items-center justify-center rounded-md text-sidebar-foreground/60 transition-colors hover:bg-sidebar-accent hover:text-sidebar-foreground",
1686
+ onClick: toggleSidebar,
1687
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: "menu", size: 18 })
1186
1688
  }
1187
1689
  ),
1188
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1189
- "main",
1190
- {
1191
- "data-slot": "sidebar-content",
1192
- className: "flex min-w-0 flex-1 flex-col",
1193
- children: [
1194
- drawer ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1195
- "div",
1196
- {
1197
- "data-slot": "sidebar-topbar",
1198
- className: "flex h-14 items-center gap-2 border-b border-sidebar-border bg-sidebar px-3 md:hidden",
1199
- children: [
1200
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1201
- "button",
1202
- {
1203
- type: "button",
1204
- "data-slot": "sidebar-menu-trigger",
1205
- "aria-label": t("pactor.layout.openNavigation"),
1206
- "aria-expanded": drawerOpen,
1207
- className: "flex size-8 items-center justify-center rounded-md text-sidebar-foreground/60 transition-colors hover:bg-sidebar-accent hover:text-sidebar-foreground",
1208
- onClick: () => setDrawerOpen(true),
1209
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: "menu", size: 18 })
1210
- }
1211
- ),
1212
- brandNode
1213
- ]
1214
- }
1215
- ) : null,
1216
- children
1217
- ]
1218
- }
1219
- )
1690
+ brandNode
1220
1691
  ]
1221
1692
  }
1222
- )
1223
- }
1224
- );
1225
- }
1226
- function SidebarEntry({
1227
- item,
1228
- depth,
1229
- collapsed
1230
- }) {
1231
- const entryClass = cn(
1232
- "flex w-full items-center gap-2 rounded-md px-3 py-2 text-left text-sm transition-colors",
1233
- "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
1234
- collapsed && "justify-center px-0"
1235
- );
1236
- const indentStyle = !collapsed && depth > 0 ? { paddingLeft: 12 + depth * 16 } : void 0;
1237
- const labelNode = collapsed ? null : item.label;
1238
- const iconNode = item.icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon, { name: item.icon, size: "sm" }) : null;
1239
- const entry = item.href ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1240
- "a",
1241
- {
1242
- "data-slot": "sidebar-item",
1243
- href: item.href,
1244
- className: entryClass,
1245
- style: indentStyle,
1246
- children: [
1247
- iconNode,
1248
- labelNode
1249
- ]
1250
- }
1251
- ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { "data-slot": "sidebar-item", className: entryClass, style: indentStyle, children: [
1252
- iconNode,
1253
- labelNode
1254
- ] });
1255
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-slot": "sidebar-entry", children: [
1256
- collapsed ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RailTooltip, { label: item.label, children: entry }) : entry,
1257
- item.children?.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1258
- SidebarEntry,
1259
- {
1260
- item: child,
1261
- depth: depth + 1,
1262
- collapsed
1263
- },
1264
- child.href ?? child.label ?? index
1265
- ))
1693
+ ),
1694
+ children
1695
+ ] })
1266
1696
  ] });
1267
1697
  }
1268
1698
 
1269
1699
  // src/components/components/Menu/index.tsx
1270
- var import_jsx_runtime9 = require("react/jsx-runtime");
1700
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1271
1701
  function Menu2({
1272
1702
  items = [],
1273
1703
  mode = "inline",
@@ -1279,7 +1709,7 @@ function Menu2({
1279
1709
  const drawer = useSidebarDrawer();
1280
1710
  const collapsed = mode === "inline" && drawer?.collapsed === true;
1281
1711
  let previousGroup;
1282
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1712
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1283
1713
  "nav",
1284
1714
  {
1285
1715
  "data-slot": "menu",
@@ -1296,8 +1726,8 @@ function Menu2({
1296
1726
  groupLabel = item.group;
1297
1727
  }
1298
1728
  previousGroup = item.group;
1299
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-slot": "menu-group-entry", children: [
1300
- groupLabel !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1729
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { "data-slot": "menu-group-entry", children: [
1730
+ groupLabel !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1301
1731
  "div",
1302
1732
  {
1303
1733
  "data-slot": "menu-group",
@@ -1305,7 +1735,7 @@ function Menu2({
1305
1735
  children: groupLabel
1306
1736
  }
1307
1737
  ),
1308
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1738
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1309
1739
  MenuEntry,
1310
1740
  {
1311
1741
  item,
@@ -1330,7 +1760,7 @@ function MenuEntry({
1330
1760
  collapsed = false
1331
1761
  }) {
1332
1762
  const selected = item.key === selectedKey;
1333
- const button = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1763
+ const button = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1334
1764
  "button",
1335
1765
  {
1336
1766
  type: "button",
@@ -1341,7 +1771,7 @@ function MenuEntry({
1341
1771
  "flex w-full items-center gap-2 rounded-md text-sm transition-colors",
1342
1772
  mode === "horizontal" ? "px-3 py-2" : "px-3 py-2 text-left",
1343
1773
  collapsed && "justify-center px-0",
1344
- selected ? "bg-accent font-medium text-accent-foreground" : "cursor-pointer text-muted-foreground hover:bg-accent/50 hover:text-foreground",
1774
+ selected ? "bg-(--menu-active-background) font-medium text-(--menu-active-foreground)" : "cursor-pointer text-muted-foreground hover:bg-(--menu-hover-background)/50 hover:text-foreground",
1345
1775
  item.disabled && "cursor-not-allowed opacity-50 hover:bg-transparent hover:text-muted-foreground"
1346
1776
  ),
1347
1777
  style: mode === "inline" && depth > 0 && !collapsed ? { paddingLeft: 12 + depth * 16 } : void 0,
@@ -1351,10 +1781,10 @@ function MenuEntry({
1351
1781
  }
1352
1782
  },
1353
1783
  children: [
1354
- item.icon ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon, { name: item.icon, size: "sm" }) : null,
1355
- collapsed ? null : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "min-w-0 flex-1 truncate text-left", children: item.label }),
1356
- item.dot && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-slot": "menu-item-dot", className: "size-1.5 shrink-0 rounded-full bg-destructive" }) : null,
1357
- item.badge !== void 0 && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1784
+ item.icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: item.icon, size: "sm" }) : null,
1785
+ collapsed ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "min-w-0 flex-1 truncate text-left", children: item.label }),
1786
+ item.dot && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { "data-slot": "menu-item-dot", className: "size-1.5 shrink-0 rounded-full bg-destructive" }) : null,
1787
+ item.badge !== void 0 && !collapsed ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1358
1788
  "span",
1359
1789
  {
1360
1790
  "data-slot": "menu-item-badge",
@@ -1365,9 +1795,9 @@ function MenuEntry({
1365
1795
  ]
1366
1796
  }
1367
1797
  );
1368
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { "data-slot": "menu-entry", "data-key": item.key, children: [
1369
- collapsed ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RailTooltip, { label: item.label, children: button }) : button,
1370
- item.children?.map((child) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1798
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { "data-slot": "menu-entry", "data-key": item.key, children: [
1799
+ collapsed ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RailTooltip, { label: item.label, children: button }) : button,
1800
+ item.children?.map((child) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1371
1801
  MenuEntry,
1372
1802
  {
1373
1803
  item: child,
@@ -1383,7 +1813,7 @@ function MenuEntry({
1383
1813
  }
1384
1814
 
1385
1815
  // src/layout/chat/ChatLayout.tsx
1386
- var import_jsx_runtime10 = require("react/jsx-runtime");
1816
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1387
1817
  function ChatLayout({
1388
1818
  brand,
1389
1819
  menu,
@@ -1398,7 +1828,7 @@ function ChatLayout({
1398
1828
  sidebarFooter,
1399
1829
  children
1400
1830
  }) {
1401
- const registryMenus = (0, import_react4.useMemo)(() => {
1831
+ const registryMenus = (0, import_react5.useMemo)(() => {
1402
1832
  if (menu !== void 0 || registry === void 0) {
1403
1833
  return [];
1404
1834
  }
@@ -1407,10 +1837,10 @@ function ChatLayout({
1407
1837
  return visible.flatMap((item) => menuItemToMenuData(item));
1408
1838
  }, [menu, registry, permissionChecker]);
1409
1839
  const menuItems = menu ?? registryMenus;
1410
- const [bridgePath, setBridgePath] = (0, import_react4.useState)(
1840
+ const [bridgePath, setBridgePath] = (0, import_react5.useState)(
1411
1841
  () => bridge?.getLocation().pathname ?? "/"
1412
1842
  );
1413
- (0, import_react4.useEffect)(() => {
1843
+ (0, import_react5.useEffect)(() => {
1414
1844
  if (bridge === void 0) {
1415
1845
  return;
1416
1846
  }
@@ -1418,7 +1848,7 @@ function ChatLayout({
1418
1848
  setBridgePath(location.pathname);
1419
1849
  });
1420
1850
  }, [bridge]);
1421
- const activeKey = (0, import_react4.useMemo)(() => {
1851
+ const activeKey = (0, import_react5.useMemo)(() => {
1422
1852
  if (activeMenuKey !== void 0) {
1423
1853
  return activeMenuKey;
1424
1854
  }
@@ -1438,7 +1868,7 @@ function ChatLayout({
1438
1868
  bridge.push(item.path);
1439
1869
  }
1440
1870
  };
1441
- const sidebarContent = sidebar !== void 0 && sidebar !== null ? sidebar : menuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1871
+ const sidebarContent = sidebar !== void 0 && sidebar !== null ? sidebar : menuItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1442
1872
  Menu2,
1443
1873
  {
1444
1874
  items: menuItems.map((item) => chatMenuItemToUiMenuItem(item)),
@@ -1446,7 +1876,7 @@ function ChatLayout({
1446
1876
  onSelect: handleSelect
1447
1877
  }
1448
1878
  ) : void 0;
1449
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1879
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1450
1880
  Sidebar,
1451
1881
  {
1452
1882
  brand,
@@ -1454,7 +1884,7 @@ function ChatLayout({
1454
1884
  sidebarFooter,
1455
1885
  collapsible,
1456
1886
  locationKey: routeProp?.path ?? bridgePath,
1457
- children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1887
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1458
1888
  "div",
1459
1889
  {
1460
1890
  "data-slot": "chat-layout-content",
@@ -1508,14 +1938,14 @@ function menuItemToMenuData(item) {
1508
1938
  }
1509
1939
 
1510
1940
  // src/ui/card.tsx
1511
- var import_jsx_runtime11 = require("react/jsx-runtime");
1941
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1512
1942
  function Card({ className, ...props }) {
1513
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1943
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1514
1944
  "div",
1515
1945
  {
1516
1946
  "data-slot": "card",
1517
1947
  className: cn(
1518
- "flex flex-col gap-6 rounded-xl border border-border bg-card py-6 text-card-foreground shadow-sm",
1948
+ "flex flex-col gap-6 rounded-xl border border-border bg-card py-6 text-card-foreground shadow-(--card-shadow)",
1519
1949
  className
1520
1950
  ),
1521
1951
  ...props
@@ -1523,7 +1953,7 @@ function Card({ className, ...props }) {
1523
1953
  );
1524
1954
  }
1525
1955
  function CardHeader({ className, ...props }) {
1526
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1956
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1527
1957
  "div",
1528
1958
  {
1529
1959
  "data-slot": "card-header",
@@ -1536,7 +1966,7 @@ function CardHeader({ className, ...props }) {
1536
1966
  );
1537
1967
  }
1538
1968
  function CardTitle({ className, ...props }) {
1539
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1969
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1540
1970
  "div",
1541
1971
  {
1542
1972
  "data-slot": "card-title",
@@ -1546,7 +1976,7 @@ function CardTitle({ className, ...props }) {
1546
1976
  );
1547
1977
  }
1548
1978
  function CardContent({ className, ...props }) {
1549
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1979
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1550
1980
  "div",
1551
1981
  {
1552
1982
  "data-slot": "card-content",
@@ -1557,26 +1987,26 @@ function CardContent({ className, ...props }) {
1557
1987
  }
1558
1988
 
1559
1989
  // src/layout/basic/LoginLayout.tsx
1560
- var import_jsx_runtime12 = require("react/jsx-runtime");
1990
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1561
1991
  function LoginLayout({
1562
1992
  variant = "center",
1563
1993
  brand,
1564
1994
  children
1565
1995
  }) {
1566
- const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
1996
+ const brandBlock = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { "data-slot": "login-brand", className: "flex flex-col items-center gap-2", children: [
1567
1997
  brand.logo,
1568
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
1569
- brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
1998
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h1", { className: "text-xl font-semibold", children: brand.title }),
1999
+ brand.description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "text-sm text-muted-foreground", children: brand.description })
1570
2000
  ] });
1571
2001
  if (variant === "split") {
1572
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2002
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1573
2003
  "div",
1574
2004
  {
1575
2005
  "data-slot": "login-layout",
1576
2006
  "data-variant": "split",
1577
2007
  className: "grid min-h-screen grid-cols-2 bg-background text-foreground",
1578
2008
  children: [
1579
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2009
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1580
2010
  "div",
1581
2011
  {
1582
2012
  "data-slot": "login-brand-panel",
@@ -1584,7 +2014,7 @@ function LoginLayout({
1584
2014
  children: brandBlock
1585
2015
  }
1586
2016
  ),
1587
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2017
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1588
2018
  "div",
1589
2019
  {
1590
2020
  "data-slot": "login-form-panel",
@@ -1596,46 +2026,46 @@ function LoginLayout({
1596
2026
  }
1597
2027
  );
1598
2028
  }
1599
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2029
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1600
2030
  "div",
1601
2031
  {
1602
2032
  "data-slot": "login-layout",
1603
2033
  "data-variant": "center",
1604
2034
  className: "flex min-h-screen items-center justify-center bg-muted/40 text-foreground",
1605
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
1606
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(CardHeader, { className: "px-6", children: [
1607
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
2035
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Card, { "data-slot": "login-card", className: "w-full max-w-sm gap-4 py-6", children: [
2036
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(CardHeader, { className: "px-6", children: [
2037
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CardTitle, { className: "sr-only", children: brand.title }),
1608
2038
  brandBlock
1609
2039
  ] }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
2040
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CardContent, { className: "flex flex-col gap-4 px-6", children })
1611
2041
  ] })
1612
2042
  }
1613
2043
  );
1614
2044
  }
1615
2045
 
1616
2046
  // src/layout/basic/LandingLayout.tsx
1617
- var import_jsx_runtime13 = require("react/jsx-runtime");
2047
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1618
2048
  function LandingLayout({
1619
2049
  navbar,
1620
2050
  footer,
1621
2051
  children
1622
2052
  }) {
1623
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2053
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1624
2054
  "div",
1625
2055
  {
1626
2056
  "data-slot": "landing-layout",
1627
2057
  className: "flex min-h-screen flex-col bg-background text-foreground",
1628
2058
  children: [
1629
- navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2059
+ navbar !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1630
2060
  "header",
1631
2061
  {
1632
2062
  "data-slot": "landing-navbar",
1633
- className: "border-b border-border bg-background",
2063
+ className: "border-b border-border bg-card",
1634
2064
  children: navbar
1635
2065
  }
1636
2066
  ),
1637
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
1638
- footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2067
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("main", { "data-slot": "landing-content", className: "flex-1", children }),
2068
+ footer !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1639
2069
  "footer",
1640
2070
  {
1641
2071
  "data-slot": "landing-footer",