@zendir/ui 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +419 -386
  2. package/README.md +640 -631
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/index.js +17 -221
  5. package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
  6. package/dist/react/3d/CesiumCaptureSource.js +364 -283
  7. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  8. package/dist/react/3d/ZenSpace3D.d.ts +2 -3
  9. package/dist/react/3d/ZenSpace3D.js +1681 -1237
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -1
  11. package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
  12. package/dist/react/3d/ZenSpace3DCesium.js +513 -560
  13. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
  14. package/dist/react/3d/ZenSpace3DShaders.js +61 -66
  15. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
  16. package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
  17. package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
  18. package/dist/react/3d/ZenSpace3DUtils.js +37 -24
  19. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  20. package/dist/react/3d/capturePngAnalysis.js +42 -36
  21. package/dist/react/3d/capturePngAnalysis.js.map +1 -1
  22. package/dist/react/3d/index.d.ts +3 -3
  23. package/dist/react/3d/index.js +5 -53
  24. package/dist/react/3d/threeLoader.d.ts +1 -1
  25. package/dist/react/3d/threeLoader.js +23 -18
  26. package/dist/react/3d/threeLoader.js.map +1 -1
  27. package/dist/react/astro/ClassificationBanner.d.ts +2 -3
  28. package/dist/react/astro/ClassificationBanner.js +95 -79
  29. package/dist/react/astro/ClassificationBanner.js.map +1 -1
  30. package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
  31. package/dist/react/astro/GlobalStatusBar.js +157 -163
  32. package/dist/react/astro/GlobalStatusBar.js.map +1 -1
  33. package/dist/react/astro/MissionClock.d.ts +7 -8
  34. package/dist/react/astro/MissionClock.js +377 -400
  35. package/dist/react/astro/MissionClock.js.map +1 -1
  36. package/dist/react/astro/MonitoringIcon.d.ts +1 -2
  37. package/dist/react/astro/MonitoringIcon.js +422 -358
  38. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  39. package/dist/react/astro/Notification.d.ts +1 -2
  40. package/dist/react/astro/Notification.js +229 -126
  41. package/dist/react/astro/Notification.js.map +1 -1
  42. package/dist/react/astro/Progress.d.ts +0 -1
  43. package/dist/react/astro/Progress.js +199 -141
  44. package/dist/react/astro/Progress.js.map +1 -1
  45. package/dist/react/astro/SimulationControls.d.ts +3 -4
  46. package/dist/react/astro/SimulationControls.js +596 -650
  47. package/dist/react/astro/SimulationControls.js.map +1 -1
  48. package/dist/react/astro/StatusIndicator.d.ts +0 -1
  49. package/dist/react/astro/StatusIndicator.js +236 -170
  50. package/dist/react/astro/StatusIndicator.js.map +1 -1
  51. package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
  52. package/dist/react/astro/UnifiedTimeline.js +2345 -2392
  53. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  54. package/dist/react/astro/index.d.ts +5 -5
  55. package/dist/react/astro/index.js +1 -25
  56. package/dist/react/cards/AccessCard.d.ts +0 -1
  57. package/dist/react/cards/AccessCard.js +471 -405
  58. package/dist/react/cards/AccessCard.js.map +1 -1
  59. package/dist/react/cards/OrbitCard.d.ts +0 -1
  60. package/dist/react/cards/OrbitCard.js +487 -364
  61. package/dist/react/cards/OrbitCard.js.map +1 -1
  62. package/dist/react/cards/SpacecraftCard.d.ts +0 -1
  63. package/dist/react/cards/SpacecraftCard.js +813 -925
  64. package/dist/react/cards/SpacecraftCard.js.map +1 -1
  65. package/dist/react/cards/TelemetryCard.d.ts +0 -1
  66. package/dist/react/cards/TelemetryCard.js +1055 -732
  67. package/dist/react/cards/TelemetryCard.js.map +1 -1
  68. package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
  69. package/dist/react/cards/TelemetryStreamCard.js +323 -297
  70. package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
  71. package/dist/react/cards/index.d.ts +1 -1
  72. package/dist/react/cards/index.js +1 -8
  73. package/dist/react/charts/GroundTrackMap.d.ts +6 -7
  74. package/dist/react/charts/GroundTrackMap.js +1377 -1256
  75. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  76. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
  77. package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
  78. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
  79. package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
  80. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
  81. package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
  82. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
  83. package/dist/react/charts/index.d.ts +1 -1
  84. package/dist/react/charts/index.js +7 -100
  85. package/dist/react/charts/unified/AstroChart.d.ts +1 -2
  86. package/dist/react/charts/unified/AstroChart.js +1331 -1411
  87. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  88. package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
  89. package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
  90. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
  91. package/dist/react/charts/unified/domain.d.ts +12 -13
  92. package/dist/react/charts/unified/domain.js +3999 -3145
  93. package/dist/react/charts/unified/domain.js.map +1 -1
  94. package/dist/react/charts/unified/generators.d.ts +3 -4
  95. package/dist/react/charts/unified/generators.js +561 -498
  96. package/dist/react/charts/unified/generators.js.map +1 -1
  97. package/dist/react/charts/unified/index.d.ts +1 -1
  98. package/dist/react/charts/unified/presets.d.ts +14 -15
  99. package/dist/react/charts/unified/presets.js +857 -994
  100. package/dist/react/charts/unified/presets.js.map +1 -1
  101. package/dist/react/charts/unified/sync.d.ts +2 -3
  102. package/dist/react/charts/unified/sync.js +229 -195
  103. package/dist/react/charts/unified/sync.js.map +1 -1
  104. package/dist/react/charts/unified/theme.d.ts +11 -12
  105. package/dist/react/charts/unified/theme.js +606 -642
  106. package/dist/react/charts/unified/theme.js.map +1 -1
  107. package/dist/react/charts/unified/types.d.ts +32 -33
  108. package/dist/react/charts/unified/useChartStream.d.ts +1 -2
  109. package/dist/react/charts/unified/useChartStream.js +203 -216
  110. package/dist/react/charts/unified/useChartStream.js.map +1 -1
  111. package/dist/react/chatgpt/AppCard.d.ts +1 -2
  112. package/dist/react/chatgpt/index.d.ts +7 -7
  113. package/dist/react/chatgpt/index.js +160 -139
  114. package/dist/react/chatgpt/index.js.map +1 -1
  115. package/dist/react/context/CategoryContext.d.ts +0 -1
  116. package/dist/react/context/CategoryContext.js +78 -29
  117. package/dist/react/context/CategoryContext.js.map +1 -1
  118. package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
  119. package/dist/react/context/DisplaySettingsContext.js +205 -156
  120. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  121. package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
  122. package/dist/react/context/SpatialSelectionContext.js +36 -7
  123. package/dist/react/context/SpatialSelectionContext.js.map +1 -1
  124. package/dist/react/core/data/DataTable.d.ts +3 -4
  125. package/dist/react/core/data/DataTable.js +473 -440
  126. package/dist/react/core/data/DataTable.js.map +1 -1
  127. package/dist/react/core/data/DataValue.d.ts +4 -5
  128. package/dist/react/core/data/DataValue.js +605 -571
  129. package/dist/react/core/data/DataValue.js.map +1 -1
  130. package/dist/react/core/data/propertyConfig.d.ts +1 -2
  131. package/dist/react/core/data/propertyConfig.js +446 -382
  132. package/dist/react/core/data/propertyConfig.js.map +1 -1
  133. package/dist/react/core/display/AstroIcon.d.ts +4 -5
  134. package/dist/react/core/display/AstroIcon.js +339 -429
  135. package/dist/react/core/display/AstroIcon.js.map +1 -1
  136. package/dist/react/core/display/Badge.d.ts +2 -3
  137. package/dist/react/core/display/Badge.js +131 -131
  138. package/dist/react/core/display/Badge.js.map +1 -1
  139. package/dist/react/core/display/CardHeader.d.ts +0 -1
  140. package/dist/react/core/display/CardHeader.js +398 -311
  141. package/dist/react/core/display/CardHeader.js.map +1 -1
  142. package/dist/react/core/display/Container.d.ts +2 -3
  143. package/dist/react/core/display/Container.js +640 -668
  144. package/dist/react/core/display/Container.js.map +1 -1
  145. package/dist/react/core/display/CopyButton.d.ts +1 -2
  146. package/dist/react/core/display/CopyButton.js +158 -101
  147. package/dist/react/core/display/CopyButton.js.map +1 -1
  148. package/dist/react/core/display/GlassCard.d.ts +3 -4
  149. package/dist/react/core/display/GlassCard.js +416 -369
  150. package/dist/react/core/display/GlassCard.js.map +1 -1
  151. package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
  152. package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
  153. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
  154. package/dist/react/core/display/Icon.d.ts +2 -3
  155. package/dist/react/core/display/Icon.js +172 -143
  156. package/dist/react/core/display/Icon.js.map +1 -1
  157. package/dist/react/core/display/Typography.d.ts +24 -25
  158. package/dist/react/core/display/Typography.js +360 -178
  159. package/dist/react/core/display/Typography.js.map +1 -1
  160. package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
  161. package/dist/react/core/feedback/ConfirmDialog.js +343 -304
  162. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
  163. package/dist/react/core/feedback/Dialog.d.ts +2 -3
  164. package/dist/react/core/feedback/Dialog.js +189 -197
  165. package/dist/react/core/feedback/Dialog.js.map +1 -1
  166. package/dist/react/core/feedback/Toast.d.ts +2 -3
  167. package/dist/react/core/feedback/Toast.js +346 -207
  168. package/dist/react/core/feedback/Toast.js.map +1 -1
  169. package/dist/react/core/index.d.ts +26 -26
  170. package/dist/react/core/index.js +7 -119
  171. package/dist/react/core/inputs/Button.d.ts +2 -3
  172. package/dist/react/core/inputs/Button.js +281 -304
  173. package/dist/react/core/inputs/Button.js.map +1 -1
  174. package/dist/react/core/inputs/Checkbox.d.ts +2 -3
  175. package/dist/react/core/inputs/Checkbox.js +139 -127
  176. package/dist/react/core/inputs/Checkbox.js.map +1 -1
  177. package/dist/react/core/inputs/Input.d.ts +3 -4
  178. package/dist/react/core/inputs/Input.js +277 -285
  179. package/dist/react/core/inputs/Input.js.map +1 -1
  180. package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
  181. package/dist/react/core/inputs/LimitsBar.js +271 -196
  182. package/dist/react/core/inputs/LimitsBar.js.map +1 -1
  183. package/dist/react/core/inputs/NumberInput.d.ts +2 -3
  184. package/dist/react/core/inputs/NumberInput.js +531 -503
  185. package/dist/react/core/inputs/NumberInput.js.map +1 -1
  186. package/dist/react/core/inputs/PinInput.d.ts +2 -3
  187. package/dist/react/core/inputs/PinInput.js +224 -207
  188. package/dist/react/core/inputs/PinInput.js.map +1 -1
  189. package/dist/react/core/inputs/Select.d.ts +1 -2
  190. package/dist/react/core/inputs/Select.js +298 -299
  191. package/dist/react/core/inputs/Select.js.map +1 -1
  192. package/dist/react/core/inputs/Toggle.d.ts +2 -3
  193. package/dist/react/core/inputs/Toggle.js +142 -148
  194. package/dist/react/core/inputs/Toggle.js.map +1 -1
  195. package/dist/react/core/layout/Box.d.ts +3 -4
  196. package/dist/react/core/layout/Box.js +118 -122
  197. package/dist/react/core/layout/Box.js.map +1 -1
  198. package/dist/react/core/layout/Center.d.ts +0 -1
  199. package/dist/react/core/layout/Center.js +45 -32
  200. package/dist/react/core/layout/Center.js.map +1 -1
  201. package/dist/react/core/layout/Divider.d.ts +1 -2
  202. package/dist/react/core/layout/Divider.js +112 -106
  203. package/dist/react/core/layout/Divider.js.map +1 -1
  204. package/dist/react/core/layout/Flex.d.ts +4 -5
  205. package/dist/react/core/layout/Flex.js +120 -124
  206. package/dist/react/core/layout/Flex.js.map +1 -1
  207. package/dist/react/core/layout/Grid.d.ts +5 -6
  208. package/dist/react/core/layout/Grid.js +131 -138
  209. package/dist/react/core/layout/Grid.js.map +1 -1
  210. package/dist/react/core/layout/Spacer.d.ts +0 -1
  211. package/dist/react/core/layout/Spacer.js +36 -29
  212. package/dist/react/core/layout/Spacer.js.map +1 -1
  213. package/dist/react/core/layout/Stack.d.ts +4 -5
  214. package/dist/react/core/layout/Stack.js +127 -70
  215. package/dist/react/core/layout/Stack.js.map +1 -1
  216. package/dist/react/core/layout/responsive.d.ts +1 -2
  217. package/dist/react/core/layout/responsive.js +25 -19
  218. package/dist/react/core/layout/responsive.js.map +1 -1
  219. package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
  220. package/dist/react/core/layout/useBreakpoint.js +119 -66
  221. package/dist/react/core/layout/useBreakpoint.js.map +1 -1
  222. package/dist/react/core/navigation/AppBar.d.ts +1 -2
  223. package/dist/react/core/navigation/AppBar.js +827 -805
  224. package/dist/react/core/navigation/AppBar.js.map +1 -1
  225. package/dist/react/core/navigation/Pagination.d.ts +2 -3
  226. package/dist/react/core/navigation/Pagination.js +207 -187
  227. package/dist/react/core/navigation/Pagination.js.map +1 -1
  228. package/dist/react/core/navigation/SideNav.d.ts +5 -6
  229. package/dist/react/core/navigation/SideNav.js +855 -629
  230. package/dist/react/core/navigation/SideNav.js.map +1 -1
  231. package/dist/react/core/navigation/Tabs.d.ts +0 -1
  232. package/dist/react/core/navigation/Tabs.js +113 -119
  233. package/dist/react/core/navigation/Tabs.js.map +1 -1
  234. package/dist/react/core/overlays/Popover.d.ts +2 -3
  235. package/dist/react/core/overlays/Popover.js +303 -282
  236. package/dist/react/core/overlays/Popover.js.map +1 -1
  237. package/dist/react/core/overlays/SidePanel.d.ts +1 -2
  238. package/dist/react/core/overlays/SidePanel.js +217 -212
  239. package/dist/react/core/overlays/SidePanel.js.map +1 -1
  240. package/dist/react/core/overlays/Tooltip.d.ts +1 -2
  241. package/dist/react/core/overlays/Tooltip.js +170 -176
  242. package/dist/react/core/overlays/Tooltip.js.map +1 -1
  243. package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
  244. package/dist/react/core/widgets/ActivityPlanner.js +855 -517
  245. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
  246. package/dist/react/core/widgets/Capture.d.ts +2 -3
  247. package/dist/react/core/widgets/Capture.js +965 -779
  248. package/dist/react/core/widgets/Capture.js.map +1 -1
  249. package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
  250. package/dist/react/core/widgets/ChatPanel.js +1734 -1034
  251. package/dist/react/core/widgets/ChatPanel.js.map +1 -1
  252. package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
  253. package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
  254. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
  255. package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
  256. package/dist/react/core/widgets/CommandBuilder.js +624 -516
  257. package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
  258. package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
  259. package/dist/react/core/widgets/ConnectionForm.js +528 -492
  260. package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
  261. package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
  262. package/dist/react/core/widgets/FileExplorer.js +617 -505
  263. package/dist/react/core/widgets/FileExplorer.js.map +1 -1
  264. package/dist/react/core/widgets/HexViewer.d.ts +2 -3
  265. package/dist/react/core/widgets/HexViewer.js +1353 -1091
  266. package/dist/react/core/widgets/HexViewer.js.map +1 -1
  267. package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
  268. package/dist/react/core/widgets/ImageFrame.js +230 -193
  269. package/dist/react/core/widgets/ImageFrame.js.map +1 -1
  270. package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
  271. package/dist/react/core/widgets/ImageGallery.js +380 -314
  272. package/dist/react/core/widgets/ImageGallery.js.map +1 -1
  273. package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
  274. package/dist/react/core/widgets/ImagePanel.js +110 -101
  275. package/dist/react/core/widgets/ImagePanel.js.map +1 -1
  276. package/dist/react/core/widgets/LogViewer.d.ts +2 -3
  277. package/dist/react/core/widgets/LogViewer.js +711 -607
  278. package/dist/react/core/widgets/LogViewer.js.map +1 -1
  279. package/dist/react/core/widgets/MessageStream.d.ts +3 -4
  280. package/dist/react/core/widgets/MessageStream.js +514 -444
  281. package/dist/react/core/widgets/MessageStream.js.map +1 -1
  282. package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
  283. package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
  284. package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
  285. package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
  286. package/dist/react/core/widgets/PacketViewer.js +550 -421
  287. package/dist/react/core/widgets/PacketViewer.js.map +1 -1
  288. package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
  289. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
  290. package/dist/react/hooks/index.d.ts +5 -5
  291. package/dist/react/hooks/useAccessWindows.d.ts +0 -1
  292. package/dist/react/hooks/useCompactMode.d.ts +1 -1
  293. package/dist/react/hooks/useCompactMode.js +104 -58
  294. package/dist/react/hooks/useCompactMode.js.map +1 -1
  295. package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
  296. package/dist/react/hooks/useSimulationScene.d.ts +1 -2
  297. package/dist/react/hooks/useSimulationScene.js +481 -374
  298. package/dist/react/hooks/useSimulationScene.js.map +1 -1
  299. package/dist/react/index.d.ts +3 -3
  300. package/dist/react/panels/LayerControlPanel.d.ts +1 -2
  301. package/dist/react/panels/LayerControlPanel.js +223 -180
  302. package/dist/react/panels/LayerControlPanel.js.map +1 -1
  303. package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
  304. package/dist/react/panels/ObjectInventoryPanel.js +315 -250
  305. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
  306. package/dist/react/panels/index.d.ts +1 -1
  307. package/dist/react/panels/index.js +1 -6
  308. package/dist/react/shared/ErrorBoundary.d.ts +1 -2
  309. package/dist/react/shared/ErrorBoundary.js +170 -139
  310. package/dist/react/shared/ErrorBoundary.js.map +1 -1
  311. package/dist/react/shared/Skeleton.d.ts +1 -2
  312. package/dist/react/shared/Skeleton.js +300 -301
  313. package/dist/react/shared/Skeleton.js.map +1 -1
  314. package/dist/react/theme/ThemeProvider.d.ts +2 -321
  315. package/dist/react/theme/ThemeProvider.js +313 -939
  316. package/dist/react/theme/ThemeProvider.js.map +1 -1
  317. package/dist/react/theme/cardAccent.d.ts +1 -2
  318. package/dist/react/theme/cardAccent.js +196 -126
  319. package/dist/react/theme/cardAccent.js.map +1 -1
  320. package/dist/react/theme/config.d.ts +0 -1
  321. package/dist/react/theme/config.js +47 -25
  322. package/dist/react/theme/config.js.map +1 -1
  323. package/dist/react/theme/index.d.ts +2 -2
  324. package/dist/react/theme/index.js +1 -16
  325. package/dist/react/theme/types.d.ts +332 -0
  326. package/dist/react/theme/types.js +39 -0
  327. package/dist/react/theme/types.js.map +1 -0
  328. package/dist/react/types.d.ts +8 -8
  329. package/dist/react/types.js +147 -47
  330. package/dist/react/types.js.map +1 -1
  331. package/dist/react/utils/categoryPalette.d.ts +0 -1
  332. package/dist/react/utils/categoryPalette.js +91 -102
  333. package/dist/react/utils/categoryPalette.js.map +1 -1
  334. package/dist/react/utils/index.d.ts +5 -5
  335. package/dist/react/utils/index.js +457 -371
  336. package/dist/react/utils/index.js.map +1 -1
  337. package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
  338. package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
  339. package/dist/react/visualizations/NavBallCard.d.ts +0 -1
  340. package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
  341. package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
  342. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
  343. package/dist/react/visualizations/index.d.ts +3 -3
  344. package/dist/react.d.ts +2 -1
  345. package/dist/react.js +17 -221
  346. package/dist/shaders/atmosphere.frag.js +6 -5
  347. package/dist/shaders/atmosphere.frag.js.map +1 -1
  348. package/dist/shaders/atmosphere.vert.js +6 -5
  349. package/dist/shaders/atmosphere.vert.js.map +1 -1
  350. package/dist/shaders/stars.frag.js +6 -5
  351. package/dist/shaders/stars.frag.js.map +1 -1
  352. package/dist/shaders/stars.vert.js +6 -5
  353. package/dist/shaders/stars.vert.js.map +1 -1
  354. package/dist/style.css +26 -3
  355. package/dist/tokens/core.d.ts +159 -0
  356. package/dist/tokens/core.js +144 -0
  357. package/dist/tokens/core.js.map +1 -0
  358. package/dist/tokens/css-vars.d.ts +213 -2
  359. package/dist/tokens/css-vars.js +590 -227
  360. package/dist/tokens/css-vars.js.map +1 -1
  361. package/dist/tokens/index.d.ts +31 -228
  362. package/dist/tokens/index.js +281 -366
  363. package/dist/tokens/index.js.map +1 -1
  364. package/dist/tokens/palettes/astro.d.ts +129 -0
  365. package/dist/tokens/palettes/astro.js +112 -0
  366. package/dist/tokens/palettes/astro.js.map +1 -0
  367. package/dist/tokens/palettes/index.d.ts +288 -0
  368. package/dist/tokens/palettes/index.js +35 -0
  369. package/dist/tokens/palettes/index.js.map +1 -0
  370. package/dist/tokens/palettes/tailwind.d.ts +324 -0
  371. package/dist/tokens/palettes/tailwind.js +201 -0
  372. package/dist/tokens/palettes/tailwind.js.map +1 -0
  373. package/dist/tokens/palettes/zendir.d.ts +126 -0
  374. package/dist/tokens/palettes/zendir.js +92 -0
  375. package/dist/tokens/palettes/zendir.js.map +1 -0
  376. package/dist/tokens/themes.d.ts +30 -0
  377. package/dist/tokens/themes.js +704 -0
  378. package/dist/tokens/themes.js.map +1 -0
  379. package/dist/tokens/tokens.css +533 -155
  380. package/dist/types/index.d.ts +2 -2
  381. package/package.json +310 -313
  382. package/dist/index.js.map +0 -1
  383. package/dist/react/3d/index.js.map +0 -1
  384. package/dist/react/astro/index.js.map +0 -1
  385. package/dist/react/cards/index.js.map +0 -1
  386. package/dist/react/charts/index.js.map +0 -1
  387. package/dist/react/core/index.js.map +0 -1
  388. package/dist/react/panels/index.js.map +0 -1
  389. package/dist/react/theme/astro-tokens.d.ts +0 -153
  390. package/dist/react/theme/index.js.map +0 -1
  391. package/dist/react.js.map +0 -1
