@marcoschwartz/lite-ui 0.23.5 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  Alert: () => Alert,
36
36
  AlertCircleIcon: () => AlertCircleIcon,
37
37
  AppShell: () => AppShell,
38
+ AppShellSection: () => AppShellSection,
38
39
  AppleIcon: () => AppleIcon,
39
40
  AreaChart: () => AreaChart,
40
41
  ArrowDownIcon: () => ArrowDownIcon,
@@ -155,6 +156,7 @@ __export(index_exports, {
155
156
  themeScript: () => themeScript,
156
157
  themes: () => themes,
157
158
  toast: () => toast,
159
+ useAppShell: () => useAppShell,
158
160
  useSidebar: () => useSidebar,
159
161
  useTheme: () => useTheme,
160
162
  useToast: () => useToast,
@@ -1248,172 +1250,309 @@ var SlackIcon = createIcon(
1248
1250
 
1249
1251
  // src/components/AppShell.tsx
1250
1252
  var import_jsx_runtime78 = require("react/jsx-runtime");
1253
+ var AppShellContext = (0, import_react5.createContext)(null);
1254
+ var useAppShell = () => {
1255
+ const context = (0, import_react5.useContext)(AppShellContext);
1256
+ if (!context) {
1257
+ throw new Error("useAppShell must be used within AppShell");
1258
+ }
1259
+ return context;
1260
+ };
1261
+ var heightClasses = {
1262
+ sm: "h-12",
1263
+ // 48px
1264
+ md: "h-16",
1265
+ // 64px
1266
+ lg: "h-20"
1267
+ // 80px
1268
+ };
1251
1269
  var widthClasses2 = {
1252
1270
  sm: "w-48",
1271
+ // 192px
1253
1272
  md: "w-64",
1273
+ // 256px
1254
1274
  lg: "w-80"
1275
+ // 320px
1255
1276
  };
1256
- var breakpointClasses = {
1257
- sm: "sm",
1258
- md: "md",
1259
- lg: "lg",
1260
- xl: "xl"
1277
+ var paddingClasses = {
1278
+ none: "p-0",
1279
+ sm: "p-2",
1280
+ md: "p-4",
1281
+ lg: "p-6"
1261
1282
  };
1262
- var getVariantClasses = (variant) => {
1283
+ var getVariantClasses = (variant, withBorder = true) => {
1284
+ const borderClass = withBorder ? "border-[hsl(var(--border))]" : "border-transparent";
1263
1285
  switch (variant) {
1264
1286
  case "glass":
1265
- return "bg-[hsl(var(--background))]/80 backdrop-blur-xl";
1287
+ return `bg-[hsl(var(--background))]/80 backdrop-blur-xl ${borderClass}`;
1266
1288
  case "transparent":
1267
- return "bg-transparent";
1289
+ return `bg-transparent ${borderClass}`;
1268
1290
  case "solid":
1269
1291
  default:
1270
- return "bg-[hsl(var(--background))] border-b border-[hsl(var(--border))]";
1292
+ return `bg-[hsl(var(--card))] ${borderClass}`;
1271
1293
  }
1272
1294
  };
1273
- var AppShell = ({
1274
- children,
1275
- navbar,
1276
- header,
1277
- navbarTitle,
1278
- navbarLogo,
1279
- defaultNavbarOpen = false,
1280
- responsive = true,
1281
- className = ""
1282
- }) => {
1283
- const [isMobileNavbarOpen, setIsMobileNavbarOpen] = (0, import_react5.useState)(defaultNavbarOpen);
1284
- const navbarWidth = navbar?.width || "md";
1285
- const navbarBreakpoint = navbar?.breakpoint || "md";
1286
- const navbarPosition = navbar?.position || "side";
1287
- const widthClass = widthClasses2[navbarWidth];
1288
- const breakpoint = breakpointClasses[navbarBreakpoint];
1289
- if (!responsive && navbar) {
1290
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex flex-col ${className}`, children: [
1291
- header && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full", children: header }),
1292
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-1", children: [
1293
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("aside", { className: `${widthClass} bg-[hsl(var(--card))] border-r border-[hsl(var(--border))] h-full overflow-y-auto`, children: navbar.content }),
1294
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: "flex-1 overflow-y-auto", children })
1295
- ] })
1296
- ] });
1295
+ var getBreakpointHideClass = (breakpoint) => {
1296
+ switch (breakpoint) {
1297
+ case "sm":
1298
+ return "sm:hidden";
1299
+ case "md":
1300
+ return "md:hidden";
1301
+ case "lg":
1302
+ return "lg:hidden";
1303
+ case "xl":
1304
+ return "xl:hidden";
1297
1305
  }
1298
- if (!responsive) {
1299
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex flex-col ${className}`, children: [
1300
- header && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full", children: header }),
1301
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: "flex-1 overflow-y-auto", children })
1302
- ] });
1306
+ };
1307
+ var getBreakpointShowClass = (breakpoint) => {
1308
+ switch (breakpoint) {
1309
+ case "sm":
1310
+ return "hidden sm:flex";
1311
+ case "md":
1312
+ return "hidden md:flex";
1313
+ case "lg":
1314
+ return "hidden lg:flex";
1315
+ case "xl":
1316
+ return "hidden xl:flex";
1303
1317
  }
1304
- if (navbar && navbarPosition === "top") {
1305
- const mobileMenuClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
1306
- const desktopNavClass = navbarBreakpoint === "sm" ? "sm:flex" : navbarBreakpoint === "md" ? "md:flex" : navbarBreakpoint === "lg" ? "lg:flex" : "xl:flex";
1307
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex flex-col bg-[hsl(var(--background))] ${className}`, children: [
1308
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("nav", { className: `sticky top-0 z-30 ${getVariantClasses(navbar.variant)}`, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex justify-between items-center h-16", children: [
1309
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex items-center", children: navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null }),
1310
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: `hidden ${desktopNavClass} items-center gap-6`, children: navbar.content }),
1311
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1312
- "button",
1313
- {
1314
- className: `${mobileMenuClass} p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors`,
1315
- onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
1316
- "aria-label": "Toggle menu",
1317
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(MenuIcon, { size: "md" })
1318
- }
1319
- )
1320
- ] }) }) }),
1321
- header && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full", children: header }),
1322
- isMobileNavbarOpen && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
1323
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1324
- "div",
1325
- {
1326
- className: `${mobileMenuClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
1327
- onClick: () => setIsMobileNavbarOpen(false)
1328
- }
1329
- ),
1330
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `${mobileMenuClass} fixed left-0 top-0 bottom-0 z-50 w-64 bg-[hsl(var(--card))] shadow-2xl animate-in slide-in-from-left duration-300`, children: [
1331
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "p-4 border-b border-[hsl(var(--border))] flex items-center justify-between", children: [
1332
- navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null,
1318
+ };
1319
+ var MobileDrawer = ({
1320
+ isOpen,
1321
+ onClose,
1322
+ position,
1323
+ breakpoint,
1324
+ title,
1325
+ logo,
1326
+ children
1327
+ }) => {
1328
+ if (!isOpen) return null;
1329
+ const hideClass = getBreakpointHideClass(breakpoint);
1330
+ const slideClass = position === "left" ? "left-0 animate-in slide-in-from-left" : "right-0 animate-in slide-in-from-right";
1331
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
1332
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1333
+ "div",
1334
+ {
1335
+ className: `${hideClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
1336
+ onClick: onClose
1337
+ }
1338
+ ),
1339
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
1340
+ "div",
1341
+ {
1342
+ className: `${hideClass} fixed ${slideClass} top-0 bottom-0 z-50 w-64 bg-[hsl(var(--card))] shadow-2xl duration-300 flex flex-col`,
1343
+ children: [
1344
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "p-4 border-b border-[hsl(var(--border))] flex items-center justify-between shrink-0", children: [
1345
+ logo ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { children: logo }) : title ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) : /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", {}),
1333
1346
  /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1334
1347
  "button",
1335
1348
  {
1336
1349
  className: "p-1 rounded hover:bg-[hsl(var(--accent))] transition-colors",
1337
- onClick: () => setIsMobileNavbarOpen(false),
1350
+ onClick: onClose,
1338
1351
  "aria-label": "Close menu",
1339
1352
  children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1340
1353
  }
1341
1354
  )
1342
1355
  ] }),
1343
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1344
- "div",
1356
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex-1 overflow-y-auto", onClick: onClose, children })
1357
+ ]
1358
+ }
1359
+ )
1360
+ ] });
1361
+ };
1362
+ var AppShell = ({
1363
+ children,
1364
+ header,
1365
+ navbar,
1366
+ aside,
1367
+ footer,
1368
+ logo,
1369
+ title,
1370
+ layout = "default",
1371
+ padding = "none",
1372
+ className = ""
1373
+ }) => {
1374
+ const [navbarOpen, setNavbarOpen] = (0, import_react5.useState)(false);
1375
+ const [asideOpen, setAsideOpen] = (0, import_react5.useState)(false);
1376
+ const navbarWidth = navbar?.width || "md";
1377
+ const navbarBreakpoint = navbar?.breakpoint || "md";
1378
+ const navbarCollapsedMobile = navbar?.collapsed?.mobile ?? false;
1379
+ const navbarCollapsedDesktop = navbar?.collapsed?.desktop ?? false;
1380
+ const navbarVariant = navbar?.variant || "solid";
1381
+ const navbarWithBorder = navbar?.withBorder ?? true;
1382
+ const asideWidth = aside?.width || "md";
1383
+ const asideBreakpoint = aside?.breakpoint || "md";
1384
+ const asideCollapsedMobile = aside?.collapsed?.mobile ?? true;
1385
+ const asideCollapsedDesktop = aside?.collapsed?.desktop ?? false;
1386
+ const asideVariant = aside?.variant || "solid";
1387
+ const asideWithBorder = aside?.withBorder ?? true;
1388
+ const headerHeight = header?.height || "md";
1389
+ const headerVariant = header?.variant || "solid";
1390
+ const headerWithBorder = header?.withBorder ?? true;
1391
+ const headerCollapsed = header?.collapsed ?? false;
1392
+ const footerHeight = footer?.height || "md";
1393
+ const footerVariant = footer?.variant || "solid";
1394
+ const footerWithBorder = footer?.withBorder ?? true;
1395
+ const footerCollapsed = footer?.collapsed ?? false;
1396
+ const showNavbarHamburger = navbar && !navbarCollapsedMobile;
1397
+ const showAsideHamburger = aside && !asideCollapsedMobile;
1398
+ const needsMobileHeader = showNavbarHamburger || showAsideHamburger;
1399
+ const navbarDesktopShowClass = getBreakpointShowClass(navbarBreakpoint);
1400
+ const navbarMobileHideClass = getBreakpointHideClass(navbarBreakpoint);
1401
+ const asideDesktopShowClass = getBreakpointShowClass(asideBreakpoint);
1402
+ const asideMobileHideClass = getBreakpointHideClass(asideBreakpoint);
1403
+ const contextValue = {
1404
+ navbarOpen,
1405
+ setNavbarOpen,
1406
+ asideOpen,
1407
+ setAsideOpen
1408
+ };
1409
+ if (layout === "alt") {
1410
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(AppShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex bg-[hsl(var(--background))] ${className}`, children: [
1411
+ navbar && !navbarCollapsedDesktop && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
1412
+ "aside",
1413
+ {
1414
+ className: `${navbarDesktopShowClass} ${widthClasses2[navbarWidth]} ${getVariantClasses(navbarVariant, navbarWithBorder)} ${navbarWithBorder ? "border-r" : ""} flex-col shrink-0`,
1415
+ children: [
1416
+ (logo || title) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: `${heightClasses[headerHeight]} px-4 flex items-center border-b border-[hsl(var(--border))] shrink-0`, children: logo || /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1417
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("nav", { className: "flex-1 overflow-y-auto", children: navbar.content })
1418
+ ]
1419
+ }
1420
+ ),
1421
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex-1 flex flex-col min-w-0", children: [
1422
+ needsMobileHeader && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `${navbarMobileHideClass} sticky top-0 z-30 ${heightClasses[headerHeight]} px-4 flex items-center justify-between ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""}`, children: [
1423
+ showNavbarHamburger && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1424
+ "button",
1345
1425
  {
1346
- className: "p-4 flex flex-col gap-4",
1347
- onClick: () => setIsMobileNavbarOpen(false),
1348
- children: navbar.content
1426
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1427
+ onClick: () => setNavbarOpen(true),
1428
+ "aria-label": "Open navigation",
1429
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(MenuIcon, { size: "md" })
1349
1430
  }
1350
- )
1351
- ] })
1352
- ] }),
1353
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: "flex-1 overflow-y-auto", children })
1354
- ] });
1355
- }
1356
- if (navbar) {
1357
- const mobileHeaderClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
1358
- const desktopNavbarClass = navbarBreakpoint === "sm" ? "sm:block" : navbarBreakpoint === "md" ? "md:block" : navbarBreakpoint === "lg" ? "lg:block" : "xl:block";
1359
- const mobileDrawerClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
1360
- const sidebarWidthClass = navbarWidth === "sm" ? "w-48" : navbarWidth === "lg" ? "w-80" : "w-64";
1361
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex flex-col bg-[hsl(var(--background))] ${className}`, children: [
1362
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `${mobileHeaderClass} sticky top-0 z-30 ${getVariantClasses(navbar.variant)} px-4 py-3 flex items-center justify-between`, children: [
1363
- navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null,
1364
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1365
- "button",
1366
- {
1367
- className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1368
- onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
1369
- "aria-label": "Toggle menu",
1370
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(MenuIcon, { size: "md" })
1371
- }
1372
- )
1373
- ] }),
1374
- header && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full", children: header }),
1375
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-1 min-h-0", children: [
1376
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("aside", { className: `hidden ${desktopNavbarClass} ${sidebarWidthClass} ${navbar.variant === "glass" ? "bg-[hsl(var(--background))]/80 backdrop-blur-xl" : navbar.variant === "transparent" ? "bg-transparent" : "bg-[hsl(var(--card))] border-r border-[hsl(var(--border))]"} overflow-y-auto shrink-0`, children: navbar.content }),
1377
- isMobileNavbarOpen && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
1378
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1379
- "div",
1431
+ ),
1432
+ (logo || title) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex-1 flex justify-center", children: logo || /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1433
+ showAsideHamburger ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1434
+ "button",
1380
1435
  {
1381
- className: `${mobileDrawerClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
1382
- onClick: () => setIsMobileNavbarOpen(false)
1436
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1437
+ onClick: () => setAsideOpen(true),
1438
+ "aria-label": "Open sidebar",
1439
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(MenuIcon, { size: "md" })
1383
1440
  }
1384
- ),
1385
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `${mobileDrawerClass} fixed left-0 top-0 bottom-0 z-50 w-64 bg-[hsl(var(--card))] shadow-2xl animate-in slide-in-from-left duration-300`, children: [
1386
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "p-4 border-b border-[hsl(var(--border))] flex items-center justify-between", children: [
1387
- navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null,
1388
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1389
- "button",
1390
- {
1391
- className: "p-1 rounded hover:bg-[hsl(var(--accent))] transition-colors",
1392
- onClick: () => setIsMobileNavbarOpen(false),
1393
- "aria-label": "Close menu",
1394
- children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1395
- }
1396
- )
1397
- ] }),
1398
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1399
- "div",
1400
- {
1401
- className: "overflow-y-auto h-[calc(100vh-73px)]",
1402
- onClick: () => setIsMobileNavbarOpen(false),
1403
- children: navbar.content
1404
- }
1405
- )
1406
- ] })
1441
+ ) : showNavbarHamburger && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-10" })
1407
1442
  ] }),
