@zendir/ui 0.1.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 +19 -0
- package/LICENSE +21 -0
- package/README.md +589 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/react/3d/EarthViewer.d.ts +46 -0
- package/dist/react/3d/EarthViewer.js +836 -0
- package/dist/react/3d/EarthViewer.js.map +1 -0
- package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
- package/dist/react/3d/SolarSystemViewer.js +372 -0
- package/dist/react/3d/SolarSystemViewer.js.map +1 -0
- package/dist/react/3d/ZenSpace3D.d.ts +16 -0
- package/dist/react/3d/ZenSpace3D.js +1253 -0
- package/dist/react/3d/ZenSpace3D.js.map +1 -0
- package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
- package/dist/react/3d/ZenSpace3DCesium.js +186 -0
- package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
- package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
- package/dist/react/3d/ZenSpace3DShaders.js +94 -0
- package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
- package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
- package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
- package/dist/react/3d/ZenSpace3DUtils.js +213 -0
- package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
- package/dist/react/3d/index.d.ts +23 -0
- package/dist/react/3d/threeLoader.d.ts +22 -0
- package/dist/react/3d/threeLoader.js +18 -0
- package/dist/react/3d/threeLoader.js.map +1 -0
- package/dist/react/astro/ClassificationBanner.d.ts +25 -0
- package/dist/react/astro/ClassificationBanner.js +83 -0
- package/dist/react/astro/ClassificationBanner.js.map +1 -0
- package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
- package/dist/react/astro/GlobalStatusBar.js +165 -0
- package/dist/react/astro/GlobalStatusBar.js.map +1 -0
- package/dist/react/astro/MissionClock.d.ts +169 -0
- package/dist/react/astro/MissionClock.js +411 -0
- package/dist/react/astro/MissionClock.js.map +1 -0
- package/dist/react/astro/MonitoringIcon.d.ts +60 -0
- package/dist/react/astro/MonitoringIcon.js +369 -0
- package/dist/react/astro/MonitoringIcon.js.map +1 -0
- package/dist/react/astro/Notification.d.ts +42 -0
- package/dist/react/astro/Notification.js +156 -0
- package/dist/react/astro/Notification.js.map +1 -0
- package/dist/react/astro/Progress.d.ts +39 -0
- package/dist/react/astro/Progress.js +149 -0
- package/dist/react/astro/Progress.js.map +1 -0
- package/dist/react/astro/SimulationControls.d.ts +136 -0
- package/dist/react/astro/SimulationControls.js +668 -0
- package/dist/react/astro/SimulationControls.js.map +1 -0
- package/dist/react/astro/StatusIndicator.d.ts +34 -0
- package/dist/react/astro/StatusIndicator.js +189 -0
- package/dist/react/astro/StatusIndicator.js.map +1 -0
- package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
- package/dist/react/astro/UnifiedTimeline.js +1768 -0
- package/dist/react/astro/UnifiedTimeline.js.map +1 -0
- package/dist/react/astro/index.d.ts +63 -0
- package/dist/react/cards/AccessCard.d.ts +37 -0
- package/dist/react/cards/AccessCard.js +410 -0
- package/dist/react/cards/AccessCard.js.map +1 -0
- package/dist/react/cards/OrbitCard.d.ts +31 -0
- package/dist/react/cards/OrbitCard.js +372 -0
- package/dist/react/cards/OrbitCard.js.map +1 -0
- package/dist/react/cards/SpacecraftCard.d.ts +54 -0
- package/dist/react/cards/SpacecraftCard.js +941 -0
- package/dist/react/cards/SpacecraftCard.js.map +1 -0
- package/dist/react/cards/TelemetryCard.d.ts +40 -0
- package/dist/react/cards/TelemetryCard.js +742 -0
- package/dist/react/cards/TelemetryCard.js.map +1 -0
- package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
- package/dist/react/cards/TelemetryStreamCard.js +309 -0
- package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
- package/dist/react/cards/index.d.ts +13 -0
- package/dist/react/charts/GroundTrackMap.d.ts +112 -0
- package/dist/react/charts/GroundTrackMap.js +1123 -0
- package/dist/react/charts/GroundTrackMap.js.map +1 -0
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
- package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
- package/dist/react/charts/index.d.ts +10 -0
- package/dist/react/charts/unified/AstroChart.d.ts +24 -0
- package/dist/react/charts/unified/AstroChart.js +1405 -0
- package/dist/react/charts/unified/AstroChart.js.map +1 -0
- package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
- package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
- package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
- package/dist/react/charts/unified/domain.d.ts +845 -0
- package/dist/react/charts/unified/domain.js +3168 -0
- package/dist/react/charts/unified/domain.js.map +1 -0
- package/dist/react/charts/unified/generators.d.ts +276 -0
- package/dist/react/charts/unified/generators.js +518 -0
- package/dist/react/charts/unified/generators.js.map +1 -0
- package/dist/react/charts/unified/index.d.ts +55 -0
- package/dist/react/charts/unified/presets.d.ts +290 -0
- package/dist/react/charts/unified/presets.js +999 -0
- package/dist/react/charts/unified/presets.js.map +1 -0
- package/dist/react/charts/unified/sync.d.ts +69 -0
- package/dist/react/charts/unified/sync.js +219 -0
- package/dist/react/charts/unified/sync.js.map +1 -0
- package/dist/react/charts/unified/theme.d.ts +447 -0
- package/dist/react/charts/unified/theme.js +562 -0
- package/dist/react/charts/unified/theme.js.map +1 -0
- package/dist/react/charts/unified/types.d.ts +826 -0
- package/dist/react/charts/unified/useChartStream.d.ts +58 -0
- package/dist/react/charts/unified/useChartStream.js +226 -0
- package/dist/react/charts/unified/useChartStream.js.map +1 -0
- package/dist/react/chatgpt/AppCard.d.ts +59 -0
- package/dist/react/chatgpt/AppCard.js +306 -0
- package/dist/react/chatgpt/AppCard.js.map +1 -0
- package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
- package/dist/react/chatgpt/index.d.ts +167 -0
- package/dist/react/chatgpt/index.js +166 -0
- package/dist/react/chatgpt/index.js.map +1 -0
- package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
- package/dist/react/context/DisplaySettingsContext.js +169 -0
- package/dist/react/context/DisplaySettingsContext.js.map +1 -0
- package/dist/react/context/index.d.ts +5 -0
- package/dist/react/core/ActivityPlanner.d.ts +45 -0
- package/dist/react/core/ActivityPlanner.js +532 -0
- package/dist/react/core/ActivityPlanner.js.map +1 -0
- package/dist/react/core/AppBar.d.ts +71 -0
- package/dist/react/core/AppBar.js +817 -0
- package/dist/react/core/AppBar.js.map +1 -0
- package/dist/react/core/AstroIcon.d.ts +84 -0
- package/dist/react/core/AstroIcon.js +1243 -0
- package/dist/react/core/AstroIcon.js.map +1 -0
- package/dist/react/core/Badge.d.ts +27 -0
- package/dist/react/core/Badge.js +134 -0
- package/dist/react/core/Badge.js.map +1 -0
- package/dist/react/core/Button.d.ts +26 -0
- package/dist/react/core/Button.js +306 -0
- package/dist/react/core/Button.js.map +1 -0
- package/dist/react/core/CardHeader.d.ts +34 -0
- package/dist/react/core/CardHeader.js +316 -0
- package/dist/react/core/CardHeader.js.map +1 -0
- package/dist/react/core/ChatPanel.d.ts +627 -0
- package/dist/react/core/ChatPanel.js +1144 -0
- package/dist/react/core/ChatPanel.js.map +1 -0
- package/dist/react/core/Checkbox.d.ts +26 -0
- package/dist/react/core/Checkbox.js +130 -0
- package/dist/react/core/Checkbox.js.map +1 -0
- package/dist/react/core/ColorPickerPanel.d.ts +25 -0
- package/dist/react/core/ColorPickerPanel.js +293 -0
- package/dist/react/core/ColorPickerPanel.js.map +1 -0
- package/dist/react/core/CommandBuilder.d.ts +74 -0
- package/dist/react/core/CommandBuilder.js +518 -0
- package/dist/react/core/CommandBuilder.js.map +1 -0
- package/dist/react/core/ConfirmDialog.d.ts +45 -0
- package/dist/react/core/ConfirmDialog.js +315 -0
- package/dist/react/core/ConfirmDialog.js.map +1 -0
- package/dist/react/core/ConnectionForm.d.ts +57 -0
- package/dist/react/core/ConnectionForm.js +496 -0
- package/dist/react/core/ConnectionForm.js.map +1 -0
- package/dist/react/core/Container.d.ts +51 -0
- package/dist/react/core/Container.js +670 -0
- package/dist/react/core/Container.js.map +1 -0
- package/dist/react/core/CopyButton.d.ts +39 -0
- package/dist/react/core/CopyButton.js +105 -0
- package/dist/react/core/CopyButton.js.map +1 -0
- package/dist/react/core/DataTable.d.ts +113 -0
- package/dist/react/core/DataTable.js +446 -0
- package/dist/react/core/DataTable.js.map +1 -0
- package/dist/react/core/DataValue.d.ts +64 -0
- package/dist/react/core/DataValue.js +545 -0
- package/dist/react/core/DataValue.js.map +1 -0
- package/dist/react/core/Dialog.d.ts +32 -0
- package/dist/react/core/Dialog.js +201 -0
- package/dist/react/core/Dialog.js.map +1 -0
- package/dist/react/core/FileExplorer.d.ts +65 -0
- package/dist/react/core/FileExplorer.js +520 -0
- package/dist/react/core/FileExplorer.js.map +1 -0
- package/dist/react/core/GlassCard.d.ts +129 -0
- package/dist/react/core/GlassCard.js +375 -0
- package/dist/react/core/GlassCard.js.map +1 -0
- package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
- package/dist/react/core/HeaderIconWithStatus.js +157 -0
- package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
- package/dist/react/core/HexViewer.d.ts +143 -0
- package/dist/react/core/HexViewer.js +1106 -0
- package/dist/react/core/HexViewer.js.map +1 -0
- package/dist/react/core/Icon.d.ts +32 -0
- package/dist/react/core/Icon.js +142 -0
- package/dist/react/core/Icon.js.map +1 -0
- package/dist/react/core/ImageGallery.d.ts +41 -0
- package/dist/react/core/ImageGallery.js +320 -0
- package/dist/react/core/ImageGallery.js.map +1 -0
- package/dist/react/core/Input.d.ts +38 -0
- package/dist/react/core/Input.js +288 -0
- package/dist/react/core/Input.js.map +1 -0
- package/dist/react/core/LimitsBar.d.ts +51 -0
- package/dist/react/core/LimitsBar.js +200 -0
- package/dist/react/core/LimitsBar.js.map +1 -0
- package/dist/react/core/LogViewer.d.ts +61 -0
- package/dist/react/core/LogViewer.js +599 -0
- package/dist/react/core/LogViewer.js.map +1 -0
- package/dist/react/core/MessageStream.d.ts +58 -0
- package/dist/react/core/MessageStream.js +455 -0
- package/dist/react/core/MessageStream.js.map +1 -0
- package/dist/react/core/MissionCalendar.d.ts +81 -0
- package/dist/react/core/MissionCalendar.js +1049 -0
- package/dist/react/core/MissionCalendar.js.map +1 -0
- package/dist/react/core/NumberInput.d.ts +85 -0
- package/dist/react/core/NumberInput.js +507 -0
- package/dist/react/core/NumberInput.js.map +1 -0
- package/dist/react/core/PacketViewer.d.ts +73 -0
- package/dist/react/core/PacketViewer.js +431 -0
- package/dist/react/core/PacketViewer.js.map +1 -0
- package/dist/react/core/Pagination.d.ts +30 -0
- package/dist/react/core/Pagination.js +190 -0
- package/dist/react/core/Pagination.js.map +1 -0
- package/dist/react/core/PinInput.d.ts +41 -0
- package/dist/react/core/PinInput.js +210 -0
- package/dist/react/core/PinInput.js.map +1 -0
- package/dist/react/core/Popover.d.ts +55 -0
- package/dist/react/core/Popover.js +288 -0
- package/dist/react/core/Popover.js.map +1 -0
- package/dist/react/core/Select.d.ts +42 -0
- package/dist/react/core/Select.js +303 -0
- package/dist/react/core/Select.js.map +1 -0
- package/dist/react/core/SideNav.d.ts +103 -0
- package/dist/react/core/SideNav.js +551 -0
- package/dist/react/core/SideNav.js.map +1 -0
- package/dist/react/core/SidePanel.d.ts +33 -0
- package/dist/react/core/SidePanel.js +199 -0
- package/dist/react/core/SidePanel.js.map +1 -0
- package/dist/react/core/Tabs.d.ts +47 -0
- package/dist/react/core/Tabs.js +129 -0
- package/dist/react/core/Tabs.js.map +1 -0
- package/dist/react/core/Toast.d.ts +56 -0
- package/dist/react/core/Toast.js +229 -0
- package/dist/react/core/Toast.js.map +1 -0
- package/dist/react/core/Toggle.d.ts +22 -0
- package/dist/react/core/Toggle.js +151 -0
- package/dist/react/core/Toggle.js.map +1 -0
- package/dist/react/core/Tooltip.d.ts +19 -0
- package/dist/react/core/Tooltip.js +179 -0
- package/dist/react/core/Tooltip.js.map +1 -0
- package/dist/react/core/Typography.d.ts +127 -0
- package/dist/react/core/Typography.js +187 -0
- package/dist/react/core/Typography.js.map +1 -0
- package/dist/react/core/index.d.ts +108 -0
- package/dist/react/core/layout/Box.d.ts +77 -0
- package/dist/react/core/layout/Box.js +126 -0
- package/dist/react/core/layout/Box.js.map +1 -0
- package/dist/react/core/layout/Center.d.ts +20 -0
- package/dist/react/core/layout/Center.js +34 -0
- package/dist/react/core/layout/Center.js.map +1 -0
- package/dist/react/core/layout/Divider.d.ts +16 -0
- package/dist/react/core/layout/Divider.js +108 -0
- package/dist/react/core/layout/Divider.js.map +1 -0
- package/dist/react/core/layout/Flex.d.ts +30 -0
- package/dist/react/core/layout/Flex.js +128 -0
- package/dist/react/core/layout/Flex.js.map +1 -0
- package/dist/react/core/layout/Grid.d.ts +36 -0
- package/dist/react/core/layout/Grid.js +142 -0
- package/dist/react/core/layout/Grid.js.map +1 -0
- package/dist/react/core/layout/Spacer.d.ts +8 -0
- package/dist/react/core/layout/Spacer.js +31 -0
- package/dist/react/core/layout/Spacer.js.map +1 -0
- package/dist/react/core/layout/Stack.d.ts +54 -0
- package/dist/react/core/layout/Stack.js +74 -0
- package/dist/react/core/layout/Stack.js.map +1 -0
- package/dist/react/core/layout/index.d.ts +38 -0
- package/dist/react/core/layout/responsive.d.ts +23 -0
- package/dist/react/core/layout/responsive.js +26 -0
- package/dist/react/core/layout/responsive.js.map +1 -0
- package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
- package/dist/react/core/layout/useBreakpoint.js +73 -0
- package/dist/react/core/layout/useBreakpoint.js.map +1 -0
- package/dist/react/core/propertyConfig.d.ts +443 -0
- package/dist/react/core/propertyConfig.js +399 -0
- package/dist/react/core/propertyConfig.js.map +1 -0
- package/dist/react/hooks/index.d.ts +21 -0
- package/dist/react/hooks/useAccessWindows.d.ts +66 -0
- package/dist/react/hooks/useCompactMode.d.ts +82 -0
- package/dist/react/hooks/useCompactMode.js +62 -0
- package/dist/react/hooks/useCompactMode.js.map +1 -0
- package/dist/react/hooks/useLiveSelection.d.ts +57 -0
- package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
- package/dist/react/hooks/useSimulationTime.d.ts +61 -0
- package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
- package/dist/react/hooks/useSpacecraftPosition.js +89 -0
- package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
- package/dist/react/hooks/useTelemetry.d.ts +55 -0
- package/dist/react/hooks/useTelemetry.js +73 -0
- package/dist/react/hooks/useTelemetry.js.map +1 -0
- package/dist/react/hooks/useZendirSession.d.ts +109 -0
- package/dist/react/hooks/useZendirSession.js +148 -0
- package/dist/react/hooks/useZendirSession.js.map +1 -0
- package/dist/react/index.d.ts +74 -0
- package/dist/react/shared/ErrorBoundary.d.ts +63 -0
- package/dist/react/shared/ErrorBoundary.js +142 -0
- package/dist/react/shared/ErrorBoundary.js.map +1 -0
- package/dist/react/shared/Skeleton.d.ts +110 -0
- package/dist/react/shared/Skeleton.js +324 -0
- package/dist/react/shared/Skeleton.js.map +1 -0
- package/dist/react/shared/index.d.ts +12 -0
- package/dist/react/theme/ThemeProvider.d.ts +385 -0
- package/dist/react/theme/ThemeProvider.js +1096 -0
- package/dist/react/theme/ThemeProvider.js.map +1 -0
- package/dist/react/theme/astro-tokens.d.ts +153 -0
- package/dist/react/theme/cardAccent.d.ts +75 -0
- package/dist/react/theme/cardAccent.js +137 -0
- package/dist/react/theme/cardAccent.js.map +1 -0
- package/dist/react/theme/config.d.ts +39 -0
- package/dist/react/theme/index.d.ts +9 -0
- package/dist/react/types.d.ts +360 -0
- package/dist/react/types.js +58 -0
- package/dist/react/types.js.map +1 -0
- package/dist/react/utils/index.d.ts +247 -0
- package/dist/react/utils/index.js +423 -0
- package/dist/react/utils/index.js.map +1 -0
- package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
- package/dist/react/visualizations/EclipseTimerCard.js +250 -0
- package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
- package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
- package/dist/react/visualizations/LinkBudgetCard.js +444 -0
- package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
- package/dist/react/visualizations/NavBallCard.d.ts +17 -0
- package/dist/react/visualizations/NavBallCard.js +243 -0
- package/dist/react/visualizations/NavBallCard.js.map +1 -0
- package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
- package/dist/react/visualizations/PropulsionCard.js +298 -0
- package/dist/react/visualizations/PropulsionCard.js.map +1 -0
- package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
- package/dist/react/visualizations/SensorFootprintCard.js +326 -0
- package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
- package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
- package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
- package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
- package/dist/react/visualizations/index.d.ts +17 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +421 -0
- package/dist/react.js.map +1 -0
- package/dist/shaders/atmosphere.frag.js +5 -0
- package/dist/shaders/atmosphere.frag.js.map +1 -0
- package/dist/shaders/atmosphere.vert.js +5 -0
- package/dist/shaders/atmosphere.vert.js.map +1 -0
- package/dist/shaders/stars.frag.js +5 -0
- package/dist/shaders/stars.frag.js.map +1 -0
- package/dist/shaders/stars.vert.js +5 -0
- package/dist/shaders/stars.vert.js.map +1 -0
- package/dist/style.css +143 -0
- package/dist/tokens/index.d.ts +296 -0
- package/dist/tokens/index.js +263 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/tokens.css +155 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +220 -0
- package/sdk-stub.js +22 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TelemetryCard.js","sources":["../../../src/react/cards/TelemetryCard.tsx"],"sourcesContent":["/**\n * @zendir/ui - TelemetryCard Component\n * \n * Enterprise-grade spacecraft telemetry data card.\n * \n * AstroUXDS Compliance:\n * - Status colors used semantically (battery level, health status)\n * - Dual-coded status indicators (color + shape via StatusIndicator)\n * - Zendir accent colors for non-status elements (icons, decorative)\n * - Tabular numbers with fontVariantNumeric for data display\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 * - Subsystem toggles (power, attitude, comms)\n * - Anomaly alerts\n * - Loading and empty states\n */\n\nimport React, { memo, useMemo, useState } from 'react';\nimport type { TelemetryData } from '../types';\nimport { useTheme } from '../theme';\nimport { StatusIndicator } from '../astro';\nimport { DataValue, DataValueGroup } from '../core/DataValue';\nimport { getPropertyConfig } from '../core/propertyConfig';\nimport { AstroIcon } from '../core/AstroIcon';\nimport { CardHeader } from '../core/CardHeader';\nimport { HeaderIconWithStatus } from '../core/HeaderIconWithStatus';\nimport { Icon, type IconName } from '../core/Icon';\nimport { useCompactMode } from '../hooks';\nimport { useCardBorderStyle } from '../context/DisplaySettingsContext';\nimport {\n safeNumber,\n formatTime,\n classNames,\n getStatusColor,\n deriveBatteryStatus,\n normalizeStatus,\n type StatusLevel,\n} from '../utils';\n\nexport interface TelemetryCardProps {\n /** Telemetry data */\n telemetry?: TelemetryData;\n /** Spacecraft name */\n spacecraftName?: string;\n /** Show power subsystem */\n showPower?: boolean;\n /** Show attitude subsystem */\n showAttitude?: boolean;\n /** Show communications */\n showComms?: boolean;\n /** Loading state */\n loading?: boolean;\n /** Custom className */\n className?: 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 health status level\n * Uses normalizeStatus utility to convert SDK terms to StatusLevel\n */\nfunction getHealthStatus(healthStatus: string | undefined): StatusLevel {\n return normalizeStatus(healthStatus);\n}\n\n/**\n * Get battery status based on level\n * @deprecated Use deriveBatteryStatus from utils instead\n */\nfunction getBatteryStatus(level: number | undefined): StatusLevel {\n return deriveBatteryStatus(level);\n}\n\n/**\n * TelemetryCard - Displays spacecraft telemetry data\n * \n * @example\n * ```tsx\n * <TelemetryCard\n * telemetry={telemetryData}\n * spacecraftName=\"ISS\"\n * showPower\n * showAttitude\n * showComms\n * />\n * ```\n */\nexport const TelemetryCard = memo(function TelemetryCard({\n telemetry,\n spacecraftName,\n showPower = true,\n showAttitude = true,\n showComms = true,\n loading = false,\n className = '',\n compact = false,\n defaultExpanded = false,\n onPinChange,\n}: TelemetryCardProps): 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 // 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, transitionDuration: compactTransition } = useCompactMode({\n compact,\n defaultExpanded,\n onPinChange,\n });\n \n // Track if we're animating to prevent flicker\n const [_isAnimating, _setIsAnimating] = useState(false);\n \n // Smooth animation timing\n const animationDuration = prefersReducedMotion ? 0 : 250;\n const animationEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';\n\n // Computed statuses\n const healthStatus = useMemo(\n () => getHealthStatus(telemetry?.health?.status),\n [telemetry?.health?.status]\n );\n\n const batteryStatus = useMemo(\n () => getBatteryStatus(telemetry?.power?.batteryLevel),\n [telemetry?.power?.batteryLevel]\n );\n\n const transitionDuration = prefersReducedMotion ? '0ms' : '200ms';\n\n // Loading state\n if (loading) {\n return (\n <div\n className={classNames('zendir-telemetry-card', 'loading', className)}\n role=\"article\"\n aria-busy=\"true\"\n aria-label=\"Loading telemetry data\"\n style={{\n backgroundColor: cardBg,\n ...cardGlass,\n ...cardBorderStyle,\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n minHeight: 200,\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>\n <div\n style={{\n width: 24,\n height: 24,\n borderRadius: 4,\n backgroundColor: 'rgba(255,255,255,0.1)',\n }}\n />\n <div\n style={{\n height: 16,\n width: '40%',\n backgroundColor: 'rgba(255,255,255,0.1)',\n borderRadius: 4,\n }}\n />\n </div>\n {[1, 2, 3].map((i) => (\n <div key={i} style={{ marginBottom: 16 }}>\n <div\n style={{\n height: 12,\n width: '30%',\n backgroundColor: 'rgba(255,255,255,0.08)',\n borderRadius: 2,\n marginBottom: 8,\n }}\n />\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: 8,\n }}\n >\n {[1, 2, 3, 4].map((j) => (\n <div\n key={j}\n style={{\n height: 32,\n backgroundColor: 'rgba(255,255,255,0.06)',\n borderRadius: 4,\n }}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n }\n\n // Empty state\n if (!telemetry) {\n return (\n <div\n className={classNames('zendir-telemetry-card', 'empty', className)}\n role=\"article\"\n aria-label=\"No telemetry 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 <AstroIcon name=\"antenna\" size=\"normal\" label=\"\" style={{ opacity: 0.5 }} />\n <p style={{ margin: '8px 0 0 0', fontSize: tokens.typography.body[2].fontSize }}>No telemetry data available</p>\n </div>\n );\n }\n\n const sectionStyle: React.CSSProperties = {\n marginBottom: tokens.spacing.md,\n paddingBottom: tokens.spacing.md,\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n };\n\n /** Fixed width so all section and metric icons align on one vertical line */\n const iconColumnWidth = 20;\n const iconGap = tokens.spacing.sm;\n const rowGap = tokens.spacing.smd;\n const sectionGridColumns = `${iconColumnWidth}px 1fr ${iconColumnWidth}px 1fr`;\n\n // Compact metric item component for consistent styling\n const CompactMetric = ({ \n icon, \n label, \n value, \n color, \n astroIcon \n }: { \n icon?: string; \n label: string; \n value: string | number; \n color?: string;\n astroIcon?: string;\n }) => (\n <div style={{ \n display: 'flex', \n alignItems: 'center', \n gap: 3,\n padding: `2px 0`,\n }}>\n {astroIcon ? (\n <AstroIcon name={astroIcon} size={12} color={color ?? tokens.colors.text.secondary} />\n ) : icon ? (\n <Icon name={icon as IconName} size={12} color={color ?? tokens.colors.text.secondary} />\n ) : null}\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, // Roboto - Astro UX compliant\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 both states\n const renderCompactContent = () => {\n const power = telemetry?.power ?? telemetry?.subsystems?.power;\n const attitude = telemetry?.attitude ?? telemetry?.subsystems?.attitude;\n const comms = telemetry?.communications ?? telemetry?.subsystems?.comms;\n const thermal = telemetry?.subsystems?.thermal;\n const compactStatusColor = getStatusColor(healthStatus);\n\n return (\n <>\n {/* Header: Icon with status badge overlay → Name → (flex) → Badges on right */}\n {/* Follows MonitoringIcon layout pattern for consistency */}\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 with status badge + Name */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm, minWidth: 0, flex: 1 }}>\n {/* Icon with status badge - MonitoringIcon pattern */}\n <HeaderIconWithStatus \n icon=\"antenna-receive\" \n size={20} \n status={healthStatus}\n statusColor={compactStatusColor}\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 minWidth: 0,\n }}>\n {spacecraftName ? spacecraftName.split(' ')[0] : 'Telemetry'}\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: Badges (pin indicator, etc.) */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.xs, flexShrink: 0 }}>\n {isPinned && (\n <Icon name=\"lock\" size={10} color={tokens.colors.accent.primary} />\n )}\n </div>\n </div>\n\n {/* Metrics grid */}\n <div style={{ \n display: 'grid', \n gridTemplateColumns: 'repeat(3, 1fr)',\n gap: `${tokens.spacing.xs} ${tokens.spacing.sm}`,\n }}>\n {/* Power metrics */}\n {showPower && power && (\n <>\n {power.batteryLevel !== undefined && (\n <CompactMetric \n icon=\"battery\" \n label=\"Battery\" \n value={`${safeNumber(power.batteryLevel, 0)}%`}\n color={getStatusColor(batteryStatus)}\n />\n )}\n {(power.solarGeneration ?? power.solarArrayOutput) !== undefined && (\n <CompactMetric \n astroIcon=\"solar\" \n label=\"Solar\" \n value={`${safeNumber(power.solarGeneration ?? power.solarArrayOutput, 1)}W`}\n color={tokens.colors.status.standby}\n />\n )}\n {power.voltage !== undefined && (\n <CompactMetric \n astroIcon=\"propulsion-power\" \n label=\"Voltage\" \n value={`${safeNumber(power.voltage, 1)}V`}\n />\n )}\n </>\n )}\n\n {/* Attitude metrics */}\n {showAttitude && attitude && (\n <>\n {attitude.pointingError !== undefined && (\n <CompactMetric \n astroIcon=\"explore\" \n label=\"Pointing\" \n value={`${safeNumber(attitude.pointingError, 2)}°`}\n />\n )}\n {attitude.targetMode && (\n <CompactMetric \n astroIcon=\"explore\" \n label=\"Mode\" \n value={attitude.targetMode}\n />\n )}\n </>\n )}\n\n {/* Thermal metrics */}\n {thermal && (\n <>\n {thermal.cpuTemp !== undefined && (\n <CompactMetric \n icon=\"thermometer\" \n label=\"CPU\" \n value={`${safeNumber(thermal.cpuTemp, 0)}°C`}\n color={thermal.cpuTemp > 50 ? tokens.colors.status.caution : undefined}\n />\n )}\n </>\n )}\n\n {/* Comms metrics */}\n {showComms && comms && (\n <>\n {comms.signalStrength !== undefined && (\n <CompactMetric \n astroIcon=\"antenna\" \n label=\"Signal\" \n value={`${safeNumber(comms.signalStrength, 0)}%`}\n />\n )}\n {(comms.downlinkRate ?? comms.dataRate) !== undefined && (\n <CompactMetric \n astroIcon=\"antenna-transmit\" \n label=\"Rate\" \n value={`${safeNumber(comms.downlinkRate ?? comms.dataRate, 0)}Mb`}\n />\n )}\n {comms.transmitterStatus && (\n <CompactMetric \n astroIcon=\"antenna-receive\" \n label=\"TX\" \n value={comms.transmitterStatus === 'transmitting' ? 'ON' : 'OFF'}\n color={comms.transmitterStatus === 'transmitting' ? tokens.colors.status.normal : tokens.colors.status.off}\n />\n )}\n </>\n )}\n </div>\n </>\n );\n };\n\n // Compact mode with overlay expansion - prevents layout shift\n if (compact) {\n return (\n <article\n className={classNames('zendir-telemetry-card', 'compact', expanded ? 'expanded' : '', className)}\n {...handlers}\n aria-label={spacecraftName ? `${spacecraftName} Telemetry${expanded ? '' : ' (compact)'}` : 'Telemetry Data'}\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 ${tokens.colors.accent.primary}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 - resolve data with fallbacks like compact view\n (() => {\n const power = telemetry?.power ?? telemetry?.subsystems?.power;\n const attitude = telemetry?.attitude ?? telemetry?.subsystems?.attitude;\n const comms = telemetry?.communications ?? telemetry?.subsystems?.comms;\n return (\n <>\n {/* Header - consistent icon/status with compact view */}\n <header\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: tokens.spacing.md,\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm }}>\n {/* Icon with status badge - MonitoringIcon pattern */}\n <HeaderIconWithStatus \n icon=\"antenna-receive\" \n size={24} \n status={healthStatus}\n />\n <h3\n style={{\n margin: 0,\n fontSize: tokens.typography.fontSize.md,\n fontWeight: tokens.typography.fontWeight.semibold,\n }}\n >\n {spacecraftName ? `${spacecraftName} Telemetry` : 'Telemetry'}\n </h3>\n {isPinned && (\n <Icon name=\"lock\" size={12} color={tokens.colors.accent.primary} style={{ marginLeft: 4 }} />\n )}\n </div>\n <StatusIndicator status={healthStatus} label={healthStatus} small />\n </header>\n\n {/* Power Section - fixed icon column so all icons align vertically */}\n {showPower && (\n <section style={sectionStyle} aria-label=\"Power subsystem\">\n <div style={{ display: 'grid', gridTemplateColumns: sectionGridColumns, gap: `${rowGap} ${iconGap}`, alignItems: 'center' }}>\n <AstroIcon name=\"propulsion-power\" size={12} color={tokens.colors.text.tertiary} />\n <h4 style={{ margin: 0, gridColumn: '2 / -1', fontSize: tokens.typography.fontSize.xs, fontWeight: tokens.typography.fontWeight.medium, color: tokens.colors.text.secondary }}>\n Power\n </h4>\n <AstroIcon name={getPropertyConfig('battery').icon} size={16} color={getStatusColor(batteryStatus)} />\n <DataValue property=\"battery\" value={power?.batteryLevel} size=\"sm\" variant=\"card\" showIcon={false} />\n <AstroIcon name={getPropertyConfig('voltage').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"voltage\" value={power?.voltage} size=\"sm\" variant=\"card\" showIcon={false} />\n <AstroIcon name={getPropertyConfig('solarPower').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"solarPower\" value={power?.solarGeneration ?? power?.solarArrayOutput} size=\"sm\" variant=\"card\" status=\"standby\" showIcon={false} />\n <AstroIcon name={getPropertyConfig('load').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"load\" value={power?.consumption} size=\"sm\" variant=\"card\" showIcon={false} />\n </div>\n\n {/* Battery progress bar */}\n <div\n style={{\n marginTop: tokens.spacing.sm,\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={power?.batteryLevel ?? 0}\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, power?.batteryLevel ?? 0))}%`,\n backgroundColor: getStatusColor(batteryStatus),\n borderRadius: 2,\n transition: `width ${transitionDuration} ease-out`,\n }}\n />\n </div>\n </section>\n )}\n\n {/* Attitude Section - fixed icon column so all icons align vertically */}\n {showAttitude && (\n <section style={sectionStyle} aria-label=\"Attitude subsystem\">\n <div style={{ display: 'grid', gridTemplateColumns: sectionGridColumns, gap: `${rowGap} ${iconGap}`, alignItems: 'center' }}>\n <AstroIcon name=\"explore\" size={12} color={tokens.colors.text.tertiary} />\n <h4 style={{ margin: 0, gridColumn: '2 / -1', fontSize: tokens.typography.fontSize.xs, fontWeight: tokens.typography.fontWeight.medium, color: tokens.colors.text.secondary }}>\n Attitude\n </h4>\n <AstroIcon name={getPropertyConfig('roll').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"roll\" value={attitude?.eulerAngles?.roll ?? attitude?.pointingError} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name={getPropertyConfig('pitch').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"pitch\" value={attitude?.eulerAngles?.pitch} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name={getPropertyConfig('yaw').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"yaw\" value={attitude?.eulerAngles?.yaw} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name=\"explore\" size={16} color={tokens.colors.text.tertiary} />\n <DataValue label=\"Mode\" icon=\"explore\" value={attitude?.targetMode ?? '--'} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n </div>\n </section>\n )}\n\n {/* Communications Section - fixed icon column so all icons align vertically */}\n {showComms && (\n <section style={{ marginBottom: tokens.spacing.sm }} aria-label=\"Communications subsystem\">\n <div style={{ display: 'grid', gridTemplateColumns: sectionGridColumns, gap: `${rowGap} ${iconGap}`, alignItems: 'center' }}>\n <AstroIcon name=\"antenna\" size={12} color={tokens.colors.text.tertiary} />\n <h4 style={{ margin: 0, gridColumn: '2 / -1', fontSize: tokens.typography.fontSize.xs, fontWeight: tokens.typography.fontWeight.medium, color: tokens.colors.text.secondary }}>\n Communications\n </h4>\n <AstroIcon name=\"antenna-transmit\" size={16} color={tokens.colors.text.tertiary} />\n <DataValue label=\"Status\" icon=\"antenna-transmit\" value={comms?.transmitterStatus ?? comms?.status ?? '--'} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name={getPropertyConfig('signalStrength').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"signalStrength\" value={comms?.signalStrength} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name=\"antenna-receive\" size={16} color={tokens.colors.text.tertiary} />\n <DataValue label=\"Transmitted\" icon=\"antenna-receive\" value={comms?.packetsTransmitted ?? comms?.dataRate ?? '--'} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <span style={{ gridColumn: '4 / -1' }} />\n </div>\n </section>\n )}\n\n {/* Timestamp */}\n {telemetry?.timestamp && (\n <time\n dateTime={telemetry.timestamp}\n style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.tertiary,\n marginTop: tokens.spacing.sm,\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {formatTime(telemetry.timestamp)}\n </time>\n )}\n </>\n );\n })()\n ) : (\n // Compact content\n renderCompactContent()\n )}\n </article>\n );\n }\n\n return (\n <article\n className={classNames('zendir-telemetry-card', compact ? 'expanded' : '', className)}\n {...(compact ? handlers : {})}\n role={compact ? handlers.role : 'article'}\n tabIndex={compact ? handlers.tabIndex : undefined}\n aria-expanded={compact ? handlers['aria-expanded'] : undefined}\n aria-label={spacecraftName ? `${spacecraftName} Telemetry` : 'Telemetry Data'}\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 fontSize: tokens.typography.fontSize.sm,\n cursor: compact ? 'pointer' : undefined,\n transition: compact ? `all ${compactTransition} ease-out` : undefined,\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=\"antenna-receive\"\n title={spacecraftName ? `${spacecraftName} Telemetry` : 'Telemetry'}\n status={healthStatus}\n isPinned={compact && isPinned}\n />\n\n {/* Power Section - fixed icon column so all icons align vertically */}\n {showPower && (\n <section style={sectionStyle} aria-label=\"Power subsystem\">\n <div style={{ display: 'grid', gridTemplateColumns: sectionGridColumns, gap: `${rowGap} ${iconGap}`, alignItems: 'center' }}>\n <AstroIcon name=\"propulsion-power\" size={12} color={tokens.colors.text.tertiary} />\n <h4 style={{ margin: 0, gridColumn: '2 / -1', fontSize: tokens.typography.fontSize.xs, fontWeight: tokens.typography.fontWeight.medium, color: tokens.colors.text.secondary }}>\n Power\n </h4>\n <AstroIcon name={getPropertyConfig('battery').icon} size={16} color={getStatusColor(batteryStatus)} />\n <DataValue property=\"battery\" value={telemetry.power?.batteryLevel} size=\"sm\" variant=\"card\" showIcon={false} />\n <AstroIcon name={getPropertyConfig('voltage').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"voltage\" value={telemetry.power?.voltage} size=\"sm\" variant=\"card\" showIcon={false} />\n <AstroIcon name={getPropertyConfig('solarPower').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"solarPower\" value={telemetry.power?.solarGeneration} size=\"sm\" variant=\"card\" status=\"standby\" showIcon={false} />\n <AstroIcon name={getPropertyConfig('load').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"load\" value={telemetry.power?.consumption} size=\"sm\" variant=\"card\" showIcon={false} />\n </div>\n\n {/* Battery progress bar */}\n <div\n style={{\n marginTop: tokens.spacing.sm,\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 ?? 0}\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 ?? 0))}%`,\n backgroundColor: getStatusColor(batteryStatus),\n borderRadius: 2,\n transition: `width ${transitionDuration} ease-out`,\n }}\n />\n </div>\n </section>\n )}\n\n {/* Attitude Section - fixed icon column so all icons align vertically */}\n {showAttitude && (\n <section style={sectionStyle} aria-label=\"Attitude subsystem\">\n <div style={{ display: 'grid', gridTemplateColumns: sectionGridColumns, gap: `${rowGap} ${iconGap}`, alignItems: 'center' }}>\n <AstroIcon name=\"explore\" size={12} color={tokens.colors.text.tertiary} />\n <h4 style={{ margin: 0, gridColumn: '2 / -1', fontSize: tokens.typography.fontSize.xs, fontWeight: tokens.typography.fontWeight.medium, color: tokens.colors.text.secondary }}>\n Attitude\n </h4>\n <AstroIcon name={getPropertyConfig('roll').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"roll\" value={telemetry.attitude?.eulerAngles?.roll} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name={getPropertyConfig('pitch').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"pitch\" value={telemetry.attitude?.eulerAngles?.pitch} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name={getPropertyConfig('yaw').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"yaw\" value={telemetry.attitude?.eulerAngles?.yaw} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n <AstroIcon name=\"explore\" size={16} color={tokens.colors.text.tertiary} />\n <DataValue label=\"Mode\" icon=\"explore\" value={telemetry.attitude?.targetMode ?? '--'} size=\"sm\" variant=\"card\" showStatus={false} showIcon={false} />\n </div>\n {telemetry.attitude?.pointingError !== undefined && (\n <div style={{ display: 'flex', alignItems: 'center', gap: iconGap, marginTop: tokens.spacing.sm }}>\n <AstroIcon name={getPropertyConfig('pointingError').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"pointingError\" value={telemetry.attitude.pointingError} size=\"sm\" variant=\"inline\" showIcon={false} />\n </div>\n )}\n </section>\n )}\n\n {/* Communications Section - fixed icon column so all icons align vertically */}\n {showComms && (\n <section style={{ marginBottom: tokens.spacing.md }} aria-label=\"Communications subsystem\">\n <div style={{ display: 'grid', gridTemplateColumns: sectionGridColumns, gap: `${rowGap} ${iconGap}`, alignItems: 'center' }}>\n <AstroIcon name=\"antenna\" size={12} color={tokens.colors.text.tertiary} />\n <h4 style={{ margin: 0, gridColumn: '2 / -1', fontSize: tokens.typography.fontSize.xs, fontWeight: tokens.typography.fontWeight.medium, color: tokens.colors.text.secondary }}>\n Communications\n </h4>\n <AstroIcon name=\"antenna-transmit\" size={16} color={tokens.colors.text.tertiary} />\n <DataValue\n label=\"Status\"\n icon=\"antenna-transmit\"\n value={telemetry.communications?.transmitterStatus ?? '--'}\n size=\"sm\"\n variant=\"card\"\n showIcon={false}\n status={\n telemetry.communications?.transmitterStatus === 'transmitting'\n ? 'normal'\n : telemetry.communications?.transmitterStatus === 'error'\n ? 'critical'\n : 'off'\n }\n />\n <AstroIcon name={getPropertyConfig('queue').icon} size={16} color={tokens.colors.text.tertiary} />\n <DataValue property=\"queue\" value={telemetry.communications?.packetsQueued} size=\"sm\" variant=\"card\" showIcon={false} />\n <AstroIcon name=\"antenna-receive\" size={16} color={tokens.colors.text.tertiary} />\n <DataValue\n label=\"Transmitted\"\n icon=\"antenna-receive\"\n value={safeNumber((telemetry.communications?.bytesTransmitted ?? 0) / 1024, 1)}\n unit=\"KB\"\n size=\"sm\"\n variant=\"card\"\n showStatus={false}\n showIcon={false}\n />\n <span style={{ gridColumn: '4 / -1' }} />\n </div>\n </section>\n )}\n\n {/* Anomalies Alert */}\n {telemetry.health?.anomalies && telemetry.health.anomalies.length > 0 && (\n <div\n role=\"alert\"\n style={{\n backgroundColor: `${tokens.colors.status.critical}15`,\n border: `1px solid ${tokens.colors.status.critical}40`,\n borderRadius: tokens.borderRadius.md,\n padding: tokens.spacing.sm,\n marginTop: tokens.spacing.md,\n }}\n >\n <h4\n style={{\n margin: `0 0 ${tokens.spacing.xs} 0`,\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n color: tokens.colors.status.critical,\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n }}\n >\n ⚠️ Anomalies ({telemetry.health.anomalies.length})\n </h4>\n <ul style={{ margin: 0, paddingLeft: 16 }}>\n {telemetry.health.anomalies.map((anomaly: { id: string; message: string; severity?: string }, idx: number) => (\n <li\n key={idx}\n style={{\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.status.critical,\n marginTop: 2,\n }}\n >\n {typeof anomaly === 'object' && anomaly !== null && 'message' in anomaly ? anomaly.message : String(anomaly)}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {/* Timestamp Footer */}\n <footer\n style={{\n marginTop: tokens.spacing.md,\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary, // WCAG AA compliant - 4.5:1 contrast\n textAlign: 'right',\n }}\n >\n <time dateTime={telemetry.timestamp}>{formatTime(telemetry.timestamp)} UTC</time>\n </footer>\n </article>\n );\n});\n\n// Note: DataCell is deprecated in favor of DataValue from core.\n// Use <DataValue property=\"...\" value={...} /> for automatic icon/status integration.\n"],"names":["TelemetryCard","_a","_b","_c","_d","_e","_f"],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { StatusLevel } from '../utils';
|
|
3
|
+
|
|
4
|
+
export interface TelemetryMetric {
|
|
5
|
+
/** Unique identifier */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Display label */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Current value */
|
|
10
|
+
value: number | string;
|
|
11
|
+
/** Unit suffix */
|
|
12
|
+
unit?: string;
|
|
13
|
+
/** Status level for color coding */
|
|
14
|
+
status?: StatusLevel;
|
|
15
|
+
/** Format function for value display */
|
|
16
|
+
format?: (value: number) => string;
|
|
17
|
+
}
|
|
18
|
+
export interface TelemetryStreamCardProps {
|
|
19
|
+
/** Card title */
|
|
20
|
+
title?: string;
|
|
21
|
+
/** Number of channels */
|
|
22
|
+
channelCount?: number;
|
|
23
|
+
/** Update frequency (Hz) */
|
|
24
|
+
frequency?: number;
|
|
25
|
+
/** Streaming status */
|
|
26
|
+
isStreaming?: boolean;
|
|
27
|
+
/** Metric channels to display */
|
|
28
|
+
metrics?: TelemetryMetric[];
|
|
29
|
+
/** Loading state */
|
|
30
|
+
loading?: boolean;
|
|
31
|
+
/** Custom className */
|
|
32
|
+
className?: string;
|
|
33
|
+
/** Enable compact mode - shows condensed view that expands on hover/click */
|
|
34
|
+
compact?: boolean;
|
|
35
|
+
/** Start expanded when in compact mode (pinned state) */
|
|
36
|
+
defaultExpanded?: boolean;
|
|
37
|
+
/** Callback when pin state changes in compact mode */
|
|
38
|
+
onPinChange?: (isPinned: boolean) => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* TelemetryStreamCard - Compact streaming telemetry display
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <TelemetryStreamCard
|
|
46
|
+
* title="Telemetry"
|
|
47
|
+
* channelCount={12}
|
|
48
|
+
* frequency={1}
|
|
49
|
+
* isStreaming={true}
|
|
50
|
+
* metrics={[
|
|
51
|
+
* { id: 'cpu', label: 'CPU Temp', value: 42, unit: '°C', status: 'normal' },
|
|
52
|
+
* { id: 'voltage', label: 'Bus Voltage', value: 28.4, unit: 'V' },
|
|
53
|
+
* { id: 'wheel', label: 'Wheel Speed', value: 2450, unit: 'rpm' },
|
|
54
|
+
* { id: 'memory', label: 'Memory', value: 78, unit: '%', status: 'caution' },
|
|
55
|
+
* ]}
|
|
56
|
+
* />
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare const TelemetryStreamCard: React.NamedExoticComponent<TelemetryStreamCardProps>;
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useMemo } from "react";
|
|
3
|
+
import { Icon } from "../core/Icon.js";
|
|
4
|
+
import { CardHeader } from "../core/CardHeader.js";
|
|
5
|
+
import { classNames } from "../utils/index.js";
|
|
6
|
+
import { useTheme } from "../theme/ThemeProvider.js";
|
|
7
|
+
import { useCompactMode } from "../hooks/useCompactMode.js";
|
|
8
|
+
function getMetricColor(status, tokens) {
|
|
9
|
+
if (!status || status === "normal") return tokens.colors.status.normal;
|
|
10
|
+
if (status === "caution") return tokens.colors.status.caution;
|
|
11
|
+
if (status === "critical") return tokens.colors.status.critical;
|
|
12
|
+
if (status === "standby") return tokens.colors.status.standby;
|
|
13
|
+
return tokens.colors.text.primary;
|
|
14
|
+
}
|
|
15
|
+
const TelemetryStreamCard = memo(function TelemetryStreamCard2({
|
|
16
|
+
title = "Telemetry",
|
|
17
|
+
channelCount = 12,
|
|
18
|
+
frequency = 1,
|
|
19
|
+
isStreaming = true,
|
|
20
|
+
metrics = [],
|
|
21
|
+
loading = false,
|
|
22
|
+
className = "",
|
|
23
|
+
compact = false,
|
|
24
|
+
defaultExpanded = false,
|
|
25
|
+
onPinChange
|
|
26
|
+
}) {
|
|
27
|
+
const { tokens, theme, prefersReducedMotion } = useTheme();
|
|
28
|
+
const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
|
|
29
|
+
const isBoldVariant = theme === "transparent-bold";
|
|
30
|
+
const isMinimalVariant = theme === "transparent-minimal";
|
|
31
|
+
const useGlassMode = isBoldVariant || isMinimalVariant;
|
|
32
|
+
const glassAccentColor = tokens.colors.accent.primary;
|
|
33
|
+
const glassAccentMuted = `${glassAccentColor}66`;
|
|
34
|
+
const { expanded, isPinned, handlers, transitionDuration } = useCompactMode({
|
|
35
|
+
compact,
|
|
36
|
+
defaultExpanded,
|
|
37
|
+
onPinChange
|
|
38
|
+
});
|
|
39
|
+
const glassContainerStyle = useGlassMode ? {
|
|
40
|
+
backgroundColor: "rgba(10, 15, 25, 0.35)",
|
|
41
|
+
backdropFilter: "blur(12px)",
|
|
42
|
+
WebkitBackdropFilter: "blur(12px)",
|
|
43
|
+
border: `1px solid ${glassAccentMuted}`,
|
|
44
|
+
borderTop: isBoldVariant ? `2px solid ${glassAccentColor}` : `1px solid ${glassAccentColor}`
|
|
45
|
+
} : {};
|
|
46
|
+
const cardStyle = useMemo(() => ({
|
|
47
|
+
position: "relative",
|
|
48
|
+
overflow: "hidden",
|
|
49
|
+
...useGlassMode ? glassContainerStyle : {
|
|
50
|
+
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.surface,
|
|
51
|
+
...isTransparentTheme && {
|
|
52
|
+
backdropFilter: "blur(12px)",
|
|
53
|
+
WebkitBackdropFilter: "blur(12px)"
|
|
54
|
+
},
|
|
55
|
+
...tokens.colors.border.cardStyleDefault ?? { border: `1px solid ${tokens.colors.border.default}` }
|
|
56
|
+
},
|
|
57
|
+
borderRadius: tokens.borderRadius.lg,
|
|
58
|
+
padding: tokens.spacing.md
|
|
59
|
+
}), [tokens, isTransparentTheme, useGlassMode, glassContainerStyle]);
|
|
60
|
+
const metricBoxStyle = useMemo(() => ({
|
|
61
|
+
backgroundColor: tokens.colors.background.elevated,
|
|
62
|
+
borderRadius: tokens.borderRadius.md,
|
|
63
|
+
padding: tokens.spacing.sm
|
|
64
|
+
}), [tokens]);
|
|
65
|
+
if (loading) {
|
|
66
|
+
return /* @__PURE__ */ jsxs(
|
|
67
|
+
"article",
|
|
68
|
+
{
|
|
69
|
+
className: classNames("zendir-telemetry-stream-card", className),
|
|
70
|
+
style: cardStyle,
|
|
71
|
+
"aria-busy": "true",
|
|
72
|
+
"aria-label": "Loading telemetry stream",
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 16 }, children: [
|
|
75
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
76
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
77
|
+
height: 16,
|
|
78
|
+
width: 80,
|
|
79
|
+
backgroundColor: tokens.colors.background.elevated,
|
|
80
|
+
borderRadius: 4,
|
|
81
|
+
marginBottom: 4
|
|
82
|
+
} }),
|
|
83
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
84
|
+
height: 12,
|
|
85
|
+
width: 100,
|
|
86
|
+
backgroundColor: tokens.colors.background.elevated,
|
|
87
|
+
borderRadius: 4
|
|
88
|
+
} })
|
|
89
|
+
] }),
|
|
90
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
91
|
+
height: 24,
|
|
92
|
+
width: 70,
|
|
93
|
+
backgroundColor: tokens.colors.background.elevated,
|
|
94
|
+
borderRadius: 12
|
|
95
|
+
} })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(2, 1fr)", gap: 12 }, children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsxs("div", { style: metricBoxStyle, children: [
|
|
98
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
99
|
+
height: 10,
|
|
100
|
+
width: 60,
|
|
101
|
+
backgroundColor: tokens.colors.background.base,
|
|
102
|
+
borderRadius: 4,
|
|
103
|
+
marginBottom: 8
|
|
104
|
+
} }),
|
|
105
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
106
|
+
height: 20,
|
|
107
|
+
width: 80,
|
|
108
|
+
backgroundColor: tokens.colors.background.base,
|
|
109
|
+
borderRadius: 4
|
|
110
|
+
} })
|
|
111
|
+
] }, i)) })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (compact && !expanded) {
|
|
117
|
+
return /* @__PURE__ */ jsxs(
|
|
118
|
+
"article",
|
|
119
|
+
{
|
|
120
|
+
className: classNames("zendir-telemetry-stream-card", "compact", className),
|
|
121
|
+
...handlers,
|
|
122
|
+
style: {
|
|
123
|
+
...cardStyle,
|
|
124
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
|
|
125
|
+
cursor: "pointer",
|
|
126
|
+
transition: `all ${transitionDuration} ease-out`
|
|
127
|
+
},
|
|
128
|
+
onMouseEnter: (e) => {
|
|
129
|
+
handlers.onMouseEnter();
|
|
130
|
+
if (!prefersReducedMotion) {
|
|
131
|
+
e.currentTarget.style.transform = "scale(1.01)";
|
|
132
|
+
e.currentTarget.style.boxShadow = `0 4px 12px ${tokens.colors.accent.primary}20`;
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
onMouseLeave: (e) => {
|
|
136
|
+
handlers.onMouseLeave();
|
|
137
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
138
|
+
e.currentTarget.style.boxShadow = "";
|
|
139
|
+
},
|
|
140
|
+
"aria-label": `${title} (compact)`,
|
|
141
|
+
children: [
|
|
142
|
+
useGlassMode && /* @__PURE__ */ jsx(
|
|
143
|
+
"div",
|
|
144
|
+
{
|
|
145
|
+
style: {
|
|
146
|
+
position: "absolute",
|
|
147
|
+
inset: 0,
|
|
148
|
+
background: "linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.1) 100%)",
|
|
149
|
+
pointerEvents: "none",
|
|
150
|
+
zIndex: 0
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: tokens.spacing.md, position: "relative", zIndex: 1 }, children: [
|
|
155
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm, flex: 1, minWidth: 0 }, children: [
|
|
156
|
+
/* @__PURE__ */ jsx(
|
|
157
|
+
"div",
|
|
158
|
+
{
|
|
159
|
+
style: {
|
|
160
|
+
width: 8,
|
|
161
|
+
height: 8,
|
|
162
|
+
borderRadius: "50%",
|
|
163
|
+
backgroundColor: isStreaming ? tokens.colors.status.normal : tokens.colors.status.off,
|
|
164
|
+
boxShadow: isStreaming ? `0 0 6px ${tokens.colors.status.normal}` : "none",
|
|
165
|
+
flexShrink: 0
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
170
|
+
fontWeight: tokens.typography.fontWeight.medium,
|
|
171
|
+
color: useGlassMode ? glassAccentColor : void 0,
|
|
172
|
+
textShadow: useGlassMode ? `0 0 16px ${glassAccentMuted}` : void 0
|
|
173
|
+
}, children: title.split(" ")[0] }),
|
|
174
|
+
useGlassMode && /* @__PURE__ */ jsx("div", { style: {
|
|
175
|
+
flex: 1,
|
|
176
|
+
height: isBoldVariant ? "2px" : "1px",
|
|
177
|
+
minWidth: 20,
|
|
178
|
+
background: `linear-gradient(90deg, ${glassAccentColor} 0%, ${glassAccentMuted} 60%, transparent 100%)`,
|
|
179
|
+
boxShadow: isBoldVariant ? `0 0 8px ${glassAccentMuted}` : void 0
|
|
180
|
+
} })
|
|
181
|
+
] }),
|
|
182
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm, flexShrink: 0 }, children: [
|
|
183
|
+
/* @__PURE__ */ jsxs("span", { style: {
|
|
184
|
+
color: tokens.colors.text.tertiary,
|
|
185
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
186
|
+
backgroundColor: useGlassMode ? `${glassAccentColor}20` : void 0,
|
|
187
|
+
padding: useGlassMode ? "1px 6px" : void 0,
|
|
188
|
+
borderRadius: tokens.borderRadius.sm
|
|
189
|
+
}, children: [
|
|
190
|
+
channelCount,
|
|
191
|
+
"ch"
|
|
192
|
+
] }),
|
|
193
|
+
metrics.slice(0, 2).map((metric) => /* @__PURE__ */ jsxs(
|
|
194
|
+
"span",
|
|
195
|
+
{
|
|
196
|
+
style: {
|
|
197
|
+
fontVariantNumeric: "tabular-nums",
|
|
198
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
199
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
200
|
+
color: getMetricColor(metric.status, tokens)
|
|
201
|
+
},
|
|
202
|
+
children: [
|
|
203
|
+
metric.value,
|
|
204
|
+
metric.unit ? metric.unit : ""
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
metric.id
|
|
208
|
+
)),
|
|
209
|
+
isPinned && /* @__PURE__ */ jsx(Icon, { name: "lock", size: 12, color: tokens.colors.accent.primary })
|
|
210
|
+
] })
|
|
211
|
+
] })
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
return /* @__PURE__ */ jsxs(
|
|
217
|
+
"article",
|
|
218
|
+
{
|
|
219
|
+
className: classNames("zendir-telemetry-stream-card", compact ? "expanded" : "", className),
|
|
220
|
+
...compact ? handlers : {},
|
|
221
|
+
role: compact ? handlers.role : "article",
|
|
222
|
+
tabIndex: compact ? handlers.tabIndex : void 0,
|
|
223
|
+
"aria-expanded": compact ? handlers["aria-expanded"] : void 0,
|
|
224
|
+
style: {
|
|
225
|
+
...cardStyle,
|
|
226
|
+
cursor: compact ? "pointer" : void 0,
|
|
227
|
+
transition: compact ? `all ${transitionDuration} ease-out` : void 0
|
|
228
|
+
},
|
|
229
|
+
"aria-label": `${title} - ${isStreaming ? "Streaming" : "Paused"}`,
|
|
230
|
+
"aria-live": "polite",
|
|
231
|
+
children: [
|
|
232
|
+
useGlassMode && /* @__PURE__ */ jsx(
|
|
233
|
+
"div",
|
|
234
|
+
{
|
|
235
|
+
style: {
|
|
236
|
+
position: "absolute",
|
|
237
|
+
inset: 0,
|
|
238
|
+
background: "linear-gradient(135deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.1) 100%)",
|
|
239
|
+
pointerEvents: "none",
|
|
240
|
+
zIndex: 0
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
),
|
|
244
|
+
/* @__PURE__ */ jsx(
|
|
245
|
+
CardHeader,
|
|
246
|
+
{
|
|
247
|
+
icon: "antenna-receive",
|
|
248
|
+
title,
|
|
249
|
+
subtitle: `${channelCount} channels • ${frequency} Hz`,
|
|
250
|
+
status: isStreaming ? "normal" : "standby",
|
|
251
|
+
badge: isStreaming ? "Streaming" : "Paused",
|
|
252
|
+
badgeColor: isStreaming ? tokens.colors.status.normal : tokens.colors.status.standby
|
|
253
|
+
}
|
|
254
|
+
),
|
|
255
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
256
|
+
display: "grid",
|
|
257
|
+
gridTemplateColumns: "repeat(2, 1fr)",
|
|
258
|
+
gap: 12
|
|
259
|
+
}, children: metrics.map((metric) => /* @__PURE__ */ jsxs(
|
|
260
|
+
"div",
|
|
261
|
+
{
|
|
262
|
+
style: metricBoxStyle,
|
|
263
|
+
role: "group",
|
|
264
|
+
"aria-label": `${metric.label}: ${metric.value}${metric.unit || ""}`,
|
|
265
|
+
children: [
|
|
266
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
267
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
268
|
+
// 0.625rem / 10px (AstroUXDS compact)
|
|
269
|
+
fontWeight: tokens.typography.fontWeight.medium,
|
|
270
|
+
// 500 (AstroUXDS medium)
|
|
271
|
+
textTransform: "uppercase",
|
|
272
|
+
letterSpacing: "0.05em",
|
|
273
|
+
color: tokens.colors.text.tertiary,
|
|
274
|
+
marginBottom: 4
|
|
275
|
+
}, children: metric.label }),
|
|
276
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
277
|
+
fontSize: tokens.typography.fontSize.lg,
|
|
278
|
+
fontWeight: tokens.typography.fontWeight.bold,
|
|
279
|
+
// 700 (AstroUXDS bold)
|
|
280
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
281
|
+
fontVariantNumeric: "tabular-nums",
|
|
282
|
+
color: getMetricColor(metric.status, tokens)
|
|
283
|
+
}, children: [
|
|
284
|
+
typeof metric.value === "number" ? metric.format ? metric.format(metric.value) : metric.value.toLocaleString() : metric.value,
|
|
285
|
+
metric.unit && /* @__PURE__ */ jsx("span", { style: {
|
|
286
|
+
fontSize: tokens.typography.fontSize.sm,
|
|
287
|
+
fontWeight: tokens.typography.fontWeight.normal,
|
|
288
|
+
// 400 (AstroUXDS normal)
|
|
289
|
+
marginLeft: 2
|
|
290
|
+
}, children: metric.unit })
|
|
291
|
+
] })
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
metric.id
|
|
295
|
+
)) }),
|
|
296
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
297
|
+
@keyframes pulse {
|
|
298
|
+
0%, 100% { opacity: 1; }
|
|
299
|
+
50% { opacity: 0.5; }
|
|
300
|
+
}
|
|
301
|
+
` })
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
export {
|
|
307
|
+
TelemetryStreamCard
|
|
308
|
+
};
|
|
309
|
+
//# sourceMappingURL=TelemetryStreamCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TelemetryStreamCard.js","sources":["../../../src/react/cards/TelemetryStreamCard.tsx"],"sourcesContent":["/**\n * @zendir/ui - TelemetryStreamCard Component\n * \n * Compact streaming telemetry card showing individual metric channels.\n * Designed for real-time data display with configurable metrics.\n * \n * Features:\n * - Configurable metric channels\n * - Streaming status indicator\n * - Color-coded values based on thresholds\n * - WCAG 2.1 AA accessibility\n */\n\nimport React, { memo, useMemo } from 'react';\nimport { useTheme } from '../theme';\nimport { Icon } from '../core/Icon';\nimport { CardHeader } from '../core/CardHeader';\nimport { useCompactMode } from '../hooks';\nimport { classNames, type StatusLevel } from '../utils';\n\nexport interface TelemetryMetric {\n /** Unique identifier */\n id: string;\n /** Display label */\n label: string;\n /** Current value */\n value: number | string;\n /** Unit suffix */\n unit?: string;\n /** Status level for color coding */\n status?: StatusLevel;\n /** Format function for value display */\n format?: (value: number) => string;\n}\n\nexport interface TelemetryStreamCardProps {\n /** Card title */\n title?: string;\n /** Number of channels */\n channelCount?: number;\n /** Update frequency (Hz) */\n frequency?: number;\n /** Streaming status */\n isStreaming?: boolean;\n /** Metric channels to display */\n metrics?: TelemetryMetric[];\n /** Loading state */\n loading?: boolean;\n /** Custom className */\n className?: 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 status color for a metric value\n */\nfunction getMetricColor(status: StatusLevel | undefined, tokens: any): string {\n if (!status || status === 'normal') return tokens.colors.status.normal;\n if (status === 'caution') return tokens.colors.status.caution;\n if (status === 'critical') return tokens.colors.status.critical;\n if (status === 'standby') return tokens.colors.status.standby;\n return tokens.colors.text.primary;\n}\n\n/**\n * TelemetryStreamCard - Compact streaming telemetry display\n * \n * @example\n * ```tsx\n * <TelemetryStreamCard\n * title=\"Telemetry\"\n * channelCount={12}\n * frequency={1}\n * isStreaming={true}\n * metrics={[\n * { id: 'cpu', label: 'CPU Temp', value: 42, unit: '°C', status: 'normal' },\n * { id: 'voltage', label: 'Bus Voltage', value: 28.4, unit: 'V' },\n * { id: 'wheel', label: 'Wheel Speed', value: 2450, unit: 'rpm' },\n * { id: 'memory', label: 'Memory', value: 78, unit: '%', status: 'caution' },\n * ]}\n * />\n * ```\n */\nexport const TelemetryStreamCard = memo(function TelemetryStreamCard({\n title = 'Telemetry',\n channelCount = 12,\n frequency = 1,\n isStreaming = true,\n metrics = [],\n loading = false,\n className = '',\n compact = false,\n defaultExpanded = false,\n onPinChange,\n}: TelemetryStreamCardProps): 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 // Compact mode state management\n const { expanded, isPinned, handlers, transitionDuration } = useCompactMode({\n compact,\n defaultExpanded,\n onPinChange,\n });\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 // Card styles - Use transparent background with blur for transparent themes (matching Timeline)\n const cardStyle = useMemo(() => ({\n position: 'relative' as const,\n overflow: 'hidden' as const,\n ...(useGlassMode ? glassContainerStyle : {\n backgroundColor: isTransparentTheme ? 'transparent' : tokens.colors.background.surface,\n ...(isTransparentTheme && { \n backdropFilter: 'blur(12px)' as const, \n WebkitBackdropFilter: 'blur(12px)' as const,\n }),\n ...(tokens.colors.border.cardStyleDefault ?? { border: `1px solid ${tokens.colors.border.default}` }),\n }),\n borderRadius: tokens.borderRadius.lg,\n padding: tokens.spacing.md,\n }), [tokens, isTransparentTheme, useGlassMode, glassContainerStyle]);\n\n // Metric box styles\n const metricBoxStyle = useMemo(() => ({\n backgroundColor: tokens.colors.background.elevated,\n borderRadius: tokens.borderRadius.md,\n padding: tokens.spacing.sm,\n }), [tokens]);\n\n // Loading state\n if (loading) {\n return (\n <article\n className={classNames('zendir-telemetry-stream-card', className)}\n style={cardStyle}\n aria-busy=\"true\"\n aria-label=\"Loading telemetry stream\"\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>\n <div>\n <div style={{\n height: 16,\n width: 80,\n backgroundColor: tokens.colors.background.elevated,\n borderRadius: 4,\n marginBottom: 4,\n }} />\n <div style={{\n height: 12,\n width: 100,\n backgroundColor: tokens.colors.background.elevated,\n borderRadius: 4,\n }} />\n </div>\n <div style={{\n height: 24,\n width: 70,\n backgroundColor: tokens.colors.background.elevated,\n borderRadius: 12,\n }} />\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12 }}>\n {[1, 2, 3, 4].map((i) => (\n <div key={i} style={metricBoxStyle}>\n <div style={{\n height: 10,\n width: 60,\n backgroundColor: tokens.colors.background.base,\n borderRadius: 4,\n marginBottom: 8,\n }} />\n <div style={{\n height: 20,\n width: 80,\n backgroundColor: tokens.colors.background.base,\n borderRadius: 4,\n }} />\n </div>\n ))}\n </div>\n </article>\n );\n }\n\n // Compact view - shows streaming status and first few metrics\n if (compact && !expanded) {\n return (\n <article\n className={classNames('zendir-telemetry-stream-card', 'compact', className)}\n {...handlers}\n style={{\n ...cardStyle,\n padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,\n cursor: 'pointer',\n transition: `all ${transitionDuration} ease-out`,\n }}\n onMouseEnter={(e) => {\n handlers.onMouseEnter();\n if (!prefersReducedMotion) {\n (e.currentTarget as HTMLElement).style.transform = 'scale(1.01)';\n (e.currentTarget as HTMLElement).style.boxShadow = `0 4px 12px ${tokens.colors.accent.primary}20`;\n }\n }}\n onMouseLeave={(e) => {\n handlers.onMouseLeave();\n (e.currentTarget as HTMLElement).style.transform = 'scale(1)';\n (e.currentTarget as HTMLElement).style.boxShadow = '';\n }}\n aria-label={`${title} (compact)`}\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 <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: tokens.spacing.md, position: 'relative', zIndex: 1 }}>\n {/* Left side: Status indicator + Title + Accent line */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm, flex: 1, minWidth: 0 }}>\n <div\n style={{\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: isStreaming ? tokens.colors.status.normal : tokens.colors.status.off,\n boxShadow: isStreaming ? `0 0 6px ${tokens.colors.status.normal}` : 'none',\n flexShrink: 0,\n }}\n />\n <span style={{ \n fontWeight: tokens.typography.fontWeight.medium,\n color: useGlassMode ? glassAccentColor : undefined,\n textShadow: useGlassMode ? `0 0 16px ${glassAccentMuted}` : undefined,\n }}>\n {title.split(' ')[0]}\n </span>\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: Channel count badge + Metrics + Pin */}\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm, flexShrink: 0 }}>\n <span style={{ \n color: tokens.colors.text.tertiary, \n fontSize: tokens.typography.fontSize.xs,\n backgroundColor: useGlassMode ? `${glassAccentColor}20` : undefined,\n padding: useGlassMode ? '1px 6px' : undefined,\n borderRadius: tokens.borderRadius.sm,\n }}>\n {channelCount}ch\n </span>\n {metrics.slice(0, 2).map(metric => (\n <span\n key={metric.id}\n style={{\n fontVariantNumeric: 'tabular-nums',\n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: tokens.typography.fontSize.xs,\n color: getMetricColor(metric.status, tokens),\n }}\n >\n {metric.value}{metric.unit ? metric.unit : ''}\n </span>\n ))}\n {isPinned && (\n <Icon name=\"lock\" size={12} color={tokens.colors.accent.primary} />\n )}\n </div>\n </div>\n </article>\n );\n }\n\n return (\n <article\n className={classNames('zendir-telemetry-stream-card', compact ? 'expanded' : '', className)}\n {...(compact ? handlers : {})}\n role={compact ? handlers.role : 'article'}\n tabIndex={compact ? handlers.tabIndex : undefined}\n aria-expanded={compact ? handlers['aria-expanded'] : undefined}\n style={{\n ...cardStyle,\n cursor: compact ? 'pointer' : undefined,\n transition: compact ? `all ${transitionDuration} ease-out` : undefined,\n }}\n aria-label={`${title} - ${isStreaming ? 'Streaming' : 'Paused'}`}\n aria-live=\"polite\"\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=\"antenna-receive\"\n title={title}\n subtitle={`${channelCount} channels • ${frequency} Hz`}\n status={isStreaming ? 'normal' : 'standby'}\n badge={isStreaming ? 'Streaming' : 'Paused'}\n badgeColor={isStreaming ? tokens.colors.status.normal : tokens.colors.status.standby}\n />\n\n {/* Metrics Grid */}\n <div style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(2, 1fr)',\n gap: 12,\n }}>\n {metrics.map((metric) => (\n <div\n key={metric.id}\n style={metricBoxStyle}\n role=\"group\"\n aria-label={`${metric.label}: ${metric.value}${metric.unit || ''}`}\n >\n <div style={{\n fontSize: tokens.typography.fontSize.xxs, // 0.625rem / 10px (AstroUXDS compact)\n fontWeight: tokens.typography.fontWeight.medium, // 500 (AstroUXDS medium)\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n color: tokens.colors.text.tertiary,\n marginBottom: 4,\n }}>\n {metric.label}\n </div>\n <div style={{\n fontSize: tokens.typography.fontSize.lg,\n fontWeight: tokens.typography.fontWeight.bold, // 700 (AstroUXDS bold)\n fontFamily: tokens.typography.fontFamily.mono,\n fontVariantNumeric: 'tabular-nums',\n color: getMetricColor(metric.status, tokens),\n }}>\n {typeof metric.value === 'number'\n ? metric.format\n ? metric.format(metric.value)\n : metric.value.toLocaleString()\n : metric.value}\n {metric.unit && (\n <span style={{\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.normal, // 400 (AstroUXDS normal)\n marginLeft: 2,\n }}>\n {metric.unit}\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n\n {/* Pulse animation */}\n <style>{`\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n `}</style>\n </article>\n );\n});\n"],"names":["TelemetryStreamCard"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zendir/ui - Card Components
|
|
3
|
+
*/
|
|
4
|
+
export { SpacecraftCard } from './SpacecraftCard';
|
|
5
|
+
export type { SpacecraftCardProps } from './SpacecraftCard';
|
|
6
|
+
export { TelemetryCard } from './TelemetryCard';
|
|
7
|
+
export type { TelemetryCardProps } from './TelemetryCard';
|
|
8
|
+
export { AccessCard } from './AccessCard';
|
|
9
|
+
export type { AccessCardProps } from './AccessCard';
|
|
10
|
+
export { OrbitCard } from './OrbitCard';
|
|
11
|
+
export type { OrbitCardProps } from './OrbitCard';
|
|
12
|
+
export { TelemetryStreamCard } from './TelemetryStreamCard';
|
|
13
|
+
export type { TelemetryStreamCardProps, TelemetryMetric } from './TelemetryStreamCard';
|