@marcoschwartz/lite-ui 0.23.4 → 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.mjs CHANGED
@@ -21,10 +21,10 @@ var themes = {
21
21
  link: "bg-transparent text-[hsl(var(--primary))] underline-offset-4 hover:underline !p-0 !h-auto !min-h-0 shadow-none"
22
22
  },
23
23
  sizes: {
24
- sm: "px-3 py-1.5 text-sm h-8",
25
- md: "px-4 py-2 text-sm h-9",
26
- lg: "px-5 py-2.5 text-base h-10",
27
- xl: "px-6 py-3 text-base h-11"
24
+ sm: "px-3 py-1.5 text-sm",
25
+ md: "px-4 py-2.5 text-base",
26
+ lg: "px-4 py-3 text-lg",
27
+ xl: "px-6 py-3.5 text-lg"
28
28
  },
29
29
  disabled: "pointer-events-none opacity-50"
30
30
  },
@@ -32,8 +32,8 @@ var themes = {
32
32
  base: "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] text-left transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] pr-10 cursor-pointer",
33
33
  sizes: {
34
34
  sm: "px-3 py-1.5 text-sm",
35
- md: "px-3 py-2.5 text-sm",
36
- lg: "px-4 py-3 text-base",
35
+ md: "px-4 py-2.5 text-base",
36
+ lg: "px-4 py-3 text-lg",
37
37
  xl: "px-4 py-3.5 text-lg"
38
38
  },
39
39
  disabled: "pointer-events-none opacity-50 bg-[hsl(var(--muted))]"
@@ -541,7 +541,7 @@ var useSidebar = () => {
541
541
  };
542
542
 
543
543
  // src/components/AppShell.tsx
544
- import { useState as useState4 } from "react";
544
+ import { useState as useState4, createContext as createContext3, useContext as useContext3 } from "react";
545
545
 
546
546
  // src/icons/icon-utils.tsx
547
547
  import { jsx as jsx8 } from "react/jsx-runtime";
@@ -1086,172 +1086,309 @@ var SlackIcon = createIcon(
1086
1086
 
1087
1087
  // src/components/AppShell.tsx
1088
1088
  import { Fragment as Fragment11, jsx as jsx78, jsxs as jsxs9 } from "react/jsx-runtime";
1089
+ var AppShellContext = createContext3(null);
1090
+ var useAppShell = () => {
1091
+ const context = useContext3(AppShellContext);
1092
+ if (!context) {
1093
+ throw new Error("useAppShell must be used within AppShell");
1094
+ }
1095
+ return context;
1096
+ };
1097
+ var heightClasses = {
1098
+ sm: "h-12",
1099
+ // 48px
1100
+ md: "h-16",
1101
+ // 64px
1102
+ lg: "h-20"
1103
+ // 80px
1104
+ };
1089
1105
  var widthClasses2 = {
1090
1106
  sm: "w-48",
1107
+ // 192px
1091
1108
  md: "w-64",
1109
+ // 256px
1092
1110
  lg: "w-80"
1111
+ // 320px
1093
1112
  };
1094
- var breakpointClasses = {
1095
- sm: "sm",
1096
- md: "md",
1097
- lg: "lg",
1098
- xl: "xl"
1113
+ var paddingClasses = {
1114
+ none: "p-0",
1115
+ sm: "p-2",
1116
+ md: "p-4",
1117
+ lg: "p-6"
1099
1118
  };
1100
- var getVariantClasses = (variant) => {
1119
+ var getVariantClasses = (variant, withBorder = true) => {
1120
+ const borderClass = withBorder ? "border-[hsl(var(--border))]" : "border-transparent";
1101
1121
  switch (variant) {
1102
1122
  case "glass":
1103
- return "bg-[hsl(var(--background))]/80 backdrop-blur-xl";
1123
+ return `bg-[hsl(var(--background))]/80 backdrop-blur-xl ${borderClass}`;
1104
1124
  case "transparent":
1105
- return "bg-transparent";
1125
+ return `bg-transparent ${borderClass}`;
1106
1126
  case "solid":
1107
1127
  default:
1108
- return "bg-[hsl(var(--background))] border-b border-[hsl(var(--border))]";
1128
+ return `bg-[hsl(var(--card))] ${borderClass}`;
1109
1129
  }
1110
1130
  };
1111
- var AppShell = ({
1112
- children,
1113
- navbar,
1114
- header,
1115
- navbarTitle,
1116
- navbarLogo,
1117
- defaultNavbarOpen = false,
1118
- responsive = true,
1119
- className = ""
1120
- }) => {
1121
- const [isMobileNavbarOpen, setIsMobileNavbarOpen] = useState4(defaultNavbarOpen);
1122
- const navbarWidth = navbar?.width || "md";
1123
- const navbarBreakpoint = navbar?.breakpoint || "md";
1124
- const navbarPosition = navbar?.position || "side";
1125
- const widthClass = widthClasses2[navbarWidth];
1126
- const breakpoint = breakpointClasses[navbarBreakpoint];
1127
- if (!responsive && navbar) {
1128
- return /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex flex-col ${className}`, children: [
1129
- header && /* @__PURE__ */ jsx78("div", { className: "w-full", children: header }),
1130
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-1", children: [
1131
- /* @__PURE__ */ jsx78("aside", { className: `${widthClass} bg-[hsl(var(--card))] border-r border-[hsl(var(--border))] h-full overflow-y-auto`, children: navbar.content }),
1132
- /* @__PURE__ */ jsx78("main", { className: "flex-1 overflow-y-auto", children })
1133
- ] })
1134
- ] });
1131
+ var getBreakpointHideClass = (breakpoint) => {
1132
+ switch (breakpoint) {
1133
+ case "sm":
1134
+ return "sm:hidden";
1135
+ case "md":
1136
+ return "md:hidden";
1137
+ case "lg":
1138
+ return "lg:hidden";
1139
+ case "xl":
1140
+ return "xl:hidden";
1135
1141
  }
1136
- if (!responsive) {
1137
- return /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex flex-col ${className}`, children: [
1138
- header && /* @__PURE__ */ jsx78("div", { className: "w-full", children: header }),
1139
- /* @__PURE__ */ jsx78("main", { className: "flex-1 overflow-y-auto", children })
1140
- ] });
1142
+ };
1143
+ var getBreakpointShowClass = (breakpoint) => {
1144
+ switch (breakpoint) {
1145
+ case "sm":
1146
+ return "hidden sm:flex";
1147
+ case "md":
1148
+ return "hidden md:flex";
1149
+ case "lg":
1150
+ return "hidden lg:flex";
1151
+ case "xl":
1152
+ return "hidden xl:flex";
1141
1153
  }
1142
- if (navbar && navbarPosition === "top") {
1143
- const mobileMenuClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
1144
- const desktopNavClass = navbarBreakpoint === "sm" ? "sm:flex" : navbarBreakpoint === "md" ? "md:flex" : navbarBreakpoint === "lg" ? "lg:flex" : "xl:flex";
1145
- return /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex flex-col bg-[hsl(var(--background))] ${className}`, children: [
1146
- /* @__PURE__ */ jsx78("nav", { className: `sticky top-0 z-30 ${getVariantClasses(navbar.variant)}`, children: /* @__PURE__ */ jsx78("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs9("div", { className: "flex justify-between items-center h-16", children: [
1147
- /* @__PURE__ */ jsx78("div", { className: "flex items-center", children: navbarLogo ? /* @__PURE__ */ jsx78("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null }),
1148
- /* @__PURE__ */ jsx78("div", { className: `hidden ${desktopNavClass} items-center gap-6`, children: navbar.content }),
1149
- /* @__PURE__ */ jsx78(
1150
- "button",
1151
- {
1152
- className: `${mobileMenuClass} p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors`,
1153
- onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
1154
- "aria-label": "Toggle menu",
1155
- children: /* @__PURE__ */ jsx78(MenuIcon, { size: "md" })
1156
- }
1157
- )
1158
- ] }) }) }),
1159
- header && /* @__PURE__ */ jsx78("div", { className: "w-full", children: header }),
1160
- isMobileNavbarOpen && /* @__PURE__ */ jsxs9(Fragment11, { children: [
1161
- /* @__PURE__ */ jsx78(
1162
- "div",
1163
- {
1164
- className: `${mobileMenuClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
1165
- onClick: () => setIsMobileNavbarOpen(false)
1166
- }
1167
- ),
1168
- /* @__PURE__ */ jsxs9("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: [
1169
- /* @__PURE__ */ jsxs9("div", { className: "p-4 border-b border-[hsl(var(--border))] flex items-center justify-between", children: [
1170
- navbarLogo ? /* @__PURE__ */ jsx78("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null,
1154
+ };
1155
+ var MobileDrawer = ({
1156
+ isOpen,
1157
+ onClose,
1158
+ position,
1159
+ breakpoint,
1160
+ title,
1161
+ logo,
1162
+ children
1163
+ }) => {
1164
+ if (!isOpen) return null;
1165
+ const hideClass = getBreakpointHideClass(breakpoint);
1166
+ const slideClass = position === "left" ? "left-0 animate-in slide-in-from-left" : "right-0 animate-in slide-in-from-right";
1167
+ return /* @__PURE__ */ jsxs9(Fragment11, { children: [
1168
+ /* @__PURE__ */ jsx78(
1169
+ "div",
1170
+ {
1171
+ className: `${hideClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
1172
+ onClick: onClose
1173
+ }
1174
+ ),
1175
+ /* @__PURE__ */ jsxs9(
1176
+ "div",
1177
+ {
1178
+ className: `${hideClass} fixed ${slideClass} top-0 bottom-0 z-50 w-64 bg-[hsl(var(--card))] shadow-2xl duration-300 flex flex-col`,
1179
+ children: [
1180
+ /* @__PURE__ */ jsxs9("div", { className: "p-4 border-b border-[hsl(var(--border))] flex items-center justify-between shrink-0", children: [
1181
+ logo ? /* @__PURE__ */ jsx78("div", { children: logo }) : title ? /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) : /* @__PURE__ */ jsx78("div", {}),
1171
1182
  /* @__PURE__ */ jsx78(
1172
1183
  "button",
1173
1184
  {
1174
1185
  className: "p-1 rounded hover:bg-[hsl(var(--accent))] transition-colors",
1175
- onClick: () => setIsMobileNavbarOpen(false),
1186
+ onClick: onClose,
1176
1187
  "aria-label": "Close menu",
1177
1188
  children: /* @__PURE__ */ jsx78("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx78("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1178
1189
  }
1179
1190
  )
1180
1191
  ] }),
1181
- /* @__PURE__ */ jsx78(
1182
- "div",
1192
+ /* @__PURE__ */ jsx78("div", { className: "flex-1 overflow-y-auto", onClick: onClose, children })
1193
+ ]
1194
+ }
1195
+ )
1196
+ ] });
1197
+ };
1198
+ var AppShell = ({
1199
+ children,
1200
+ header,
1201
+ navbar,
1202
+ aside,
1203
+ footer,
1204
+ logo,
1205
+ title,
1206
+ layout = "default",
1207
+ padding = "none",
1208
+ className = ""
1209
+ }) => {
1210
+ const [navbarOpen, setNavbarOpen] = useState4(false);
1211
+ const [asideOpen, setAsideOpen] = useState4(false);
1212
+ const navbarWidth = navbar?.width || "md";
1213
+ const navbarBreakpoint = navbar?.breakpoint || "md";
1214
+ const navbarCollapsedMobile = navbar?.collapsed?.mobile ?? false;
1215
+ const navbarCollapsedDesktop = navbar?.collapsed?.desktop ?? false;
1216
+ const navbarVariant = navbar?.variant || "solid";
1217
+ const navbarWithBorder = navbar?.withBorder ?? true;
1218
+ const asideWidth = aside?.width || "md";
1219
+ const asideBreakpoint = aside?.breakpoint || "md";
1220
+ const asideCollapsedMobile = aside?.collapsed?.mobile ?? true;
1221
+ const asideCollapsedDesktop = aside?.collapsed?.desktop ?? false;
1222
+ const asideVariant = aside?.variant || "solid";
1223
+ const asideWithBorder = aside?.withBorder ?? true;
1224
+ const headerHeight = header?.height || "md";
1225
+ const headerVariant = header?.variant || "solid";
1226
+ const headerWithBorder = header?.withBorder ?? true;
1227
+ const headerCollapsed = header?.collapsed ?? false;
1228
+ const footerHeight = footer?.height || "md";
1229
+ const footerVariant = footer?.variant || "solid";
1230
+ const footerWithBorder = footer?.withBorder ?? true;
1231
+ const footerCollapsed = footer?.collapsed ?? false;
1232
+ const showNavbarHamburger = navbar && !navbarCollapsedMobile;
1233
+ const showAsideHamburger = aside && !asideCollapsedMobile;
1234
+ const needsMobileHeader = showNavbarHamburger || showAsideHamburger;
1235
+ const navbarDesktopShowClass = getBreakpointShowClass(navbarBreakpoint);
1236
+ const navbarMobileHideClass = getBreakpointHideClass(navbarBreakpoint);
1237
+ const asideDesktopShowClass = getBreakpointShowClass(asideBreakpoint);
1238
+ const asideMobileHideClass = getBreakpointHideClass(asideBreakpoint);
1239
+ const contextValue = {
1240
+ navbarOpen,
1241
+ setNavbarOpen,
1242
+ asideOpen,
1243
+ setAsideOpen
1244
+ };
1245
+ if (layout === "alt") {
1246
+ return /* @__PURE__ */ jsx78(AppShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex bg-[hsl(var(--background))] ${className}`, children: [
1247
+ navbar && !navbarCollapsedDesktop && /* @__PURE__ */ jsxs9(
1248
+ "aside",
1249
+ {
1250
+ className: `${navbarDesktopShowClass} ${widthClasses2[navbarWidth]} ${getVariantClasses(navbarVariant, navbarWithBorder)} ${navbarWithBorder ? "border-r" : ""} flex-col shrink-0`,
1251
+ children: [
1252
+ (logo || title) && /* @__PURE__ */ jsx78("div", { className: `${heightClasses[headerHeight]} px-4 flex items-center border-b border-[hsl(var(--border))] shrink-0`, children: logo || /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1253
+ /* @__PURE__ */ jsx78("nav", { className: "flex-1 overflow-y-auto", children: navbar.content })
1254
+ ]
1255
+ }
1256
+ ),
1257
+ /* @__PURE__ */ jsxs9("div", { className: "flex-1 flex flex-col min-w-0", children: [
1258
+ needsMobileHeader && /* @__PURE__ */ jsxs9("div", { className: `${navbarMobileHideClass} sticky top-0 z-30 ${heightClasses[headerHeight]} px-4 flex items-center justify-between ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""}`, children: [
1259
+ showNavbarHamburger && /* @__PURE__ */ jsx78(
1260
+ "button",
1183
1261
  {
1184
- className: "p-4 flex flex-col gap-4",
1185
- onClick: () => setIsMobileNavbarOpen(false),
1186
- children: navbar.content
1262
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1263
+ onClick: () => setNavbarOpen(true),
1264
+ "aria-label": "Open navigation",
1265
+ children: /* @__PURE__ */ jsx78(MenuIcon, { size: "md" })
1187
1266
  }
1188
- )
1189
- ] })
1190
- ] }),
1191
- /* @__PURE__ */ jsx78("main", { className: "flex-1 overflow-y-auto", children })
1192
- ] });
1193
- }
1194
- if (navbar) {
1195
- const mobileHeaderClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
1196
- const desktopNavbarClass = navbarBreakpoint === "sm" ? "sm:block" : navbarBreakpoint === "md" ? "md:block" : navbarBreakpoint === "lg" ? "lg:block" : "xl:block";
1197
- const mobileDrawerClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
1198
- const sidebarWidthClass = navbarWidth === "sm" ? "w-48" : navbarWidth === "lg" ? "w-80" : "w-64";
1199
- return /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex flex-col bg-[hsl(var(--background))] ${className}`, children: [
1200
- /* @__PURE__ */ jsxs9("div", { className: `${mobileHeaderClass} sticky top-0 z-30 ${getVariantClasses(navbar.variant)} px-4 py-3 flex items-center justify-between`, children: [
1201
- navbarLogo ? /* @__PURE__ */ jsx78("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null,
1202
- /* @__PURE__ */ jsx78(
1203
- "button",
1204
- {
1205
- className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1206
- onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
1207
- "aria-label": "Toggle menu",
1208
- children: /* @__PURE__ */ jsx78(MenuIcon, { size: "md" })
1209
- }
1210
- )
1211
- ] }),
1212
- header && /* @__PURE__ */ jsx78("div", { className: "w-full", children: header }),
1213
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-1 min-h-0", children: [
1214
- /* @__PURE__ */ jsx78("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 }),
1215
- isMobileNavbarOpen && /* @__PURE__ */ jsxs9(Fragment11, { children: [
1216
- /* @__PURE__ */ jsx78(
1217
- "div",
1267
+ ),
1268
+ (logo || title) && /* @__PURE__ */ jsx78("div", { className: "flex-1 flex justify-center", children: logo || /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1269
+ showAsideHamburger ? /* @__PURE__ */ jsx78(
1270
+ "button",
1218
1271
  {
1219
- className: `${mobileDrawerClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
1220
- onClick: () => setIsMobileNavbarOpen(false)
1272
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1273
+ onClick: () => setAsideOpen(true),
1274
+ "aria-label": "Open sidebar",
1275
+ children: /* @__PURE__ */ jsx78(MenuIcon, { size: "md" })
1221
1276
  }
1222
- ),
1223
- /* @__PURE__ */ jsxs9("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: [
1224
- /* @__PURE__ */ jsxs9("div", { className: "p-4 border-b border-[hsl(var(--border))] flex items-center justify-between", children: [
1225
- navbarLogo ? /* @__PURE__ */ jsx78("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: navbarTitle }) : null,
1226
- /* @__PURE__ */ jsx78(
1227
- "button",
1228
- {
1229
- className: "p-1 rounded hover:bg-[hsl(var(--accent))] transition-colors",
1230
- onClick: () => setIsMobileNavbarOpen(false),
1231
- "aria-label": "Close menu",
1232
- children: /* @__PURE__ */ jsx78("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx78("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
1233
- }
1234
- )
1235
- ] }),
1236
- /* @__PURE__ */ jsx78(
1237
- "div",
1238
- {
1239
- className: "overflow-y-auto h-[calc(100vh-73px)]",
1240
- onClick: () => setIsMobileNavbarOpen(false),
1241
- children: navbar.content
1242
- }
1243
- )
1244
- ] })
1277
+ ) : showNavbarHamburger && /* @__PURE__ */ jsx78("div", { className: "w-10" })
1245
1278
  ] }),
1246
- /* @__PURE__ */ jsx78("main", { className: "flex-1 overflow-y-auto min-h-screen", children })
1247
- ] })
1248
- ] });
1279
+ header && !headerCollapsed && /* @__PURE__ */ jsx78("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 }),
1280
+ /* @__PURE__ */ jsx78("main", { className: `flex-1 overflow-y-auto ${paddingClasses[padding]}`, children }),
1281
+ footer && !footerCollapsed && /* @__PURE__ */ jsx78("footer", { className: `${heightClasses[footerHeight]} ${getVariantClasses(footerVariant, footerWithBorder)} ${footerWithBorder ? "border-t" : ""} px-4 flex items-center shrink-0`, children: footer.content })
1282
+ ] }),
1283
+ aside && !asideCollapsedDesktop && /* @__PURE__ */ jsx78(
1284
+ "aside",
1285
+ {
1286
+ className: `${asideDesktopShowClass} ${widthClasses2[asideWidth]} ${getVariantClasses(asideVariant, asideWithBorder)} ${asideWithBorder ? "border-l" : ""} flex-col shrink-0 overflow-y-auto`,
1287
+ children: aside.content
1288
+ }
1289
+ ),
1290
+ navbar && !navbarCollapsedMobile && /* @__PURE__ */ jsx78(
1291
+ MobileDrawer,
1292
+ {
1293
+ isOpen: navbarOpen,
1294
+ onClose: () => setNavbarOpen(false),
1295
+ position: "left",
1296
+ breakpoint: navbarBreakpoint,
1297
+ title,
1298
+ logo,
1299
+ children: navbar.content
1300
+ }
1301
+ ),
1302
+ aside && !asideCollapsedMobile && /* @__PURE__ */ jsx78(
1303
+ MobileDrawer,
1304
+ {
1305
+ isOpen: asideOpen,
1306
+ onClose: () => setAsideOpen(false),
1307
+ position: "right",
1308
+ breakpoint: asideBreakpoint,
1309
+ title: "Sidebar",
1310
+ children: aside.content
1311
+ }
1312
+ )
1313
+ ] }) });
1249
1314
  }
