@zendir/ui 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/CHANGELOG.md +419 -406
  2. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  3. package/dist/react/3d/ZenSpace3D.js.map +1 -1
  4. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
  5. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
  6. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  7. package/dist/react/3d/capturePngAnalysis.js.map +1 -1
  8. package/dist/react/3d/threeLoader.js.map +1 -1
  9. package/dist/react/astro/ClassificationBanner.js.map +1 -1
  10. package/dist/react/astro/GlobalStatusBar.js.map +1 -1
  11. package/dist/react/astro/MissionClock.js.map +1 -1
  12. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  13. package/dist/react/astro/Notification.js.map +1 -1
  14. package/dist/react/astro/Progress.js.map +1 -1
  15. package/dist/react/astro/SimulationControls.js.map +1 -1
  16. package/dist/react/astro/StatusIndicator.js.map +1 -1
  17. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  18. package/dist/react/cards/AccessCard.js.map +1 -1
  19. package/dist/react/cards/OrbitCard.js.map +1 -1
  20. package/dist/react/cards/SpacecraftCard.js.map +1 -1
  21. package/dist/react/cards/TelemetryCard.js.map +1 -1
  22. package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
  23. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  24. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
  25. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
  26. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
  27. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  28. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
  29. package/dist/react/charts/unified/domain.js.map +1 -1
  30. package/dist/react/charts/unified/generators.js.map +1 -1
  31. package/dist/react/charts/unified/presets.js.map +1 -1
  32. package/dist/react/charts/unified/sync.js.map +1 -1
  33. package/dist/react/charts/unified/theme.js.map +1 -1
  34. package/dist/react/charts/unified/useChartStream.js.map +1 -1
  35. package/dist/react/chatgpt/index.js.map +1 -1
  36. package/dist/react/context/CategoryContext.js.map +1 -1
  37. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  38. package/dist/react/context/SpatialSelectionContext.js.map +1 -1
  39. package/dist/react/core/data/DataTable.js.map +1 -1
  40. package/dist/react/core/data/DataValue.js.map +1 -1
  41. package/dist/react/core/data/propertyConfig.js.map +1 -1
  42. package/dist/react/core/display/AstroIcon.js.map +1 -1
  43. package/dist/react/core/display/Badge.js.map +1 -1
  44. package/dist/react/core/display/CardHeader.js.map +1 -1
  45. package/dist/react/core/display/Container.js.map +1 -1
  46. package/dist/react/core/display/CopyButton.js.map +1 -1
  47. package/dist/react/core/display/GlassCard.js.map +1 -1
  48. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
  49. package/dist/react/core/display/Icon.js.map +1 -1
  50. package/dist/react/core/display/Typography.js.map +1 -1
  51. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
  52. package/dist/react/core/feedback/Dialog.js.map +1 -1
  53. package/dist/react/core/feedback/Toast.js.map +1 -1
  54. package/dist/react/core/inputs/Button.js.map +1 -1
  55. package/dist/react/core/inputs/Checkbox.js.map +1 -1
  56. package/dist/react/core/inputs/Input.js.map +1 -1
  57. package/dist/react/core/inputs/LimitsBar.js.map +1 -1
  58. package/dist/react/core/inputs/NumberInput.js.map +1 -1
  59. package/dist/react/core/inputs/PinInput.js.map +1 -1
  60. package/dist/react/core/inputs/Select.js.map +1 -1
  61. package/dist/react/core/inputs/Toggle.js.map +1 -1
  62. package/dist/react/core/layout/Box.js.map +1 -1
  63. package/dist/react/core/layout/Center.js.map +1 -1
  64. package/dist/react/core/layout/Divider.js.map +1 -1
  65. package/dist/react/core/layout/Flex.js.map +1 -1
  66. package/dist/react/core/layout/Grid.js.map +1 -1
  67. package/dist/react/core/layout/Spacer.js.map +1 -1
  68. package/dist/react/core/layout/Stack.js.map +1 -1
  69. package/dist/react/core/layout/responsive.js.map +1 -1
  70. package/dist/react/core/layout/useBreakpoint.js.map +1 -1
  71. package/dist/react/core/navigation/AppBar.js.map +1 -1
  72. package/dist/react/core/navigation/Pagination.js.map +1 -1
  73. package/dist/react/core/navigation/SideNav.js.map +1 -1
  74. package/dist/react/core/navigation/Tabs.js.map +1 -1
  75. package/dist/react/core/overlays/Popover.js.map +1 -1
  76. package/dist/react/core/overlays/SidePanel.js.map +1 -1
  77. package/dist/react/core/overlays/Tooltip.js.map +1 -1
  78. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
  79. package/dist/react/core/widgets/Capture.js.map +1 -1
  80. package/dist/react/core/widgets/ChatPanel.js.map +1 -1
  81. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
  82. package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
  83. package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
  84. package/dist/react/core/widgets/FileExplorer.js.map +1 -1
  85. package/dist/react/core/widgets/HexViewer.js.map +1 -1
  86. package/dist/react/core/widgets/ImageFrame.js.map +1 -1
  87. package/dist/react/core/widgets/ImageGallery.js.map +1 -1
  88. package/dist/react/core/widgets/ImagePanel.js.map +1 -1
  89. package/dist/react/core/widgets/LogViewer.js.map +1 -1
  90. package/dist/react/core/widgets/MessageStream.js.map +1 -1
  91. package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
  92. package/dist/react/core/widgets/PacketViewer.js.map +1 -1
  93. package/dist/react/hooks/useCompactMode.js.map +1 -1
  94. package/dist/react/hooks/useSimulationScene.js.map +1 -1
  95. package/dist/react/panels/LayerControlPanel.js.map +1 -1
  96. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
  97. package/dist/react/shared/ErrorBoundary.js.map +1 -1
  98. package/dist/react/shared/Skeleton.js.map +1 -1
  99. package/dist/react/theme/ThemeProvider.js +2 -1
  100. package/dist/react/theme/ThemeProvider.js.map +1 -1
  101. package/dist/react/theme/cardAccent.js.map +1 -1
  102. package/dist/react/theme/config.js.map +1 -1
  103. package/dist/react/theme/types.js.map +1 -1
  104. package/dist/react/types.js.map +1 -1
  105. package/dist/react/utils/categoryPalette.js.map +1 -1
  106. package/dist/react/utils/index.js.map +1 -1
  107. package/dist/style.css +216 -216
  108. package/dist/tokens/core.js.map +1 -1
  109. package/dist/tokens/index.js.map +1 -1
  110. package/dist/tokens/palettes/astro.js.map +1 -1
  111. package/dist/tokens/palettes/index.js.map +1 -1
  112. package/dist/tokens/palettes/tailwind.js.map +1 -1
  113. package/dist/tokens/palettes/zendir.js.map +1 -1
  114. package/dist/tokens/themes.js.map +1 -1
  115. package/dist/tokens/tokens.css +533 -533
  116. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,406 +1,419 @@
