@zendir/ui 0.5.0 → 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 +20 -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 -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 +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
package/README.md CHANGED
@@ -1,631 +1,640 @@
1
- <h1 align="center">@zendir/ui</h1>
2
-
3
- <p align="center">
4
- React components for space operations.<br />
5
- Built on the <a href="https://www.astrouxds.com/">Astro UX Design System</a>.
6
- </p>
7
-
8
- <p align="center">
9
- <img src="https://img.shields.io/npm/v/@zendir/ui?style=flat&colorA=18181B&colorB=6C47FF" alt="npm version" />
10
- <img src="https://img.shields.io/badge/license-MIT-6C47FF.svg?style=flat&colorA=18181B" alt="License" />
11
- <img src="https://img.shields.io/badge/TypeScript-5.0+-6C47FF.svg?style=flat&colorA=18181B" alt="TypeScript" />
12
- <img src="https://img.shields.io/badge/React-18%2F19-6C47FF.svg?style=flat&colorA=18181B" alt="React" />
13
- <img src="https://img.shields.io/badge/WCAG_2.2_AA-conformant-6C47FF.svg?style=flat&colorA=18181B" alt="WCAG 2.2 AA conformant" />
14
- </p>
15
-
16
- <p align="center">
17
- <a href="#quick-start">Quick Start</a> · <a href="#components">Components</a> · <a href="#ai-integration">AI Integration</a> · <a href="#theme-system">Theming</a> · <a href="#accessibility">Accessibility</a> · <a href="https://storybook.zendir.io">Storybook</a> · <a href="CONTRIBUTING.md">Contributing</a> · <a href="CODE_OF_CONDUCT.md">Code of Conduct</a>
18
- </p>
19
-
20
- ---
21
-
22
- ## Overview
23
-
24
- React components for satellite telemetry, orbit visualisation, mission control dashboards, and space simulations. Follows the [Astro UX Design System](https://www.astrouxds.com/) used by the U.S. Space Force.
25
-
26
- - **Astro UX-aligned** — dual-coded status indicators, classification banners, mission clocks
27
- - **TypeScript-first** — full type definitions
28
- - **Accessible** — [WCAG 2.2 AA](https://www.w3.org/TR/WCAG22/) conformant, keyboard navigable, reduced-motion aware, EAA-aligned
29
- - **Tree-shakeable** with optional peer dependencies
30
- - Works standalone or with [`zendir-ts`](https://www.npmjs.com/package/zendir-ts) for live API integration
31
-
32
- The full component catalogue with live examples lives in [Storybook](https://storybook.zendir.io).
33
-
34
- ## Quick Start
35
-
36
- ### Install
37
-
38
- ```bash
39
- npm install @zendir/ui
40
- ```
41
-
42
- > The SDK is optional. All TypeScript types ship with the UI library.
43
- > Install `zendir-ts` only if you need the API client.
44
- >
45
- > Recent versions of `@zendir/ui` hide the SDK specifier from static
46
- > import-analysis, so no Vite alias is required — missing `zendir-ts` simply
47
- > causes hooks like `useZendirSession` to report "SDK not installed" while the
48
- > rest of the UI keeps working.
49
- >
50
- > **Older bundlers / strict resolvers:** if you hit "Failed to resolve import
51
- > 'zendir-ts'", point the optional peer at the bundled stub:
52
- > ```js
53
- > // vite.config.js
54
- > resolve: { alias: { 'zendir-ts': require.resolve('@zendir/ui/sdk-stub') } }
55
- > ```
56
-
57
- ### Use
58
-
59
- ```tsx
60
- import { ThemeProvider, SpacecraftCard, StatusIndicator } from '@zendir/ui/react';
61
-
62
- function App() {
63
- return (
64
- <ThemeProvider defaultVariant="hybrid" defaultMode="dark">
65
- <StatusIndicator status="normal" label="System Healthy" />
66
-
67
- <SpacecraftCard
68
- spacecraft={{
69
- id: 'SAT-001',
70
- name: 'Explorer-1',
71
- noradId: 25544,
72
- type: 'LEO Satellite',
73
- status: 'operational',
74
- }}
75
- position={{
76
- latitude: 45.2,
77
- longitude: -122.5,
78
- altitude: 408,
79
- velocity: 7.66,
80
- }}
81
- />
82
- </ThemeProvider>
83
- );
84
- }
85
- ```
86
-
87
- ---
88
-
89
- ## Components
90
-
91
- ### Core
92
-
93
- Foundational primitives that compose into any interface.
94
-
95
- | Component | Description |
96
- |-----------|-------------|
97
- | `Button` | Primary, secondary, and borderless variants with icon and loading support |
98
- | `Input` | Text input with label, icon, validation, and size variants |
99
- | `Select` | Dropdown selection with search and multi-select |
100
- | `Toggle` | On/off switch with label |
101
- | `Checkbox` | Checkbox and radio with accessible labeling |
102
- | `Dialog` | Modal dialog with action slots |
103
- | `Tabs` | Tabbed navigation with panel content |
104
- | `Tooltip` | Contextual overlay on hover/focus |
105
- | `Container` | Surface card with title, status accent, and elevation |
106
- | `Badge` | Inline status label |
107
- | `Pagination` | Page navigation controls |
108
- | `NumberInput` | Numeric stepper with min/max/step and slider |
109
- | `SidePanel` | Slide-out panel with configurable position |
110
- | `DataTable` | Sortable, filterable data grid |
111
- | `Menu` / `Popover` | Context menus and floating content |
112
- | `ChatPanel` | AI chat interface with structured blocks, status system, and [4 LLM integration strategies](#ai-integration) |
113
-
114
- ### Status & Monitoring
115
-
116
- Astro UX status system — six severity levels, dual-coded with color and shape so that status is never conveyed by color alone (WCAG 1.4.1 Use of Color).
117
-
118
- ```tsx
119
- import { StatusIndicator, MonitoringIcon } from '@zendir/ui/react';
120
-
121
- <StatusIndicator status="normal" label="Operational" />
122
- <StatusIndicator status="caution" label="Battery Low" />
123
- <StatusIndicator status="critical" label="Comm Loss" pulse />
124
-
125
- <MonitoringIcon status="normal" icon="power" label="Power" sublabel="85%" />
126
- ```
127
-
128
- **Status levels:** `off` · `standby` · `normal` · `caution` · `serious` · `critical`
129
-
130
- ### Data Cards
131
-
132
- Pre-built cards for common space operations data. All cards support **compact mode** — collapsed by default, expand on hover, pin on click.
133
-
134
- | Card | Data |
135
- |------|------|
136
- | `SpacecraftCard` | ID, orbit type, status, position |
137
- | `TelemetryCard` | Subsystem health, alerts |
138
- | `TelemetryStreamCard` | Live metric streaming |
139
- | `AccessCard` | Ground station contact windows |
140
- | `OrbitCard` | Keplerian elements, period, epoch |
141
-
142
- ```tsx
143
- <SpacecraftCard compact spacecraft={data} position={pos} />
144
- <TelemetryCard compact telemetry={tlm} />
145
- ```
146
-
147
- ### DataValue
148
-
149
- Display telemetry values with automatic icons, units, and status derivation from 30+ built-in property presets.
150
-
151
- ```tsx
152
- import { DataValue, DataValueGroup } from '@zendir/ui/react';
153
-
154
- <DataValue property="temperature" value={72.5} />
155
- <DataValue property="battery" value={25} /> {/* auto-derives 'caution' */}
156
-
157
- <DataValueGroup columns={2} title="Power" icon="propulsion-power">
158
- <DataValue property="battery" value={85} />
159
- <DataValue property="voltage" value={28.4} />
160
- <DataValue property="solarPower" value={124} />
161
- </DataValueGroup>
162
- ```
163
-
164
- **Presets:** `battery` · `voltage` · `temperature` · `signalStrength` · `altitude` · `velocity` · `fuelLevel` · `cpuUsage` · `memoryUsage` · and 20+ more (see [Storybook](https://storybook.zendir.io) for the full list)
165
-
166
- ### Visualizations
167
-
168
- Domain-specific visualization cards for mission operations.
169
-
170
- | Card | Description |
171
- |------|-------------|
172
- | `LinkBudgetCard` | RF link budget waterfall |
173
- | `ThermalHeatmapCard` | Spacecraft thermal zone status |
174
- | `PropulsionCard` | Fuel, thrusters, delta-V budget |
175
- | `EclipseTimerCard` | Eclipse/sunlight timing |
176
- | `NavBallCard` | 3D attitude indicator |
177
- | `SensorFootprintCard` | Ground sensor coverage |
178
-
179
- ### Charts
180
-
181
- 40+ chart types built on ECharts with Astro UX color palettes, built-in export (PNG, SVG, CSV), zoom/pan, and streaming support.
182
-
183
- ```tsx
184
- import { PowerChart, AttitudeChart, GroundTrackMap } from '@zendir/ui/react';
185
-
186
- <PowerChart data={powerData} height={300} />
187
- <AttitudeChart data={attitudeData} height={250} />
188
- <GroundTrackMap groundTrack={track} groundStations={stations} />
189
- ```
190
-
191
- **Includes:** Line, Area, Bar, Pie, Donut, Gauge, Radar, Heatmap, Scatter, Sankey, Treemap, Sunburst, Candlestick, 3D Scatter/Surface/Bar, Waterfall, Doppler, and domain-specific charts for power, attitude, thermal, orbits, contacts, spectrum, and more.
192
-
193
- ### 3D Viewers
194
-
195
- Three viewers covering the operations spectrum from full-Earth to full solar system, with optional WebGL2 (Three.js) and Cesium backends.
196
-
197
- ```tsx
198
- import { ZenSpace3D, EarthViewer, SolarSystemViewer } from '@zendir/ui/react';
199
-
200
- // Unified 3D space view — Three.js by default, optional Cesium backend for
201
- // physically-accurate ECI/ECEF transforms and high-fidelity Earth imagery.
202
- // Pair with `useSimulationScene` (see SDK Integration) to render a live
203
- // simulation directly from a `zendir-ts` `ZendirClient`.
204
- <ZenSpace3D
205
- satellites={satellites}
206
- groundStations={groundStations}
207
- satelliteCoverages={coverages}
208
- referenceTime={referenceDate}
209
- />
210
-
211
- // Lightweight Three.js Earth view — good for small dashboards and demos.
212
- <EarthViewer
213
- spacecraft={[{ id: 'SAT-001', name: 'Explorer-1', latitude: 45.2, longitude: -122.5, altitude: 408 }]}
214
- groundStations={[{ id: 'DSN-14', name: 'Goldstone', latitude: 35.4, longitude: -116.9 }]}
215
- showAtmosphere
216
- showOrbits
217
- autoRotate
218
- />
219
-
220
- <SolarSystemViewer focusedPlanet="earth" autoOrbit showLabels />
221
- ```
222
-
223
- Coverage geometry (footprint polygons, sensor cones, nadir lines) is rendered from explicit `SatelliteCoverage` records — see `ZenSpace3DTypes` for the full prop surface. Heavy orbital propagation (SGP4 / TLE) is intentionally **not** shipped in this package; bring your own propagator (e.g. [`satellite.js`](https://github.com/shashwatak/satellite-js)) and feed positions in via props, or use `useSimulationScene` to read live `Position_BN_N` from the engine.
224
-
225
- ### Astro UX Components
226
-
227
- Mission operations components following [Astro UX Design System](https://www.astrouxds.com/) specifications.
228
-
229
- | Component | Description |
230
- |-----------|-------------|
231
- | `GlobalStatusBar` | Application header with app name, clock, monitoring icons |
232
- | `MissionClock` | UTC/local time display with multiple formats |
233
- | `ClassificationBanner` | Security classification banner (CUI through Top Secret) |
234
- | `Timeline` | Gantt, list, and scatter views for mission events |
235
- | `Progress` | Determinate and indeterminate progress indicators |
236
- | `Notification` | Toast notifications with status and auto-dismiss |
237
-
238
- ---
239
-
240
- ## Theme System
241
-
242
- Wrap your application in `ThemeProvider` to enable the full token-based design system.
243
-
244
- ```tsx
245
- import { ThemeProvider, useTheme } from '@zendir/ui/react';
246
-
247
- <ThemeProvider
248
- defaultVariant="hybrid" // 'astro' | 'purple-hue' | 'hybrid' | 'transparent'
249
- defaultMode="dark" // 'light' | 'dark'
250
- persistPreference={true} // save to localStorage
251
- >
252
- <App />
253
- </ThemeProvider>
254
- ```
255
-
256
- Access tokens anywhere:
257
-
258
- ```tsx
259
- const { tokens, mode, setMode } = useTheme();
260
-
261
- <div style={{
262
- background: tokens.colors.background.surface,
263
- color: tokens.colors.text.primary,
264
- padding: tokens.spacing.md,
265
- borderRadius: tokens.borderRadius.md,
266
- }}>
267
- ...
268
- </div>
269
- ```
270
-
271
- **Token categories:** colors (background, border, text, status, semantic, accent, interactive) · spacing · border radius · typography (Astro-compliant scale) · shadows · animation · focus
272
-
273
- ### Card Accent System
274
-
275
- Automatically assign accent colors to cards by content domain:
276
-
277
- ```tsx
278
- import { CardAccentProvider, useCardAccent } from '@zendir/ui/react';
279
-
280
- <CardAccentProvider accentMode="mix">
281
- <Container title="Power Systems" accentColor={getAccentColor('Power Systems')}>
282
- ...
283
- </Container>
284
- </CardAccentProvider>
285
- ```
286
-
287
- **Accent modes:** `cyan` · `electric` · `purple` · `teal` · `prussianBlue` · `green` · `amber` · `mix`
288
-
289
- ---
290
-
291
- ## SDK Integration (Optional)
292
-
293
- For live API integration, add the Zendir TypeScript SDK (`zendir-ts`):
294
-
295
- ```bash
296
- npm install zendir-ts
297
- ```
298
-
299
- `useZendirSession` provisions the container + simulation lifecycle.
300
- `useSimulationScene` is the canonical bridge — it polls `Position_BN_N`,
301
- buckets the simulation structure, and feeds props straight into `<ZenSpace3D />`.
302
-
303
- ```tsx
304
- import { useZendirSession, useSimulationScene, ZenSpace3D } from '@zendir/ui/react';
305
-
306
- function MissionControl() {
307
- // Lifecycle: createContainer → waitForRunning → createSimulation
308
- const { client, session, connect, disconnect, isLoading, error } =
309
- useZendirSession({ apiKey: 'your-key', autoConnect: true });
310
-
311
- // Live data: structure + position polling, ECI→ECEF on the Cesium backend
312
- const scene = useSimulationScene({
313
- client,
314
- containerId: session?.containerId ?? null,
315
- simulationId: session?.simulationId ?? null,
316
- });
317
-
318
- if (error) return <div>Error: {error}</div>;
319
- if (isLoading) return <div>Connecting…</div>;
320
- if (!session) return <button onClick={connect}>Connect</button>;
321
-
322
- return (
323
- <ZenSpace3D
324
- satellites={scene.satellites}
325
- groundStations={scene.groundStations}
326
- referenceTime={scene.referenceDate}
327
- />
328
- );
329
- }
330
- ```
331
-
332
- | Hook | Purpose |
333
- |---|---|
334
- | `useZendirSession` | Container + simulation lifecycle (`createContainer` → `waitForRunning` → `createSimulation`); `disconnect` tears down |
335
- | `useSimulationScene` | Bridges a `ZendirClient` to live `<ZenSpace3D />` props (satellites, ground stations, custom objects, reference time) |
336
- | `useAccessWindows` | Pure client-side AOS/LOS pass-timing math from a list of `AccessPass` records (no SDK call) |
337
-
338
- ---
339
-
340
- ## AI Integration
341
-
342
- The `ChatPanel` component provides a complete AI-powered operator interface with structured responses, interactive blocks, and four integration strategies — including first-class MCP (Model Context Protocol) support.
343
-
344
- ### Quick Setup
345
-
346
- ```tsx
347
- import { ChatPanel, parseChatResponse } from '@zendir/ui/react';
348
-
349
- function OperatorChat() {
350
- const [messages, setMessages] = useState([]);
351
-
352
- const handleSend = async (text) => {
353
- setMessages(prev => [...prev, { id: Date.now(), role: 'user', content: text, timestamp: Date.now() }]);
354
- const response = await callYourAI(text);
355
- const msg = parseChatResponse(response); // auto-detects JSON, YAML, or plain text
356
- setMessages(prev => [...prev, msg]);
357
- };
358
-
359
- return <ChatPanel messages={messages} onSend={handleSend} title="Mission AI" />;
360
- }
361
- ```
362
-
363
- ### Four Integration Strategies
364
-
365
- | Strategy | Token Cost | Best For |
366
- |----------|-----------|----------|
367
- | **Tool/Function Calling** | Lowest | OpenAI, Anthropic, Gemini (production) |
368
- | **MCP (Model Context Protocol)** | Lowest | Multi-tool, multi-server architectures |
369
- | **YAML Prompt** | ~30-40% less than JSON | Any LLM, cost-sensitive deployments |
370
- | **JSON Prompt** | Baseline | Simplest setup, widest LLM compatibility |
371
-
372
- #### Strategy 1: Tool / Function Calling _(recommended for single-provider)_
373
-
374
- ```ts
375
- import { CHAT_RESPONSE_TOOL_SCHEMA, parseChatResponse } from '@zendir/ui/react';
376
-
377
- // OpenAI
378
- const res = await openai.chat.completions.create({
379
- model: 'gpt-4o',
380
- messages: history,
381
- tools: [{ type: 'function', function: CHAT_RESPONSE_TOOL_SCHEMA }],
382
- tool_choice: { type: 'function', function: { name: 'respond_to_operator' } },
383
- });
384
- const msg = parseChatResponse(res.choices[0].message.tool_calls[0].function.arguments, 'json');
385
-
386
- // Anthropic
387
- tools: [{ name: CHAT_RESPONSE_TOOL_SCHEMA.name,
388
- description: CHAT_RESPONSE_TOOL_SCHEMA.description,
389
- input_schema: CHAT_RESPONSE_TOOL_SCHEMA.parameters }]
390
-
391
- // Google Gemini
392
- tools: [{ functionDeclarations: [CHAT_RESPONSE_TOOL_SCHEMA] }]
393
- ```
394
-
395
- #### Strategy 2: MCP (Model Context Protocol) _(recommended for multi-tool)_
396
-
397
- ```ts
398
- // Server: Register your tool with the pre-built schema
399
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
400
- import { CHAT_RESPONSE_MCP_TOOL } from '@zendir/ui';
401
-
402
- const server = new McpServer({ name: 'ops-assistant', version: '1.0.0' });
403
- server.tool(
404
- CHAT_RESPONSE_MCP_TOOL.name,
405
- CHAT_RESPONSE_MCP_TOOL.description,
406
- CHAT_RESPONSE_MCP_TOOL.inputSchema,
407
- async (args) => ({ content: [{ type: 'text', text: JSON.stringify(args) }] })
408
- );
409
-
410
- // Client: Convert MCP results to ChatPanel messages
411
- import { parseMcpToolResult } from '@zendir/ui/react';
412
-
413
- const result = await mcpClient.callTool({ name: 'check_health', arguments: { id: 'SAT-001' } });
414
- const msg = parseMcpToolResult('check_health', result);
415
- ```
416
-
417
- #### Strategy 3: YAML Prompt
418
-
419
- ```ts
420
- import { CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT, parseChatResponse } from '@zendir/ui/react';
421
-
422
- const systemPrompt = `You are a spacecraft ops assistant.\n\n${CHAT_RESPONSE_YAML_PROMPT}\n\n${CHAT_STATUS_RULES_PROMPT}`;
423
- const msg = parseChatResponse(aiOutput, 'yaml');
424
- ```
425
-
426
- #### Strategy 4: JSON Prompt
427
-
428
- ```ts
429
- import { CHAT_RESPONSE_JSON_PROMPT, CHAT_STATUS_RULES_PROMPT, parseChatResponse } from '@zendir/ui/react';
430
-
431
- const systemPrompt = `You are a spacecraft ops assistant.\n\n${CHAT_RESPONSE_JSON_PROMPT}\n\n${CHAT_STATUS_RULES_PROMPT}`;
432
- const msg = parseChatResponse(aiOutput, 'json');
433
- ```
434
-
435
- ### Global Configuration
436
-
437
- ```ts
438
- import yaml from 'js-yaml';
439
- import { createChatResponseParser } from '@zendir/ui/react';
440
-
441
- // Create once, use everywhere
442
- export const parseAI = createChatResponseParser({
443
- yamlParser: (s) => yaml.load(s), // plug in production YAML parser
444
- defaultFormat: 'yaml', // default format
445
- });
446
-
447
- const msg = parseAI(aiOutput);
448
- ```
449
-
450
- ### Structured Blocks
451
-
452
- AI responses can include rich structured content:
453
-
454
- | Block Type | Description | Interactive |
455
- |-----------|-------------|-------------|
456
- | `alert` | Status banner with severity shape | No |
457
- | `telemetry` | Key-value readout with per-row status | No |
458
- | `progress` | Progress bar with status color | No |
459
- | `table` | Data table with column headers | No |
460
- | `kv` | Compact key-value metadata | No |
461
- | `command` | Code block with copy/run buttons | Yes |
462
- | `choice` | Single or multi-select options | Yes |
463
- | `confirm` | Confirmation gate (authorize/abort) | Yes |
464
-
465
- Interactive blocks fire `onBlockEvent` with `{ blockId, messageId, action, value }`.
466
-
467
- ### Exported Helpers
468
-
469
- | Export | What It Does |
470
- |--------|-------------|
471
- | `CHAT_RESPONSE_TOOL_SCHEMA` | Function/tool schema for OpenAI, Anthropic, Gemini |
472
- | `CHAT_RESPONSE_MCP_TOOL` | MCP server tool definition (for `server.tool()` registration) |
473
- | `parseChatResponse()` | Universal parser: auto-detects JSON / YAML / plain text |
474
- | `parseMcpToolResult()` | Bridge MCP tool results → ChatMessage with blocks |
475
- | `createChatResponseParser()` | Factory for pre-configured parser (custom YAML, format, IDs) |
476
- | `CHAT_RESPONSE_JSON_PROMPT` | JSON format instructions + block schema |
477
- | `CHAT_RESPONSE_YAML_PROMPT` | YAML format instructions + block schema |
478
- | `CHAT_STATUS_RULES_PROMPT` | Astro UX status thresholds (battery, temp, signal, memory) |
479
- | `McpToolResult` / `McpToolContent` | Lightweight MCP types (no SDK dependency needed) |
480
-
481
- > See the **[AI Integration Guide](https://storybook.zendir.io/?path=/story/core-chatpanel--ai-integration-guide)** and **[MCP Integration](https://storybook.zendir.io/?path=/story/core-chatpanel--mcp-integration)** stories in Storybook for interactive demos.
482
-
483
- ---
484
-
485
- ## AI Host / MCP Integration
486
-
487
- Components are designed to embed in any AI host — ChatGPT Apps, Anthropic MCP Apps, Google Gemini, or any MCP-compatible environment. The SDK includes dedicated hooks and a universal widget wrapper:
488
-
489
- ### AppCard — Universal Widget Wrapper
490
-
491
- `AppCard` is the base widget wrapper for any AI host — ChatGPT Apps, Anthropic MCP Apps, Google Gemini, or any MCP-compatible environment:
492
-
493
- ```tsx
494
- import { AppCard, useToolOutput, useCallTool } from '@zendir/ui/react';
495
-
496
- function SatelliteWidget() {
497
- const data = useToolOutput<SatelliteHealth>();
498
- const { callTool, isLoading, error } = useCallTool();
499
-
500
- return (
501
- <AppCard
502
- title="SAT-001"
503
- subtitle="Health Monitor · LEO 421km"
504
- status={{ level: 'caution', label: 'Battery Low' }} // Astro UX dual-coded (shape + color)
505
- loading={isLoading}
506
- error={error?.message}
507
- onRetry={() => callTool('refresh_telemetry', { id: 'SAT-001' })}
508
- allowFullscreen
509
- icon={<span>🛰️</span>}
510
- >
511
- <TelemetryDisplay data={data} />
512
- </AppCard>
513
- );
514
- }
515
- ```
516
-
517
- **Enterprise features:** Error boundary (children never crash host), loading skeleton, error display with retry, Astro UX 6-level status badges with shapes, WCAG 2.1 AA ARIA labels, `maxHeight` auto-constraint, theme sync, fullscreen support.
518
-
519
- ### MCP Server → ChatPanel Bridge
520
-
521
- Register your MCP server tools to produce ChatPanel-compatible structured blocks:
522
-
523
- ```ts
524
- // server.ts
525
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
526
- import { CHAT_RESPONSE_MCP_TOOL } from '@zendir/ui';
527
-
528
- const server = new McpServer({ name: 'sat-ops', version: '1.0.0' });
529
- server.tool(
530
- CHAT_RESPONSE_MCP_TOOL.name,
531
- CHAT_RESPONSE_MCP_TOOL.description,
532
- CHAT_RESPONSE_MCP_TOOL.inputSchema,
533
- async (args) => ({ content: [{ type: 'text', text: JSON.stringify(args) }] })
534
- );
535
- ```
536
-
537
- ```tsx
538
- // client.tsx Parse MCP results into ChatPanel messages
539
- import { parseMcpToolResult, ChatPanel } from '@zendir/ui/react';
540
-
541
- const result = await mcpClient.callTool({ name: 'check_health', arguments: { id: 'SAT-001' } });
542
- const msg = parseMcpToolResult('check_health', result); // → ChatMessage with typed blocks
543
- ```
544
-
545
- ### Available Host Hooks
546
-
547
- | Hook | Purpose |
548
- |------|---------|
549
- | `useToolOutput()` | Read tool result (structuredContent) |
550
- | `useToolInput()` | Read tool invocation arguments |
551
- | `useCallTool()` | Call other MCP tools from widget |
552
- | `useSendMessage()` | Insert follow-up user messages |
553
- | `useChatGPTTheme()` | Match light/dark theme |
554
- | `useWidgetState()` | Persist widget state across renders |
555
- | `useMaxHeight()` | Get host height constraint |
556
- | `useDisplayMode()` | Manage inline/PiP/fullscreen |
557
- | `isInChatGPT()` | Detect ChatGPT environment |
558
-
559
- ---
560
-
561
- ## Project Structure
562
-
563
- ```
564
- src/
565
- ├── react/
566
- │ ├── core/ # Buttons, inputs, dialogs, data table
567
- │ ├── astro/ # Astro UX — timeline, status bar, clock
568
- │ ├── cards/ # Spacecraft, telemetry, orbit, access
569
- │ ├── charts/ # 40+ ECharts components
570
- ├── visualizations/ # Link budget, thermal, propulsion
571
- │ ├── 3d/ # Earth viewer, solar system
572
- │ ├── hooks/ # Data hooks
573
- │ ├── theme/ # ThemeProvider, tokens
574
- │ ├── chatgpt/ # AI host / MCP integration (AppCard, hooks)
575
- └── shared/ # Error boundaries, skeletons, utils
576
- └── tokens/ # Design tokens (CSS + TypeScript)
577
- ```
578
-
579
- ## Development
580
-
581
- ```bash
582
- git clone https://github.com/zendir-dev/zendir-ui.git
583
- cd zendir-ui && npm install
584
-
585
- npm run storybook # Component playground
586
- npm run demo # Full demo app
587
- npm run build # Production build
588
- npm run test # Run tests
589
- npm run lint # Lint check
590
- ```
591
-
592
- ## Accessibility
593
-
594
- Zendir UI conforms to [**WCAG 2.2 Level AA**](https://www.w3.org/TR/WCAG22/) and is designed to satisfy the [**European Accessibility Act (EAA)**](https://ec.europa.eu/social/main.jsp?catId=1202) via [**EN 301 549 v3.2.1**](https://www.etsi.org/deliver/etsi_en/301500_301599/301549/03.02.01_60/en_301549v030201p.pdf) and the **Revised Section 508**.
595
-
596
- - **Keyboard** every component is fully operable via keyboard. Focus order follows DOM order, focus indicators meet 3:1 contrast, and no keyboard traps exist.
597
- - **Screen readers** semantic HTML, ARIA roles, live regions for dynamic content, and descriptive labels on all icon-only controls.
598
- - **Color** status indicators use dual coding (color + shape). All text meets 4.5:1 contrast; accent colors are dynamically adjusted at runtime to guarantee compliance across all themes.
599
- - **Motion** — all animations and transitions respect `prefers-reduced-motion` globally via CSS and JavaScript.
600
- - **Target size** — interactive controls meet the 24 × 24 px minimum (WCAG 2.5.8).
601
- - **Forms** — validation errors are identified with `aria-invalid`, associated via `aria-describedby`, and announced with `role="alert"`.
602
-
603
- | Standard | Status |
604
- |----------|--------|
605
- | WCAG 2.2 Level AA | Conformant |
606
- | EN 301 549 v3.2.1 Clause 11 | Designed for conformance |
607
- | EAA Directive (EU) 2019/882 | Designed for conformance |
608
- | Revised Section 508 | Conformant |
609
-
610
- Testing: [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) in CI, [axe-core](https://storybook.js.org/addons/@storybook/addon-a11y) on all Storybook stories, manual keyboard and screen reader verification (VoiceOver, NVDA, TalkBack).
611
-
612
- Accessibility issues are treated as **P0 bugs**. [Report an issue](https://github.com/zendir-dev/zendir-ui/issues) with the `accessibility` label.
613
-
614
- ---
615
-
616
- ## Browser Support
617
-
618
- Chrome 90+ · Firefox 88+ · Safari 14+ · Edge 90+
619
-
620
- WebGL required for 3D components (graceful fallback to 2D).
621
-
622
-
623
- ## License
624
-
625
- [MIT](LICENSE) Space Services Australia Pty Ltd
626
-
627
- ---
628
-
629
- <p align="center">
630
- <a href="https://www.astrouxds.com/">Astro UX Design System</a> · <a href="https://storybook.zendir.io">Storybook</a> · <a href="https://github.com/zendir-dev/zendir-ui/issues">Issues</a> · <a href="CONTRIBUTING.md">Contributing</a>
631
- </p>
1
+ <h1 align="center">@zendir/ui</h1>
2
+
3
+ <p align="center">
4
+ React components for space operations.<br />
5
+ Built on the <a href="https://www.astrouxds.com/">Astro UX Design System</a>.
6
+ </p>
7
+
8
+ <p align="center">
9
+ <img src="https://img.shields.io/npm/v/@zendir/ui?style=flat&colorA=18181B&colorB=6C47FF" alt="npm version" />
10
+ <img src="https://img.shields.io/badge/license-MIT-6C47FF.svg?style=flat&colorA=18181B" alt="License" />
11
+ <img src="https://img.shields.io/badge/TypeScript-5.0+-6C47FF.svg?style=flat&colorA=18181B" alt="TypeScript" />
12
+ <img src="https://img.shields.io/badge/React-18%2F19-6C47FF.svg?style=flat&colorA=18181B" alt="React" />
13
+ <img src="https://img.shields.io/badge/WCAG_2.2_AA-conformant-6C47FF.svg?style=flat&colorA=18181B" alt="WCAG 2.2 AA conformant" />
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="#quick-start">Quick Start</a> · <a href="#components">Components</a> · <a href="#ai-integration">AI Integration</a> · <a href="#theme-system">Theming</a> · <a href="#accessibility">Accessibility</a> · <a href="https://storybook.zendir.io">Storybook</a> · <a href="CONTRIBUTING.md">Contributing</a> · <a href="CODE_OF_CONDUCT.md">Code of Conduct</a>
18
+ </p>
19
+
20
+ ---
21
+
22
+ ## Overview
23
+
24
+ React components for satellite telemetry, orbit visualisation, mission control dashboards, and space simulations. Follows the [Astro UX Design System](https://www.astrouxds.com/) used by the U.S. Space Force.
25
+
26
+ - **Astro UX-aligned** — dual-coded status indicators, classification banners, mission clocks
27
+ - **TypeScript-first** — full type definitions
28
+ - **Accessible** — [WCAG 2.2 AA](https://www.w3.org/TR/WCAG22/) conformant, keyboard navigable, reduced-motion aware, EAA-aligned
29
+ - **Tree-shakeable** with optional peer dependencies
30
+ - Works standalone or with [`zendir-ts`](https://www.npmjs.com/package/zendir-ts) for live API integration
31
+
32
+ The full component catalogue with live examples lives in [Storybook](https://storybook.zendir.io).
33
+
34
+ ## Quick Start
35
+
36
+ ### Install
37
+
38
+ ```bash
39
+ npm install @zendir/ui
40
+ ```
41
+
42
+ > The SDK is optional. All TypeScript types ship with the UI library.
43
+ > Install `zendir-ts` only if you need the API client.
44
+ >
45
+ > Recent versions of `@zendir/ui` hide the SDK specifier from static
46
+ > import-analysis, so no Vite alias is required — missing `zendir-ts` simply
47
+ > causes hooks like `useZendirSession` to report "SDK not installed" while the
48
+ > rest of the UI keeps working.
49
+ >
50
+ > **Older bundlers / strict resolvers:** if you hit "Failed to resolve import
51
+ > 'zendir-ts'", point the optional peer at the bundled stub:
52
+ > ```js
53
+ > // vite.config.js
54
+ > resolve: { alias: { 'zendir-ts': require.resolve('@zendir/ui/sdk-stub') } }
55
+ > ```
56
+
57
+ ### Use
58
+
59
+ ```tsx
60
+ import { ThemeProvider, SpacecraftCard, StatusIndicator } from '@zendir/ui/react';
61
+
62
+ function App() {
63
+ return (
64
+ <ThemeProvider defaultVariant="hybrid" defaultMode="dark">
65
+ <StatusIndicator status="normal" label="System Healthy" />
66
+
67
+ <SpacecraftCard
68
+ spacecraft={{
69
+ id: 'SAT-001',
70
+ name: 'Explorer-1',
71
+ noradId: 25544,
72
+ type: 'LEO Satellite',
73
+ status: 'operational',
74
+ }}
75
+ position={{
76
+ latitude: 45.2,
77
+ longitude: -122.5,
78
+ altitude: 408,
79
+ velocity: 7.66,
80
+ }}
81
+ />
82
+ </ThemeProvider>
83
+ );
84
+ }
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Components
90
+
91
+ ### Core
92
+
93
+ Foundational primitives that compose into any interface.
94
+
95
+ | Component | Description |
96
+ |-----------|-------------|
97
+ | `Button` | Primary, secondary, and borderless variants with icon and loading support |
98
+ | `Input` | Text input with label, icon, validation, and size variants |
99
+ | `Select` | Dropdown selection with search and multi-select |
100
+ | `Toggle` | On/off switch with label |
101
+ | `Checkbox` | Checkbox and radio with accessible labeling |
102
+ | `Dialog` | Modal dialog with action slots |
103
+ | `Tabs` | Tabbed navigation with panel content |
104
+ | `Tooltip` | Contextual overlay on hover/focus |
105
+ | `Container` | Surface card with title, status accent, and elevation |
106
+ | `Badge` | Inline status label |
107
+ | `Pagination` | Page navigation controls |
108
+ | `NumberInput` | Numeric stepper with min/max/step and slider |
109
+ | `SidePanel` | Slide-out panel with configurable position |
110
+ | `DataTable` | Sortable, filterable data grid |
111
+ | `Menu` / `Popover` | Context menus and floating content |
112
+ | `ChatPanel` | AI chat interface with structured blocks, status system, and [4 LLM integration strategies](#ai-integration) |
113
+
114
+ ### Status & Monitoring
115
+
116
+ Astro UX status system — six severity levels, dual-coded with color and shape so that status is never conveyed by color alone (WCAG 1.4.1 Use of Color).
117
+
118
+ ```tsx
119
+ import { StatusIndicator, MonitoringIcon } from '@zendir/ui/react';
120
+
121
+ <StatusIndicator status="normal" label="Operational" />
122
+ <StatusIndicator status="caution" label="Battery Low" />
123
+ <StatusIndicator status="critical" label="Comm Loss" pulse />
124
+
125
+ <MonitoringIcon status="normal" icon="power" label="Power" sublabel="85%" />
126
+ ```
127
+
128
+ **Status levels:** `off` · `standby` · `normal` · `caution` · `serious` · `critical`
129
+
130
+ ### Data Cards
131
+
132
+ Pre-built cards for common space operations data. All cards support **compact mode** — collapsed by default, expand on hover, pin on click.
133
+
134
+ | Card | Data |
135
+ |------|------|
136
+ | `SpacecraftCard` | ID, orbit type, status, position |
137
+ | `TelemetryCard` | Subsystem health, alerts |
138
+ | `TelemetryStreamCard` | Live metric streaming |
139
+ | `AccessCard` | Ground station contact windows |
140
+ | `OrbitCard` | Keplerian elements, period, epoch |
141
+
142
+ ```tsx
143
+ <SpacecraftCard compact spacecraft={data} position={pos} />
144
+ <TelemetryCard compact telemetry={tlm} />
145
+ ```
146
+
147
+ ### DataValue
148
+
149
+ Display telemetry values with automatic icons, units, and status derivation from 30+ built-in property presets.
150
+
151
+ ```tsx
152
+ import { DataValue, DataValueGroup } from '@zendir/ui/react';
153
+
154
+ <DataValue property="temperature" value={72.5} />
155
+ <DataValue property="battery" value={25} /> {/* auto-derives 'caution' */}
156
+
157
+ <DataValueGroup columns={2} title="Power" icon="propulsion-power">
158
+ <DataValue property="battery" value={85} />
159
+ <DataValue property="voltage" value={28.4} />
160
+ <DataValue property="solarPower" value={124} />
161
+ </DataValueGroup>
162
+ ```
163
+
164
+ **Presets:** `battery` · `voltage` · `temperature` · `signalStrength` · `altitude` · `velocity` · `fuelLevel` · `cpuUsage` · `memoryUsage` · and 20+ more (see [Storybook](https://storybook.zendir.io) for the full list)
165
+
166
+ ### Visualizations
167
+
168
+ Domain-specific visualization cards for mission operations.
169
+
170
+ | Card | Description |
171
+ |------|-------------|
172
+ | `LinkBudgetCard` | RF link budget waterfall |
173
+ | `ThermalHeatmapCard` | Spacecraft thermal zone status |
174
+ | `PropulsionCard` | Fuel, thrusters, delta-V budget |
175
+ | `EclipseTimerCard` | Eclipse/sunlight timing |
176
+ | `NavBallCard` | 3D attitude indicator |
177
+ | `SensorFootprintCard` | Ground sensor coverage |
178
+
179
+ ### Charts
180
+
181
+ 40+ chart types built on ECharts with Zendir brand and Astro UX data-viz palettes, built-in export (PNG, SVG, CSV), zoom/pan, and streaming support.
182
+
183
+ ```tsx
184
+ import { PowerChart, AttitudeChart, GroundTrackMap } from '@zendir/ui/react';
185
+
186
+ <PowerChart data={powerData} height={300} />
187
+ <AttitudeChart data={attitudeData} height={250} />
188
+ <GroundTrackMap groundTrack={track} groundStations={stations} />
189
+ ```
190
+
191
+ **Includes:** Line, Area, Bar, Pie, Donut, Gauge, Radar, Heatmap, Scatter, Sankey, Treemap, Sunburst, Candlestick, 3D Scatter/Surface/Bar, Waterfall, Doppler, and domain-specific charts for power, attitude, thermal, orbits, contacts, spectrum, and more.
192
+
193
+ ### 3D Viewers
194
+
195
+ Three viewers covering the operations spectrum from full-Earth to full solar system, with optional WebGL2 (Three.js) and Cesium backends.
196
+
197
+ ```tsx
198
+ import { ZenSpace3D, EarthViewer, SolarSystemViewer } from '@zendir/ui/react';
199
+
200
+ // Unified 3D space view — Three.js by default, optional Cesium backend for
201
+ // physically-accurate ECI/ECEF transforms and high-fidelity Earth imagery.
202
+ // Pair with `useSimulationScene` (see SDK Integration) to render a live
203
+ // simulation directly from a `zendir-ts` `ZendirClient`.
204
+ <ZenSpace3D
205
+ satellites={satellites}
206
+ groundStations={groundStations}
207
+ satelliteCoverages={coverages}
208
+ referenceTime={referenceDate}
209
+ />
210
+
211
+ // Lightweight Three.js Earth view — good for small dashboards and demos.
212
+ <EarthViewer
213
+ spacecraft={[{ id: 'SAT-001', name: 'Explorer-1', latitude: 45.2, longitude: -122.5, altitude: 408 }]}
214
+ groundStations={[{ id: 'DSN-14', name: 'Goldstone', latitude: 35.4, longitude: -116.9 }]}
215
+ showAtmosphere
216
+ showOrbits
217
+ autoRotate
218
+ />
219
+
220
+ <SolarSystemViewer focusedPlanet="earth" autoOrbit showLabels />
221
+ ```
222
+
223
+ Coverage geometry (footprint polygons, sensor cones, nadir lines) is rendered from explicit `SatelliteCoverage` records — see `ZenSpace3DTypes` for the full prop surface. Heavy orbital propagation (SGP4 / TLE) is intentionally **not** shipped in this package; bring your own propagator (e.g. [`satellite.js`](https://github.com/shashwatak/satellite-js)) and feed positions in via props, or use `useSimulationScene` to read live `Position_BN_N` from the engine.
224
+
225
+ ### Astro UX Components
226
+
227
+ Mission operations components following [Astro UX Design System](https://www.astrouxds.com/) specifications.
228
+
229
+ | Component | Description |
230
+ |-----------|-------------|
231
+ | `GlobalStatusBar` | Application header with app name, clock, monitoring icons |
232
+ | `MissionClock` | UTC/local time display with multiple formats |
233
+ | `ClassificationBanner` | Security classification banner (CUI through Top Secret) |
234
+ | `Timeline` | Gantt, list, and scatter views for mission events |
235
+ | `Progress` | Determinate and indeterminate progress indicators |
236
+ | `Notification` | Toast notifications with status and auto-dismiss |
237
+
238
+ ---
239
+
240
+ ## Theme System
241
+
242
+ Wrap your application in `ThemeProvider` to enable the full token-based design system.
243
+
244
+ ```tsx
245
+ import { ThemeProvider, useTheme } from '@zendir/ui/react';
246
+
247
+ <ThemeProvider
248
+ defaultVariant="hybrid" // 'astro' | 'purple-hue' | 'hybrid' | 'nebula' |
249
+ // 'transparent' | 'transparent-bold' | 'transparent-minimal'
250
+ defaultMode="dark" // 'light' | 'dark'
251
+ persist={true} // save to localStorage
252
+ >
253
+ <App />
254
+ </ThemeProvider>
255
+ ```
256
+
257
+ Seven theme variants are available: `hybrid` (default, Astro status colors + purple accents), `nebula` (palette-native — Ultraviolet accent on Zendir neutral surfaces), `astro` (AstroUXDS reference, dark + light), `purple-hue`, and the glassmorphic `transparent` / `transparent-bold` / `transparent-minimal` family.
258
+
259
+ Access tokens anywhere:
260
+
261
+ ```tsx
262
+ const { tokens, mode, setMode } = useTheme();
263
+
264
+ <div style={{
265
+ background: tokens.colors.background.surface,
266
+ color: tokens.colors.text.primary,
267
+ padding: tokens.spacing.md,
268
+ borderRadius: tokens.borderRadius.md,
269
+ }}>
270
+ ...
271
+ </div>
272
+ ```
273
+
274
+ **Token categories:** colors (background, border, text, status, semantic, accent, interactive) · spacing · border radius · typography (Astro-compliant scale) · shadows · animation · focus
275
+
276
+ Tokens flow from primitive palettes (`src/tokens/palettes/` — Zendir brand, Astro UXDS status, Tailwind v4.2 scales) through semantic themes (`src/tokens/themes.ts`) into generated CSS variables (`@zendir/ui/tokens/css`, `--zendir-*`) and the `ThemeProvider` runtime. See `THEME_ARCHITECTURE.md` for the full layering model.
277
+
278
+ ### Card Accent System
279
+
280
+ Automatically assign accent colors to cards by content domain:
281
+
282
+ ```tsx
283
+ import { CardAccentProvider, useCardAccent } from '@zendir/ui/react';
284
+
285
+ <CardAccentProvider accentMode="mix">
286
+ <Container title="Power Systems" accentColor={getAccentColor('Power Systems')}>
287
+ ...
288
+ </Container>
289
+ </CardAccentProvider>
290
+ ```
291
+
292
+ **Accent modes:** `cyan` · `electric` · `purple` · `teal` · `prussianBlue` · `green` · `amber` · `mix`
293
+
294
+ ---
295
+
296
+ ## SDK Integration (Optional)
297
+
298
+ For live API integration, add the Zendir TypeScript SDK (`zendir-ts`):
299
+
300
+ ```bash
301
+ npm install zendir-ts
302
+ ```
303
+
304
+ `useZendirSession` provisions the container + simulation lifecycle.
305
+ `useSimulationScene` is the canonical bridge — it polls `Position_BN_N`,
306
+ buckets the simulation structure, and feeds props straight into `<ZenSpace3D />`.
307
+
308
+ ```tsx
309
+ import { useZendirSession, useSimulationScene, ZenSpace3D } from '@zendir/ui/react';
310
+
311
+ function MissionControl() {
312
+ // Lifecycle: createContainer → waitForRunning → createSimulation
313
+ const { client, session, connect, disconnect, isLoading, error } =
314
+ useZendirSession({ apiKey: 'your-key', autoConnect: true });
315
+
316
+ // Live data: structure + position polling, ECI→ECEF on the Cesium backend
317
+ const scene = useSimulationScene({
318
+ client,
319
+ containerId: session?.containerId ?? null,
320
+ simulationId: session?.simulationId ?? null,
321
+ });
322
+
323
+ if (error) return <div>Error: {error}</div>;
324
+ if (isLoading) return <div>Connecting…</div>;
325
+ if (!session) return <button onClick={connect}>Connect</button>;
326
+
327
+ return (
328
+ <ZenSpace3D
329
+ satellites={scene.satellites}
330
+ groundStations={scene.groundStations}
331
+ referenceTime={scene.referenceDate}
332
+ />
333
+ );
334
+ }
335
+ ```
336
+
337
+ | Hook | Purpose |
338
+ |---|---|
339
+ | `useZendirSession` | Container + simulation lifecycle (`createContainer` → `waitForRunning` → `createSimulation`); `disconnect` tears down |
340
+ | `useSimulationScene` | Bridges a `ZendirClient` to live `<ZenSpace3D />` props (satellites, ground stations, custom objects, reference time) |
341
+ | `useAccessWindows` | Pure client-side AOS/LOS pass-timing math from a list of `AccessPass` records (no SDK call) |
342
+
343
+ ---
344
+
345
+ ## AI Integration
346
+
347
+ The `ChatPanel` component provides a complete AI-powered operator interface with structured responses, interactive blocks, and four integration strategies — including first-class MCP (Model Context Protocol) support.
348
+
349
+ ### Quick Setup
350
+
351
+ ```tsx
352
+ import { ChatPanel, parseChatResponse } from '@zendir/ui/react';
353
+
354
+ function OperatorChat() {
355
+ const [messages, setMessages] = useState([]);
356
+
357
+ const handleSend = async (text) => {
358
+ setMessages(prev => [...prev, { id: Date.now(), role: 'user', content: text, timestamp: Date.now() }]);
359
+ const response = await callYourAI(text);
360
+ const msg = parseChatResponse(response); // auto-detects JSON, YAML, or plain text
361
+ setMessages(prev => [...prev, msg]);
362
+ };
363
+
364
+ return <ChatPanel messages={messages} onSend={handleSend} title="Mission AI" />;
365
+ }
366
+ ```
367
+
368
+ ### Four Integration Strategies
369
+
370
+ | Strategy | Token Cost | Best For |
371
+ |----------|-----------|----------|
372
+ | **Tool/Function Calling** | Lowest | OpenAI, Anthropic, Gemini (production) |
373
+ | **MCP (Model Context Protocol)** | Lowest | Multi-tool, multi-server architectures |
374
+ | **YAML Prompt** | ~30-40% less than JSON | Any LLM, cost-sensitive deployments |
375
+ | **JSON Prompt** | Baseline | Simplest setup, widest LLM compatibility |
376
+
377
+ #### Strategy 1: Tool / Function Calling _(recommended for single-provider)_
378
+
379
+ ```ts
380
+ import { CHAT_RESPONSE_TOOL_SCHEMA, parseChatResponse } from '@zendir/ui/react';
381
+
382
+ // OpenAI
383
+ const res = await openai.chat.completions.create({
384
+ model: 'gpt-4o',
385
+ messages: history,
386
+ tools: [{ type: 'function', function: CHAT_RESPONSE_TOOL_SCHEMA }],
387
+ tool_choice: { type: 'function', function: { name: 'respond_to_operator' } },
388
+ });
389
+ const msg = parseChatResponse(res.choices[0].message.tool_calls[0].function.arguments, 'json');
390
+
391
+ // Anthropic
392
+ tools: [{ name: CHAT_RESPONSE_TOOL_SCHEMA.name,
393
+ description: CHAT_RESPONSE_TOOL_SCHEMA.description,
394
+ input_schema: CHAT_RESPONSE_TOOL_SCHEMA.parameters }]
395
+
396
+ // Google Gemini
397
+ tools: [{ functionDeclarations: [CHAT_RESPONSE_TOOL_SCHEMA] }]
398
+ ```
399
+
400
+ #### Strategy 2: MCP (Model Context Protocol) _(recommended for multi-tool)_
401
+
402
+ ```ts
403
+ // Server: Register your tool with the pre-built schema
404
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
405
+ import { CHAT_RESPONSE_MCP_TOOL } from '@zendir/ui';
406
+
407
+ const server = new McpServer({ name: 'ops-assistant', version: '1.0.0' });
408
+ server.tool(
409
+ CHAT_RESPONSE_MCP_TOOL.name,
410
+ CHAT_RESPONSE_MCP_TOOL.description,
411
+ CHAT_RESPONSE_MCP_TOOL.inputSchema,
412
+ async (args) => ({ content: [{ type: 'text', text: JSON.stringify(args) }] })
413
+ );
414
+
415
+ // Client: Convert MCP results to ChatPanel messages
416
+ import { parseMcpToolResult } from '@zendir/ui/react';
417
+
418
+ const result = await mcpClient.callTool({ name: 'check_health', arguments: { id: 'SAT-001' } });
419
+ const msg = parseMcpToolResult('check_health', result);
420
+ ```
421
+
422
+ #### Strategy 3: YAML Prompt
423
+
424
+ ```ts
425
+ import { CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT, parseChatResponse } from '@zendir/ui/react';
426
+
427
+ const systemPrompt = `You are a spacecraft ops assistant.\n\n${CHAT_RESPONSE_YAML_PROMPT}\n\n${CHAT_STATUS_RULES_PROMPT}`;
428
+ const msg = parseChatResponse(aiOutput, 'yaml');
429
+ ```
430
+
431
+ #### Strategy 4: JSON Prompt
432
+
433
+ ```ts
434
+ import { CHAT_RESPONSE_JSON_PROMPT, CHAT_STATUS_RULES_PROMPT, parseChatResponse } from '@zendir/ui/react';
435
+
436
+ const systemPrompt = `You are a spacecraft ops assistant.\n\n${CHAT_RESPONSE_JSON_PROMPT}\n\n${CHAT_STATUS_RULES_PROMPT}`;
437
+ const msg = parseChatResponse(aiOutput, 'json');
438
+ ```
439
+
440
+ ### Global Configuration
441
+
442
+ ```ts
443
+ import yaml from 'js-yaml';
444
+ import { createChatResponseParser } from '@zendir/ui/react';
445
+
446
+ // Create once, use everywhere
447
+ export const parseAI = createChatResponseParser({
448
+ yamlParser: (s) => yaml.load(s), // plug in production YAML parser
449
+ defaultFormat: 'yaml', // default format
450
+ });
451
+
452
+ const msg = parseAI(aiOutput);
453
+ ```
454
+
455
+ ### Structured Blocks
456
+
457
+ AI responses can include rich structured content:
458
+
459
+ | Block Type | Description | Interactive |
460
+ |-----------|-------------|-------------|
461
+ | `alert` | Status banner with severity shape | No |
462
+ | `telemetry` | Key-value readout with per-row status | No |
463
+ | `progress` | Progress bar with status color | No |
464
+ | `table` | Data table with column headers | No |
465
+ | `kv` | Compact key-value metadata | No |
466
+ | `command` | Code block with copy/run buttons | Yes |
467
+ | `choice` | Single or multi-select options | Yes |
468
+ | `confirm` | Confirmation gate (authorize/abort) | Yes |
469
+
470
+ Interactive blocks fire `onBlockEvent` with `{ blockId, messageId, action, value }`.
471
+
472
+ ### Exported Helpers
473
+
474
+ | Export | What It Does |
475
+ |--------|-------------|
476
+ | `CHAT_RESPONSE_TOOL_SCHEMA` | Function/tool schema for OpenAI, Anthropic, Gemini |
477
+ | `CHAT_RESPONSE_MCP_TOOL` | MCP server tool definition (for `server.tool()` registration) |
478
+ | `parseChatResponse()` | Universal parser: auto-detects JSON / YAML / plain text |
479
+ | `parseMcpToolResult()` | Bridge MCP tool results ChatMessage with blocks |
480
+ | `createChatResponseParser()` | Factory for pre-configured parser (custom YAML, format, IDs) |
481
+ | `CHAT_RESPONSE_JSON_PROMPT` | JSON format instructions + block schema |
482
+ | `CHAT_RESPONSE_YAML_PROMPT` | YAML format instructions + block schema |
483
+ | `CHAT_STATUS_RULES_PROMPT` | Astro UX status thresholds (battery, temp, signal, memory) |
484
+ | `McpToolResult` / `McpToolContent` | Lightweight MCP types (no SDK dependency needed) |
485
+
486
+ > See the **[AI Integration Guide](https://storybook.zendir.io/?path=/story/core-chatpanel--ai-integration-guide)** and **[MCP Integration](https://storybook.zendir.io/?path=/story/core-chatpanel--mcp-integration)** stories in Storybook for interactive demos.
487
+
488
+ ---
489
+
490
+ ## AI Host / MCP Integration
491
+
492
+ Components are designed to embed in any AI host — ChatGPT Apps, Anthropic MCP Apps, Google Gemini, or any MCP-compatible environment. The SDK includes dedicated hooks and a universal widget wrapper:
493
+
494
+ ### AppCard Universal Widget Wrapper
495
+
496
+ `AppCard` is the base widget wrapper for any AI host — ChatGPT Apps, Anthropic MCP Apps, Google Gemini, or any MCP-compatible environment:
497
+
498
+ ```tsx
499
+ import { AppCard, useToolOutput, useCallTool } from '@zendir/ui/react';
500
+
501
+ function SatelliteWidget() {
502
+ const data = useToolOutput<SatelliteHealth>();
503
+ const { callTool, isLoading, error } = useCallTool();
504
+
505
+ return (
506
+ <AppCard
507
+ title="SAT-001"
508
+ subtitle="Health Monitor · LEO 421km"
509
+ status={{ level: 'caution', label: 'Battery Low' }} // Astro UX dual-coded (shape + color)
510
+ loading={isLoading}
511
+ error={error?.message}
512
+ onRetry={() => callTool('refresh_telemetry', { id: 'SAT-001' })}
513
+ allowFullscreen
514
+ icon={<span>🛰️</span>}
515
+ >
516
+ <TelemetryDisplay data={data} />
517
+ </AppCard>
518
+ );
519
+ }
520
+ ```
521
+
522
+ **Enterprise features:** Error boundary (children never crash host), loading skeleton, error display with retry, Astro UX 6-level status badges with shapes, WCAG 2.1 AA ARIA labels, `maxHeight` auto-constraint, theme sync, fullscreen support.
523
+
524
+ ### MCP Server → ChatPanel Bridge
525
+
526
+ Register your MCP server tools to produce ChatPanel-compatible structured blocks:
527
+
528
+ ```ts
529
+ // server.ts
530
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
531
+ import { CHAT_RESPONSE_MCP_TOOL } from '@zendir/ui';
532
+
533
+ const server = new McpServer({ name: 'sat-ops', version: '1.0.0' });
534
+ server.tool(
535
+ CHAT_RESPONSE_MCP_TOOL.name,
536
+ CHAT_RESPONSE_MCP_TOOL.description,
537
+ CHAT_RESPONSE_MCP_TOOL.inputSchema,
538
+ async (args) => ({ content: [{ type: 'text', text: JSON.stringify(args) }] })
539
+ );
540
+ ```
541
+
542
+ ```tsx
543
+ // client.tsx — Parse MCP results into ChatPanel messages
544
+ import { parseMcpToolResult, ChatPanel } from '@zendir/ui/react';
545
+
546
+ const result = await mcpClient.callTool({ name: 'check_health', arguments: { id: 'SAT-001' } });
547
+ const msg = parseMcpToolResult('check_health', result); // → ChatMessage with typed blocks
548
+ ```
549
+
550
+ ### Available Host Hooks
551
+
552
+ | Hook | Purpose |
553
+ |------|---------|
554
+ | `useToolOutput()` | Read tool result (structuredContent) |
555
+ | `useToolInput()` | Read tool invocation arguments |
556
+ | `useCallTool()` | Call other MCP tools from widget |
557
+ | `useSendMessage()` | Insert follow-up user messages |
558
+ | `useChatGPTTheme()` | Match light/dark theme |
559
+ | `useWidgetState()` | Persist widget state across renders |
560
+ | `useMaxHeight()` | Get host height constraint |
561
+ | `useDisplayMode()` | Manage inline/PiP/fullscreen |
562
+ | `isInChatGPT()` | Detect ChatGPT environment |
563
+
564
+ ---
565
+
566
+ ## Project Structure
567
+
568
+ ```
569
+ src/
570
+ ├── react/
571
+ │ ├── core/ # Buttons, inputs, dialogs, data table
572
+ │ ├── astro/ # Astro UX — timeline, status bar, clock
573
+ │ ├── cards/ # Spacecraft, telemetry, orbit, access
574
+ │ ├── charts/ # 40+ ECharts components
575
+ ├── visualizations/ # Link budget, thermal, propulsion
576
+ │ ├── 3d/ # Earth viewer, solar system
577
+ │ ├── hooks/ # Data hooks
578
+ │ ├── theme/ # ThemeProvider runtime, theme types, foundation stories
579
+ │ ├── chatgpt/ # AI host / MCP integration (AppCard, hooks)
580
+ │ └── shared/ # Error boundaries, skeletons, utils
581
+ └── tokens/ # Design tokens
582
+ ├── palettes/ # Primitive color scales (Zendir, Astro UXDS, Tailwind v4.2)
583
+ ├── themes.ts # Semantic theme definitions (7 variants)
584
+ ├── core.ts # Shared non-color tokens (spacing, typography, shadows)
585
+ └── tokens.css # Generated CSS variables (+ css-vars.ts) — npm run build:tokens
586
+ ```
587
+
588
+ ## Development
589
+
590
+ ```bash
591
+ git clone https://github.com/zendir-dev/zendir-ui.git
592
+ cd zendir-ui && npm install
593
+
594
+ npm run storybook # Component playground
595
+ npm run demo # Full demo app
596
+ npm run build # Production build
597
+ npm run test # Run tests
598
+ npm run lint # Lint check
599
+ ```
600
+
601
+ ## Accessibility
602
+
603
+ Zendir UI conforms to [**WCAG 2.2 Level AA**](https://www.w3.org/TR/WCAG22/) and is designed to satisfy the [**European Accessibility Act (EAA)**](https://ec.europa.eu/social/main.jsp?catId=1202) via [**EN 301 549 v3.2.1**](https://www.etsi.org/deliver/etsi_en/301500_301599/301549/03.02.01_60/en_301549v030201p.pdf) and the **Revised Section 508**.
604
+
605
+ - **Keyboard** — every component is fully operable via keyboard. Focus order follows DOM order, focus indicators meet 3:1 contrast, and no keyboard traps exist.
606
+ - **Screen readers** semantic HTML, ARIA roles, live regions for dynamic content, and descriptive labels on all icon-only controls.
607
+ - **Color** status indicators use dual coding (color + shape). All text meets 4.5:1 contrast; accent colors are dynamically adjusted at runtime to guarantee compliance across all themes.
608
+ - **Motion** all animations and transitions respect `prefers-reduced-motion` globally via CSS and JavaScript.
609
+ - **Target size** — interactive controls meet the 24 × 24 px minimum (WCAG 2.5.8).
610
+ - **Forms** validation errors are identified with `aria-invalid`, associated via `aria-describedby`, and announced with `role="alert"`.
611
+
612
+ | Standard | Status |
613
+ |----------|--------|
614
+ | WCAG 2.2 Level AA | Conformant |
615
+ | EN 301 549 v3.2.1 Clause 11 | Designed for conformance |
616
+ | EAA Directive (EU) 2019/882 | Designed for conformance |
617
+ | Revised Section 508 | Conformant |
618
+
619
+ Testing: [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) in CI, [axe-core](https://storybook.js.org/addons/@storybook/addon-a11y) on all Storybook stories, manual keyboard and screen reader verification (VoiceOver, NVDA, TalkBack).
620
+
621
+ Accessibility issues are treated as **P0 bugs**. [Report an issue](https://github.com/zendir-dev/zendir-ui/issues) with the `accessibility` label.
622
+
623
+ ---
624
+
625
+ ## Browser Support
626
+
627
+ Chrome 90+ · Firefox 88+ · Safari 14+ · Edge 90+
628
+
629
+ WebGL required for 3D components (graceful fallback to 2D).
630
+
631
+
632
+ ## License
633
+
634
+ [MIT](LICENSE) — Space Services Australia Pty Ltd
635
+
636
+ ---
637
+
638
+ <p align="center">
639
+ <a href="https://www.astrouxds.com/">Astro UX Design System</a> · <a href="https://storybook.zendir.io">Storybook</a> · <a href="https://github.com/zendir-dev/zendir-ui/issues">Issues</a> · <a href="CONTRIBUTING.md">Contributing</a>
640
+ </p>