1250
- return /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex flex-col ${className}`, children: [
1251
- header && /* @__PURE__ */ jsx78("div", { className: "w-full", children: header }),
1252
- /* @__PURE__ */ jsx78("main", { className: "flex-1 overflow-y-auto", children })
1253
- ] });
1315
+ return /* @__PURE__ */ jsx78(AppShellContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs9("div", { className: `min-h-screen flex flex-col bg-[hsl(var(--background))] ${className}`, children: [
1316
+ needsMobileHeader && /* @__PURE__ */ jsxs9("div", { className: `${navbarMobileHideClass} sticky top-0 z-30 ${heightClasses[headerHeight]} px-4 flex items-center justify-between ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""}`, children: [
1317
+ showNavbarHamburger && /* @__PURE__ */ jsx78(
1318
+ "button",
1319
+ {
1320
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1321
+ onClick: () => setNavbarOpen(true),
1322
+ "aria-label": "Open navigation",
1323
+ children: /* @__PURE__ */ jsx78(MenuIcon, { size: "md" })
1324
+ }
1325
+ ),
1326
+ (logo || title) && /* @__PURE__ */ jsx78("div", { className: "flex-1 flex justify-center", children: logo || /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1327
+ showAsideHamburger ? /* @__PURE__ */ jsx78(
1328
+ "button",
1329
+ {
1330
+ className: "p-2 rounded-lg hover:bg-[hsl(var(--accent))] transition-colors",
1331
+ onClick: () => setAsideOpen(true),
1332
+ "aria-label": "Open sidebar",
1333
+ children: /* @__PURE__ */ jsx78(MenuIcon, { size: "md" })
1334
+ }
1335
+ ) : showNavbarHamburger && /* @__PURE__ */ jsx78("div", { className: "w-10" })
1336
+ ] }),
1337
+ header && !headerCollapsed && /* @__PURE__ */ jsxs9("header", { className: `sticky top-0 z-20 ${heightClasses[headerHeight]} ${getVariantClasses(headerVariant, headerWithBorder)} ${headerWithBorder ? "border-b" : ""} px-4 flex items-center`, children: [
1338
+ (logo || title) && /* @__PURE__ */ jsx78("div", { className: "mr-4 shrink-0", children: logo || /* @__PURE__ */ jsx78("span", { className: "text-xl font-bold text-[hsl(var(--foreground))]", children: title }) }),
1339
+ /* @__PURE__ */ jsx78("div", { className: "flex-1", children: header.content })
1340
+ ] }),
1341
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-1 min-h-0", children: [
1342
+ navbar && !navbarCollapsedDesktop && /* @__PURE__ */ jsx78(
1343
+ "nav",
1344
+ {
1345
+ className: `${navbarDesktopShowClass} ${widthClasses2[navbarWidth]} ${getVariantClasses(navbarVariant, navbarWithBorder)} ${navbarWithBorder ? "border-r" : ""} flex-col shrink-0 overflow-y-auto`,
1346
+ children: navbar.content
1347
+ }
1348
+ ),
1349
+ /* @__PURE__ */ jsx78("main", { className: `flex-1 overflow-y-auto min-w-0 ${paddingClasses[padding]}`, children }),
1350
+ aside && !asideCollapsedDesktop && /* @__PURE__ */ jsx78(
1351
+ "aside",
1352
+ {
1353
+ className: `${asideDesktopShowClass} ${widthClasses2[asideWidth]} ${getVariantClasses(asideVariant, asideWithBorder)} ${asideWithBorder ? "border-l" : ""} flex-col shrink-0 overflow-y-auto`,
1354
+ children: aside.content
1355
+ }
1356
+ )
1357
+ ] }),
1358
+ footer && !footerCollapsed && /* @__PURE__ */ jsx78("footer", { className: `${heightClasses[footerHeight]} ${getVariantClasses(footerVariant, footerWithBorder)} ${footerWithBorder ? "border-t" : ""} px-4 flex items-center shrink-0`, children: footer.content }),
1359
+ navbar && !navbarCollapsedMobile && /* @__PURE__ */ jsx78(
1360
+ MobileDrawer,
1361
+ {
1362
+ isOpen: navbarOpen,
1363
+ onClose: () => setNavbarOpen(false),
1364
+ position: "left",
1365
+ breakpoint: navbarBreakpoint,
1366
+ title,
1367
+ logo,
1368
+ children: navbar.content
1369
+ }
1370
+ ),
1371
+ aside && !asideCollapsedMobile && /* @__PURE__ */ jsx78(
1372
+ MobileDrawer,
1373
+ {
1374
+ isOpen: asideOpen,
1375
+ onClose: () => setAsideOpen(false),
1376
+ position: "right",
1377
+ breakpoint: asideBreakpoint,
1378
+ title: "Sidebar",
1379
+ children: aside.content
1380
+ }
1381
+ )
1382
+ ] }) });
1383
+ };
1384
+ var AppShellSection = ({
1385
+ children,
1386
+ grow = false,
1387
+ className = ""
1388
+ }) => {
1389
+ return /* @__PURE__ */ jsx78("div", { className: `${grow ? "flex-1" : ""} ${className}`, children });
1254
1390
  };
1391
+ AppShell.Section = AppShellSection;
1255
1392
 
1256
1393
  // src/components/Drawer.tsx
1257
1394
  import { useEffect as useEffect4 } from "react";
@@ -1404,8 +1541,8 @@ import { useState as useState5, useRef as useRef2 } from "react";
1404
1541
  import { jsx as jsx81, jsxs as jsxs12 } from "react/jsx-runtime";
1405
1542
  var sizeClasses5 = {
1406
1543
  sm: "px-3 py-1.5 text-sm",
1407
- md: "px-3 py-2.5 text-sm",
1408
- lg: "px-4 py-3 text-base"
1544
+ md: "px-4 py-2.5 text-base",
1545
+ lg: "px-4 py-3 text-lg"
1409
1546
  };
1410
1547
  var NumberInput = ({
1411
1548
  label,
@@ -1649,7 +1786,7 @@ var ActionMenu = ({
1649
1786
 
1650
1787
  // src/components/Card.tsx
1651
1788
  import { jsx as jsx83 } from "react/jsx-runtime";
1652
- var paddingClasses = {
1789
+ var paddingClasses2 = {
1653
1790
  none: "",
1654
1791
  sm: "p-4",
1655
1792
  md: "p-6",
@@ -1662,7 +1799,7 @@ var Card = ({
1662
1799
  hover = false,
1663
1800
  ...props
1664
1801
  }) => {
1665
- const paddingClass = paddingClasses[padding];
1802
+ const paddingClass = paddingClasses2[padding];
1666
1803
  const hoverClass = hover ? "hover:shadow-lg hover:border-[hsl(var(--ring))]/50 cursor-pointer transition-all duration-200 ease-in-out" : "";
1667
1804
  return /* @__PURE__ */ jsx83(
1668
1805
  "div",
@@ -2205,7 +2342,7 @@ var DatePicker = ({
2205
2342
  year: "numeric"
2206
2343
  });
2207
2344
  };
2208
- const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-sm transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] cursor-pointer";
2345
+ const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-base transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] cursor-pointer";
2209
2346
  const errorStyles = error ? "border-[hsl(var(--destructive))] focus:ring-[hsl(var(--destructive))]/50" : "";
2210
2347
  const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "";
2211
2348
  const calendar = isOpen && mounted && calendarPosition ? /* @__PURE__ */ jsxs20(
@@ -2307,7 +2444,7 @@ import { forwardRef as forwardRef4 } from "react";
2307
2444
  import { jsx as jsx93, jsxs as jsxs21 } from "react/jsx-runtime";
2308
2445
  var TimePicker = forwardRef4(
2309
2446
  ({ label, error, helperText, className = "", disabled, ...props }, ref) => {
2310
- const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-3 py-2.5 text-sm transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))]";
2447
+ const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-base transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))]";
2311
2448
  const errorStyles = error ? "border-[hsl(var(--destructive))] focus:ring-[hsl(var(--destructive))]/50" : "";
2312
2449
  const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "";
2313
2450
  return /* @__PURE__ */ jsxs21("div", { className, children: [
@@ -2487,7 +2624,7 @@ var DateTimePicker = ({
2487
2624
  const displayMinutes = minutes.toString().padStart(2, "0");
2488
2625
  return `${displayHours}:${displayMinutes} ${period}`;
2489
2626
  };
2490
- const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-sm transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] cursor-pointer";
2627
+ const baseStyles = "w-full appearance-none rounded-md border border-[hsl(var(--input))] bg-transparent text-[hsl(var(--foreground))] px-4 py-2.5 text-base transition-colors duration-150 focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))]/50 focus:border-[hsl(var(--ring))] hover:border-[hsl(var(--muted-foreground))] cursor-pointer";
2491
2628
  const errorStyles = error ? "border-[hsl(var(--destructive))] focus:ring-[hsl(var(--destructive))]/50" : "";
2492
2629
  const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-[hsl(var(--muted))]" : "";
2493
2630
  const picker = isOpen && mounted && pickerPosition ? /* @__PURE__ */ jsxs22(
@@ -3194,8 +3331,8 @@ var Textarea = ({
3194
3331
  }) => {
3195
3332
  const sizeClasses7 = {
3196
3333
  sm: "px-3 py-1.5 text-sm min-h-[80px]",
3197
- md: "px-3 py-2.5 text-sm min-h-[100px]",
3198
- lg: "px-4 py-3 text-base min-h-[120px]"
3334
+ md: "px-4 py-2.5 text-base min-h-[100px]",
3335
+ lg: "px-4 py-3 text-lg min-h-[120px]"
3199
3336
  };
3200
3337
  const resizeClasses = {
3201
3338
  none: "resize-none",
@@ -3847,11 +3984,11 @@ var RichTextEditor = ({
3847
3984
  };
3848
3985
 
3849
3986
  // src/components/Toast.tsx
3850
- import { createContext as createContext3, useContext as useContext3, useState as useState13, useCallback as useCallback2 } from "react";
3987
+ import { createContext as createContext4, useContext as useContext4, useState as useState13, useCallback as useCallback2 } from "react";
3851
3988
  import { jsx as jsx102, jsxs as jsxs29 } from "react/jsx-runtime";
3852
- var ToastContext = createContext3(void 0);
3989
+ var ToastContext = createContext4(void 0);
3853
3990
  var useToast = () => {
3854
- const context = useContext3(ToastContext);
3991
+ const context = useContext4(ToastContext);
3855
3992
  if (!context) {
3856
3993
  throw new Error("useToast must be used within a ToastProvider");
3857
3994
  }
@@ -8721,6 +8858,7 @@ export {
8721
8858
  Alert,
8722
8859
  AlertCircleIcon,
8723
8860
  AppShell,
8861
+ AppShellSection,
8724
8862
  AppleIcon,
8725
8863
  AreaChart,
8726
8864
  ArrowDownIcon,
@@ -8841,6 +8979,7 @@ export {
8841
8979
  themeScript,
8842
8980
  themes,
8843
8981
  toast,
8982
+ useAppShell,
8844
8983
  useSidebar,
8845
8984
  useTheme,
8846
8985
  useToast,