1
- # @zendir/ui
2
-
3
- ## 0.6.0
4
-
5
- ### Minor Changes
6
-
7
- - **ImageGallery**: new optional `badge` field on `GalleryImage` renders an
8
- overlay pill on thumbnails (e.g. flagging newly downlinked images).
9
- - **ThemeProvider**: explicit `theme`/`mode` props are now authoritative and
10
- no longer overridden by persisted preferences; use `defaultVariant`/
11
- `defaultMode` to opt into localStorage restore.
12
- - New opt-in `nebula` theme (Prussian Slate / Ultraviolet).
13
- - Primitive color scales are now importable from `@zendir/ui/tokens` (Zendir
14
- brand, Astro UXDS status, Tailwind v4.2) and emitted as `--zendir-*` CSS
15
- variables, so product code and charts can reference endorsed palette stops
16
- directly.
17
- - Theme types and palettes extracted into dedicated modules
18
- (`react/theme/types`, `tokens/palettes`, `tokens/core`); public API
19
- unchanged.
20
- - Toolchain security refresh: Vitest 4, Vite 8, Storybook 10 — clears every
21
- outstanding dependency audit advisory (production deps were already clean).
22
-
23
- ## 0.5.0
24
-
25
- ### Minor Changes
26
-
27
- - Add a `stat` variant to `DataValue` for compact top-bar telemetry chips
28
- (value over a small uppercase label, status-tinted).
29
- - Refresh `SideNav` styling and layout.
30
-
31
- ### Patch Changes
32
-
33
- - Harden Popover first-open positioning: seed the panel's position state as
34
- `fixed` and gate visibility on a `positioned` flag that resets on close, so
35
- neither the first open nor any reopen flashes at stale coordinates.
36
-
37
- ## 0.4.1
38
-
39
- ### Patch Changes
40
-
41
- - Fix Popover first-open positioning flash: panel now renders with
42
- `visibility: hidden` until the initial `requestAnimationFrame` resolves
43
- real coordinates, preventing the one-frame misposition on first open.
44
-
45
- ## 0.4.0
46
-
47
- ### Minor Changes
48
-
49
- - Add `ImageFrame` widget: renders a single-channel sensor/CCD data frame
50
- (`number[]` of samples) as a false-colour image on a canvas, with
51
- fixed-ceiling normalisation, `cividis`/`gray` colormaps, an optional raw
52
- value grid, and loading/empty states. Purely presentational — callers
53
- pass the frame data in. Also exports the pure `decodeImage` helper.
54
-
55
- ### Patch Changes
56
-
57
- - Scope the Dialog focus trap to the open transition so typing in a dialog
58
- input isn't interrupted when the surrounding parent re-renders.
59
-
60
- ## 0.3.0
61
-
62
- **Upgrade from npm:** The latest public release on the registry is
63
- [0.2.21](https://www.npmjs.com/package/@zendir/ui). This **0.3.0** release
64
- is the next version on npm and combines the hook / 3D integration work
65
- with the token / `react/core/` architecture pass below.
66
-
67
- This release reframes the React hook layer around a single, well-defined
68
- bridge from `zendir-ts` to the live `<ZenSpace3D />` surface, and
69
- replaces three legacy SDK-coupled hooks with smaller, REST-aligned
70
- primitives. The Cesium backend gains proper sub-satellite ground-track
71
- alignment, and the `ZenSpace3DUtils` helper module is slimmed to only
72
- what the live backends actually consume. It also eliminates token drift
73
- hazards by consolidating literals, auto-generating `tokens.css`, and
74
- reorganising `react/core/` into thematic subfolders.
75
-
76
- ### Features
77
-
78
- - **`useSimulationScene`** primary integration hook
79
- (`@zendir/ui/react/hooks` and `@zendir/ui/react/3d`). Bridges a
80
- `zendir-ts` `ZendirClient` to `ZenSpace3D` props: fetches
81
- `GetSimulationStructure` once, buckets spacecraft / ground stations /
82
- planets, and polls `Position_BN_N` / `Velocity_BN_N` on a configurable
83
- interval (default 2 s). Exports `SimulationSceneClient`,
84
- `SimulationSceneObject`, `StructureDiag`, `PositionTickDiag`, and
85
- `UseSimulationSceneResult` for typed app integration.
86
- - **Operator 3D surface** the hook is intended to drive a full-screen
87
- `ZenSpace3D` in host apps (e.g. `space-range-operator`
88
- `/admin/3d/:containerId/:simulationId`). Feed
89
- `useSimulationScene` with `containerId`, `simulationId`, and the
90
- session `client`.
91
- - **`ZenSpace3DProps.referenceTime`** — new `Date` prop used by the
92
- Cesium backend to convert ECI/J2000 positions into the Earth-Fixed
93
- (ECEF) frame Cesium renders. Passing the simulation clock (sim epoch
94
- + sim seconds) lines the sub-satellite point on Earth up with the
95
- true ground track; omitting it falls back to wall-clock time and the
96
- ground track will drift.
97
- - **Top-level re-exports** — `ZenSpace3D`, `useSimulationScene`, and
98
- their types are now available from the main `@zendir/ui/react`
99
- entry in addition to the `react/3d` and `react/hooks` subpaths.
100
-
101
- ### Breaking Changes
102
-
103
- - **Removed legacy SDK hooks**: `useTelemetry`, `useSpacecraftPosition`,
104
- and `useSimulationTime` no longer exist. Their
105
- responsibilities are covered by `useSimulationScene` (live position /
106
- velocity bucketed onto scene objects) and by the `referenceDate` /
107
- `positionTickDiag` fields on its result.
108
- - **`useAccessWindows` is now pure client-side math**. The Zendir REST
109
- API does not expose a server-side access-prediction endpoint, so the
110
- hook no longer attempts to load `zendir-ts` or fetch passes. It now
111
- accepts a `windows: AccessPass[]` input (compute these with your own
112
- propagator / SGP4 / demo data) and returns `TimerConfig` objects for
113
- `<MissionClock />`. Removed options: `spacecraftId`, `groundStationId`,
114
- `passCount`. Removed result fields: `isConnected`, `isSdkAvailable`,
115
- `error`. The `manualWindows` option is kept as a deprecated alias
116
- for `windows` for one minor.
117
- - **Renames in `useAccessWindows`**: the `AccessWindow` type is now
118
- `AccessPass`, and `createDemoAccessWindows` is now
119
- `createDemoAccessPasses`. Update imports accordingly.
120
- - **`ZenSpace3DUtils` pruned to the live surface**. Unused helpers were
121
- removed: `cartesianToLatLonAlt`, `cartesianToSpherical`,
122
- `sphericalToCartesian`, `eciToEcef`, `calculateGMST`,
123
- `dateToJulianDate`, `parseTLE`, `propagateSGP4Simple`,
124
- `propagateSatellite`, `generateOrbitPath`, `isVisible`,
125
- `calculateVisibilityConeGeometry`, `calculateFootprint`,
126
- `generateHexGrid`, `updateHexGridCoverage`, all vector-math helpers
127
- (`dot`, `cross`, `magnitude`, `normalize`, `subtract`, `add`,
128
- `scale`, `distance`, `lerp`), `easeInOutCubic`, `smoothstep`,
129
- `lerpColor`, `hexToRgb`, `getGradientColor`, `formatDuration`,
130
- `formatDistance`, `formatVelocity`, `formatDateTime`, and the
131
- constants `EARTH_MU`, `AU_KM`, `J2000_EPOCH`. Retained:
132
- `EARTH_RADIUS_KM`, `DEG_TO_RAD`, `RAD_TO_DEG`, `SCENE_EARTH_RADIUS`,
133
- `KM_TO_SCENE`, `latLonAltToCartesian`, `easeOutCubic`. For orbital
134
- mechanics, use a dedicated library (`satellite.js` for SGP4) or
135
- Cesium's built-in transforms; the Three.js path already draws
136
- coverage from the explicit `SatelliteCoverage` props.
137
-
138
- ### Improvements
139
-
140
- - **`useZendirSession`** reworked container + simulation lifecycle
141
- (provision container, poll until `RUNNING`, then create a simulation),
142
- with a new `SessionInfo` export and `preloadZendirSdk` /
143
- `isZendirSdkAvailable` utilities.
144
- - **`ZenSpace3D` Cesium backend** — substantial rework
145
- (`ZenSpace3DCesium.tsx`) so positions streamed in J2000/ECI are
146
- correctly rotated into ECEF each frame using the simulation clock,
147
- keeping the orbit and its ground track visually consistent.
148
- - **`ZenSpace3DTypes` docs** updated SDK-compatibility example to the
149
- new `useSimulationScene` pattern and clarified that coverage geometry
150
- is either explicit (`footprintPolygon` / `halfAngle`) or computed
151
- locally by the viewer.
152
- - **`types.ts`** — clarified that UI-domain types (`Quaternion`,
153
- `Vector3D`, `PointingMode`, etc.) ship with `@zendir/ui` and are not
154
- provided by `zendir-ts` (which is REST-only and intentionally
155
- minimal). Helpers like `estimateOrbitalPeriod` /
156
- `estimateOrbitalVelocity` are documented as client-side approximations.
157
- - **Docs refresh** — `SDKIntegration.mdx`, `ComponentsOverview.mdx`,
158
- and `Introduction.mdx` updated to reflect the `zendir-ts` rename
159
- (previously `@zendir/sdk`) and the new hook surface.
160
-
161
- ### Migration
162
-
163
- ```tsx
164
- // Before (0.2.x)
165
- import { useTelemetry, useSpacecraftPosition, useSimulationTime } from '@zendir/ui/react/hooks';
166
-
167
- // After (0.3.0)
168
- import { useSimulationScene } from '@zendir/ui/react/hooks';
169
-
170
- const scene = useSimulationScene({ client, containerId, simulationId });
171
- // scene.satellites, scene.groundStations, scene.referenceDate, scene.positionTickDiag
172
- ```
173
-
174
- ```tsx
175
- // Before (0.2.x)
176
- import { useAccessWindows, createDemoAccessWindows, AccessWindow } from '@zendir/ui/react/hooks';
177
-
178
- const { aosTimer, losTimer } = useAccessWindows({
179
- spacecraftId: 'my-sat',
180
- groundStationId: 'gs-1',
181
- });
182
-
183
- // After (0.3.0)
184
- import { useAccessWindows, createDemoAccessPasses, AccessPass } from '@zendir/ui/react/hooks';
185
-
186
- const passes: AccessPass[] = computePasses(satellite, groundStation); // your propagator
187
- const { aosTimer, losTimer } = useAccessWindows({ windows: passes });
188
- ```
189
-
190
- ### Notes
191
-
192
- - Consumer apps that use a published tarball should depend on
193
- `"@zendir/ui": "^0.3.0"`. Monorepo/local development can keep
194
- `"@zendir/ui": "file:../zendir-ui"`.
195
- - After `npm publish` in this package, run `npm install` in consuming
196
- apps to pick up 0.3.0 (no automatic push; release is manual).
197
-
198
-
199
- ### Architecture `core/` reorganised
200
-
201
- The 42-file flat `react/core/` folder is split into thematic subfolders:
202
- `inputs/`, `feedback/`, `overlays/`, `navigation/`, `data/`, `display/`,
203
- `widgets/` (alongside the existing `layout/`).
204
-
205
- - The `core/index.ts` barrel still exports everything by name. Consumers
206
- using `import { Button } from '@zendir/ui'` or `from '@zendir/ui/react/core'`
207
- are unaffected.
208
- - Deep imports like `from '@zendir/ui/react/core/Button'` now resolve via
209
- the new path; if you have these, switch to the barrel for stability.
210
-
211
- ### Theme + a11y
212
-
213
- - **JS-side `tokens.animation.*` honours `prefers-reduced-motion`.**
214
- The global CSS @media rule already stripped CSS animations; this
215
- extends the same behaviour to the JS-side tokens surface so animation
216
- libraries (Framer Motion etc.) reading `tokens.animation.fast` get
217
- collapsed values too.
218
-
219
-
220
- ### Removed
221
-
222
- - Legacy `EarthViewer` and `SolarSystemViewer` 3D components (~1.6k LOC
223
- of dead code; superseded by `ZenSpace3D`).
224
- - Deprecated `ChatGPTCard` alias (use `AppCard`) and `useIntrinsicHeight`
225
- no-op hook (use `useMaxHeight`).
226
- - `scripts/build-tokens.js` (had its own duplicate token literal —
227
- replaced by `build-tokens.ts` that imports from `tokens/index.ts`).
228
-
229
- ### Internal
230
-
231
- - `src/react/core/` reorganised — see "Architecture" above.
232
- - Operator and dashboard verified working with new structure.
233
- - **Toolchain** — ESLint 9 flat config (`eslint.config.js`), `typescript-eslint` v8,
234
- Vitest 2.1 + Vite 5.4; `npm audit fix -w @zendir/ui --legacy-peer-deps` at monorepo
235
- root to clear hoisted dev CVEs without `--force` onto Vite 8. Storybook 8
236
- `eslint-plugin-storybook` rules removed until Storybook 10+ (plugin v0.8 uses
237
- APIs dropped in ESLint 9).
238
- - 284/284 tests pass; typecheck clean; build clean.
239
-
240
- ---
241
-
242
- ## 0.2.21
243
-
244
- ### Improvements
245
-
246
- - **SidePanel**: Fixed sudden layout shift when opening/closing width animates from `0px` smoothly during the `opening` phase (previously snapped to full width instantly, causing the flex layout to jump). Closing transition no longer drops width to `0px` instantly while the panel is still sliding out.
247
- - **SidePanel**: Slowed transitions from `0.5s` to `0.6s` and switched to a calmer `cubic-bezier(0.2, 0.8, 0.2, 1)` ease curve for a smoother, less jarring feel — based on UX research showing 500–600ms with deceleration easing reads as "calm" without feeling sluggish.
248
-
249
- ---
250
-
251
- ## 0.2.20
252
-
253
- ### Improvements
254
-
255
- - **SidePanel**: Smoother open/close animation — CSS transitions increased from 0.3s to 0.5s with matched JavaScript timing (550ms closing timeout) to prevent premature unmount during slide-out.
256
-
257
- ---
258
-
259
- ## 0.2.5
260
-
261
- ### Bug Fixes
262
-
263
- - **Container**: Fixed `[object Object]` rendering when `subtitle` is a React element. Non-string subtitles (JSX) are now rendered directly below the `CardHeader` instead of being coerced via `String()`.
264
-
265
- ---
266
-
267
- ## 0.2.4
268
-
269
- ### Features
270
-
271
- #### GroundTrackMap — Layers Panel
272
-
273
- - **Layers icon + dropdown panel** — the top-right control bar now shows a stacked-diamond icon that opens a clean dropdown panel with two sections: **Base Map** (Dark/Satellite radio) and **Overlays** (toggle switches for Day/Night terminator, Grid Lines, and custom layers).
274
- - **Custom layers API** — pass `customLayers: MapLayerDef[]` to add your own toggle items to the Overlays section. The map provides the toggle UI; the consumer app renders its own overlay content via `onLayerChange(layerId, enabled)`.
275
- - **Persistent tile style** — Dark/Satellite choice is saved to `localStorage` and restored across tabs and page reloads.
276
- - **Unified control bar** Recenter, Layers, and Zoom (+/−) are now a single horizontal row at top-right, replacing both the old separate controls and Leaflet's native zoom.
277
- - **Runtime overlay toggling** — built-in overlays (Terminator, Grid) can now be toggled on/off at runtime from the Layers panel without remounting the map.
278
-
279
- ### Breaking Changes
280
-
281
- - `showMapStyleToggle` prop is still accepted but now controls whether the "Base Map" section appears in the Layers panel (default `true`).
282
- - Leaflet's native zoom controls have been replaced by custom-styled buttons matching the Astro UXDS dark ops aesthetic.
283
-
284
- ### Documentation
285
-
286
- - **LayersPanel** story demonstrates the full layers panel with base map toggle and overlay switches.
287
- - **CustomLayers** story shows how to add developer-defined overlay toggles with `MapLayerDef[]` and respond via `onLayerChange`.
288
-
289
- ---
290
-
291
- ## 0.2.3
292
-
293
- ### Features
294
-
295
- #### GroundTrackMap Map Style Toggle
296
-
297
- - **Built-in Dark / Satellite tile switcher** — when no explicit `tileUrl` is passed, a compact toggle appears below the Leaflet zoom controls allowing operators to switch between Dark (CartoDB) and Satellite (Esri World Imagery) tile layers.
298
- - **No-flash tile swap** — toggling swaps only the tile layer without recreating the Leaflet map, preserving the current zoom, pan, and overlay state.
299
- - **`showMapStyleToggle` prop** — defaults to `true`. Set to `false` to hide the toggle. Automatically hidden when an explicit `tileUrl` is provided (backward compatible).
300
- - **`TILE_PRESETS`**exported preset URLs (`dark`, `satellite`, `light`) for quick tile configuration.
301
-
302
- #### GroundTrackMap — Terminator Boundary Line
303
-
304
- - **Geometric terminator line** — a subtle dashed line at the 0° solar depression boundary (geometric sunset/sunrise) is now drawn on both Canvas and Leaflet backends, giving a clear visual reference for the day/night edge while the graduated fade provides the realistic transition.
305
-
306
- #### UnifiedTimeline — Playhead Auto-Follow
307
-
308
- - **Auto-scroll to playhead** when the playhead marker moves near the edge of the visible chart viewport, the view auto-scrolls to keep it centered. Throttled at 300ms to avoid fighting user scrolling.
309
- - **Smooth playhead animation** — the playhead line now uses a CSS transition (`left 0.4s linear`) for glide-smooth movement between position updates.
310
-
311
- ### Documentation
312
-
313
- - **Map Style Toggle** story demonstrates the built-in tile switcher with a satellite track and terminator, including opt-out patterns.
314
- - Updated component description with Map Style Toggle feature.
315
-
316
- ### Internal
317
-
318
- - Refactored tile layer lifecycle in `GroundTrackMapLeaflet` — tile creation is now a separate effect from map initialization, enabling smooth in-place tile swaps.
319
- - **Fixed duplicate tile layer on mount** the initial mount effect no longer creates a tile layer; the dedicated tile-swap effect is solely responsible, eliminating z-order conflicts that caused the terminator overlay to render behind tiles.
320
- - **Attribution management** — tile swap effect now properly adds/removes Carto vs OSM attribution when switching tile styles.
321
- - Map controls repositioned to bottom-left for reliable visibility across container sizes.
322
-
323
- ---
324
-
325
- ## 0.2.2
326
-
327
- ### Features
328
-
329
- #### GroundTrackMap — Night Visualization
330
-
331
- - **Seamless night polygon** completely rewritten terminator geometry: sunset/sunrise curves are now computed as continuous longitude pairs, producing a single closed polygon with no antimeridian artifacts. Eliminates all "jerk" lines and rendering glitches at the poles.
332
- - **`nightTileUrl` prop** — optional second tile layer (e.g. NASA Black Marble, VIIRS city lights) rendered beneath the terminator overlay. The graduated twilight gradient naturally masks the day-to-night tile transition. Leaflet backend only.
333
- - **`lightSources` prop** — array of point light sources (`LightSource` interface) rendered as soft glow dots on the night side of the map. Each light is masked by the terminator: invisible in daylight, fading in through twilight, full brightness at night. Supports custom colors, radii, intensity, and labels.
334
- - **Solar elevation masking** light source visibility is computed per-point using the exact solar elevation angle (not polygon containment), giving a smooth and physically correct twilight fade for each individual light.
335
-
336
- ### Documentation
337
-
338
- - **City Lights at Night** story — 35+ world cities as `lightSources`, demonstrating realistic nighttime glow.
339
- - **City Lights Time Travel** story — interactive UTC hour slider showing lights switching on/off as the terminator sweeps.
340
- - **Custom Light Sources** story — mission scenario with colored RF emitters, bases, and relay nodes.
341
- - **Night Tile Layer** story — demonstrates `nightTileUrl` combined with `lightSources`.
342
- - Updated component description with Night Tile Layer and Dynamic Light Sources sections.
343
-
344
- ### Bug Fixes
345
-
346
- - Fixed terminator night polygon antimeridian wrapping sunset and sunrise curves are now generated as continuous coordinate pairs (no `lon ± 180` mirroring), preventing the polygon from crossing the day side.
347
- - Removed unused `buildBandPolygon` function from Leaflet backend.
348
-
349
- ---
350
-
351
- ## 0.2.0
352
-
353
- ### Features
354
-
355
- #### SDK Category System (New)
356
- - **`CategoryDef`** — shared interface for a named, colored data category (`id`, `color`, `label?`), used across Timeline, GroundTrackMap, and any future component.
357
- - **`CategoryPalette`** — utility class that maps category IDs to stable colors and labels, with built-in fallback palettes for auto-assignment.
358
- - **`CategoryProvider` / `useCategoryPalette`** — optional React Context for sharing a `CategoryPalette` and a custom display label (e.g. "Squad", "Division") across an entire dashboard. Fully opt-in; components work standalone without it.
359
- - New Storybook documentation page (`SDK Category Concept`) with interactive examples, architecture diagrams, and integration guidance.
360
-
361
- #### UnifiedTimeline
362
- - **Team / category-aware events** — events now carry structured team identity (`id`, `color`, `label?`), enabling category-colored event bars and badges.
363
- - **Multi-select team filter** — replaces the former boolean `teamColoredOnly` toggle; users can filter by specific teams via pill-style checkboxes.
364
- - **`teamLabel` prop** — devs can rename "Team" to any domain-specific term (e.g. "Squad", "Division"); also readable from `CategoryProvider` context.
365
- - **Day markers** — `showDayMarkers` draws labeled day boundaries on multi-day timelines.
366
- - **Redesigned filter bar** — collapsible panel with Astro UX filter icon, search field moved to top header row, responsive breakpoints.
367
- - **Performance** — bounding-box culling for `ChartView` events outside the visible viewport.
368
-
369
- #### GroundTrackMap
370
- - **Twilight terminator with gradient zones** realistic Civil / Nautical / Astronomical / Full Night shading derived from solar depression angle, replacing the former hard-edge day/night line. Uses `depressionDeg` for precise boundaries.
371
- - **Collaborative pins**new `MapPin` interface and `pins` / `pinsEditable` / `onPinAdd` / `onPinUpdate` / `onPinRemove` props for placing colored points-of-interest synced across terminals.
372
- - **Enhanced satellite visualization** `showFootprint` / `footprintRadius` for sensor coverage circles, `futureTrackIndex` for solid-past / dashed-future track split, `passMarkers` for AOS/LOS diamonds.
373
- - **Ground station antenna icons** — `dish`, `phased-array`, `omni`, and `relay` icon types with coverage circles and Astro status colors.
374
- - **Legend overlay** — auto-generated satellite + ground station legend with status indicators.
375
- - Category-aware pin colors via `CategoryProvider` integration.
376
-
377
- #### SimulationControls
378
- - Increased control-button background opacities for better visibility on dark themes.
379
-
380
- ### Documentation
381
- - Comprehensive Storybook updates for Timeline (`WithCategoryProvider`, `MultiDayWithCategories` stories) and GroundTrackMap (`SDK Category Integration` section).
382
- - New `CategoryConcept` Storybook page with `PaletteBasics`, `ProviderAndHook`, and `DynamicCategories` interactive stories.
383
-
384
- ### Breaking Changes
385
- - `TimelineEvent.color` replaced by `TimelineEvent.team` (`TimelineTeam` / `CategoryDef`). Plain string colors are still accepted for backward compatibility but are treated as legacy entries.
386
- - `TimelineFilter.teamColoredOnly` replaced by `TimelineFilter.teams` (multi-select `string[]`).
387
-
388
- ---
389
-
390
- ## 0.1.0
391
-
392
- Initial public release.
393
-
394
- ### Features
395
-
396
- - 60+ React components for space, air, land, and maritime operations
397
- - Built on Astro UX Design System
398
- - Themeable (Zen, Hybrid, Astro, Glass) with dark/light mode
399
- - ECharts-based charting (line, area, bar, radar, treemap, sankey, and more)
400
- - 3D viewers (Earth, Solar System, ZenSpace3D) via Three.js
401
- - Ground track maps (Leaflet and canvas backends)
402
- - Mission control widgets (MissionClock, SimulationControls, UnifiedTimeline)
403
- - Layout primitives (Box, Flex, Grid, Stack, Container, SideNav, SidePanel)
404
- - Accessibility-first (WCAG 2.2 AA oriented)
405
- - Design tokens as JS objects and CSS custom properties
406
- - Optional `zendir-ts` (Zendir TypeScript SDK) integration with graceful fallback
1
+ # @zendir/ui
2
+
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - **ThemeProvider**: set the theme variant on `data-theme` and the mode on
8
+ `data-mode` (previously `data-theme` carried the mode and the variant went
9
+ to the unused `data-variant`). The generated `tokens.css` keys its blocks on
10
+ `[data-theme="<variant>"]` / `[data-mode="light"]`, so the mismatch meant the
11
+ static `--zendir-*` CSS variables always resolved to the default (hybrid)
12
+ block non-hybrid variants (nebula, astro, purple-hue) only themed via
13
+ `useThemeTokens()`, not via CSS variables. CSS-variable consumers now get the
14
+ selected variant. `data-variant` is retained for backward compatibility.
15
+
16
+ ## 0.6.0
17
+
18
+ ### Minor Changes
19
+
20
+ - **ImageGallery**: new optional `badge` field on `GalleryImage` renders an
21
+ overlay pill on thumbnails (e.g. flagging newly downlinked images).
22
+ - **ThemeProvider**: explicit `theme`/`mode` props are now authoritative and
23
+ no longer overridden by persisted preferences; use `defaultVariant`/
24
+ `defaultMode` to opt into localStorage restore.
25
+ - New opt-in `nebula` theme (Prussian Slate / Ultraviolet).
26
+ - Primitive color scales are now importable from `@zendir/ui/tokens` (Zendir
27
+ brand, Astro UXDS status, Tailwind v4.2) and emitted as `--zendir-*` CSS
28
+ variables, so product code and charts can reference endorsed palette stops
29
+ directly.
30
+ - Theme types and palettes extracted into dedicated modules
31
+ (`react/theme/types`, `tokens/palettes`, `tokens/core`); public API
32
+ unchanged.
33
+ - Toolchain security refresh: Vitest 4, Vite 8, Storybook 10 — clears every
34
+ outstanding dependency audit advisory (production deps were already clean).
35
+
36
+ ## 0.5.0
37
+
38
+ ### Minor Changes
39
+
40
+ - Add a `stat` variant to `DataValue` for compact top-bar telemetry chips
41
+ (value over a small uppercase label, status-tinted).
42
+ - Refresh `SideNav` styling and layout.
43
+
44
+ ### Patch Changes
45
+
46
+ - Harden Popover first-open positioning: seed the panel's position state as
47
+ `fixed` and gate visibility on a `positioned` flag that resets on close, so
48
+ neither the first open nor any reopen flashes at stale coordinates.
49
+
50
+ ## 0.4.1
51
+
52
+ ### Patch Changes
53
+
54
+ - Fix Popover first-open positioning flash: panel now renders with
55
+ `visibility: hidden` until the initial `requestAnimationFrame` resolves
56
+ real coordinates, preventing the one-frame misposition on first open.
57
+
58
+ ## 0.4.0
59
+
60
+ ### Minor Changes
61
+
62
+ - Add `ImageFrame` widget: renders a single-channel sensor/CCD data frame
63
+ (`number[]` of samples) as a false-colour image on a canvas, with
64
+ fixed-ceiling normalisation, `cividis`/`gray` colormaps, an optional raw
65
+ value grid, and loading/empty states. Purely presentational — callers
66
+ pass the frame data in. Also exports the pure `decodeImage` helper.
67
+
68
+ ### Patch Changes
69
+
70
+ - Scope the Dialog focus trap to the open transition so typing in a dialog
71
+ input isn't interrupted when the surrounding parent re-renders.
72
+
73
+ ## 0.3.0
74
+
75
+ **Upgrade from npm:** The latest public release on the registry is
76
+ [0.2.21](https://www.npmjs.com/package/@zendir/ui). This **0.3.0** release
77
+ is the next version on npm and combines the hook / 3D integration work
78
+ with the token / `react/core/` architecture pass below.
79
+
80
+ This release reframes the React hook layer around a single, well-defined
81
+ bridge from `zendir-ts` to the live `<ZenSpace3D />` surface, and
82
+ replaces three legacy SDK-coupled hooks with smaller, REST-aligned
83
+ primitives. The Cesium backend gains proper sub-satellite ground-track
84
+ alignment, and the `ZenSpace3DUtils` helper module is slimmed to only
85
+ what the live backends actually consume. It also eliminates token drift
86
+ hazards by consolidating literals, auto-generating `tokens.css`, and
87
+ reorganising `react/core/` into thematic subfolders.
88
+
89
+ ### Features
90
+
91
+ - **`useSimulationScene`** — primary integration hook
92
+ (`@zendir/ui/react/hooks` and `@zendir/ui/react/3d`). Bridges a
93
+ `zendir-ts` `ZendirClient` to `ZenSpace3D` props: fetches
94
+ `GetSimulationStructure` once, buckets spacecraft / ground stations /
95
+ planets, and polls `Position_BN_N` / `Velocity_BN_N` on a configurable
96
+ interval (default 2 s). Exports `SimulationSceneClient`,
97
+ `SimulationSceneObject`, `StructureDiag`, `PositionTickDiag`, and
98
+ `UseSimulationSceneResult` for typed app integration.
99
+ - **Operator 3D surface** the hook is intended to drive a full-screen
100
+ `ZenSpace3D` in host apps (e.g. `space-range-operator`
101
+ `/admin/3d/:containerId/:simulationId`). Feed
102
+ `useSimulationScene` with `containerId`, `simulationId`, and the
103
+ session `client`.
104
+ - **`ZenSpace3DProps.referenceTime`** — new `Date` prop used by the
105
+ Cesium backend to convert ECI/J2000 positions into the Earth-Fixed
106
+ (ECEF) frame Cesium renders. Passing the simulation clock (sim epoch
107
+ + sim seconds) lines the sub-satellite point on Earth up with the
108
+ true ground track; omitting it falls back to wall-clock time and the
109
+ ground track will drift.
110
+ - **Top-level re-exports** `ZenSpace3D`, `useSimulationScene`, and
111
+ their types are now available from the main `@zendir/ui/react`
112
+ entry in addition to the `react/3d` and `react/hooks` subpaths.
113
+
114
+ ### Breaking Changes
115
+
116
+ - **Removed legacy SDK hooks**: `useTelemetry`, `useSpacecraftPosition`,
117
+ and `useSimulationTime` no longer exist. Their
118
+ responsibilities are covered by `useSimulationScene` (live position /
119
+ velocity bucketed onto scene objects) and by the `referenceDate` /
120
+ `positionTickDiag` fields on its result.
121
+ - **`useAccessWindows` is now pure client-side math**. The Zendir REST
122
+ API does not expose a server-side access-prediction endpoint, so the
123
+ hook no longer attempts to load `zendir-ts` or fetch passes. It now
124
+ accepts a `windows: AccessPass[]` input (compute these with your own
125
+ propagator / SGP4 / demo data) and returns `TimerConfig` objects for
126
+ `<MissionClock />`. Removed options: `spacecraftId`, `groundStationId`,
127
+ `passCount`. Removed result fields: `isConnected`, `isSdkAvailable`,
128
+ `error`. The `manualWindows` option is kept as a deprecated alias
129
+ for `windows` for one minor.
130
+ - **Renames in `useAccessWindows`**: the `AccessWindow` type is now
131
+ `AccessPass`, and `createDemoAccessWindows` is now
132
+ `createDemoAccessPasses`. Update imports accordingly.
133
+ - **`ZenSpace3DUtils` pruned to the live surface**. Unused helpers were
134
+ removed: `cartesianToLatLonAlt`, `cartesianToSpherical`,
135
+ `sphericalToCartesian`, `eciToEcef`, `calculateGMST`,
136
+ `dateToJulianDate`, `parseTLE`, `propagateSGP4Simple`,
137
+ `propagateSatellite`, `generateOrbitPath`, `isVisible`,
138
+ `calculateVisibilityConeGeometry`, `calculateFootprint`,
139
+ `generateHexGrid`, `updateHexGridCoverage`, all vector-math helpers
140
+ (`dot`, `cross`, `magnitude`, `normalize`, `subtract`, `add`,
141
+ `scale`, `distance`, `lerp`), `easeInOutCubic`, `smoothstep`,
142
+ `lerpColor`, `hexToRgb`, `getGradientColor`, `formatDuration`,
143
+ `formatDistance`, `formatVelocity`, `formatDateTime`, and the
144
+ constants `EARTH_MU`, `AU_KM`, `J2000_EPOCH`. Retained:
145
+ `EARTH_RADIUS_KM`, `DEG_TO_RAD`, `RAD_TO_DEG`, `SCENE_EARTH_RADIUS`,
146
+ `KM_TO_SCENE`, `latLonAltToCartesian`, `easeOutCubic`. For orbital
147
+ mechanics, use a dedicated library (`satellite.js` for SGP4) or
148
+ Cesium's built-in transforms; the Three.js path already draws
149
+ coverage from the explicit `SatelliteCoverage` props.
150
+
151
+ ### Improvements
152
+
153
+ - **`useZendirSession`** reworked container + simulation lifecycle
154
+ (provision container, poll until `RUNNING`, then create a simulation),
155
+ with a new `SessionInfo` export and `preloadZendirSdk` /
156
+ `isZendirSdkAvailable` utilities.
157
+ - **`ZenSpace3D` Cesium backend** — substantial rework
158
+ (`ZenSpace3DCesium.tsx`) so positions streamed in J2000/ECI are
159
+ correctly rotated into ECEF each frame using the simulation clock,
160
+ keeping the orbit and its ground track visually consistent.
161
+ - **`ZenSpace3DTypes` docs** — updated SDK-compatibility example to the
162
+ new `useSimulationScene` pattern and clarified that coverage geometry
163
+ is either explicit (`footprintPolygon` / `halfAngle`) or computed
164
+ locally by the viewer.
165
+ - **`types.ts`** clarified that UI-domain types (`Quaternion`,
166
+ `Vector3D`, `PointingMode`, etc.) ship with `@zendir/ui` and are not
167
+ provided by `zendir-ts` (which is REST-only and intentionally
168
+ minimal). Helpers like `estimateOrbitalPeriod` /
169
+ `estimateOrbitalVelocity` are documented as client-side approximations.
170
+ - **Docs refresh** `SDKIntegration.mdx`, `ComponentsOverview.mdx`,
171
+ and `Introduction.mdx` updated to reflect the `zendir-ts` rename
172
+ (previously `@zendir/sdk`) and the new hook surface.
173
+
174
+ ### Migration
175
+
176
+ ```tsx
177
+ // Before (0.2.x)
178
+ import { useTelemetry, useSpacecraftPosition, useSimulationTime } from '@zendir/ui/react/hooks';
179
+
180
+ // After (0.3.0)
181
+ import { useSimulationScene } from '@zendir/ui/react/hooks';
182
+
183
+ const scene = useSimulationScene({ client, containerId, simulationId });
184
+ // scene.satellites, scene.groundStations, scene.referenceDate, scene.positionTickDiag
185
+ ```
186
+
187
+ ```tsx
188
+ // Before (0.2.x)
189
+ import { useAccessWindows, createDemoAccessWindows, AccessWindow } from '@zendir/ui/react/hooks';
190
+
191
+ const { aosTimer, losTimer } = useAccessWindows({
192
+ spacecraftId: 'my-sat',
193
+ groundStationId: 'gs-1',
194
+ });
195
+
196
+ // After (0.3.0)
197
+ import { useAccessWindows, createDemoAccessPasses, AccessPass } from '@zendir/ui/react/hooks';
198
+
199
+ const passes: AccessPass[] = computePasses(satellite, groundStation); // your propagator
200
+ const { aosTimer, losTimer } = useAccessWindows({ windows: passes });
201
+ ```
202
+
203
+ ### Notes
204
+
205
+ - Consumer apps that use a published tarball should depend on
206
+ `"@zendir/ui": "^0.3.0"`. Monorepo/local development can keep
207
+ `"@zendir/ui": "file:../zendir-ui"`.
208
+ - After `npm publish` in this package, run `npm install` in consuming
209
+ apps to pick up 0.3.0 (no automatic push; release is manual).
210
+
211
+
212
+ ### Architecture — `core/` reorganised
213
+
214
+ The 42-file flat `react/core/` folder is split into thematic subfolders:
215
+ `inputs/`, `feedback/`, `overlays/`, `navigation/`, `data/`, `display/`,
216
+ `widgets/` (alongside the existing `layout/`).
217
+
218
+ - The `core/index.ts` barrel still exports everything by name. Consumers
219
+ using `import { Button } from '@zendir/ui'` or `from '@zendir/ui/react/core'`
220
+ are unaffected.
221
+ - Deep imports like `from '@zendir/ui/react/core/Button'` now resolve via
222
+ the new path; if you have these, switch to the barrel for stability.
223
+
224
+ ### Theme + a11y
225
+
226
+ - **JS-side `tokens.animation.*` honours `prefers-reduced-motion`.**
227
+ The global CSS @media rule already stripped CSS animations; this
228
+ extends the same behaviour to the JS-side tokens surface so animation
229
+ libraries (Framer Motion etc.) reading `tokens.animation.fast` get
230
+ collapsed values too.
231
+
232
+
233
+ ### Removed
234
+
235
+ - Legacy `EarthViewer` and `SolarSystemViewer` 3D components (~1.6k LOC
236
+ of dead code; superseded by `ZenSpace3D`).
237
+ - Deprecated `ChatGPTCard` alias (use `AppCard`) and `useIntrinsicHeight`
238
+ no-op hook (use `useMaxHeight`).
239
+ - `scripts/build-tokens.js` (had its own duplicate token literal —
240
+ replaced by `build-tokens.ts` that imports from `tokens/index.ts`).
241
+
242
+ ### Internal
243
+
244
+ - `src/react/core/` reorganised — see "Architecture" above.
245
+ - Operator and dashboard verified working with new structure.
246
+ - **Toolchain**ESLint 9 flat config (`eslint.config.js`), `typescript-eslint` v8,
247
+ Vitest 2.1 + Vite 5.4; `npm audit fix -w @zendir/ui --legacy-peer-deps` at monorepo
248
+ root to clear hoisted dev CVEs without `--force` onto Vite 8. Storybook 8
249
+ `eslint-plugin-storybook` rules removed until Storybook 10+ (plugin v0.8 uses
250
+ APIs dropped in ESLint 9).
251
+ - 284/284 tests pass; typecheck clean; build clean.
252
+
253
+ ---
254
+
255
+ ## 0.2.21
256
+
257
+ ### Improvements
258
+
259
+ - **SidePanel**: Fixed sudden layout shift when opening/closing — width animates from `0px` smoothly during the `opening` phase (previously snapped to full width instantly, causing the flex layout to jump). Closing transition no longer drops width to `0px` instantly while the panel is still sliding out.
260
+ - **SidePanel**: Slowed transitions from `0.5s` to `0.6s` and switched to a calmer `cubic-bezier(0.2, 0.8, 0.2, 1)` ease curve for a smoother, less jarring feel — based on UX research showing 500–600ms with deceleration easing reads as "calm" without feeling sluggish.
261
+
262
+ ---
263
+
264
+ ## 0.2.20
265
+
266
+ ### Improvements
267
+
268
+ - **SidePanel**: Smoother open/close animation — CSS transitions increased from 0.3s to 0.5s with matched JavaScript timing (550ms closing timeout) to prevent premature unmount during slide-out.
269
+
270
+ ---
271
+
272
+ ## 0.2.5
273
+
274
+ ### Bug Fixes
275
+
276
+ - **Container**: Fixed `[object Object]` rendering when `subtitle` is a React element. Non-string subtitles (JSX) are now rendered directly below the `CardHeader` instead of being coerced via `String()`.
277
+
278
+ ---
279
+
280
+ ## 0.2.4
281
+
282
+ ### Features
283
+
284
+ #### GroundTrackMap — Layers Panel
285
+
286
+ - **Layers icon + dropdown panel** — the top-right control bar now shows a stacked-diamond icon that opens a clean dropdown panel with two sections: **Base Map** (Dark/Satellite radio) and **Overlays** (toggle switches for Day/Night terminator, Grid Lines, and custom layers).
287
+ - **Custom layers API** — pass `customLayers: MapLayerDef[]` to add your own toggle items to the Overlays section. The map provides the toggle UI; the consumer app renders its own overlay content via `onLayerChange(layerId, enabled)`.
288
+ - **Persistent tile style** — Dark/Satellite choice is saved to `localStorage` and restored across tabs and page reloads.
289
+ - **Unified control bar** — Recenter, Layers, and Zoom (+/−) are now a single horizontal row at top-right, replacing both the old separate controls and Leaflet's native zoom.
290
+ - **Runtime overlay toggling** — built-in overlays (Terminator, Grid) can now be toggled on/off at runtime from the Layers panel without remounting the map.
291
+
292
+ ### Breaking Changes
293
+
294
+ - `showMapStyleToggle` prop is still accepted but now controls whether the "Base Map" section appears in the Layers panel (default `true`).
295
+ - Leaflet's native zoom controls have been replaced by custom-styled buttons matching the Astro UXDS dark ops aesthetic.
296
+
297
+ ### Documentation
298
+
299
+ - **LayersPanel** story demonstrates the full layers panel with base map toggle and overlay switches.
300
+ - **CustomLayers** story shows how to add developer-defined overlay toggles with `MapLayerDef[]` and respond via `onLayerChange`.
301
+
302
+ ---
303
+
304
+ ## 0.2.3
305
+
306
+ ### Features
307
+
308
+ #### GroundTrackMapMap Style Toggle
309
+
310
+ - **Built-in Dark / Satellite tile switcher** — when no explicit `tileUrl` is passed, a compact toggle appears below the Leaflet zoom controls allowing operators to switch between Dark (CartoDB) and Satellite (Esri World Imagery) tile layers.
311
+ - **No-flash tile swap** — toggling swaps only the tile layer without recreating the Leaflet map, preserving the current zoom, pan, and overlay state.
312
+ - **`showMapStyleToggle` prop** — defaults to `true`. Set to `false` to hide the toggle. Automatically hidden when an explicit `tileUrl` is provided (backward compatible).
313
+ - **`TILE_PRESETS`**exported preset URLs (`dark`, `satellite`, `light`) for quick tile configuration.
314
+
315
+ #### GroundTrackMap — Terminator Boundary Line
316
+
317
+ - **Geometric terminator line** — a subtle dashed line at the 0° solar depression boundary (geometric sunset/sunrise) is now drawn on both Canvas and Leaflet backends, giving a clear visual reference for the day/night edge while the graduated fade provides the realistic transition.
318
+
319
+ #### UnifiedTimelinePlayhead Auto-Follow
320
+
321
+ - **Auto-scroll to playhead** when the playhead marker moves near the edge of the visible chart viewport, the view auto-scrolls to keep it centered. Throttled at 300ms to avoid fighting user scrolling.
322
+ - **Smooth playhead animation** — the playhead line now uses a CSS transition (`left 0.4s linear`) for glide-smooth movement between position updates.
323
+
324
+ ### Documentation
325
+
326
+ - **Map Style Toggle** story — demonstrates the built-in tile switcher with a satellite track and terminator, including opt-out patterns.
327
+ - Updated component description with Map Style Toggle feature.
328
+
329
+ ### Internal
330
+
331
+ - Refactored tile layer lifecycle in `GroundTrackMapLeaflet` tile creation is now a separate effect from map initialization, enabling smooth in-place tile swaps.
332
+ - **Fixed duplicate tile layer on mount** — the initial mount effect no longer creates a tile layer; the dedicated tile-swap effect is solely responsible, eliminating z-order conflicts that caused the terminator overlay to render behind tiles.
333
+ - **Attribution management** — tile swap effect now properly adds/removes Carto vs OSM attribution when switching tile styles.
334
+ - Map controls repositioned to bottom-left for reliable visibility across container sizes.
335
+
336
+ ---
337
+
338
+ ## 0.2.2
339
+
340
+ ### Features
341
+
342
+ #### GroundTrackMap Night Visualization
343
+
344
+ - **Seamless night polygon** — completely rewritten terminator geometry: sunset/sunrise curves are now computed as continuous longitude pairs, producing a single closed polygon with no antimeridian artifacts. Eliminates all "jerk" lines and rendering glitches at the poles.
345
+ - **`nightTileUrl` prop** — optional second tile layer (e.g. NASA Black Marble, VIIRS city lights) rendered beneath the terminator overlay. The graduated twilight gradient naturally masks the day-to-night tile transition. Leaflet backend only.
346
+ - **`lightSources` prop** array of point light sources (`LightSource` interface) rendered as soft glow dots on the night side of the map. Each light is masked by the terminator: invisible in daylight, fading in through twilight, full brightness at night. Supports custom colors, radii, intensity, and labels.
347
+ - **Solar elevation masking** light source visibility is computed per-point using the exact solar elevation angle (not polygon containment), giving a smooth and physically correct twilight fade for each individual light.
348
+
349
+ ### Documentation
350
+
351
+ - **City Lights at Night** story — 35+ world cities as `lightSources`, demonstrating realistic nighttime glow.
352
+ - **City Lights Time Travel** story — interactive UTC hour slider showing lights switching on/off as the terminator sweeps.
353
+ - **Custom Light Sources** story — mission scenario with colored RF emitters, bases, and relay nodes.
354
+ - **Night Tile Layer** story — demonstrates `nightTileUrl` combined with `lightSources`.
355
+ - Updated component description with Night Tile Layer and Dynamic Light Sources sections.
356
+
357
+ ### Bug Fixes
358
+
359
+ - Fixed terminator night polygon antimeridian wrapping — sunset and sunrise curves are now generated as continuous coordinate pairs (no `lon ± 180` mirroring), preventing the polygon from crossing the day side.
360
+ - Removed unused `buildBandPolygon` function from Leaflet backend.
361
+
362
+ ---
363
+
364
+ ## 0.2.0
365
+
366
+ ### Features
367
+
368
+ #### SDK Category System (New)
369
+ - **`CategoryDef`** — shared interface for a named, colored data category (`id`, `color`, `label?`), used across Timeline, GroundTrackMap, and any future component.
370
+ - **`CategoryPalette`**utility class that maps category IDs to stable colors and labels, with built-in fallback palettes for auto-assignment.
371
+ - **`CategoryProvider` / `useCategoryPalette`** optional React Context for sharing a `CategoryPalette` and a custom display label (e.g. "Squad", "Division") across an entire dashboard. Fully opt-in; components work standalone without it.
372
+ - New Storybook documentation page (`SDK Category Concept`) with interactive examples, architecture diagrams, and integration guidance.
373
+
374
+ #### UnifiedTimeline
375
+ - **Team / category-aware events** events now carry structured team identity (`id`, `color`, `label?`), enabling category-colored event bars and badges.
376
+ - **Multi-select team filter** — replaces the former boolean `teamColoredOnly` toggle; users can filter by specific teams via pill-style checkboxes.
377
+ - **`teamLabel` prop** — devs can rename "Team" to any domain-specific term (e.g. "Squad", "Division"); also readable from `CategoryProvider` context.
378
+ - **Day markers** `showDayMarkers` draws labeled day boundaries on multi-day timelines.
379
+ - **Redesigned filter bar** — collapsible panel with Astro UX filter icon, search field moved to top header row, responsive breakpoints.
380
+ - **Performance** — bounding-box culling for `ChartView` events outside the visible viewport.
381
+
382
+ #### GroundTrackMap
383
+ - **Twilight terminator with gradient zones** — realistic Civil / Nautical / Astronomical / Full Night shading derived from solar depression angle, replacing the former hard-edge day/night line. Uses `depressionDeg` for precise boundaries.
384
+ - **Collaborative pins** — new `MapPin` interface and `pins` / `pinsEditable` / `onPinAdd` / `onPinUpdate` / `onPinRemove` props for placing colored points-of-interest synced across terminals.
385
+ - **Enhanced satellite visualization** `showFootprint` / `footprintRadius` for sensor coverage circles, `futureTrackIndex` for solid-past / dashed-future track split, `passMarkers` for AOS/LOS diamonds.
386
+ - **Ground station antenna icons** — `dish`, `phased-array`, `omni`, and `relay` icon types with coverage circles and Astro status colors.
387
+ - **Legend overlay** — auto-generated satellite + ground station legend with status indicators.
388
+ - Category-aware pin colors via `CategoryProvider` integration.
389
+
390
+ #### SimulationControls
391
+ - Increased control-button background opacities for better visibility on dark themes.
392
+
393
+ ### Documentation
394
+ - Comprehensive Storybook updates for Timeline (`WithCategoryProvider`, `MultiDayWithCategories` stories) and GroundTrackMap (`SDK Category Integration` section).
395
+ - New `CategoryConcept` Storybook page with `PaletteBasics`, `ProviderAndHook`, and `DynamicCategories` interactive stories.
396
+
397
+ ### Breaking Changes
398
+ - `TimelineEvent.color` replaced by `TimelineEvent.team` (`TimelineTeam` / `CategoryDef`). Plain string colors are still accepted for backward compatibility but are treated as legacy entries.
399
+ - `TimelineFilter.teamColoredOnly` replaced by `TimelineFilter.teams` (multi-select `string[]`).
400
+
401
+ ---
402
+
403
+ ## 0.1.0
404
+
405
+ Initial public release.
406
+
407
+ ### Features
408
+
409
+ - 60+ React components for space, air, land, and maritime operations
410
+ - Built on Astro UX Design System
411
+ - Themeable (Zen, Hybrid, Astro, Glass) with dark/light mode
412
+ - ECharts-based charting (line, area, bar, radar, treemap, sankey, and more)
413
+ - 3D viewers (Earth, Solar System, ZenSpace3D) via Three.js
414
+ - Ground track maps (Leaflet and canvas backends)
415
+ - Mission control widgets (MissionClock, SimulationControls, UnifiedTimeline)
416
+ - Layout primitives (Box, Flex, Grid, Stack, Container, SideNav, SidePanel)
417
+ - Accessibility-first (WCAG 2.2 AA oriented)
418
+ - Design tokens as JS objects and CSS custom properties
419
+ - Optional `zendir-ts` (Zendir TypeScript SDK) integration with graceful fallback