@zendir/ui 0.2.20 → 0.3.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 +192 -1
- package/README.md +70 -28
- package/dist/index.d.ts +1 -1
- package/dist/index.js +57 -41
- package/dist/index.js.map +1 -1
- package/dist/react/3d/CesiumCaptureSource.d.ts +119 -0
- package/dist/react/3d/CesiumCaptureSource.js +307 -0
- package/dist/react/3d/CesiumCaptureSource.js.map +1 -0
- package/dist/react/3d/ZenSpace3D.js +1253 -0
- package/dist/react/3d/ZenSpace3D.js.map +1 -0
- package/dist/react/3d/ZenSpace3DCesium.js +579 -0
- package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
- package/dist/react/3d/ZenSpace3DTypes.d.ts +28 -1
- package/dist/react/3d/ZenSpace3DUtils.d.ts +17 -173
- package/dist/react/3d/ZenSpace3DUtils.js +28 -0
- package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
- package/dist/react/3d/capturePngAnalysis.d.ts +16 -0
- package/dist/react/3d/index.d.ts +10 -12
- package/dist/react/3d/threeLoader.js +18 -0
- package/dist/react/3d/threeLoader.js.map +1 -0
- package/dist/react/astro/MonitoringIcon.js +1 -1
- package/dist/react/astro/MonitoringIcon.js.map +1 -1
- package/dist/react/astro/SimulationControls.js +2 -2
- package/dist/react/astro/SimulationControls.js.map +1 -1
- package/dist/react/astro/UnifiedTimeline.js +4 -4
- package/dist/react/astro/UnifiedTimeline.js.map +1 -1
- package/dist/react/charts/GroundTrackMap.d.ts +2 -15
- package/dist/react/charts/GroundTrackMap.js +1 -1
- package/dist/react/charts/GroundTrackMap.js.map +1 -1
- package/dist/react/charts/unified/AstroChart.js +34 -13
- package/dist/react/charts/unified/AstroChart.js.map +1 -1
- package/dist/react/chatgpt/AppCard.d.ts +0 -4
- package/dist/react/chatgpt/index.d.ts +0 -19
- package/dist/react/context/SpatialSelectionContext.d.ts +40 -0
- package/dist/react/context/SpatialSelectionContext.js +10 -0
- package/dist/react/context/SpatialSelectionContext.js.map +1 -0
- package/dist/react/context/index.d.ts +2 -0
- package/dist/react/core/{DataTable.d.ts → data/DataTable.d.ts} +1 -1
- package/dist/react/core/{DataTable.js → data/DataTable.js} +4 -4
- package/dist/react/core/data/DataTable.js.map +1 -0
- package/dist/react/core/{DataValue.d.ts → data/DataValue.d.ts} +2 -2
- package/dist/react/core/{DataValue.js → data/DataValue.js} +2 -2
- package/dist/react/core/data/DataValue.js.map +1 -0
- package/dist/react/core/{propertyConfig.d.ts → data/propertyConfig.d.ts} +2 -2
- package/dist/react/core/data/propertyConfig.js.map +1 -0
- package/dist/react/core/{AstroIcon.js → display/AstroIcon.js} +1 -1
- package/dist/react/core/display/AstroIcon.js.map +1 -0
- package/dist/react/core/{Badge.d.ts → display/Badge.d.ts} +1 -1
- package/dist/react/core/{Badge.js → display/Badge.js} +2 -2
- package/dist/react/core/display/Badge.js.map +1 -0
- package/dist/react/core/{CardHeader.d.ts → display/CardHeader.d.ts} +1 -1
- package/dist/react/core/{CardHeader.js → display/CardHeader.js} +2 -2
- package/dist/react/core/display/CardHeader.js.map +1 -0
- package/dist/react/core/{Container.d.ts → display/Container.d.ts} +1 -1
- package/dist/react/core/{Container.js → display/Container.js} +3 -3
- package/dist/react/core/display/Container.js.map +1 -0
- package/dist/react/core/{CopyButton.js → display/CopyButton.js} +1 -1
- package/dist/react/core/display/CopyButton.js.map +1 -0
- package/dist/react/core/{GlassCard.d.ts → display/GlassCard.d.ts} +1 -1
- package/dist/react/core/{GlassCard.js → display/GlassCard.js} +2 -2
- package/dist/react/core/display/GlassCard.js.map +1 -0
- package/dist/react/core/{HeaderIconWithStatus.d.ts → display/HeaderIconWithStatus.d.ts} +1 -1
- package/dist/react/core/{HeaderIconWithStatus.js → display/HeaderIconWithStatus.js} +1 -1
- package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -0
- package/dist/react/core/{Icon.d.ts → display/Icon.d.ts} +1 -1
- package/dist/react/core/{Icon.js → display/Icon.js} +1 -1
- package/dist/react/core/display/Icon.js.map +1 -0
- package/dist/react/core/{Typography.d.ts → display/Typography.d.ts} +13 -4
- package/dist/react/core/{Typography.js → display/Typography.js} +1 -1
- package/dist/react/core/display/Typography.js.map +1 -0
- package/dist/react/core/{ConfirmDialog.js → feedback/ConfirmDialog.js} +1 -1
- package/dist/react/core/feedback/ConfirmDialog.js.map +1 -0
- package/dist/react/core/{Dialog.js → feedback/Dialog.js} +2 -2
- package/dist/react/core/feedback/Dialog.js.map +1 -0
- package/dist/react/core/{Toast.js → feedback/Toast.js} +3 -3
- package/dist/react/core/feedback/Toast.js.map +1 -0
- package/dist/react/core/index.d.ts +85 -83
- package/dist/react/core/{Button.js → inputs/Button.js} +2 -2
- package/dist/react/core/inputs/Button.js.map +1 -0
- package/dist/react/core/{Checkbox.js → inputs/Checkbox.js} +2 -2
- package/dist/react/core/inputs/Checkbox.js.map +1 -0
- package/dist/react/core/{Input.d.ts → inputs/Input.d.ts} +1 -1
- package/dist/react/core/{Input.js → inputs/Input.js} +3 -3
- package/dist/react/core/inputs/Input.js.map +1 -0
- package/dist/react/core/{LimitsBar.js → inputs/LimitsBar.js} +1 -1
- package/dist/react/core/inputs/LimitsBar.js.map +1 -0
- package/dist/react/core/{NumberInput.d.ts → inputs/NumberInput.d.ts} +2 -2
- package/dist/react/core/{NumberInput.js → inputs/NumberInput.js} +3 -3
- package/dist/react/core/inputs/NumberInput.js.map +1 -0
- package/dist/react/core/{PinInput.js → inputs/PinInput.js} +2 -2
- package/dist/react/core/inputs/PinInput.js.map +1 -0
- package/dist/react/core/{Select.js → inputs/Select.js} +3 -3
- package/dist/react/core/inputs/Select.js.map +1 -0
- package/dist/react/core/{Toggle.js → inputs/Toggle.js} +2 -2
- package/dist/react/core/inputs/Toggle.js.map +1 -0
- package/dist/react/core/{AppBar.d.ts → navigation/AppBar.d.ts} +1 -1
- package/dist/react/core/{AppBar.js → navigation/AppBar.js} +7 -7
- package/dist/react/core/navigation/AppBar.js.map +1 -0
- package/dist/react/core/{Pagination.js → navigation/Pagination.js} +2 -2
- package/dist/react/core/navigation/Pagination.js.map +1 -0
- package/dist/react/core/{SideNav.d.ts → navigation/SideNav.d.ts} +1 -1
- package/dist/react/core/{SideNav.js → navigation/SideNav.js} +8 -9
- package/dist/react/core/navigation/SideNav.js.map +1 -0
- package/dist/react/core/{Tabs.js → navigation/Tabs.js} +2 -2
- package/dist/react/core/navigation/Tabs.js.map +1 -0
- package/dist/react/core/{Popover.js → overlays/Popover.js} +1 -1
- package/dist/react/core/overlays/Popover.js.map +1 -0
- package/dist/react/core/{SidePanel.js → overlays/SidePanel.js} +7 -7
- package/dist/react/core/overlays/SidePanel.js.map +1 -0
- package/dist/react/core/{Tooltip.js → overlays/Tooltip.js} +2 -2
- package/dist/react/core/overlays/Tooltip.js.map +1 -0
- package/dist/react/core/{ActivityPlanner.js → widgets/ActivityPlanner.js} +1 -1
- package/dist/react/core/widgets/ActivityPlanner.js.map +1 -0
- package/dist/react/core/widgets/Capture.d.ts +140 -0
- package/dist/react/core/widgets/Capture.js +804 -0
- package/dist/react/core/widgets/Capture.js.map +1 -0
- package/dist/react/core/{ChatPanel.d.ts → widgets/ChatPanel.d.ts} +1 -1
- package/dist/react/core/{ChatPanel.js → widgets/ChatPanel.js} +5 -4
- package/dist/react/core/widgets/ChatPanel.js.map +1 -0
- package/dist/react/core/{ColorPickerPanel.d.ts → widgets/ColorPickerPanel.d.ts} +1 -1
- package/dist/react/core/{ColorPickerPanel.js → widgets/ColorPickerPanel.js} +3 -3
- package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -0
- package/dist/react/core/{CommandBuilder.js → widgets/CommandBuilder.js} +1 -1
- package/dist/react/core/widgets/CommandBuilder.js.map +1 -0
- package/dist/react/core/{ConnectionForm.d.ts → widgets/ConnectionForm.d.ts} +1 -1
- package/dist/react/core/{ConnectionForm.js → widgets/ConnectionForm.js} +2 -2
- package/dist/react/core/widgets/ConnectionForm.js.map +1 -0
- package/dist/react/core/{FileExplorer.js → widgets/FileExplorer.js} +2 -2
- package/dist/react/core/widgets/FileExplorer.js.map +1 -0
- package/dist/react/core/{HexViewer.js → widgets/HexViewer.js} +1 -1
- package/dist/react/core/widgets/HexViewer.js.map +1 -0
- package/dist/react/core/{ImageGallery.d.ts → widgets/ImageGallery.d.ts} +1 -1
- package/dist/react/core/{ImageGallery.js → widgets/ImageGallery.js} +3 -3
- package/dist/react/core/widgets/ImageGallery.js.map +1 -0
- package/dist/react/core/{LogViewer.d.ts → widgets/LogViewer.d.ts} +13 -3
- package/dist/react/core/{LogViewer.js → widgets/LogViewer.js} +28 -8
- package/dist/react/core/widgets/LogViewer.js.map +1 -0
- package/dist/react/core/{MessageStream.d.ts → widgets/MessageStream.d.ts} +2 -2
- package/dist/react/core/{MessageStream.js → widgets/MessageStream.js} +4 -4
- package/dist/react/core/widgets/MessageStream.js.map +1 -0
- package/dist/react/core/{MissionCalendar.js → widgets/MissionCalendar.js} +2 -2
- package/dist/react/core/widgets/MissionCalendar.js.map +1 -0
- package/dist/react/core/{PacketViewer.js → widgets/PacketViewer.js} +1 -1
- package/dist/react/core/widgets/PacketViewer.js.map +1 -0
- package/dist/react/core/widgets/capture-placeholder.png.js +5 -0
- package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -0
- package/dist/react/hooks/index.d.ts +9 -11
- package/dist/react/hooks/useAccessWindows.d.ts +15 -19
- package/dist/react/hooks/useGroundTrackHistory.d.ts +34 -0
- package/dist/react/hooks/useSimulationScene.d.ts +141 -0
- package/dist/react/hooks/useSimulationScene.js +401 -0
- package/dist/react/hooks/useSimulationScene.js.map +1 -0
- package/dist/react/hooks/useZendirSession.d.ts +44 -69
- package/dist/react/index.d.ts +10 -5
- package/dist/react/panels/LayerControlPanel.d.ts +54 -0
- package/dist/react/panels/LayerControlPanel.js +184 -0
- package/dist/react/panels/LayerControlPanel.js.map +1 -0
- package/dist/react/panels/ObjectInventoryPanel.d.ts +57 -0
- package/dist/react/panels/ObjectInventoryPanel.js +261 -0
- package/dist/react/panels/ObjectInventoryPanel.js.map +1 -0
- package/dist/react/panels/index.d.ts +15 -0
- package/dist/react/theme/ThemeProvider.d.ts +2 -0
- package/dist/react/theme/ThemeProvider.js +50 -72
- package/dist/react/theme/ThemeProvider.js.map +1 -1
- package/dist/react/types.d.ts +32 -3
- package/dist/react/types.js.map +1 -1
- package/dist/react.js +57 -41
- package/dist/react.js.map +1 -1
- 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 +6 -4
- package/dist/tokens/css-vars.d.ts +91 -0
- package/dist/tokens/css-vars.js +228 -0
- package/dist/tokens/css-vars.js.map +1 -0
- package/dist/tokens/index.d.ts +71 -18
- package/dist/tokens/index.js +206 -97
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/tokens.css +50 -50
- package/package.json +27 -22
- package/sdk-stub.js +10 -5
- package/dist/react/3d/EarthViewer.d.ts +0 -46
- package/dist/react/3d/SolarSystemViewer.d.ts +0 -43
- package/dist/react/chatgpt/ChatGPTCard.d.ts +0 -6
- package/dist/react/core/ActivityPlanner.js.map +0 -1
- package/dist/react/core/AppBar.js.map +0 -1
- package/dist/react/core/AstroIcon.js.map +0 -1
- package/dist/react/core/Badge.js.map +0 -1
- package/dist/react/core/Button.js.map +0 -1
- package/dist/react/core/CardHeader.js.map +0 -1
- package/dist/react/core/ChatPanel.js.map +0 -1
- package/dist/react/core/Checkbox.js.map +0 -1
- package/dist/react/core/ColorPickerPanel.js.map +0 -1
- package/dist/react/core/CommandBuilder.js.map +0 -1
- package/dist/react/core/ConfirmDialog.js.map +0 -1
- package/dist/react/core/ConnectionForm.js.map +0 -1
- package/dist/react/core/Container.js.map +0 -1
- package/dist/react/core/CopyButton.js.map +0 -1
- package/dist/react/core/DataTable.js.map +0 -1
- package/dist/react/core/DataValue.js.map +0 -1
- package/dist/react/core/Dialog.js.map +0 -1
- package/dist/react/core/FileExplorer.js.map +0 -1
- package/dist/react/core/GlassCard.js.map +0 -1
- package/dist/react/core/HeaderIconWithStatus.js.map +0 -1
- package/dist/react/core/HexViewer.js.map +0 -1
- package/dist/react/core/Icon.js.map +0 -1
- package/dist/react/core/ImageGallery.js.map +0 -1
- package/dist/react/core/Input.js.map +0 -1
- package/dist/react/core/LimitsBar.js.map +0 -1
- package/dist/react/core/LogViewer.js.map +0 -1
- package/dist/react/core/MessageStream.js.map +0 -1
- package/dist/react/core/MissionCalendar.js.map +0 -1
- package/dist/react/core/NumberInput.js.map +0 -1
- package/dist/react/core/PacketViewer.js.map +0 -1
- package/dist/react/core/Pagination.js.map +0 -1
- package/dist/react/core/PinInput.js.map +0 -1
- package/dist/react/core/Popover.js.map +0 -1
- package/dist/react/core/Select.js.map +0 -1
- package/dist/react/core/SideNav.js.map +0 -1
- package/dist/react/core/SidePanel.js.map +0 -1
- package/dist/react/core/Tabs.js.map +0 -1
- package/dist/react/core/Toast.js.map +0 -1
- package/dist/react/core/Toggle.js.map +0 -1
- package/dist/react/core/Tooltip.js.map +0 -1
- package/dist/react/core/Typography.js.map +0 -1
- package/dist/react/core/propertyConfig.js.map +0 -1
- package/dist/react/hooks/useSimulationTime.d.ts +0 -61
- package/dist/react/hooks/useSpacecraftPosition.d.ts +0 -50
- package/dist/react/hooks/useTelemetry.d.ts +0 -55
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- /package/dist/react/core/{propertyConfig.js → data/propertyConfig.js} +0 -0
- /package/dist/react/core/{AstroIcon.d.ts → display/AstroIcon.d.ts} +0 -0
- /package/dist/react/core/{CopyButton.d.ts → display/CopyButton.d.ts} +0 -0
- /package/dist/react/core/{ConfirmDialog.d.ts → feedback/ConfirmDialog.d.ts} +0 -0
- /package/dist/react/core/{Dialog.d.ts → feedback/Dialog.d.ts} +0 -0
- /package/dist/react/core/{Toast.d.ts → feedback/Toast.d.ts} +0 -0
- /package/dist/react/core/{Button.d.ts → inputs/Button.d.ts} +0 -0
- /package/dist/react/core/{Checkbox.d.ts → inputs/Checkbox.d.ts} +0 -0
- /package/dist/react/core/{LimitsBar.d.ts → inputs/LimitsBar.d.ts} +0 -0
- /package/dist/react/core/{PinInput.d.ts → inputs/PinInput.d.ts} +0 -0
- /package/dist/react/core/{Select.d.ts → inputs/Select.d.ts} +0 -0
- /package/dist/react/core/{Toggle.d.ts → inputs/Toggle.d.ts} +0 -0
- /package/dist/react/core/{Pagination.d.ts → navigation/Pagination.d.ts} +0 -0
- /package/dist/react/core/{Tabs.d.ts → navigation/Tabs.d.ts} +0 -0
- /package/dist/react/core/{Popover.d.ts → overlays/Popover.d.ts} +0 -0
- /package/dist/react/core/{SidePanel.d.ts → overlays/SidePanel.d.ts} +0 -0
- /package/dist/react/core/{Tooltip.d.ts → overlays/Tooltip.d.ts} +0 -0
- /package/dist/react/core/{ActivityPlanner.d.ts → widgets/ActivityPlanner.d.ts} +0 -0
- /package/dist/react/core/{CommandBuilder.d.ts → widgets/CommandBuilder.d.ts} +0 -0
- /package/dist/react/core/{FileExplorer.d.ts → widgets/FileExplorer.d.ts} +0 -0
- /package/dist/react/core/{HexViewer.d.ts → widgets/HexViewer.d.ts} +0 -0
- /package/dist/react/core/{MissionCalendar.d.ts → widgets/MissionCalendar.d.ts} +0 -0
- /package/dist/react/core/{PacketViewer.d.ts → widgets/PacketViewer.d.ts} +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { SimulationSceneObject, StructureDiag, PositionTickDiag } from '../hooks/useSimulationScene';
|
|
3
|
+
|
|
4
|
+
export type ObjectInventoryKind = SimulationSceneObject['kind'];
|
|
5
|
+
export interface ObjectInventoryPanelProps {
|
|
6
|
+
/** Objects to list. Typically `useSimulationScene().objects`. */
|
|
7
|
+
objects: SimulationSceneObject[];
|
|
8
|
+
/** Click handler — fires with the clicked object. Pure forward; the
|
|
9
|
+
* panel does not navigate, focus, or fly anywhere itself. */
|
|
10
|
+
onSelect?: (object: SimulationSceneObject) => void;
|
|
11
|
+
/** Currently selected object id (highlights the row). Pass `null` for none. */
|
|
12
|
+
selectedId?: string | null;
|
|
13
|
+
/** Where to anchor the panel on its parent. Default: `top-left`. */
|
|
14
|
+
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
15
|
+
/** Pixel offsets from the anchor. Defaults to (16, 56) so a top bar fits above. */
|
|
16
|
+
offset?: {
|
|
17
|
+
x?: number;
|
|
18
|
+
y?: number;
|
|
19
|
+
};
|
|
20
|
+
/** Hide the panel without unmounting (preserves `selectedId` state). */
|
|
21
|
+
hidden?: boolean;
|
|
22
|
+
/** Width in pixels. Default 330. */
|
|
23
|
+
width?: number;
|
|
24
|
+
/** Maximum height (CSS value). Default `'50vh'`. */
|
|
25
|
+
maxHeight?: string | number;
|
|
26
|
+
/** Allow the user to collapse / expand the panel. Default true. */
|
|
27
|
+
collapsible?: boolean;
|
|
28
|
+
/** Initial collapsed state. Default false. */
|
|
29
|
+
defaultCollapsed?: boolean;
|
|
30
|
+
/** Optional title override. Default: `"API Objects · N"`. */
|
|
31
|
+
title?: ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Optional structure diagnostic block (raw keys + counts from
|
|
34
|
+
* getSimulationStructure). Useful in dev / debug builds; omit in
|
|
35
|
+
* production for a cleaner look.
|
|
36
|
+
*/
|
|
37
|
+
structureDiag?: StructureDiag | null;
|
|
38
|
+
/** Optional position-tick diagnostic block. */
|
|
39
|
+
positionTickDiag?: PositionTickDiag | null;
|
|
40
|
+
/** Custom labels per kind (defaults: "Spacecraft", "Ground Stations", "Celestial Bodies"). */
|
|
41
|
+
kindLabels?: Partial<Record<ObjectInventoryKind, string>>;
|
|
42
|
+
/** Inline style override on the outer container. */
|
|
43
|
+
style?: CSSProperties;
|
|
44
|
+
}
|
|
45
|
+
export declare const ObjectInventoryPanel: import('react').NamedExoticComponent<ObjectInventoryPanelProps>;
|
|
46
|
+
/**
|
|
47
|
+
* Sensible default fly-to distance per object kind, for use with
|
|
48
|
+
* `<ZenSpace3D />`'s imperative `focusOn(id, { zoom })` handle.
|
|
49
|
+
*
|
|
50
|
+
* spacecraft: 2 000 000 m (≈ 2 000 km — close orbital view)
|
|
51
|
+
* groundStation: 1 500 000 m (≈ 1 500 km — high-altitude angled view)
|
|
52
|
+
* celestialBody: 50 000 000 m (≈ 50 000 km — full-planet view)
|
|
53
|
+
*
|
|
54
|
+
* Override per call if the consumer wants tighter/looser framing.
|
|
55
|
+
*/
|
|
56
|
+
export declare function recommendedFlyDistance(kind: ObjectInventoryKind): number;
|
|
57
|
+
export default ObjectInventoryPanel;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useState, useCallback } from "react";
|
|
3
|
+
import { useThemeTokens } from "../theme/ThemeProvider.js";
|
|
4
|
+
import { useSpatialSelection } from "../context/SpatialSelectionContext.js";
|
|
5
|
+
function shortId(id) {
|
|
6
|
+
return id.length <= 8 ? id : id.slice(0, 8);
|
|
7
|
+
}
|
|
8
|
+
const DEFAULT_KIND_LABELS = {
|
|
9
|
+
spacecraft: "Spacecraft",
|
|
10
|
+
groundStation: "Ground Stations",
|
|
11
|
+
celestialBody: "Celestial Bodies"
|
|
12
|
+
};
|
|
13
|
+
const KIND_ORDER = ["spacecraft", "groundStation", "celestialBody"];
|
|
14
|
+
const ObjectInventoryPanel = memo(function ObjectInventoryPanel2({
|
|
15
|
+
objects,
|
|
16
|
+
onSelect,
|
|
17
|
+
selectedId,
|
|
18
|
+
position = "top-left",
|
|
19
|
+
offset,
|
|
20
|
+
hidden = false,
|
|
21
|
+
width = 330,
|
|
22
|
+
maxHeight = "50vh",
|
|
23
|
+
collapsible = true,
|
|
24
|
+
defaultCollapsed = false,
|
|
25
|
+
title,
|
|
26
|
+
structureDiag,
|
|
27
|
+
positionTickDiag,
|
|
28
|
+
kindLabels,
|
|
29
|
+
style
|
|
30
|
+
}) {
|
|
31
|
+
var _a;
|
|
32
|
+
const tokens = useThemeTokens();
|
|
33
|
+
const [collapsed, setCollapsed] = useState(defaultCollapsed);
|
|
34
|
+
const ctx = useSpatialSelection();
|
|
35
|
+
const effectiveSelectedId = selectedId !== void 0 ? selectedId : (ctx == null ? void 0 : ctx.selectedId) ?? null;
|
|
36
|
+
const effectiveOnSelect = useCallback(
|
|
37
|
+
(obj) => {
|
|
38
|
+
onSelect == null ? void 0 : onSelect(obj);
|
|
39
|
+
if (!onSelect) ctx == null ? void 0 : ctx.setSelectedId(obj.id);
|
|
40
|
+
},
|
|
41
|
+
[onSelect, ctx]
|
|
42
|
+
);
|
|
43
|
+
const labels = { ...DEFAULT_KIND_LABELS, ...kindLabels };
|
|
44
|
+
const entries = Array.isArray(objects) ? objects : [];
|
|
45
|
+
const offX = (offset == null ? void 0 : offset.x) ?? 16;
|
|
46
|
+
const offY = (offset == null ? void 0 : offset.y) ?? 56;
|
|
47
|
+
const anchor = (() => {
|
|
48
|
+
switch (position) {
|
|
49
|
+
case "top-right":
|
|
50
|
+
return { top: offY, right: offX };
|
|
51
|
+
case "bottom-left":
|
|
52
|
+
return { bottom: offY, left: offX };
|
|
53
|
+
case "bottom-right":
|
|
54
|
+
return { bottom: offY, right: offX };
|
|
55
|
+
case "top-left":
|
|
56
|
+
default:
|
|
57
|
+
return { top: offY, left: offX };
|
|
58
|
+
}
|
|
59
|
+
})();
|
|
60
|
+
if (hidden) return null;
|
|
61
|
+
const dim = { opacity: 0.55, fontSize: "0.9em" };
|
|
62
|
+
return /* @__PURE__ */ jsxs(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
"data-testid": "zendir-object-inventory",
|
|
66
|
+
style: {
|
|
67
|
+
position: "absolute",
|
|
68
|
+
zIndex: 2,
|
|
69
|
+
width,
|
|
70
|
+
maxHeight,
|
|
71
|
+
overflow: "auto",
|
|
72
|
+
padding: tokens.spacing.sm,
|
|
73
|
+
borderRadius: ((_a = tokens.borderRadius) == null ? void 0 : _a.md) ?? 6,
|
|
74
|
+
border: "1px solid rgba(255,255,255,0.12)",
|
|
75
|
+
background: "rgba(0,0,0,0.72)",
|
|
76
|
+
color: tokens.colors.text.primary,
|
|
77
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
78
|
+
lineHeight: 1.35,
|
|
79
|
+
...anchor,
|
|
80
|
+
...style
|
|
81
|
+
},
|
|
82
|
+
children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
PanelHeader,
|
|
85
|
+
{
|
|
86
|
+
title: title ?? `API Objects · ${entries.length}`,
|
|
87
|
+
collapsible,
|
|
88
|
+
collapsed,
|
|
89
|
+
onToggle: () => setCollapsed((c) => !c)
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
!collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
93
|
+
KIND_ORDER.map((kind) => {
|
|
94
|
+
const items = entries.filter((o) => o.kind === kind);
|
|
95
|
+
return /* @__PURE__ */ jsx(
|
|
96
|
+
ObjectInventoryGroup,
|
|
97
|
+
{
|
|
98
|
+
title: `${labels[kind]} (${items.length})`,
|
|
99
|
+
items,
|
|
100
|
+
selectedId: effectiveSelectedId,
|
|
101
|
+
onSelect: onSelect != null ? onSelect : ctx ? effectiveOnSelect : void 0
|
|
102
|
+
},
|
|
103
|
+
kind
|
|
104
|
+
);
|
|
105
|
+
}),
|
|
106
|
+
structureDiag !== void 0 && /* @__PURE__ */ jsx(StructureDiagBlock, { diag: structureDiag, dim }),
|
|
107
|
+
positionTickDiag !== void 0 && /* @__PURE__ */ jsx(PositionTickDiagBlock, { diag: positionTickDiag, dim })
|
|
108
|
+
] })
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
const PanelHeader = ({
|
|
114
|
+
title,
|
|
115
|
+
collapsible,
|
|
116
|
+
collapsed,
|
|
117
|
+
onToggle
|
|
118
|
+
}) => {
|
|
119
|
+
if (!collapsible) {
|
|
120
|
+
return /* @__PURE__ */ jsx("div", { style: { marginBottom: 6, fontWeight: 600 }, children: title });
|
|
121
|
+
}
|
|
122
|
+
return /* @__PURE__ */ jsxs(
|
|
123
|
+
"button",
|
|
124
|
+
{
|
|
125
|
+
type: "button",
|
|
126
|
+
onClick: onToggle,
|
|
127
|
+
"aria-expanded": !collapsed,
|
|
128
|
+
style: {
|
|
129
|
+
display: "flex",
|
|
130
|
+
width: "100%",
|
|
131
|
+
alignItems: "center",
|
|
132
|
+
justifyContent: "space-between",
|
|
133
|
+
marginBottom: 6,
|
|
134
|
+
padding: 0,
|
|
135
|
+
background: "none",
|
|
136
|
+
border: "none",
|
|
137
|
+
color: "inherit",
|
|
138
|
+
font: "inherit",
|
|
139
|
+
fontWeight: 600,
|
|
140
|
+
cursor: "pointer",
|
|
141
|
+
textAlign: "left"
|
|
142
|
+
},
|
|
143
|
+
children: [
|
|
144
|
+
/* @__PURE__ */ jsx("span", { children: title }),
|
|
145
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { opacity: 0.7, fontSize: "0.85em" }, children: collapsed ? "▸" : "▾" })
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
const ObjectInventoryGroup = ({
|
|
151
|
+
title,
|
|
152
|
+
items,
|
|
153
|
+
selectedId,
|
|
154
|
+
onSelect
|
|
155
|
+
}) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: 6 }, children: [
|
|
156
|
+
/* @__PURE__ */ jsx("div", { style: { opacity: 0.85 }, children: title }),
|
|
157
|
+
items.length === 0 ? /* @__PURE__ */ jsx("div", { style: { opacity: 0.6 }, children: "—" }) : items.map((item) => /* @__PURE__ */ jsx(
|
|
158
|
+
ObjectRow,
|
|
159
|
+
{
|
|
160
|
+
object: item,
|
|
161
|
+
selected: item.id === selectedId,
|
|
162
|
+
onSelect
|
|
163
|
+
},
|
|
164
|
+
item.id
|
|
165
|
+
))
|
|
166
|
+
] });
|
|
167
|
+
const ObjectRow = ({
|
|
168
|
+
object,
|
|
169
|
+
selected,
|
|
170
|
+
onSelect
|
|
171
|
+
}) => {
|
|
172
|
+
const handleClick = useCallback(() => onSelect == null ? void 0 : onSelect(object), [onSelect, object]);
|
|
173
|
+
const interactive = onSelect != null;
|
|
174
|
+
return /* @__PURE__ */ jsxs(
|
|
175
|
+
"div",
|
|
176
|
+
{
|
|
177
|
+
role: interactive ? "button" : void 0,
|
|
178
|
+
tabIndex: interactive ? 0 : void 0,
|
|
179
|
+
onClick: interactive ? handleClick : void 0,
|
|
180
|
+
onKeyDown: interactive ? (e) => {
|
|
181
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
182
|
+
e.preventDefault();
|
|
183
|
+
handleClick();
|
|
184
|
+
}
|
|
185
|
+
} : void 0,
|
|
186
|
+
style: {
|
|
187
|
+
opacity: 0.95,
|
|
188
|
+
padding: "1px 4px",
|
|
189
|
+
borderRadius: 3,
|
|
190
|
+
cursor: interactive ? "pointer" : "default",
|
|
191
|
+
background: selected ? "rgba(255,255,255,0.12)" : "transparent"
|
|
192
|
+
},
|
|
193
|
+
children: [
|
|
194
|
+
object.name,
|
|
195
|
+
" ",
|
|
196
|
+
/* @__PURE__ */ jsxs("span", { style: { opacity: 0.6 }, children: [
|
|
197
|
+
"(",
|
|
198
|
+
shortId(object.id),
|
|
199
|
+
")"
|
|
200
|
+
] })
|
|
201
|
+
]
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
};
|
|
205
|
+
const StructureDiagBlock = ({
|
|
206
|
+
diag,
|
|
207
|
+
dim
|
|
208
|
+
}) => /* @__PURE__ */ jsx("div", { style: { marginTop: 8, borderTop: "1px solid rgba(255,255,255,0.1)", paddingTop: 6 }, children: diag ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
209
|
+
/* @__PURE__ */ jsx("div", { style: { ...dim, marginBottom: 2 }, children: "Raw structure keys:" }),
|
|
210
|
+
/* @__PURE__ */ jsx("div", { style: dim, children: diag.topLevelKeys.join(", ") || "—" }),
|
|
211
|
+
/* @__PURE__ */ jsxs("div", { style: { ...dim, marginTop: 2 }, children: [
|
|
212
|
+
"Objects[]: ",
|
|
213
|
+
diag.rawObjectCount < 0 ? "absent" : diag.rawObjectCount,
|
|
214
|
+
" · ",
|
|
215
|
+
"Systems[]: ",
|
|
216
|
+
diag.rawSystemCount < 0 ? "absent" : diag.rawSystemCount
|
|
217
|
+
] })
|
|
218
|
+
] }) : /* @__PURE__ */ jsx("div", { style: { ...dim, marginTop: 4 }, children: "Waiting for structure…" }) });
|
|
219
|
+
const PositionTickDiagBlock = ({
|
|
220
|
+
diag,
|
|
221
|
+
dim
|
|
222
|
+
}) => {
|
|
223
|
+
if (!diag) return null;
|
|
224
|
+
return /* @__PURE__ */ jsxs("div", { style: { marginTop: 8, borderTop: "1px solid rgba(255,255,255,0.1)", paddingTop: 6 }, children: [
|
|
225
|
+
/* @__PURE__ */ jsx("div", { style: { ...dim, marginBottom: 2 }, children: "Last position tick:" }),
|
|
226
|
+
/* @__PURE__ */ jsxs("div", { style: dim, children: [
|
|
227
|
+
"ok ",
|
|
228
|
+
diag.parsedOk,
|
|
229
|
+
"/",
|
|
230
|
+
diag.requested,
|
|
231
|
+
diag.parseFailed > 0 && ` · parseFail ${diag.parseFailed}`,
|
|
232
|
+
diag.requestFailed > 0 && ` · reqFail ${diag.requestFailed}`
|
|
233
|
+
] }),
|
|
234
|
+
/* @__PURE__ */ jsxs("div", { style: dim, children: [
|
|
235
|
+
"asked for:",
|
|
236
|
+
" ",
|
|
237
|
+
diag.requestedProps ? diag.requestedProps.join(", ") : "getAllProperties (fallback)"
|
|
238
|
+
] }),
|
|
239
|
+
diag.firstResponseKeys.length > 0 && /* @__PURE__ */ jsxs("div", { style: { ...dim, wordBreak: "break-all" }, children: [
|
|
240
|
+
"got keys: ",
|
|
241
|
+
diag.firstResponseKeys.slice(0, 12).join(", "),
|
|
242
|
+
diag.firstResponseKeys.length > 12 && " …"
|
|
243
|
+
] }),
|
|
244
|
+
diag.firstResponseSample && /* @__PURE__ */ jsx("div", { style: { ...dim, wordBreak: "break-all" }, children: diag.firstResponseSample })
|
|
245
|
+
] });
|
|
246
|
+
};
|
|
247
|
+
function recommendedFlyDistance(kind) {
|
|
248
|
+
switch (kind) {
|
|
249
|
+
case "spacecraft":
|
|
250
|
+
return 2e6;
|
|
251
|
+
case "groundStation":
|
|
252
|
+
return 15e5;
|
|
253
|
+
case "celestialBody":
|
|
254
|
+
return 5e7;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
export {
|
|
258
|
+
ObjectInventoryPanel,
|
|
259
|
+
recommendedFlyDistance
|
|
260
|
+
};
|
|
261
|
+
//# sourceMappingURL=ObjectInventoryPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectInventoryPanel.js","sources":["../../../src/react/panels/ObjectInventoryPanel.tsx"],"sourcesContent":["/**\n * @zendir/ui - ObjectInventoryPanel\n *\n * Themed list of simulation objects, grouped by `kind` (spacecraft /\n * ground stations / celestial bodies). Pair with `useSimulationScene`:\n *\n * ```tsx\n * const scene = useSimulationScene({ client, containerId, simulationId });\n * <ObjectInventoryPanel\n * objects={scene.objects}\n * onSelect={(obj) => zenRef.current?.focusOn(obj.id, {\n * zoom: recommendedFlyDistance(obj.kind),\n * })}\n * />\n * ```\n *\n * The panel renders the toggle UI only — it has no opinion about WHAT\n * happens on select. The consumer wires `onSelect` to its 3D viewer's\n * imperative handle (or anywhere else — the panel is reusable in any\n * dashboard or debug context).\n */\n\nimport { memo, useCallback, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useThemeTokens } from '../theme/ThemeProvider';\nimport { useSpatialSelection } from '../context/SpatialSelectionContext';\nimport type { SimulationSceneObject, StructureDiag, PositionTickDiag } from '../hooks/useSimulationScene';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type ObjectInventoryKind = SimulationSceneObject['kind'];\n\nexport interface ObjectInventoryPanelProps {\n /** Objects to list. Typically `useSimulationScene().objects`. */\n objects: SimulationSceneObject[];\n /** Click handler — fires with the clicked object. Pure forward; the\n * panel does not navigate, focus, or fly anywhere itself. */\n onSelect?: (object: SimulationSceneObject) => void;\n /** Currently selected object id (highlights the row). Pass `null` for none. */\n selectedId?: string | null;\n\n /** Where to anchor the panel on its parent. Default: `top-left`. */\n position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n /** Pixel offsets from the anchor. Defaults to (16, 56) so a top bar fits above. */\n offset?: { x?: number; y?: number };\n /** Hide the panel without unmounting (preserves `selectedId` state). */\n hidden?: boolean;\n /** Width in pixels. Default 330. */\n width?: number;\n /** Maximum height (CSS value). Default `'50vh'`. */\n maxHeight?: string | number;\n\n /** Allow the user to collapse / expand the panel. Default true. */\n collapsible?: boolean;\n /** Initial collapsed state. Default false. */\n defaultCollapsed?: boolean;\n\n /** Optional title override. Default: `\"API Objects · N\"`. */\n title?: ReactNode;\n\n /**\n * Optional structure diagnostic block (raw keys + counts from\n * getSimulationStructure). Useful in dev / debug builds; omit in\n * production for a cleaner look.\n */\n structureDiag?: StructureDiag | null;\n /** Optional position-tick diagnostic block. */\n positionTickDiag?: PositionTickDiag | null;\n\n /** Custom labels per kind (defaults: \"Spacecraft\", \"Ground Stations\", \"Celestial Bodies\"). */\n kindLabels?: Partial<Record<ObjectInventoryKind, string>>;\n\n /** Inline style override on the outer container. */\n style?: CSSProperties;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/** Stable short-form of a GUID for inline display. */\nfunction shortId(id: string): string {\n return id.length <= 8 ? id : id.slice(0, 8);\n}\n\nconst DEFAULT_KIND_LABELS: Record<ObjectInventoryKind, string> = {\n spacecraft: 'Spacecraft',\n groundStation: 'Ground Stations',\n celestialBody: 'Celestial Bodies',\n};\n\nconst KIND_ORDER: ObjectInventoryKind[] = ['spacecraft', 'groundStation', 'celestialBody'];\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nexport const ObjectInventoryPanel = memo(function ObjectInventoryPanel({\n objects,\n onSelect,\n selectedId,\n position = 'top-left',\n offset,\n hidden = false,\n width = 330,\n maxHeight = '50vh',\n collapsible = true,\n defaultCollapsed = false,\n title,\n structureDiag,\n positionTickDiag,\n kindLabels,\n style,\n}: ObjectInventoryPanelProps) {\n const tokens = useThemeTokens();\n const [collapsed, setCollapsed] = useState(defaultCollapsed);\n\n // Optional <SpatialSelectionProvider> integration. When present, the\n // panel uses the shared selection state so other components (3D\n // viewer, GroundTrackMap, etc.) stay synchronised. Explicit props\n // always win — consumers can still override per-instance.\n const ctx = useSpatialSelection();\n const effectiveSelectedId = selectedId !== undefined ? selectedId : ctx?.selectedId ?? null;\n const effectiveOnSelect = useCallback(\n (obj: SimulationSceneObject) => {\n onSelect?.(obj);\n // Also push into the shared context if no explicit onSelect wins it.\n if (!onSelect) ctx?.setSelectedId(obj.id);\n },\n [onSelect, ctx],\n );\n\n const labels = { ...DEFAULT_KIND_LABELS, ...kindLabels };\n const entries = Array.isArray(objects) ? objects : [];\n\n // Position anchor — translate the prop into top/left/right/bottom CSS.\n const offX = offset?.x ?? 16;\n const offY = offset?.y ?? 56;\n const anchor: CSSProperties = (() => {\n switch (position) {\n case 'top-right': return { top: offY, right: offX };\n case 'bottom-left': return { bottom: offY, left: offX };\n case 'bottom-right': return { bottom: offY, right: offX };\n case 'top-left':\n default: return { top: offY, left: offX };\n }\n })();\n\n if (hidden) return null;\n\n const dim: CSSProperties = { opacity: 0.55, fontSize: '0.9em' };\n\n return (\n <div\n data-testid=\"zendir-object-inventory\"\n style={{\n position: 'absolute',\n zIndex: 2,\n width,\n maxHeight,\n overflow: 'auto',\n padding: tokens.spacing.sm,\n borderRadius: tokens.borderRadius?.md ?? 6,\n border: '1px solid rgba(255,255,255,0.12)',\n background: 'rgba(0,0,0,0.72)',\n color: tokens.colors.text.primary,\n fontSize: tokens.typography.fontSize.xs,\n lineHeight: 1.35,\n ...anchor,\n ...style,\n }}\n >\n <PanelHeader\n title={title ?? `API Objects · ${entries.length}`}\n collapsible={collapsible}\n collapsed={collapsed}\n onToggle={() => setCollapsed((c) => !c)}\n />\n\n {!collapsed && (\n <>\n {KIND_ORDER.map((kind) => {\n const items = entries.filter((o) => o.kind === kind);\n return (\n <ObjectInventoryGroup\n key={kind}\n title={`${labels[kind]} (${items.length})`}\n items={items}\n selectedId={effectiveSelectedId}\n onSelect={onSelect != null ? onSelect : (ctx ? effectiveOnSelect : undefined)}\n />\n );\n })}\n\n {structureDiag !== undefined && (\n <StructureDiagBlock diag={structureDiag} dim={dim} />\n )}\n\n {positionTickDiag !== undefined && (\n <PositionTickDiagBlock diag={positionTickDiag} dim={dim} />\n )}\n </>\n )}\n </div>\n );\n});\n\n// ─── Sub-components ───────────────────────────────────────────────────────────\n\nconst PanelHeader = ({\n title,\n collapsible,\n collapsed,\n onToggle,\n}: {\n title: ReactNode;\n collapsible: boolean;\n collapsed: boolean;\n onToggle: () => void;\n}) => {\n if (!collapsible) {\n return <div style={{ marginBottom: 6, fontWeight: 600 }}>{title}</div>;\n }\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={!collapsed}\n style={{\n display: 'flex',\n width: '100%',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: 6,\n padding: 0,\n background: 'none',\n border: 'none',\n color: 'inherit',\n font: 'inherit',\n fontWeight: 600,\n cursor: 'pointer',\n textAlign: 'left',\n }}\n >\n <span>{title}</span>\n <span aria-hidden style={{ opacity: 0.7, fontSize: '0.85em' }}>\n {collapsed ? '▸' : '▾'}\n </span>\n </button>\n );\n};\n\nconst ObjectInventoryGroup = ({\n title,\n items,\n selectedId,\n onSelect,\n}: {\n title: string;\n items: SimulationSceneObject[];\n selectedId: string | null;\n onSelect?: (obj: SimulationSceneObject) => void;\n}) => (\n <div style={{ marginBottom: 6 }}>\n <div style={{ opacity: 0.85 }}>{title}</div>\n {items.length === 0 ? (\n <div style={{ opacity: 0.6 }}>—</div>\n ) : (\n items.map((item) => (\n <ObjectRow\n key={item.id}\n object={item}\n selected={item.id === selectedId}\n onSelect={onSelect}\n />\n ))\n )}\n </div>\n);\n\nconst ObjectRow = ({\n object,\n selected,\n onSelect,\n}: {\n object: SimulationSceneObject;\n selected: boolean;\n onSelect?: (obj: SimulationSceneObject) => void;\n}) => {\n const handleClick = useCallback(() => onSelect?.(object), [onSelect, object]);\n const interactive = onSelect != null;\n return (\n <div\n role={interactive ? 'button' : undefined}\n tabIndex={interactive ? 0 : undefined}\n onClick={interactive ? handleClick : undefined}\n onKeyDown={\n interactive\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleClick();\n }\n }\n : undefined\n }\n style={{\n opacity: 0.95,\n padding: '1px 4px',\n borderRadius: 3,\n cursor: interactive ? 'pointer' : 'default',\n background: selected ? 'rgba(255,255,255,0.12)' : 'transparent',\n }}\n >\n {object.name} <span style={{ opacity: 0.6 }}>({shortId(object.id)})</span>\n </div>\n );\n};\n\nconst StructureDiagBlock = ({\n diag,\n dim,\n}: {\n diag: StructureDiag | null | undefined;\n dim: CSSProperties;\n}) => (\n <div style={{ marginTop: 8, borderTop: '1px solid rgba(255,255,255,0.1)', paddingTop: 6 }}>\n {diag ? (\n <>\n <div style={{ ...dim, marginBottom: 2 }}>Raw structure keys:</div>\n <div style={dim}>{diag.topLevelKeys.join(', ') || '—'}</div>\n <div style={{ ...dim, marginTop: 2 }}>\n Objects[]: {diag.rawObjectCount < 0 ? 'absent' : diag.rawObjectCount}\n {' · '}\n Systems[]: {diag.rawSystemCount < 0 ? 'absent' : diag.rawSystemCount}\n </div>\n </>\n ) : (\n <div style={{ ...dim, marginTop: 4 }}>Waiting for structure…</div>\n )}\n </div>\n);\n\nconst PositionTickDiagBlock = ({\n diag,\n dim,\n}: {\n diag: PositionTickDiag | null | undefined;\n dim: CSSProperties;\n}) => {\n if (!diag) return null;\n return (\n <div style={{ marginTop: 8, borderTop: '1px solid rgba(255,255,255,0.1)', paddingTop: 6 }}>\n <div style={{ ...dim, marginBottom: 2 }}>Last position tick:</div>\n <div style={dim}>\n ok {diag.parsedOk}/{diag.requested}\n {diag.parseFailed > 0 && ` · parseFail ${diag.parseFailed}`}\n {diag.requestFailed > 0 && ` · reqFail ${diag.requestFailed}`}\n </div>\n <div style={dim}>\n asked for:{' '}\n {diag.requestedProps\n ? diag.requestedProps.join(', ')\n : 'getAllProperties (fallback)'}\n </div>\n {diag.firstResponseKeys.length > 0 && (\n <div style={{ ...dim, wordBreak: 'break-all' }}>\n got keys: {diag.firstResponseKeys.slice(0, 12).join(', ')}\n {diag.firstResponseKeys.length > 12 && ' …'}\n </div>\n )}\n {diag.firstResponseSample && (\n <div style={{ ...dim, wordBreak: 'break-all' }}>{diag.firstResponseSample}</div>\n )}\n </div>\n );\n};\n\n// ─── Companion helper ─────────────────────────────────────────────────────────\n\n/**\n * Sensible default fly-to distance per object kind, for use with\n * `<ZenSpace3D />`'s imperative `focusOn(id, { zoom })` handle.\n *\n * spacecraft: 2 000 000 m (≈ 2 000 km — close orbital view)\n * groundStation: 1 500 000 m (≈ 1 500 km — high-altitude angled view)\n * celestialBody: 50 000 000 m (≈ 50 000 km — full-planet view)\n *\n * Override per call if the consumer wants tighter/looser framing.\n */\nexport function recommendedFlyDistance(kind: ObjectInventoryKind): number {\n switch (kind) {\n case 'spacecraft': return 2_000_000;\n case 'groundStation': return 1_500_000;\n case 'celestialBody': return 50_000_000;\n }\n}\n\nexport default ObjectInventoryPanel;\n"],"names":["ObjectInventoryPanel"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zendir/ui - Floating UI panels for live 3D dashboards.
|
|
3
|
+
*
|
|
4
|
+
* Both panels are **renderless** w.r.t. their data:
|
|
5
|
+
* • `<ObjectInventoryPanel />` lists objects and emits `onSelect`.
|
|
6
|
+
* • `<LayerControlPanel />` emits visibility / layer-flag changes.
|
|
7
|
+
*
|
|
8
|
+
* The consumer wires the callbacks to `<ZenSpace3D />`'s imperative
|
|
9
|
+
* handle and props. Same separation of concerns as `<GroundTrackMap />`'s
|
|
10
|
+
* `MapLayerDef` pattern — UI here, rendering there.
|
|
11
|
+
*/
|
|
12
|
+
export { ObjectInventoryPanel, recommendedFlyDistance } from './ObjectInventoryPanel';
|
|
13
|
+
export type { ObjectInventoryPanelProps, ObjectInventoryKind, } from './ObjectInventoryPanel';
|
|
14
|
+
export { LayerControlPanel } from './LayerControlPanel';
|
|
15
|
+
export type { LayerControlPanelProps, RenderLayers, GroupVisibility, GroupCounts, } from './LayerControlPanel';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useState, useEffect, useMemo, useContext, createContext } from "react";
|
|
3
|
+
import { typography, borderRadius, spacing } from "../../tokens/index.js";
|
|
3
4
|
function adjustHexBrightness(hex, factor) {
|
|
4
5
|
const normalized = hex.replace("#", "").trim();
|
|
5
6
|
const expanded = normalized.length === 3 ? normalized.split("").map((ch) => ch + ch).join("") : normalized;
|
|
@@ -58,6 +59,14 @@ const animationTokens = {
|
|
|
58
59
|
slow: 400
|
|
59
60
|
}
|
|
60
61
|
};
|
|
62
|
+
const animationTokensReduced = {
|
|
63
|
+
fast: "all 0.01ms linear",
|
|
64
|
+
normal: "all 0.01ms linear",
|
|
65
|
+
slow: "all 0.01ms linear",
|
|
66
|
+
spring: "all 0.01ms linear",
|
|
67
|
+
easing: animationTokens.easing,
|
|
68
|
+
duration: { instant: 0, fast: 0, normal: 0, slow: 0 }
|
|
69
|
+
};
|
|
61
70
|
const focusTokensDark = {
|
|
62
71
|
color: "#4dacff",
|
|
63
72
|
width: "2px",
|
|
@@ -190,26 +199,10 @@ const astroThemeDark = {
|
|
|
190
199
|
disabled: "#6b7280"
|
|
191
200
|
}
|
|
192
201
|
},
|
|
193
|
-
spacing
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
smd: "12px",
|
|
198
|
-
md: "16px",
|
|
199
|
-
mdl: "20px",
|
|
200
|
-
lg: "24px",
|
|
201
|
-
xl: "32px",
|
|
202
|
-
xxl: "48px"
|
|
203
|
-
},
|
|
204
|
-
borderRadius: {
|
|
205
|
-
none: "0",
|
|
206
|
-
xs: "1px",
|
|
207
|
-
sm: "2px",
|
|
208
|
-
md: "4px",
|
|
209
|
-
lg: "8px",
|
|
210
|
-
xl: "12px",
|
|
211
|
-
full: "9999px"
|
|
212
|
-
},
|
|
202
|
+
// spacing + borderRadius are sourced from tokens/index.ts (single source
|
|
203
|
+
// of truth — see comment at the top of this file).
|
|
204
|
+
spacing: { ...spacing },
|
|
205
|
+
borderRadius: { ...borderRadius },
|
|
213
206
|
elementSize: {
|
|
214
207
|
sm: "28px",
|
|
215
208
|
md: "36px",
|
|
@@ -217,15 +210,13 @@ const astroThemeDark = {
|
|
|
217
210
|
},
|
|
218
211
|
typography: {
|
|
219
212
|
/**
|
|
220
|
-
* Font families
|
|
213
|
+
* Font families — sourced from src/tokens/index.ts. Canonical stacks:
|
|
214
|
+
* primary: Public Sans → Roboto → system
|
|
215
|
+
* heading: Sora → Roboto → system
|
|
216
|
+
* mono: Roboto Mono → system mono
|
|
221
217
|
* @see https://www.astrouxds.com/foundations/typography/
|
|
222
218
|
*/
|
|
223
|
-
fontFamily: {
|
|
224
|
-
/** Primary font: Roboto with comprehensive system fallbacks */
|
|
225
|
-
primary: '"Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif',
|
|
226
|
-
/** Monospace font: Roboto Mono for data/code with system fallbacks */
|
|
227
|
-
mono: '"Roboto Mono", "SF Mono", "Consolas", "Liberation Mono", monospace'
|
|
228
|
-
},
|
|
219
|
+
fontFamily: { ...typography.fontFamily },
|
|
229
220
|
// Astro UX Display Styles
|
|
230
221
|
// https://www.astrouxds.com/foundations/typography/
|
|
231
222
|
display: {
|
|
@@ -256,30 +247,11 @@ const astroThemeDark = {
|
|
|
256
247
|
1: { fontSize: "1rem", fontWeight: 400, letterSpacing: "0.5px", lineHeight: "1.25rem" },
|
|
257
248
|
"1Bold": { fontSize: "1rem", fontWeight: 700, letterSpacing: "0.5px", lineHeight: "1.25rem" }
|
|
258
249
|
},
|
|
259
|
-
//
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
xxs: "0.625rem",
|
|
265
|
-
// 10px - compact labels (xs in old system)
|
|
266
|
-
xs: "0.625rem",
|
|
267
|
-
// 10px - compact (kept for backward compatibility)
|
|
268
|
-
sm: "0.75rem",
|
|
269
|
-
// 12px (Body 3)
|
|
270
|
-
base: "0.875rem",
|
|
271
|
-
// 14px (Body 2)
|
|
272
|
-
md: "0.875rem",
|
|
273
|
-
// 14px (Body 2)
|
|
274
|
-
lg: "1rem",
|
|
275
|
-
// 16px (Body 1)
|
|
276
|
-
xl: "1.25rem",
|
|
277
|
-
// 20px (Heading 3/4)
|
|
278
|
-
xxl: "1.5rem",
|
|
279
|
-
// 24px (Heading 2)
|
|
280
|
-
xxxl: "2.125rem"
|
|
281
|
-
// 34px (Heading 1)
|
|
282
|
-
},
|
|
250
|
+
// Convenience numeric scale — sourced from tokens/index.ts. Prefer the
|
|
251
|
+
// semantically-named display/heading/body/control style objects above
|
|
252
|
+
// for new code; this scale is kept for the ~300 existing components
|
|
253
|
+
// that consume `tokens.typography.fontSize.*` directly.
|
|
254
|
+
fontSize: { ...typography.fontSize },
|
|
283
255
|
/**
|
|
284
256
|
* Font weights per AstroUXDS specification
|
|
285
257
|
* Only 300, 400, 500, 700 are officially supported
|
|
@@ -986,13 +958,19 @@ function ThemeProvider({
|
|
|
986
958
|
return {
|
|
987
959
|
...base,
|
|
988
960
|
colors: resolvedColors,
|
|
989
|
-
borders: computeBorderTokens(resolvedColors)
|
|
961
|
+
borders: computeBorderTokens(resolvedColors),
|
|
962
|
+
// Honor prefers-reduced-motion in the JS token surface too. The
|
|
963
|
+
// global CSS @media rule below already strips CSS animations; this
|
|
964
|
+
// ensures JS-driven animation libraries (Framer Motion etc.) that
|
|
965
|
+
// read `tokens.animation.*` get the collapsed variant without each
|
|
966
|
+
// developer having to branch on `useTheme().prefersReducedMotion`.
|
|
967
|
+
animation: prefersReducedMotion ? animationTokensReduced : base.animation
|
|
990
968
|
};
|
|
991
|
-
}, [theme, mode, accentColor]);
|
|
969
|
+
}, [theme, mode, accentColor, prefersReducedMotion]);
|
|
992
970
|
useEffect(() => {
|
|
993
971
|
if (typeof document === "undefined") return;
|
|
994
972
|
const root = document.documentElement;
|
|
995
|
-
const { colors, typography, spacing, borderRadius, animation, focus, shadows } = tokens;
|
|
973
|
+
const { colors, typography: typography2, spacing: spacing2, borderRadius: borderRadius2, animation, focus, shadows } = tokens;
|
|
996
974
|
root.setAttribute("data-theme", mode);
|
|
997
975
|
root.setAttribute("data-variant", theme);
|
|
998
976
|
root.style.setProperty("--color-background-base", colors.background.base);
|
|
@@ -1019,22 +997,22 @@ function ThemeProvider({
|
|
|
1019
997
|
root.style.setProperty("--color-accent-primary", colors.accent.primary);
|
|
1020
998
|
root.style.setProperty("--color-accent-secondary", colors.accent.secondary);
|
|
1021
999
|
root.style.setProperty("--color-accent-tertiary", colors.accent.tertiary);
|
|
1022
|
-
root.style.setProperty("--font-family-heading",
|
|
1023
|
-
root.style.setProperty("--font-family-primary",
|
|
1024
|
-
root.style.setProperty("--font-family-mono",
|
|
1025
|
-
root.style.setProperty("--spacing-xxs",
|
|
1026
|
-
root.style.setProperty("--spacing-xs",
|
|
1027
|
-
root.style.setProperty("--spacing-sm",
|
|
1028
|
-
root.style.setProperty("--spacing-smd",
|
|
1029
|
-
root.style.setProperty("--spacing-md",
|
|
1030
|
-
root.style.setProperty("--spacing-mdl",
|
|
1031
|
-
root.style.setProperty("--spacing-lg",
|
|
1032
|
-
root.style.setProperty("--spacing-xl",
|
|
1033
|
-
root.style.setProperty("--spacing-xxl",
|
|
1034
|
-
root.style.setProperty("--radius-sm",
|
|
1035
|
-
root.style.setProperty("--radius-md",
|
|
1036
|
-
root.style.setProperty("--radius-lg",
|
|
1037
|
-
root.style.setProperty("--radius-xl",
|
|
1000
|
+
root.style.setProperty("--font-family-heading", typography2.fontFamily.heading || typography2.fontFamily.primary);
|
|
1001
|
+
root.style.setProperty("--font-family-primary", typography2.fontFamily.primary);
|
|
1002
|
+
root.style.setProperty("--font-family-mono", typography2.fontFamily.mono);
|
|
1003
|
+
root.style.setProperty("--spacing-xxs", spacing2.xxs);
|
|
1004
|
+
root.style.setProperty("--spacing-xs", spacing2.xs);
|
|
1005
|
+
root.style.setProperty("--spacing-sm", spacing2.sm);
|
|
1006
|
+
root.style.setProperty("--spacing-smd", spacing2.smd);
|
|
1007
|
+
root.style.setProperty("--spacing-md", spacing2.md);
|
|
1008
|
+
root.style.setProperty("--spacing-mdl", spacing2.mdl);
|
|
1009
|
+
root.style.setProperty("--spacing-lg", spacing2.lg);
|
|
1010
|
+
root.style.setProperty("--spacing-xl", spacing2.xl);
|
|
1011
|
+
root.style.setProperty("--spacing-xxl", spacing2.xxl);
|
|
1012
|
+
root.style.setProperty("--radius-sm", borderRadius2.sm);
|
|
1013
|
+
root.style.setProperty("--radius-md", borderRadius2.md);
|
|
1014
|
+
root.style.setProperty("--radius-lg", borderRadius2.lg);
|
|
1015
|
+
root.style.setProperty("--radius-xl", borderRadius2.xl);
|
|
1038
1016
|
const motionMultiplier = prefersReducedMotion ? 0 : 1;
|
|
1039
1017
|
root.style.setProperty("--animation-fast", prefersReducedMotion ? "none" : animation.fast);
|
|
1040
1018
|
root.style.setProperty("--animation-normal", prefersReducedMotion ? "none" : animation.normal);
|
|
@@ -1051,7 +1029,7 @@ function ThemeProvider({
|
|
|
1051
1029
|
root.style.setProperty("--shadow-xl", shadows.xl);
|
|
1052
1030
|
document.body.style.backgroundColor = colors.background.base;
|
|
1053
1031
|
document.body.style.color = colors.text.primary;
|
|
1054
|
-
document.body.style.fontFamily =
|
|
1032
|
+
document.body.style.fontFamily = typography2.fontFamily.primary;
|
|
1055
1033
|
}, [tokens, theme, mode, prefersReducedMotion]);
|
|
1056
1034
|
const scrollbarCSS = useMemo(() => buildScrollbarCSS(tokens, mode, prefersReducedMotion), [tokens, mode, prefersReducedMotion]);
|
|
1057
1035
|
const value = useMemo(
|