@zendir/ui 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +34 -0
  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 -538
  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 +11 -5
  229. package/dist/react/core/navigation/SideNav.js +857 -602
  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 +312 -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 +217 -194
  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 +419 -41
  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,620 +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_STATUS_COLORS = {
8
- off: "#a4abb6",
9
- standby: "#2dccff",
10
- normal: "#56f000",
11
- caution: "#fce83a",
12
- serious: "#ffb302",
13
- critical: "#ff3838"
14
- };
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";
50
+ function ensureSideNavReveal() {
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);
57
+ }
58
+ /** Astro UX dual-coded status shape (color + geometry). */
15
59
  function NavStatusShape({ status, size = 8 }) {
16
- const color = SIDENAV_STATUS_COLORS[status] ?? SIDENAV_STATUS_COLORS.off;
17
- const glow = `${color}50`;
18
- const style = { flexShrink: 0, filter: `drop-shadow(0 0 3px ${glow})` };
19
- switch (status) {
20
- case "caution":
21
- 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 }) });
22
- case "serious":
23
- 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 }) });
24
- case "critical":
25
- 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 }) });
26
- case "standby":
27
- 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" }) });
28
- case "off":
29
- 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 }) });
30
- default:
31
- 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 }) });
32
- }
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
+ }
33
145
  }