@@ -1,649 +1,875 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { memo, useState, useEffect, useCallback, useContext, useLayoutEffect, createContext } from "react";
3
1
  import { useTheme } from "../../theme/ThemeProvider.js";
4
- import { safeAccentText } from "../../utils/index.js";
5
2
  import { Icon } from "../display/Icon.js";
6
- const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
7
- const SIDENAV_REVEAL_STYLE_ID = "zendir-sidenav-reveal";
3
+ import { safeAccentText } from "../../utils/index.js";
4
+ import { createContext, memo, useCallback, useContext, useEffect, useLayoutEffect, useState } from "react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/react/core/navigation/SideNav.tsx
7
+ /**
8
+ * @zendir/ui - SideNav Component
9
+ *
10
+ * Persistent sidebar navigation for operator dashboards. Compound component
11
+ * pattern with Header, Item, Section, Divider, and Footer subcomponents.
12
+ *
13
+ * Responsive: Full sidebar on desktop, hamburger overlay on mobile.
14
+ *
15
+ * Astro UX Compliance:
16
+ * - Persistent side navigation pattern (AstroUXDS Navigation)
17
+ * - Status indicator integration
18
+ * - Active state highlighting with accent color
19
+ * - Keyboard navigation support
20
+ * - Reduced motion support
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <SideNav>
25
+ * <SideNav.Header logo={<Icon name="satellite" size={24} />} title="Space Range" badge="Operator" />
26
+ * <SideNav.Section title="Operations">
27
+ * <SideNav.Item icon="controls" label="Controls" description="System command interface" href="/controls" active />
28
+ * <SideNav.Item icon="telemetry" label="Telemetry" href="/telemetry" badge={3} tag="LIVE" tagVariant="success" />
29
+ * <SideNav.Item icon="images" label="Images" href="/images" />
30
+ * </SideNav.Section>
31
+ * <SideNav.Divider />
32
+ * <SideNav.Section title="Analysis">
33
+ * <SideNav.Item icon="chart" label="Plots" href="/plots" />
34
+ * <SideNav.Item icon="map" label="Map" href="/map" />
35
+ * </SideNav.Section>
36
+ * <SideNav.Footer>
37
+ * <SideNav.Item icon="settings" label="Settings" href="/settings" />
38
+ * </SideNav.Footer>
39
+ * </SideNav>
40
+ * ```
41
+ */
42
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
43
+ /**
44
+ * Content that only renders when expanded (item labels, section titles, the
45
+ * header meta block) fades and slides in rather than popping, so widening the
46
+ * rail reads as material flowing in. Injected once as a stylesheet because
47
+ * keyframes can't be expressed inline; honours `prefers-reduced-motion`.
48
+ */
49
+ var SIDENAV_REVEAL_STYLE_ID = "zendir-sidenav-reveal";
8
50
  function ensureSideNavReveal() {
9
- if (typeof document === "undefined") return;
10
- if (document.getElementById(SIDENAV_REVEAL_STYLE_ID)) return;
11
- const el = document.createElement("style");
12
- el.id = SIDENAV_REVEAL_STYLE_ID;
13
- el.textContent = '@keyframes zsn-reveal{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:translateX(0)}}.zsn-reveal{animation:zsn-reveal 220ms cubic-bezier(0.22,1,0.36,1)}.zsn-label{transition:opacity 220ms cubic-bezier(0.22,1,0.36,1),transform 220ms cubic-bezier(0.22,1,0.36,1)}.zsn-label[data-collapsed="true"]{opacity:0;transform:translateX(-6px);pointer-events:none}@media (prefers-reduced-motion: reduce){.zsn-reveal,.zsn-label{animation:none;transition:none}}';
14
- document.head.appendChild(el);
51
+ if (typeof document === "undefined") return;
52
+ if (document.getElementById(SIDENAV_REVEAL_STYLE_ID)) return;
53
+ const el = document.createElement("style");
54
+ el.id = SIDENAV_REVEAL_STYLE_ID;
55
+ el.textContent = "@keyframes zsn-reveal{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:translateX(0)}}.zsn-reveal{animation:zsn-reveal 220ms cubic-bezier(0.22,1,0.36,1)}.zsn-label{transition:opacity 220ms cubic-bezier(0.22,1,0.36,1),transform 220ms cubic-bezier(0.22,1,0.36,1)}.zsn-label[data-collapsed=\"true\"]{opacity:0;transform:translateX(-6px);pointer-events:none}@media (prefers-reduced-motion: reduce){.zsn-reveal,.zsn-label{animation:none;transition:none}}";
56
+ document.head.appendChild(el);
15
57
  }
