@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.
- package/dist/{chunk-7TBDPNLY.cjs → chunk-5QFB6AIQ.cjs} +40 -11
- package/dist/chunk-5QFB6AIQ.cjs.map +1 -0
- package/dist/{chunk-GE6XUREM.cjs → chunk-DJHS2XRW.cjs} +185 -21
- package/dist/chunk-DJHS2XRW.cjs.map +1 -0
- package/dist/{chunk-CZ6X6PZT.js → chunk-LO5QZO7F.js} +192 -28
- package/dist/chunk-LO5QZO7F.js.map +1 -0
- package/dist/{chunk-GFH5HOCO.js → chunk-XLBGB7IW.js} +40 -12
- package/dist/chunk-XLBGB7IW.js.map +1 -0
- package/dist/dashboard/DashboardCanvas.d.ts +5 -1
- package/dist/dashboard/DashboardCanvas.d.ts.map +1 -1
- package/dist/dashboard/GoldCard.d.ts +19 -0
- package/dist/dashboard/GoldCard.d.ts.map +1 -0
- package/dist/dashboard/KpiCard.d.ts.map +1 -1
- package/dist/dashboard/index.cjs +28 -24
- package/dist/dashboard/index.d.ts +1 -0
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +1 -1
- package/dist/index.cjs +46 -42
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/layout/AppShell.d.ts +27 -6
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Topbar.d.ts.map +1 -1
- package/dist/layout/index.cjs +17 -17
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +1 -1
- package/package.json +3 -6
- package/src/dashboard/DashboardCanvas.tsx +13 -2
- package/src/dashboard/GoldCard.tsx +38 -0
- package/src/dashboard/KpiCard.tsx +4 -2
- package/src/dashboard/index.ts +1 -0
- package/src/index.ts +6 -0
- package/src/layout/AppShell.tsx +240 -20
- package/src/layout/ModulePage.tsx +2 -2
- package/src/layout/Sidebar.tsx +32 -6
- package/src/layout/Topbar.tsx +46 -17
- package/src/layout/index.ts +9 -1
- package/dist/chunk-7TBDPNLY.cjs.map +0 -1
- package/dist/chunk-CZ6X6PZT.js.map +0 -1
- package/dist/chunk-GE6XUREM.cjs.map +0 -1
- 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,
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
1237
|
-
//# sourceMappingURL=chunk-
|
|
1400
|
+
//# sourceMappingURL=chunk-LO5QZO7F.js.map
|
|
1401
|
+
//# sourceMappingURL=chunk-LO5QZO7F.js.map
|