JSPM

  • Created
  • Published
  • Downloads 490
  • Score
    100M100P100Q83905F
  • License MIT

React UI components for space operations, built on the Astro UX Design System

Package Exports

  • @zendir/ui
  • @zendir/ui/react
  • @zendir/ui/react/3d
  • @zendir/ui/react/astro
  • @zendir/ui/react/cards
  • @zendir/ui/react/charts
  • @zendir/ui/react/chatgpt
  • @zendir/ui/react/core
  • @zendir/ui/react/core/Badge
  • @zendir/ui/react/core/Button
  • @zendir/ui/react/core/Checkbox
  • @zendir/ui/react/core/ConfirmDialog
  • @zendir/ui/react/core/Dialog
  • @zendir/ui/react/core/GlassCard
  • @zendir/ui/react/core/Input
  • @zendir/ui/react/core/NumberInput
  • @zendir/ui/react/core/PinInput
  • @zendir/ui/react/core/Popover
  • @zendir/ui/react/core/Select
  • @zendir/ui/react/core/SideNav
  • @zendir/ui/react/core/Tabs
  • @zendir/ui/react/core/Toast
  • @zendir/ui/react/core/Toggle
  • @zendir/ui/react/core/Tooltip
  • @zendir/ui/react/core/Typography
  • @zendir/ui/react/layout/Flex
  • @zendir/ui/react/layout/Grid
  • @zendir/ui/react/panels
  • @zendir/ui/react/theme
  • @zendir/ui/sdk-stub
  • @zendir/ui/styles
  • @zendir/ui/tokens
  • @zendir/ui/tokens/css
  • @zendir/ui/tokens/css-vars

Readme

@zendir/ui

React components for space operations.
Built on the Astro UX Design System.

npm version License TypeScript React WCAG 2.2 AA conformant

Quick Start · Components · AI Integration · Theming · Accessibility · Storybook · Contributing · Code of Conduct


Overview

React components for satellite telemetry, orbit visualisation, mission control dashboards, and space simulations. Follows the Astro UX Design System used by the U.S. Space Force.

  • Astro UX-aligned — dual-coded status indicators, classification banners, mission clocks
  • TypeScript-first — full type definitions
  • AccessibleWCAG 2.2 AA conformant, keyboard navigable, reduced-motion aware, EAA-aligned
  • Tree-shakeable with optional peer dependencies
  • Works standalone or with zendir-ts for live API integration

The full component catalogue with live examples lives in Storybook.

Quick Start

Install

npm install @zendir/ui

The SDK is optional. All TypeScript types ship with the UI library. Install zendir-ts only if you need the API client.

Recent versions of @zendir/ui hide the SDK specifier from static import-analysis, so no Vite alias is required — missing zendir-ts simply causes hooks like useZendirSession to report "SDK not installed" while the rest of the UI keeps working.

Older bundlers / strict resolvers: if you hit "Failed to resolve import 'zendir-ts'", point the optional peer at the bundled stub:

// vite.config.js
resolve: { alias: { 'zendir-ts': require.resolve('@zendir/ui/sdk-stub') } }

Use

import { ThemeProvider, SpacecraftCard, StatusIndicator } from '@zendir/ui/react';

function App() {
  return (
    <ThemeProvider defaultVariant="hybrid" defaultMode="dark">
      <StatusIndicator status="normal" label="System Healthy" />

      <SpacecraftCard
        spacecraft={{
          id: 'SAT-001',
          name: 'Explorer-1',
          noradId: 25544,
          type: 'LEO Satellite',
          status: 'operational',
        }}
        position={{
          latitude: 45.2,
          longitude: -122.5,
          altitude: 408,
          velocity: 7.66,
        }}
      />
    </ThemeProvider>
  );
}

Components

Core

Foundational primitives that compose into any interface.