34
- const SIDENAV_BREAKPOINTS = {
35
- mobile: 768,
36
- tablet: 1024
146
+ var SIDENAV_BREAKPOINTS = {
147
+ mobile: 768,
148
+ tablet: 1024
37
149
  };
38
150
  function getSideNavMode(width) {
39
- if (width < SIDENAV_BREAKPOINTS.mobile) return "mobile";
40
- if (width < SIDENAV_BREAKPOINTS.tablet) return "tablet";
41
- return "desktop";
151
+ if (width < SIDENAV_BREAKPOINTS.mobile) return "mobile";
152
+ if (width < SIDENAV_BREAKPOINTS.tablet) return "tablet";
153
+ return "desktop";
42
154
  }
43
- const SideNavContext = createContext({
44
- collapsed: false,
45
- mobileOpen: false,
46
- mode: "desktop",
47
- showCollapseToggle: true,
48
- setMobileOpen: () => {
49
- },
50
- toggleCollapse: () => {
51
- }
155
+ var SideNavContext = createContext({
156
+ collapsed: false,
157
+ mobileOpen: false,
158
+ mode: "desktop",
159
+ density: "default",
160
+ showCollapseToggle: true,
161
+ setMobileOpen: () => {},
162
+ toggleCollapse: () => {}
52
163
  });
53
- const SideNavRoot = memo(function SideNav2({
54
- collapsed,
55
- onCollapsedChange,
56
- showCollapseToggle = true,
57
- width = 260,
58
- collapsedWidth = 64,
59
- mobileVariant = "drawer",
60
- children,
61
- style
62
- }) {
63
- const { tokens, theme } = useTheme();
64
- const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
65
- const [mobileOpen, setMobileOpen] = useState(false);
66
- const [userCollapsed, setUserCollapsed] = useState(null);
67
- const [viewMode, setViewMode] = useState("desktop");
68
- useIsomorphicLayoutEffect(() => {
69
- if (typeof window === "undefined") return;
70
- setViewMode(getSideNavMode(window.innerWidth));
71
- let rafId;
72
- const handleResize = () => {
73
- cancelAnimationFrame(rafId);
74
- rafId = requestAnimationFrame(() => setViewMode(getSideNavMode(window.innerWidth)));
75
- };
76
- window.addEventListener("resize", handleResize, { passive: true });
77
- return () => {
78
- window.removeEventListener("resize", handleResize);
79
- cancelAnimationFrame(rafId);
80
- };
81
- }, []);
82
- const effectiveMode = mobileVariant === "collapsed" && viewMode === "mobile" ? "tablet" : viewMode;
83
- useEffect(() => {
84
- setUserCollapsed(null);
85
- }, [effectiveMode]);
86
- useEffect(() => {
87
- if (effectiveMode !== "mobile" && mobileOpen) setMobileOpen(false);
88
- }, [effectiveMode, mobileOpen]);
89
- useEffect(() => {
90
- if (!mobileOpen) return;
91
- const handleEsc = (e) => {
92
- if (e.key === "Escape") setMobileOpen(false);
93
- };
94
- document.addEventListener("keydown", handleEsc);
95
- return () => document.removeEventListener("keydown", handleEsc);
96
- }, [mobileOpen]);
97
- const autoCollapsed = effectiveMode === "tablet";
98
- const isCollapsed = collapsed !== void 0 ? collapsed : userCollapsed !== null ? userCollapsed : autoCollapsed;
99
- const isMobile = effectiveMode === "mobile";
100
- const navWidth = isCollapsed ? collapsedWidth : width;
101
- const handleToggleCollapse = useCallback(() => {
102
- const next = !isCollapsed;
103
- setUserCollapsed(next);
104
- onCollapsedChange == null ? void 0 : onCollapsedChange(next);
105
- }, [isCollapsed, onCollapsedChange]);
106
- const navStyle = {
107
- display: "flex",
108
- flexDirection: "column",
109
- width: isMobile ? 280 : navWidth,
110
- height: "100%",
111
- backgroundColor: isTransparentTheme ? "rgba(15, 12, 30, 0.7)" : tokens.colors.background.surface,
112
- borderRight: `1px solid ${tokens.colors.border.muted}`,
113
- transition: "width 0.25s ease, transform 0.25s ease",
114
- overflowX: "hidden",
115
- overflowY: "auto",
116
- flexShrink: 0,
117
- fontFamily: tokens.typography.fontFamily.primary,
118
- ...isTransparentTheme ? {
119
- backdropFilter: "blur(16px)",
120
- WebkitBackdropFilter: "blur(16px)"
121
- } : {},
122
- ...style
123
- };
124
- const contextValue = { collapsed: isCollapsed, mobileOpen, mode: effectiveMode, showCollapseToggle, setMobileOpen, toggleCollapse: handleToggleCollapse };
125
- if (isMobile) {
126
- return /* @__PURE__ */ jsxs(SideNavContext.Provider, { value: contextValue, children: [
127
- /* @__PURE__ */ jsx(
128
- "button",
129
- {
130
- "aria-label": "Open navigation",
131
- onClick: () => setMobileOpen(true),
132
- style: {
133
- position: "fixed",
134
- top: 6,
135
- left: 6,
136
- zIndex: 1001,
137
- display: "flex",
138
- alignItems: "center",
139
- justifyContent: "center",
140
- width: 32,
141
- height: 32,
142
- border: "none",
143
- borderRadius: tokens.borderRadius.sm,
144
- backgroundColor: "transparent",
145
- color: tokens.colors.text.primary,
146
- cursor: "pointer",
147
- padding: 0,
148
- transition: tokens.animation.fast
149
- },
150
- children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", children: [
151
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
152
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
153
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
154
- ] })
155
- }
156
- ),
157
- /* @__PURE__ */ jsx(
158
- "div",
159
- {
160
- "aria-hidden": "true",
161
- style: {
162
- position: "fixed",
163
- inset: 0,
164
- zIndex: 1002,
165
- backgroundColor: `${tokens.colors.background.base}99`,
166
- backdropFilter: "blur(4px)",
167
- opacity: mobileOpen ? 1 : 0,
168
- pointerEvents: mobileOpen ? "auto" : "none",
169
- transition: "opacity 0.25s ease"
170
- },
171
- onClick: () => setMobileOpen(false)
172
- }
173
- ),
174
- /* @__PURE__ */ jsx(
175
- "nav",
176
- {
177
- role: "navigation",
178
- "aria-label": "Main navigation",
179
- style: {
180
- ...navStyle,
181
- position: "fixed",
182
- top: 0,
183
- left: 0,
184
- zIndex: 1003,
185
- transform: mobileOpen ? "translateX(0)" : "translateX(-100%)",
186
- boxShadow: mobileOpen ? tokens.shadows.xl : "none"
187
- },
188
- children
189
- }
190
- )
191
- ] });
192
- }
193
- 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
+ });
194
330
  });
