@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.
- package/CHANGELOG.md +20 -0
- package/README.md +640 -631
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.js +17 -221
- package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
- package/dist/react/3d/CesiumCaptureSource.js +364 -283
- package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
- package/dist/react/3d/ZenSpace3D.d.ts +2 -3
- package/dist/react/3d/ZenSpace3D.js +1681 -1237
- package/dist/react/3d/ZenSpace3D.js.map +1 -1
- package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
- package/dist/react/3d/ZenSpace3DCesium.js +513 -560
- package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
- package/dist/react/3d/ZenSpace3DShaders.js +61 -66
- package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
- package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
- package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
- package/dist/react/3d/ZenSpace3DUtils.js +37 -24
- package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
- package/dist/react/3d/capturePngAnalysis.js +42 -36
- package/dist/react/3d/capturePngAnalysis.js.map +1 -1
- package/dist/react/3d/index.d.ts +3 -3
- package/dist/react/3d/index.js +5 -53
- package/dist/react/3d/threeLoader.d.ts +1 -1
- package/dist/react/3d/threeLoader.js +23 -18
- package/dist/react/3d/threeLoader.js.map +1 -1
- package/dist/react/astro/ClassificationBanner.d.ts +2 -3
- package/dist/react/astro/ClassificationBanner.js +95 -79
- package/dist/react/astro/ClassificationBanner.js.map +1 -1
- package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
- package/dist/react/astro/GlobalStatusBar.js +157 -163
- package/dist/react/astro/GlobalStatusBar.js.map +1 -1
- package/dist/react/astro/MissionClock.d.ts +7 -8
- package/dist/react/astro/MissionClock.js +377 -400
- package/dist/react/astro/MissionClock.js.map +1 -1
- package/dist/react/astro/MonitoringIcon.d.ts +1 -2
- package/dist/react/astro/MonitoringIcon.js +422 -358
- package/dist/react/astro/MonitoringIcon.js.map +1 -1
- package/dist/react/astro/Notification.d.ts +1 -2
- package/dist/react/astro/Notification.js +229 -126
- package/dist/react/astro/Notification.js.map +1 -1
- package/dist/react/astro/Progress.d.ts +0 -1
- package/dist/react/astro/Progress.js +199 -141
- package/dist/react/astro/Progress.js.map +1 -1
- package/dist/react/astro/SimulationControls.d.ts +3 -4
- package/dist/react/astro/SimulationControls.js +596 -650
- package/dist/react/astro/SimulationControls.js.map +1 -1
- package/dist/react/astro/StatusIndicator.d.ts +0 -1
- package/dist/react/astro/StatusIndicator.js +236 -170
- package/dist/react/astro/StatusIndicator.js.map +1 -1
- package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
- package/dist/react/astro/UnifiedTimeline.js +2345 -2392
- package/dist/react/astro/UnifiedTimeline.js.map +1 -1
- package/dist/react/astro/index.d.ts +5 -5
- package/dist/react/astro/index.js +1 -25
- package/dist/react/cards/AccessCard.d.ts +0 -1
- package/dist/react/cards/AccessCard.js +471 -405
- package/dist/react/cards/AccessCard.js.map +1 -1
- package/dist/react/cards/OrbitCard.d.ts +0 -1
- package/dist/react/cards/OrbitCard.js +487 -364
- package/dist/react/cards/OrbitCard.js.map +1 -1
- package/dist/react/cards/SpacecraftCard.d.ts +0 -1
- package/dist/react/cards/SpacecraftCard.js +813 -925
- package/dist/react/cards/SpacecraftCard.js.map +1 -1
- package/dist/react/cards/TelemetryCard.d.ts +0 -1
- package/dist/react/cards/TelemetryCard.js +1055 -732
- package/dist/react/cards/TelemetryCard.js.map +1 -1
- package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
- package/dist/react/cards/TelemetryStreamCard.js +323 -297
- package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
- package/dist/react/cards/index.d.ts +1 -1
- package/dist/react/cards/index.js +1 -8
- package/dist/react/charts/GroundTrackMap.d.ts +6 -7
- package/dist/react/charts/GroundTrackMap.js +1377 -1256
- package/dist/react/charts/GroundTrackMap.js.map +1 -1
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
- package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
- package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
- package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
- package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
- package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
- package/dist/react/charts/index.d.ts +1 -1
- package/dist/react/charts/index.js +7 -100
- package/dist/react/charts/unified/AstroChart.d.ts +1 -2
- package/dist/react/charts/unified/AstroChart.js +1331 -1411
- package/dist/react/charts/unified/AstroChart.js.map +1 -1
- package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
- package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
- package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
- package/dist/react/charts/unified/domain.d.ts +12 -13
- package/dist/react/charts/unified/domain.js +3999 -3145
- package/dist/react/charts/unified/domain.js.map +1 -1
- package/dist/react/charts/unified/generators.d.ts +3 -4
- package/dist/react/charts/unified/generators.js +561 -498
- package/dist/react/charts/unified/generators.js.map +1 -1
- package/dist/react/charts/unified/index.d.ts +1 -1
- package/dist/react/charts/unified/presets.d.ts +14 -15
- package/dist/react/charts/unified/presets.js +857 -994
- package/dist/react/charts/unified/presets.js.map +1 -1
- package/dist/react/charts/unified/sync.d.ts +2 -3
- package/dist/react/charts/unified/sync.js +229 -195
- package/dist/react/charts/unified/sync.js.map +1 -1
- package/dist/react/charts/unified/theme.d.ts +11 -12
- package/dist/react/charts/unified/theme.js +606 -642
- package/dist/react/charts/unified/theme.js.map +1 -1
- package/dist/react/charts/unified/types.d.ts +32 -33
- package/dist/react/charts/unified/useChartStream.d.ts +1 -2
- package/dist/react/charts/unified/useChartStream.js +203 -216
- package/dist/react/charts/unified/useChartStream.js.map +1 -1
- package/dist/react/chatgpt/AppCard.d.ts +1 -2
- package/dist/react/chatgpt/index.d.ts +7 -7
- package/dist/react/chatgpt/index.js +160 -139
- package/dist/react/chatgpt/index.js.map +1 -1
- package/dist/react/context/CategoryContext.d.ts +0 -1
- package/dist/react/context/CategoryContext.js +78 -29
- package/dist/react/context/CategoryContext.js.map +1 -1
- package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
- package/dist/react/context/DisplaySettingsContext.js +205 -156
- package/dist/react/context/DisplaySettingsContext.js.map +1 -1
- package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
- package/dist/react/context/SpatialSelectionContext.js +36 -7
- package/dist/react/context/SpatialSelectionContext.js.map +1 -1
- package/dist/react/core/data/DataTable.d.ts +3 -4
- package/dist/react/core/data/DataTable.js +473 -440
- package/dist/react/core/data/DataTable.js.map +1 -1
- package/dist/react/core/data/DataValue.d.ts +4 -5
- package/dist/react/core/data/DataValue.js +605 -571
- package/dist/react/core/data/DataValue.js.map +1 -1
- package/dist/react/core/data/propertyConfig.d.ts +1 -2
- package/dist/react/core/data/propertyConfig.js +446 -382
- package/dist/react/core/data/propertyConfig.js.map +1 -1
- package/dist/react/core/display/AstroIcon.d.ts +4 -5
- package/dist/react/core/display/AstroIcon.js +339 -429
- package/dist/react/core/display/AstroIcon.js.map +1 -1
- package/dist/react/core/display/Badge.d.ts +2 -3
- package/dist/react/core/display/Badge.js +131 -131
- package/dist/react/core/display/Badge.js.map +1 -1
- package/dist/react/core/display/CardHeader.d.ts +0 -1
- package/dist/react/core/display/CardHeader.js +398 -311
- package/dist/react/core/display/CardHeader.js.map +1 -1
- package/dist/react/core/display/Container.d.ts +2 -3
- package/dist/react/core/display/Container.js +640 -668
- package/dist/react/core/display/Container.js.map +1 -1
- package/dist/react/core/display/CopyButton.d.ts +1 -2
- package/dist/react/core/display/CopyButton.js +158 -101
- package/dist/react/core/display/CopyButton.js.map +1 -1
- package/dist/react/core/display/GlassCard.d.ts +3 -4
- package/dist/react/core/display/GlassCard.js +416 -369
- package/dist/react/core/display/GlassCard.js.map +1 -1
- package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
- package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
- package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
- package/dist/react/core/display/Icon.d.ts +2 -3
- package/dist/react/core/display/Icon.js +172 -143
- package/dist/react/core/display/Icon.js.map +1 -1
- package/dist/react/core/display/Typography.d.ts +24 -25
- package/dist/react/core/display/Typography.js +360 -178
- package/dist/react/core/display/Typography.js.map +1 -1
- package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
- package/dist/react/core/feedback/ConfirmDialog.js +343 -304
- package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
- package/dist/react/core/feedback/Dialog.d.ts +2 -3
- package/dist/react/core/feedback/Dialog.js +189 -197
- package/dist/react/core/feedback/Dialog.js.map +1 -1
- package/dist/react/core/feedback/Toast.d.ts +2 -3
- package/dist/react/core/feedback/Toast.js +346 -207
- package/dist/react/core/feedback/Toast.js.map +1 -1
- package/dist/react/core/index.d.ts +26 -26
- package/dist/react/core/index.js +7 -119
- package/dist/react/core/inputs/Button.d.ts +2 -3
- package/dist/react/core/inputs/Button.js +281 -304
- package/dist/react/core/inputs/Button.js.map +1 -1
- package/dist/react/core/inputs/Checkbox.d.ts +2 -3
- package/dist/react/core/inputs/Checkbox.js +139 -127
- package/dist/react/core/inputs/Checkbox.js.map +1 -1
- package/dist/react/core/inputs/Input.d.ts +3 -4
- package/dist/react/core/inputs/Input.js +277 -285
- package/dist/react/core/inputs/Input.js.map +1 -1
- package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
- package/dist/react/core/inputs/LimitsBar.js +271 -196
- package/dist/react/core/inputs/LimitsBar.js.map +1 -1
- package/dist/react/core/inputs/NumberInput.d.ts +2 -3
- package/dist/react/core/inputs/NumberInput.js +531 -503
- package/dist/react/core/inputs/NumberInput.js.map +1 -1
- package/dist/react/core/inputs/PinInput.d.ts +2 -3
- package/dist/react/core/inputs/PinInput.js +224 -207
- package/dist/react/core/inputs/PinInput.js.map +1 -1
- package/dist/react/core/inputs/Select.d.ts +1 -2
- package/dist/react/core/inputs/Select.js +298 -299
- package/dist/react/core/inputs/Select.js.map +1 -1
- package/dist/react/core/inputs/Toggle.d.ts +2 -3
- package/dist/react/core/inputs/Toggle.js +142 -148
- package/dist/react/core/inputs/Toggle.js.map +1 -1
- package/dist/react/core/layout/Box.d.ts +3 -4
- package/dist/react/core/layout/Box.js +118 -122
- package/dist/react/core/layout/Box.js.map +1 -1
- package/dist/react/core/layout/Center.d.ts +0 -1
- package/dist/react/core/layout/Center.js +45 -32
- package/dist/react/core/layout/Center.js.map +1 -1
- package/dist/react/core/layout/Divider.d.ts +1 -2
- package/dist/react/core/layout/Divider.js +112 -106
- package/dist/react/core/layout/Divider.js.map +1 -1
- package/dist/react/core/layout/Flex.d.ts +4 -5
- package/dist/react/core/layout/Flex.js +120 -124
- package/dist/react/core/layout/Flex.js.map +1 -1
- package/dist/react/core/layout/Grid.d.ts +5 -6
- package/dist/react/core/layout/Grid.js +131 -138
- package/dist/react/core/layout/Grid.js.map +1 -1
- package/dist/react/core/layout/Spacer.d.ts +0 -1
- package/dist/react/core/layout/Spacer.js +36 -29
- package/dist/react/core/layout/Spacer.js.map +1 -1
- package/dist/react/core/layout/Stack.d.ts +4 -5
- package/dist/react/core/layout/Stack.js +127 -70
- package/dist/react/core/layout/Stack.js.map +1 -1
- package/dist/react/core/layout/responsive.d.ts +1 -2
- package/dist/react/core/layout/responsive.js +25 -19
- package/dist/react/core/layout/responsive.js.map +1 -1
- package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
- package/dist/react/core/layout/useBreakpoint.js +119 -66
- package/dist/react/core/layout/useBreakpoint.js.map +1 -1
- package/dist/react/core/navigation/AppBar.d.ts +1 -2
- package/dist/react/core/navigation/AppBar.js +827 -805
- package/dist/react/core/navigation/AppBar.js.map +1 -1
- package/dist/react/core/navigation/Pagination.d.ts +2 -3
- package/dist/react/core/navigation/Pagination.js +207 -187
- package/dist/react/core/navigation/Pagination.js.map +1 -1
- package/dist/react/core/navigation/SideNav.d.ts +5 -6
- package/dist/react/core/navigation/SideNav.js +855 -629
- package/dist/react/core/navigation/SideNav.js.map +1 -1
- package/dist/react/core/navigation/Tabs.d.ts +0 -1
- package/dist/react/core/navigation/Tabs.js +113 -119
- package/dist/react/core/navigation/Tabs.js.map +1 -1
- package/dist/react/core/overlays/Popover.d.ts +2 -3
- package/dist/react/core/overlays/Popover.js +303 -282
- package/dist/react/core/overlays/Popover.js.map +1 -1
- package/dist/react/core/overlays/SidePanel.d.ts +1 -2
- package/dist/react/core/overlays/SidePanel.js +217 -212
- package/dist/react/core/overlays/SidePanel.js.map +1 -1
- package/dist/react/core/overlays/Tooltip.d.ts +1 -2
- package/dist/react/core/overlays/Tooltip.js +170 -176
- package/dist/react/core/overlays/Tooltip.js.map +1 -1
- package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
- package/dist/react/core/widgets/ActivityPlanner.js +855 -517
- package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
- package/dist/react/core/widgets/Capture.d.ts +2 -3
- package/dist/react/core/widgets/Capture.js +965 -779
- package/dist/react/core/widgets/Capture.js.map +1 -1
- package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
- package/dist/react/core/widgets/ChatPanel.js +1734 -1034
- package/dist/react/core/widgets/ChatPanel.js.map +1 -1
- package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
- package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
- package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
- package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
- package/dist/react/core/widgets/CommandBuilder.js +624 -516
- package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
- package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
- package/dist/react/core/widgets/ConnectionForm.js +528 -492
- package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
- package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
- package/dist/react/core/widgets/FileExplorer.js +617 -505
- package/dist/react/core/widgets/FileExplorer.js.map +1 -1
- package/dist/react/core/widgets/HexViewer.d.ts +2 -3
- package/dist/react/core/widgets/HexViewer.js +1353 -1091
- package/dist/react/core/widgets/HexViewer.js.map +1 -1
- package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
- package/dist/react/core/widgets/ImageFrame.js +230 -193
- package/dist/react/core/widgets/ImageFrame.js.map +1 -1
- package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
- package/dist/react/core/widgets/ImageGallery.js +380 -314
- package/dist/react/core/widgets/ImageGallery.js.map +1 -1
- package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
- package/dist/react/core/widgets/ImagePanel.js +110 -101
- package/dist/react/core/widgets/ImagePanel.js.map +1 -1
- package/dist/react/core/widgets/LogViewer.d.ts +2 -3
- package/dist/react/core/widgets/LogViewer.js +711 -607
- package/dist/react/core/widgets/LogViewer.js.map +1 -1
- package/dist/react/core/widgets/MessageStream.d.ts +3 -4
- package/dist/react/core/widgets/MessageStream.js +514 -444
- package/dist/react/core/widgets/MessageStream.js.map +1 -1
- package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
- package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
- package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
- package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
- package/dist/react/core/widgets/PacketViewer.js +550 -421
- package/dist/react/core/widgets/PacketViewer.js.map +1 -1
- package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
- package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
- package/dist/react/hooks/index.d.ts +5 -5
- package/dist/react/hooks/useAccessWindows.d.ts +0 -1
- package/dist/react/hooks/useCompactMode.d.ts +1 -1
- package/dist/react/hooks/useCompactMode.js +104 -58
- package/dist/react/hooks/useCompactMode.js.map +1 -1
- package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
- package/dist/react/hooks/useSimulationScene.d.ts +1 -2
- package/dist/react/hooks/useSimulationScene.js +481 -374
- package/dist/react/hooks/useSimulationScene.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/panels/LayerControlPanel.d.ts +1 -2
- package/dist/react/panels/LayerControlPanel.js +223 -180
- package/dist/react/panels/LayerControlPanel.js.map +1 -1
- package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
- package/dist/react/panels/ObjectInventoryPanel.js +315 -250
- package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
- package/dist/react/panels/index.d.ts +1 -1
- package/dist/react/panels/index.js +1 -6
- package/dist/react/shared/ErrorBoundary.d.ts +1 -2
- package/dist/react/shared/ErrorBoundary.js +170 -139
- package/dist/react/shared/ErrorBoundary.js.map +1 -1
- package/dist/react/shared/Skeleton.d.ts +1 -2
- package/dist/react/shared/Skeleton.js +300 -301
- package/dist/react/shared/Skeleton.js.map +1 -1
- package/dist/react/theme/ThemeProvider.d.ts +2 -321
- package/dist/react/theme/ThemeProvider.js +312 -939
- package/dist/react/theme/ThemeProvider.js.map +1 -1
- package/dist/react/theme/cardAccent.d.ts +1 -2
- package/dist/react/theme/cardAccent.js +196 -126
- package/dist/react/theme/cardAccent.js.map +1 -1
- package/dist/react/theme/config.d.ts +0 -1
- package/dist/react/theme/config.js +47 -25
- package/dist/react/theme/config.js.map +1 -1
- package/dist/react/theme/index.d.ts +2 -2
- package/dist/react/theme/index.js +1 -16
- package/dist/react/theme/types.d.ts +332 -0
- package/dist/react/theme/types.js +39 -0
- package/dist/react/theme/types.js.map +1 -0
- package/dist/react/types.d.ts +8 -8
- package/dist/react/types.js +147 -47
- package/dist/react/types.js.map +1 -1
- package/dist/react/utils/categoryPalette.d.ts +0 -1
- package/dist/react/utils/categoryPalette.js +91 -102
- package/dist/react/utils/categoryPalette.js.map +1 -1
- package/dist/react/utils/index.d.ts +5 -5
- package/dist/react/utils/index.js +457 -371
- package/dist/react/utils/index.js.map +1 -1
- package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
- package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
- package/dist/react/visualizations/NavBallCard.d.ts +0 -1
- package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
- package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
- package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
- package/dist/react/visualizations/index.d.ts +3 -3
- package/dist/react.d.ts +2 -1
- package/dist/react.js +17 -221
- package/dist/shaders/atmosphere.frag.js +6 -5
- package/dist/shaders/atmosphere.frag.js.map +1 -1
- package/dist/shaders/atmosphere.vert.js +6 -5
- package/dist/shaders/atmosphere.vert.js.map +1 -1
- package/dist/shaders/stars.frag.js +6 -5
- package/dist/shaders/stars.frag.js.map +1 -1
- package/dist/shaders/stars.vert.js +6 -5
- package/dist/shaders/stars.vert.js.map +1 -1
- package/dist/style.css +217 -194
- package/dist/tokens/core.d.ts +159 -0
- package/dist/tokens/core.js +144 -0
- package/dist/tokens/core.js.map +1 -0
- package/dist/tokens/css-vars.d.ts +213 -2
- package/dist/tokens/css-vars.js +590 -227
- package/dist/tokens/css-vars.js.map +1 -1
- package/dist/tokens/index.d.ts +31 -228
- package/dist/tokens/index.js +281 -366
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/palettes/astro.d.ts +129 -0
- package/dist/tokens/palettes/astro.js +112 -0
- package/dist/tokens/palettes/astro.js.map +1 -0
- package/dist/tokens/palettes/index.d.ts +288 -0
- package/dist/tokens/palettes/index.js +35 -0
- package/dist/tokens/palettes/index.js.map +1 -0
- package/dist/tokens/palettes/tailwind.d.ts +324 -0
- package/dist/tokens/palettes/tailwind.js +201 -0
- package/dist/tokens/palettes/tailwind.js.map +1 -0
- package/dist/tokens/palettes/zendir.d.ts +126 -0
- package/dist/tokens/palettes/zendir.js +92 -0
- package/dist/tokens/palettes/zendir.js.map +1 -0
- package/dist/tokens/themes.d.ts +30 -0
- package/dist/tokens/themes.js +704 -0
- package/dist/tokens/themes.js.map +1 -0
- package/dist/tokens/tokens.css +419 -41
- package/dist/types/index.d.ts +2 -2
- package/package.json +310 -313
- package/dist/index.js.map +0 -1
- package/dist/react/3d/index.js.map +0 -1
- package/dist/react/astro/index.js.map +0 -1
- package/dist/react/cards/index.js.map +0 -1
- package/dist/react/charts/index.js.map +0 -1
- package/dist/react/core/index.js.map +0 -1
- package/dist/react/panels/index.js.map +0 -1
- package/dist/react/theme/astro-tokens.d.ts +0 -153
- package/dist/react/theme/index.js.map +0 -1
- package/dist/react.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpacecraftCard.js","sources":["../../../src/react/cards/SpacecraftCard.tsx"],"sourcesContent":["/**\n * @zendir/ui - SpacecraftCard Component\n * \n * Enterprise-grade spacecraft information card.\n * \n * AstroUXDS Compliance:\n * - Status colors used for health/operational status only\n * - Orbit type uses Zendir-Astro data viz colors (categorical)\n * - Zendir accent colors for interactive elements\n * - Tabular numbers with fontVariantNumeric for data\n * - Sentence-case labels per Tier 3 compliance\n * \n * Features:\n * - Full null-safety with graceful fallbacks\n * - WCAG 2.1 AA accessibility\n * - Keyboard navigation\n * - Smooth animations with reduced-motion support\n * - Loading skeleton state\n * - Error boundary support\n * - Real SDK integration via optional client prop\n */\n\nimport React, { memo, useCallback, useMemo } from 'react';\nimport type { SpacecraftPosition, TelemetryData } from '../types';\nimport { useTheme } from '../theme';\nimport { Icon, type IconName } from '../core/display/Icon';\nimport { CardHeader } from '../core/display/CardHeader';\nimport { HeaderIconWithStatus } from '../core/display/HeaderIconWithStatus';\nimport { useCompactMode } from '../hooks';\nimport { useCardBorderStyle } from '../context/DisplaySettingsContext';\n\n// ZendirClient is optional - only used when SDK is installed\ntype ZendirClient = any;\nimport {\n safeNumber,\n formatCoordinate,\n formatAltitude,\n formatVelocity,\n formatPercentage,\n formatTime,\n getStatusColor,\n classNames,\n safeAccentText,\n type StatusLevel,\n} from '../utils';\n\nexport interface SpacecraftCardProps {\n /** Spacecraft position data (for direct data mode) */\n spacecraft?: SpacecraftPosition;\n /** Optional telemetry data */\n telemetry?: TelemetryData;\n /** Show expanded orbit info */\n showOrbit?: boolean;\n /** Show telemetry summary */\n showTelemetry?: boolean;\n /** Loading state */\n loading?: boolean;\n /** Click handler */\n onClick?: (spacecraft: SpacecraftPosition) => void;\n /** Custom className */\n className?: string;\n /** Connected mode: SDK client */\n client?: ZendirClient;\n /** Connected mode: Spacecraft ID to fetch */\n spacecraftId?: string;\n /** Enable compact mode - shows condensed view that expands on hover/click */\n compact?: boolean;\n /** Start expanded when in compact mode (pinned state) */\n defaultExpanded?: boolean;\n /** Callback when pin state changes in compact mode */\n onPinChange?: (isPinned: boolean) => void;\n}\n\n/**\n * Get orbit type color based on orbit classification\n * Uses Zendir-Astro palette for categorical (non-status) classification\n */\nfunction getOrbitTypeColor(orbitType: string | undefined, accentColor: string): string {\n // Orbit type colors using pure Zendir brand palette\n // These are categorical colors, not status colors\n const colors: Record<string, string> = {\n LEO: '#3E3CFF', // Zendir Electric - Low Earth Orbit\n MEO: '#3548C0', // Zendir Prussian Blue Light - Medium Earth Orbit \n GEO: '#9D70FF', // Zendir Purple - Geostationary\n HEO: '#1B2DA0', // Zendir Prussian Blue - Highly Elliptical\n SSO: '#B48DFF', // Zendir Purple Light - Sun-Synchronous\n POLAR: '#6B69FF', // Zendir Electric Light - Polar\n };\n return colors[orbitType?.toUpperCase() ?? ''] ?? accentColor;\n}\n\n/**\n * Derive health status from spacecraft or telemetry\n * Prefers telemetry.health.status, falls back to spacecraft.status\n */\nfunction deriveHealthStatus(\n spacecraftStatus: StatusLevel | undefined,\n telemetryStatus: string | undefined\n): StatusLevel {\n // Prefer telemetry if available, but also validate it's a proper StatusLevel\n if (telemetryStatus) {\n const validStatuses: StatusLevel[] = ['off', 'standby', 'normal', 'caution', 'serious', 'critical'];\n const normalized = telemetryStatus.toLowerCase();\n if (validStatuses.includes(normalized as StatusLevel)) {\n return normalized as StatusLevel;\n }\n // Legacy mapping for backwards compatibility\n switch (normalized) {\n case 'healthy':\n case 'nominal':\n case 'operational':\n return 'normal';\n case 'warning':\n case 'degraded':\n return 'caution';\n case 'failed':\n case 'error':\n return 'critical';\n case 'idle':\n return 'standby';\n }\n }\n // Use spacecraft.status directly (already typed as StatusLevel)\n return spacecraftStatus ?? 'off';\n}\n\n/**\n * SpacecraftCard - Displays spacecraft position and status information\n * \n * @example\n * ```tsx\n * // Direct data mode\n * <SpacecraftCard \n * spacecraft={spacecraftData}\n * telemetry={telemetryData}\n * showOrbit\n * showTelemetry\n * onClick={() => {}}\n * />\n * \n * // Connected mode (auto-fetches via SDK)\n * <SpacecraftCard\n * client={zendirClient}\n * spacecraftId=\"iss-25544\"\n * showTelemetry\n * />\n * ```\n */\nexport const SpacecraftCard = memo(function SpacecraftCard({\n spacecraft,\n telemetry,\n showOrbit = false,\n showTelemetry = false,\n loading = false,\n onClick,\n className = '',\n compact = false,\n defaultExpanded = false,\n onPinChange,\n}: SpacecraftCardProps): React.ReactElement {\n const { tokens, theme, prefersReducedMotion } = useTheme();\n const isTransparentTheme = theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const isBoldVariant = theme === 'transparent-bold';\n const isMinimalVariant = theme === 'transparent-minimal';\n const useGlassMode = isBoldVariant || isMinimalVariant;\n \n // Glass accent colors for bold/minimal themes (matching Container/AstroChart)\n const glassAccentColor = tokens.colors.accent.primary;\n const glassAccentMuted = `${glassAccentColor}66`;\n \n // WCAG AA safe accent for use as foreground text on dark backgrounds\n const accentTextColor = useMemo(() => safeAccentText(tokens.colors.accent.primary), [tokens.colors.accent.primary]);\n \n // Use transparent background with blur for transparent themes (matching Timeline)\n const cardBg = isTransparentTheme ? 'transparent' : tokens.colors.background.surface;\n const cardGlass = isTransparentTheme ? { \n backdropFilter: 'blur(12px)' as const, \n WebkitBackdropFilter: 'blur(12px)' as const,\n } : {};\n // Get card border style based on accentBorders setting\n const cardBorderStyle = useCardBorderStyle(tokens, isTransparentTheme);\n \n // Glass mode container style (matching Container/AstroChart for bold/minimal)\n const glassContainerStyle: React.CSSProperties = useGlassMode ? {\n backgroundColor: 'rgba(10, 15, 25, 0.35)',\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n border: `1px solid ${glassAccentMuted}`,\n borderTop: isBoldVariant ? `2px solid ${glassAccentColor}` : `1px solid ${glassAccentColor}`,\n } : {};\n\n // Compact mode state management\n const { expanded, isPinned, isHovered: _isHovered, handlers: compactHandlers, transitionDuration: _compactTransition } = useCompactMode({\n compact,\n defaultExpanded,\n onPinChange,\n });\n \n // Smooth animation timing\n const animationDuration = prefersReducedMotion ? 0 : 250;\n const animationEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\n // Memoized click handler\n const _handleClick = useCallback(() => {\n if (onClick && spacecraft) {\n onClick(spacecraft);\n }\n }, [onClick, spacecraft]);\n\n // Keyboard handler for accessibility\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (onClick && spacecraft && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onClick(spacecraft);\n }\n },\n [onClick, spacecraft]\n );\n\n // Memoized computed values\n const orbitColor = useMemo(\n () => getOrbitTypeColor(spacecraft?.orbitType, tokens.colors.accent.primary),\n [spacecraft?.orbitType, tokens.colors.accent.primary]\n );\n\n const healthStatus = useMemo(\n () => deriveHealthStatus(spacecraft?.status, telemetry?.health?.status),\n [spacecraft?.status, telemetry?.health?.status]\n );\n\n const statusColor = useMemo(() => getStatusColor(healthStatus), [healthStatus]);\n\n // Animation duration (respects reduced motion)\n const transitionDuration = prefersReducedMotion ? '0ms' : '200ms';\n\n // Combined click handler for compact mode and onClick (must be before early returns)\n const combinedClickHandler = useCallback(() => {\n if (compact) {\n compactHandlers.onClick();\n }\n if (onClick && spacecraft) {\n onClick(spacecraft);\n }\n }, [compact, compactHandlers, onClick, spacecraft]);\n\n // Loading state\n if (loading) {\n return (\n <div\n className={classNames('zendir-spacecraft-card', 'loading', className)}\n role=\"article\"\n aria-busy=\"true\"\n aria-label=\"Loading spacecraft data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n minHeight: 180,\n }}\n >\n {/* Loading skeleton */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16 }}>\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: '50%',\n backgroundColor: 'rgba(255,255,255,0.1)',\n animation: 'pulse 1.5s ease-in-out infinite',\n }}\n />\n <div style={{ flex: 1 }}>\n <div\n style={{\n height: 16,\n width: '60%',\n backgroundColor: 'rgba(255,255,255,0.1)',\n borderRadius: 4,\n animation: 'pulse 1.5s ease-in-out infinite',\n }}\n />\n </div>\n </div>\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: 12,\n }}\n >\n {[1, 2, 3, 4].map((i) => (\n <div key={i}>\n <div\n style={{\n height: 10,\n width: '40%',\n backgroundColor: 'rgba(255,255,255,0.08)',\n borderRadius: 2,\n marginBottom: 4,\n }}\n />\n <div\n style={{\n height: 14,\n width: '70%',\n backgroundColor: 'rgba(255,255,255,0.1)',\n borderRadius: 2,\n }}\n />\n </div>\n ))}\n </div>\n <style>{`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}</style>\n </div>\n );\n }\n\n // Empty state\n if (!spacecraft) {\n return (\n <div\n className={classNames('zendir-spacecraft-card', 'empty', className)}\n role=\"article\"\n aria-label=\"No spacecraft data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n ...(tokens.colors.border.cardStyleDashed ?? {}),\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.lg,\n textAlign: 'center',\n color: tokens.colors.text.tertiary,\n }}\n >\n <svg\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n style={{ marginBottom: 8, opacity: 0.5 }}\n >\n <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\" />\n </svg>\n <p style={{ margin: 0, fontSize: tokens.typography.body[2].fontSize }}>No spacecraft data available</p>\n </div>\n );\n }\n\n // Compact view - shows key info in a single row\n // Compact metric item component for consistent styling\n const CompactMetric = ({ \n icon, \n label, \n value, \n color,\n }: { \n icon: IconName; \n label: string; \n value: string | number; \n color?: string;\n }) => (\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n gap: 3,\n padding: `2px 0`,\n }}>\n <Icon name={icon} size={12} color={color ?? tokens.colors.text.secondary} />\n <span style={{ \n fontSize: tokens.typography.fontSize.micro, // 0.5625rem / 9px (AstroUXDS micro)\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary, // Public Sans → Roboto fallback → system stack\n color: tokens.colors.text.tertiary,\n textTransform: 'uppercase',\n minWidth: 8,\n }}>\n {label.charAt(0)}\n </span>\n <span style={{ \n fontVariantNumeric: 'tabular-nums', \n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: tokens.typography.fontSize.xs,\n color: color ?? tokens.colors.text.primary,\n fontWeight: tokens.typography.fontWeight.medium,\n }}>\n {value}\n </span>\n </div>\n );\n\n // Compact view content - reusable for rendering\n const renderCompactContent = () => {\n const power = telemetry?.subsystems?.power ?? telemetry?.power;\n const batteryLevel = power?.batteryLevel;\n const batteryStatusLocal = batteryLevel !== undefined\n ? batteryLevel > 50 ? 'normal' : batteryLevel > 20 ? 'caution' : 'critical'\n : 'off';\n\n // Status color for header icon\n const statusColor = getStatusColor(healthStatus);\n\n return (\n <>\n {/* Header: Icon (status colored) → Status symbol → Name → Badges */}\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n justifyContent: 'space-between', \n marginBottom: tokens.spacing.xs,\n paddingBottom: tokens.spacing.xs,\n borderBottom: useGlassMode ? 'none' : `1px solid ${tokens.colors.border.muted}`,\n position: 'relative',\n zIndex: 1,\n }}>\n {/* Left side: Icon + Name + Accent line */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.xs, flex: 1, minWidth: 0 }}>\n {/* Icon with status badge - MonitoringIcon pattern */}\n <HeaderIconWithStatus \n icon=\"satellite-transmit\" \n size={18} \n status={healthStatus} \n statusColor={statusColor}\n />\n {/* Name - accent color for glass mode */}\n <span style={{ \n fontWeight: tokens.typography.fontWeight.semibold, \n fontSize: tokens.typography.fontSize.sm,\n fontFamily: tokens.typography.fontFamily.primary,\n color: useGlassMode ? glassAccentColor : undefined,\n textShadow: useGlassMode ? `0 0 16px ${glassAccentMuted}` : undefined,\n whiteSpace: 'nowrap', \n overflow: 'hidden', \n textOverflow: 'ellipsis',\n }}>\n {(spacecraft.name ?? spacecraft.id ?? 'Unknown').split(' ')[0]}\n </span>\n {/* Accent line for glass mode */}\n {useGlassMode && (\n <div style={{\n flex: 1,\n height: isBoldVariant ? '2px' : '1px',\n minWidth: 20,\n background: `linear-gradient(90deg, ${glassAccentColor} 0%, ${glassAccentMuted} 60%, transparent 100%)`,\n boxShadow: isBoldVariant ? `0 0 8px ${glassAccentMuted}` : undefined,\n }} />\n )}\n </div>\n \n {/* Right side: Orbit type badge + Pin */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.xs, flexShrink: 0 }}>\n {/* Orbit type badge */}\n <span\n style={{\n backgroundColor: `${orbitColor}20`,\n color: orbitColor,\n padding: `1px 6px`,\n borderRadius: tokens.borderRadius.sm,\n fontSize: tokens.typography.fontSize.xxs, // 0.625rem / 10px (AstroUXDS compact)\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary,\n }}\n >\n {spacecraft.orbitType ?? '—'}\n </span>\n {/* Pin badge */}\n {isPinned && (\n <Icon name=\"lock\" size={10} color={tokens.colors.accent.primary} />\n )}\n </div>\n </div>\n\n {/* Metrics grid - 3 columns */}\n <div style={{ \n display: 'grid', \n gridTemplateColumns: 'repeat(3, 1fr)',\n gap: `${tokens.spacing.xs} ${tokens.spacing.sm}`,\n }}>\n {/* Position metrics */}\n <CompactMetric \n icon=\"location\" \n label=\"Latitude\" \n value={formatCoordinate(spacecraft.latitude, 'lat')}\n />\n <CompactMetric \n icon=\"location\" \n label=\"Longitude\" \n value={formatCoordinate(spacecraft.longitude, 'lon')}\n />\n <CompactMetric \n icon=\"orbit\" \n label=\"Altitude\" \n value={formatAltitude(spacecraft.altitude)}\n color={orbitColor}\n />\n\n {/* Velocity */}\n {spacecraft.velocity !== undefined && (\n <CompactMetric \n icon=\"rocket\" \n label=\"Velocity\" \n value={formatVelocity(spacecraft.velocity)}\n />\n )}\n\n {/* Telemetry data if available */}\n {batteryLevel !== undefined && (\n <CompactMetric \n icon=\"battery\" \n label=\"Battery\" \n value={formatPercentage(batteryLevel)}\n color={getStatusColor(batteryStatusLocal as StatusLevel)}\n />\n )}\n\n {/* Inclination if available */}\n {spacecraft.inclination !== undefined && (\n <CompactMetric \n icon=\"orbit\" \n label=\"Inclination\" \n value={`${safeNumber(spacecraft.inclination, 1)}°`}\n />\n )}\n </div>\n </>\n );\n };\n\n // Compact mode with in-place expansion - cards push each other\n if (compact) {\n return (\n <article\n className={classNames('zendir-spacecraft-card', 'compact', expanded ? 'expanded' : '', className)}\n {...compactHandlers}\n aria-label={`Spacecraft: ${spacecraft.name ?? spacecraft.id}${expanded ? '' : ' (compact)'}`}\n style={{\n position: 'relative',\n overflow: 'hidden',\n // Use glass container style for bold/minimal themes\n ...(useGlassMode ? glassContainerStyle : {\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n }),\n borderRadius: tokens.borderRadius.lg,\n padding: expanded ? tokens.spacing.md : tokens.spacing.sm,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n fontSize: expanded ? tokens.typography.fontSize.base : tokens.typography.fontSize.sm,\n cursor: 'pointer',\n transition: `all ${animationDuration}ms ${animationEasing}`,\n boxShadow: expanded \n ? `0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px ${orbitColor}30` \n : 'none',\n zIndex: expanded ? 50 : 1,\n }}\n >\n {/* Glass gradient overlay for bold/minimal themes */}\n {useGlassMode && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n background: 'linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.1) 100%)',\n pointerEvents: 'none',\n zIndex: 0,\n }}\n />\n )}\n {expanded ? (\n // Full expanded content\n <>\n {/* Full expanded header - matches MonitoringIcon layout pattern */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm, marginBottom: tokens.spacing.md }}>\n {/* Icon with status badge - MonitoringIcon pattern */}\n <HeaderIconWithStatus \n icon=\"satellite-transmit\" \n size={24} \n status={healthStatus}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>\n <h3\n style={{\n margin: 0,\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.semibold,\n lineHeight: 1.2,\n }}\n >\n {spacecraft.name ?? spacecraft.id}\n </h3>\n {isPinned && (\n <Icon name=\"lock\" size={12} color={tokens.colors.accent.primary} />\n )}\n </div>\n {spacecraft.id && spacecraft.name && (\n <span\n style={{\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n }}\n >\n {spacecraft.id}\n </span>\n )}\n </div>\n <span\n style={{\n backgroundColor: `${orbitColor}20`,\n color: orbitColor,\n padding: `4px 8px`,\n borderRadius: tokens.borderRadius.sm,\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n flexShrink: 0,\n }}\n >\n {spacecraft.orbitType ?? 'Unknown'}\n </span>\n </div>\n\n {/* Position Grid */}\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: tokens.spacing.sm,\n marginBottom: tokens.spacing.md,\n }}\n >\n <div>\n <span\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Latitude\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: 'tabular-nums',\n fontFamily: tokens.typography.fontFamily.mono,\n }}\n >\n {formatCoordinate(spacecraft.latitude, 'lat')}\n </span>\n </div>\n <div>\n <span\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Longitude\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: 'tabular-nums',\n fontFamily: tokens.typography.fontFamily.mono,\n }}\n >\n {formatCoordinate(spacecraft.longitude, 'lon')}\n </span>\n </div>\n <div>\n <span\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Altitude\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: 'tabular-nums',\n fontFamily: tokens.typography.fontFamily.mono,\n color: orbitColor,\n }}\n >\n {formatAltitude(spacecraft.altitude)}\n </span>\n </div>\n <div>\n <span\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Velocity\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: 'tabular-nums',\n fontFamily: tokens.typography.fontFamily.mono,\n }}\n >\n {formatVelocity(spacecraft.velocity)}\n </span>\n </div>\n </div>\n\n {/* Timestamp */}\n {spacecraft.timestamp && (\n <time\n dateTime={spacecraft.timestamp}\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {formatTime(spacecraft.timestamp)}\n </time>\n )}\n </>\n ) : (\n // Compact content\n renderCompactContent()\n )}\n </article>\n );\n }\n\n return (\n <article\n className={classNames('zendir-spacecraft-card', compact ? 'expanded' : '', className)}\n onClick={(compact || onClick) ? combinedClickHandler : undefined}\n onKeyDown={onClick ? handleKeyDown : compactHandlers.onKeyDown}\n tabIndex={onClick || compact ? 0 : undefined}\n role={compact ? compactHandlers.role : 'article'}\n aria-expanded={compact ? compactHandlers['aria-expanded'] : undefined}\n aria-label={`Spacecraft: ${spacecraft.name ?? spacecraft.id}`}\n style={{\n position: 'relative',\n overflow: 'hidden',\n ...(useGlassMode ? glassContainerStyle : {\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n }),\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n cursor: (onClick || compact) ? 'pointer' : 'default',\n transition: `all ${transitionDuration} ease-out`,\n outline: 'none',\n }}\n onMouseEnter={(e) => {\n if (compact) compactHandlers.onMouseEnter();\n if (onClick) {\n e.currentTarget.style.borderColor = tokens.colors.border.focus;\n e.currentTarget.style.boxShadow = tokens.shadows.md;\n e.currentTarget.style.transform = prefersReducedMotion ? 'none' : 'translateY(-2px)';\n }\n }}\n onMouseLeave={(e) => {\n if (compact) compactHandlers.onMouseLeave();\n if (onClick) {\n e.currentTarget.style.borderColor = tokens.colors.border.muted;\n e.currentTarget.style.boxShadow = 'none';\n e.currentTarget.style.transform = 'none';\n }\n }}\n onFocus={(e) => {\n e.currentTarget.style.outline = `2px solid ${tokens.colors.border.focus}`;\n e.currentTarget.style.outlineOffset = '2px';\n }}\n onBlur={(e) => {\n e.currentTarget.style.outline = 'none';\n }}\n >\n {/* Glass gradient overlay for bold/minimal themes */}\n {useGlassMode && (\n <div\n style={{\n position: 'absolute',\n inset: 0,\n background: 'linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.1) 100%)',\n pointerEvents: 'none',\n zIndex: 0,\n }}\n />\n )}\n \n {/* Unified Card Header - handles all theme variants */}\n <CardHeader\n icon=\"satellite-transmit\"\n title={spacecraft.name ?? spacecraft.id ?? 'Unknown'}\n subtitle={spacecraft.id && spacecraft.name ? spacecraft.id : undefined}\n status={healthStatus}\n badge={spacecraft.orbitType ?? 'Unknown'}\n badgeColor={orbitColor}\n isPinned={compact && isPinned}\n />\n\n {/* Position Data Grid */}\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: tokens.spacing.sm,\n }}\n >\n <DataCell label=\"Latitude\" value={formatCoordinate(spacecraft.latitude, 'lat')} tokens={tokens} highlightColor={accentTextColor} />\n <DataCell label=\"Longitude\" value={formatCoordinate(spacecraft.longitude, 'lon')} tokens={tokens} highlightColor={accentTextColor} />\n <DataCell label=\"Altitude\" value={formatAltitude(spacecraft.altitude)} highlight tokens={tokens} highlightColor={accentTextColor} />\n <DataCell label=\"Velocity\" value={formatVelocity(spacecraft.velocity)} tokens={tokens} highlightColor={accentTextColor} />\n </div>\n\n {/* Orbit Info (Optional) */}\n {showOrbit && spacecraft.inclination !== undefined && (\n <div\n style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.md,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n }}\n >\n <DataCell\n label=\"Inclination\"\n value={`${safeNumber(spacecraft.inclination, 1)}°`}\n inline\n tokens={tokens}\n />\n </div>\n )}\n\n {/* Telemetry Summary (Optional) */}\n {showTelemetry && telemetry && (\n <div\n style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.md,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n }}\n >\n {/* Health Status */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacing.sm,\n marginBottom: tokens.spacing.sm,\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n width: 10,\n height: 10,\n borderRadius: '50%',\n backgroundColor: statusColor,\n boxShadow: `0 0 8px ${statusColor}60`,\n }}\n />\n <span\n style={{\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n color: statusColor,\n textTransform: 'capitalize',\n }}\n >\n {telemetry.health?.status ?? 'Unknown'}\n </span>\n </div>\n\n {/* Battery Progress */}\n {telemetry.power?.batteryLevel !== undefined && (\n <div>\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n marginBottom: 4,\n fontSize: tokens.typography.fontSize.xs,\n }}\n >\n <span style={{ color: tokens.colors.text.tertiary }}>Battery</span>\n <span\n style={{\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {formatPercentage(telemetry.power.batteryLevel, false, 0)}\n </span>\n </div>\n <div\n style={{\n height: 4,\n backgroundColor: tokens.colors.border.muted,\n borderRadius: 2,\n overflow: 'hidden',\n }}\n >\n <div\n role=\"progressbar\"\n aria-valuenow={telemetry.power.batteryLevel}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label=\"Battery level\"\n style={{\n height: '100%',\n width: `${Math.min(100, Math.max(0, telemetry.power.batteryLevel))}%`,\n backgroundColor:\n telemetry.power.batteryLevel > 30\n ? tokens.colors.status.normal\n : tokens.colors.status.critical,\n borderRadius: 2,\n transition: `width ${transitionDuration} ease-out`,\n }}\n />\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Timestamp Footer */}\n {spacecraft.timestamp && (\n <footer\n style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.sm,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n textAlign: 'right',\n }}\n >\n <time dateTime={spacecraft.timestamp}>{formatTime(spacecraft.timestamp)} UTC</time>\n </footer>\n )}\n </article>\n );\n});\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\ninterface DataCellProps {\n label: string;\n value: string;\n highlight?: boolean;\n inline?: boolean;\n tokens: ReturnType<typeof useTheme>['tokens'];\n /** WCAG AA safe highlight color (computed via safeAccentText) */\n highlightColor?: string;\n}\n\nconst DataCell = memo(function DataCell({\n label,\n value,\n highlight = false,\n inline = false,\n tokens,\n highlightColor,\n}: DataCellProps): React.ReactElement {\n if (inline) {\n return (\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\n <span\n style={{\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary, // WCAG AA compliant\n fontWeight: tokens.typography.fontWeight.medium,\n }}\n >\n {label}\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.sm,\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: 'tabular-nums',\n color: tokens.colors.text.primary,\n }}\n >\n {value}\n </span>\n </div>\n );\n }\n\n return (\n <div>\n <span\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary, // WCAG AA compliant\n fontWeight: tokens.typography.fontWeight.medium,\n marginBottom: 2,\n }}\n >\n {label}\n </span>\n <span\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.sm,\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: 'tabular-nums',\n color: highlight ? (highlightColor ?? safeAccentText(tokens.colors.accent.primary)) : tokens.colors.text.primary,\n fontWeight: tokens.typography.fontWeight.medium,\n }}\n >\n {value}\n </span>\n </div>\n );\n});\n"],"names":["SpacecraftCard","_a","statusColor","DataCell"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SpacecraftCard.js","names":[],"sources":["../../../src/react/cards/SpacecraftCard.tsx"],"sourcesContent":["/**\n * @zendir/ui - SpacecraftCard Component\n *\n * Enterprise-grade spacecraft information card.\n *\n * AstroUXDS Compliance:\n * - Status colors used for health/operational status only\n * - Orbit type uses Zendir-Astro data viz colors (categorical)\n * - Zendir accent colors for interactive elements\n * - Tabular numbers with fontVariantNumeric for data\n * - Sentence-case labels per Tier 3 compliance\n *\n * Features:\n * - Full null-safety with graceful fallbacks\n * - WCAG 2.1 AA accessibility\n * - Keyboard navigation\n * - Smooth animations with reduced-motion support\n * - Loading skeleton state\n * - Error boundary support\n * - Real SDK integration via optional client prop\n */\n\nimport React, { memo, useCallback, useMemo } from \"react\";\nimport type { SpacecraftPosition, TelemetryData } from \"../types\";\nimport { useTheme } from \"../theme\";\nimport { Icon, type IconName } from \"../core/display/Icon\";\nimport { CardHeader } from \"../core/display/CardHeader\";\nimport { HeaderIconWithStatus } from \"../core/display/HeaderIconWithStatus\";\nimport { useCompactMode } from \"../hooks\";\nimport { useCardBorderStyle } from \"../context/DisplaySettingsContext\";\n\n// ZendirClient is optional - only used when SDK is installed\ntype ZendirClient = any;\nimport {\n safeNumber,\n formatCoordinate,\n formatAltitude,\n formatVelocity,\n formatPercentage,\n formatTime,\n getStatusColor,\n classNames,\n safeAccentText,\n type StatusLevel,\n} from \"../utils\";\n\nexport interface SpacecraftCardProps {\n /** Spacecraft position data (for direct data mode) */\n spacecraft?: SpacecraftPosition;\n /** Optional telemetry data */\n telemetry?: TelemetryData;\n /** Show expanded orbit info */\n showOrbit?: boolean;\n /** Show telemetry summary */\n showTelemetry?: boolean;\n /** Loading state */\n loading?: boolean;\n /** Click handler */\n onClick?: (spacecraft: SpacecraftPosition) => void;\n /** Custom className */\n className?: string;\n /** Connected mode: SDK client */\n client?: ZendirClient;\n /** Connected mode: Spacecraft ID to fetch */\n spacecraftId?: string;\n /** Enable compact mode - shows condensed view that expands on hover/click */\n compact?: boolean;\n /** Start expanded when in compact mode (pinned state) */\n defaultExpanded?: boolean;\n /** Callback when pin state changes in compact mode */\n onPinChange?: (isPinned: boolean) => void;\n}\n\n/**\n * Get orbit type color based on orbit classification\n * Uses Zendir-Astro palette for categorical (non-status) classification\n */\nfunction getOrbitTypeColor(\n orbitType: string | undefined,\n accentColor: string,\n): string {\n // Orbit type colors using pure Zendir brand palette\n // These are categorical colors, not status colors\n const colors: Record<string, string> = {\n LEO: \"#3E3CFF\", // Zendir Electric - Low Earth Orbit\n MEO: \"#3548C0\", // Zendir Prussian Blue Light - Medium Earth Orbit\n GEO: \"#9D70FF\", // Zendir Purple - Geostationary\n HEO: \"#1B2DA0\", // Zendir Prussian Blue - Highly Elliptical\n SSO: \"#B48DFF\", // Zendir Purple Light - Sun-Synchronous\n POLAR: \"#6B69FF\", // Zendir Electric Light - Polar\n };\n return colors[orbitType?.toUpperCase() ?? \"\"] ?? accentColor;\n}\n\n/**\n * Derive health status from spacecraft or telemetry\n * Prefers telemetry.health.status, falls back to spacecraft.status\n */\nfunction deriveHealthStatus(\n spacecraftStatus: StatusLevel | undefined,\n telemetryStatus: string | undefined,\n): StatusLevel {\n // Prefer telemetry if available, but also validate it's a proper StatusLevel\n if (telemetryStatus) {\n const validStatuses: StatusLevel[] = [\n \"off\",\n \"standby\",\n \"normal\",\n \"caution\",\n \"serious\",\n \"critical\",\n ];\n const normalized = telemetryStatus.toLowerCase();\n if (validStatuses.includes(normalized as StatusLevel)) {\n return normalized as StatusLevel;\n }\n // Legacy mapping for backwards compatibility\n switch (normalized) {\n case \"healthy\":\n case \"nominal\":\n case \"operational\":\n return \"normal\";\n case \"warning\":\n case \"degraded\":\n return \"caution\";\n case \"failed\":\n case \"error\":\n return \"critical\";\n case \"idle\":\n return \"standby\";\n }\n }\n // Use spacecraft.status directly (already typed as StatusLevel)\n return spacecraftStatus ?? \"off\";\n}\n\n/**\n * SpacecraftCard - Displays spacecraft position and status information\n *\n * @example\n * ```tsx\n * // Direct data mode\n * <SpacecraftCard\n * spacecraft={spacecraftData}\n * telemetry={telemetryData}\n * showOrbit\n * showTelemetry\n * onClick={() => {}}\n * />\n *\n * // Connected mode (auto-fetches via SDK)\n * <SpacecraftCard\n * client={zendirClient}\n * spacecraftId=\"iss-25544\"\n * showTelemetry\n * />\n * ```\n */\nexport const SpacecraftCard = memo(function SpacecraftCard({\n spacecraft,\n telemetry,\n showOrbit = false,\n showTelemetry = false,\n loading = false,\n onClick,\n className = \"\",\n compact = false,\n defaultExpanded = false,\n onPinChange,\n}: SpacecraftCardProps): React.ReactElement {\n const { tokens, theme, prefersReducedMotion } = useTheme();\n const isTransparentTheme =\n theme === \"transparent\" ||\n theme === \"transparent-bold\" ||\n theme === \"transparent-minimal\";\n const isBoldVariant = theme === \"transparent-bold\";\n const isMinimalVariant = theme === \"transparent-minimal\";\n const useGlassMode = isBoldVariant || isMinimalVariant;\n\n // Glass accent colors for bold/minimal themes (matching Container/AstroChart)\n const glassAccentColor = tokens.colors.accent.primary;\n const glassAccentMuted = `${glassAccentColor}66`;\n\n // WCAG AA safe accent for use as foreground text on dark backgrounds\n const accentTextColor = useMemo(\n () => safeAccentText(tokens.colors.accent.primary),\n [tokens.colors.accent.primary],\n );\n\n // Use transparent background with blur for transparent themes (matching Timeline)\n const cardBg = isTransparentTheme\n ? \"transparent\"\n : tokens.colors.background.surface;\n const cardGlass = isTransparentTheme\n ? {\n backdropFilter: \"blur(12px)\" as const,\n WebkitBackdropFilter: \"blur(12px)\" as const,\n }\n : {};\n // Get card border style based on accentBorders setting\n const cardBorderStyle = useCardBorderStyle(tokens, isTransparentTheme);\n\n // Glass mode container style (matching Container/AstroChart for bold/minimal)\n const glassContainerStyle: React.CSSProperties = useGlassMode\n ? {\n backgroundColor: \"rgba(10, 15, 25, 0.35)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n border: `1px solid ${glassAccentMuted}`,\n borderTop: isBoldVariant\n ? `2px solid ${glassAccentColor}`\n : `1px solid ${glassAccentColor}`,\n }\n : {};\n\n // Compact mode state management\n const {\n expanded,\n isPinned,\n isHovered: _isHovered,\n handlers: compactHandlers,\n transitionDuration: _compactTransition,\n } = useCompactMode({\n compact,\n defaultExpanded,\n onPinChange,\n });\n\n // Smooth animation timing\n const animationDuration = prefersReducedMotion ? 0 : 250;\n const animationEasing = \"cubic-bezier(0.4, 0, 0.2, 1)\";\n\n // Memoized click handler\n const _handleClick = useCallback(() => {\n if (onClick && spacecraft) {\n onClick(spacecraft);\n }\n }, [onClick, spacecraft]);\n\n // Keyboard handler for accessibility\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (onClick && spacecraft && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n onClick(spacecraft);\n }\n },\n [onClick, spacecraft],\n );\n\n // Memoized computed values\n const orbitColor = useMemo(\n () =>\n getOrbitTypeColor(spacecraft?.orbitType, tokens.colors.accent.primary),\n [spacecraft?.orbitType, tokens.colors.accent.primary],\n );\n\n const healthStatus = useMemo(\n () => deriveHealthStatus(spacecraft?.status, telemetry?.health?.status),\n [spacecraft?.status, telemetry?.health?.status],\n );\n\n const statusColor = useMemo(\n () => getStatusColor(healthStatus),\n [healthStatus],\n );\n\n // Animation duration (respects reduced motion)\n const transitionDuration = prefersReducedMotion ? \"0ms\" : \"200ms\";\n\n // Combined click handler for compact mode and onClick (must be before early returns)\n const combinedClickHandler = useCallback(() => {\n if (compact) {\n compactHandlers.onClick();\n }\n if (onClick && spacecraft) {\n onClick(spacecraft);\n }\n }, [compact, compactHandlers, onClick, spacecraft]);\n\n // Loading state\n if (loading) {\n return (\n <div\n className={classNames(\"zendir-spacecraft-card\", \"loading\", className)}\n role=\"article\"\n aria-busy=\"true\"\n aria-label=\"Loading spacecraft data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n minHeight: 180,\n }}\n >\n {/* Loading skeleton */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 12,\n marginBottom: 16,\n }}\n >\n <div\n style={{\n width: 32,\n height: 32,\n borderRadius: \"50%\",\n backgroundColor: \"rgba(255,255,255,0.1)\",\n animation: \"pulse 1.5s ease-in-out infinite\",\n }}\n />\n <div style={{ flex: 1 }}>\n <div\n style={{\n height: 16,\n width: \"60%\",\n backgroundColor: \"rgba(255,255,255,0.1)\",\n borderRadius: 4,\n animation: \"pulse 1.5s ease-in-out infinite\",\n }}\n />\n </div>\n </div>\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(2, 1fr)\",\n gap: 12,\n }}\n >\n {[1, 2, 3, 4].map((i) => (\n <div key={i}>\n <div\n style={{\n height: 10,\n width: \"40%\",\n backgroundColor: \"rgba(255,255,255,0.08)\",\n borderRadius: 2,\n marginBottom: 4,\n }}\n />\n <div\n style={{\n height: 14,\n width: \"70%\",\n backgroundColor: \"rgba(255,255,255,0.1)\",\n borderRadius: 2,\n }}\n />\n </div>\n ))}\n </div>\n <style>{`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}</style>\n </div>\n );\n }\n\n // Empty state\n if (!spacecraft) {\n return (\n <div\n className={classNames(\"zendir-spacecraft-card\", \"empty\", className)}\n role=\"article\"\n aria-label=\"No spacecraft data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n ...(tokens.colors.border.cardStyleDashed ?? {}),\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.lg,\n textAlign: \"center\",\n color: tokens.colors.text.tertiary,\n }}\n >\n <svg\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n style={{ marginBottom: 8, opacity: 0.5 }}\n >\n <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\" />\n </svg>\n <p style={{ margin: 0, fontSize: tokens.typography.body[2].fontSize }}>\n No spacecraft data available\n </p>\n </div>\n );\n }\n\n // Compact view - shows key info in a single row\n // Compact metric item component for consistent styling\n const CompactMetric = ({\n icon,\n label,\n value,\n color,\n }: {\n icon: IconName;\n label: string;\n value: string | number;\n color?: string;\n }) => (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 3,\n padding: `2px 0`,\n }}\n >\n <Icon\n name={icon}\n size={12}\n color={color ?? tokens.colors.text.secondary}\n />\n <span\n style={{\n fontSize: tokens.typography.fontSize.micro, // 0.5625rem / 9px (AstroUXDS micro)\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary, // Public Sans → Roboto fallback → system stack\n color: tokens.colors.text.tertiary,\n textTransform: \"uppercase\",\n minWidth: 8,\n }}\n >\n {label.charAt(0)}\n </span>\n <span\n style={{\n fontVariantNumeric: \"tabular-nums\",\n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: tokens.typography.fontSize.xs,\n color: color ?? tokens.colors.text.primary,\n fontWeight: tokens.typography.fontWeight.medium,\n }}\n >\n {value}\n </span>\n </div>\n );\n\n // Compact view content - reusable for rendering\n const renderCompactContent = () => {\n const power = telemetry?.subsystems?.power ?? telemetry?.power;\n const batteryLevel = power?.batteryLevel;\n const batteryStatusLocal =\n batteryLevel !== undefined\n ? batteryLevel > 50\n ? \"normal\"\n : batteryLevel > 20\n ? \"caution\"\n : \"critical\"\n : \"off\";\n\n // Status color for header icon\n const statusColor = getStatusColor(healthStatus);\n\n return (\n <>\n {/* Header: Icon (status colored) → Status symbol → Name → Badges */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: tokens.spacing.xs,\n paddingBottom: tokens.spacing.xs,\n borderBottom: useGlassMode\n ? \"none\"\n : `1px solid ${tokens.colors.border.muted}`,\n position: \"relative\",\n zIndex: 1,\n }}\n >\n {/* Left side: Icon + Name + Accent line */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: tokens.spacing.xs,\n flex: 1,\n minWidth: 0,\n }}\n >\n {/* Icon with status badge - MonitoringIcon pattern */}\n <HeaderIconWithStatus\n icon=\"satellite-transmit\"\n size={18}\n status={healthStatus}\n statusColor={statusColor}\n />\n {/* Name - accent color for glass mode */}\n <span\n style={{\n fontWeight: tokens.typography.fontWeight.semibold,\n fontSize: tokens.typography.fontSize.sm,\n fontFamily: tokens.typography.fontFamily.primary,\n color: useGlassMode ? glassAccentColor : undefined,\n textShadow: useGlassMode\n ? `0 0 16px ${glassAccentMuted}`\n : undefined,\n whiteSpace: \"nowrap\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n }}\n >\n {(spacecraft.name ?? spacecraft.id ?? \"Unknown\").split(\" \")[0]}\n </span>\n {/* Accent line for glass mode */}\n {useGlassMode && (\n <div\n style={{\n flex: 1,\n height: isBoldVariant ? \"2px\" : \"1px\",\n minWidth: 20,\n background: `linear-gradient(90deg, ${glassAccentColor} 0%, ${glassAccentMuted} 60%, transparent 100%)`,\n boxShadow: isBoldVariant\n ? `0 0 8px ${glassAccentMuted}`\n : undefined,\n }}\n />\n )}\n </div>\n\n {/* Right side: Orbit type badge + Pin */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: tokens.spacing.xs,\n flexShrink: 0,\n }}\n >\n {/* Orbit type badge */}\n <span\n style={{\n backgroundColor: `${orbitColor}20`,\n color: orbitColor,\n padding: `1px 6px`,\n borderRadius: tokens.borderRadius.sm,\n fontSize: tokens.typography.fontSize.xxs, // 0.625rem / 10px (AstroUXDS compact)\n fontWeight: tokens.typography.fontWeight.medium,\n fontFamily: tokens.typography.fontFamily.primary,\n }}\n >\n {spacecraft.orbitType ?? \"—\"}\n </span>\n {/* Pin badge */}\n {isPinned && (\n <Icon\n name=\"lock\"\n size={10}\n color={tokens.colors.accent.primary}\n />\n )}\n </div>\n </div>\n\n {/* Metrics grid - 3 columns */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(3, 1fr)\",\n gap: `${tokens.spacing.xs} ${tokens.spacing.sm}`,\n }}\n >\n {/* Position metrics */}\n <CompactMetric\n icon=\"location\"\n label=\"Latitude\"\n value={formatCoordinate(spacecraft.latitude, \"lat\")}\n />\n <CompactMetric\n icon=\"location\"\n label=\"Longitude\"\n value={formatCoordinate(spacecraft.longitude, \"lon\")}\n />\n <CompactMetric\n icon=\"orbit\"\n label=\"Altitude\"\n value={formatAltitude(spacecraft.altitude)}\n color={orbitColor}\n />\n\n {/* Velocity */}\n {spacecraft.velocity !== undefined && (\n <CompactMetric\n icon=\"rocket\"\n label=\"Velocity\"\n value={formatVelocity(spacecraft.velocity)}\n />\n )}\n\n {/* Telemetry data if available */}\n {batteryLevel !== undefined && (\n <CompactMetric\n icon=\"battery\"\n label=\"Battery\"\n value={formatPercentage(batteryLevel)}\n color={getStatusColor(batteryStatusLocal as StatusLevel)}\n />\n )}\n\n {/* Inclination if available */}\n {spacecraft.inclination !== undefined && (\n <CompactMetric\n icon=\"orbit\"\n label=\"Inclination\"\n value={`${safeNumber(spacecraft.inclination, 1)}°`}\n />\n )}\n </div>\n </>\n );\n };\n\n // Compact mode with in-place expansion - cards push each other\n if (compact) {\n return (\n <article\n className={classNames(\n \"zendir-spacecraft-card\",\n \"compact\",\n expanded ? \"expanded\" : \"\",\n className,\n )}\n {...compactHandlers}\n aria-label={`Spacecraft: ${spacecraft.name ?? spacecraft.id}${expanded ? \"\" : \" (compact)\"}`}\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n // Use glass container style for bold/minimal themes\n ...(useGlassMode\n ? glassContainerStyle\n : {\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n }),\n borderRadius: tokens.borderRadius.lg,\n padding: expanded ? tokens.spacing.md : tokens.spacing.sm,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n fontSize: expanded\n ? tokens.typography.fontSize.base\n : tokens.typography.fontSize.sm,\n cursor: \"pointer\",\n transition: `all ${animationDuration}ms ${animationEasing}`,\n boxShadow: expanded\n ? `0 12px 40px rgba(0,0,0,0.4), 0 0 0 1px ${orbitColor}30`\n : \"none\",\n zIndex: expanded ? 50 : 1,\n }}\n >\n {/* Glass gradient overlay for bold/minimal themes */}\n {useGlassMode && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n background:\n \"linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.1) 100%)\",\n pointerEvents: \"none\",\n zIndex: 0,\n }}\n />\n )}\n {expanded ? (\n // Full expanded content\n <>\n {/* Full expanded header - matches MonitoringIcon layout pattern */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: tokens.spacing.sm,\n marginBottom: tokens.spacing.md,\n }}\n >\n {/* Icon with status badge - MonitoringIcon pattern */}\n <HeaderIconWithStatus\n icon=\"satellite-transmit\"\n size={24}\n status={healthStatus}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <h3\n style={{\n margin: 0,\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.semibold,\n lineHeight: 1.2,\n }}\n >\n {spacecraft.name ?? spacecraft.id}\n </h3>\n {isPinned && (\n <Icon\n name=\"lock\"\n size={12}\n color={tokens.colors.accent.primary}\n />\n )}\n </div>\n {spacecraft.id && spacecraft.name && (\n <span\n style={{\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n }}\n >\n {spacecraft.id}\n </span>\n )}\n </div>\n <span\n style={{\n backgroundColor: `${orbitColor}20`,\n color: orbitColor,\n padding: `4px 8px`,\n borderRadius: tokens.borderRadius.sm,\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n flexShrink: 0,\n }}\n >\n {spacecraft.orbitType ?? \"Unknown\"}\n </span>\n </div>\n\n {/* Position Grid */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(2, 1fr)\",\n gap: tokens.spacing.sm,\n marginBottom: tokens.spacing.md,\n }}\n >\n <div>\n <span\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Latitude\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: \"tabular-nums\",\n fontFamily: tokens.typography.fontFamily.mono,\n }}\n >\n {formatCoordinate(spacecraft.latitude, \"lat\")}\n </span>\n </div>\n <div>\n <span\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Longitude\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: \"tabular-nums\",\n fontFamily: tokens.typography.fontFamily.mono,\n }}\n >\n {formatCoordinate(spacecraft.longitude, \"lon\")}\n </span>\n </div>\n <div>\n <span\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Altitude\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: \"tabular-nums\",\n fontFamily: tokens.typography.fontFamily.mono,\n color: orbitColor,\n }}\n >\n {formatAltitude(spacecraft.altitude)}\n </span>\n </div>\n <div>\n <span\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginBottom: 2,\n }}\n >\n Velocity\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.medium,\n fontVariantNumeric: \"tabular-nums\",\n fontFamily: tokens.typography.fontFamily.mono,\n }}\n >\n {formatVelocity(spacecraft.velocity)}\n </span>\n </div>\n </div>\n\n {/* Timestamp */}\n {spacecraft.timestamp && (\n <time\n dateTime={spacecraft.timestamp}\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {formatTime(spacecraft.timestamp)}\n </time>\n )}\n </>\n ) : (\n // Compact content\n renderCompactContent()\n )}\n </article>\n );\n }\n\n return (\n <article\n className={classNames(\n \"zendir-spacecraft-card\",\n compact ? \"expanded\" : \"\",\n className,\n )}\n onClick={compact || onClick ? combinedClickHandler : undefined}\n onKeyDown={onClick ? handleKeyDown : compactHandlers.onKeyDown}\n tabIndex={onClick || compact ? 0 : undefined}\n role={compact ? compactHandlers.role : \"article\"}\n aria-expanded={compact ? compactHandlers[\"aria-expanded\"] : undefined}\n aria-label={`Spacecraft: ${spacecraft.name ?? spacecraft.id}`}\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n ...(useGlassMode\n ? glassContainerStyle\n : {\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n }),\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n cursor: onClick || compact ? \"pointer\" : \"default\",\n transition: `all ${transitionDuration} ease-out`,\n outline: \"none\",\n }}\n onMouseEnter={(e) => {\n if (compact) compactHandlers.onMouseEnter();\n if (onClick) {\n e.currentTarget.style.borderColor = tokens.colors.border.focus;\n e.currentTarget.style.boxShadow = tokens.shadows.md;\n e.currentTarget.style.transform = prefersReducedMotion\n ? \"none\"\n : \"translateY(-2px)\";\n }\n }}\n onMouseLeave={(e) => {\n if (compact) compactHandlers.onMouseLeave();\n if (onClick) {\n e.currentTarget.style.borderColor = tokens.colors.border.muted;\n e.currentTarget.style.boxShadow = \"none\";\n e.currentTarget.style.transform = \"none\";\n }\n }}\n onFocus={(e) => {\n e.currentTarget.style.outline = `2px solid ${tokens.colors.border.focus}`;\n e.currentTarget.style.outlineOffset = \"2px\";\n }}\n onBlur={(e) => {\n e.currentTarget.style.outline = \"none\";\n }}\n >\n {/* Glass gradient overlay for bold/minimal themes */}\n {useGlassMode && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n background:\n \"linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.1) 100%)\",\n pointerEvents: \"none\",\n zIndex: 0,\n }}\n />\n )}\n\n {/* Unified Card Header - handles all theme variants */}\n <CardHeader\n icon=\"satellite-transmit\"\n title={spacecraft.name ?? spacecraft.id ?? \"Unknown\"}\n subtitle={spacecraft.id && spacecraft.name ? spacecraft.id : undefined}\n status={healthStatus}\n badge={spacecraft.orbitType ?? \"Unknown\"}\n badgeColor={orbitColor}\n isPinned={compact && isPinned}\n />\n\n {/* Position Data Grid */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(2, 1fr)\",\n gap: tokens.spacing.sm,\n }}\n >\n <DataCell\n label=\"Latitude\"\n value={formatCoordinate(spacecraft.latitude, \"lat\")}\n tokens={tokens}\n highlightColor={accentTextColor}\n />\n <DataCell\n label=\"Longitude\"\n value={formatCoordinate(spacecraft.longitude, \"lon\")}\n tokens={tokens}\n highlightColor={accentTextColor}\n />\n <DataCell\n label=\"Altitude\"\n value={formatAltitude(spacecraft.altitude)}\n highlight\n tokens={tokens}\n highlightColor={accentTextColor}\n />\n <DataCell\n label=\"Velocity\"\n value={formatVelocity(spacecraft.velocity)}\n tokens={tokens}\n highlightColor={accentTextColor}\n />\n </div>\n\n {/* Orbit Info (Optional) */}\n {showOrbit && spacecraft.inclination !== undefined && (\n <div\n style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.md,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n }}\n >\n <DataCell\n label=\"Inclination\"\n value={`${safeNumber(spacecraft.inclination, 1)}°`}\n inline\n tokens={tokens}\n />\n </div>\n )}\n\n {/* Telemetry Summary (Optional) */}\n {showTelemetry && telemetry && (\n <div\n style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.md,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n }}\n >\n {/* Health Status */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: tokens.spacing.sm,\n marginBottom: tokens.spacing.sm,\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n width: 10,\n height: 10,\n borderRadius: \"50%\",\n backgroundColor: statusColor,\n boxShadow: `0 0 8px ${statusColor}60`,\n }}\n />\n <span\n style={{\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n color: statusColor,\n textTransform: \"capitalize\",\n }}\n >\n {telemetry.health?.status ?? \"Unknown\"}\n </span>\n </div>\n\n {/* Battery Progress */}\n {telemetry.power?.batteryLevel !== undefined && (\n <div>\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n marginBottom: 4,\n fontSize: tokens.typography.fontSize.xs,\n }}\n >\n <span style={{ color: tokens.colors.text.tertiary }}>\n Battery\n </span>\n <span\n style={{\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {formatPercentage(telemetry.power.batteryLevel, false, 0)}\n </span>\n </div>\n <div\n style={{\n height: 4,\n backgroundColor: tokens.colors.border.muted,\n borderRadius: 2,\n overflow: \"hidden\",\n }}\n >\n <div\n role=\"progressbar\"\n aria-valuenow={telemetry.power.batteryLevel}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label=\"Battery level\"\n style={{\n height: \"100%\",\n width: `${Math.min(100, Math.max(0, telemetry.power.batteryLevel))}%`,\n backgroundColor:\n telemetry.power.batteryLevel > 30\n ? tokens.colors.status.normal\n : tokens.colors.status.critical,\n borderRadius: 2,\n transition: `width ${transitionDuration} ease-out`,\n }}\n />\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Timestamp Footer */}\n {spacecraft.timestamp && (\n <footer\n style={{\n marginTop: tokens.spacing.md,\n paddingTop: tokens.spacing.sm,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n textAlign: \"right\",\n }}\n >\n <time dateTime={spacecraft.timestamp}>\n {formatTime(spacecraft.timestamp)} UTC\n </time>\n </footer>\n )}\n </article>\n );\n});\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\ninterface DataCellProps {\n label: string;\n value: string;\n highlight?: boolean;\n inline?: boolean;\n tokens: ReturnType<typeof useTheme>[\"tokens\"];\n /** WCAG AA safe highlight color (computed via safeAccentText) */\n highlightColor?: string;\n}\n\nconst DataCell = memo(function DataCell({\n label,\n value,\n highlight = false,\n inline = false,\n tokens,\n highlightColor,\n}: DataCellProps): React.ReactElement {\n if (inline) {\n return (\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span\n style={{\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary, // WCAG AA compliant\n fontWeight: tokens.typography.fontWeight.medium,\n }}\n >\n {label}\n </span>\n <span\n style={{\n fontSize: tokens.typography.fontSize.sm,\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: \"tabular-nums\",\n color: tokens.colors.text.primary,\n }}\n >\n {value}\n </span>\n </div>\n );\n }\n\n return (\n <div>\n <span\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary, // WCAG AA compliant\n fontWeight: tokens.typography.fontWeight.medium,\n marginBottom: 2,\n }}\n >\n {label}\n </span>\n <span\n style={{\n display: \"block\",\n fontSize: tokens.typography.fontSize.sm,\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: \"tabular-nums\",\n color: highlight\n ? (highlightColor ?? safeAccentText(tokens.colors.accent.primary))\n : tokens.colors.text.primary,\n fontWeight: tokens.typography.fontWeight.medium,\n }}\n >\n {value}\n </span>\n </div>\n );\n});\n"],"mappings":"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"}
|