Component Description
Button Primary, secondary, and borderless variants with icon and loading support
Input Text input with label, icon, validation, and size variants
Select Dropdown selection with search and multi-select
Toggle On/off switch with label
Checkbox Checkbox and radio with accessible labeling
Dialog Modal dialog with action slots
Tabs Tabbed navigation with panel content
Tooltip Contextual overlay on hover/focus
Container Surface card with title, status accent, and elevation
Badge Inline status label
Pagination Page navigation controls
NumberInput Numeric stepper with min/max/step and slider
SidePanel Slide-out panel with configurable position
DataTable Sortable, filterable data grid
Menu / Popover Context menus and floating content
ChatPanel AI chat interface with structured blocks, status system, and 4 LLM integration strategies

Status & Monitoring

Astro UX status system — six severity levels, dual-coded with color and shape so that status is never conveyed by color alone (WCAG 1.4.1 Use of Color).

import { StatusIndicator, MonitoringIcon } from '@zendir/ui/react';

<StatusIndicator status="normal" label="Operational" />
<StatusIndicator status="caution" label="Battery Low" />
<StatusIndicator status="critical" label="Comm Loss" pulse />

<MonitoringIcon status="normal" icon="power" label="Power" sublabel="85%" />

Status levels: off · standby · normal · caution · serious · critical

Data Cards

Pre-built cards for common space operations data. All cards support compact mode — collapsed by default, expand on hover, pin on click.

Card Data
SpacecraftCard ID, orbit type, status, position
TelemetryCard Subsystem health, alerts
TelemetryStreamCard Live metric streaming
AccessCard Ground station contact windows
OrbitCard Keplerian elements, period, epoch
<SpacecraftCard compact spacecraft={data} position={pos} />
<TelemetryCard compact telemetry={tlm} />

DataValue

Display telemetry values with automatic icons, units, and status derivation from 30+ built-in property presets.

import { DataValue, DataValueGroup } from '@zendir/ui/react';

<DataValue property="temperature" value={72.5} />
<DataValue property="battery" value={25} />       {/* auto-derives 'caution' */}

<DataValueGroup columns={2} title="Power" icon="propulsion-power">
  <DataValue property="battery" value={85} />
  <DataValue property="voltage" value={28.4} />
  <DataValue property="solarPower" value={124} />
</DataValueGroup>

Presets: battery · voltage · temperature · signalStrength · altitude · velocity · fuelLevel · cpuUsage · memoryUsage · and 20+ more (see Storybook for the full list)

Visualizations

Domain-specific visualization cards for mission operations.

Card Description
LinkBudgetCard RF link budget waterfall
ThermalHeatmapCard Spacecraft thermal zone status
PropulsionCard Fuel, thrusters, delta-V budget
EclipseTimerCard Eclipse/sunlight timing
NavBallCard 3D attitude indicator
SensorFootprintCard Ground sensor coverage

Charts

40+ chart types built on ECharts with Zendir brand and Astro UX data-viz palettes, built-in export (PNG, SVG, CSV), zoom/pan, and streaming support.

import { PowerChart, AttitudeChart, GroundTrackMap } from '@zendir/ui/react';

<PowerChart data={powerData} height={300} />
<AttitudeChart data={attitudeData} height={250} />
<GroundTrackMap groundTrack={track} groundStations={stations} />

Includes: Line, Area, Bar, Pie, Donut, Gauge, Radar, Heatmap, Scatter, Sankey, Treemap, Sunburst, Candlestick, 3D Scatter/Surface/Bar, Waterfall, Doppler, and domain-specific charts for power, attitude, thermal, orbits, contacts, spectrum, and more.

3D Viewers

Three viewers covering the operations spectrum from full-Earth to full solar system, with optional WebGL2 (Three.js) and Cesium backends.

import { ZenSpace3D, EarthViewer, SolarSystemViewer } from '@zendir/ui/react';

// Unified 3D space view — Three.js by default, optional Cesium backend for
// physically-accurate ECI/ECEF transforms and high-fidelity Earth imagery.
// Pair with `useSimulationScene` (see SDK Integration) to render a live
// simulation directly from a `zendir-ts` `ZendirClient`.
<ZenSpace3D
  satellites={satellites}
  groundStations={groundStations}
  satelliteCoverages={coverages}
  referenceTime={referenceDate}