16
- const SIDENAV_STATUS_COLORS = {
17
- off: "#a4abb6",
18
- standby: "#2dccff",
19
- normal: "#56f000",
20
- caution: "#fce83a",
21
- serious: "#ffb302",
22
- critical: "#ff3838"
23
- };
58
+ /** Astro UX dual-coded status shape (color + geometry). */
24
59
  function NavStatusShape({ status, size = 8 }) {
25
- const color = SIDENAV_STATUS_COLORS[status] ?? SIDENAV_STATUS_COLORS.off;
26
- const glow = `${color}50`;
27
- const style = { flexShrink: 0, filter: `drop-shadow(0 0 3px ${glow})` };
28
- switch (status) {
29
- case "caution":
30
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx("rect", { x: "1", y: "1", width: "10", height: "10", fill: color }) });
31
- case "serious":
32
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx("polygon", { points: "6,1 11,6 6,11 1,6", fill: color }) });
33
- case "critical":
34
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx("polygon", { points: "6,11 1,2 11,2", fill: color }) });
35
- case "standby":
36
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "3.5", fill: "none", stroke: color, strokeWidth: "2" }) });
37
- case "off":
38
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "3", fill: color }) });
39
- default:
40
- return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", width: size, height: size, style, "aria-hidden": "true", children: /* @__PURE__ */ jsx("circle", { cx: "6", cy: "6", r: "5", fill: color }) });
41
- }
60
+ const { tokens } = useTheme();
61
+ const color = tokens.colors.status[status] ?? tokens.colors.status.off;
62
+ const style = {
63
+ flexShrink: 0,
64
+ filter: `drop-shadow(0 0 3px ${`${color}50`})`
65
+ };
66
+ switch (status) {
67
+ case "caution": return /* @__PURE__ */ jsx("svg", {
68
+ viewBox: "0 0 12 12",
69
+ width: size,
70
+ height: size,
71
+ style,
72
+ "aria-hidden": "true",
73
+ children: /* @__PURE__ */ jsx("rect", {
74
+ x: "1",
75
+ y: "1",
76
+ width: "10",
77
+ height: "10",
78
+ fill: color
79
+ })
80
+ });
81
+ case "serious": return /* @__PURE__ */ jsx("svg", {
82
+ viewBox: "0 0 12 12",
83
+ width: size,
84
+ height: size,
85
+ style,
86
+ "aria-hidden": "true",
87
+ children: /* @__PURE__ */ jsx("polygon", {
88
+ points: "6,1 11,6 6,11 1,6",
89
+ fill: color
90
+ })
91
+ });
92
+ case "critical": return /* @__PURE__ */ jsx("svg", {
93
+ viewBox: "0 0 12 12",
94
+ width: size,
95
+ height: size,
96
+ style,
97
+ "aria-hidden": "true",
98
+ children: /* @__PURE__ */ jsx("polygon", {
99
+ points: "6,11 1,2 11,2",
100
+ fill: color
101
+ })
102
+ });
103
+ case "standby": return /* @__PURE__ */ jsx("svg", {
104
+ viewBox: "0 0 12 12",
105
+ width: size,
106
+ height: size,
107
+ style,
108
+ "aria-hidden": "true",
109
+ children: /* @__PURE__ */ jsx("circle", {
110
+ cx: "6",
111
+ cy: "6",
112
+ r: "3.5",
113
+ fill: "none",
114
+ stroke: color,
115
+ strokeWidth: "2"
116
+ })
117
+ });
118
+ case "off": return /* @__PURE__ */ jsx("svg", {
119
+ viewBox: "0 0 12 12",
120
+ width: size,
121
+ height: size,
122
+ style,
123
+ "aria-hidden": "true",
124
+ children: /* @__PURE__ */ jsx("circle", {
125
+ cx: "6",
126
+ cy: "6",
127
+ r: "3",
128
+ fill: color
129
+ })
130
+ });
131
+ default: return /* @__PURE__ */ jsx("svg", {
132
+ viewBox: "0 0 12 12",
133
+ width: size,
134
+ height: size,
135
+ style,
136
+ "aria-hidden": "true",
137
+ children: /* @__PURE__ */ jsx("circle", {
138
+ cx: "6",
139
+ cy: "6",
140
+ r: "5",
141
+ fill: color
142
+ })
143
+ });
144
+ }
42
145
  }
