@fayz-ai/ui 0.6.0 → 0.6.6

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.
Files changed (44) hide show
  1. package/dist/{chunk-7TBDPNLY.cjs → chunk-5QFB6AIQ.cjs} +40 -11
  2. package/dist/chunk-5QFB6AIQ.cjs.map +1 -0
  3. package/dist/{chunk-GE6XUREM.cjs → chunk-DJHS2XRW.cjs} +185 -21
  4. package/dist/chunk-DJHS2XRW.cjs.map +1 -0
  5. package/dist/{chunk-CZ6X6PZT.js → chunk-LO5QZO7F.js} +192 -28
  6. package/dist/chunk-LO5QZO7F.js.map +1 -0
  7. package/dist/{chunk-GFH5HOCO.js → chunk-XLBGB7IW.js} +40 -12
  8. package/dist/chunk-XLBGB7IW.js.map +1 -0
  9. package/dist/dashboard/DashboardCanvas.d.ts +5 -1
  10. package/dist/dashboard/DashboardCanvas.d.ts.map +1 -1
  11. package/dist/dashboard/GoldCard.d.ts +19 -0
  12. package/dist/dashboard/GoldCard.d.ts.map +1 -0
  13. package/dist/dashboard/KpiCard.d.ts.map +1 -1
  14. package/dist/dashboard/index.cjs +28 -24
  15. package/dist/dashboard/index.d.ts +1 -0
  16. package/dist/dashboard/index.d.ts.map +1 -1
  17. package/dist/dashboard/index.js +1 -1
  18. package/dist/index.cjs +46 -42
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +2 -2
  22. package/dist/layout/AppShell.d.ts +27 -6
  23. package/dist/layout/AppShell.d.ts.map +1 -1
  24. package/dist/layout/Sidebar.d.ts.map +1 -1
  25. package/dist/layout/Topbar.d.ts.map +1 -1
  26. package/dist/layout/index.cjs +17 -17
  27. package/dist/layout/index.d.ts +1 -1
  28. package/dist/layout/index.d.ts.map +1 -1
  29. package/dist/layout/index.js +1 -1
  30. package/package.json +3 -6
  31. package/src/dashboard/DashboardCanvas.tsx +13 -2
  32. package/src/dashboard/GoldCard.tsx +38 -0
  33. package/src/dashboard/KpiCard.tsx +4 -2
  34. package/src/dashboard/index.ts +1 -0
  35. package/src/index.ts +6 -0
  36. package/src/layout/AppShell.tsx +240 -20
  37. package/src/layout/ModulePage.tsx +2 -2
  38. package/src/layout/Sidebar.tsx +32 -6
  39. package/src/layout/Topbar.tsx +46 -17
  40. package/src/layout/index.ts +9 -1
  41. package/dist/chunk-7TBDPNLY.cjs.map +0 -1
  42. package/dist/chunk-CZ6X6PZT.js.map +0 -1
  43. package/dist/chunk-GE6XUREM.cjs.map +0 -1
  44. package/dist/chunk-GFH5HOCO.js.map +0 -1