/>

// Lightweight Three.js Earth view — good for small dashboards and demos.
<EarthViewer
  spacecraft={[{ id: 'SAT-001', name: 'Explorer-1', latitude: 45.2, longitude: -122.5, altitude: 408 }]}
  groundStations={[{ id: 'DSN-14', name: 'Goldstone', latitude: 35.4, longitude: -116.9 }]}
  showAtmosphere
  showOrbits
  autoRotate
/>

<SolarSystemViewer focusedPlanet="earth" autoOrbit showLabels />

Coverage geometry (footprint polygons, sensor cones, nadir lines) is rendered from explicit SatelliteCoverage records — see ZenSpace3DTypes for the full prop surface. Heavy orbital propagation (SGP4 / TLE) is intentionally not shipped in this package; bring your own propagator (e.g. satellite.js) and feed positions in via props, or use useSimulationScene to read live Position_BN_N from the engine.

Astro UX Components

Mission operations components following Astro UX Design System specifications.

Component Description
GlobalStatusBar Application header with app name, clock, monitoring icons
MissionClock UTC/local time display with multiple formats
ClassificationBanner Security classification banner (CUI through Top Secret)
Timeline Gantt, list, and scatter views for mission events
Progress Determinate and indeterminate progress indicators
Notification Toast notifications with status and auto-dismiss

Theme System

Wrap your application in ThemeProvider to enable the full token-based design system.

import { ThemeProvider, useTheme } from '@zendir/ui/react';

<ThemeProvider
  defaultVariant="hybrid"    // 'astro' | 'purple-hue' | 'hybrid' | 'nebula' |
                             // 'transparent' | 'transparent-bold' | 'transparent-minimal'
  defaultMode="dark"         // 'light' | 'dark'
  persist={true}             // save to localStorage
>
  <App />
</ThemeProvider>

Seven theme variants are available: hybrid (default, Astro status colors + purple accents), nebula (palette-native — Ultraviolet accent on Zendir neutral surfaces), astro (AstroUXDS reference, dark + light), purple-hue, and the glassmorphic transparent / transparent-bold / transparent-minimal family.

Access tokens anywhere:

const { tokens, mode, setMode } = useTheme();

<div style={{
  background: tokens.colors.background.surface,
  color: tokens.colors.text.primary,
  padding: tokens.spacing.md,
  borderRadius: tokens.borderRadius.md,
}}>
  ...
</div>

Token categories: colors (background, border, text, status, semantic, accent, interactive) · spacing · border radius · typography (Astro-compliant scale) · shadows · animation · focus

Tokens flow from primitive palettes (src/tokens/palettes/ — Zendir brand, Astro UXDS status, Tailwind v4.2 scales) through semantic themes (src/tokens/themes.ts) into generated CSS variables (@zendir/ui/tokens/css, --zendir-*) and the ThemeProvider runtime. See THEME_ARCHITECTURE.md for the full layering model.

Card Accent System

Automatically assign accent colors to cards by content domain:

import { CardAccentProvider, useCardAccent } from '@zendir/ui/react';

<CardAccentProvider accentMode="mix">
  <Container title="Power Systems" accentColor={getAccentColor('Power Systems')}>
    ...
  </Container>
</CardAccentProvider>

Accent modes: cyan · electric · purple · teal · prussianBlue · green · amber · mix


SDK Integration (Optional)

For live API integration, add the Zendir TypeScript SDK (zendir-ts):

npm install zendir-ts

useZendirSession provisions the container + simulation lifecycle. useSimulationScene is the canonical bridge — it polls Position_BN_N, buckets the simulation structure, and feeds props straight into <ZenSpace3D />.

import { useZendirSession, useSimulationScene, ZenSpace3D } from '@zendir/ui/react';