43
- const SIDENAV_BREAKPOINTS = {
44
- mobile: 768,
45
- tablet: 1024
146
+ var SIDENAV_BREAKPOINTS = {
147
+ mobile: 768,
148
+ tablet: 1024
46
149
  };
47
150
  function getSideNavMode(width) {
48
- if (width < SIDENAV_BREAKPOINTS.mobile) return "mobile";
49
- if (width < SIDENAV_BREAKPOINTS.tablet) return "tablet";
50
- return "desktop";
151
+ if (width < SIDENAV_BREAKPOINTS.mobile) return "mobile";
152
+ if (width < SIDENAV_BREAKPOINTS.tablet) return "tablet";
153
+ return "desktop";
51
154
  }
52
- const SideNavContext = createContext({
53
- collapsed: false,
54
- mobileOpen: false,
55
- mode: "desktop",
56
- density: "default",
57
- showCollapseToggle: true,
58
- setMobileOpen: () => {
59
- },
60
- toggleCollapse: () => {
61
- }
155
+ var SideNavContext = createContext({
156
+ collapsed: false,
157
+ mobileOpen: false,
158
+ mode: "desktop",
159
+ density: "default",
160
+ showCollapseToggle: true,
161
+ setMobileOpen: () => {},
162
+ toggleCollapse: () => {}
62
163
  });
63
- const SideNavRoot = memo(function SideNav2({
64
- collapsed,
65
- onCollapsedChange,
66
- showCollapseToggle = true,
67
- width = 260,
68
- collapsedWidth = 64,
69
- density = "default",
70
- mobileVariant = "drawer",
71
- children,
72
- style
73
- }) {
74
- const { tokens, theme } = useTheme();
75
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
76
- const [mobileOpen, setMobileOpen] = useState(false);
77
- const [userCollapsed, setUserCollapsed] = useState(null);
78
- const [viewMode, setViewMode] = useState("desktop");
79
- useIsomorphicLayoutEffect(() => {
80
- if (typeof window === "undefined") return;
81
- setViewMode(getSideNavMode(window.innerWidth));
82
- let rafId;
83
- const handleResize = () => {
84
- cancelAnimationFrame(rafId);
85
- rafId = requestAnimationFrame(() => setViewMode(getSideNavMode(window.innerWidth)));
86
- };
87
- window.addEventListener("resize", handleResize, { passive: true });
88
- return () => {
89
- window.removeEventListener("resize", handleResize);
90
- cancelAnimationFrame(rafId);
91
- };
92
- }, []);
93
- useIsomorphicLayoutEffect(() => {
94
- ensureSideNavReveal();
95
- }, []);
96
- const effectiveMode = mobileVariant === "collapsed" && viewMode === "mobile" ? "tablet" : viewMode;
97
- useEffect(() => {
98
- setUserCollapsed(null);
99
- }, [effectiveMode]);
100
- useEffect(() => {
101
- if (effectiveMode !== "mobile" && mobileOpen) setMobileOpen(false);
102
- }, [effectiveMode, mobileOpen]);
103
- useEffect(() => {
104
- if (!mobileOpen) return;
105
- const handleEsc = (e) => {
106
- if (e.key === "Escape") setMobileOpen(false);
107
- };
108
- document.addEventListener("keydown", handleEsc);
109
- return () => document.removeEventListener("keydown", handleEsc);
110
- }, [mobileOpen]);
111
- const autoCollapsed = effectiveMode === "tablet";
112
- const isCollapsed = collapsed !== void 0 ? collapsed : userCollapsed !== null ? userCollapsed : autoCollapsed;
113
- const isMobile = effectiveMode === "mobile";
114
- const navWidth = isCollapsed ? collapsedWidth : width;
115
- const handleToggleCollapse = useCallback(() => {
116
- const next = !isCollapsed;
117
- setUserCollapsed(next);
118
- onCollapsedChange == null ? void 0 : onCollapsedChange(next);
119
- }, [isCollapsed, onCollapsedChange]);
120
- const navStyle = {
121
- display: "flex",
122
- flexDirection: "column",
123
- width: isMobile ? 280 : navWidth,
124
- height: "100%",
125
- backgroundColor: isTransparentTheme ? "rgba(15, 12, 30, 0.7)" : tokens.colors.background.surface,
126
- borderRight: `1px solid ${tokens.colors.border.muted}`,
127
- transition: "width 0.3s cubic-bezier(0.22, 1, 0.36, 1), transform 0.25s ease",
128
- overflowX: "hidden",
129
- overflowY: "auto",
130
- flexShrink: 0,
131
- fontFamily: tokens.typography.fontFamily.primary,
132
- ...isTransparentTheme ? {
133
- backdropFilter: "blur(16px)",
134
- WebkitBackdropFilter: "blur(16px)"
135
- } : {},
136
- ...style
137
- };
138
- const contextValue = { collapsed: isCollapsed, mobileOpen, mode: effectiveMode, density, showCollapseToggle, setMobileOpen, toggleCollapse: handleToggleCollapse };
139
- if (isMobile) {
140
- return /* @__PURE__ */ jsxs(SideNavContext.Provider, { value: contextValue, children: [
141
- /* @__PURE__ */ jsx(
142
- "button",
143
- {
144
- "aria-label": "Open navigation",
145
- onClick: () => setMobileOpen(true),
146
- style: {
147
- position: "fixed",
148
- top: 6,
149
- left: 6,
150
- zIndex: 1001,
151
- display: "flex",
152
- alignItems: "center",
153
- justifyContent: "center",
154
- width: 32,
155
- height: 32,
156
- border: "none",
157
- borderRadius: tokens.borderRadius.sm,
158
- backgroundColor: "transparent",
159
- color: tokens.colors.text.primary,
160
- cursor: "pointer",
161
- padding: 0,
162
- transition: tokens.animation.fast
163
- },
164
- children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: [
165
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
166
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
167
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
168
- ] })
169
- }
170
- ),
171
- /* @__PURE__ */ jsx(
172
- "div",
173
- {
174
- "aria-hidden": "true",
175
- style: {
176
- position: "fixed",
177
- inset: 0,
178
- zIndex: 1002,
179
- backgroundColor: `${tokens.colors.background.base}99`,
180
- backdropFilter: "blur(4px)",
181
- opacity: mobileOpen ? 1 : 0,
182
- pointerEvents: mobileOpen ? "auto" : "none",
183
- transition: "opacity 0.25s ease"
184
- },
185
- onClick: () => setMobileOpen(false)
186
- }
187
- ),
188
- /* @__PURE__ */ jsx(
189
- "nav",
190
- {
191
- role: "navigation",
192
- "aria-label": "Main navigation",
193
- style: {
194
- ...navStyle,
195
- position: "fixed",
196
- top: 0,
197
- left: 0,
198
- zIndex: 1003,
199
- transform: mobileOpen ? "translateX(0)" : "translateX(-100%)",
200
- boxShadow: mobileOpen ? tokens.shadows.xl : "none"
201
- },
202
- children
203
- }
204
- )
205
- ] });
206
- }
207
- return /* @__PURE__ */ jsx(SideNavContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("nav", { role: "navigation", "aria-label": "Main navigation", style: navStyle, children }) });
164
+ var SideNavRoot = memo(function SideNav({ collapsed, onCollapsedChange, showCollapseToggle = true, width = 260, collapsedWidth = 64, density = "default", mobileVariant = "drawer", children, style }) {
165
+ const { tokens, theme } = useTheme();
166
+ const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
167
+ const [mobileOpen, setMobileOpen] = useState(false);
168
+ const [userCollapsed, setUserCollapsed] = useState(null);
169
+ const [viewMode, setViewMode] = useState("desktop");
170
+ useIsomorphicLayoutEffect(() => {
171
+ if (typeof window === "undefined") return;
172
+ setViewMode(getSideNavMode(window.innerWidth));
173
+ let rafId;
174
+ const handleResize = () => {
175
+ cancelAnimationFrame(rafId);
176
+ rafId = requestAnimationFrame(() => setViewMode(getSideNavMode(window.innerWidth)));
177
+ };
178
+ window.addEventListener("resize", handleResize, { passive: true });
179
+ return () => {
180
+ window.removeEventListener("resize", handleResize);
181
+ cancelAnimationFrame(rafId);
182
+ };
183
+ }, []);
184
+ useIsomorphicLayoutEffect(() => {
185
+ ensureSideNavReveal();
186
+ }, []);
187
+ const effectiveMode = mobileVariant === "collapsed" && viewMode === "mobile" ? "tablet" : viewMode;
188
+ useEffect(() => {
189
+ setUserCollapsed(null);
190
+ }, [effectiveMode]);
191
+ useEffect(() => {
192
+ if (effectiveMode !== "mobile" && mobileOpen) setMobileOpen(false);
193
+ }, [effectiveMode, mobileOpen]);
194
+ useEffect(() => {
195
+ if (!mobileOpen) return;
196
+ const handleEsc = (e) => {
197
+ if (e.key === "Escape") setMobileOpen(false);
198
+ };
199
+ document.addEventListener("keydown", handleEsc);
200
+ return () => document.removeEventListener("keydown", handleEsc);
201
+ }, [mobileOpen]);
202
+ const isCollapsed = collapsed !== void 0 ? collapsed : userCollapsed !== null ? userCollapsed : effectiveMode === "tablet";
203
+ const isMobile = effectiveMode === "mobile";
204
+ const navWidth = isCollapsed ? collapsedWidth : width;
205
+ const handleToggleCollapse = useCallback(() => {
206
+ const next = !isCollapsed;
207
+ setUserCollapsed(next);
208
+ onCollapsedChange?.(next);
209
+ }, [isCollapsed, onCollapsedChange]);
210
+ const navStyle = {
211
+ display: "flex",
212
+ flexDirection: "column",
213
+ width: isMobile ? 280 : navWidth,
214
+ height: "100%",
215
+ backgroundColor: isTransparentTheme ? "rgba(15, 12, 30, 0.7)" : tokens.colors.background.surface,
216
+ borderRight: `1px solid ${tokens.colors.border.muted}`,
217
+ transition: "width 0.3s cubic-bezier(0.22, 1, 0.36, 1), transform 0.25s ease",
218
+ overflowX: "hidden",
219
+ overflowY: "auto",
220
+ flexShrink: 0,
221
+ fontFamily: tokens.typography.fontFamily.primary,
222
+ ...isTransparentTheme ? {
223
+ backdropFilter: "blur(16px)",
224
+ WebkitBackdropFilter: "blur(16px)"
225
+ } : {},
226
+ ...style
227
+ };
228
+ const contextValue = {
229
+ collapsed: isCollapsed,
230
+ mobileOpen,
231
+ mode: effectiveMode,
232
+ density,
233
+ showCollapseToggle,
234
+ setMobileOpen,
235
+ toggleCollapse: handleToggleCollapse
236
+ };
237
+ if (isMobile) return /* @__PURE__ */ jsxs(SideNavContext.Provider, {
238
+ value: contextValue,
239
+ children: [
240
+ /* @__PURE__ */ jsx("button", {
241
+ "aria-label": "Open navigation",
242
+ onClick: () => setMobileOpen(true),
243
+ style: {
244
+ position: "fixed",
245
+ top: 6,
246
+ left: 6,
247
+ zIndex: 1001,
248
+ display: "flex",
249
+ alignItems: "center",
250
+ justifyContent: "center",
251
+ width: 32,
252
+ height: 32,
253
+ border: "none",
254
+ borderRadius: tokens.borderRadius.sm,
255
+ backgroundColor: "transparent",
256
+ color: tokens.colors.text.primary,
257
+ cursor: "pointer",
258
+ padding: 0,
259
+ transition: tokens.animation.fast
260
+ },
261
+ children: /* @__PURE__ */ jsxs("svg", {
262
+ width: "18",
263
+ height: "18",
264
+ viewBox: "0 0 24 24",
265
+ fill: "none",
266
+ stroke: "currentColor",
267
+ strokeWidth: "2.5",
268
+ strokeLinecap: "round",
269
+ children: [
270
+ /* @__PURE__ */ jsx("line", {
271
+ x1: "3",
272
+ y1: "6",
273
+ x2: "21",
274
+ y2: "6"
275
+ }),
276
+ /* @__PURE__ */ jsx("line", {
277
+ x1: "3",
278
+ y1: "12",
279
+ x2: "21",
280
+ y2: "12"
281
+ }),
282
+ /* @__PURE__ */ jsx("line", {
283
+ x1: "3",
284
+ y1: "18",
285
+ x2: "21",
286
+ y2: "18"
287
+ })
288
+ ]
289
+ })
290
+ }),
291
+ /* @__PURE__ */ jsx("div", {
292
+ "aria-hidden": "true",
293
+ style: {
294
+ position: "fixed",
295
+ inset: 0,
296
+ zIndex: 1002,
297
+ backgroundColor: `${tokens.colors.background.base}99`,
298
+ backdropFilter: "blur(4px)",
299
+ opacity: mobileOpen ? 1 : 0,
300
+ pointerEvents: mobileOpen ? "auto" : "none",
301
+ transition: "opacity 0.25s ease"
302
+ },
303
+ onClick: () => setMobileOpen(false)
304
+ }),
305
+ /* @__PURE__ */ jsx("nav", {
306
+ role: "navigation",
307
+ "aria-label": "Main navigation",
308
+ style: {
309
+ ...navStyle,
310
+ position: "fixed",
311
+ top: 0,
312
+ left: 0,
313
+ zIndex: 1003,
314
+ transform: mobileOpen ? "translateX(0)" : "translateX(-100%)",
315
+ boxShadow: mobileOpen ? tokens.shadows.xl : "none"
316
+ },
317
+ children
318
+ })
319
+ ]
320
+ });
321
+ return /* @__PURE__ */ jsx(SideNavContext.Provider, {
322
+ value: contextValue,
323
+ children: /* @__PURE__ */ jsx("nav", {
324
+ role: "navigation",
325
+ "aria-label": "Main navigation",
326
+ style: navStyle,
327
+ children
328
+ })
329
+ });
208
330
  });
209
- const SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX = 44;
331
+ /** Default height for the logo row so dashboard / operator / other apps align the same mark. */
332
+ var SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX = 44;
333
+ /** Chevron toggle button for collapsing/expanding the sidebar. */
210
334
  function CollapseToggleButton() {
211
- const { tokens } = useTheme();
212
- const { collapsed, toggleCollapse } = useContext(SideNavContext);
213
- const [hovered, setHovered] = useState(false);
214
- return /* @__PURE__ */ jsx(
215
- "button",
216
- {
217
- type: "button",
218
- "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
219
- onClick: toggleCollapse,
220
- onMouseEnter: () => setHovered(true),
221
- onMouseLeave: () => setHovered(false),
222
- style: {
223
- display: "flex",
224
- alignItems: "center",
225
- justifyContent: "center",
226
- width: 28,
227
- height: 28,
228
- border: `1px solid ${hovered ? tokens.colors.border.focus : tokens.colors.border.muted}`,
229
- borderRadius: tokens.borderRadius.md,
230
- backgroundColor: hovered ? `${tokens.colors.accent.primary}15` : "transparent",
231
- color: hovered ? tokens.colors.accent.primary : tokens.colors.text.tertiary,
232
- cursor: "pointer",
233
- flexShrink: 0,
234
- padding: 0,
235
- transition: tokens.animation.fast,
236
- outline: "none"
237
- },
238
- children: /* @__PURE__ */ jsx(
239
- "svg",
240
- {
241
- width: "14",
242
- height: "14",
243
- viewBox: "0 0 24 24",
244
- fill: "none",
245
- stroke: "currentColor",
246
- strokeWidth: "2",
247
- strokeLinecap: "round",
248
- strokeLinejoin: "round",
249
- style: {
250
- transition: "transform 0.25s ease",
251
- transform: collapsed ? "rotate(180deg)" : "rotate(0deg)"
252
- },
253
- children: /* @__PURE__ */ jsx("polyline", { points: "15 18 9 12 15 6" })
254
- }
255
- )
256
- }
257
- );
335
+ const { tokens } = useTheme();
336
+ const { collapsed, toggleCollapse } = useContext(SideNavContext);
337
+ const [hovered, setHovered] = useState(false);
338
+ return /* @__PURE__ */ jsx("button", {
339
+ type: "button",
340
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
341
+ onClick: toggleCollapse,
342
+ onMouseEnter: () => setHovered(true),
343
+ onMouseLeave: () => setHovered(false),
344
+ style: {
345
+ display: "flex",
346
+ alignItems: "center",
347
+ justifyContent: "center",
348
+ width: 28,
349
+ height: 28,
350
+ border: `1px solid ${hovered ? tokens.colors.border.focus : tokens.colors.border.muted}`,
351
+ borderRadius: tokens.borderRadius.md,
352
+ backgroundColor: hovered ? `${tokens.colors.accent.primary}15` : "transparent",
353
+ color: hovered ? tokens.colors.accent.primary : tokens.colors.text.tertiary,
354
+ cursor: "pointer",
355
+ flexShrink: 0,
356
+ padding: 0,
357
+ transition: tokens.animation.fast,
358
+ outline: "none"
359
+ },
360
+ children: /* @__PURE__ */ jsx("svg", {
361
+ width: "14",
362
+ height: "14",
363
+ viewBox: "0 0 24 24",
364
+ fill: "none",
365
+ stroke: "currentColor",
366
+ strokeWidth: "2",
367
+ strokeLinecap: "round",
368
+ strokeLinejoin: "round",
369
+ style: {
370
+ transition: "transform 0.25s ease",
371
+ transform: collapsed ? "rotate(180deg)" : "rotate(0deg)"
372
+ },
373
+ children: /* @__PURE__ */ jsx("polyline", { points: "15 18 9 12 15 6" })
374
+ })
375
+ });
258
376
  }
259
- const SideNavHeader = memo(function SideNavHeader2({
260
- logo,
261
- collapsedLogo,
262
- title,
263
- subtitle,
264
- badge,
265
- badgeVariant = "info",
266
- logoSlotHeight = SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
267
- children
268
- }) {
269
- const { tokens } = useTheme();
270
- const { collapsed, mode, showCollapseToggle, toggleCollapse } = useContext(SideNavContext);
271
- const displayLogo = collapsed && collapsedLogo ? collapsedLogo : logo;
272
- const showToggle = showCollapseToggle && mode !== "mobile";
273
- const hasMeta = Boolean(title || subtitle || badge);
274
- const slotH = logoSlotHeight;
275
- const badgeColors = {
276
- info: tokens.colors.accent.primary,
277
- success: tokens.colors.status.normal,
278
- warning: tokens.colors.status.caution,
279
- caution: tokens.colors.status.serious
280
- };
281
- const metaBlock = !collapsed && hasMeta ? /* @__PURE__ */ jsxs("div", { className: "zsn-reveal", style: { flex: 1, minWidth: 0, width: "100%" }, children: [
282
- title ? /* @__PURE__ */ jsx("div", { style: {
283
- fontSize: tokens.typography.fontSize.sm,
284
- fontWeight: tokens.typography.fontWeight.bold,
285
- color: tokens.colors.text.primary,
286
- lineHeight: tokens.typography.lineHeight.tight,
287
- whiteSpace: "nowrap",
288
- overflow: "hidden",
289
- textOverflow: "ellipsis"
290
- }, children: title }) : null,
291
- subtitle || badge ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs, marginTop: title ? "2px" : 0, flexWrap: "wrap" }, children: [
292
- subtitle ? /* @__PURE__ */ jsx("span", { style: {
293
- fontSize: tokens.typography.fontSize.xxs,
294
- color: tokens.colors.text.tertiary
295
- }, children: subtitle }) : null,
296
- badge ? /* @__PURE__ */ jsx("span", { style: {
297
- fontSize: "0.6rem",
298
- fontWeight: tokens.typography.fontWeight.bold,
299
- color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),
300
- backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,
301
- border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,
302
- padding: "1px 6px",
303
- borderRadius: tokens.borderRadius.sm,
304
- textTransform: "uppercase",
305
- letterSpacing: "0.05em"
306
- }, children: badge }) : null
307
- ] }) : null
308
- ] }) : null;
309
- const logoSlot = displayLogo ? /* @__PURE__ */ jsx(
310
- "div",
311
- {
312
- style: {
313
- height: slotH,
314
- minHeight: slotH,
315
- maxHeight: slotH,
316
- width: "100%",
317
- display: "flex",
318
- alignItems: "center",
319
- justifyContent: collapsed ? "center" : "flex-start",
320
- overflow: "hidden",
321
- boxSizing: "border-box",
322
- marginBottom: !collapsed && hasMeta && displayLogo ? tokens.spacing.sm : 0
323
- },
324
- children: /* @__PURE__ */ jsx(
325
- "div",
326
- {
327
- style: {
328
- maxHeight: "100%",
329
- maxWidth: "100%",
330
- display: "flex",
331
- alignItems: "center",
332
- justifyContent: collapsed ? "center" : "flex-start",
333
- minWidth: 0,
334
- cursor: collapsed && showToggle ? "pointer" : void 0
335
- },
336
- onClick: collapsed && showToggle ? toggleCollapse : void 0,
337
- children: displayLogo
338
- }
339
- )
340
- }
341
- ) : null;
342
- if (children) {
343
- return /* @__PURE__ */ jsx("div", { style: {
344
- padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
345
- borderBottom: `1px solid ${tokens.colors.border.muted}`,
346
- flexShrink: 0,
347
- boxSizing: "border-box",
348
- position: "relative"
349
- }, children });
350
- }
351
- if (collapsed) {
352
- return /* @__PURE__ */ jsxs("div", { style: {
353
- display: "flex",
354
- flexDirection: "column",
355
- alignItems: "center",
356
- padding: `${tokens.spacing.md} ${tokens.spacing.sm}`,
357
- minHeight: slotH + 24,
358
- borderBottom: `1px solid ${tokens.colors.border.muted}`,
359
- flexShrink: 0,
360
- boxSizing: "border-box",
361
- position: "relative",
362
- justifyContent: "center"
363
- }, children: [
364
- logoSlot,
365
- showToggle ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", right: 4, top: "50%", transform: "translateY(-50%)" }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : null
366
- ] });
367
- }
368
- return /* @__PURE__ */ jsxs("div", { style: {
369
- display: "flex",
370
- flexDirection: "column",
371
- alignItems: "stretch",
372
- padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
373
- borderBottom: `1px solid ${tokens.colors.border.muted}`,
374
- flexShrink: 0,
375
- boxSizing: "border-box",
376
- position: "relative"
377
- }, children: [
378
- showToggle ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", top: tokens.spacing.sm, right: tokens.spacing.sm, zIndex: 1 }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : null,
379
- /* @__PURE__ */ jsxs("div", { style: { paddingRight: showToggle ? 36 : 0, width: "100%", minWidth: 0 }, children: [
380
- logoSlot,
381
- metaBlock
382
- ] })
383
- ] });
377
+ var SideNavHeader = memo(function SideNavHeader({ logo, collapsedLogo, title, subtitle, badge, badgeVariant = "info", logoSlotHeight = 44, children }) {
378
+ const { tokens } = useTheme();
379
+ const { collapsed, mode, showCollapseToggle, toggleCollapse } = useContext(SideNavContext);
380
+ const displayLogo = collapsed && collapsedLogo ? collapsedLogo : logo;
381
+ const showToggle = showCollapseToggle && mode !== "mobile";
382
+ const hasMeta = Boolean(title || subtitle || badge);
383
+ const slotH = logoSlotHeight;
384
+ const badgeColors = {
385
+ info: tokens.colors.accent.primary,
386
+ success: tokens.colors.status.normal,
387
+ warning: tokens.colors.status.caution,
388
+ caution: tokens.colors.status.serious
389
+ };
390
+ const metaBlock = !collapsed && hasMeta ? /* @__PURE__ */ jsxs("div", {
391
+ className: "zsn-reveal",
392
+ style: {
393
+ flex: 1,
394
+ minWidth: 0,
395
+ width: "100%"
396
+ },
397
+ children: [title ? /* @__PURE__ */ jsx("div", {
398
+ style: {
399
+ fontSize: tokens.typography.fontSize.sm,
400
+ fontWeight: tokens.typography.fontWeight.bold,
401
+ color: tokens.colors.text.primary,
402
+ lineHeight: tokens.typography.lineHeight.tight,
403
+ whiteSpace: "nowrap",
404
+ overflow: "hidden",
405
+ textOverflow: "ellipsis"
406
+ },
407
+ children: title
408
+ }) : null, subtitle || badge ? /* @__PURE__ */ jsxs("div", {
409
+ style: {
410
+ display: "flex",
411
+ alignItems: "center",
412
+ gap: tokens.spacing.xs,
413
+ marginTop: title ? "2px" : 0,
414
+ flexWrap: "wrap"
415
+ },
416
+ children: [subtitle ? /* @__PURE__ */ jsx("span", {
417
+ style: {
418
+ fontSize: tokens.typography.fontSize.xxs,
419
+ color: tokens.colors.text.tertiary
420
+ },
421
+ children: subtitle
422
+ }) : null, badge ? /* @__PURE__ */ jsx("span", {
423
+ style: {
424
+ fontSize: "0.6rem",
425
+ fontWeight: tokens.typography.fontWeight.bold,
426
+ color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),
427
+ backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,
428
+ border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,
429
+ padding: "1px 6px",
430
+ borderRadius: tokens.borderRadius.sm,
431
+ textTransform: "uppercase",
432
+ letterSpacing: "0.05em"
433
+ },
434
+ children: badge
435
+ }) : null]
436
+ }) : null]
437
+ }) : null;
438
+ const logoSlot = displayLogo ? /* @__PURE__ */ jsx("div", {
439
+ style: {
440
+ height: slotH,
441
+ minHeight: slotH,
442
+ maxHeight: slotH,
443
+ width: "100%",
444
+ display: "flex",
445
+ alignItems: "center",
446
+ justifyContent: collapsed ? "center" : "flex-start",
447
+ overflow: "hidden",
448
+ boxSizing: "border-box",
449
+ marginBottom: !collapsed && hasMeta && displayLogo ? tokens.spacing.sm : 0
450
+ },
451
+ children: /* @__PURE__ */ jsx("div", {
452
+ style: {
453
+ maxHeight: "100%",
454
+ maxWidth: "100%",
455
+ display: "flex",
456
+ alignItems: "center",
457
+ justifyContent: collapsed ? "center" : "flex-start",
458
+ minWidth: 0,
459
+ cursor: collapsed && showToggle ? "pointer" : void 0
460
+ },
461
+ onClick: collapsed && showToggle ? toggleCollapse : void 0,
462
+ children: displayLogo
463
+ })
464
+ }) : null;
465
+ if (children) return /* @__PURE__ */ jsx("div", {
466
+ style: {
467
+ padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
468
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
469
+ flexShrink: 0,
470
+ boxSizing: "border-box",
471
+ position: "relative"
472
+ },
473
+ children
474
+ });
475
+ if (collapsed) return /* @__PURE__ */ jsxs("div", {
476
+ style: {
477
+ display: "flex",
478
+ flexDirection: "column",
479
+ alignItems: "center",
480
+ padding: `${tokens.spacing.md} ${tokens.spacing.sm}`,
481
+ minHeight: slotH + 24,
482
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
483
+ flexShrink: 0,
484
+ boxSizing: "border-box",
485
+ position: "relative",
486
+ justifyContent: "center"
487
+ },
488
+ children: [logoSlot, showToggle ? /* @__PURE__ */ jsx("div", {
489
+ style: {
490
+ position: "absolute",
491
+ right: 4,
492
+ top: "50%",
493
+ transform: "translateY(-50%)"
494
+ },
495
+ children: /* @__PURE__ */ jsx(CollapseToggleButton, {})
496
+ }) : null]
497
+ });
498
+ return /* @__PURE__ */ jsxs("div", {
499
+ style: {
500
+ display: "flex",
501
+ flexDirection: "column",
502
+ alignItems: "stretch",
503
+ padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
504
+ borderBottom: `1px solid ${tokens.colors.border.muted}`,
505
+ flexShrink: 0,
506
+ boxSizing: "border-box",
507
+ position: "relative"
508
+ },
509
+ children: [showToggle ? /* @__PURE__ */ jsx("div", {
510
+ style: {
511
+ position: "absolute",
512
+ top: tokens.spacing.sm,
513
+ right: tokens.spacing.sm,
514
+ zIndex: 1
515
+ },
516
+ children: /* @__PURE__ */ jsx(CollapseToggleButton, {})
517
+ }) : null, /* @__PURE__ */ jsxs("div", {
518
+ style: {
519
+ paddingRight: showToggle ? 36 : 0,
520
+ width: "100%",
521
+ minWidth: 0
522
+ },
523
+ children: [logoSlot, metaBlock]
524
+ })]
525
+ });
384
526
  });
