@logickernel/frame 0.7.0 → 0.8.2
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/README.md +39 -33
- package/dist/index.d.mts +58 -29
- package/dist/index.d.ts +58 -29
- package/dist/index.js +139 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +138 -93
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -4
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import * as React2 from 'react';
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import Link from 'next/link';
|
|
4
|
-
import { usePathname, useRouter } from 'next/navigation';
|
|
5
|
-
import { signOut } from 'next-auth/react';
|
|
6
1
|
import * as LucideIcons from 'lucide-react';
|
|
7
2
|
import { PanelLeft, ChevronRight, Check, Circle, ChevronsUpDown, BadgeCheck, LogOut, GalleryVerticalEnd } from 'lucide-react';
|
|
8
3
|
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
|
4
|
+
import * as React2 from 'react';
|
|
5
|
+
import { useState, useEffect } from 'react';
|
|
9
6
|
import { Slot } from '@radix-ui/react-slot';
|
|
10
7
|
import { cva } from 'class-variance-authority';
|
|
11
8
|
import { clsx } from 'clsx';
|
|
@@ -14,8 +11,11 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
|
14
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
15
12
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
16
13
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
14
|
+
import Link from 'next/link';
|
|
15
|
+
import { usePathname, useRouter } from 'next/navigation';
|
|
16
|
+
import { signOut } from 'next-auth/react';
|
|
17
17
|
|
|
18
|
-
// src/components/
|
|
18
|
+
// src/components/NavMain.tsx
|
|
19
19
|
var Collapsible = CollapsiblePrimitive.Root;
|
|
20
20
|
var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
|
|
21
21
|
var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
|
|
@@ -54,7 +54,10 @@ function useSidebar() {
|
|
|
54
54
|
return context;
|
|
55
55
|
}
|
|
56
56
|
function useIsMobile() {
|
|
57
|
-
const [isMobile, setIsMobile] = React2.useState(
|
|
57
|
+
const [isMobile, setIsMobile] = React2.useState(() => {
|
|
58
|
+
if (typeof window === "undefined") return false;
|
|
59
|
+
return window.matchMedia("(max-width: 768px)").matches;
|
|
60
|
+
});
|
|
58
61
|
React2.useEffect(() => {
|
|
59
62
|
const mql = window.matchMedia("(max-width: 768px)");
|
|
60
63
|
const onChange = () => setIsMobile(mql.matches);
|
|
@@ -76,7 +79,19 @@ var SidebarProvider = React2.forwardRef(
|
|
|
76
79
|
}, ref) => {
|
|
77
80
|
const isMobile = useIsMobile();
|
|
78
81
|
const [openMobile, setOpenMobile] = React2.useState(false);
|
|
79
|
-
const
|
|
82
|
+
const getInitialState = React2.useCallback(() => {
|
|
83
|
+
if (typeof document === "undefined") return defaultOpen;
|
|
84
|
+
const cookies = document.cookie.split(";");
|
|
85
|
+
const sidebarCookie = cookies.find(
|
|
86
|
+
(cookie) => cookie.trim().startsWith(`${SIDEBAR_COOKIE_NAME}=`)
|
|
87
|
+
);
|
|
88
|
+
if (sidebarCookie) {
|
|
89
|
+
const value = sidebarCookie.split("=")[1];
|
|
90
|
+
return value === "true";
|
|
91
|
+
}
|
|
92
|
+
return defaultOpen;
|
|
93
|
+
}, [defaultOpen]);
|
|
94
|
+
const [_open, _setOpen] = React2.useState(getInitialState);
|
|
80
95
|
const open = openProp ?? _open;
|
|
81
96
|
const setOpen = React2.useCallback(
|
|
82
97
|
(value) => {
|
|
@@ -91,7 +106,11 @@ var SidebarProvider = React2.forwardRef(
|
|
|
91
106
|
[setOpenProp, open]
|
|
92
107
|
);
|
|
93
108
|
const toggleSidebar = React2.useCallback(() => {
|
|
94
|
-
|
|
109
|
+
if (isMobile) {
|
|
110
|
+
setOpenMobile((open2) => !open2);
|
|
111
|
+
} else {
|
|
112
|
+
setOpen((open2) => !open2);
|
|
113
|
+
}
|
|
95
114
|
}, [isMobile, setOpen, setOpenMobile]);
|
|
96
115
|
React2.useEffect(() => {
|
|
97
116
|
const handleKeyDown = (event) => {
|
|
@@ -103,6 +122,15 @@ var SidebarProvider = React2.forwardRef(
|
|
|
103
122
|
window.addEventListener("keydown", handleKeyDown);
|
|
104
123
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
105
124
|
}, [toggleSidebar]);
|
|
125
|
+
React2.useEffect(() => {
|
|
126
|
+
if (isMobile && openMobile) {
|
|
127
|
+
const originalStyle = window.getComputedStyle(document.body).overflow;
|
|
128
|
+
document.body.style.overflow = "hidden";
|
|
129
|
+
return () => {
|
|
130
|
+
document.body.style.overflow = originalStyle;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}, [isMobile, openMobile]);
|
|
106
134
|
const state = open ? "expanded" : "collapsed";
|
|
107
135
|
const contextValue = React2.useMemo(
|
|
108
136
|
() => ({
|
|
@@ -126,7 +154,7 @@ var SidebarProvider = React2.forwardRef(
|
|
|
126
154
|
...style
|
|
127
155
|
},
|
|
128
156
|
className: cn(
|
|
129
|
-
"group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar",
|
|
157
|
+
"group/sidebar-wrapper flex min-h-svh w-full bg-background has-[[data-variant=inset]]:bg-sidebar",
|
|
130
158
|
className
|
|
131
159
|
),
|
|
132
160
|
ref,
|
|
@@ -162,35 +190,44 @@ var Sidebar = React2.forwardRef(
|
|
|
162
190
|
);
|
|
163
191
|
}
|
|
164
192
|
if (isMobile) {
|
|
165
|
-
return /* @__PURE__ */
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
"fixed inset-y-0 z-50 flex h-svh w-[--sidebar-width] flex-col bg-sidebar p-2 text-sidebar-foreground",
|
|
180
|
-
side === "left" ? "left-0 border-r" : "right-0 border-l",
|
|
181
|
-
className
|
|
182
|
-
),
|
|
183
|
-
style: {
|
|
184
|
-
"--sidebar-width": SIDEBAR_WIDTH_MOBILE
|
|
185
|
-
},
|
|
186
|
-
onClick: (e) => e.stopPropagation(),
|
|
187
|
-
ref,
|
|
188
|
-
...props,
|
|
189
|
-
children
|
|
193
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
194
|
+
/* @__PURE__ */ jsx(
|
|
195
|
+
"div",
|
|
196
|
+
{
|
|
197
|
+
onClick: () => setOpenMobile(false),
|
|
198
|
+
"aria-hidden": "true",
|
|
199
|
+
style: {
|
|
200
|
+
position: "fixed",
|
|
201
|
+
inset: 0,
|
|
202
|
+
zIndex: 40,
|
|
203
|
+
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
|
204
|
+
opacity: openMobile ? 1 : 0,
|
|
205
|
+
transition: "opacity 200ms",
|
|
206
|
+
pointerEvents: openMobile ? "auto" : "none"
|
|
190
207
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
208
|
+
}
|
|
209
|
+
),
|
|
210
|
+
/* @__PURE__ */ jsx(
|
|
211
|
+
"div",
|
|
212
|
+
{
|
|
213
|
+
"data-sidebar": "sidebar",
|
|
214
|
+
"data-mobile": "true",
|
|
215
|
+
className: cn(
|
|
216
|
+
"fixed inset-y-0 z-50 flex h-svh w-[--sidebar-width] flex-col bg-sidebar p-2 text-sidebar-foreground transition-transform duration-200 ease-in-out",
|
|
217
|
+
side === "left" ? "left-0 border-r" : "right-0 border-l",
|
|
218
|
+
openMobile ? "translate-x-0" : side === "left" ? "-translate-x-full" : "translate-x-full",
|
|
219
|
+
className
|
|
220
|
+
),
|
|
221
|
+
style: {
|
|
222
|
+
"--sidebar-width": SIDEBAR_WIDTH_MOBILE
|
|
223
|
+
},
|
|
224
|
+
onClick: (e) => e.stopPropagation(),
|
|
225
|
+
ref,
|
|
226
|
+
...props,
|
|
227
|
+
children
|
|
228
|
+
}
|
|
229
|
+
)
|
|
230
|
+
] });
|
|
194
231
|
}
|
|
195
232
|
return /* @__PURE__ */ jsxs(
|
|
196
233
|
"div",
|
|
@@ -287,23 +324,24 @@ var SidebarRail = React2.forwardRef(({ className, ...props }, ref) => {
|
|
|
287
324
|
});
|
|
288
325
|
SidebarRail.displayName = "SidebarRail";
|
|
289
326
|
var SidebarInset = React2.forwardRef(({ className, style, ...props }, ref) => {
|
|
290
|
-
const { state, isMobile } = useSidebar();
|
|
291
327
|
return /* @__PURE__ */ jsx(
|
|
292
|
-
"
|
|
328
|
+
"div",
|
|
293
329
|
{
|
|
294
330
|
ref,
|
|
295
331
|
className: cn(
|
|
296
332
|
"relative flex min-h-svh flex-1 flex-col bg-background",
|
|
297
|
-
// Auto-adjust margin based on sidebar state
|
|
298
|
-
// Transition duration uses CSS variable for consistency
|
|
299
333
|
"transition-[margin-left] duration-200 ease-linear",
|
|
334
|
+
// Use peer selectors to respond to sidebar state
|
|
300
335
|
// On mobile, no margin needed (sidebar is overlay)
|
|
301
|
-
//
|
|
302
|
-
//
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
336
|
+
// For default "sidebar" variant, the spacer div already creates space, so no margin needed
|
|
337
|
+
// Only add margin for floating/inset variants that don't have a spacer
|
|
338
|
+
"md:peer-data-[variant=floating]:ml-[--sidebar-width]",
|
|
339
|
+
"md:peer-data-[variant=floating]:peer-data-[collapsible=offcanvas]:ml-0",
|
|
340
|
+
"md:peer-data-[variant=floating]:peer-data-[collapsible=icon]:ml-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]",
|
|
341
|
+
"md:peer-data-[variant=inset]:ml-[--sidebar-width]",
|
|
342
|
+
"md:peer-data-[variant=inset]:peer-data-[collapsible=offcanvas]:ml-0",
|
|
343
|
+
"md:peer-data-[variant=inset]:peer-data-[collapsible=icon]:ml-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]",
|
|
344
|
+
// Inset variant specific styles
|
|
307
345
|
"peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
|
|
308
346
|
className
|
|
309
347
|
),
|
|
@@ -661,7 +699,7 @@ function getIconComponent(icon) {
|
|
|
661
699
|
}
|
|
662
700
|
function NavMain({ items, adapter }) {
|
|
663
701
|
const pathname = adapter.usePathname();
|
|
664
|
-
const
|
|
702
|
+
const Link2 = adapter.Link;
|
|
665
703
|
const groups = [];
|
|
666
704
|
let currentGroup = {
|
|
667
705
|
items: []
|
|
@@ -717,7 +755,7 @@ function NavMain({ items, adapter }) {
|
|
|
717
755
|
]
|
|
718
756
|
}
|
|
719
757
|
) }),
|
|
720
|
-
/* @__PURE__ */ jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsx(SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
758
|
+
/* @__PURE__ */ jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsx(SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsx(Link2, { href: subItem.url, children: /* @__PURE__ */ jsx("span", { children: subItem.title }) }) }) }, subItem.title)) }) })
|
|
721
759
|
] })
|
|
722
760
|
},
|
|
723
761
|
item.title
|
|
@@ -729,7 +767,7 @@ function NavMain({ items, adapter }) {
|
|
|
729
767
|
asChild: true,
|
|
730
768
|
tooltip: item.title,
|
|
731
769
|
isActive,
|
|
732
|
-
children: /* @__PURE__ */ jsxs(
|
|
770
|
+
children: /* @__PURE__ */ jsxs(Link2, { href: item.url, children: [
|
|
733
771
|
item.icon && /* @__PURE__ */ jsx(item.icon, {}),
|
|
734
772
|
/* @__PURE__ */ jsx("span", { children: item.title })
|
|
735
773
|
] })
|
|
@@ -1165,28 +1203,24 @@ function useNavigation({
|
|
|
1165
1203
|
}, [organizationId, apiBaseUrl, enabled]);
|
|
1166
1204
|
return { items, organizations, loading, error };
|
|
1167
1205
|
}
|
|
1168
|
-
var NextJSLink = ({ href, children, className }) => /* @__PURE__ */ jsx(Link, { href, className, children });
|
|
1169
1206
|
function AppSidebar({
|
|
1170
1207
|
user,
|
|
1171
|
-
adapter
|
|
1208
|
+
adapter,
|
|
1172
1209
|
data,
|
|
1173
1210
|
organizationId,
|
|
1174
1211
|
apiBaseUrl,
|
|
1175
1212
|
...props
|
|
1176
1213
|
}) {
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
signOut
|
|
1188
|
-
}), [pathname, router]);
|
|
1189
|
-
const adapter = externalAdapter ?? internalAdapter;
|
|
1214
|
+
if (!adapter) {
|
|
1215
|
+
throw new Error(
|
|
1216
|
+
"AppSidebar: adapter is required. Please provide a framework adapter. For Next.js, use: const adapter = useNextJSAdapter()"
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
if (typeof adapter.usePathname !== "function") {
|
|
1220
|
+
throw new Error(
|
|
1221
|
+
"AppSidebar: Invalid adapter provided. The adapter must have a usePathname function. Make sure you're using the correct adapter for your framework."
|
|
1222
|
+
);
|
|
1223
|
+
}
|
|
1190
1224
|
const currentPathname = adapter.usePathname();
|
|
1191
1225
|
const isPropsMode = data !== void 0;
|
|
1192
1226
|
const pathSegments = currentPathname.split("/");
|
|
@@ -1236,52 +1270,63 @@ function AppLayout({
|
|
|
1236
1270
|
data,
|
|
1237
1271
|
organizationId,
|
|
1238
1272
|
apiBaseUrl,
|
|
1239
|
-
useApiNavigation,
|
|
1240
|
-
headerContent,
|
|
1241
|
-
showHeader = true,
|
|
1242
1273
|
children
|
|
1243
1274
|
}) {
|
|
1244
|
-
const isApiMode = useApiNavigation === true;
|
|
1245
|
-
const navigationApiBaseUrl = apiBaseUrl;
|
|
1246
1275
|
return /* @__PURE__ */ jsxs(SidebarProvider, { children: [
|
|
1247
1276
|
/* @__PURE__ */ jsx(
|
|
1248
1277
|
AppSidebar,
|
|
1249
1278
|
{
|
|
1250
1279
|
user,
|
|
1251
1280
|
adapter,
|
|
1252
|
-
data
|
|
1281
|
+
data,
|
|
1253
1282
|
organizationId,
|
|
1254
|
-
apiBaseUrl
|
|
1283
|
+
apiBaseUrl
|
|
1255
1284
|
}
|
|
1256
1285
|
),
|
|
1257
1286
|
/* @__PURE__ */ jsxs(SidebarInset, { children: [
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
headerContent && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1261
|
-
/* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-border" }),
|
|
1262
|
-
headerContent
|
|
1263
|
-
] })
|
|
1264
|
-
] }),
|
|
1265
|
-
/* @__PURE__ */ jsx("main", { className: "flex flex-1 flex-col gap-4 p-4 md:p-6", children })
|
|
1287
|
+
/* @__PURE__ */ jsx(SidebarTrigger, {}),
|
|
1288
|
+
children
|
|
1266
1289
|
] })
|
|
1267
1290
|
] });
|
|
1268
1291
|
}
|
|
1269
|
-
function
|
|
1270
|
-
const
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1292
|
+
function useNextJSAdapter() {
|
|
1293
|
+
const pathname = usePathname();
|
|
1294
|
+
const nextRouter = useRouter();
|
|
1295
|
+
const router = React2.useMemo(
|
|
1296
|
+
() => {
|
|
1297
|
+
if (!nextRouter) {
|
|
1298
|
+
throw new Error(
|
|
1299
|
+
"Next.js router is not available. Make sure you're using useNextJSAdapter in a Client Component ('use client') and that Next.js router is properly initialized."
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1275
1302
|
return {
|
|
1276
|
-
push: (path) =>
|
|
1277
|
-
refresh: () =>
|
|
1303
|
+
push: (path) => nextRouter.push(path),
|
|
1304
|
+
refresh: () => nextRouter.refresh()
|
|
1278
1305
|
};
|
|
1279
1306
|
},
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1307
|
+
[nextRouter]
|
|
1308
|
+
);
|
|
1309
|
+
const NextJSLink = React2.useMemo(
|
|
1310
|
+
() => ({ href, children, className }) => /* @__PURE__ */ jsx(Link, { href, className, children }),
|
|
1311
|
+
[]
|
|
1312
|
+
);
|
|
1313
|
+
const adapter = React2.useMemo(
|
|
1314
|
+
() => ({
|
|
1315
|
+
usePathname: () => {
|
|
1316
|
+
if (pathname === void 0 || pathname === null) {
|
|
1317
|
+
return "";
|
|
1318
|
+
}
|
|
1319
|
+
return pathname;
|
|
1320
|
+
},
|
|
1321
|
+
useRouter: () => router,
|
|
1322
|
+
Link: NextJSLink,
|
|
1323
|
+
signOut
|
|
1324
|
+
}),
|
|
1325
|
+
[pathname, router, NextJSLink]
|
|
1326
|
+
);
|
|
1327
|
+
return adapter;
|
|
1283
1328
|
}
|
|
1284
1329
|
|
|
1285
|
-
export { AppLayout, AppSidebar, NavMain, NavUser, SidebarInset, SidebarProvider, SidebarTrigger, TeamSwitcher,
|
|
1330
|
+
export { AppLayout, AppSidebar, NavMain, NavUser, SidebarInset, SidebarProvider, SidebarTrigger, TeamSwitcher, getIconComponent, useNavigation, useNextJSAdapter, useSidebar };
|
|
1286
1331
|
//# sourceMappingURL=index.mjs.map
|
|
1287
1332
|
//# sourceMappingURL=index.mjs.map
|