195
- 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. */
196
334
  function CollapseToggleButton() {
197
- const { tokens } = useTheme();
198
- const { collapsed, toggleCollapse } = useContext(SideNavContext);
199
- const [hovered, setHovered] = useState(false);
200
- return /* @__PURE__ */ jsx(
201
- "button",
202
- {
203
- type: "button",
204
- "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
205
- onClick: toggleCollapse,
206
- onMouseEnter: () => setHovered(true),
207
- onMouseLeave: () => setHovered(false),
208
- style: {
209
- display: "flex",
210
- alignItems: "center",
211
- justifyContent: "center",
212
- width: 28,
213
- height: 28,
214
- border: `1px solid ${hovered ? tokens.colors.border.focus : tokens.colors.border.muted}`,
215
- borderRadius: tokens.borderRadius.md,
216
- backgroundColor: hovered ? `${tokens.colors.accent.primary}15` : "transparent",
217
- color: hovered ? tokens.colors.accent.primary : tokens.colors.text.tertiary,
218
- cursor: "pointer",
219
- flexShrink: 0,
220
- padding: 0,
221
- transition: tokens.animation.fast,
222
- outline: "none"
223
- },
224
- children: /* @__PURE__ */ jsx(
225
- "svg",
226
- {
227
- width: "14",
228
- height: "14",
229
- viewBox: "0 0 24 24",
230
- fill: "none",
231
- stroke: "currentColor",
232
- strokeWidth: "2",
233
- strokeLinecap: "round",
234
- strokeLinejoin: "round",
235
- style: {
236
- transition: "transform 0.25s ease",
237
- transform: collapsed ? "rotate(180deg)" : "rotate(0deg)"
238
- },
239
- children: /* @__PURE__ */ jsx("polyline", { points: "15 18 9 12 15 6" })
240
- }
241
- )
242
- }
243
- );
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
+ });
244
376
  }