1408
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: "flex-1 overflow-y-auto min-h-screen", children })
1409
- ] })
1410
- ] });
1443
+ header && !headerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("header", { className: `sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 flex items-center shrink-0`, children: header.content }),
1444
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: `flex-1 overflow-y-auto ${paddingClasses[padding]}`, children }),
1445
+ footer && !footerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("footer", { className: `${heightClasses[footerHeight]} ${getVariantClasses(footerVariant, footerWithBorder)} ${footerWithBorder ? "border-t" : ""} px-4 flex items-center shrink-0`, children: footer.content })
1446
+ ] }),
1447
+ aside && !asideCollapsedDesktop && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1448
+ "aside",
1449
+ {
1450
+ className: `${asideDesktopShowClass} ${widthClasses2[asideWidth]} ${getVariantClasses(asideVariant, asideWithBorder)} ${asideWithBorder ? "border-l" : ""} flex-col shrink-0 overflow-y-auto`,
1451
+ children: aside.content
1452
+ }
1453
+ ),
1454
+ navbar && !navbarCollapsedMobile && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1455
+ MobileDrawer,
1456
+ {
1457
+ isOpen: navbarOpen,
1458
+ onClose: () => setNavbarOpen(false),
1459
+ position: "left",
1460
+ breakpoint: navbarBreakpoint,
1461
+ title,
1462
+ logo,
1463
+ children: navbar.content
1464
+ }
1465
+ ),
1466
+ aside && !asideCollapsedMobile && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1467
+ MobileDrawer,
1468
+ {
1469
+ isOpen: asideOpen,
1470
+ onClose: () => setAsideOpen(false),
1471
+ position: "right",
1472
+ breakpoint: asideBreakpoint,
1473
+ title: "Sidebar",
1474
+ children: aside.content
1475
+ }
1476
+ )
1477
+ ] }) });
1411
1478
  }
