@fayz-ai/ui 0.5.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 (51) 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/dist/tailwind.cjs +30 -0
  31. package/dist/tailwind.cjs.map +1 -0
  32. package/dist/tailwind.d.ts +19 -0
  33. package/dist/tailwind.d.ts.map +1 -0
  34. package/dist/tailwind.js +28 -0
  35. package/dist/tailwind.js.map +1 -0
  36. package/package.json +9 -6
  37. package/src/dashboard/DashboardCanvas.tsx +13 -2
  38. package/src/dashboard/GoldCard.tsx +38 -0
  39. package/src/dashboard/KpiCard.tsx +4 -2
  40. package/src/dashboard/index.ts +1 -0
  41. package/src/index.ts +6 -0
  42. package/src/layout/AppShell.tsx +240 -20
  43. package/src/layout/ModulePage.tsx +2 -2
  44. package/src/layout/Sidebar.tsx +32 -6
  45. package/src/layout/Topbar.tsx +46 -17
  46. package/src/layout/index.ts +9 -1
  47. package/src/tailwind.ts +43 -0
  48. package/dist/chunk-7TBDPNLY.cjs.map +0 -1
  49. package/dist/chunk-CZ6X6PZT.js.map +0 -1
  50. package/dist/chunk-GE6XUREM.cjs.map +0 -1
  51. package/dist/chunk-GFH5HOCO.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { useCrossModuleBack, useBackHandler, SaveBarProvider, SaveBar } from './chunk-E526FHZ4.js';
2
2
  import { cn } from './chunk-DNYVEOAX.js';
3
3
  import * as React3 from 'react';
4
- import { Workflow, Star, MessageSquare, LayoutDashboard, Award, Zap, Mic, UsersRound, Disc3, ListMusic, Eye, Music, Layers, Banknote, CalendarDays, Radio, PartyPopper, Wheat, Egg, Apple, LeafyGreen, LayoutTemplate, Heart, PawPrint, Cat, Dog, Search, List, Plus, Filter, Building2, Contact, Handshake, MapPin, UtensilsCrossed, Camera, Tag, Percent, Globe, MessageCircle, BookOpen, UserCog, Briefcase, ClipboardList, Wrench, Target, ShoppingCart, Megaphone, DollarSign, Mail, FileText, BarChart3, Package, Calendar, Bell, CreditCard, Settings, Users, Home, PanelLeftClose, PanelLeft, Menu, ChevronRight, ChevronLeft, TreePalm, UserPlus, ArrowDownRight, ArrowUpRight, Ruler, Warehouse, Wallet, Sparkles, AlertTriangle, Clock, CircleDollarSign, TrendingUp, Receipt, Landmark, TableProperties, SlidersHorizontal, Plug, ArrowLeftRight, ArrowUpCircle, ArrowDownCircle, ChevronDown } from 'lucide-react';
4
+ import { FileCheck2, Clock3, Boxes, Workflow, UserX, UserPlus, UserCheck, TrendingUp, Star, Inbox, MessageSquare, LayoutDashboard, Award, Zap, Mic, UsersRound, Disc3, ListMusic, Eye, Music, Layers, CircleDollarSign, Landmark, Banknote, BadgeDollarSign, CalendarX, CalendarCheck2, CalendarDays, Radio, PartyPopper, Wheat, Egg, Apple, LeafyGreen, LayoutTemplate, FolderOpen, Heart, PawPrint, Cat, Dog, Clock, Ban, Shield, Search, ListPlus, List, Plus, Filter, Building2, Contact, Handshake, Map, MapPin, UtensilsCrossed, Camera, Tags, Tag, Percent, Globe, MessageCircle, BookOpenCheck, BookOpen, UserCog, Briefcase, ListChecks, ClipboardList, ShoppingBag, Receipt, Wrench, Target, ShoppingCart, Megaphone, DollarSign, Mail, FileText, BarChart3, Activity, Package, CalendarClock, Calendar, Bell, CreditCard, Settings, Users, Home, PanelLeftClose, PanelLeft, Menu, ChevronRight, ChevronLeft, Box, TreePalm, ArrowDownRight, ArrowUpRight, Ruler, Warehouse, Wallet, Sparkles, AlertTriangle, TableProperties, SlidersHorizontal, Plug, ArrowLeftRight, ArrowUpCircle, ArrowDownCircle, ChevronDown, ClipboardCheck, PiggyBank } from 'lucide-react';
5
5
  import * as Tooltip from '@radix-ui/react-tooltip';