245
- const SideNavHeader = memo(function SideNavHeader2({
246
- logo,
247
- collapsedLogo,
248
- title,
249
- subtitle,
250
- badge,
251
- badgeVariant = "info",
252
- logoSlotHeight = SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
253
- children
254
- }) {
255
- const { tokens } = useTheme();
256
- const { collapsed, mode, showCollapseToggle, toggleCollapse } = useContext(SideNavContext);
257
- const displayLogo = collapsed && collapsedLogo ? collapsedLogo : logo;
258
- const showToggle = showCollapseToggle && mode !== "mobile";
259
- const hasMeta = Boolean(title || subtitle || badge);
260
- const slotH = logoSlotHeight;
261
- const badgeColors = {
262
- info: tokens.colors.accent.primary,
263
- success: tokens.colors.status.normal,
264
- warning: tokens.colors.status.caution,
265
- caution: tokens.colors.status.serious
266
- };
267
- const metaBlock = !collapsed && hasMeta ? /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, width: "100%" }, children: [
268
- title ? /* @__PURE__ */ jsx("div", { style: {
269
- fontSize: tokens.typography.fontSize.sm,
270
- fontWeight: tokens.typography.fontWeight.bold,
271
- color: tokens.colors.text.primary,
272
- lineHeight: tokens.typography.lineHeight.tight,
273
- whiteSpace: "nowrap",
274
- overflow: "hidden",
275
- textOverflow: "ellipsis"
276
- }, children: title }) : null,
277
- subtitle || badge ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs, marginTop: title ? "2px" : 0, flexWrap: "wrap" }, children: [
278
- subtitle ? /* @__PURE__ */ jsx("span", { style: {
279
- fontSize: tokens.typography.fontSize.xxs,
280
- color: tokens.colors.text.tertiary
281
- }, children: subtitle }) : null,
282
- badge ? /* @__PURE__ */ jsx("span", { style: {
283
- fontSize: "0.6rem",
284
- fontWeight: tokens.typography.fontWeight.bold,
285
- color: badgeColors[badgeVariant] || safeAccentText(tokens.colors.accent.primary),
286
- backgroundColor: `${badgeColors[badgeVariant] || tokens.colors.accent.primary}18`,
287
- border: `1px solid ${badgeColors[badgeVariant] || tokens.colors.accent.primary}30`,
288
- padding: "1px 6px",
289
- borderRadius: tokens.borderRadius.sm,
290
- textTransform: "uppercase",
291
- letterSpacing: "0.05em"
292
- }, children: badge }) : null
293
- ] }) : null
294
- ] }) : null;
295
- const logoSlot = displayLogo ? /* @__PURE__ */ jsx(
296
- "div",
297
- {
298
- style: {
299
- height: slotH,
300
- minHeight: slotH,
301
- maxHeight: slotH,
302
- width: "100%",
303
- display: "flex",
304
- alignItems: "center",
305
- justifyContent: collapsed ? "center" : "flex-start",
306
- overflow: "hidden",
307
- boxSizing: "border-box",
308
- marginBottom: !collapsed && hasMeta && displayLogo ? tokens.spacing.sm : 0
309
- },
310
- children: /* @__PURE__ */ jsx(
311
- "div",
312
- {
313
- style: {
314
- maxHeight: "100%",
315
- maxWidth: "100%",
316
- display: "flex",
317
- alignItems: "center",
318
- justifyContent: collapsed ? "center" : "flex-start",
319
- minWidth: 0,
320
- cursor: collapsed && showToggle ? "pointer" : void 0
321
- },
322
- onClick: collapsed && showToggle ? toggleCollapse : void 0,
323
- children: displayLogo
324
- }
325
- )
326
- }
327
- ) : null;
328
- if (children) {
329
- return /* @__PURE__ */ jsx("div", { style: {
330
- padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
331
- borderBottom: `1px solid ${tokens.colors.border.muted}`,
332
- flexShrink: 0,
333
- boxSizing: "border-box",
334
- position: "relative"
335
- }, children });
336
- }
337
- if (collapsed) {
338
- return /* @__PURE__ */ jsxs("div", { style: {
339
- display: "flex",
340
- flexDirection: "column",
341
- alignItems: "center",
342
- padding: `${tokens.spacing.md} ${tokens.spacing.sm}`,
343
- minHeight: slotH + 24,
344
- borderBottom: `1px solid ${tokens.colors.border.muted}`,
345
- flexShrink: 0,
346
- boxSizing: "border-box",
347
- position: "relative",
348
- justifyContent: "center"
349
- }, children: [
350
- logoSlot,
351
- showToggle ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", right: 4, top: "50%", transform: "translateY(-50%)" }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : null
352
- ] });
353
- }
354
- return /* @__PURE__ */ jsxs("div", { style: {
355
- display: "flex",
356
- flexDirection: "column",
357
- alignItems: "stretch",
358
- padding: `${tokens.spacing.md} 16px ${tokens.spacing.md} 15px`,
359
- borderBottom: `1px solid ${tokens.colors.border.muted}`,
360
- flexShrink: 0,
361
- boxSizing: "border-box",
362
- position: "relative"
363
- }, children: [
364
- showToggle ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", top: tokens.spacing.sm, right: tokens.spacing.sm, zIndex: 1 }, children: /* @__PURE__ */ jsx(CollapseToggleButton, {}) }) : null,
365
- /* @__PURE__ */ jsxs("div", { style: { paddingRight: showToggle ? 36 : 0, width: "100%", minWidth: 0 }, children: [
366
- logoSlot,
367
- metaBlock
368
- ] })
369
- ] });
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
+ });
370
526
  });