1412
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex flex-col ${className}`, children: [
1413
- header && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full", children: header }),
1414
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: "flex-1 overflow-y-auto", children })
1415
- ] });
1479
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(AppShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `min-h-screen flex flex-col bg-[hsl(var(--background))] ${className}`, children: [
1480
+ needsMobileHeader && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: `${navbarMobileHideClass} sticky top-0 z-30 ${heightClasses[headerHeight]} px-4 flex items-center justify-between ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""}`, children: [
1481
+ showNavbarHamburger && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1482
+ "button",
1483
+ {
1484
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1485
+ onClick: () => setNavbarOpen(true),
1486
+ "aria-label": "Open navigation",
1487
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(MenuIcon, { size: "md" })
1488
+ }
1489
+ ),
1490
+ (logo || title) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex-1 flex justify-center", children: logo || /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1491
+ showAsideHamburger ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1492
+ "button",
1493
+ {
1494
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1495
+ onClick: () => setAsideOpen(true),
1496
+ "aria-label": "Open sidebar",
1497
+ children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(MenuIcon, { size: "md" })
1498
+ }
1499
+ ) : showNavbarHamburger && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-10" })
1500
+ ] }),
1501
+ header && !headerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("header", { className: `sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 flex items-center`, children: [
1502
+ (logo || title) && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "mr-4 shrink-0", children: logo || /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1503
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex-1", children: header.content })
1504
+ ] }),
1505
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-1 min-h-0", children: [
1506
+ navbar && !navbarCollapsedDesktop && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1507
+ "nav",
1508
+ {
1509
+ className: `${navbarDesktopShowClass} ${widthClasses2[navbarWidth]} ${getVariantClasses(navbarVariant, navbarWithBorder)} ${navbarWithBorder ? "border-r" : ""} flex-col shrink-0 overflow-y-auto`,
1510
+ children: navbar.content
1511
+ }
1512
+ ),
1513
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("main", { className: `flex-1 overflow-y-auto min-w-0 ${paddingClasses[padding]}`, children }),
1514
+ aside && !asideCollapsedDesktop && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1515
+ "aside",
1516
+ {
1517
+ className: `${asideDesktopShowClass} ${widthClasses2[asideWidth]} ${getVariantClasses(asideVariant, asideWithBorder)} ${asideWithBorder ? "border-l" : ""} flex-col shrink-0 overflow-y-auto`,
1518
+ children: aside.content
1519
+ }
1520
+ )
1521
+ ] }),
1522
+ footer && !footerCollapsed && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("footer", { className: `${heightClasses[footerHeight]} ${getVariantClasses(footerVariant, footerWithBorder)} ${footerWithBorder ? "border-t" : ""} px-4 flex items-center shrink-0`, children: footer.content }),
1523
+ navbar && !navbarCollapsedMobile && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1524
+ MobileDrawer,
1525
+ {
1526
+ isOpen: navbarOpen,
1527
+ onClose: () => setNavbarOpen(false),
1528
+ position: "left",
1529
+ breakpoint: navbarBreakpoint,
1530
+ title,
1531
+ logo,
1532
+ children: navbar.content
1533
+ }
1534
+ ),
1535
+ aside && !asideCollapsedMobile && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
1536
+ MobileDrawer,
1537
+ {
1538
+ isOpen: asideOpen,
1539
+ onClose: () => setAsideOpen(false),
1540
+ position: "right",
1541
+ breakpoint: asideBreakpoint,
1542
+ title: "Sidebar",
1543
+ children: aside.content
1544
+ }
1545
+ )
1546
+ ] }) });
1547
+ };
1548
+ var AppShellSection = ({
1549
+ children,
1550
+ grow = false,
1551
+ className = ""
1552
+ }) => {
1553
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: `${grow ? "flex-1" : ""} ${className}`, children });
1416
1554
  };
1555
+ AppShell.Section = AppShellSection;
1417
1556
 
1418
1557
  // src/components/Drawer.tsx
1419
1558
  var import_react6 = require("react");
@@ -1811,7 +1950,7 @@ var ActionMenu = ({
1811
1950
 
1812
1951
  // src/components/Card.tsx
1813
1952
  var import_jsx_runtime83 = require("react/jsx-runtime");
1814
- var paddingClasses = {
1953
+ var paddingClasses2 = {
1815
1954
  none: "",
1816
1955
  sm: "p-4",
1817
1956
  md: "p-6",
@@ -1824,7 +1963,7 @@ var Card = ({
1824
1963
  hover = false,
1825
1964
  ...props
1826
1965
  }) => {
1827
- const paddingClass = paddingClasses[padding];
1966
+ const paddingClass = paddingClasses2[padding];
1828
1967
  const hoverClass = hover ? "hover:shadow-lg hover:border-[hsl(var(--ring))]/50 cursor-pointer transition-all duration-200 ease-in-out" : "";
1829
1968
  return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(
1830
1969
  "div",
@@ -8884,6 +9023,7 @@ function getThemeScript() {
8884
9023
  Alert,
8885
9024
  AlertCircleIcon,
8886
9025
  AppShell,
9026
+ AppShellSection,
8887
9027
  AppleIcon,
8888
9028
  AreaChart,
8889
9029
  ArrowDownIcon,
@@ -9004,6 +9144,7 @@ function getThemeScript() {
9004
9144
  themeScript,
9005
9145
  themes,
9006
9146
  toast,
9147
+ useAppShell,
9007
9148
  useSidebar,
9008
9149
  useTheme,
9009
9150
  useToast,