6
6
  import { create } from 'zustand';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -26,7 +26,9 @@ var ICON_MAP = {
26
26
  CreditCard,
27
27
  Bell,
28
28
  Calendar,
29
+ CalendarClock,
29
30
  Package,
31
+ Activity,
30
32
  BarChart3,
31
33
  FileText,
32
34
  Mail,
@@ -35,28 +37,39 @@ var ICON_MAP = {
35
37
  ShoppingCart,
36
38
  Target,
37
39
  Wrench,
40
+ Receipt,
41
+ ShoppingBag,
38
42
  ClipboardList,
43
+ ListChecks,
39
44
  Briefcase,
40
45
  UserCog,
41
46
  BookOpen,
47
+ BookOpenCheck,
42
48
  MessageCircle,
43
49
  Globe,
44
50
  Percent,
45
51
  Tag,
52
+ Tags,
46
53
  Camera,
47
54
  UtensilsCrossed,
48
55
  MapPin,
56
+ Map,
49
57
  Handshake,
50
58
  Contact,
51
59
  Building2,
52
60
  Filter,
53
61
  Plus,
54
62
  List,
63
+ ListPlus,
55
64
  Search,
65
+ Shield,
66
+ Ban,
67
+ Clock,
56
68
  Dog,
57
69
  Cat,
58
70
  PawPrint,
59
71
  Heart,
72
+ FolderOpen,
60
73
  LayoutTemplate,
61
74
  LeafyGreen,
62
75
  Apple,
@@ -65,7 +78,12 @@ var ICON_MAP = {
65
78
  PartyPopper,
66
79
  Radio,
67
80
  CalendarDays,
81
+ CalendarCheck2,
82
+ CalendarX,
83
+ BadgeDollarSign,
68
84
  Banknote,
85
+ Landmark,
86
+ CircleDollarSign,
69
87
  Layers,
70
88
  Music,
71
89
  Eye,
@@ -77,8 +95,16 @@ var ICON_MAP = {
77
95
  Award,
78
96
  LayoutDashboard,
79
97
  MessageSquare,
98
+ Inbox,
80
99
  Star,
81
- Workflow
100
+ TrendingUp,
101
+ UserCheck,
102
+ UserPlus,
103
+ UserX,
104
+ Workflow,
105
+ Boxes,
106
+ Clock3,
107
+ FileCheck2
82
108
  };
83
109
  function getIcon(name) {
84
110
  return ICON_MAP[name] ?? Home;
@@ -408,23 +434,29 @@ var ICON_MAP2 = {
408
434
  CreditCard: CreditCard,
409
435
  Bell: Bell,
410
436
  Calendar: Calendar,
437
+ CalendarClock: CalendarClock,
411
438
  Package: Package,
439
+ Activity: Activity,
412
440
  BarChart3: BarChart3,
413
441
  FileText: FileText,
414
442
  Mail: Mail,
415
443
  DollarSign: DollarSign,
416
444
  Megaphone: Megaphone,
417
445
  ShoppingCart: ShoppingCart,
446
+ ShoppingBag: ShoppingBag,
418
447
  Target: Target,
419
448
  Wrench: Wrench,
420
449
  ClipboardList: ClipboardList,
450
+ ClipboardCheck,
421
451
  Briefcase: Briefcase,
422
452
  UserCog: UserCog,
423
453
  BookOpen: BookOpen,
424
454
  MessageCircle: MessageCircle,
425
455
  Globe: Globe,
456
+ BookOpenCheck: BookOpenCheck,
426
457
  Percent: Percent,
427
458
  Tag: Tag,
459
+ Tags: Tags,
428
460
  Camera: Camera,
429
461
  UtensilsCrossed: UtensilsCrossed,
430
462
  Search: Search,
@@ -435,7 +467,10 @@ var ICON_MAP2 = {
435
467
  ChevronDown: ChevronDown,
436
468
  Filter: Filter,
437
469
  Plus: Plus,
470
+ Shield: Shield,
438
471
  List: List,
472
+ ListChecks: ListChecks,
473
+ FolderOpen: FolderOpen,
439
474
  Dog: Dog,
440
475
  Cat: Cat,
441
476
  PawPrint: PawPrint,
@@ -451,11 +486,11 @@ var ICON_MAP2 = {
451
486
  Plug,
452
487
  SlidersHorizontal,
453
488
  TableProperties,
454
- Landmark,
455
- Receipt,
456
- TrendingUp,
457
- CircleDollarSign,
458
- Clock,
489
+ Landmark: Landmark,
490
+ Receipt: Receipt,
491
+ TrendingUp: TrendingUp,
492
+ CircleDollarSign: CircleDollarSign,
493
+ Clock: Clock,
459
494
  AlertTriangle,
460
495
  Sparkles,
461
496
  Wallet,
@@ -463,11 +498,16 @@ var ICON_MAP2 = {
463
498
  Ruler,
464
499
  ArrowUpRight,
465
500
  ArrowDownRight,
466
- UserPlus,
501
+ UserPlus: UserPlus,
502
+ UserX: UserX,
467
503
  TreePalm,
504
+ Boxes: Boxes,
505
+ Box,
506
+ FileCheck2: FileCheck2,
468
507
  PartyPopper: PartyPopper,
469
508
  Radio: Radio,
470
509
  CalendarDays: CalendarDays,
510
+ BadgeDollarSign: BadgeDollarSign,
471
511
  Banknote: Banknote,
472
512
  Layers: Layers,
473
513
  Music: Music,
@@ -475,7 +515,17 @@ var ICON_MAP2 = {
475
515
  ListMusic: ListMusic,
476
516
  Disc3: Disc3,
477
517
  UsersRound: UsersRound,
478
- Mic: Mic
518
+ Mic: Mic,
519
+ CalendarCheck2: CalendarCheck2,
520
+ CalendarX: CalendarX,
521
+ ListPlus: ListPlus,
522
+ Map: Map,
523
+ Ban: Ban,
524
+ Clock3: Clock3,
525
+ Inbox: Inbox,
526
+ UserCheck: UserCheck,
527
+ Star: Star,
528
+ Zap: Zap
479
529
  };
480
530
  function getIcon2(name) {
481
531
  return ICON_MAP2[name] ?? Home;
@@ -560,7 +610,7 @@ function Topbar({
560
610
  return /* @__PURE__ */ jsxs("header", { "data-print": "hide", className: "sticky top-0 z-50 w-full shrink-0", children: [
561
611
  /* @__PURE__ */ jsx("div", { className: "border-b border-sidebar-border bg-sidebar text-sidebar-foreground", children: /* @__PURE__ */ jsxs("div", { className: "flex h-14 w-full items-center justify-between px-4 md:px-6", children: [
562
612
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
563
- /* @__PURE__ */ jsx(
613
+ onMenuClick && /* @__PURE__ */ jsx(
564
614
  "button",
565
615
  {
566
616
  onClick: onMenuClick,
@@ -575,7 +625,7 @@ function Topbar({
575
625
  "button",
576
626
  {
577
627
  onClick: () => setCommandPaletteOpen(true),
578
- 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",
628
+ 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",
579
629
  children: [
580
630
  /* @__PURE__ */ jsx(Search, { className: "absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-sidebar-muted" }),
581
631
  /* @__PURE__ */ jsx("span", { className: "text-xs", children: searchPlaceholder }),
@@ -606,7 +656,7 @@ function Topbar({
606
656
  const left = active.offsetLeft - el.offsetWidth / 2 + active.offsetWidth / 2;
607
657
  el.scrollTo({ left: Math.max(0, left), behavior: "smooth" });
608
658
  }
609
- }, className: "flex items-center gap-0.5 overflow-x-auto scrollbar-hide", children: allNav.map((item) => {
659
+ }, className: "flex items-center gap-0.5 overflow-x-auto scrollbar-none", children: allNav.map((item) => {
610
660
  if (item.children && item.children.length > 0) {
611
661
  return /* @__PURE__ */ jsx(
612
662
  NavDropdown,
@@ -669,14 +719,22 @@ function SidebarLayout({
669
719
  topbarEnd,
670
720
  userMenuSlot,
671
721
  notificationSlot,
672
- unreadCount = 0
722
+ unreadCount = 0,
723
+ hasBottomNav = false,
724
+ mobileHeader = "minimal"
673
725
  }) {
674
726
  const sidebarCollapsed = useLayoutStore((s) => s.sidebarCollapsed);
675
727
  const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
676
728
  const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
677
729
  const [headerSlot, setHeaderSlot] = React3.useState(null);
678
730
  const [actionsSlot, setActionsSlot] = React3.useState(null);
679
- return /* @__PURE__ */ jsx(SaveBarProvider, { children: /* @__PURE__ */ jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsxs("div", { className: "flex h-screen overflow-hidden bg-background", children: [
731
+ return /* @__PURE__ */ jsx(SaveBarProvider, { children: /* @__PURE__ */ jsx(ModuleHeaderSlotContext.Provider, { value: headerSlot, children: /* @__PURE__ */ jsx(ModuleHeaderActionsSlotContext.Provider, { value: actionsSlot, children: /* @__PURE__ */ jsxs("div", { className: cn(
732
+ "flex h-screen overflow-hidden bg-background",
733
+ // Frame mode: the inset gap around the framed card takes the sidebar (menu)
734
+ // color, so the white card reads as a panel floating on the same tone as the
735
+ // left menu. The card's own md:m-2 margin reveals this behind it.
736
+ frame && "md:bg-sidebar"
737
+ ), children: [
680
738
  /* @__PURE__ */ jsx("div", { className: "hidden md:flex", children: /* @__PURE__ */ jsx(
681
739
  Sidebar,
682
740
  {
@@ -704,9 +762,12 @@ function SidebarLayout({
704
762
  "relative flex flex-1 flex-col overflow-hidden",
705
763
  frame && "md:m-2 md:rounded-xl md:border md:border-border md:bg-card"
706
764
  ), children: [
707
- /* @__PURE__ */ 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: [
765
+ /* @__PURE__ */ jsxs("div", { className: cn(
766
+ "flex min-h-14 shrink-0 items-center justify-between gap-3 border-b border-border bg-card px-4 py-2",
767
+ mobileHeader !== "minimal" && "hidden md:flex"
768
+ ), children: [
708
769
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-3", children: [
709
- /* @__PURE__ */ jsx(
770
+ !hasBottomNav && /* @__PURE__ */ jsx(
710
771
  "button",
711
772
  {
712
773
  onClick: () => setMobileMenuOpen(true),
@@ -724,7 +785,7 @@ function SidebarLayout({
724
785
  topbarEnd
725
786
  ] })
726
787
  ] }),
727
- /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto", children }),
788
+ /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children }),
728
789
  /* @__PURE__ */ jsx(SaveBar, {})
729
790
  ] }),
730
791
  mobileMenuOpen && /* @__PURE__ */ jsx(
@@ -764,7 +825,8 @@ function TopbarLayout({
764
825
  frame,
765
826
  currentPath,
766
827
  topbarStart,
767
- topbarEnd
828
+ topbarEnd,
829
+ hasBottomNav = false
768
830
  }) {
769
831
  const [mobileMenuOpen, setMobileMenuOpen] = React3.useState(false);
770
832
  return /* @__PURE__ */ jsx(SaveBarProvider, { children: /* @__PURE__ */ jsxs("div", { className: "relative flex h-screen flex-col overflow-hidden bg-background", children: [
@@ -783,10 +845,10 @@ function TopbarLayout({
783
845
  userMenuExtras,
784
846
  leftContent: topbarStart,
785
847
  rightContent: topbarEnd,
786
- onMenuClick: () => setMobileMenuOpen(true)
848
+ onMenuClick: hasBottomNav ? void 0 : () => setMobileMenuOpen(true)
787
849
  }
788
850
  ),
789
- /* @__PURE__ */ jsx("main", { className: cn("flex-1 overflow-y-auto", frame && "md:p-2"), children: /* @__PURE__ */ jsx("div", { className: cn("min-h-full", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children }) }),
851
+ /* @__PURE__ */ jsx("main", { className: cn("flex-1 overflow-y-auto pb-16 md:pb-0", frame && "md:bg-sidebar md:p-2"), children: /* @__PURE__ */ jsx("div", { className: cn("min-h-full", frame && "md:rounded-xl md:border md:border-border md:bg-card"), children }) }),
790
852
  /* @__PURE__ */ jsx(SaveBar, {}),
791
853
  mobileMenuOpen && /* @__PURE__ */ jsx(
792
854
  MobileOverlay,
@@ -824,7 +886,7 @@ function MinimalLayout({
824
886
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: logo ?? /* @__PURE__ */ jsx("span", { className: "text-lg font-bold", children: "App" }) }),
825
887
  headerEnd && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: headerEnd })
826
888
  ] }),
827
- /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto", children })
889
+ /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-y-auto pb-16 md:pb-0", children })
828
890
  ] });
829
891
  }
830
892
  function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
@@ -886,6 +948,82 @@ function MobileOverlay({ onClose, onNavigate, ...sidebarProps }) {
886
948
  )
887
949
  ] });
888
950
  }
951
+ var BOTTOM_NAV_ICONS = {
952
+ Home: Home,
953
+ Receipt: Receipt,
954
+ ArrowLeftRight: ArrowLeftRight,
955
+ Calendar: Calendar,
956
+ CreditCard: CreditCard,
957
+ Settings: Settings,
958
+ Menu: Menu,
959
+ MessageCircle: MessageCircle,
960
+ Wallet: Wallet,
961
+ PiggyBank,
962
+ Plus: Plus
963
+ };
964
+ function FloatingProfileAvatar({ user, onClick }) {
965
+ if (!user) return null;
966
+ const label = user.fullName || user.email;
967
+ return /* @__PURE__ */ jsx(
968
+ "button",
969
+ {
970
+ type: "button",
971
+ onClick,
972
+ "aria-label": "Profile",
973
+ className: "fixed right-3 top-3 z-40 md:hidden",
974
+ children: user.avatarUrl ? /* @__PURE__ */ jsx(
975
+ "img",
976
+ {
977
+ src: user.avatarUrl,
978
+ alt: "",
979
+ className: "h-9 w-9 rounded-full object-cover shadow-md ring-2 ring-background"
980
+ }
981
+ ) : /* @__PURE__ */ 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() })
982
+ }
983
+ );
984
+ }
985
+ function MobileBottomNav({
986
+ items,
987
+ currentPath,
988
+ onNavigate,
989
+ onAction
990
+ }) {
991
+ const path = currentPath ?? "";
992
+ return /* @__PURE__ */ 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) => {
993
+ if (item.kind === "action") {
994
+ const ActionIcon = BOTTOM_NAV_ICONS[item.icon] ?? Plus;
995
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-1 items-start justify-center", children: /* @__PURE__ */ jsx(
996
+ "button",
997
+ {
998
+ type: "button",
999
+ onClick: () => onAction?.(item.id),
1000
+ "aria-label": item.label ?? "Add",
1001
+ 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",
1002
+ children: /* @__PURE__ */ jsx(ActionIcon, { className: "h-6 w-6" })
1003
+ }
1004
+ ) }, item.id);
1005
+ }
1006
+ const isActive = item.route === "/" ? path === "/" || path === "" : path === item.route || path.startsWith(item.route + "/");
1007
+ const Icon = BOTTOM_NAV_ICONS[item.icon] ?? Home;
1008
+ return /* @__PURE__ */ jsxs(
1009
+ "button",
1010
+ {
1011
+ type: "button",
1012
+ onClick: () => onNavigate?.(item.route),
1013
+ className: cn(
1014
+ "flex flex-1 flex-col items-center justify-center gap-0.5 px-1 py-1 transition-colors",
1015
+ isActive ? "text-primary" : "text-muted-foreground"
1016
+ ),
1017
+ "aria-current": isActive ? "page" : void 0,
1018
+ children: [
1019
+ /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5" }),
1020
+ /* @__PURE__ */ jsx("span", { className: "text-xs", children: item.label })
1021
+ ]
1022
+ },
1023
+ item.route
1024
+ );
1025
+ }) });
1026
+ }
889
1027
  function AppShell({
890
1028
  variant,
891
1029
  contentFrame,
@@ -906,13 +1044,28 @@ function AppShell({
906
1044
  topbarEnd,
907
1045
  sidebarTopContent,
908
1046
  sidebarFooterContent,
1047
+ bottomNav,
1048
+ onBottomNavAction,
1049
+ mobileHeader = "minimal",
909
1050
  userMenuSlot,
910
1051
  notificationSlot,
911
1052
  unreadCount = 0
912
1053
  }) {
1054
+ const hasBottomNav = !!bottomNav?.length;
1055
+ const bottomBar = hasBottomNav ? /* @__PURE__ */ jsx(
1056
+ MobileBottomNav,
1057
+ {
1058
+ items: bottomNav,
1059
+ currentPath,
1060
+ onNavigate,
1061
+ onAction: onBottomNavAction
1062
+ }
1063
+ ) : null;
1064
+ const floatingAvatar = mobileHeader === "transparent" && user ? /* @__PURE__ */ jsx(FloatingProfileAvatar, { user, onClick: onProfile }) : null;
1065
+ let layoutElement;
913
1066
  switch (variant) {
914
1067
  case "sidebar":
915
- return /* @__PURE__ */ jsx(
1068
+ layoutElement = /* @__PURE__ */ jsx(
916
1069
  SidebarLayout,
917
1070
  {
918
1071
  navigation,
@@ -935,11 +1088,14 @@ function AppShell({
935
1088
  userMenuSlot,
936
1089
  notificationSlot,
937
1090
  unreadCount,
1091
+ hasBottomNav,
1092
+ mobileHeader,
938
1093
  children
939
1094
  }
940
1095
  );
1096
+ break;
941
1097
  case "topbar":
942
- return /* @__PURE__ */ jsx(
1098
+ layoutElement = /* @__PURE__ */ jsx(
943
1099
  TopbarLayout,
944
1100
  {
945
1101
  navigation,
@@ -955,15 +1111,23 @@ function AppShell({
955
1111
  currentPath,
956
1112
  topbarStart,
957
1113
  topbarEnd,
1114
+ hasBottomNav,
958
1115
  children
959
1116
  }
960
1117
  );
1118
+ break;
961
1119
  case "minimal":
962
- return /* @__PURE__ */ jsx(MinimalLayout, { logo, user, headerEnd: topbarEnd, children });
1120
+ layoutElement = /* @__PURE__ */ jsx(MinimalLayout, { logo, user, headerEnd: topbarEnd, children });
1121
+ break;
963
1122
  default: {
964
1123
  return null;
965
1124
  }
966
1125
  }
1126
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1127
+ layoutElement,
1128
+ floatingAvatar,
1129
+ bottomBar
1130
+ ] });
967
1131
  }
968
1132
  var NavTransitionContext = React3.createContext("slide");
969
1133
  function NavTransitionProvider({ value, children }) {
@@ -1052,7 +1216,7 @@ function MobileTabs({ nav }) {
1052
1216
  }
1053
1217
  }, [nav]);
1054
1218
  return /* @__PURE__ */ jsxs("div", { className: "md:hidden -mx-1 mb-4 no-print", children: [
1055
- /* @__PURE__ */ jsx("div", { ref: scrollRef, className: "flex gap-1 px-1 pb-2 overflow-x-auto scrollbar-hide", children: nav.map((item) => {
1219
+ /* @__PURE__ */ jsx("div", { ref: scrollRef, className: "flex gap-1 px-1 pb-2 overflow-x-auto scrollbar-none", children: nav.map((item) => {
1056
1220
  const Icon = item.icon ? ICON_MAP2[item.icon] ?? null : null;
1057
1221
  const hasChildren = item.children && item.children.length > 0;
1058
1222
  const isActive = item.active || item.children?.some((c) => c.active);
@@ -1175,7 +1339,7 @@ function ModuleHeader({ nav }) {
1175
1339
  const kids = item.children ?? [];
1176
1340
  return kids.find((c) => /list/i.test(c.id) || /^list$/i.test(c.label)) ?? kids[kids.length - 1];
1177
1341
  }
1178
- const content = /* @__PURE__ */ jsx("div", { className: "flex w-full min-w-0 items-center gap-4", children: /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-0.5 overflow-x-auto scrollbar-hide", children: nav.map((item) => {
1342
+ const content = /* @__PURE__ */ jsx("div", { className: "flex w-full min-w-0 items-center gap-4", children: /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-0.5 overflow-x-auto scrollbar-none", children: nav.map((item) => {
1179
1343
  const Icon = item.icon ? ICON_MAP2[item.icon] ?? null : null;
1180
1344
  const hasChildren = item.children && item.children.length > 0;
1181
1345
  const isActive = item.active || item.children?.some((c) => c.active);
@@ -1233,5 +1397,5 @@ function ModulePage({ title, subtitle, nav, children, className, headerAction, s
1233
1397
  }
1234
1398
 
1235
1399
  export { AppShell, BackStyleProvider, ICON_MAP, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeaderActions, PageTransition, Sidebar, SubpageHeader, Topbar, useBackStyle, useLayoutStore, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useNavTransition };
1236
- //# sourceMappingURL=chunk-CZ6X6PZT.js.map
1237
- //# sourceMappingURL=chunk-CZ6X6PZT.js.map
1400
+ //# sourceMappingURL=chunk-LO5QZO7F.js.map
1401
+ //# sourceMappingURL=chunk-LO5QZO7F.js.map