@@ -50,7 +50,9 @@ var ICON_MAP = {
50
50
  CreditCard: lucideReact.CreditCard,
51
51
  Bell: lucideReact.Bell,
52
52
  Calendar: lucideReact.Calendar,
53
+ CalendarClock: lucideReact.CalendarClock,
53
54
  Package: lucideReact.Package,
55
+ Activity: lucideReact.Activity,
54
56
  BarChart3: lucideReact.BarChart3,
55
57
  FileText: lucideReact.FileText,
56
58
  Mail: lucideReact.Mail,
@@ -59,28 +61,39 @@ var ICON_MAP = {
59
61
  ShoppingCart: lucideReact.ShoppingCart,
60
62
  Target: lucideReact.Target,
61
63
  Wrench: lucideReact.Wrench,
64
+ Receipt: lucideReact.Receipt,
65
+ ShoppingBag: lucideReact.ShoppingBag,
62
66
  ClipboardList: lucideReact.ClipboardList,
67
+ ListChecks: lucideReact.ListChecks,
63
68
  Briefcase: lucideReact.Briefcase,
64
69
  UserCog: lucideReact.UserCog,
65
70
  BookOpen: lucideReact.BookOpen,
71
+ BookOpenCheck: lucideReact.BookOpenCheck,
66
72
  MessageCircle: lucideReact.MessageCircle,
67
73
  Globe: lucideReact.Globe,
68
74
  Percent: lucideReact.Percent,
69
75
  Tag: lucideReact.Tag,
76
+ Tags: lucideReact.Tags,
70
77
  Camera: lucideReact.Camera,
71
78
  UtensilsCrossed: lucideReact.UtensilsCrossed,
72
79
  MapPin: lucideReact.MapPin,
80
+ Map: lucideReact.Map,
73
81
  Handshake: lucideReact.Handshake,
74
82
  Contact: lucideReact.Contact,
75
83
  Building2: lucideReact.Building2,
76
84
  Filter: lucideReact.Filter,
77
85
  Plus: lucideReact.Plus,
78
86
  List: lucideReact.List,
87
+ ListPlus: lucideReact.ListPlus,
79
88
  Search: lucideReact.Search,
89
+ Shield: lucideReact.Shield,
90
+ Ban: lucideReact.Ban,
91
+ Clock: lucideReact.Clock,
80
92
  Dog: lucideReact.Dog,
81
93
  Cat: lucideReact.Cat,
82
94
  PawPrint: lucideReact.PawPrint,
83
95
  Heart: lucideReact.Heart,
96
+ FolderOpen: lucideReact.FolderOpen,
84
97
  LayoutTemplate: lucideReact.LayoutTemplate,
85
98
  LeafyGreen: lucideReact.LeafyGreen,
86
99
  Apple: lucideReact.Apple,
@@ -89,7 +102,12 @@ var ICON_MAP = {
89
102
  PartyPopper: lucideReact.PartyPopper,
90
103
  Radio: lucideReact.Radio,
91
104
  CalendarDays: lucideReact.CalendarDays,
105
+ CalendarCheck2: lucideReact.CalendarCheck2,
106
+ CalendarX: lucideReact.CalendarX,
107
+ BadgeDollarSign: lucideReact.BadgeDollarSign,
92
108
  Banknote: lucideReact.Banknote,
109
+ Landmark: lucideReact.Landmark,
110
+ CircleDollarSign: lucideReact.CircleDollarSign,
93
111
  Layers: lucideReact.Layers,
94
112
  Music: lucideReact.Music,
95
113
  Eye: lucideReact.Eye,
@@ -101,8 +119,16 @@ var ICON_MAP = {
101
119
  Award: lucideReact.Award,
102
120
  LayoutDashboard: lucideReact.LayoutDashboard,
103
121
  MessageSquare: lucideReact.MessageSquare,
122
+ Inbox: lucideReact.Inbox,
104
123
  Star: lucideReact.Star,
105
- Workflow: lucideReact.Workflow
124
+ TrendingUp: lucideReact.TrendingUp,
125
+ UserCheck: lucideReact.UserCheck,
126
+ UserPlus: lucideReact.UserPlus,
127
+ UserX: lucideReact.UserX,
128
+ Workflow: lucideReact.Workflow,
129
+ Boxes: lucideReact.Boxes,
130
+ Clock3: lucideReact.Clock3,
131
+ FileCheck2: lucideReact.FileCheck2
106
132
  };
107
133
  function getIcon(name) {
108
134
  return ICON_MAP[name] ?? lucideReact.Home;
@@ -432,23 +458,29 @@ var ICON_MAP2 = {
432
458
  CreditCard: lucideReact.CreditCard,
433
459
  Bell: lucideReact.Bell,
434
460
  Calendar: lucideReact.Calendar,
461
+ CalendarClock: lucideReact.CalendarClock,
435
462
  Package: lucideReact.Package,
463
+ Activity: lucideReact.Activity,
436
464
  BarChart3: lucideReact.BarChart3,
437
465
  FileText: lucideReact.FileText,
438
466
  Mail: lucideReact.Mail,
439
467
  DollarSign: lucideReact.DollarSign,
440
468
  Megaphone: lucideReact.Megaphone,
441
469
  ShoppingCart: lucideReact.ShoppingCart,
470
+ ShoppingBag: lucideReact.ShoppingBag,
442
471
  Target: lucideReact.Target,
443
472
  Wrench: lucideReact.Wrench,
444
473
  ClipboardList: lucideReact.ClipboardList,
474
+ ClipboardCheck: lucideReact.ClipboardCheck,
445
475
  Briefcase: lucideReact.Briefcase,
446
476
  UserCog: lucideReact.UserCog,
447
477
  BookOpen: lucideReact.BookOpen,
448
478
  MessageCircle: lucideReact.MessageCircle,
449
479
  Globe: lucideReact.Globe,
480
+ BookOpenCheck: lucideReact.BookOpenCheck,
450
481
  Percent: lucideReact.Percent,
451
482
  Tag: lucideReact.Tag,
483
+ Tags: lucideReact.Tags,
452
484
  Camera: lucideReact.Camera,
453
485
  UtensilsCrossed: lucideReact.UtensilsCrossed,
454
486
  Search: lucideReact.Search,
@@ -459,7 +491,10 @@ var ICON_MAP2 = {
459
491
  ChevronDown: lucideReact.ChevronDown,
460
492
  Filter: lucideReact.Filter,
461
493
  Plus: lucideReact.Plus,
494
+ Shield: lucideReact.Shield,
462
495
  List: lucideReact.List,
496
+ ListChecks: lucideReact.ListChecks,
497
+ FolderOpen: lucideReact.FolderOpen,
463
498
  Dog: lucideReact.Dog,
464
499
  Cat: lucideReact.Cat,
465
500
  PawPrint: lucideReact.PawPrint,
@@ -488,10 +523,15 @@ var ICON_MAP2 = {
488
523
  ArrowUpRight: lucideReact.ArrowUpRight,
489
524
  ArrowDownRight: lucideReact.ArrowDownRight,
490
525
  UserPlus: lucideReact.UserPlus,
526
+ UserX: lucideReact.UserX,
491
527
  TreePalm: lucideReact.TreePalm,
528
+ Boxes: lucideReact.Boxes,
529
+ Box: lucideReact.Box,
530
+ FileCheck2: lucideReact.FileCheck2,
492
531
  PartyPopper: lucideReact.PartyPopper,
493
532
  Radio: lucideReact.Radio,
494
533
  CalendarDays: lucideReact.CalendarDays,
534
+ BadgeDollarSign: lucideReact.BadgeDollarSign,
495
535
  Banknote: lucideReact.Banknote,
496
536
  Layers: lucideReact.Layers,
497
537
  Music: lucideReact.Music,
@@ -499,7 +539,17 @@ var ICON_MAP2 = {
499
539
  ListMusic: lucideReact.ListMusic,
500
540
  Disc3: lucideReact.Disc3,
501
541
  UsersRound: lucideReact.UsersRound,
502
- Mic: lucideReact.Mic
542
+ Mic: lucideReact.Mic,
543
+ CalendarCheck2: lucideReact.CalendarCheck2,
544
+ CalendarX: lucideReact.CalendarX,
545
+ ListPlus: lucideReact.ListPlus,
546
+ Map: lucideReact.Map,
547
+ Ban: lucideReact.Ban,
548
+ Clock3: lucideReact.Clock3,
549
+ Inbox: lucideReact.Inbox,
550
+ UserCheck: lucideReact.UserCheck,
551
+ Star: lucideReact.Star,
552
+ Zap: lucideReact.Zap
503
553
  };
504
554
  function getIcon2(name) {
505
555
  return ICON_MAP2[name] ?? lucideReact.Home;
@@ -584,7 +634,7 @@ function Topbar({
584
634
  return /* @__PURE__ */ jsxRuntime.jsxs("header", { "data-print": "hide", className: "sticky top-0 z-50 w-full shrink-0", children: [
585
635
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b border-sidebar-border bg-sidebar text-sidebar-foreground", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-14 w-full items-center justify-between px-4 md:px-6", children: [
586
636
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
587
- /* @__PURE__ */ jsxRuntime.jsx(
637
+ onMenuClick && /* @__PURE__ */ jsxRuntime.jsx(
588
638
  "button",
589
639
  {
590
640
  onClick: onMenuClick,
@@ -599,7 +649,7 @@ function Topbar({
599
649
  "button",
600
650
  {
601
651
  onClick: () => setCommandPaletteOpen(true),
602
- className: "relative flex h-8 w-full items-center rounded-md border border-sidebar-border bg-sidebar-accent px-3 pl-8 text-sm text-sidebar-muted shadow-sm transition-colors hover:bg-card",
652
+ className: "relative flex h-8 w-full items-center rounded-md border border-sidebar-border bg-sidebar-accent px-3 pl-8 text-sm text-sidebar-muted shadow-sm transition-colors hover:border-sidebar-foreground/25 hover:bg-sidebar-foreground/10 hover:text-sidebar-foreground",
603
653
  children: [
604
654
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-sidebar-muted" }),
605
655
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: searchPlaceholder }),
@@ -630,7 +680,7 @@ function Topbar({
630
680
  const left = active.offsetLeft - el.offsetWidth / 2 + active.offsetWidth / 2;
631
681
  el.scrollTo({ left: Math.max(0, left), behavior: "smooth" });
632
682
  }
633
- }, className: "flex items-center gap-0.5 overflow-x-auto scrollbar-hide", children: allNav.map((item) => {
683
+ }, className: "flex items-center gap-0.5 overflow-x-auto scrollbar-none", children: allNav.map((item) => {
634
684
  if (item.children && item.children.length > 0) {
635
685
  return /* @__PURE__ */ jsxRuntime.jsx(
636
686
  NavDropdown,
@@ -693,14 +743,22 @@ function SidebarLayout({
693
743
  topbarEnd,
694
744
  userMenuSlot,
695
745
  notificationSlot,
696
- unreadCount = 0
746
+ unreadCount = 0,
747
+ hasBottomNav = false,
748
+ mobileHeader = "minimal"
697
749
  }) {
698
750
  const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
699
751
  const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
700
752
  const [mobileMenuOpen, setMobileMenuOpen] = React3__namespace.useState(false);
701
753
  const [headerSlot, setHeaderSlot] = React3__namespace.useState(null);
702
754
  const [actionsSlot, setActionsSlot] = React3__namespace.useState(null);
703
- return /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen overflow-hidden bg-background", children: [
755
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsxRuntime.jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn(
756
+ "flex h-screen overflow-hidden bg-background",
757
+ // Frame mode: the inset gap around the framed card takes the sidebar (menu)
758
+ // color, so the white card reads as a panel floating on the same tone as the
759
+ // left menu. The card's own md:m-2 margin reveals this behind it.
760
+ frame && "md:bg-sidebar"
761
+ ), children: [
704
762
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:flex", children: /* @__PURE__ */ jsxRuntime.jsx(
705
763
  Sidebar,
706
764
  {
@@ -728,9 +786,12 @@ function SidebarLayout({
728
786
  "relative flex flex-1 flex-col overflow-hidden",
729
787
  frame && "md:m-2 md:rounded-xl md:border md:border-border md:bg-card"
730
788
  ), children: [
731
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-14 shrink-0 items-center justify-between gap-3 border-b border-border bg-card px-4 py-2", children: [
789
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn(
790
+ "flex min-h-14 shrink-0 items-center justify-between gap-3 border-b border-border bg-card px-4 py-2",
791
+ mobileHeader !== "minimal" && "hidden md:flex"
792
+ ), children: [
732
793
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
733
- /* @__PURE__ */ jsxRuntime.jsx(
794
+ !hasBottomNav && /* @__PURE__ */ jsxRuntime.jsx(
734
795
  "button",
735
796
  {
736
797
  onClick: () => setMobileMenuOpen(true),
@@ -748,7 +809,7 @@ function SidebarLayout({
748
809
  topbarEnd
749
810
  ] })
750
811
  ] }),
751
- /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto", children }),
812
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children }),
752
813
  /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBar, {})
753
814
  ] }),
754
815
  mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
@@ -788,7 +849,8 @@ function TopbarLayout({
788
849
  frame,
789
850
  currentPath,
790
851
  topbarStart,
791
- topbarEnd
852
+ topbarEnd,
853
+ hasBottomNav = false
792
854
  }) {
793
855
  const [mobileMenuOpen, setMobileMenuOpen] = React3__namespace.useState(false);
794
856
  return /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBarProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex h-screen flex-col overflow-hidden bg-background", children: [
@@ -807,10 +869,10 @@ function TopbarLayout({
807
869
  userMenuExtras,
808
870
  leftContent: topbarStart,
809
871
  rightContent: topbarEnd,
810
- onMenuClick: () => setMobileMenuOpen(true)
872
+ onMenuClick: hasBottomNav ? void 0 : () => setMobileMenuOpen(true)
811
873
  }
812
874
  ),
813
- /* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkVVVZO2LE_cjs.cn("flex-1 overflow-y-auto", frame && "md:p-2"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("min-h-full", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children }) }),
875
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: chunkVVVZO2LE_cjs.cn("flex-1 overflow-y-auto pb-16 md:pb-0", frame && "md:bg-sidebar md:p-2"), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("min-h-full", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children }) }),
814
876
  /* @__PURE__ */ jsxRuntime.jsx(chunkW4XXXJRW_cjs.SaveBar, {}),
815
877
  mobileMenuOpen && /* @__PURE__ */ jsxRuntime.jsx(
816
878
  MobileOverlay,
@@ -848,7 +910,7 @@ function MinimalLayout({
848
910
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: logo ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-bold", children: "App" }) }),
849
911
  headerEnd && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: headerEnd })
850
912
  ] }),
851
- /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto", children })
913
+ /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children })
852
914
  ] });
853
915
  }
854
916
  function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
@@ -910,6 +972,82 @@ function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
910
972
  )
911
973
  ] });
912
974
  }
975
+ var BOTTOM_NAV_ICONS = {
976
+ Home: lucideReact.Home,
977
+ Receipt: lucideReact.Receipt,
978
+ ArrowLeftRight: lucideReact.ArrowLeftRight,
979
+ Calendar: lucideReact.Calendar,
980
+ CreditCard: lucideReact.CreditCard,
981
+ Settings: lucideReact.Settings,
982
+ Menu: lucideReact.Menu,
983
+ MessageCircle: lucideReact.MessageCircle,
984
+ Wallet: lucideReact.Wallet,
985
+ PiggyBank: lucideReact.PiggyBank,
986
+ Plus: lucideReact.Plus
987
+ };
988
+ function FloatingProfileAvatar({ user, onClick }) {
989
+ if (!user) return null;
990
+ const label = user.fullName || user.email;
991
+ return /* @__PURE__ */ jsxRuntime.jsx(
992
+ "button",
993
+ {
994
+ type: "button",
995
+ onClick,
996
+ "aria-label": "Profile",
997
+ className: "fixed right-3 top-3 z-40 md:hidden",
998
+ children: user.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(
999
+ "img",
1000
+ {
1001
+ src: user.avatarUrl,
1002
+ alt: "",
1003
+ className: "h-9 w-9 rounded-full object-cover shadow-md ring-2 ring-background"
1004
+ }
1005
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-9 w-9 items-center justify-center rounded-full bg-primary text-sm font-semibold text-primary-foreground shadow-md ring-2 ring-background", children: (label || "?").charAt(0).toUpperCase() })
1006
+ }
1007
+ );
1008
+ }
1009
+ function MobileBottomNav({
1010
+ items,
1011
+ currentPath,
1012
+ onNavigate,
1013
+ onAction
1014
+ }) {
1015
+ const path = currentPath ?? "";
1016
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "fixed inset-x-0 bottom-0 z-50 flex h-16 items-center justify-around border-t border-border bg-background md:hidden", children: items.map((item) => {
1017
+ if (item.kind === "action") {
1018
+ const ActionIcon = BOTTOM_NAV_ICONS[item.icon] ?? lucideReact.Plus;
1019
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-start justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
1020
+ "button",
1021
+ {
1022
+ type: "button",
1023
+ onClick: () => onAction?.(item.id),
1024
+ "aria-label": item.label ?? "Add",
1025
+ className: "-mt-6 flex h-14 w-14 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-lg shadow-primary/30 ring-4 ring-background transition-transform active:scale-95",
1026
+ children: /* @__PURE__ */ jsxRuntime.jsx(ActionIcon, { className: "h-6 w-6" })
1027
+ }
1028
+ ) }, item.id);
1029
+ }
1030
+ const isActive = item.route === "/" ? path === "/" || path === "" : path === item.route || path.startsWith(item.route + "/");
1031
+ const Icon = BOTTOM_NAV_ICONS[item.icon] ?? lucideReact.Home;
1032
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1033
+ "button",
1034
+ {
1035
+ type: "button",
1036
+ onClick: () => onNavigate?.(item.route),
1037
+ className: chunkVVVZO2LE_cjs.cn(
1038
+ "flex flex-1 flex-col items-center justify-center gap-0.5 px-1 py-1 transition-colors",
1039
+ isActive ? "text-primary" : "text-muted-foreground"
1040
+ ),
1041
+ "aria-current": isActive ? "page" : void 0,
1042
+ children: [
1043
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-5 w-5" }),
1044
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs", children: item.label })
1045
+ ]
1046
+ },
1047
+ item.route
1048
+ );
1049
+ }) });
1050
+ }
913
1051
  function AppShell({
914
1052
  variant,
915
1053
  contentFrame,
@@ -930,13 +1068,28 @@ function AppShell({
930
1068
  topbarEnd,
931
1069
  sidebarTopContent,
932
1070
  sidebarFooterContent,
1071
+ bottomNav,
1072
+ onBottomNavAction,
1073
+ mobileHeader = "minimal",
933
1074
  userMenuSlot,
934
1075
  notificationSlot,
935
1076
  unreadCount = 0
936
1077
  }) {
1078
+ const hasBottomNav = !!bottomNav?.length;
1079
+ const bottomBar = hasBottomNav ? /* @__PURE__ */ jsxRuntime.jsx(
1080
+ MobileBottomNav,
1081
+ {
1082
+ items: bottomNav,
1083
+ currentPath,
1084
+ onNavigate,
1085
+ onAction: onBottomNavAction
1086
+ }
1087
+ ) : null;
1088
+ const floatingAvatar = mobileHeader === "transparent" && user ? /* @__PURE__ */ jsxRuntime.jsx(FloatingProfileAvatar, { user, onClick: onProfile }) : null;
1089
+ let layoutElement;
937
1090
  switch (variant) {
938
1091
  case "sidebar":
939
- return /* @__PURE__ */ jsxRuntime.jsx(
1092
+ layoutElement = /* @__PURE__ */ jsxRuntime.jsx(
940
1093
  SidebarLayout,
941
1094
  {
942
1095
  navigation,
@@ -959,11 +1112,14 @@ function AppShell({
959
1112
  userMenuSlot,
960
1113
  notificationSlot,
961
1114
  unreadCount,
1115
+ hasBottomNav,
1116
+ mobileHeader,
962
1117
  children
963
1118
  }
964
1119
  );
1120
+ break;
965
1121
  case "topbar":
966
- return /* @__PURE__ */ jsxRuntime.jsx(
1122
+ layoutElement = /* @__PURE__ */ jsxRuntime.jsx(
967
1123
  TopbarLayout,
968
1124
  {
969
1125
  navigation,
@@ -979,15 +1135,23 @@ function AppShell({
979
1135
  currentPath,
980
1136
  topbarStart,
981
1137
  topbarEnd,
1138
+ hasBottomNav,
982
1139
  children
983
1140
  }
984
1141
  );
1142
+ break;
985
1143
  case "minimal":
986
- return /* @__PURE__ */ jsxRuntime.jsx(MinimalLayout, { logo, user, headerEnd: topbarEnd, children });
1144
+ layoutElement = /* @__PURE__ */ jsxRuntime.jsx(MinimalLayout, { logo, user, headerEnd: topbarEnd, children });
1145
+ break;
987
1146
  default: {
988
1147
  return null;
989
1148
  }
990
1149
  }
1150
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1151
+ layoutElement,
1152
+ floatingAvatar,
1153
+ bottomBar
1154
+ ] });
991
1155
  }
992
1156
  var NavTransitionContext = React3__namespace.createContext("slide");
993
1157
  function NavTransitionProvider({ value, children }) {
@@ -1076,7 +1240,7 @@ function MobileTabs({ nav }) {
1076
1240
  }
1077
1241
  }, [nav]);
1078
1242
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden -mx-1 mb-4 no-print", children: [
1079
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex gap-1 px-1 pb-2 overflow-x-auto scrollbar-hide", children: nav.map((item) => {
1243
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex gap-1 px-1 pb-2 overflow-x-auto scrollbar-none", children: nav.map((item) => {
1080
1244
  const Icon = item.icon ? ICON_MAP2[item.icon] ?? null : null;
1081
1245
  const hasChildren = item.children && item.children.length > 0;
1082
1246
  const isActive = item.active || item.children?.some((c) => c.active);
@@ -1199,7 +1363,7 @@ function ModuleHeader({ nav }) {
1199
1363
  const kids = item.children ?? [];
1200
1364
  return kids.find((c) => /list/i.test(c.id) || /^list$/i.test(c.label)) ?? kids[kids.length - 1];
1201
1365
  }
1202
- const content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full min-w-0 items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-0.5 overflow-x-auto scrollbar-hide", children: nav.map((item) => {
1366
+ const content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex w-full min-w-0 items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-0 items-center gap-0.5 overflow-x-auto scrollbar-none", children: nav.map((item) => {
1203
1367
  const Icon = item.icon ? ICON_MAP2[item.icon] ?? null : null;
1204
1368
  const hasChildren = item.children && item.children.length > 0;
1205
1369
  const isActive = item.active || item.children?.some((c) => c.active);
@@ -1273,5 +1437,5 @@ exports.useModuleHeaderActionsSlot = useModuleHeaderActionsSlot;
1273
1437
  exports.useModuleHeaderSlot = useModuleHeaderSlot;
1274
1438
  exports.useModuleLayout = useModuleLayout;
1275
1439
  exports.useNavTransition = useNavTransition;
1276
- //# sourceMappingURL=chunk-GE6XUREM.cjs.map
1277
- //# sourceMappingURL=chunk-GE6XUREM.cjs.map
1440
+ //# sourceMappingURL=chunk-DJHS2XRW.cjs.map
1441
+ //# sourceMappingURL=chunk-DJHS2XRW.cjs.map