371
- const TAG_COLORS = {
372
- default: { bg: "#ffffff10", fg: "#9590a8", border: "#ffffff15" },
373
- info: { bg: "#8a2be218", fg: "#c4a0ff", border: "#8a2be230" },
374
- success: { bg: "#56f00018", fg: "#56f000", border: "#56f00030" },
375
- warning: { bg: "#fce83a18", fg: "#fce83a", border: "#fce83a30" },
376
- 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
+ }
377
553
  };
378
- const SideNavItem = memo(function SideNavItem2({
379
- icon,
380
- label,
381
- description,
382
- tag,
383
- tagVariant = "default",
384
- href,
385
- onClick,
386
- active = false,
387
- disabled = false,
388
- badge,
389
- external = false,
390
- status,
391
- statusLabel,
392
- suffix
393
- }) {
394
- const { tokens } = useTheme();
395
- const { collapsed, setMobileOpen } = useContext(SideNavContext);
396
- const [isHovered, setIsHovered] = useState(false);
397
- const handleClick = useCallback((e) => {
398
- if (disabled) return;
399
- if (onClick && href && !e.metaKey && !e.ctrlKey && !e.shiftKey) {
400
- e.preventDefault();
401
- }
402
- setMobileOpen(false);
403
- onClick == null ? void 0 : onClick();
404
- }, [disabled, onClick, href, setMobileOpen]);
405
- const statusColor = status ? SIDENAV_STATUS_COLORS[status] ?? void 0 : void 0;
406
- const accentColor = statusColor && active ? statusColor : safeAccentText(tokens.colors.accent.primary);
407
- const hasDescription = !!description && !collapsed;
408
- const iconElement = typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { name: icon, size: hasDescription ? 22 : 20, color: active ? accentColor : tokens.colors.text.secondary }) : icon;
409
- const itemStyle = {
410
- display: "flex",
411
- alignItems: hasDescription ? "flex-start" : "center",
412
- gap: tokens.spacing.sm,
413
- padding: collapsed ? `${tokens.spacing.sm} 0` : hasDescription ? `10px 16px 10px 12px` : `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 12px`,
414
- justifyContent: collapsed ? "center" : "flex-start",
415
- color: active ? accentColor : disabled ? tokens.colors.text.tertiary : tokens.colors.text.secondary,
416
- backgroundColor: active ? `${accentColor}12` : isHovered && !disabled ? `${accentColor}08` : "transparent",
417
- fontSize: tokens.typography.fontSize.sm,
418
- fontWeight: active ? tokens.typography.fontWeight.semibold : tokens.typography.fontWeight.normal,
419
- fontFamily: tokens.typography.fontFamily.primary,
420
- cursor: disabled ? "not-allowed" : "pointer",
421
- textDecoration: "none",
422
- borderTop: "none",
423
- borderRight: "none",
424
- borderBottom: "none",
425
- borderLeft: active ? `3px solid ${accentColor}` : "3px solid transparent",
426
- outline: "none",
427
- width: "100%",
428
- boxSizing: "border-box",
429
- transition: tokens.animation.fast,
430
- position: "relative",
431
- opacity: disabled ? 0.5 : 1
432
- };
433
- const tagColors = TAG_COLORS[tagVariant] ?? TAG_COLORS.default;
434
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
435
- iconElement && /* @__PURE__ */ jsxs("span", { style: { flexShrink: 0, display: "flex", position: "relative", marginTop: hasDescription ? "2px" : 0 }, children: [
436
- iconElement,
437
- collapsed && status && /* @__PURE__ */ jsx(
438
- "span",
439
- {
440
- style: {
441
- position: "absolute",
442
- top: -3,
443
- left: -4,
444
- lineHeight: 0
445
- },
446
- title: statusLabel ?? status,
447
- children: /* @__PURE__ */ jsx(NavStatusShape, { status, size: 7 })
448
- }
449
- )
450
- ] }),
451
- !collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
452
- /* @__PURE__ */ jsxs("span", { style: { flex: 1, minWidth: 0, overflow: "hidden" }, children: [
453
- /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
454
- /* @__PURE__ */ jsx("span", { style: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: label }),
455
- tag && /* @__PURE__ */ jsx("span", { style: {
456
- fontSize: "0.6rem",
457
- fontWeight: tokens.typography.fontWeight.bold,
458
- color: tagColors.fg,
459
- backgroundColor: tagColors.bg,
460
- border: `1px solid ${tagColors.border}`,
461
- padding: "1px 5px",
462
- borderRadius: tokens.borderRadius.sm,
463
- textTransform: "uppercase",
464
- letterSpacing: "0.04em",
465
- flexShrink: 0,
466
- lineHeight: "1.3",
467
- whiteSpace: "nowrap"
468
- }, children: tag })
469
- ] }),
470
- description && /* @__PURE__ */ jsx("span", { style: {
471
- display: "block",
472
- fontSize: tokens.typography.fontSize.xxs,
473
- color: tokens.colors.text.tertiary,
474
- lineHeight: tokens.typography.lineHeight.normal,
475
- marginTop: "2px",
476
- whiteSpace: "nowrap",
477
- overflow: "hidden",
478
- textOverflow: "ellipsis",
479
- fontWeight: tokens.typography.fontWeight.normal
480
- }, children: description })
481
- ] }),
482
- (badge !== void 0 && badge > 0 || status || suffix || external) && /* @__PURE__ */ jsxs("span", { style: {
483
- display: "inline-flex",
484
- alignItems: "center",
485
- gap: 8,
486
- flexShrink: 0,
487
- marginTop: hasDescription ? "2px" : 0
488
- }, children: [
489
- badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx("span", { style: {
490
- fontSize: "0.65rem",
491
- fontWeight: tokens.typography.fontWeight.bold,
492
- color: "#fff",
493
- backgroundColor: tokens.colors.status.critical,
494
- borderRadius: tokens.borderRadius.full,
495
- minWidth: "18px",
496
- height: "18px",
497
- display: "inline-flex",
498
- alignItems: "center",
499
- justifyContent: "center",
500
- padding: "0 5px",
501
- flexShrink: 0,
502
- lineHeight: 1,
503
- boxSizing: "border-box"
504
- }, children: badge > 99 ? "99+" : badge }),
505
- status && /* @__PURE__ */ jsx(
506
- "span",
507
- {
508
- style: { display: "inline-flex", alignItems: "center", flexShrink: 0 },
509
- role: "status",
510
- "aria-label": `Status: ${statusLabel ?? status}`,
511
- title: statusLabel ?? status,
512
- children: /* @__PURE__ */ jsx(NavStatusShape, { status, size: 8 })
513
- }
514
- ),
515
- suffix && /* @__PURE__ */ jsx("span", { style: { flexShrink: 0, display: "inline-flex", alignItems: "center" }, children: suffix }),
516
- 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: [
517
- /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
518
- /* @__PURE__ */ jsx("polyline", { points: "15 3 21 3 21 9" }),
519
- /* @__PURE__ */ jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
520
- ] })
521
- ] })
522
- ] })
523
- ] });
524
- const props = {
525
- style: itemStyle,
526
- onMouseEnter: () => setIsHovered(true),
527
- onMouseLeave: () => setIsHovered(false),
528
- title: collapsed ? label : void 0,
529
- "aria-current": active ? "page" : void 0,
530
- "aria-disabled": disabled
531
- };
532
- if (href && !disabled) {
533
- return /* @__PURE__ */ jsx("a", { href, onClick: handleClick, target: external ? "_blank" : void 0, rel: external ? "noopener noreferrer" : void 0, ...props, children: content });
534
- }
535
- 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
+ });
536
779
  });