function MissionControl() {
  // Lifecycle: createContainer → waitForRunning → createSimulation
  const { client, session, connect, disconnect, isLoading, error } =
    useZendirSession({ apiKey: 'your-key', autoConnect: true });

  // Live data: structure + position polling, ECI→ECEF on the Cesium backend
  const scene = useSimulationScene({
    client,
    containerId: session?.containerId ?? null,
    simulationId: session?.simulationId ?? null,
  });

  if (error)         return <div>Error: {error}</div>;
  if (isLoading)     return <div>Connecting…</div>;
  if (!session)      return <button onClick={connect}>Connect</button>;

  return (
    <ZenSpace3D
      satellites={scene.satellites}
      groundStations={scene.groundStations}
      referenceTime={scene.referenceDate}
    />
  );
}
Hook Purpose
useZendirSession Container + simulation lifecycle (createContainerwaitForRunningcreateSimulation); disconnect tears down
useSimulationScene Bridges a ZendirClient to live <ZenSpace3D /> props (satellites, ground stations, custom objects, reference time)
useAccessWindows Pure client-side AOS/LOS pass-timing math from a list of AccessPass records (no SDK call)

AI Integration

The ChatPanel component provides a complete AI-powered operator interface with structured responses, interactive blocks, and four integration strategies — including first-class MCP (Model Context Protocol) support.

Quick Setup

import { ChatPanel, parseChatResponse } from '@zendir/ui/react';

function OperatorChat() {
  const [messages, setMessages] = useState([]);

  const handleSend = async (text) => {
    setMessages(prev => [...prev, { id: Date.now(), role: 'user', content: text, timestamp: Date.now() }]);
    const response = await callYourAI(text);
    const msg = parseChatResponse(response);   // auto-detects JSON, YAML, or plain text
    setMessages(prev => [...prev, msg]);
  };

  return <ChatPanel messages={messages} onSend={handleSend} title="Mission AI" />;
}

Four Integration Strategies

Strategy Token Cost Best For
Tool/Function Calling Lowest OpenAI, Anthropic, Gemini (production)
MCP (Model Context Protocol) Lowest Multi-tool, multi-server architectures
YAML Prompt ~30-40% less than JSON Any LLM, cost-sensitive deployments
JSON Prompt Baseline Simplest setup, widest LLM compatibility
import { CHAT_RESPONSE_TOOL_SCHEMA, parseChatResponse } from '@zendir/ui/react';

// OpenAI
const res = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: history,
  tools: [{ type: 'function', function: CHAT_RESPONSE_TOOL_SCHEMA }],
  tool_choice: { type: 'function', function: { name: 'respond_to_operator' } },
});
const msg = parseChatResponse(res.choices[0].message.tool_calls[0].function.arguments, 'json');

// Anthropic
tools: [{ name: CHAT_RESPONSE_TOOL_SCHEMA.name,
          description: CHAT_RESPONSE_TOOL_SCHEMA.description,
          input_schema: CHAT_RESPONSE_TOOL_SCHEMA.parameters }]

// Google Gemini
tools: [{ functionDeclarations: [CHAT_RESPONSE_TOOL_SCHEMA] }]
// Server: Register your tool with the pre-built schema
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { CHAT_RESPONSE_MCP_TOOL } from '@zendir/ui';

const server = new McpServer({ name: 'ops-assistant', version: '1.0.0' });
server.tool(
  CHAT_RESPONSE_MCP_TOOL.name,
  CHAT_RESPONSE_MCP_TOOL.description,
  CHAT_RESPONSE_MCP_TOOL.inputSchema,
  async (args) => ({ content: [{ type: 'text', text: JSON.stringify(args) }] })
);

// Client: Convert MCP results to ChatPanel messages
import { parseMcpToolResult } from '@zendir/ui/react';

const result = await mcpClient.callTool({ name: 'check_health', arguments: { id: 'SAT-001' } });
const msg = parseMcpToolResult('check_health', result);

Strategy 3: YAML Prompt

import { CHAT_RESPONSE_YAML_PROMPT, CHAT_STATUS_RULES_PROMPT, parseChatResponse } from '@zendir/ui/react';

const systemPrompt = `You are a spacecraft ops assistant.\n\n${CHAT_RESPONSE_YAML_PROMPT}\n\n${CHAT_STATUS_RULES_PROMPT}`;
const msg = parseChatResponse(aiOutput, 'yaml');