385
- const TAG_COLORS = {
386
- default: { bg: "#ffffff10", fg: "#9590a8", border: "#ffffff15" },
387
- info: { bg: "#8a2be218", fg: "#c4a0ff", border: "#8a2be230" },
388
- success: { bg: "#56f00018", fg: "#56f000", border: "#56f00030" },
389
- warning: { bg: "#fce83a18", fg: "#fce83a", border: "#fce83a30" },
390
- danger: { bg: "#ff383818", fg: "#ff3838", border: "#ff383830" }
527
+ var TAG_COLORS = {
528
+ default: {
529
+ bg: "#ffffff10",
530
+ fg: "#9590a8",
531
+ border: "#ffffff15"
532
+ },
533
+ info: {
534
+ bg: "#8a2be218",
535
+ fg: "#c4a0ff",
536
+ border: "#8a2be230"
537
+ },
538
+ success: {
539
+ bg: "#56f00018",
540
+ fg: "#56f000",
541
+ border: "#56f00030"
542
+ },
543
+ warning: {
544
+ bg: "#fce83a18",
545
+ fg: "#fce83a",
546
+ border: "#fce83a30"
547
+ },
548
+ danger: {
549
+ bg: "#ff383818",
550
+ fg: "#ff3838",
551
+ border: "#ff383830"
552
+ }
391
553
  };
392
- const SideNavItem = memo(function SideNavItem2({
393
- icon,
394
- label,
395
- description,
396
- tag,
397
- tagVariant = "default",
398
- href,
399
- onClick,
400
- active = false,
401
- disabled = false,
402
- badge,
403
- external = false,
404
- status,
405
- statusLabel,
406
- suffix
407
- }) {
408
- const { tokens } = useTheme();
409
- const { collapsed, setMobileOpen, density } = useContext(SideNavContext);
410
- const compact = density === "compact" && !collapsed;
411
- const [isHovered, setIsHovered] = useState(false);
412
- const handleClick = useCallback((e) => {
413
- if (disabled) return;
414
- if (onClick && href && !e.metaKey && !e.ctrlKey && !e.shiftKey) {
415
- e.preventDefault();
416
- }
417
- setMobileOpen(false);
418
- onClick == null ? void 0 : onClick();
419
- }, [disabled, onClick, href, setMobileOpen]);
420
- const statusColor = status ? SIDENAV_STATUS_COLORS[status] ?? void 0 : void 0;
421
- const accentColor = statusColor && active ? statusColor : safeAccentText(tokens.colors.accent.primary);
422
- const hasDescription = !!description && !collapsed;
423
- const iconElement = typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: hasDescription ? 22 : 20, color: active ? accentColor : tokens.colors.text.secondary }) : icon;
424
- const itemStyle = {
425
- display: "flex",
426
- alignItems: hasDescription ? "flex-start" : "center",
427
- gap: tokens.spacing.sm,
428
- // Collapsed keeps the SAME 12px left inset as the expanded row, so the
429
- // icon holds its horizontal position when the rail expands — it doesn't
430
- // jump from a centered slot to a left-aligned one. Size the collapsed
431
- // width so that fixed inset reads as centered.
432
- padding: collapsed ? `${tokens.spacing.sm} 12px` : compact ? "7px 8px" : hasDescription ? `10px 16px 10px 12px` : `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 12px`,
433
- // Compact: pill-style rounded row (mock parity). Default: square row.
434
- borderRadius: compact ? tokens.borderRadius.md : 0,
435
- justifyContent: "flex-start",
436
- color: active ? accentColor : disabled ? tokens.colors.text.tertiary : tokens.colors.text.secondary,
437
- backgroundColor: active ? `${accentColor}12` : isHovered && !disabled ? `${accentColor}08` : "transparent",
438
- fontSize: compact ? tokens.typography.fontSize.xs : tokens.typography.fontSize.sm,
439
- fontWeight: active ? tokens.typography.fontWeight.semibold : tokens.typography.fontWeight.normal,
440
- fontFamily: tokens.typography.fontFamily.primary,
441
- cursor: disabled ? "not-allowed" : "pointer",
442
- textDecoration: "none",
443
- borderTop: "none",
444
- borderRight: "none",
445
- borderBottom: "none",
446
- // Compact drops the left accent bar — the active row is conveyed by the
447
- // bg tint + accent text alone (mock parity). Default keeps the 3px bar.
448
- borderLeft: compact ? "none" : active ? `3px solid ${accentColor}` : "3px solid transparent",
449
- outline: "none",
450
- width: "100%",
451
- boxSizing: "border-box",
452
- transition: tokens.animation.fast,
453
- position: "relative",
454
- opacity: disabled ? 0.5 : 1
455
- };
456
- const tagColors = TAG_COLORS[tagVariant] ?? TAG_COLORS.default;
457
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
458
- iconElement && /* @__PURE__ */ jsxs("span", { style: { flexShrink: 0, display: "flex", position: "relative", marginTop: hasDescription ? "2px" : 0 }, children: [
459
- iconElement,
460
- collapsed && status && /* @__PURE__ */ jsx(
461
- "span",
462
- {
463
- style: {
464
- position: "absolute",
465
- top: -3,
466
- left: -4,
467
- lineHeight: 0
468
- },
469
- title: statusLabel ?? status,
470
- children: /* @__PURE__ */ jsx(NavStatusShape, { status, size: 7 })
471
- }
472
- )
473
- ] }),
474
- /* @__PURE__ */ jsxs(
475
- "span",
476
- {
477
- className: "zsn-label",
478
- "data-collapsed": collapsed ? "true" : "false",
479
- style: { flex: 1, minWidth: 0, overflow: "hidden" },
480
- children: [
481
- /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
482
- /* @__PURE__ */ jsx("span", { style: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: label }),
483
- tag && /* @__PURE__ */ jsx("span", { style: {
484
- fontSize: "0.6rem",
485
- fontWeight: tokens.typography.fontWeight.bold,
486
- color: tagColors.fg,
487
- backgroundColor: tagColors.bg,
488
- border: `1px solid ${tagColors.border}`,
489
- padding: "1px 5px",
490
- borderRadius: tokens.borderRadius.sm,
491
- textTransform: "uppercase",
492
- letterSpacing: "0.04em",
493
- flexShrink: 0,
494
- lineHeight: "1.3",
495
- whiteSpace: "nowrap"
496
- }, children: tag })
497
- ] }),
498
- description && !collapsed && /* @__PURE__ */ jsx("span", { style: {
499
- display: "block",
500
- fontSize: tokens.typography.fontSize.xxs,
501
- color: tokens.colors.text.tertiary,
502
- lineHeight: tokens.typography.lineHeight.normal,
503
- marginTop: "2px",
504
- whiteSpace: "nowrap",
505
- overflow: "hidden",
506
- textOverflow: "ellipsis",
507
- fontWeight: tokens.typography.fontWeight.normal
508
- }, children: description })
509
- ]
510
- }
511
- ),
512
- !collapsed && (badge !== void 0 && badge > 0 || status || suffix || external) && /* @__PURE__ */ jsxs("span", { className: "zsn-reveal", style: {
513
- display: "inline-flex",
514
- alignItems: "center",
515
- gap: 8,
516
- flexShrink: 0,
517
- marginTop: hasDescription ? "2px" : 0
518
- }, children: [
519
- badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx("span", { style: {
520
- fontSize: "0.65rem",
521
- fontWeight: tokens.typography.fontWeight.bold,
522
- color: "#fff",
523
- backgroundColor: tokens.colors.status.critical,
524
- borderRadius: tokens.borderRadius.full,
525
- minWidth: "18px",
526
- height: "18px",
527
- display: "inline-flex",
528
- alignItems: "center",
529
- justifyContent: "center",
530
- padding: "0 5px",
531
- flexShrink: 0,
532
- lineHeight: 1,
533
- boxSizing: "border-box"
534
- }, children: badge > 99 ? "99+" : badge }),
535
- status && /* @__PURE__ */ jsx(
536
- "span",
537
- {
538
- style: { display: "inline-flex", alignItems: "center", flexShrink: 0 },
539
- role: "status",
540
- "aria-label": `Status: ${statusLabel ?? status}`,
541
- title: statusLabel ?? status,
542
- children: /* @__PURE__ */ jsx(NavStatusShape, { status, size: 8 })
543
- }
544
- ),
545
- suffix && /* @__PURE__ */ jsx("span", { style: { flexShrink: 0, display: "inline-flex", alignItems: "center" }, children: suffix }),
546
- external && /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", style: { flexShrink: 0, opacity: 0.5 }, children: [
547
- /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
548
- /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
549
- /* @__PURE__ */ jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
550
- ] })
551
- ] })
552
- ] });
553
- const props = {
554
- style: itemStyle,
555
- onMouseEnter: () => setIsHovered(true),
556
- onMouseLeave: () => setIsHovered(false),
557
- title: collapsed ? label : void 0,
558
- "aria-current": active ? "page" : void 0,
559
- "aria-disabled": disabled
560
- };
561
- if (href && !disabled) {
562
- return /* @__PURE__ */ jsx("a", { href, onClick: handleClick, target: external ? "_blank" : void 0, rel: external ? "noopener noreferrer" : void 0, ...props, children: content });
563
- }
564
- return /* @__PURE__ */ jsx("button", { type: "button", onClick: handleClick, disabled, ...props, children: content });
554
+ var SideNavItem = memo(function SideNavItem({ icon, label, description, tag, tagVariant = "default", href, onClick, active = false, disabled = false, badge, external = false, status, statusLabel, suffix }) {
555
+ const { tokens } = useTheme();
556
+ const { collapsed, setMobileOpen, density } = useContext(SideNavContext);
557
+ const compact = density === "compact" && !collapsed;
558
+ const [isHovered, setIsHovered] = useState(false);
559
+ const handleClick = useCallback((e) => {
560
+ if (disabled) return;
561
+ if (onClick && href && !e.metaKey && !e.ctrlKey && !e.shiftKey) e.preventDefault();
562
+ setMobileOpen(false);
563
+ onClick?.();
564
+ }, [
565
+ disabled,
566
+ onClick,
567
+ href,
568
+ setMobileOpen
569
+ ]);
570
+ const statusColor = status ? tokens.colors.status[status] ?? void 0 : void 0;
571
+ const accentColor = statusColor && active ? statusColor : safeAccentText(tokens.colors.accent.primary);
572
+ const hasDescription = !!description && !collapsed;
573
+ const iconElement = typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, {
574
+ name: icon,
575
+ size: hasDescription ? 22 : 20,
576
+ color: active ? accentColor : tokens.colors.text.secondary
577
+ }) : icon;
578
+ const itemStyle = {
579
+ display: "flex",
580
+ alignItems: hasDescription ? "flex-start" : "center",
581
+ gap: tokens.spacing.sm,
582
+ padding: collapsed ? `${tokens.spacing.sm} 12px` : compact ? "7px 8px" : hasDescription ? `10px 16px 10px 12px` : `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 12px`,
583
+ borderRadius: compact ? tokens.borderRadius.md : 0,
584
+ justifyContent: "flex-start",
585
+ color: active ? accentColor : disabled ? tokens.colors.text.tertiary : tokens.colors.text.secondary,
586
+ backgroundColor: active ? `${accentColor}12` : isHovered && !disabled ? `${accentColor}08` : "transparent",
587
+ fontSize: compact ? tokens.typography.fontSize.xs : tokens.typography.fontSize.sm,
588
+ fontWeight: active ? tokens.typography.fontWeight.semibold : tokens.typography.fontWeight.normal,
589
+ fontFamily: tokens.typography.fontFamily.primary,
590
+ cursor: disabled ? "not-allowed" : "pointer",
591
+ textDecoration: "none",
592
+ borderTop: "none",
593
+ borderRight: "none",
594
+ borderBottom: "none",
595
+ borderLeft: compact ? "none" : active ? `3px solid ${accentColor}` : "3px solid transparent",
596
+ outline: "none",
597
+ width: "100%",
598
+ boxSizing: "border-box",
599
+ transition: tokens.animation.fast,
600
+ position: "relative",
601
+ opacity: disabled ? .5 : 1
602
+ };
603
+ const tagColors = TAG_COLORS[tagVariant] ?? TAG_COLORS.default;
604
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
605
+ iconElement && /* @__PURE__ */ jsxs("span", {
606
+ style: {
607
+ flexShrink: 0,
608
+ display: "flex",
609
+ position: "relative",
610
+ marginTop: hasDescription ? "2px" : 0
611
+ },
612
+ children: [iconElement, collapsed && status && /* @__PURE__ */ jsx("span", {
613
+ style: {
614
+ position: "absolute",
615
+ top: -3,
616
+ left: -4,
617
+ lineHeight: 0
618
+ },
619
+ title: statusLabel ?? status,
620
+ children: /* @__PURE__ */ jsx(NavStatusShape, {
621
+ status,
622
+ size: 7
623
+ })
624
+ })]
625
+ }),
626
+ /* @__PURE__ */ jsxs("span", {
627
+ className: "zsn-label",
628
+ "data-collapsed": collapsed ? "true" : "false",
629
+ style: {
630
+ flex: 1,
631
+ minWidth: 0,
632
+ overflow: "hidden"
633
+ },
634
+ children: [/* @__PURE__ */ jsxs("span", {
635
+ style: {
636
+ display: "flex",
637
+ alignItems: "center",
638
+ gap: 6
639
+ },
640
+ children: [/* @__PURE__ */ jsx("span", {
641
+ style: {
642
+ whiteSpace: "nowrap",
643
+ overflow: "hidden",
644
+ textOverflow: "ellipsis"
645
+ },
646
+ children: label
647
+ }), tag && /* @__PURE__ */ jsx("span", {
648
+ style: {
649
+ fontSize: "0.6rem",
650
+ fontWeight: tokens.typography.fontWeight.bold,
651
+ color: tagColors.fg,
652
+ backgroundColor: tagColors.bg,
653
+ border: `1px solid ${tagColors.border}`,
654
+ padding: "1px 5px",
655
+ borderRadius: tokens.borderRadius.sm,
656
+ textTransform: "uppercase",
657
+ letterSpacing: "0.04em",
658
+ flexShrink: 0,
659
+ lineHeight: "1.3",
660
+ whiteSpace: "nowrap"
661
+ },
662
+ children: tag
663
+ })]
664
+ }), description && !collapsed && /* @__PURE__ */ jsx("span", {
665
+ style: {
666
+ display: "block",
667
+ fontSize: tokens.typography.fontSize.xxs,
668
+ color: tokens.colors.text.tertiary,
669
+ lineHeight: tokens.typography.lineHeight.normal,
670
+ marginTop: "2px",
671
+ whiteSpace: "nowrap",
672
+ overflow: "hidden",
673
+ textOverflow: "ellipsis",
674
+ fontWeight: tokens.typography.fontWeight.normal
675
+ },
676
+ children: description
677
+ })]
678
+ }),
679
+ !collapsed && (badge !== void 0 && badge > 0 || status || suffix || external) && /* @__PURE__ */ jsxs("span", {
680
+ className: "zsn-reveal",
681
+ style: {
682
+ display: "inline-flex",
683
+ alignItems: "center",
684
+ gap: 8,
685
+ flexShrink: 0,
686
+ marginTop: hasDescription ? "2px" : 0
687
+ },
688
+ children: [
689
+ badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx("span", {
690
+ style: {
691
+ fontSize: "0.65rem",
692
+ fontWeight: tokens.typography.fontWeight.bold,
693
+ color: "#fff",
694
+ backgroundColor: tokens.colors.status.critical,
695
+ borderRadius: tokens.borderRadius.full,
696
+ minWidth: "18px",
697
+ height: "18px",
698
+ display: "inline-flex",
699
+ alignItems: "center",
700
+ justifyContent: "center",
701
+ padding: "0 5px",
702
+ flexShrink: 0,
703
+ lineHeight: 1,
704
+ boxSizing: "border-box"
705
+ },
706
+ children: badge > 99 ? "99+" : badge
707
+ }),
708
+ status && /* @__PURE__ */ jsx("span", {
709
+ style: {
710
+ display: "inline-flex",
711
+ alignItems: "center",
712
+ flexShrink: 0
713
+ },
714
+ role: "status",
715
+ "aria-label": `Status: ${statusLabel ?? status}`,
716
+ title: statusLabel ?? status,
717
+ children: /* @__PURE__ */ jsx(NavStatusShape, {
718
+ status,
719
+ size: 8
720
+ })
721
+ }),
722
+ suffix && /* @__PURE__ */ jsx("span", {
723
+ style: {
724
+ flexShrink: 0,
725
+ display: "inline-flex",
726
+ alignItems: "center"
727
+ },
728
+ children: suffix
729
+ }),
730
+ external && /* @__PURE__ */ jsxs("svg", {
731
+ width: "12",
732
+ height: "12",
733
+ viewBox: "0 0 24 24",
734
+ fill: "none",
735
+ stroke: "currentColor",
736
+ strokeWidth: "2",
737
+ strokeLinecap: "round",
738
+ style: {
739
+ flexShrink: 0,
740
+ opacity: .5
741
+ },
742
+ children: [
743
+ /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
744
+ /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
745
+ /* @__PURE__ */ jsx("line", {
746
+ x1: "10",
747
+ y1: "14",
748
+ x2: "21",
749
+ y2: "3"
750
+ })
751
+ ]
752
+ })
753
+ ]
754
+ })
755
+ ] });
756
+ const props = {
757
+ style: itemStyle,
758
+ onMouseEnter: () => setIsHovered(true),
759
+ onMouseLeave: () => setIsHovered(false),
760
+ title: collapsed ? label : void 0,
761
+ "aria-current": active ? "page" : void 0,
762
+ "aria-disabled": disabled
763
+ };
764
+ if (href && !disabled) return /* @__PURE__ */ jsx("a", {
765
+ href,
766
+ onClick: handleClick,
767
+ target: external ? "_blank" : void 0,
768
+ rel: external ? "noopener noreferrer" : void 0,
769
+ ...props,
770
+ children: content
771
+ });
772
+ return /* @__PURE__ */ jsx("button", {
773
+ type: "button",
774
+ onClick: handleClick,
775
+ disabled,
776
+ ...props,
777
+ children: content
778
+ });
565
779
  });
