@inf-monkeys-tech/monkeys-design 2.0.5 → 2.0.7

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.
@@ -6,6 +6,8 @@ type NavigationSidebarSurface = "frosted" | "outlined" | "panel" | "plain";
6
6
  type NavigationSidebarActiveVariant = "muted" | "outline" | "soft" | "solid";
7
7
  type NavigationSidebarCollapsePlacement = "edge" | "footer" | "header" | "none";
8
8
  interface NavigationSidebarAppearance {
9
+ /** Shared panel and row presentation; omitted preserves legacy appearances. */
10
+ preset?: "unified";
9
11
  density?: NavigationSidebarDensity;
10
12
  surface?: NavigationSidebarSurface;
11
13
  activeVariant?: NavigationSidebarActiveVariant;
@@ -6,6 +6,8 @@ type NavigationSidebarSurface = "frosted" | "outlined" | "panel" | "plain";
6
6
  type NavigationSidebarActiveVariant = "muted" | "outline" | "soft" | "solid";
7
7
  type NavigationSidebarCollapsePlacement = "edge" | "footer" | "header" | "none";
8
8
  interface NavigationSidebarAppearance {
9
+ /** Shared panel and row presentation; omitted preserves legacy appearances. */
10
+ preset?: "unified";
9
11
  density?: NavigationSidebarDensity;
10
12
  surface?: NavigationSidebarSurface;
11
13
  activeVariant?: NavigationSidebarActiveVariant;
@@ -1319,6 +1319,7 @@ function DataExplorerViewTree({
1319
1319
  onSelectNode?.(node, context);
1320
1320
  },
1321
1321
  onKeyDown: (event) => {
1322
+ if (event.target !== event.currentTarget) return;
1322
1323
  if (!isSelectable) return;
1323
1324
  if (event.key !== "Enter" && event.key !== " ") return;
1324
1325
  event.preventDefault();
@@ -1445,7 +1446,7 @@ function DataExplorerViewTree({
1445
1446
  "div",
1446
1447
  {
1447
1448
  className: cn(theme.slots.treeRoot, classNames?.root, className),
1448
- role: hasAnyNodes ? "tree" : void 0,
1449
+ role: hasAnyNodes || resolvedGroups.some((group) => !group.hideHeader) ? "tree" : void 0,
1449
1450
  children: resolvedGroups.map((group) => {
1450
1451
  const groupExpanded = group.hideHeader || group.collapsible === false || resolvedExpandedGroupIds.has(group.id);
1451
1452
  const groupNodeCount = group.nodes?.length ?? 0;
@@ -1462,6 +1463,10 @@ function DataExplorerViewTree({
1462
1463
  !group.hideHeader ? /* @__PURE__ */ jsxRuntime.jsxs(
1463
1464
  "div",
1464
1465
  {
1466
+ role: "treeitem",
1467
+ "aria-label": typeof group.label === "string" ? group.label : void 0,
1468
+ "aria-selected": group.selectable ? groupSelected : void 0,
1469
+ "aria-expanded": groupCollapsible ? groupExpanded : void 0,
1465
1470
  className: cn(
1466
1471
  theme.slots.treeGroupHeader,
1467
1472
  theme.slots.treeGroupHeaderButton,
@@ -1546,6 +1551,7 @@ function DataExplorerViewTree({
1546
1551
  groupExpanded ? /* @__PURE__ */ jsxRuntime.jsx(
1547
1552
  "div",
1548
1553
  {
1554
+ role: "group",
1549
1555
  className: cn(
1550
1556
  theme.slots.treeGroupContent,
1551
1557
  classNames?.groupContent,
@@ -1574,6 +1580,72 @@ function DataExplorerViewTree({
1574
1580
  }
1575
1581
  );
1576
1582
  }
1583
+
1584
+ // src/components/navigation-sidebar/unified-appearance.ts
1585
+ var unifiedRow = "gap-2 rounded-[var(--radius)] border border-transparent text-sm font-medium motion-reduce:transition-none";
1586
+ var unifiedIcon = "size-[var(--monkeys-component-navigation-sidebar-icon-size,1.125rem)] shrink-0 text-inherit [&_svg]:size-full";
1587
+ var unifiedInactive = "text-foreground hover:border-transparent hover:bg-[var(--navigation-internal-hover-background)] hover:text-[var(--navigation-internal-hover-foreground)]";
1588
+ var unifiedSelected = "border-[var(--navigation-internal-selected-border)] bg-[var(--navigation-internal-selected-background)] text-[var(--navigation-internal-selected-foreground)] hover:border-[var(--navigation-internal-selected-border)] hover:bg-[var(--navigation-internal-selected-background)] hover:text-[var(--navigation-internal-selected-foreground)]";
1589
+ var unifiedThemeDefaults = "[--navigation-internal-theme-selected-background:color-mix(in_srgb,hsl(var(--monkeys-color-primary,var(--primary)))_10%,transparent)] [--navigation-internal-theme-selected-foreground:hsl(var(--monkeys-color-primary,var(--primary)))] dark:[--navigation-internal-theme-selected-background:hsl(var(--monkeys-color-accent,var(--accent)))] dark:[--navigation-internal-theme-selected-foreground:hsl(var(--monkeys-color-foreground,var(--foreground)))]";
1590
+ function unifiedStyle(activeVariant) {
1591
+ const background = {
1592
+ muted: "hsl(var(--monkeys-color-accent,var(--accent)))",
1593
+ soft: "color-mix(in srgb,hsl(var(--monkeys-color-primary,var(--primary))) 10%,transparent)",
1594
+ solid: "hsl(var(--monkeys-color-primary,var(--primary)))",
1595
+ outline: "hsl(var(--monkeys-color-background,var(--background)))"
1596
+ }[activeVariant ?? "muted"];
1597
+ const foreground = activeVariant === "solid" ? "hsl(var(--monkeys-color-primary-foreground,var(--primary-foreground)))" : "hsl(var(--monkeys-color-foreground,var(--foreground)))";
1598
+ const border = activeVariant === void 0 || activeVariant === "muted" ? "transparent" : activeVariant === "soft" ? "color-mix(in srgb,hsl(var(--monkeys-color-primary,var(--primary))) 25%,transparent)" : activeVariant === "outline" ? "color-mix(in srgb,hsl(var(--monkeys-color-primary,var(--primary))) 55%,transparent)" : "hsl(var(--monkeys-color-primary,var(--primary)))";
1599
+ return {
1600
+ "--navigation-internal-default-selected-background": activeVariant === void 0 ? "var(--navigation-internal-theme-selected-background)" : background,
1601
+ "--navigation-internal-default-selected-foreground": activeVariant === void 0 ? "var(--navigation-internal-theme-selected-foreground)" : foreground,
1602
+ "--navigation-internal-selected-background": "var(--monkeys-component-navigation-sidebar-row-selected-background,var(--navigation-internal-default-selected-background))",
1603
+ "--navigation-internal-selected-foreground": "var(--monkeys-component-navigation-sidebar-row-selected-foreground,var(--navigation-internal-default-selected-foreground))",
1604
+ "--navigation-internal-selected-border": `var(--monkeys-component-navigation-sidebar-row-selected-border,${border})`,
1605
+ "--navigation-internal-hover-background": "var(--monkeys-component-navigation-sidebar-row-hover-background,color-mix(in srgb,hsl(var(--monkeys-color-accent,var(--accent))) 65%,transparent))",
1606
+ "--navigation-internal-hover-foreground": "var(--monkeys-component-navigation-sidebar-row-hover-foreground,hsl(var(--monkeys-color-foreground,var(--foreground))))"
1607
+ };
1608
+ }
1609
+ var treeStateVariables = "[--navigation-internal-selected-background:var(--monkeys-component-navigation-sidebar-row-selected-background,var(--monkeys-component-navigation-sidebar-tree-row-selected-background,var(--navigation-internal-default-selected-background)))] [--navigation-internal-selected-foreground:var(--monkeys-component-navigation-sidebar-row-selected-foreground,var(--monkeys-component-navigation-sidebar-tree-row-selected-foreground,var(--navigation-internal-default-selected-foreground)))] [--navigation-internal-hover-background:var(--monkeys-component-navigation-sidebar-row-hover-background,var(--monkeys-component-navigation-sidebar-tree-row-hover-background,color-mix(in_srgb,hsl(var(--monkeys-color-accent,var(--accent)))_65%,transparent)))] [--navigation-internal-hover-foreground:var(--monkeys-component-navigation-sidebar-row-hover-foreground,var(--monkeys-component-navigation-sidebar-tree-row-hover-foreground,hsl(var(--monkeys-color-foreground,var(--foreground)))))]";
1610
+ var selectedTreeNode = "aria-selected:border-[var(--navigation-internal-selected-border)] aria-selected:bg-[var(--navigation-internal-selected-background)] aria-selected:text-[var(--navigation-internal-selected-foreground)] aria-selected:hover:border-[var(--navigation-internal-selected-border)] aria-selected:hover:bg-[var(--navigation-internal-selected-background)] aria-selected:hover:text-[var(--navigation-internal-selected-foreground)]";
1611
+ var nestedControl = "text-inherit hover:bg-foreground/10 hover:text-inherit focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none";
1612
+ function unifiedTreeClassNames(height, padding, overrides = {}) {
1613
+ const row = cn(unifiedRow, height, padding, unifiedInactive);
1614
+ return {
1615
+ ...overrides,
1616
+ root: cn(treeStateVariables, "space-y-0.5", overrides.root),
1617
+ group: cn(
1618
+ "space-y-0.5",
1619
+ // A visible group header adds a level; headerless groups contain root items.
1620
+ "[&>[role=treeitem]+[role=group]]:pl-[var(--monkeys-component-navigation-sidebar-tree-group-indent,1rem)]",
1621
+ overrides.group
1622
+ ),
1623
+ groupHeaderButton: cn("h-auto", row, overrides.groupHeaderButton),
1624
+ nodeButton: cn(row, selectedTreeNode, overrides.nodeButton),
1625
+ itemSelected: cn(unifiedSelected, overrides.itemSelected),
1626
+ nodeIcon: cn(
1627
+ unifiedIcon,
1628
+ "group-hover/tree-node:text-inherit",
1629
+ overrides.nodeIcon
1630
+ ),
1631
+ nodeLabel: cn("font-medium", overrides.nodeLabel),
1632
+ nodeDescription: cn("text-inherit", overrides.nodeDescription),
1633
+ nodeDisabled: cn("opacity-50", overrides.nodeDisabled),
1634
+ groupActions: cn(
1635
+ nestedControl,
1636
+ "order-2 size-5 p-0 group-focus-within/tree-group:opacity-100",
1637
+ overrides.groupActions
1638
+ ),
1639
+ nodeActions: cn(
1640
+ nestedControl,
1641
+ "order-2 size-5 p-0 group-focus-within/tree-node:opacity-100",
1642
+ overrides.nodeActions
1643
+ ),
1644
+ nodeToggle: cn(nestedControl, "order-1", overrides.nodeToggle),
1645
+ expander: cn(nestedControl, "order-1", overrides.expander),
1646
+ nodeDragHandle: cn(nestedControl, overrides.nodeDragHandle)
1647
+ };
1648
+ }
1577
1649
  function CollapseIcon({ collapsed }) {
1578
1650
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", viewBox: "0 0 20 20", className: "h-4 w-4", fill: "none", children: /* @__PURE__ */ jsxRuntime.jsx(
1579
1651
  "path",
@@ -1759,22 +1831,34 @@ function activeVariantClassName(activeVariant) {
1759
1831
  return "border-primary/25 bg-primary/10 text-foreground";
1760
1832
  }
1761
1833
  function resolveAppearance(appearance) {
1762
- const density = appearance?.density ?? "default";
1834
+ if (appearance?.preset !== void 0 && appearance.preset !== "unified") {
1835
+ throw new TypeError(
1836
+ `Unknown NavigationSidebar preset "${appearance.preset}". Supported preset: unified.`
1837
+ );
1838
+ }
1839
+ const unified = appearance?.preset === "unified";
1840
+ const density = appearance?.density ?? (unified ? "compact" : "default");
1763
1841
  const surface = appearance?.surface ?? "panel";
1764
- const activeVariant = appearance?.activeVariant ?? "soft";
1842
+ const activeVariant = appearance?.activeVariant ?? (unified ? "muted" : "soft");
1765
1843
  return {
1844
+ unified,
1766
1845
  density,
1767
1846
  surface,
1768
1847
  activeVariant,
1848
+ selected: unified ? unifiedSelected : activeVariantClassName(activeVariant),
1849
+ inactive: unified ? unifiedInactive : "text-muted-foreground hover:border-border/70 hover:bg-muted/60 hover:text-foreground",
1769
1850
  root: cn(
1770
1851
  surface === "plain" && "border-transparent bg-transparent shadow-none",
1771
1852
  surface === "panel" && "border-border/70 bg-card text-card-foreground shadow-sm",
1772
1853
  surface === "frosted" && "border-border/55 bg-card/80 text-card-foreground shadow-sm backdrop-blur-xl",
1773
- surface === "outlined" && "border-border bg-background text-foreground shadow-none"
1854
+ surface === "outlined" && "border-border bg-background text-foreground shadow-none",
1855
+ unified && "rounded-[var(--radius)] shadow-none",
1856
+ unified && unifiedThemeDefaults,
1857
+ unified && surface === "panel" && "border-[var(--monkeys-component-navigation-sidebar-border,hsl(var(--monkeys-color-border,var(--border))))] bg-[var(--monkeys-component-navigation-sidebar-background,hsl(var(--monkeys-color-card,var(--card))))] text-foreground"
1774
1858
  ),
1775
- itemHeight: density === "compact" ? "min-h-9" : density === "comfortable" ? "min-h-14" : "min-h-11",
1776
- itemPadding: density === "compact" ? "px-2 py-1.5" : density === "comfortable" ? "px-3 py-3" : "px-3 py-2",
1777
- searchHeight: density === "compact" ? "h-8" : density === "comfortable" ? "h-10" : "h-9"
1859
+ itemHeight: density === "compact" ? unified ? "min-h-[var(--monkeys-component-navigation-sidebar-row-height,2.5rem)]" : "min-h-9" : density === "comfortable" ? "min-h-14" : "min-h-11",
1860
+ itemPadding: density === "compact" ? unified ? "px-2 py-2" : "px-2 py-1.5" : density === "comfortable" ? "px-3 py-3" : "px-3 py-2",
1861
+ searchHeight: density === "compact" ? unified ? "h-[var(--monkeys-component-navigation-sidebar-row-height,2.5rem)]" : "h-8" : density === "comfortable" ? "h-10" : "h-9"
1778
1862
  };
1779
1863
  }
1780
1864
  var navigationTreeRowHoverClassName = "hover:bg-[var(--monkeys-component-navigation-sidebar-tree-row-hover-background,hsl(var(--muted)))] hover:text-[var(--monkeys-component-navigation-sidebar-tree-row-hover-foreground,hsl(var(--foreground)))]";
@@ -1829,7 +1913,8 @@ function entryClassName({
1829
1913
  "group/navigation-item relative flex w-full min-w-0 items-center gap-3 rounded-[var(--radius)] border border-transparent text-left text-sm outline-none transition-[background-color,border-color,color,box-shadow] focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none",
1830
1914
  appearance.itemHeight,
1831
1915
  appearance.itemPadding,
1832
- embedded ? "min-h-0 self-stretch border-0 bg-transparent text-inherit hover:bg-transparent hover:text-inherit" : active ? activeVariantClassName(appearance.activeVariant) : "text-muted-foreground hover:border-border/70 hover:bg-muted/60 hover:text-foreground",
1916
+ appearance.unified && unifiedRow,
1917
+ embedded ? "min-h-0 self-stretch border-0 bg-transparent text-inherit hover:bg-transparent hover:text-inherit" : active ? appearance.selected : appearance.inactive,
1833
1918
  collapsed && !mobile && "justify-center px-0",
1834
1919
  item.disabled && "pointer-events-none opacity-50",
1835
1920
  classNames?.item,
@@ -1844,7 +1929,8 @@ function EntryContent({
1844
1929
  collapsed,
1845
1930
  mobile,
1846
1931
  classNames,
1847
- endIndicator
1932
+ endIndicator,
1933
+ appearance
1848
1934
  }) {
1849
1935
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1850
1936
  hasRenderableNode(item.icon) ? /* @__PURE__ */ jsxRuntime.jsx(
@@ -1852,6 +1938,7 @@ function EntryContent({
1852
1938
  {
1853
1939
  className: cn(
1854
1940
  "flex size-5 shrink-0 items-center justify-center [&_svg]:size-full",
1941
+ appearance.unified && unifiedIcon,
1855
1942
  classNames?.itemIcon
1856
1943
  ),
1857
1944
  "aria-hidden": "true",
@@ -1871,6 +1958,7 @@ function EntryContent({
1871
1958
  {
1872
1959
  className: cn(
1873
1960
  "min-w-0 truncate font-semibold",
1961
+ appearance.unified && "font-medium",
1874
1962
  classNames?.itemLabel
1875
1963
  ),
1876
1964
  children: item.label
@@ -1881,6 +1969,7 @@ function EntryContent({
1881
1969
  {
1882
1970
  className: cn(
1883
1971
  "mt-0.5 truncate text-xs font-normal",
1972
+ appearance.unified && "text-inherit",
1884
1973
  classNames?.itemDescription
1885
1974
  ),
1886
1975
  children: item.description
@@ -1961,6 +2050,7 @@ function EntryButton({
1961
2050
  children: /* @__PURE__ */ jsxRuntime.jsx(
1962
2051
  EntryContent,
1963
2052
  {
2053
+ appearance,
1964
2054
  item,
1965
2055
  collapsed,
1966
2056
  mobile,
@@ -1997,6 +2087,7 @@ function EntryPresentation({
1997
2087
  children: /* @__PURE__ */ jsxRuntime.jsx(
1998
2088
  EntryContent,
1999
2089
  {
2090
+ appearance,
2000
2091
  item,
2001
2092
  collapsed: false,
2002
2093
  mobile: true,
@@ -2013,7 +2104,8 @@ function routeRowClassName({
2013
2104
  return cn(
2014
2105
  "flex w-full min-w-0 items-center gap-0.5 rounded-[var(--radius)] border border-transparent pr-1 text-sm transition-[background-color,border-color,color,box-shadow] motion-reduce:transition-none",
2015
2106
  appearance.itemHeight,
2016
- active ? activeVariantClassName(appearance.activeVariant) : "text-muted-foreground hover:border-border/70 hover:bg-muted/60 hover:text-foreground"
2107
+ appearance.unified && unifiedRow,
2108
+ active ? appearance.selected : appearance.inactive
2017
2109
  );
2018
2110
  }
2019
2111
  function filterCatalogItems(items, activeFilterId) {
@@ -2167,7 +2259,8 @@ function ChildEntry({
2167
2259
  "flex w-full min-w-0 flex-1 items-center gap-3 rounded-[var(--radius)] border border-transparent text-left text-sm font-semibold outline-none transition-[background-color,border-color,color,box-shadow] focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none",
2168
2260
  appearance.itemHeight,
2169
2261
  appearance.itemPadding,
2170
- embedded ? "min-h-0 self-stretch border-0 bg-transparent text-inherit hover:bg-transparent hover:text-inherit" : active ? activeVariantClassName(appearance.activeVariant) : "text-muted-foreground hover:border-border/70 hover:bg-muted/60 hover:text-foreground",
2262
+ appearance.unified && unifiedRow,
2263
+ embedded ? "min-h-0 self-stretch border-0 bg-transparent text-inherit hover:bg-transparent hover:text-inherit" : active ? appearance.selected : appearance.inactive,
2171
2264
  child.disabled && "pointer-events-none opacity-50",
2172
2265
  classNames?.childItem,
2173
2266
  active && classNames?.childItemActive,
@@ -2179,7 +2272,10 @@ function ChildEntry({
2179
2272
  hasRenderableNode(child.icon) ? /* @__PURE__ */ jsxRuntime.jsx(
2180
2273
  "span",
2181
2274
  {
2182
- className: "flex size-5 shrink-0 items-center justify-center [&_svg]:size-full",
2275
+ className: cn(
2276
+ "flex size-5 shrink-0 items-center justify-center [&_svg]:size-full",
2277
+ appearance.unified && unifiedIcon
2278
+ ),
2183
2279
  "aria-hidden": "true",
2184
2280
  children: child.icon
2185
2281
  }
@@ -2328,6 +2424,7 @@ function CollapsedChildMenu({
2328
2424
  children: /* @__PURE__ */ jsxRuntime.jsx(
2329
2425
  EntryContent,
2330
2426
  {
2427
+ appearance,
2331
2428
  item,
2332
2429
  collapsed: !mobile,
2333
2430
  mobile,
@@ -2441,137 +2538,148 @@ function RouteContent({
2441
2538
  onExpandedItemIdsChange
2442
2539
  ]
2443
2540
  );
2444
- return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: cn("grid list-none gap-2 p-0", classNames?.list), children: routeItems.map((item, itemIndex) => {
2445
- const disclosure = isDisclosureRouteItem(item);
2446
- const active = !disclosure && item.id === activeItemId;
2447
- const hasChildren = Boolean(item.children?.length);
2448
- const childrenCollapsible = collapsibleItemIds.has(item.id);
2449
- const childrenExpanded = !childrenCollapsible || expandedItemIdSet.has(item.id);
2450
- const showItemActions = !collapsed && hasRenderableNode(item.actions);
2451
- const compoundItemRow = collapsed && hasChildren && Boolean(onChildSelect) || !collapsed && childrenCollapsible && !disclosure || showItemActions;
2452
- const childListId = `${disclosureId}-route-children-${itemIndex}`;
2453
- return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "grid min-w-0 gap-1", children: [
2454
- collapsed && disclosure ? /* @__PURE__ */ jsxRuntime.jsx(
2455
- CollapsedChildMenu,
2456
- {
2457
- item,
2458
- activeChildId,
2459
- label: collapsedChildMenuLabel,
2460
- onChildSelect,
2461
- classNames,
2462
- appearance,
2463
- triggerVariant: "item"
2464
- }
2465
- ) : /* @__PURE__ */ jsxRuntime.jsxs(
2466
- "div",
2467
- {
2468
- "data-navigation-sidebar-item-row": compoundItemRow ? item.id : void 0,
2469
- "data-active": compoundItemRow ? String(active) : void 0,
2470
- className: compoundItemRow ? routeRowClassName({ active, appearance }) : void 0,
2471
- children: [
2472
- /* @__PURE__ */ jsxRuntime.jsx(
2473
- EntryButton,
2474
- {
2475
- item,
2476
- active,
2477
- collapsed,
2478
- embedded: compoundItemRow,
2479
- itemAs: disclosure ? "button" : itemAs,
2480
- appearance,
2481
- classNames,
2482
- onSelect: disclosure ? () => toggleItemExpanded(item) : onItemSelect ? () => onItemSelect(item) : void 0,
2483
- ariaControls: !collapsed && childrenCollapsible && disclosure ? childListId : void 0,
2484
- ariaExpanded: !collapsed && childrenCollapsible && disclosure ? childrenExpanded : void 0,
2485
- endIndicator: !collapsed && disclosure && !showItemActions ? /* @__PURE__ */ jsxRuntime.jsx(DisclosureIcon, { expanded: childrenExpanded }) : void 0
2486
- }
2487
- ),
2488
- showItemActions ? /* @__PURE__ */ jsxRuntime.jsx(
2489
- RouteActions,
2490
- {
2491
- itemId: item.id,
2492
- actions: item.actions,
2493
- kind: "item",
2494
- className: classNames?.itemActions
2495
- }
2496
- ) : null,
2497
- collapsed && onChildSelect ? /* @__PURE__ */ jsxRuntime.jsx(
2498
- CollapsedChildMenu,
2499
- {
2500
- item,
2501
- activeChildId,
2502
- label: collapsedChildMenuLabel,
2503
- onChildSelect,
2504
- classNames
2505
- }
2506
- ) : null,
2507
- !collapsed && childrenCollapsible && (!disclosure || showItemActions) ? /* @__PURE__ */ jsxRuntime.jsx(
2508
- RouteChildrenToggle,
2509
- {
2510
- item,
2511
- expanded: childrenExpanded,
2512
- controls: childListId,
2513
- label: disclosureLabel,
2514
- onToggle: () => toggleItemExpanded(item),
2515
- classNames
2516
- }
2517
- ) : null
2518
- ]
2519
- }
2541
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": ariaLabel, children: /* @__PURE__ */ jsxRuntime.jsx(
2542
+ "ul",
2543
+ {
2544
+ className: cn(
2545
+ "grid list-none gap-2 p-0",
2546
+ appearance.unified && "gap-0.5",
2547
+ classNames?.list
2520
2548
  ),
2521
- !collapsed && hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
2522
- "ul",
2523
- {
2524
- id: childListId,
2525
- hidden: !childrenExpanded,
2526
- style: childrenExpanded ? void 0 : { display: "none" },
2527
- className: cn(
2528
- "ml-5 grid list-none gap-0.5 border-l border-border/70 py-1 pl-3",
2529
- classNames?.childList
2549
+ children: routeItems.map((item, itemIndex) => {
2550
+ const disclosure = isDisclosureRouteItem(item);
2551
+ const active = !disclosure && item.id === activeItemId;
2552
+ const hasChildren = Boolean(item.children?.length);
2553
+ const childrenCollapsible = collapsibleItemIds.has(item.id);
2554
+ const childrenExpanded = !childrenCollapsible || expandedItemIdSet.has(item.id);
2555
+ const showItemActions = !collapsed && hasRenderableNode(item.actions);
2556
+ const compoundItemRow = collapsed && hasChildren && Boolean(onChildSelect) || !collapsed && childrenCollapsible && !disclosure || showItemActions;
2557
+ const childListId = `${disclosureId}-route-children-${itemIndex}`;
2558
+ return /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "grid min-w-0 gap-1", children: [
2559
+ collapsed && disclosure ? /* @__PURE__ */ jsxRuntime.jsx(
2560
+ CollapsedChildMenu,
2561
+ {
2562
+ item,
2563
+ activeChildId,
2564
+ label: collapsedChildMenuLabel,
2565
+ onChildSelect,
2566
+ classNames,
2567
+ appearance,
2568
+ triggerVariant: "item"
2569
+ }
2570
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
2571
+ "div",
2572
+ {
2573
+ "data-navigation-sidebar-item-row": compoundItemRow ? item.id : void 0,
2574
+ "data-active": compoundItemRow ? String(active) : void 0,
2575
+ className: compoundItemRow ? routeRowClassName({ active, appearance }) : void 0,
2576
+ children: [
2577
+ /* @__PURE__ */ jsxRuntime.jsx(
2578
+ EntryButton,
2579
+ {
2580
+ item,
2581
+ active,
2582
+ collapsed,
2583
+ embedded: compoundItemRow,
2584
+ itemAs: disclosure ? "button" : itemAs,
2585
+ appearance,
2586
+ classNames,
2587
+ onSelect: disclosure ? () => toggleItemExpanded(item) : onItemSelect ? () => onItemSelect(item) : void 0,
2588
+ ariaControls: !collapsed && childrenCollapsible && disclosure ? childListId : void 0,
2589
+ ariaExpanded: !collapsed && childrenCollapsible && disclosure ? childrenExpanded : void 0,
2590
+ endIndicator: !collapsed && disclosure && !showItemActions ? /* @__PURE__ */ jsxRuntime.jsx(DisclosureIcon, { expanded: childrenExpanded }) : void 0
2591
+ }
2592
+ ),
2593
+ showItemActions ? /* @__PURE__ */ jsxRuntime.jsx(
2594
+ RouteActions,
2595
+ {
2596
+ itemId: item.id,
2597
+ actions: item.actions,
2598
+ kind: "item",
2599
+ className: classNames?.itemActions
2600
+ }
2601
+ ) : null,
2602
+ collapsed && onChildSelect ? /* @__PURE__ */ jsxRuntime.jsx(
2603
+ CollapsedChildMenu,
2604
+ {
2605
+ item,
2606
+ activeChildId,
2607
+ label: collapsedChildMenuLabel,
2608
+ onChildSelect,
2609
+ classNames
2610
+ }
2611
+ ) : null,
2612
+ !collapsed && childrenCollapsible && (!disclosure || showItemActions) ? /* @__PURE__ */ jsxRuntime.jsx(
2613
+ RouteChildrenToggle,
2614
+ {
2615
+ item,
2616
+ expanded: childrenExpanded,
2617
+ controls: childListId,
2618
+ label: disclosureLabel,
2619
+ onToggle: () => toggleItemExpanded(item),
2620
+ classNames
2621
+ }
2622
+ ) : null
2623
+ ]
2624
+ }
2530
2625
  ),
2531
- children: item.children?.map((child) => {
2532
- const hasChildActions = hasRenderableNode(child.actions);
2533
- const childActive = child.id === activeChildId;
2534
- const childEntry = /* @__PURE__ */ jsxRuntime.jsx(
2535
- ChildEntry,
2536
- {
2537
- child,
2538
- parent: item,
2539
- active: childActive,
2540
- interactive: Boolean(onChildSelect),
2541
- onSelect: onChildSelect,
2542
- appearance,
2543
- classNames,
2544
- embedded: hasChildActions
2545
- }
2546
- );
2547
- return /* @__PURE__ */ jsxRuntime.jsx("li", { children: hasChildActions ? /* @__PURE__ */ jsxRuntime.jsxs(
2548
- "div",
2549
- {
2550
- "data-navigation-sidebar-child-row": child.id,
2551
- "data-active": String(childActive),
2552
- className: routeRowClassName({
2553
- active: childActive,
2554
- appearance
2555
- }),
2556
- children: [
2557
- childEntry,
2558
- /* @__PURE__ */ jsxRuntime.jsx(
2559
- RouteActions,
2560
- {
2561
- itemId: child.id,
2562
- actions: child.actions,
2563
- kind: "child",
2564
- className: classNames?.childActions
2565
- }
2566
- )
2567
- ]
2568
- }
2569
- ) : childEntry }, child.id);
2570
- })
2571
- }
2572
- ) : null
2573
- ] }, item.id);
2574
- }) }) });
2626
+ !collapsed && hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
2627
+ "ul",
2628
+ {
2629
+ id: childListId,
2630
+ hidden: !childrenExpanded,
2631
+ style: childrenExpanded ? void 0 : { display: "none" },
2632
+ className: cn(
2633
+ "ml-5 grid list-none gap-0.5 border-l border-border/70 py-1 pl-3",
2634
+ appearance.unified && "border-border",
2635
+ classNames?.childList
2636
+ ),
2637
+ children: item.children?.map((child) => {
2638
+ const hasChildActions = hasRenderableNode(child.actions);
2639
+ const childActive = child.id === activeChildId;
2640
+ const childEntry = /* @__PURE__ */ jsxRuntime.jsx(
2641
+ ChildEntry,
2642
+ {
2643
+ child,
2644
+ parent: item,
2645
+ active: childActive,
2646
+ interactive: Boolean(onChildSelect),
2647
+ onSelect: onChildSelect,
2648
+ appearance,
2649
+ classNames,
2650
+ embedded: hasChildActions
2651
+ }
2652
+ );
2653
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { children: hasChildActions ? /* @__PURE__ */ jsxRuntime.jsxs(
2654
+ "div",
2655
+ {
2656
+ "data-navigation-sidebar-child-row": child.id,
2657
+ "data-active": String(childActive),
2658
+ className: routeRowClassName({
2659
+ active: childActive,
2660
+ appearance
2661
+ }),
2662
+ children: [
2663
+ childEntry,
2664
+ /* @__PURE__ */ jsxRuntime.jsx(
2665
+ RouteActions,
2666
+ {
2667
+ itemId: child.id,
2668
+ actions: child.actions,
2669
+ kind: "child",
2670
+ className: classNames?.childActions
2671
+ }
2672
+ )
2673
+ ]
2674
+ }
2675
+ ) : childEntry }, child.id);
2676
+ })
2677
+ }
2678
+ ) : null
2679
+ ] }, item.id);
2680
+ })
2681
+ }
2682
+ ) });
2575
2683
  }
2576
2684
  function flattenCatalogItems(items, sections, activeFilterId) {
2577
2685
  return [
@@ -2881,7 +2989,11 @@ function NavigationSidebarInner(props, ref) {
2881
2989
  DataExplorerViewTree,
2882
2990
  {
2883
2991
  ...treeProps,
2884
- classNames: resolveNavigationTreeClassNames(treeProps.classNames)
2992
+ classNames: appearance.unified ? unifiedTreeClassNames(
2993
+ appearance.itemHeight,
2994
+ appearance.itemPadding,
2995
+ treeProps.classNames
2996
+ ) : resolveNavigationTreeClassNames(treeProps.classNames)
2885
2997
  }
2886
2998
  );
2887
2999
  };
@@ -2894,6 +3006,7 @@ function NavigationSidebarInner(props, ref) {
2894
3006
  "aria-label": props.ariaLabel,
2895
3007
  "data-monkeys-component": props.dataComponent ?? "navigation-sidebar",
2896
3008
  "data-navigation-sidebar-kind": props.kind,
3009
+ "data-navigation-sidebar-preset": props.appearance?.preset,
2897
3010
  "data-collapsed": resolvedCollapsed ? "true" : "false",
2898
3011
  className: cn(
2899
3012
  "relative flex h-full min-h-0 shrink-0 flex-col overflow-visible rounded-[calc(var(--radius)+0.25rem)] border transition-[width,opacity] duration-300 motion-reduce:transition-none",
@@ -2904,6 +3017,7 @@ function NavigationSidebarInner(props, ref) {
2904
3017
  props.className
2905
3018
  ),
2906
3019
  style: {
3020
+ ...appearance.unified ? unifiedStyle(props.appearance?.activeVariant) : {},
2907
3021
  ...props.style,
2908
3022
  width: props.widthMode === "fill" ? void 0 : resolvedCollapsed ? bounds.collapsedWidth : resolvedWidth,
2909
3023
  transition: isResizing ? "none" : props.style?.transition
@@ -2941,6 +3055,7 @@ function NavigationSidebarInner(props, ref) {
2941
3055
  {
2942
3056
  className: cn(
2943
3057
  "flex min-h-12 min-w-0 items-center gap-2 border-b border-border/60 px-3",
3058
+ appearance.unified && "min-h-14 border-border px-[var(--monkeys-component-navigation-sidebar-content-inline-padding,var(--global-spacing,0.75rem))]",
2944
3059
  resolvedCollapsed && "justify-center px-1",
2945
3060
  props.classNames?.header
2946
3061
  ),
@@ -2984,6 +3099,7 @@ function NavigationSidebarInner(props, ref) {
2984
3099
  {
2985
3100
  className: cn(
2986
3101
  "px-[var(--monkeys-component-navigation-sidebar-content-inline-padding,var(--global-spacing,0.75rem))] pb-2 pt-3",
3102
+ appearance.unified && "pb-1",
2987
3103
  props.classNames?.search
2988
3104
  ),
2989
3105
  children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -2991,7 +3107,8 @@ function NavigationSidebarInner(props, ref) {
2991
3107
  {
2992
3108
  className: cn(
2993
3109
  "flex items-center gap-2 rounded-md border border-input bg-[var(--monkeys-component-navigation-sidebar-search-background,hsl(var(--monkeys-color-control-surface)))] px-3 text-muted-foreground ring-offset-control-surface focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
2994
- appearance.searchHeight
3110
+ appearance.searchHeight,
3111
+ appearance.unified && "rounded-[var(--radius)] border-border bg-[var(--monkeys-component-navigation-sidebar-search-background,transparent)] px-2"
2995
3112
  ),
2996
3113
  children: [
2997
3114
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -2999,6 +3116,7 @@ function NavigationSidebarInner(props, ref) {
2999
3116
  {
3000
3117
  className: cn(
3001
3118
  "flex shrink-0",
3119
+ appearance.unified && unifiedIcon,
3002
3120
  props.classNames?.searchIcon
3003
3121
  ),
3004
3122
  "aria-hidden": "true",
@@ -3052,6 +3170,7 @@ function NavigationSidebarInner(props, ref) {
3052
3170
  {
3053
3171
  className: cn(
3054
3172
  "min-h-0 flex-1 overflow-y-auto px-[var(--monkeys-component-navigation-sidebar-content-inline-padding,var(--global-spacing,0.75rem))] py-3",
3173
+ appearance.unified && props.search && "pt-1",
3055
3174
  resolvedCollapsed && "px-1.5",
3056
3175
  props.classNames?.content
3057
3176
  ),
@@ -3063,6 +3182,7 @@ function NavigationSidebarInner(props, ref) {
3063
3182
  {
3064
3183
  className: cn(
3065
3184
  "flex shrink-0 items-center gap-2 border-t border-border/70 p-3",
3185
+ appearance.unified && "border-border",
3066
3186
  resolvedCollapsed && "justify-center px-1",
3067
3187
  props.classNames?.footer
3068
3188
  ),