537
- const SideNavSection = memo(function SideNavSection2({
538
- title,
539
- children
540
- }) {
541
- const { tokens } = useTheme();
542
- const { collapsed } = useContext(SideNavContext);
543
- return /* @__PURE__ */ jsxs("div", { style: { marginTop: tokens.spacing.sm }, children: [
544
- title && !collapsed && /* @__PURE__ */ jsx("div", { style: {
545
- padding: `${tokens.spacing.xs} 16px ${tokens.spacing.xs} 15px`,
546
- fontSize: tokens.typography.fontSize.xxs,
547
- fontWeight: tokens.typography.fontWeight.bold,
548
- color: tokens.colors.text.tertiary,
549
- textTransform: "uppercase",
550
- letterSpacing: "0.08em"
551
- }, children: title }),
552
- collapsed && title && /* @__PURE__ */ jsx("div", { style: {
553
- width: "60%",
554
- height: "1px",
555
- backgroundColor: tokens.colors.border.muted,
556
- margin: `${tokens.spacing.xs} auto`
557
- } }),
558
- children
559
- ] });
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
+ });
560
807
  });
561
- const SideNavDivider = memo(function SideNavDivider2({
562
- label
563
- }) {
564
- const { tokens } = useTheme();
565
- const { collapsed } = useContext(SideNavContext);
566
- if (collapsed) {
567
- return /* @__PURE__ */ jsx("div", { style: {
568
- width: "60%",
569
- height: "1px",
570
- backgroundColor: tokens.colors.border.muted,
571
- margin: `${tokens.spacing.sm} auto`
572
- } });
573
- }
574
- if (label) {
575
- return /* @__PURE__ */ jsxs("div", { style: {
576
- display: "flex",
577
- alignItems: "center",
578
- gap: tokens.spacing.sm,
579
- padding: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`
580
- }, children: [
581
- /* @__PURE__ */ jsx("div", { style: { flex: 1, height: "1px", backgroundColor: tokens.colors.border.muted } }),
582
- /* @__PURE__ */ jsx("span", { style: {
583
- fontSize: tokens.typography.fontSize.xxs,
584
- color: tokens.colors.text.tertiary,
585
- textTransform: "uppercase",
586
- letterSpacing: "0.06em",
587
- whiteSpace: "nowrap"
588
- }, children: label }),
589
- /* @__PURE__ */ jsx("div", { style: { flex: 1, height: "1px", backgroundColor: tokens.colors.border.muted } })
590
- ] });
591
- }
592
- return /* @__PURE__ */ jsx("div", { style: {
593
- height: "1px",
594
- backgroundColor: tokens.colors.border.muted,
595
- margin: `${tokens.spacing.sm} 16px ${tokens.spacing.sm} 15px`
596
- } });
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
+ } });
597
852
  });
598
- const SideNavFooter = memo(function SideNavFooter2({
599
- children
600
- }) {
601
- const { tokens } = useTheme();
602
- return /* @__PURE__ */ jsx("div", { style: {
603
- marginTop: "auto",
604
- borderTop: `1px solid ${tokens.colors.border.muted}`,
605
- paddingTop: tokens.spacing.xs,
606
- paddingBottom: tokens.spacing.xs
607
- }, 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
+ });
608
864
  });
609
- const SideNav = Object.assign(SideNavRoot, {
610
- Header: SideNavHeader,
611
- Item: SideNavItem,
612
- Section: SideNavSection,
613
- Divider: SideNavDivider,
614
- Footer: SideNavFooter
865
+ var SideNav = Object.assign(SideNavRoot, {
866
+ Header: SideNavHeader,
867
+ Item: SideNavItem,
868
+ Section: SideNavSection,
869
+ Divider: SideNavDivider,
870
+ Footer: SideNavFooter
615
871
  });
616
- export {
617
- SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX,
618
- SideNav
619
- };
620
- //# sourceMappingURL=SideNav.js.map
872
+ //#endregion
873
+ export { SIDENAV_HEADER_LOGO_SLOT_HEIGHT_PX, SideNav, SideNav as default };
874
+
875
+ //# sourceMappingURL=SideNav.js.map