Strategy 4: JSON Prompt

import { CHAT_RESPONSE_JSON_PROMPT, CHAT_STATUS_RULES_PROMPT, parseChatResponse } from '@zendir/ui/react';

const systemPrompt = `You are a spacecraft ops assistant.\n\n${CHAT_RESPONSE_JSON_PROMPT}\n\n${CHAT_STATUS_RULES_PROMPT}`;
const msg = parseChatResponse(aiOutput, 'json');

Global Configuration

import yaml from 'js-yaml';
import { createChatResponseParser } from '@zendir/ui/react';

// Create once, use everywhere
export const parseAI = createChatResponseParser({
  yamlParser: (s) => yaml.load(s),    // plug in production YAML parser
  defaultFormat: 'yaml',               // default format
});

const msg = parseAI(aiOutput);

Structured Blocks

AI responses can include rich structured content:

Block Type Description Interactive
alert Status banner with severity shape No
telemetry Key-value readout with per-row status No
progress Progress bar with status color No
table Data table with column headers No
kv Compact key-value metadata No
command Code block with copy/run buttons Yes
choice Single or multi-select options Yes
confirm Confirmation gate (authorize/abort) Yes

Interactive blocks fire onBlockEvent with { blockId, messageId, action, value }.

Exported Helpers

Export What It Does
CHAT_RESPONSE_TOOL_SCHEMA Function/tool schema for OpenAI, Anthropic, Gemini
CHAT_RESPONSE_MCP_TOOL MCP server tool definition (for server.tool() registration)
parseChatResponse() Universal parser: auto-detects JSON / YAML / plain text
parseMcpToolResult() Bridge MCP tool results → ChatMessage with blocks
createChatResponseParser() Factory for pre-configured parser (custom YAML, format, IDs)
CHAT_RESPONSE_JSON_PROMPT JSON format instructions + block schema
CHAT_RESPONSE_YAML_PROMPT YAML format instructions + block schema
CHAT_STATUS_RULES_PROMPT Astro UX status thresholds (battery, temp, signal, memory)
McpToolResult / McpToolContent Lightweight MCP types (no SDK dependency needed)

See the AI Integration Guide and MCP Integration stories in Storybook for interactive demos.


AI Host / MCP Integration

Components are designed to embed in any AI host — ChatGPT Apps, Anthropic MCP Apps, Google Gemini, or any MCP-compatible environment. The SDK includes dedicated hooks and a universal widget wrapper:

AppCard — Universal Widget Wrapper

AppCard is the base widget wrapper for any AI host — ChatGPT Apps, Anthropic MCP Apps, Google Gemini, or any MCP-compatible environment:

import { AppCard, useToolOutput, useCallTool } from '@zendir/ui/react';

function SatelliteWidget() {
  const data = useToolOutput<SatelliteHealth>();
  const { callTool, isLoading, error } = useCallTool();

  return (
    <AppCard
      title="SAT-001"
      subtitle="Health Monitor · LEO 421km"
      status={{ level: 'caution', label: 'Battery Low' }}  // Astro UX dual-coded (shape + color)
      loading={isLoading}
      error={error?.message}
      onRetry={() => callTool('refresh_telemetry', { id: 'SAT-001' })}
      allowFullscreen
      icon={<span>🛰️</span>}
    >
      <TelemetryDisplay data={data} />
    </AppCard>
  );
}

Enterprise features: Error boundary (children never crash host), loading skeleton, error display with retry, Astro UX 6-level status badges with shapes, WCAG 2.1 AA ARIA labels, maxHeight auto-constraint, theme sync, fullscreen support.

MCP Server → ChatPanel Bridge

Register your MCP server tools to produce ChatPanel-compatible structured blocks:

// server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { CHAT_RESPONSE_MCP_TOOL } from '@zendir/ui';

