@almadar/ui 6.12.0 → 6.13.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.
@@ -29035,6 +29035,18 @@ var init_useAuthContext = __esm({
29035
29035
  "hooks/useAuthContext.ts"() {
29036
29036
  }
29037
29037
  });
29038
+ function resolveActiveNavHref(items, currentPath) {
29039
+ let best;
29040
+ for (const item of items) {
29041
+ for (const href of item.children?.length ? [item.href, ...item.children.map((c) => c.href)] : [item.href]) {
29042
+ if (currentPath === href) return href;
29043
+ if (currentPath.startsWith(href + "/") && (!best || href.length > best.length)) {
29044
+ best = href;
29045
+ }
29046
+ }
29047
+ }
29048
+ return best;
29049
+ }
29038
29050
  var DashboardLayout, NavLink, NavLinkTopnav, NavLinkBottom;
29039
29051
  var init_DashboardLayout = __esm({
29040
29052
  "components/core/templates/DashboardLayout.tsx"() {
@@ -29106,6 +29118,7 @@ var init_DashboardLayout = __esm({
29106
29118
  const location = reactRouterDom.useLocation();
29107
29119
  const ctxPagePath = providers.useCurrentPagePath();
29108
29120
  const activePath = (currentPath || void 0) ?? ctxPagePath ?? location.pathname;
29121
+ const activeHref = React96.useMemo(() => resolveActiveNavHref(navItems, activePath), [navItems, activePath]);
29109
29122
  const { signOut: authSignOut } = useAuthContext();
29110
29123
  const user = userProp || (null);
29111
29124
  const { t } = hooks.useTranslate();
@@ -29198,7 +29211,7 @@ var init_DashboardLayout = __esm({
29198
29211
  NavLink,
29199
29212
  {
29200
29213
  item,
29201
- currentPath: activePath,
29214
+ activeHref,
29202
29215
  compact: isRail
29203
29216
  },
29204
29217
  item.href
@@ -29265,7 +29278,7 @@ var init_DashboardLayout = __esm({
29265
29278
  NavLinkTopnav,
29266
29279
  {
29267
29280
  item,
29268
- currentPath: activePath
29281
+ activeHref
29269
29282
  },
29270
29283
  item.href
29271
29284
  ))
@@ -29441,7 +29454,7 @@ var init_DashboardLayout = __esm({
29441
29454
  NavLinkBottom,
29442
29455
  {
29443
29456
  item,
29444
- currentPath: activePath
29457
+ activeHref
29445
29458
  },
29446
29459
  item.href
29447
29460
  )) })
@@ -29455,15 +29468,71 @@ var init_DashboardLayout = __esm({
29455
29468
  DashboardLayout.displayName = "DashboardLayout";
29456
29469
  NavLink = ({
29457
29470
  item,
29458
- currentPath,
29471
+ activeHref,
29459
29472
  compact = false
29460
29473
  }) => {
29461
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
29474
+ const hasChildren = !!item.children?.length;
29475
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
29476
+ const isActive = item.href === activeHref || childActive;
29477
+ const [open, setOpen] = React96.useState(childActive);
29462
29478
  const iconClassName = cn(
29463
29479
  "h-5 w-5",
29464
29480
  isActive ? "text-primary-foreground" : "text-muted-foreground"
29465
29481
  );
29466
29482
  if (compact) {
29483
+ if (hasChildren) {
29484
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
29485
+ /* @__PURE__ */ jsxRuntime.jsx(
29486
+ Button,
29487
+ {
29488
+ variant: "ghost",
29489
+ title: item.label,
29490
+ "aria-label": item.label,
29491
+ "aria-expanded": open,
29492
+ className: cn(
29493
+ "flex items-center justify-center w-full px-2 py-2 rounded-lg transition-colors",
29494
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29495
+ ),
29496
+ onClick: () => setOpen(!open),
29497
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { as: "span", className: "relative inline-flex", children: [
29498
+ item.icon ? typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "font-semibold", as: "span", children: item.label.charAt(0).toUpperCase() }),
29499
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(
29500
+ Badge,
29501
+ {
29502
+ variant: isActive ? "primary" : "default",
29503
+ size: "sm",
29504
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
29505
+ children: item.badge
29506
+ }
29507
+ )
29508
+ ] })
29509
+ }
29510
+ ),
29511
+ open && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29512
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
29513
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "absolute left-full top-0 ml-2 w-48 bg-card dark:bg-card rounded-lg shadow-lg border border-border dark:border-border py-1 z-30", children: item.children.map((child) => {
29514
+ const childIsActive = child.href === activeHref;
29515
+ return /* @__PURE__ */ jsxRuntime.jsxs(
29516
+ reactRouterDom.Link,
29517
+ {
29518
+ to: child.href,
29519
+ onClick: () => setOpen(false),
29520
+ className: cn(
29521
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
29522
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29523
+ ),
29524
+ children: [
29525
+ child.icon && (typeof child.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: child.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(child.icon, { className: "h-4 w-4" })),
29526
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
29527
+ child.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
29528
+ ]
29529
+ },
29530
+ child.href
29531
+ );
29532
+ }) })
29533
+ ] })
29534
+ ] });
29535
+ }
29467
29536
  return /* @__PURE__ */ jsxRuntime.jsx(
29468
29537
  reactRouterDom.Link,
29469
29538
  {
@@ -29489,6 +29558,78 @@ var init_DashboardLayout = __esm({
29489
29558
  }
29490
29559
  );
29491
29560
  }
29561
+ if (hasChildren) {
29562
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { children: [
29563
+ /* @__PURE__ */ jsxRuntime.jsxs(
29564
+ Button,
29565
+ {
29566
+ variant: "ghost",
29567
+ "aria-expanded": open,
29568
+ className: cn(
29569
+ "flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium transition-colors",
29570
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29571
+ ),
29572
+ onClick: () => setOpen(!open),
29573
+ children: [
29574
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: iconClassName })),
29575
+ /* @__PURE__ */ jsxRuntime.jsx(
29576
+ Typography,
29577
+ {
29578
+ variant: "small",
29579
+ color: isActive ? "inherit" : "primary",
29580
+ className: "flex-1 text-left",
29581
+ as: "span",
29582
+ children: item.label
29583
+ }
29584
+ ),
29585
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
29586
+ /* @__PURE__ */ jsxRuntime.jsx(
29587
+ Icon,
29588
+ {
29589
+ name: "chevron-down",
29590
+ className: cn("h-4 w-4 shrink-0 transition-transform", open && "rotate-180")
29591
+ }
29592
+ )
29593
+ ]
29594
+ }
29595
+ ),
29596
+ open && /* @__PURE__ */ jsxRuntime.jsx(
29597
+ VStack,
29598
+ {
29599
+ gap: "none",
29600
+ className: "mt-1 ml-4 pl-4 border-l border-border dark:border-border space-y-1",
29601
+ children: item.children.map((child) => {
29602
+ const childIsActive = child.href === activeHref;
29603
+ return /* @__PURE__ */ jsxRuntime.jsxs(
29604
+ reactRouterDom.Link,
29605
+ {
29606
+ to: child.href,
29607
+ className: cn(
29608
+ "flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm transition-colors",
29609
+ childIsActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29610
+ ),
29611
+ children: [
29612
+ child.icon && (typeof child.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: child.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(child.icon, { className: "h-4 w-4" })),
29613
+ /* @__PURE__ */ jsxRuntime.jsx(
29614
+ Typography,
29615
+ {
29616
+ variant: "small",
29617
+ color: childIsActive ? "inherit" : "primary",
29618
+ className: "flex-1",
29619
+ as: "span",
29620
+ children: child.label
29621
+ }
29622
+ ),
29623
+ child.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
29624
+ ]
29625
+ },
29626
+ child.href
29627
+ );
29628
+ })
29629
+ }
29630
+ )
29631
+ ] });
29632
+ }
29492
29633
  return /* @__PURE__ */ jsxRuntime.jsxs(
29493
29634
  reactRouterDom.Link,
29494
29635
  {
@@ -29517,9 +29658,63 @@ var init_DashboardLayout = __esm({
29517
29658
  NavLink.displayName = "NavLink";
29518
29659
  NavLinkTopnav = ({
29519
29660
  item,
29520
- currentPath
29661
+ activeHref
29521
29662
  }) => {
29522
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
29663
+ const hasChildren = !!item.children?.length;
29664
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
29665
+ const isActive = item.href === activeHref || childActive;
29666
+ const [open, setOpen] = React96.useState(false);
29667
+ if (hasChildren) {
29668
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
29669
+ /* @__PURE__ */ jsxRuntime.jsxs(
29670
+ Button,
29671
+ {
29672
+ variant: "ghost",
29673
+ "aria-expanded": open,
29674
+ className: cn(
29675
+ "flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors whitespace-nowrap",
29676
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29677
+ ),
29678
+ onClick: () => setOpen(!open),
29679
+ children: [
29680
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: "h-4 w-4" })),
29681
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "inherit", className: "flex-1", as: "span", children: item.label }),
29682
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
29683
+ /* @__PURE__ */ jsxRuntime.jsx(
29684
+ Icon,
29685
+ {
29686
+ name: "chevron-down",
29687
+ className: cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180")
29688
+ }
29689
+ )
29690
+ ]
29691
+ }
29692
+ ),
29693
+ open && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29694
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
29695
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "absolute left-0 top-full mt-1 w-48 bg-card dark:bg-card rounded-lg shadow-lg border border-border dark:border-border py-1 z-30", children: item.children.map((child) => {
29696
+ const childIsActive = child.href === activeHref;
29697
+ return /* @__PURE__ */ jsxRuntime.jsxs(
29698
+ reactRouterDom.Link,
29699
+ {
29700
+ to: child.href,
29701
+ onClick: () => setOpen(false),
29702
+ className: cn(
29703
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
29704
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29705
+ ),
29706
+ children: [
29707
+ child.icon && (typeof child.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: child.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(child.icon, { className: "h-4 w-4" })),
29708
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
29709
+ child.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
29710
+ ]
29711
+ },
29712
+ child.href
29713
+ );
29714
+ }) })
29715
+ ] })
29716
+ ] });
29717
+ }
29523
29718
  return /* @__PURE__ */ jsxRuntime.jsxs(
29524
29719
  reactRouterDom.Link,
29525
29720
  {
@@ -29539,9 +29734,9 @@ var init_DashboardLayout = __esm({
29539
29734
  NavLinkTopnav.displayName = "NavLinkTopnav";
29540
29735
  NavLinkBottom = ({
29541
29736
  item,
29542
- currentPath
29737
+ activeHref
29543
29738
  }) => {
29544
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
29739
+ const isActive = item.href === activeHref;
29545
29740
  const iconClassName = cn(
29546
29741
  "h-5 w-5",
29547
29742
  isActive ? "text-primary" : "text-muted-foreground"
package/dist/avl/index.js CHANGED
@@ -28959,6 +28959,18 @@ var init_useAuthContext = __esm({
28959
28959
  "hooks/useAuthContext.ts"() {
28960
28960
  }
28961
28961
  });
28962
+ function resolveActiveNavHref(items, currentPath) {
28963
+ let best;
28964
+ for (const item of items) {
28965
+ for (const href of item.children?.length ? [item.href, ...item.children.map((c) => c.href)] : [item.href]) {
28966
+ if (currentPath === href) return href;
28967
+ if (currentPath.startsWith(href + "/") && (!best || href.length > best.length)) {
28968
+ best = href;
28969
+ }
28970
+ }
28971
+ }
28972
+ return best;
28973
+ }
28962
28974
  var DashboardLayout, NavLink, NavLinkTopnav, NavLinkBottom;
28963
28975
  var init_DashboardLayout = __esm({
28964
28976
  "components/core/templates/DashboardLayout.tsx"() {
@@ -29030,6 +29042,7 @@ var init_DashboardLayout = __esm({
29030
29042
  const location = useLocation();
29031
29043
  const ctxPagePath = useCurrentPagePath();
29032
29044
  const activePath = (currentPath || void 0) ?? ctxPagePath ?? location.pathname;
29045
+ const activeHref = useMemo(() => resolveActiveNavHref(navItems, activePath), [navItems, activePath]);
29033
29046
  const { signOut: authSignOut } = useAuthContext();
29034
29047
  const user = userProp || (null);
29035
29048
  const { t } = useTranslate();
@@ -29122,7 +29135,7 @@ var init_DashboardLayout = __esm({
29122
29135
  NavLink,
29123
29136
  {
29124
29137
  item,
29125
- currentPath: activePath,
29138
+ activeHref,
29126
29139
  compact: isRail
29127
29140
  },
29128
29141
  item.href
@@ -29189,7 +29202,7 @@ var init_DashboardLayout = __esm({
29189
29202
  NavLinkTopnav,
29190
29203
  {
29191
29204
  item,
29192
- currentPath: activePath
29205
+ activeHref
29193
29206
  },
29194
29207
  item.href
29195
29208
  ))
@@ -29365,7 +29378,7 @@ var init_DashboardLayout = __esm({
29365
29378
  NavLinkBottom,
29366
29379
  {
29367
29380
  item,
29368
- currentPath: activePath
29381
+ activeHref
29369
29382
  },
29370
29383
  item.href
29371
29384
  )) })
@@ -29379,15 +29392,71 @@ var init_DashboardLayout = __esm({
29379
29392
  DashboardLayout.displayName = "DashboardLayout";
29380
29393
  NavLink = ({
29381
29394
  item,
29382
- currentPath,
29395
+ activeHref,
29383
29396
  compact = false
29384
29397
  }) => {
29385
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
29398
+ const hasChildren = !!item.children?.length;
29399
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
29400
+ const isActive = item.href === activeHref || childActive;
29401
+ const [open, setOpen] = useState(childActive);
29386
29402
  const iconClassName = cn(
29387
29403
  "h-5 w-5",
29388
29404
  isActive ? "text-primary-foreground" : "text-muted-foreground"
29389
29405
  );
29390
29406
  if (compact) {
29407
+ if (hasChildren) {
29408
+ return /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
29409
+ /* @__PURE__ */ jsx(
29410
+ Button,
29411
+ {
29412
+ variant: "ghost",
29413
+ title: item.label,
29414
+ "aria-label": item.label,
29415
+ "aria-expanded": open,
29416
+ className: cn(
29417
+ "flex items-center justify-center w-full px-2 py-2 rounded-lg transition-colors",
29418
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29419
+ ),
29420
+ onClick: () => setOpen(!open),
29421
+ children: /* @__PURE__ */ jsxs(Box, { as: "span", className: "relative inline-flex", children: [
29422
+ item.icon ? typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsx(item.icon, { className: iconClassName }) : /* @__PURE__ */ jsx(Typography, { variant: "small", className: "font-semibold", as: "span", children: item.label.charAt(0).toUpperCase() }),
29423
+ item.badge && /* @__PURE__ */ jsx(
29424
+ Badge,
29425
+ {
29426
+ variant: isActive ? "primary" : "default",
29427
+ size: "sm",
29428
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
29429
+ children: item.badge
29430
+ }
29431
+ )
29432
+ ] })
29433
+ }
29434
+ ),
29435
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
29436
+ /* @__PURE__ */ jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
29437
+ /* @__PURE__ */ jsx(Box, { className: "absolute left-full top-0 ml-2 w-48 bg-card dark:bg-card rounded-lg shadow-lg border border-border dark:border-border py-1 z-30", children: item.children.map((child) => {
29438
+ const childIsActive = child.href === activeHref;
29439
+ return /* @__PURE__ */ jsxs(
29440
+ Link,
29441
+ {
29442
+ to: child.href,
29443
+ onClick: () => setOpen(false),
29444
+ className: cn(
29445
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
29446
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29447
+ ),
29448
+ children: [
29449
+ child.icon && (typeof child.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: child.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsx(child.icon, { className: "h-4 w-4" })),
29450
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
29451
+ child.badge && /* @__PURE__ */ jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
29452
+ ]
29453
+ },
29454
+ child.href
29455
+ );
29456
+ }) })
29457
+ ] })
29458
+ ] });
29459
+ }
29391
29460
  return /* @__PURE__ */ jsx(
29392
29461
  Link,
29393
29462
  {
@@ -29413,6 +29482,78 @@ var init_DashboardLayout = __esm({
29413
29482
  }
29414
29483
  );
29415
29484
  }
29485
+ if (hasChildren) {
29486
+ return /* @__PURE__ */ jsxs(Box, { children: [
29487
+ /* @__PURE__ */ jsxs(
29488
+ Button,
29489
+ {
29490
+ variant: "ghost",
29491
+ "aria-expanded": open,
29492
+ className: cn(
29493
+ "flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium transition-colors",
29494
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29495
+ ),
29496
+ onClick: () => setOpen(!open),
29497
+ children: [
29498
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsx(item.icon, { className: iconClassName })),
29499
+ /* @__PURE__ */ jsx(
29500
+ Typography,
29501
+ {
29502
+ variant: "small",
29503
+ color: isActive ? "inherit" : "primary",
29504
+ className: "flex-1 text-left",
29505
+ as: "span",
29506
+ children: item.label
29507
+ }
29508
+ ),
29509
+ item.badge && /* @__PURE__ */ jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
29510
+ /* @__PURE__ */ jsx(
29511
+ Icon,
29512
+ {
29513
+ name: "chevron-down",
29514
+ className: cn("h-4 w-4 shrink-0 transition-transform", open && "rotate-180")
29515
+ }
29516
+ )
29517
+ ]
29518
+ }
29519
+ ),
29520
+ open && /* @__PURE__ */ jsx(
29521
+ VStack,
29522
+ {
29523
+ gap: "none",
29524
+ className: "mt-1 ml-4 pl-4 border-l border-border dark:border-border space-y-1",
29525
+ children: item.children.map((child) => {
29526
+ const childIsActive = child.href === activeHref;
29527
+ return /* @__PURE__ */ jsxs(
29528
+ Link,
29529
+ {
29530
+ to: child.href,
29531
+ className: cn(
29532
+ "flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm transition-colors",
29533
+ childIsActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29534
+ ),
29535
+ children: [
29536
+ child.icon && (typeof child.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: child.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsx(child.icon, { className: "h-4 w-4" })),
29537
+ /* @__PURE__ */ jsx(
29538
+ Typography,
29539
+ {
29540
+ variant: "small",
29541
+ color: childIsActive ? "inherit" : "primary",
29542
+ className: "flex-1",
29543
+ as: "span",
29544
+ children: child.label
29545
+ }
29546
+ ),
29547
+ child.badge && /* @__PURE__ */ jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
29548
+ ]
29549
+ },
29550
+ child.href
29551
+ );
29552
+ })
29553
+ }
29554
+ )
29555
+ ] });
29556
+ }
29416
29557
  return /* @__PURE__ */ jsxs(
29417
29558
  Link,
29418
29559
  {
@@ -29441,9 +29582,63 @@ var init_DashboardLayout = __esm({
29441
29582
  NavLink.displayName = "NavLink";
29442
29583
  NavLinkTopnav = ({
29443
29584
  item,
29444
- currentPath
29585
+ activeHref
29445
29586
  }) => {
29446
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
29587
+ const hasChildren = !!item.children?.length;
29588
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
29589
+ const isActive = item.href === activeHref || childActive;
29590
+ const [open, setOpen] = useState(false);
29591
+ if (hasChildren) {
29592
+ return /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
29593
+ /* @__PURE__ */ jsxs(
29594
+ Button,
29595
+ {
29596
+ variant: "ghost",
29597
+ "aria-expanded": open,
29598
+ className: cn(
29599
+ "flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors whitespace-nowrap",
29600
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29601
+ ),
29602
+ onClick: () => setOpen(!open),
29603
+ children: [
29604
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsx(item.icon, { className: "h-4 w-4" })),
29605
+ /* @__PURE__ */ jsx(Typography, { variant: "small", color: "inherit", className: "flex-1", as: "span", children: item.label }),
29606
+ item.badge && /* @__PURE__ */ jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
29607
+ /* @__PURE__ */ jsx(
29608
+ Icon,
29609
+ {
29610
+ name: "chevron-down",
29611
+ className: cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180")
29612
+ }
29613
+ )
29614
+ ]
29615
+ }
29616
+ ),
29617
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
29618
+ /* @__PURE__ */ jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
29619
+ /* @__PURE__ */ jsx(Box, { className: "absolute left-0 top-full mt-1 w-48 bg-card dark:bg-card rounded-lg shadow-lg border border-border dark:border-border py-1 z-30", children: item.children.map((child) => {
29620
+ const childIsActive = child.href === activeHref;
29621
+ return /* @__PURE__ */ jsxs(
29622
+ Link,
29623
+ {
29624
+ to: child.href,
29625
+ onClick: () => setOpen(false),
29626
+ className: cn(
29627
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
29628
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
29629
+ ),
29630
+ children: [
29631
+ child.icon && (typeof child.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: child.icon, className: "h-4 w-4" }) : /* @__PURE__ */ jsx(child.icon, { className: "h-4 w-4" })),
29632
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
29633
+ child.badge && /* @__PURE__ */ jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
29634
+ ]
29635
+ },
29636
+ child.href
29637
+ );
29638
+ }) })
29639
+ ] })
29640
+ ] });
29641
+ }
29447
29642
  return /* @__PURE__ */ jsxs(
29448
29643
  Link,
29449
29644
  {
@@ -29463,9 +29658,9 @@ var init_DashboardLayout = __esm({
29463
29658
  NavLinkTopnav.displayName = "NavLinkTopnav";
29464
29659
  NavLinkBottom = ({
29465
29660
  item,
29466
- currentPath
29661
+ activeHref
29467
29662
  }) => {
29468
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
29663
+ const isActive = item.href === activeHref;
29469
29664
  const iconClassName = cn(
29470
29665
  "h-5 w-5",
29471
29666
  isActive ? "text-primary" : "text-muted-foreground"