@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
@@ -1,184 +1,227 @@
1
- import { jsxs, jsx } from "react/jsx-runtime";
2
- import { memo, useCallback } from "react";
3
1
  import { useThemeTokens } from "../theme/ThemeProvider.js";
4
- const LayerControlPanel = memo(function LayerControlPanel2({
5
- layers,
6
- onLayersChange,
7
- visibility,
8
- onVisibilityChange,
9
- groupCounts,
10
- customLayers,
11
- customLayerState,
12
- onCustomLayerChange,
13
- position = "top-right",
14
- offset,
15
- hidden = false,
16
- style,
17
- hideRenderFlags = false,
18
- hideGroups = false,
19
- hideCustomLayers = false
20
- }) {
21
- var _a;
22
- const tokens = useThemeTokens();
23
- const showLabels = (layers == null ? void 0 : layers.labels) === true;
24
- const showCoverage = (layers == null ? void 0 : layers.coverage) === true;
25
- const showOrbits = (layers == null ? void 0 : layers.orbits) !== false;
26
- const showSpacecraft = (visibility == null ? void 0 : visibility.spacecraft) !== false;
27
- const showGroundStations = (visibility == null ? void 0 : visibility.groundStations) !== false;
28
- const showCelestialBodies = (visibility == null ? void 0 : visibility.celestialBodies) !== false;
29
- const toggleLayer = useCallback(
30
- (key) => {
31
- if (!onLayersChange) return;
32
- const current = key === "orbits" ? showOrbits : key === "labels" ? showLabels : showCoverage;
33
- onLayersChange({ ...layers ?? {}, [key]: !current });
34
- },
35
- [layers, onLayersChange, showLabels, showCoverage, showOrbits]
36
- );
37
- const toggleVisibility = useCallback(
38
- (key) => {
39
- if (!onVisibilityChange) return;
40
- const current = key === "spacecraft" ? showSpacecraft : key === "groundStations" ? showGroundStations : showCelestialBodies;
41
- onVisibilityChange({ ...visibility ?? {}, [key]: !current });
42
- },
43
- [visibility, onVisibilityChange, showSpacecraft, showGroundStations, showCelestialBodies]
44
- );
45
- const offX = (offset == null ? void 0 : offset.x) ?? 16;
46
- const offY = (offset == null ? void 0 : offset.y) ?? 16;
47
- const anchor = (() => {
48
- switch (position) {
49
- case "top-left":
50
- return { top: offY, left: offX };
51
- case "bottom-left":
52
- return { bottom: offY, left: offX };
53
- case "bottom-right":
54
- return { bottom: offY, right: offX };
55
- case "top-right":
56
- default:
57
- return { top: offY, right: offX };
58
- }
59
- })();
60
- if (hidden) return null;
61
- const showRender = !hideRenderFlags && onLayersChange != null;
62
- const showGroupsSection = !hideGroups && onVisibilityChange != null;
63
- const showCustom = !hideCustomLayers && ((customLayers == null ? void 0 : customLayers.length) ?? 0) > 0;
64
- if (!showRender && !showGroupsSection && !showCustom) return null;
65
- const cnt = (n) => typeof n === "number" ? ` (${n})` : "";
66
- return /* @__PURE__ */ jsxs(
67
- "div",
68
- {
69
- "data-testid": "zendir-layer-control",
70
- style: {
71
- position: "absolute",
72
- zIndex: 2,
73
- display: "flex",
74
- flexDirection: "column",
75
- gap: 6,
76
- padding: tokens.spacing.sm,
77
- borderRadius: ((_a = tokens.borderRadius) == null ? void 0 : _a.md) ?? 6,
78
- border: "1px solid rgba(255,255,255,0.12)",
79
- background: "rgba(0,0,0,0.72)",
80
- color: tokens.colors.text.primary,
81
- fontSize: tokens.typography.fontSize.xs,
82
- lineHeight: 1.2,
83
- ...anchor,
84
- ...style
85
- },
86
- children: [
87
- showRender && /* @__PURE__ */ jsxs(Section, { title: "Render", children: [
88
- /* @__PURE__ */ jsx(Toggle, { label: "Orbits", active: showOrbits, onClick: () => toggleLayer("orbits") }),
89
- /* @__PURE__ */ jsx(Toggle, { label: "Labels", active: showLabels, onClick: () => toggleLayer("labels") }),
90
- /* @__PURE__ */ jsx(Toggle, { label: "Coverage", active: showCoverage, onClick: () => toggleLayer("coverage") })
91
- ] }),
92
- showGroupsSection && /* @__PURE__ */ jsxs(Section, { title: "Objects", children: [
93
- /* @__PURE__ */ jsx(
94
- Toggle,
95
- {
96
- label: `Spacecraft${cnt(groupCounts == null ? void 0 : groupCounts.spacecraft)}`,
97
- active: showSpacecraft,
98
- onClick: () => toggleVisibility("spacecraft")
99
- }
100
- ),
101
- /* @__PURE__ */ jsx(
102
- Toggle,
103
- {
104
- label: `Ground Stations${cnt(groupCounts == null ? void 0 : groupCounts.groundStations)}`,
105
- active: showGroundStations,
106
- onClick: () => toggleVisibility("groundStations")
107
- }
108
- ),
109
- /* @__PURE__ */ jsx(
110
- Toggle,
111
- {
112
- label: `Celestial${cnt(groupCounts == null ? void 0 : groupCounts.celestialBodies)}`,
113
- active: showCelestialBodies,
114
- onClick: () => toggleVisibility("celestialBodies")
115
- }
116
- )
117
- ] }),
118
- showCustom && /* @__PURE__ */ jsx(Section, { title: "Overlays", children: (customLayers ?? []).map((layer) => /* @__PURE__ */ jsx(
119
- Toggle,
120
- {
121
- label: layer.label,
122
- active: (customLayerState == null ? void 0 : customLayerState[layer.id]) ?? layer.defaultEnabled ?? false,
123
- onClick: () => {
124
- const current = (customLayerState == null ? void 0 : customLayerState[layer.id]) ?? layer.defaultEnabled ?? false;
125
- onCustomLayerChange == null ? void 0 : onCustomLayerChange(layer.id, !current);
126
- }
127
- },
128
- layer.id
129
- )) })
130
- ]
131
- }
132
- );
2
+ import { memo, useCallback } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/react/panels/LayerControlPanel.tsx
5
+ /**
6
+ * @zendir/ui - LayerControlPanel
7
+ *
8
+ * Floating layer-toggle panel for the 3D viewer (mirrors the
9
+ * `MapLayerDef` pattern from `<GroundTrackMap />`). Three sections:
10
+ *
11
+ * 1. Render flags labels / coverage / orbits (HOW objects draw)
12
+ * 2. Object groups — spacecraft / GS / celestial (WHICH objects draw)
13
+ * 3. Custom layers — app-defined overlays (caller renders them)
14
+ *
15
+ * The panel is **toggle UI only**. It emits `onChange` callbacks; the
16
+ * consumer wires them to `<ZenSpace3D layers={...} visibility={...} />`
17
+ * (or to its own overlay state for custom layers). Same contract as
18
+ * `MapLayerDef` — keeps the panel reusable and the renderer
19
+ * untouched.
20
+ *
21
+ * ```tsx
22
+ * const [layers, setLayers] = useState({ orbits: true, labels: false, coverage: false });
23
+ * const [visibility, setVisibility] = useState({
24
+ * spacecraft: true, groundStations: true, celestialBodies: true,
25
+ * });
26
+ * const [customLayers, setCustomLayers] = useState<Record<string, boolean>>({ rf: false });
27
+ *
28
+ * <ZenSpace3D layers={layers} visibility={visibility} ... />
29
+ * <LayerControlPanel
30
+ * layers={layers}
31
+ * visibility={visibility}
32
+ * customLayers={[{ id: 'rf', label: 'RF Coverage' }]}
33
+ * customLayerState={customLayers}
34
+ * groupCounts={{ spacecraft: scene.satellites.length, ... }}
35
+ * onLayersChange={setLayers}
36
+ * onVisibilityChange={setVisibility}
37
+ * onCustomLayerChange={(id, on) => setCustomLayers((c) => ({ ...c, [id]: on }))}
38
+ * />
39
+ * ```
40
+ */
41
+ var LayerControlPanel = memo(function LayerControlPanel({ layers, onLayersChange, visibility, onVisibilityChange, groupCounts, customLayers, customLayerState, onCustomLayerChange, position = "top-right", offset, hidden = false, style, hideRenderFlags = false, hideGroups = false, hideCustomLayers = false }) {
42
+ const tokens = useThemeTokens();
43
+ const showLabels = layers?.labels === true;
44
+ const showCoverage = layers?.coverage === true;
45
+ const showOrbits = layers?.orbits !== false;
46
+ const showSpacecraft = visibility?.spacecraft !== false;
47
+ const showGroundStations = visibility?.groundStations !== false;
48
+ const showCelestialBodies = visibility?.celestialBodies !== false;
49
+ const toggleLayer = useCallback((key) => {
50
+ if (!onLayersChange) return;
51
+ const current = key === "orbits" ? showOrbits : key === "labels" ? showLabels : showCoverage;
52
+ onLayersChange({
53
+ ...layers ?? {},
54
+ [key]: !current
55
+ });
56
+ }, [
57
+ layers,
58
+ onLayersChange,
59
+ showLabels,
60
+ showCoverage,
61
+ showOrbits
62
+ ]);
63
+ const toggleVisibility = useCallback((key) => {
64
+ if (!onVisibilityChange) return;
65
+ const current = key === "spacecraft" ? showSpacecraft : key === "groundStations" ? showGroundStations : showCelestialBodies;
66
+ onVisibilityChange({
67
+ ...visibility ?? {},
68
+ [key]: !current
69
+ });
70
+ }, [
71
+ visibility,
72
+ onVisibilityChange,
73
+ showSpacecraft,
74
+ showGroundStations,
75
+ showCelestialBodies
76
+ ]);
77
+ const offX = offset?.x ?? 16;
78
+ const offY = offset?.y ?? 16;
79
+ const anchor = (() => {
80
+ switch (position) {
81
+ case "top-left": return {
82
+ top: offY,
83
+ left: offX
84
+ };
85
+ case "bottom-left": return {
86
+ bottom: offY,
87
+ left: offX
88
+ };
89
+ case "bottom-right": return {
90
+ bottom: offY,
91
+ right: offX
92
+ };
93
+ default: return {
94
+ top: offY,
95
+ right: offX
96
+ };
97
+ }
98
+ })();
99
+ if (hidden) return null;
100
+ const showRender = !hideRenderFlags && onLayersChange != null;
101
+ const showGroupsSection = !hideGroups && onVisibilityChange != null;
102
+ const showCustom = !hideCustomLayers && (customLayers?.length ?? 0) > 0;
103
+ if (!showRender && !showGroupsSection && !showCustom) return null;
104
+ const cnt = (n) => typeof n === "number" ? ` (${n})` : "";
105
+ return /* @__PURE__ */ jsxs("div", {
106
+ "data-testid": "zendir-layer-control",
107
+ style: {
108
+ position: "absolute",
109
+ zIndex: 2,
110
+ display: "flex",
111
+ flexDirection: "column",
112
+ gap: 6,
113
+ padding: tokens.spacing.sm,
114
+ borderRadius: tokens.borderRadius?.md ?? 6,
115
+ border: "1px solid rgba(255,255,255,0.12)",
116
+ background: "rgba(0,0,0,0.72)",
117
+ color: tokens.colors.text.primary,
118
+ fontSize: tokens.typography.fontSize.xs,
119
+ lineHeight: 1.2,
120
+ ...anchor,
121
+ ...style
122
+ },
123
+ children: [
124
+ showRender && /* @__PURE__ */ jsxs(Section, {
125
+ title: "Render",
126
+ children: [
127
+ /* @__PURE__ */ jsx(Toggle, {
128
+ label: "Orbits",
129
+ active: showOrbits,
130
+ onClick: () => toggleLayer("orbits")
131
+ }),
132
+ /* @__PURE__ */ jsx(Toggle, {
133
+ label: "Labels",
134
+ active: showLabels,
135
+ onClick: () => toggleLayer("labels")
136
+ }),
137
+ /* @__PURE__ */ jsx(Toggle, {
138
+ label: "Coverage",
139
+ active: showCoverage,
140
+ onClick: () => toggleLayer("coverage")
141
+ })
142
+ ]
143
+ }),
144
+ showGroupsSection && /* @__PURE__ */ jsxs(Section, {
145
+ title: "Objects",
146
+ children: [
147
+ /* @__PURE__ */ jsx(Toggle, {
148
+ label: `Spacecraft${cnt(groupCounts?.spacecraft)}`,
149
+ active: showSpacecraft,
150
+ onClick: () => toggleVisibility("spacecraft")
151
+ }),
152
+ /* @__PURE__ */ jsx(Toggle, {
153
+ label: `Ground Stations${cnt(groupCounts?.groundStations)}`,
154
+ active: showGroundStations,
155
+ onClick: () => toggleVisibility("groundStations")
156
+ }),
157
+ /* @__PURE__ */ jsx(Toggle, {
158
+ label: `Celestial${cnt(groupCounts?.celestialBodies)}`,
159
+ active: showCelestialBodies,
160
+ onClick: () => toggleVisibility("celestialBodies")
161
+ })
162
+ ]
163
+ }),
164
+ showCustom && /* @__PURE__ */ jsx(Section, {
165
+ title: "Overlays",
166
+ children: (customLayers ?? []).map((layer) => /* @__PURE__ */ jsx(Toggle, {
167
+ label: layer.label,
168
+ active: customLayerState?.[layer.id] ?? layer.defaultEnabled ?? false,
169
+ onClick: () => {
170
+ const current = customLayerState?.[layer.id] ?? layer.defaultEnabled ?? false;
171
+ onCustomLayerChange?.(layer.id, !current);
172
+ }
173
+ }, layer.id))
174
+ })
175
+ ]
176
+ });
133
177
  });
134
- const Section = ({ title, children }) => {
135
- const tokens = useThemeTokens();
136
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
137
- /* @__PURE__ */ jsx(
138
- "div",
139
- {
140
- style: {
141
- opacity: 0.6,
142
- fontSize: "0.85em",
143
- textTransform: "uppercase",
144
- letterSpacing: 0.5,
145
- color: tokens.colors.text.secondary
146
- },
147
- children: title
148
- }
149
- ),
150
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children })
151
- ] });
152
- };
153
- const Toggle = ({
154
- label,
155
- active,
156
- onClick
157
- }) => {
158
- var _a;
159
- const tokens = useThemeTokens();
160
- return /* @__PURE__ */ jsx(
161
- "button",
162
- {
163
- type: "button",
164
- onClick,
165
- "aria-pressed": active,
166
- style: {
167
- padding: `${tokens.spacing.xs}px ${tokens.spacing.sm}px`,
168
- borderRadius: ((_a = tokens.borderRadius) == null ? void 0 : _a.sm) ?? 4,
169
- background: active ? "rgba(100,200,255,0.2)" : "rgba(0,0,0,0.6)",
170
- border: `1px solid ${active ? "rgba(100,200,255,0.6)" : "rgba(255,255,255,0.15)"}`,
171
- color: active ? "rgba(100,200,255,1)" : tokens.colors.text.secondary,
172
- fontSize: tokens.typography.fontSize.xs,
173
- cursor: "pointer",
174
- letterSpacing: 0.3,
175
- textAlign: "left"
176
- },
177
- children: label
178
- }
179
- );
178
+ var Section = ({ title, children }) => {
179
+ return /* @__PURE__ */ jsxs("div", {
180
+ style: {
181
+ display: "flex",
182
+ flexDirection: "column",
183
+ gap: 4
184
+ },
185
+ children: [/* @__PURE__ */ jsx("div", {
186
+ style: {
187
+ opacity: .6,
188
+ fontSize: "0.85em",
189
+ textTransform: "uppercase",
190
+ letterSpacing: .5,
191
+ color: useThemeTokens().colors.text.secondary
192
+ },
193
+ children: title
194
+ }), /* @__PURE__ */ jsx("div", {
195
+ style: {
196
+ display: "flex",
197
+ flexDirection: "column",
198
+ gap: 4
199
+ },
200
+ children
201
+ })]
202
+ });
180
203
  };
181
- export {
182
- LayerControlPanel
204
+ var Toggle = ({ label, active, onClick }) => {
205
+ const tokens = useThemeTokens();
206
+ return /* @__PURE__ */ jsx("button", {
207
+ type: "button",
208
+ onClick,
209
+ "aria-pressed": active,
210
+ style: {
211
+ padding: `${tokens.spacing.xs}px ${tokens.spacing.sm}px`,
212
+ borderRadius: tokens.borderRadius?.sm ?? 4,
213
+ background: active ? "rgba(100,200,255,0.2)" : "rgba(0,0,0,0.6)",
214
+ border: `1px solid ${active ? "rgba(100,200,255,0.6)" : "rgba(255,255,255,0.15)"}`,
215
+ color: active ? "rgba(100,200,255,1)" : tokens.colors.text.secondary,
216
+ fontSize: tokens.typography.fontSize.xs,
217
+ cursor: "pointer",
218
+ letterSpacing: .3,
219
+ textAlign: "left"
220
+ },
221
+ children: label
222
+ });
183
223
  };
184
- //# sourceMappingURL=LayerControlPanel.js.map
224
+ //#endregion
225
+ export { LayerControlPanel, LayerControlPanel as default };
226
+
227
+ //# sourceMappingURL=LayerControlPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LayerControlPanel.js","sources":["../../../src/react/panels/LayerControlPanel.tsx"],"sourcesContent":["/**\n * @zendir/ui - LayerControlPanel\n *\n * Floating layer-toggle panel for the 3D viewer (mirrors the\n * `MapLayerDef` pattern from `<GroundTrackMap />`). Three sections:\n *\n * 1. Render flags — labels / coverage / orbits (HOW objects draw)\n * 2. Object groups — spacecraft / GS / celestial (WHICH objects draw)\n * 3. Custom layers — app-defined overlays (caller renders them)\n *\n * The panel is **toggle UI only**. It emits `onChange` callbacks; the\n * consumer wires them to `<ZenSpace3D layers={...} visibility={...} />`\n * (or to its own overlay state for custom layers). Same contract as\n * `MapLayerDef` — keeps the panel reusable and the renderer\n * untouched.\n *\n * ```tsx\n * const [layers, setLayers] = useState({ orbits: true, labels: false, coverage: false });\n * const [visibility, setVisibility] = useState({\n * spacecraft: true, groundStations: true, celestialBodies: true,\n * });\n * const [customLayers, setCustomLayers] = useState<Record<string, boolean>>({ rf: false });\n *\n * <ZenSpace3D layers={layers} visibility={visibility} ... />\n * <LayerControlPanel\n * layers={layers}\n * visibility={visibility}\n * customLayers={[{ id: 'rf', label: 'RF Coverage' }]}\n * customLayerState={customLayers}\n * groupCounts={{ spacecraft: scene.satellites.length, ... }}\n * onLayersChange={setLayers}\n * onVisibilityChange={setVisibility}\n * onCustomLayerChange={(id, on) => setCustomLayers((c) => ({ ...c, [id]: on }))}\n * />\n * ```\n */\n\nimport { memo, useCallback } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useThemeTokens } from '../theme/ThemeProvider';\nimport type { LayerDef } from '../types';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** Render-flag layers — passed straight through to `<ZenSpace3D layers={...} />`. */\nexport interface RenderLayers {\n labels?: boolean;\n coverage?: boolean;\n orbits?: boolean;\n}\n\n/** Object-group visibility — passed straight through to `<ZenSpace3D visibility={...} />`. */\nexport interface GroupVisibility {\n spacecraft?: boolean;\n groundStations?: boolean;\n celestialBodies?: boolean;\n}\n\n/** Counts shown in the group toggles (\"Spacecraft (5)\"). All optional. */\nexport interface GroupCounts {\n spacecraft?: number;\n groundStations?: number;\n celestialBodies?: number;\n}\n\nexport interface LayerControlPanelProps {\n // ─── Render flags ─────────────────────────────────────────────────────────\n /** Current render-flag state. Each key defaults to: orbits=on, labels=off, coverage=off. */\n layers?: RenderLayers;\n /** Called with the next render-flag state when any toggle is clicked. */\n onLayersChange?: (next: RenderLayers) => void;\n\n // ─── Object-group visibility ──────────────────────────────────────────────\n /** Current group-visibility state. Each key defaults to true (visible). */\n visibility?: GroupVisibility;\n /** Called with the next visibility state when any toggle is clicked. */\n onVisibilityChange?: (next: GroupVisibility) => void;\n /** Counts to render in group toggle labels (e.g. \"Spacecraft (5)\"). */\n groupCounts?: GroupCounts;\n\n // ─── Custom layers (app-defined overlays) ─────────────────────────────────\n /** App-defined layer toggles. The panel only renders the toggle UI. */\n customLayers?: LayerDef[];\n /** Current state of each custom layer (id → on/off). */\n customLayerState?: Record<string, boolean>;\n /** Fires when a custom layer is toggled. The consumer renders the overlay itself. */\n onCustomLayerChange?: (id: string, enabled: boolean) => void;\n\n // ─── Layout / theming ─────────────────────────────────────────────────────\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n offset?: { x?: number; y?: number };\n hidden?: boolean;\n style?: CSSProperties;\n\n /** Hide the render-flags section (`true` to suppress). */\n hideRenderFlags?: boolean;\n /** Hide the object-group section. */\n hideGroups?: boolean;\n /** Hide the custom-layers section even if `customLayers` is non-empty. */\n hideCustomLayers?: boolean;\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nexport const LayerControlPanel = memo(function LayerControlPanel({\n layers,\n onLayersChange,\n visibility,\n onVisibilityChange,\n groupCounts,\n customLayers,\n customLayerState,\n onCustomLayerChange,\n position = 'top-right',\n offset,\n hidden = false,\n style,\n hideRenderFlags = false,\n hideGroups = false,\n hideCustomLayers = false,\n}: LayerControlPanelProps) {\n const tokens = useThemeTokens();\n\n // Default render-flag state — matches ZenSpace3D's defaults.\n const showLabels = layers?.labels === true;\n const showCoverage = layers?.coverage === true;\n const showOrbits = layers?.orbits !== false;\n\n // Default group-visibility — matches ZenSpace3D's defaults (everything on).\n const showSpacecraft = visibility?.spacecraft !== false;\n const showGroundStations = visibility?.groundStations !== false;\n const showCelestialBodies = visibility?.celestialBodies !== false;\n\n const toggleLayer = useCallback(\n (key: keyof RenderLayers) => {\n if (!onLayersChange) return;\n const current =\n key === 'orbits'\n ? showOrbits\n : key === 'labels'\n ? showLabels\n : showCoverage;\n onLayersChange({ ...(layers ?? {}), [key]: !current });\n },\n [layers, onLayersChange, showLabels, showCoverage, showOrbits],\n );\n\n const toggleVisibility = useCallback(\n (key: keyof GroupVisibility) => {\n if (!onVisibilityChange) return;\n const current =\n key === 'spacecraft'\n ? showSpacecraft\n : key === 'groundStations'\n ? showGroundStations\n : showCelestialBodies;\n onVisibilityChange({ ...(visibility ?? {}), [key]: !current });\n },\n [visibility, onVisibilityChange, showSpacecraft, showGroundStations, showCelestialBodies],\n );\n\n const offX = offset?.x ?? 16;\n const offY = offset?.y ?? 16;\n const anchor: CSSProperties = (() => {\n switch (position) {\n case 'top-left': return { top: offY, left: offX };\n case 'bottom-left': return { bottom: offY, left: offX };\n case 'bottom-right': return { bottom: offY, right: offX };\n case 'top-right':\n default: return { top: offY, right: offX };\n }\n })();\n\n if (hidden) return null;\n\n const showRender = !hideRenderFlags && onLayersChange != null;\n const showGroupsSection = !hideGroups && onVisibilityChange != null;\n const showCustom = !hideCustomLayers && (customLayers?.length ?? 0) > 0;\n\n if (!showRender && !showGroupsSection && !showCustom) return null;\n\n const cnt = (n: number | undefined) =>\n typeof n === 'number' ? ` (${n})` : '';\n\n return (\n <div\n data-testid=\"zendir-layer-control\"\n style={{\n position: 'absolute',\n zIndex: 2,\n display: 'flex',\n flexDirection: 'column',\n gap: 6,\n padding: tokens.spacing.sm,\n borderRadius: tokens.borderRadius?.md ?? 6,\n border: '1px solid rgba(255,255,255,0.12)',\n background: 'rgba(0,0,0,0.72)',\n color: tokens.colors.text.primary,\n fontSize: tokens.typography.fontSize.xs,\n lineHeight: 1.2,\n ...anchor,\n ...style,\n }}\n >\n {showRender && (\n <Section title=\"Render\">\n <Toggle label=\"Orbits\" active={showOrbits} onClick={() => toggleLayer('orbits')} />\n <Toggle label=\"Labels\" active={showLabels} onClick={() => toggleLayer('labels')} />\n <Toggle label=\"Coverage\" active={showCoverage} onClick={() => toggleLayer('coverage')} />\n </Section>\n )}\n\n {showGroupsSection && (\n <Section title=\"Objects\">\n <Toggle\n label={`Spacecraft${cnt(groupCounts?.spacecraft)}`}\n active={showSpacecraft}\n onClick={() => toggleVisibility('spacecraft')}\n />\n <Toggle\n label={`Ground Stations${cnt(groupCounts?.groundStations)}`}\n active={showGroundStations}\n onClick={() => toggleVisibility('groundStations')}\n />\n <Toggle\n label={`Celestial${cnt(groupCounts?.celestialBodies)}`}\n active={showCelestialBodies}\n onClick={() => toggleVisibility('celestialBodies')}\n />\n </Section>\n )}\n\n {showCustom && (\n <Section title=\"Overlays\">\n {(customLayers ?? []).map((layer) => (\n <Toggle\n key={layer.id}\n label={layer.label}\n active={\n customLayerState?.[layer.id] ??\n layer.defaultEnabled ??\n false\n }\n onClick={() => {\n const current =\n customLayerState?.[layer.id] ??\n layer.defaultEnabled ??\n false;\n onCustomLayerChange?.(layer.id, !current);\n }}\n />\n ))}\n </Section>\n )}\n </div>\n );\n});\n\n// ─── Sub-components ───────────────────────────────────────────────────────────\n\nconst Section = ({ title, children }: { title: string; children: ReactNode }) => {\n const tokens = useThemeTokens();\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>\n <div\n style={{\n opacity: 0.6,\n fontSize: '0.85em',\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n color: tokens.colors.text.secondary,\n }}\n >\n {title}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>{children}</div>\n </div>\n );\n};\n\nconst Toggle = ({\n label,\n active,\n onClick,\n}: {\n label: string;\n active: boolean;\n onClick: () => void;\n}) => {\n const tokens = useThemeTokens();\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-pressed={active}\n style={{\n padding: `${tokens.spacing.xs}px ${tokens.spacing.sm}px`,\n borderRadius: tokens.borderRadius?.sm ?? 4,\n background: active ? 'rgba(100,200,255,0.2)' : 'rgba(0,0,0,0.6)',\n border: `1px solid ${active ? 'rgba(100,200,255,0.6)' : 'rgba(255,255,255,0.15)'}`,\n color: active ? 'rgba(100,200,255,1)' : tokens.colors.text.secondary,\n fontSize: tokens.typography.fontSize.xs,\n cursor: 'pointer',\n letterSpacing: 0.3,\n textAlign: 'left',\n }}\n >\n {label}\n </button>\n );\n};\n\nexport default LayerControlPanel;\n"],"names":["LayerControlPanel"],"mappings":";;;AAwGO,MAAM,oBAAoB,KAAK,SAASA,mBAAkB;AAAA,EAC/D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,mBAAmB;AACrB,GAA2B;;AACzB,QAAM,SAAS,eAAA;AAGf,QAAM,cAAe,iCAAQ,YAAa;AAC1C,QAAM,gBAAe,iCAAQ,cAAa;AAC1C,QAAM,cAAe,iCAAQ,YAAa;AAG1C,QAAM,kBAAsB,yCAAY,gBAAoB;AAC5D,QAAM,sBAAsB,yCAAY,oBAAoB;AAC5D,QAAM,uBAAsB,yCAAY,qBAAoB;AAE5D,QAAM,cAAc;AAAA,IAClB,CAAC,QAA4B;AAC3B,UAAI,CAAC,eAAgB;AACrB,YAAM,UACJ,QAAQ,WACJ,aACA,QAAQ,WACN,aACA;AACR,qBAAe,EAAE,GAAI,UAAU,CAAA,GAAK,CAAC,GAAG,GAAG,CAAC,SAAS;AAAA,IACvD;AAAA,IACA,CAAC,QAAQ,gBAAgB,YAAY,cAAc,UAAU;AAAA,EAAA;AAG/D,QAAM,mBAAmB;AAAA,IACvB,CAAC,QAA+B;AAC9B,UAAI,CAAC,mBAAoB;AACzB,YAAM,UACJ,QAAQ,eACJ,iBACA,QAAQ,mBACN,qBACA;AACR,yBAAmB,EAAE,GAAI,cAAc,CAAA,GAAK,CAAC,GAAG,GAAG,CAAC,SAAS;AAAA,IAC/D;AAAA,IACA,CAAC,YAAY,oBAAoB,gBAAgB,oBAAoB,mBAAmB;AAAA,EAAA;AAG1F,QAAM,QAAO,iCAAQ,MAAK;AAC1B,QAAM,QAAO,iCAAQ,MAAK;AAC1B,QAAM,UAAyB,MAAM;AACnC,YAAQ,UAAA;AAAA,MACN,KAAK;AAAgB,eAAO,EAAE,KAAK,MAAM,MAAM,KAAA;AAAA,MAC/C,KAAK;AAAgB,eAAO,EAAE,QAAQ,MAAM,MAAM,KAAA;AAAA,MAClD,KAAK;AAAgB,eAAO,EAAE,QAAQ,MAAM,OAAO,KAAA;AAAA,MACnD,KAAK;AAAA,MACL;AAAqB,eAAO,EAAE,KAAK,MAAM,OAAO,KAAA;AAAA,IAAK;AAAA,EAEzD,GAAA;AAEA,MAAI,OAAQ,QAAO;AAEnB,QAAM,aAAa,CAAC,mBAAmB,kBAAkB;AACzD,QAAM,oBAAoB,CAAC,cAAc,sBAAsB;AAC/D,QAAM,aAAa,CAAC,sBAAqB,6CAAc,WAAU,KAAK;AAEtE,MAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC,WAAY,QAAO;AAE7D,QAAM,MAAM,CAAC,MACX,OAAO,MAAM,WAAW,KAAK,CAAC,MAAM;AAEtC,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,eAAY;AAAA,MACZ,OAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,eAAe;AAAA,QACf,KAAK;AAAA,QACL,SAAS,OAAO,QAAQ;AAAA,QACxB,gBAAc,YAAO,iBAAP,mBAAqB,OAAM;AAAA,QACzC,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,OAAO,OAAO,OAAO,KAAK;AAAA,QAC1B,UAAU,OAAO,WAAW,SAAS;AAAA,QACrC,YAAY;AAAA,QACZ,GAAG;AAAA,QACH,GAAG;AAAA,MAAA;AAAA,MAGJ,UAAA;AAAA,QAAA,cACC,qBAAC,SAAA,EAAQ,OAAM,UACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAO,OAAM,UAAW,QAAQ,YAAc,SAAS,MAAM,YAAY,QAAQ,EAAA,CAAG;AAAA,UACrF,oBAAC,QAAA,EAAO,OAAM,UAAW,QAAQ,YAAc,SAAS,MAAM,YAAY,QAAQ,EAAA,CAAG;AAAA,UACrF,oBAAC,QAAA,EAAO,OAAM,YAAW,QAAQ,cAAc,SAAS,MAAM,YAAY,UAAU,EAAA,CAAG;AAAA,QAAA,GACzF;AAAA,QAGD,qBACC,qBAAC,SAAA,EAAQ,OAAM,WACb,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,aAAa,IAAI,2CAAa,UAAU,CAAC;AAAA,cAChD,QAAQ;AAAA,cACR,SAAS,MAAM,iBAAiB,YAAY;AAAA,YAAA;AAAA,UAAA;AAAA,UAE9C;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,kBAAkB,IAAI,2CAAa,cAAc,CAAC;AAAA,cACzD,QAAQ;AAAA,cACR,SAAS,MAAM,iBAAiB,gBAAgB;AAAA,YAAA;AAAA,UAAA;AAAA,UAElD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAO,YAAY,IAAI,2CAAa,eAAe,CAAC;AAAA,cACpD,QAAQ;AAAA,cACR,SAAS,MAAM,iBAAiB,iBAAiB;AAAA,YAAA;AAAA,UAAA;AAAA,QACnD,GACF;AAAA,QAGD,cACC,oBAAC,SAAA,EAAQ,OAAM,YACX,2BAAgB,CAAA,GAAI,IAAI,CAAC,UACzB;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,OAAO,MAAM;AAAA,YACb,SACE,qDAAmB,MAAM,QACzB,MAAM,kBACN;AAAA,YAEF,SAAS,MAAM;AACb,oBAAM,WACJ,qDAAmB,MAAM,QACzB,MAAM,kBACN;AACF,yEAAsB,MAAM,IAAI,CAAC;AAAA,YACnC;AAAA,UAAA;AAAA,UAbK,MAAM;AAAA,QAAA,CAed,EAAA,CACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;AAID,MAAM,UAAU,CAAC,EAAE,OAAO,eAAuD;AAC/E,QAAM,SAAS,eAAA;AACf,SACE,qBAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAA,GAC3D,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,UACV,eAAe;AAAA,UACf,eAAe;AAAA,UACf,OAAO,OAAO,OAAO,KAAK;AAAA,QAAA;AAAA,QAG3B,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEH,oBAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAA,GAAM,SAAA,CAAS;AAAA,EAAA,GAC9E;AAEJ;AAEA,MAAM,SAAS,CAAC;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,MAIM;;AACJ,QAAM,SAAS,eAAA;AACf,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL;AAAA,MACA,gBAAc;AAAA,MACd,OAAO;AAAA,QACL,SAAS,GAAG,OAAO,QAAQ,EAAE,MAAM,OAAO,QAAQ,EAAE;AAAA,QACpD,gBAAc,YAAO,iBAAP,mBAAqB,OAAM;AAAA,QACzC,YAAY,SAAS,0BAA0B;AAAA,QAC/C,QAAQ,aAAa,SAAS,0BAA0B,wBAAwB;AAAA,QAChF,OAAO,SAAS,wBAAwB,OAAO,OAAO,KAAK;AAAA,QAC3D,UAAU,OAAO,WAAW,SAAS;AAAA,QACrC,QAAQ;AAAA,QACR,eAAe;AAAA,QACf,WAAW;AAAA,MAAA;AAAA,MAGZ,UAAA;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"LayerControlPanel.js","names":[],"sources":["../../../src/react/panels/LayerControlPanel.tsx"],"sourcesContent":["/**\n * @zendir/ui - LayerControlPanel\n *\n * Floating layer-toggle panel for the 3D viewer (mirrors the\n * `MapLayerDef` pattern from `<GroundTrackMap />`). Three sections:\n *\n * 1. Render flags — labels / coverage / orbits (HOW objects draw)\n * 2. Object groups — spacecraft / GS / celestial (WHICH objects draw)\n * 3. Custom layers — app-defined overlays (caller renders them)\n *\n * The panel is **toggle UI only**. It emits `onChange` callbacks; the\n * consumer wires them to `<ZenSpace3D layers={...} visibility={...} />`\n * (or to its own overlay state for custom layers). Same contract as\n * `MapLayerDef` — keeps the panel reusable and the renderer\n * untouched.\n *\n * ```tsx\n * const [layers, setLayers] = useState({ orbits: true, labels: false, coverage: false });\n * const [visibility, setVisibility] = useState({\n * spacecraft: true, groundStations: true, celestialBodies: true,\n * });\n * const [customLayers, setCustomLayers] = useState<Record<string, boolean>>({ rf: false });\n *\n * <ZenSpace3D layers={layers} visibility={visibility} ... />\n * <LayerControlPanel\n * layers={layers}\n * visibility={visibility}\n * customLayers={[{ id: 'rf', label: 'RF Coverage' }]}\n * customLayerState={customLayers}\n * groupCounts={{ spacecraft: scene.satellites.length, ... }}\n * onLayersChange={setLayers}\n * onVisibilityChange={setVisibility}\n * onCustomLayerChange={(id, on) => setCustomLayers((c) => ({ ...c, [id]: on }))}\n * />\n * ```\n */\n\nimport { memo, useCallback } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { useThemeTokens } from \"../theme/ThemeProvider\";\nimport type { LayerDef } from \"../types\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** Render-flag layers — passed straight through to `<ZenSpace3D layers={...} />`. */\nexport interface RenderLayers {\n labels?: boolean;\n coverage?: boolean;\n orbits?: boolean;\n}\n\n/** Object-group visibility — passed straight through to `<ZenSpace3D visibility={...} />`. */\nexport interface GroupVisibility {\n spacecraft?: boolean;\n groundStations?: boolean;\n celestialBodies?: boolean;\n}\n\n/** Counts shown in the group toggles (\"Spacecraft (5)\"). All optional. */\nexport interface GroupCounts {\n spacecraft?: number;\n groundStations?: number;\n celestialBodies?: number;\n}\n\nexport interface LayerControlPanelProps {\n // ─── Render flags ─────────────────────────────────────────────────────────\n /** Current render-flag state. Each key defaults to: orbits=on, labels=off, coverage=off. */\n layers?: RenderLayers;\n /** Called with the next render-flag state when any toggle is clicked. */\n onLayersChange?: (next: RenderLayers) => void;\n\n // ─── Object-group visibility ──────────────────────────────────────────────\n /** Current group-visibility state. Each key defaults to true (visible). */\n visibility?: GroupVisibility;\n /** Called with the next visibility state when any toggle is clicked. */\n onVisibilityChange?: (next: GroupVisibility) => void;\n /** Counts to render in group toggle labels (e.g. \"Spacecraft (5)\"). */\n groupCounts?: GroupCounts;\n\n // ─── Custom layers (app-defined overlays) ─────────────────────────────────\n /** App-defined layer toggles. The panel only renders the toggle UI. */\n customLayers?: LayerDef[];\n /** Current state of each custom layer (id → on/off). */\n customLayerState?: Record<string, boolean>;\n /** Fires when a custom layer is toggled. The consumer renders the overlay itself. */\n onCustomLayerChange?: (id: string, enabled: boolean) => void;\n\n // ─── Layout / theming ─────────────────────────────────────────────────────\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n offset?: { x?: number; y?: number };\n hidden?: boolean;\n style?: CSSProperties;\n\n /** Hide the render-flags section (`true` to suppress). */\n hideRenderFlags?: boolean;\n /** Hide the object-group section. */\n hideGroups?: boolean;\n /** Hide the custom-layers section even if `customLayers` is non-empty. */\n hideCustomLayers?: boolean;\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nexport const LayerControlPanel = memo(function LayerControlPanel({\n layers,\n onLayersChange,\n visibility,\n onVisibilityChange,\n groupCounts,\n customLayers,\n customLayerState,\n onCustomLayerChange,\n position = \"top-right\",\n offset,\n hidden = false,\n style,\n hideRenderFlags = false,\n hideGroups = false,\n hideCustomLayers = false,\n}: LayerControlPanelProps) {\n const tokens = useThemeTokens();\n\n // Default render-flag state — matches ZenSpace3D's defaults.\n const showLabels = layers?.labels === true;\n const showCoverage = layers?.coverage === true;\n const showOrbits = layers?.orbits !== false;\n\n // Default group-visibility — matches ZenSpace3D's defaults (everything on).\n const showSpacecraft = visibility?.spacecraft !== false;\n const showGroundStations = visibility?.groundStations !== false;\n const showCelestialBodies = visibility?.celestialBodies !== false;\n\n const toggleLayer = useCallback(\n (key: keyof RenderLayers) => {\n if (!onLayersChange) return;\n const current =\n key === \"orbits\"\n ? showOrbits\n : key === \"labels\"\n ? showLabels\n : showCoverage;\n onLayersChange({ ...(layers ?? {}), [key]: !current });\n },\n [layers, onLayersChange, showLabels, showCoverage, showOrbits],\n );\n\n const toggleVisibility = useCallback(\n (key: keyof GroupVisibility) => {\n if (!onVisibilityChange) return;\n const current =\n key === \"spacecraft\"\n ? showSpacecraft\n : key === \"groundStations\"\n ? showGroundStations\n : showCelestialBodies;\n onVisibilityChange({ ...(visibility ?? {}), [key]: !current });\n },\n [\n visibility,\n onVisibilityChange,\n showSpacecraft,\n showGroundStations,\n showCelestialBodies,\n ],\n );\n\n const offX = offset?.x ?? 16;\n const offY = offset?.y ?? 16;\n const anchor: CSSProperties = (() => {\n switch (position) {\n case \"top-left\":\n return { top: offY, left: offX };\n case \"bottom-left\":\n return { bottom: offY, left: offX };\n case \"bottom-right\":\n return { bottom: offY, right: offX };\n case \"top-right\":\n default:\n return { top: offY, right: offX };\n }\n })();\n\n if (hidden) return null;\n\n const showRender = !hideRenderFlags && onLayersChange != null;\n const showGroupsSection = !hideGroups && onVisibilityChange != null;\n const showCustom = !hideCustomLayers && (customLayers?.length ?? 0) > 0;\n\n if (!showRender && !showGroupsSection && !showCustom) return null;\n\n const cnt = (n: number | undefined) =>\n typeof n === \"number\" ? ` (${n})` : \"\";\n\n return (\n <div\n data-testid=\"zendir-layer-control\"\n style={{\n position: \"absolute\",\n zIndex: 2,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n padding: tokens.spacing.sm,\n borderRadius: tokens.borderRadius?.md ?? 6,\n border: \"1px solid rgba(255,255,255,0.12)\",\n background: \"rgba(0,0,0,0.72)\",\n color: tokens.colors.text.primary,\n fontSize: tokens.typography.fontSize.xs,\n lineHeight: 1.2,\n ...anchor,\n ...style,\n }}\n >\n {showRender && (\n <Section title=\"Render\">\n <Toggle\n label=\"Orbits\"\n active={showOrbits}\n onClick={() => toggleLayer(\"orbits\")}\n />\n <Toggle\n label=\"Labels\"\n active={showLabels}\n onClick={() => toggleLayer(\"labels\")}\n />\n <Toggle\n label=\"Coverage\"\n active={showCoverage}\n onClick={() => toggleLayer(\"coverage\")}\n />\n </Section>\n )}\n\n {showGroupsSection && (\n <Section title=\"Objects\">\n <Toggle\n label={`Spacecraft${cnt(groupCounts?.spacecraft)}`}\n active={showSpacecraft}\n onClick={() => toggleVisibility(\"spacecraft\")}\n />\n <Toggle\n label={`Ground Stations${cnt(groupCounts?.groundStations)}`}\n active={showGroundStations}\n onClick={() => toggleVisibility(\"groundStations\")}\n />\n <Toggle\n label={`Celestial${cnt(groupCounts?.celestialBodies)}`}\n active={showCelestialBodies}\n onClick={() => toggleVisibility(\"celestialBodies\")}\n />\n </Section>\n )}\n\n {showCustom && (\n <Section title=\"Overlays\">\n {(customLayers ?? []).map((layer) => (\n <Toggle\n key={layer.id}\n label={layer.label}\n active={\n customLayerState?.[layer.id] ?? layer.defaultEnabled ?? false\n }\n onClick={() => {\n const current =\n customLayerState?.[layer.id] ?? layer.defaultEnabled ?? false;\n onCustomLayerChange?.(layer.id, !current);\n }}\n />\n ))}\n </Section>\n )}\n </div>\n );\n});\n\n// ─── Sub-components ───────────────────────────────────────────────────────────\n\nconst Section = ({\n title,\n children,\n}: {\n title: string;\n children: ReactNode;\n}) => {\n const tokens = useThemeTokens();\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n <div\n style={{\n opacity: 0.6,\n fontSize: \"0.85em\",\n textTransform: \"uppercase\",\n letterSpacing: 0.5,\n color: tokens.colors.text.secondary,\n }}\n >\n {title}\n </div>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n {children}\n </div>\n </div>\n );\n};\n\nconst Toggle = ({\n label,\n active,\n onClick,\n}: {\n label: string;\n active: boolean;\n onClick: () => void;\n}) => {\n const tokens = useThemeTokens();\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-pressed={active}\n style={{\n padding: `${tokens.spacing.xs}px ${tokens.spacing.sm}px`,\n borderRadius: tokens.borderRadius?.sm ?? 4,\n background: active ? \"rgba(100,200,255,0.2)\" : \"rgba(0,0,0,0.6)\",\n border: `1px solid ${active ? \"rgba(100,200,255,0.6)\" : \"rgba(255,255,255,0.15)\"}`,\n color: active ? \"rgba(100,200,255,1)\" : tokens.colors.text.secondary,\n fontSize: tokens.typography.fontSize.xs,\n cursor: \"pointer\",\n letterSpacing: 0.3,\n textAlign: \"left\",\n }}\n >\n {label}\n </button>\n );\n};\n\nexport default LayerControlPanel;\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
2
  import { SimulationSceneObject, StructureDiag, PositionTickDiag } from '../hooks/useSimulationScene';
3
-
4
- export type ObjectInventoryKind = SimulationSceneObject['kind'];
3
+ export type ObjectInventoryKind = SimulationSceneObject["kind"];
5
4
  export interface ObjectInventoryPanelProps {
6
5
  /** Objects to list. Typically `useSimulationScene().objects`. */
7
6
  objects: SimulationSceneObject[];
@@ -11,7 +10,7 @@ export interface ObjectInventoryPanelProps {
11
10
  /** Currently selected object id (highlights the row). Pass `null` for none. */
12
11
  selectedId?: string | null;
13
12
  /** Where to anchor the panel on its parent. Default: `top-left`. */
14
- position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
13
+ position?: "top-left" | "top-right" | "bottom-left" | "bottom-right";
15
14
  /** Pixel offsets from the anchor. Defaults to (16, 56) so a top bar fits above. */
16
15
  offset?: {
17
16
  x?: number;