const server = new McpServer({ name: 'sat-ops', version: '1.0.0' });
server.tool(
  CHAT_RESPONSE_MCP_TOOL.name,
  CHAT_RESPONSE_MCP_TOOL.description,
  CHAT_RESPONSE_MCP_TOOL.inputSchema,
  async (args) => ({ content: [{ type: 'text', text: JSON.stringify(args) }] })
);
// client.tsx — Parse MCP results into ChatPanel messages
import { parseMcpToolResult, ChatPanel } from '@zendir/ui/react';

const result = await mcpClient.callTool({ name: 'check_health', arguments: { id: 'SAT-001' } });
const msg = parseMcpToolResult('check_health', result);  // → ChatMessage with typed blocks

Available Host Hooks

Hook Purpose
useToolOutput() Read tool result (structuredContent)
useToolInput() Read tool invocation arguments
useCallTool() Call other MCP tools from widget
useSendMessage() Insert follow-up user messages
useChatGPTTheme() Match light/dark theme
useWidgetState() Persist widget state across renders
useMaxHeight() Get host height constraint
useDisplayMode() Manage inline/PiP/fullscreen
isInChatGPT() Detect ChatGPT environment

Project Structure

src/
├── react/
│   ├── core/            # Buttons, inputs, dialogs, data table
│   ├── astro/           # Astro UX — timeline, status bar, clock
│   ├── cards/           # Spacecraft, telemetry, orbit, access
│   ├── charts/          # 40+ ECharts components
│   ├── visualizations/  # Link budget, thermal, propulsion
│   ├── 3d/              # Earth viewer, solar system
│   ├── hooks/           # Data hooks
│   ├── theme/           # ThemeProvider runtime, theme types, foundation stories
│   ├── chatgpt/         # AI host / MCP integration (AppCard, hooks)
│   └── shared/          # Error boundaries, skeletons, utils
└── tokens/              # Design tokens
    ├── palettes/        # Primitive color scales (Zendir, Astro UXDS, Tailwind v4.2)
    ├── themes.ts        # Semantic theme definitions (7 variants)
    ├── core.ts          # Shared non-color tokens (spacing, typography, shadows)
    └── tokens.css       # Generated CSS variables (+ css-vars.ts) — npm run build:tokens

Development

git clone https://github.com/zendir-dev/zendir-ui.git
cd zendir-ui && npm install

npm run storybook     # Component playground
npm run demo          # Full demo app
npm run build         # Production build
npm run test          # Run tests
npm run lint          # Lint check

Accessibility

Zendir UI conforms to WCAG 2.2 Level AA and is designed to satisfy the European Accessibility Act (EAA) via EN 301 549 v3.2.1 and the Revised Section 508.

  • Keyboard — every component is fully operable via keyboard. Focus order follows DOM order, focus indicators meet 3:1 contrast, and no keyboard traps exist.
  • Screen readers — semantic HTML, ARIA roles, live regions for dynamic content, and descriptive labels on all icon-only controls.
  • Color — status indicators use dual coding (color + shape). All text meets 4.5:1 contrast; accent colors are dynamically adjusted at runtime to guarantee compliance across all themes.
  • Motion — all animations and transitions respect prefers-reduced-motion globally via CSS and JavaScript.
  • Target size — interactive controls meet the 24 × 24 px minimum (WCAG 2.5.8).
  • Forms — validation errors are identified with aria-invalid, associated via aria-describedby, and announced with role="alert".
Standard Status
WCAG 2.2 Level AA Conformant
EN 301 549 v3.2.1 Clause 11 Designed for conformance
EAA Directive (EU) 2019/882 Designed for conformance
Revised Section 508 Conformant

Testing: eslint-plugin-jsx-a11y in CI, axe-core on all Storybook stories, manual keyboard and screen reader verification (VoiceOver, NVDA, TalkBack).

Accessibility issues are treated as P0 bugs. Report an issue with the accessibility label.


Browser Support

Chrome 90+ · Firefox 88+ · Safari 14+ · Edge 90+

WebGL required for 3D components (graceful fallback to 2D).

License

MIT — Space Services Australia Pty Ltd


Astro UX Design System · Storybook · Issues · Contributing