566
- const SideNavSection = memo(function SideNavSection2({
567
- title,
568
- children
569
- }) {
570
- const { tokens } = useTheme();
571
- const { collapsed } = useContext(SideNavContext);
572
- return /* @__PURE__ */ jsxs("div", { style: { marginTop: tokens.spacing.sm }, children: [
573
- title && !collapsed && /* @__PURE__ */ jsx("div", { className: "zsn-reveal", style: {
574
- padding: `${tokens.spacing.xs} 16px ${tokens.spacing.xs} 15px`,
575
- fontSize: tokens.typography.fontSize.xxs,
576
- fontWeight: tokens.typography.fontWeight.bold,
577
- color: tokens.colors.text.tertiary,
578
- textTransform: "uppercase",
579
- letterSpacing: "0.08em"
580
- }, children: title }),
581
- collapsed && title && /* @__PURE__ */ jsx("div", { style: {
582
- width: "60%",
583
- height: "1px",
584
- backgroundColor: tokens.colors.border.muted,
585
- margin: `${tokens.spacing.xs} auto`
586
- } }),
587
- children
588
- ] });
780
+ var SideNavSection = memo(function SideNavSection({ title, children }) {
781
+ const { tokens } = useTheme();
782
+ const { collapsed } = useContext(SideNavContext);
783
+ return /* @__PURE__ */ jsxs("div", {
784
+ style: { marginTop: tokens.spacing.sm },
785
+ children: [
786
+ title && !collapsed && /* @__PURE__ */ jsx("div", {
787
+ className: "zsn-reveal",
788
+ style: {
789
+ padding: `${tokens.spacing.xs} 16px ${tokens.spacing.xs} 15px`,
790
+ fontSize: tokens.typography.fontSize.xxs,
791
+ fontWeight: tokens.typography.fontWeight.bold,
792
+ color: tokens.colors.text.tertiary,
793
+ textTransform: "uppercase",
794
+ letterSpacing: "0.08em"
795
+ },
796
+ children: title
797
+ }),
798
+ collapsed && title && /* @__PURE__ */ jsx("div", { style: {
799
+ width: "60%",
800
+ height: "1px",
801
+ backgroundColor: tokens.colors.border.muted,
802
+ margin: `${tokens.spacing.xs} auto`
803
+ } }),
804
+ children
805
+ ]
806
+ });
589
807
  });
590
- const SideNavDivider = memo(function SideNavDivider2({
591
- label
592
- }) {
593
- const { tokens } = useTheme();
594
- const { collapsed } = useContext(SideNavContext);
595
- if (collapsed) {
596
- return /* @__PURE__ */ jsx("div", { style: {
597
- width: "60%",
598
- height: "1px",
599
- backgroundColor: tokens.colors.border.muted,
600
- margin: `${tokens.spacing.sm} auto`
601
- } });
602
- }
603
- if (label) {
604
- return /* @__PURE__ */ jsxs("div", { style: {
605
- display: "flex",
606
- alignItems: "center",
607
- gap: tokens.spacing.sm,
608
- padding: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`
609
- }, children: [
610
- /* @__PURE__ */ jsx("div", { style: { flex: 1, height: "1px", backgroundColor: tokens.colors.border.muted } }),
611
- /* @__PURE__ */ jsx("span", { style: {
612
- fontSize: tokens.typography.fontSize.xxs,
613
- color: tokens.colors.text.tertiary,
614
- textTransform: "uppercase",
615
- letterSpacing: "0.06em",
616
- whiteSpace: "nowrap"
617
- }, children: label }),
618
- /* @__PURE__ */ jsx("div", { style: { flex: 1, height: "1px", backgroundColor: tokens.colors.border.muted } })
619
- ] });
620
- }
621
- return /* @__PURE__ */ jsx("div", { style: {
622
- height: "1px",
623
- backgroundColor: tokens.colors.border.muted,
624
- margin: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`
625
- } });
808
+ var SideNavDivider = memo(function SideNavDivider({ label }) {
809
+ const { tokens } = useTheme();
810
+ const { collapsed } = useContext(SideNavContext);
811
+ if (collapsed) return /* @__PURE__ */ jsx("div", { style: {
812
+ width: "60%",
813
+ height: "1px",
814
+ backgroundColor: tokens.colors.border.muted,
815
+ margin: `${tokens.spacing.sm} auto`
816
+ } });
817
+ if (label) return /* @__PURE__ */ jsxs("div", {
818
+ style: {
819
+ display: "flex",
820
+ alignItems: "center",
821
+ gap: tokens.spacing.sm,
822
+ padding: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`
823
+ },
824
+ children: [
825
+ /* @__PURE__ */ jsx("div", { style: {
826
+ flex: 1,
827
+ height: "1px",
828
+ backgroundColor: tokens.colors.border.muted
829
+ } }),
830
+ /* @__PURE__ */ jsx("span", {
831
+ style: {
832
+ fontSize: tokens.typography.fontSize.xxs,
833
+ color: tokens.colors.text.tertiary,
834
+ textTransform: "uppercase",
835
+ letterSpacing: "0.06em",
836
+ whiteSpace: "nowrap"
837
+ },
838
+ children: label
839
+ }),
840
+ /* @__PURE__ */ jsx("div", { style: {
841
+ flex: 1,
842
+ height: "1px",
843
+ backgroundColor: tokens.colors.border.muted
844
+ } })
845
+ ]
846
+ });
847
+ return /* @__PURE__ */ jsx("div", { style: {
848
+ height: "1px",
849
+ backgroundColor: tokens.colors.border.muted,
850
+ margin: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`
851
+ } });
626
852
  });
627
- const SideNavFooter = memo(function SideNavFooter2({
628
- children
629
- }) {
630
- const { tokens } = useTheme();
631
- return /* @__PURE__ */ jsx("div", { style: {
632
- marginTop: "auto",
633
- borderTop: `1px solid ${tokens.colors.border.muted}`,
634
- paddingTop: tokens.spacing.xs,
635
- paddingBottom: tokens.spacing.xs
636
- }, children });
853
+ var SideNavFooter = memo(function SideNavFooter({ children }) {
854
+ const { tokens } = useTheme();
855
+ return /* @__PURE__ */ jsx("div", {
856
+ style: {
857
+ marginTop: "auto",
858
+ borderTop: `1px solid ${tokens.colors.border.muted}`,
859
+ paddingTop: tokens.spacing.xs,
860
+ paddingBottom: tokens.spacing.xs
861
+ },
862
+ children
863
+ });
637
864
  });
638
- const SideNav = Object.assign(SideNavRoot, {
639
- Header: SideNavHeader,
640
- Item: SideNavItem,
641
- Section: SideNavSection,
642
- Divider: SideNavDivider,
643
- Footer: SideNavFooter
865
+ var SideNav = Object.assign(SideNavRoot, {
866
+ Header: SideNavHeader,
867
+ Item: SideNavItem,
868
+ Section: SideNavSection,
869
+ Divider: SideNavDivider,
870
+ Footer: SideNavFooter
644
871
  });
645
- export {
646
- SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
647
- SideNav
648
- };
649
- //# sourceMappingURL=SideNav.js.map
872
+ //#endregion
873
+ export { SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, SideNav, SideNav as default };
874
+
875
+ //# sourceMappingURL=SideNav.js.map