@almadar/ui 6.11.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.
@@ -26432,6 +26432,18 @@ var init_DashboardGrid = __esm({
26432
26432
  DashboardGrid.displayName = "DashboardGrid";
26433
26433
  }
26434
26434
  });
26435
+ function resolveActiveNavHref(items, currentPath) {
26436
+ let best;
26437
+ for (const item of items) {
26438
+ for (const href of item.children?.length ? [item.href, ...item.children.map((c) => c.href)] : [item.href]) {
26439
+ if (currentPath === href) return href;
26440
+ if (currentPath.startsWith(href + "/") && (!best || href.length > best.length)) {
26441
+ best = href;
26442
+ }
26443
+ }
26444
+ }
26445
+ return best;
26446
+ }
26435
26447
  var DashboardLayout, NavLink, NavLinkTopnav, NavLinkBottom;
26436
26448
  var init_DashboardLayout = __esm({
26437
26449
  "components/core/templates/DashboardLayout.tsx"() {
@@ -26503,6 +26515,7 @@ var init_DashboardLayout = __esm({
26503
26515
  const location = reactRouterDom.useLocation();
26504
26516
  const ctxPagePath = providers.useCurrentPagePath();
26505
26517
  const activePath = (currentPath || void 0) ?? ctxPagePath ?? location.pathname;
26518
+ const activeHref = React87.useMemo(() => resolveActiveNavHref(navItems, activePath), [navItems, activePath]);
26506
26519
  const { signOut: authSignOut } = useAuthContext();
26507
26520
  const user = userProp || (null);
26508
26521
  const { t } = hooks.useTranslate();
@@ -26595,7 +26608,7 @@ var init_DashboardLayout = __esm({
26595
26608
  NavLink,
26596
26609
  {
26597
26610
  item,
26598
- currentPath: activePath,
26611
+ activeHref,
26599
26612
  compact: isRail
26600
26613
  },
26601
26614
  item.href
@@ -26662,7 +26675,7 @@ var init_DashboardLayout = __esm({
26662
26675
  NavLinkTopnav,
26663
26676
  {
26664
26677
  item,
26665
- currentPath: activePath
26678
+ activeHref
26666
26679
  },
26667
26680
  item.href
26668
26681
  ))
@@ -26838,7 +26851,7 @@ var init_DashboardLayout = __esm({
26838
26851
  NavLinkBottom,
26839
26852
  {
26840
26853
  item,
26841
- currentPath: activePath
26854
+ activeHref
26842
26855
  },
26843
26856
  item.href
26844
26857
  )) })
@@ -26852,15 +26865,71 @@ var init_DashboardLayout = __esm({
26852
26865
  DashboardLayout.displayName = "DashboardLayout";
26853
26866
  NavLink = ({
26854
26867
  item,
26855
- currentPath,
26868
+ activeHref,
26856
26869
  compact = false
26857
26870
  }) => {
26858
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
26871
+ const hasChildren = !!item.children?.length;
26872
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
26873
+ const isActive = item.href === activeHref || childActive;
26874
+ const [open, setOpen] = React87.useState(childActive);
26859
26875
  const iconClassName = cn(
26860
26876
  "h-5 w-5",
26861
26877
  isActive ? "text-primary-foreground" : "text-muted-foreground"
26862
26878
  );
26863
26879
  if (compact) {
26880
+ if (hasChildren) {
26881
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
26882
+ /* @__PURE__ */ jsxRuntime.jsx(
26883
+ Button,
26884
+ {
26885
+ variant: "ghost",
26886
+ title: item.label,
26887
+ "aria-label": item.label,
26888
+ "aria-expanded": open,
26889
+ className: cn(
26890
+ "flex items-center justify-center w-full px-2 py-2 rounded-lg transition-colors",
26891
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26892
+ ),
26893
+ onClick: () => setOpen(!open),
26894
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { as: "span", className: "relative inline-flex", children: [
26895
+ 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() }),
26896
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(
26897
+ Badge,
26898
+ {
26899
+ variant: isActive ? "primary" : "default",
26900
+ size: "sm",
26901
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
26902
+ children: item.badge
26903
+ }
26904
+ )
26905
+ ] })
26906
+ }
26907
+ ),
26908
+ open && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
26909
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
26910
+ /* @__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) => {
26911
+ const childIsActive = child.href === activeHref;
26912
+ return /* @__PURE__ */ jsxRuntime.jsxs(
26913
+ reactRouterDom.Link,
26914
+ {
26915
+ to: child.href,
26916
+ onClick: () => setOpen(false),
26917
+ className: cn(
26918
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
26919
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26920
+ ),
26921
+ children: [
26922
+ 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" })),
26923
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
26924
+ child.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
26925
+ ]
26926
+ },
26927
+ child.href
26928
+ );
26929
+ }) })
26930
+ ] })
26931
+ ] });
26932
+ }
26864
26933
  return /* @__PURE__ */ jsxRuntime.jsx(
26865
26934
  reactRouterDom.Link,
26866
26935
  {
@@ -26886,6 +26955,78 @@ var init_DashboardLayout = __esm({
26886
26955
  }
26887
26956
  );
26888
26957
  }
26958
+ if (hasChildren) {
26959
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { children: [
26960
+ /* @__PURE__ */ jsxRuntime.jsxs(
26961
+ Button,
26962
+ {
26963
+ variant: "ghost",
26964
+ "aria-expanded": open,
26965
+ className: cn(
26966
+ "flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium transition-colors",
26967
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26968
+ ),
26969
+ onClick: () => setOpen(!open),
26970
+ children: [
26971
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsxRuntime.jsx(item.icon, { className: iconClassName })),
26972
+ /* @__PURE__ */ jsxRuntime.jsx(
26973
+ Typography,
26974
+ {
26975
+ variant: "small",
26976
+ color: isActive ? "inherit" : "primary",
26977
+ className: "flex-1 text-left",
26978
+ as: "span",
26979
+ children: item.label
26980
+ }
26981
+ ),
26982
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
26983
+ /* @__PURE__ */ jsxRuntime.jsx(
26984
+ Icon,
26985
+ {
26986
+ name: "chevron-down",
26987
+ className: cn("h-4 w-4 shrink-0 transition-transform", open && "rotate-180")
26988
+ }
26989
+ )
26990
+ ]
26991
+ }
26992
+ ),
26993
+ open && /* @__PURE__ */ jsxRuntime.jsx(
26994
+ VStack,
26995
+ {
26996
+ gap: "none",
26997
+ className: "mt-1 ml-4 pl-4 border-l border-border dark:border-border space-y-1",
26998
+ children: item.children.map((child) => {
26999
+ const childIsActive = child.href === activeHref;
27000
+ return /* @__PURE__ */ jsxRuntime.jsxs(
27001
+ reactRouterDom.Link,
27002
+ {
27003
+ to: child.href,
27004
+ className: cn(
27005
+ "flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm transition-colors",
27006
+ childIsActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
27007
+ ),
27008
+ children: [
27009
+ 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" })),
27010
+ /* @__PURE__ */ jsxRuntime.jsx(
27011
+ Typography,
27012
+ {
27013
+ variant: "small",
27014
+ color: childIsActive ? "inherit" : "primary",
27015
+ className: "flex-1",
27016
+ as: "span",
27017
+ children: child.label
27018
+ }
27019
+ ),
27020
+ child.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
27021
+ ]
27022
+ },
27023
+ child.href
27024
+ );
27025
+ })
27026
+ }
27027
+ )
27028
+ ] });
27029
+ }
26889
27030
  return /* @__PURE__ */ jsxRuntime.jsxs(
26890
27031
  reactRouterDom.Link,
26891
27032
  {
@@ -26914,9 +27055,63 @@ var init_DashboardLayout = __esm({
26914
27055
  NavLink.displayName = "NavLink";
26915
27056
  NavLinkTopnav = ({
26916
27057
  item,
26917
- currentPath
27058
+ activeHref
26918
27059
  }) => {
26919
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
27060
+ const hasChildren = !!item.children?.length;
27061
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
27062
+ const isActive = item.href === activeHref || childActive;
27063
+ const [open, setOpen] = React87.useState(false);
27064
+ if (hasChildren) {
27065
+ return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", children: [
27066
+ /* @__PURE__ */ jsxRuntime.jsxs(
27067
+ Button,
27068
+ {
27069
+ variant: "ghost",
27070
+ "aria-expanded": open,
27071
+ className: cn(
27072
+ "flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors whitespace-nowrap",
27073
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
27074
+ ),
27075
+ onClick: () => setOpen(!open),
27076
+ children: [
27077
+ 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" })),
27078
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", color: "inherit", className: "flex-1", as: "span", children: item.label }),
27079
+ item.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
27080
+ /* @__PURE__ */ jsxRuntime.jsx(
27081
+ Icon,
27082
+ {
27083
+ name: "chevron-down",
27084
+ className: cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180")
27085
+ }
27086
+ )
27087
+ ]
27088
+ }
27089
+ ),
27090
+ open && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
27091
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
27092
+ /* @__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) => {
27093
+ const childIsActive = child.href === activeHref;
27094
+ return /* @__PURE__ */ jsxRuntime.jsxs(
27095
+ reactRouterDom.Link,
27096
+ {
27097
+ to: child.href,
27098
+ onClick: () => setOpen(false),
27099
+ className: cn(
27100
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
27101
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
27102
+ ),
27103
+ children: [
27104
+ 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" })),
27105
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
27106
+ child.badge && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
27107
+ ]
27108
+ },
27109
+ child.href
27110
+ );
27111
+ }) })
27112
+ ] })
27113
+ ] });
27114
+ }
26920
27115
  return /* @__PURE__ */ jsxRuntime.jsxs(
26921
27116
  reactRouterDom.Link,
26922
27117
  {
@@ -26936,9 +27131,9 @@ var init_DashboardLayout = __esm({
26936
27131
  NavLinkTopnav.displayName = "NavLinkTopnav";
26937
27132
  NavLinkBottom = ({
26938
27133
  item,
26939
- currentPath
27134
+ activeHref
26940
27135
  }) => {
26941
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
27136
+ const isActive = item.href === activeHref;
26942
27137
  const iconClassName = cn(
26943
27138
  "h-5 w-5",
26944
27139
  isActive ? "text-primary" : "text-muted-foreground"
@@ -26358,6 +26358,18 @@ var init_DashboardGrid = __esm({
26358
26358
  DashboardGrid.displayName = "DashboardGrid";
26359
26359
  }
26360
26360
  });
26361
+ function resolveActiveNavHref(items, currentPath) {
26362
+ let best;
26363
+ for (const item of items) {
26364
+ for (const href of item.children?.length ? [item.href, ...item.children.map((c) => c.href)] : [item.href]) {
26365
+ if (currentPath === href) return href;
26366
+ if (currentPath.startsWith(href + "/") && (!best || href.length > best.length)) {
26367
+ best = href;
26368
+ }
26369
+ }
26370
+ }
26371
+ return best;
26372
+ }
26361
26373
  var DashboardLayout, NavLink, NavLinkTopnav, NavLinkBottom;
26362
26374
  var init_DashboardLayout = __esm({
26363
26375
  "components/core/templates/DashboardLayout.tsx"() {
@@ -26429,6 +26441,7 @@ var init_DashboardLayout = __esm({
26429
26441
  const location = useLocation();
26430
26442
  const ctxPagePath = useCurrentPagePath();
26431
26443
  const activePath = (currentPath || void 0) ?? ctxPagePath ?? location.pathname;
26444
+ const activeHref = useMemo(() => resolveActiveNavHref(navItems, activePath), [navItems, activePath]);
26432
26445
  const { signOut: authSignOut } = useAuthContext();
26433
26446
  const user = userProp || (null);
26434
26447
  const { t } = useTranslate();
@@ -26521,7 +26534,7 @@ var init_DashboardLayout = __esm({
26521
26534
  NavLink,
26522
26535
  {
26523
26536
  item,
26524
- currentPath: activePath,
26537
+ activeHref,
26525
26538
  compact: isRail
26526
26539
  },
26527
26540
  item.href
@@ -26588,7 +26601,7 @@ var init_DashboardLayout = __esm({
26588
26601
  NavLinkTopnav,
26589
26602
  {
26590
26603
  item,
26591
- currentPath: activePath
26604
+ activeHref
26592
26605
  },
26593
26606
  item.href
26594
26607
  ))
@@ -26764,7 +26777,7 @@ var init_DashboardLayout = __esm({
26764
26777
  NavLinkBottom,
26765
26778
  {
26766
26779
  item,
26767
- currentPath: activePath
26780
+ activeHref
26768
26781
  },
26769
26782
  item.href
26770
26783
  )) })
@@ -26778,15 +26791,71 @@ var init_DashboardLayout = __esm({
26778
26791
  DashboardLayout.displayName = "DashboardLayout";
26779
26792
  NavLink = ({
26780
26793
  item,
26781
- currentPath,
26794
+ activeHref,
26782
26795
  compact = false
26783
26796
  }) => {
26784
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
26797
+ const hasChildren = !!item.children?.length;
26798
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
26799
+ const isActive = item.href === activeHref || childActive;
26800
+ const [open, setOpen] = useState(childActive);
26785
26801
  const iconClassName = cn(
26786
26802
  "h-5 w-5",
26787
26803
  isActive ? "text-primary-foreground" : "text-muted-foreground"
26788
26804
  );
26789
26805
  if (compact) {
26806
+ if (hasChildren) {
26807
+ return /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
26808
+ /* @__PURE__ */ jsx(
26809
+ Button,
26810
+ {
26811
+ variant: "ghost",
26812
+ title: item.label,
26813
+ "aria-label": item.label,
26814
+ "aria-expanded": open,
26815
+ className: cn(
26816
+ "flex items-center justify-center w-full px-2 py-2 rounded-lg transition-colors",
26817
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26818
+ ),
26819
+ onClick: () => setOpen(!open),
26820
+ children: /* @__PURE__ */ jsxs(Box, { as: "span", className: "relative inline-flex", children: [
26821
+ 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() }),
26822
+ item.badge && /* @__PURE__ */ jsx(
26823
+ Badge,
26824
+ {
26825
+ variant: isActive ? "primary" : "default",
26826
+ size: "sm",
26827
+ className: "absolute -top-2 -right-2 px-1 py-0 text-[10px] leading-4",
26828
+ children: item.badge
26829
+ }
26830
+ )
26831
+ ] })
26832
+ }
26833
+ ),
26834
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
26835
+ /* @__PURE__ */ jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
26836
+ /* @__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) => {
26837
+ const childIsActive = child.href === activeHref;
26838
+ return /* @__PURE__ */ jsxs(
26839
+ Link,
26840
+ {
26841
+ to: child.href,
26842
+ onClick: () => setOpen(false),
26843
+ className: cn(
26844
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
26845
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26846
+ ),
26847
+ children: [
26848
+ 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" })),
26849
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
26850
+ child.badge && /* @__PURE__ */ jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
26851
+ ]
26852
+ },
26853
+ child.href
26854
+ );
26855
+ }) })
26856
+ ] })
26857
+ ] });
26858
+ }
26790
26859
  return /* @__PURE__ */ jsx(
26791
26860
  Link,
26792
26861
  {
@@ -26812,6 +26881,78 @@ var init_DashboardLayout = __esm({
26812
26881
  }
26813
26882
  );
26814
26883
  }
26884
+ if (hasChildren) {
26885
+ return /* @__PURE__ */ jsxs(Box, { children: [
26886
+ /* @__PURE__ */ jsxs(
26887
+ Button,
26888
+ {
26889
+ variant: "ghost",
26890
+ "aria-expanded": open,
26891
+ className: cn(
26892
+ "flex items-center gap-3 w-full px-3 py-2 rounded-lg text-sm font-medium transition-colors",
26893
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26894
+ ),
26895
+ onClick: () => setOpen(!open),
26896
+ children: [
26897
+ item.icon && (typeof item.icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: item.icon, className: iconClassName }) : /* @__PURE__ */ jsx(item.icon, { className: iconClassName })),
26898
+ /* @__PURE__ */ jsx(
26899
+ Typography,
26900
+ {
26901
+ variant: "small",
26902
+ color: isActive ? "inherit" : "primary",
26903
+ className: "flex-1 text-left",
26904
+ as: "span",
26905
+ children: item.label
26906
+ }
26907
+ ),
26908
+ item.badge && /* @__PURE__ */ jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
26909
+ /* @__PURE__ */ jsx(
26910
+ Icon,
26911
+ {
26912
+ name: "chevron-down",
26913
+ className: cn("h-4 w-4 shrink-0 transition-transform", open && "rotate-180")
26914
+ }
26915
+ )
26916
+ ]
26917
+ }
26918
+ ),
26919
+ open && /* @__PURE__ */ jsx(
26920
+ VStack,
26921
+ {
26922
+ gap: "none",
26923
+ className: "mt-1 ml-4 pl-4 border-l border-border dark:border-border space-y-1",
26924
+ children: item.children.map((child) => {
26925
+ const childIsActive = child.href === activeHref;
26926
+ return /* @__PURE__ */ jsxs(
26927
+ Link,
26928
+ {
26929
+ to: child.href,
26930
+ className: cn(
26931
+ "flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm transition-colors",
26932
+ childIsActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
26933
+ ),
26934
+ children: [
26935
+ 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" })),
26936
+ /* @__PURE__ */ jsx(
26937
+ Typography,
26938
+ {
26939
+ variant: "small",
26940
+ color: childIsActive ? "inherit" : "primary",
26941
+ className: "flex-1",
26942
+ as: "span",
26943
+ children: child.label
26944
+ }
26945
+ ),
26946
+ child.badge && /* @__PURE__ */ jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
26947
+ ]
26948
+ },
26949
+ child.href
26950
+ );
26951
+ })
26952
+ }
26953
+ )
26954
+ ] });
26955
+ }
26815
26956
  return /* @__PURE__ */ jsxs(
26816
26957
  Link,
26817
26958
  {
@@ -26840,9 +26981,63 @@ var init_DashboardLayout = __esm({
26840
26981
  NavLink.displayName = "NavLink";
26841
26982
  NavLinkTopnav = ({
26842
26983
  item,
26843
- currentPath
26984
+ activeHref
26844
26985
  }) => {
26845
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
26986
+ const hasChildren = !!item.children?.length;
26987
+ const childActive = hasChildren && item.children.some((child) => child.href === activeHref);
26988
+ const isActive = item.href === activeHref || childActive;
26989
+ const [open, setOpen] = useState(false);
26990
+ if (hasChildren) {
26991
+ return /* @__PURE__ */ jsxs(Box, { className: "relative", children: [
26992
+ /* @__PURE__ */ jsxs(
26993
+ Button,
26994
+ {
26995
+ variant: "ghost",
26996
+ "aria-expanded": open,
26997
+ className: cn(
26998
+ "flex items-center gap-1.5 px-3 py-1.5 rounded-md text-sm font-medium transition-colors whitespace-nowrap",
26999
+ isActive ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:bg-muted hover:text-foreground"
27000
+ ),
27001
+ onClick: () => setOpen(!open),
27002
+ children: [
27003
+ 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" })),
27004
+ /* @__PURE__ */ jsx(Typography, { variant: "small", color: "inherit", className: "flex-1", as: "span", children: item.label }),
27005
+ item.badge && /* @__PURE__ */ jsx(Badge, { variant: isActive ? "primary" : "default", size: "sm", children: item.badge }),
27006
+ /* @__PURE__ */ jsx(
27007
+ Icon,
27008
+ {
27009
+ name: "chevron-down",
27010
+ className: cn("h-3.5 w-3.5 shrink-0 transition-transform", open && "rotate-180")
27011
+ }
27012
+ )
27013
+ ]
27014
+ }
27015
+ ),
27016
+ open && /* @__PURE__ */ jsxs(Fragment, { children: [
27017
+ /* @__PURE__ */ jsx(Box, { className: "fixed inset-0 z-20", onClick: () => setOpen(false) }),
27018
+ /* @__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) => {
27019
+ const childIsActive = child.href === activeHref;
27020
+ return /* @__PURE__ */ jsxs(
27021
+ Link,
27022
+ {
27023
+ to: child.href,
27024
+ onClick: () => setOpen(false),
27025
+ className: cn(
27026
+ "flex items-center gap-2 px-3 py-2 text-sm transition-colors",
27027
+ childIsActive ? "bg-muted text-foreground font-medium" : "text-muted-foreground hover:bg-muted hover:text-foreground"
27028
+ ),
27029
+ children: [
27030
+ 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" })),
27031
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "flex-1", as: "span", children: child.label }),
27032
+ child.badge && /* @__PURE__ */ jsx(Badge, { variant: childIsActive ? "primary" : "default", size: "sm", children: child.badge })
27033
+ ]
27034
+ },
27035
+ child.href
27036
+ );
27037
+ }) })
27038
+ ] })
27039
+ ] });
27040
+ }
26846
27041
  return /* @__PURE__ */ jsxs(
26847
27042
  Link,
26848
27043
  {
@@ -26862,9 +27057,9 @@ var init_DashboardLayout = __esm({
26862
27057
  NavLinkTopnav.displayName = "NavLinkTopnav";
26863
27058
  NavLinkBottom = ({
26864
27059
  item,
26865
- currentPath
27060
+ activeHref
26866
27061
  }) => {
26867
- const isActive = currentPath === item.href || currentPath.startsWith(item.href + "/");
27062
+ const isActive = item.href === activeHref;
26868
27063
  const iconClassName = cn(
26869
27064
  "h-5 w-5",
26870
27065
  isActive ? "text-primary" : "text-muted-foreground"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "6.11.0",
3
+ "version": "6.13.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -118,11 +118,11 @@
118
118
  "access": "public"
119
119
  },
120
120
  "dependencies": {
121
- "@almadar/core": "^10.87.0",
121
+ "@almadar/core": "^10.89.0",
122
122
  "@almadar/evaluator": "^2.45.0",
123
123
  "@almadar/logger": "^1.12.0",
124
- "@almadar/runtime": "^6.72.0",
125
- "@almadar/std": "^16.208.0",
124
+ "@almadar/runtime": "^6.74.0",
125
+ "@almadar/std": "^16.210.0",
126
126
  "@almadar/syntax": "^1.17.0",
127
127
  "@dnd-kit/core": "^6.3.1",
128
128
  "@dnd-kit/sortable": "^10.0.0",