@zendir/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/LICENSE +21 -0
- package/README.md +589 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/react/3d/EarthViewer.d.ts +46 -0
- package/dist/react/3d/EarthViewer.js +836 -0
- package/dist/react/3d/EarthViewer.js.map +1 -0
- package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
- package/dist/react/3d/SolarSystemViewer.js +372 -0
- package/dist/react/3d/SolarSystemViewer.js.map +1 -0
- package/dist/react/3d/ZenSpace3D.d.ts +16 -0
- package/dist/react/3d/ZenSpace3D.js +1253 -0
- package/dist/react/3d/ZenSpace3D.js.map +1 -0
- package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
- package/dist/react/3d/ZenSpace3DCesium.js +186 -0
- package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
- package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
- package/dist/react/3d/ZenSpace3DShaders.js +94 -0
- package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
- package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
- package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
- package/dist/react/3d/ZenSpace3DUtils.js +213 -0
- package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
- package/dist/react/3d/index.d.ts +23 -0
- package/dist/react/3d/threeLoader.d.ts +22 -0
- package/dist/react/3d/threeLoader.js +18 -0
- package/dist/react/3d/threeLoader.js.map +1 -0
- package/dist/react/astro/ClassificationBanner.d.ts +25 -0
- package/dist/react/astro/ClassificationBanner.js +83 -0
- package/dist/react/astro/ClassificationBanner.js.map +1 -0
- package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
- package/dist/react/astro/GlobalStatusBar.js +165 -0
- package/dist/react/astro/GlobalStatusBar.js.map +1 -0
- package/dist/react/astro/MissionClock.d.ts +169 -0
- package/dist/react/astro/MissionClock.js +411 -0
- package/dist/react/astro/MissionClock.js.map +1 -0
- package/dist/react/astro/MonitoringIcon.d.ts +60 -0
- package/dist/react/astro/MonitoringIcon.js +369 -0
- package/dist/react/astro/MonitoringIcon.js.map +1 -0
- package/dist/react/astro/Notification.d.ts +42 -0
- package/dist/react/astro/Notification.js +156 -0
- package/dist/react/astro/Notification.js.map +1 -0
- package/dist/react/astro/Progress.d.ts +39 -0
- package/dist/react/astro/Progress.js +149 -0
- package/dist/react/astro/Progress.js.map +1 -0
- package/dist/react/astro/SimulationControls.d.ts +136 -0
- package/dist/react/astro/SimulationControls.js +668 -0
- package/dist/react/astro/SimulationControls.js.map +1 -0
- package/dist/react/astro/StatusIndicator.d.ts +34 -0
- package/dist/react/astro/StatusIndicator.js +189 -0
- package/dist/react/astro/StatusIndicator.js.map +1 -0
- package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
- package/dist/react/astro/UnifiedTimeline.js +1768 -0
- package/dist/react/astro/UnifiedTimeline.js.map +1 -0
- package/dist/react/astro/index.d.ts +63 -0
- package/dist/react/cards/AccessCard.d.ts +37 -0
- package/dist/react/cards/AccessCard.js +410 -0
- package/dist/react/cards/AccessCard.js.map +1 -0
- package/dist/react/cards/OrbitCard.d.ts +31 -0
- package/dist/react/cards/OrbitCard.js +372 -0
- package/dist/react/cards/OrbitCard.js.map +1 -0
- package/dist/react/cards/SpacecraftCard.d.ts +54 -0
- package/dist/react/cards/SpacecraftCard.js +941 -0
- package/dist/react/cards/SpacecraftCard.js.map +1 -0
- package/dist/react/cards/TelemetryCard.d.ts +40 -0
- package/dist/react/cards/TelemetryCard.js +742 -0
- package/dist/react/cards/TelemetryCard.js.map +1 -0
- package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
- package/dist/react/cards/TelemetryStreamCard.js +309 -0
- package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
- package/dist/react/cards/index.d.ts +13 -0
- package/dist/react/charts/GroundTrackMap.d.ts +112 -0
- package/dist/react/charts/GroundTrackMap.js +1123 -0
- package/dist/react/charts/GroundTrackMap.js.map +1 -0
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
- package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
- package/dist/react/charts/index.d.ts +10 -0
- package/dist/react/charts/unified/AstroChart.d.ts +24 -0
- package/dist/react/charts/unified/AstroChart.js +1405 -0
- package/dist/react/charts/unified/AstroChart.js.map +1 -0
- package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
- package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
- package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
- package/dist/react/charts/unified/domain.d.ts +845 -0
- package/dist/react/charts/unified/domain.js +3168 -0
- package/dist/react/charts/unified/domain.js.map +1 -0
- package/dist/react/charts/unified/generators.d.ts +276 -0
- package/dist/react/charts/unified/generators.js +518 -0
- package/dist/react/charts/unified/generators.js.map +1 -0
- package/dist/react/charts/unified/index.d.ts +55 -0
- package/dist/react/charts/unified/presets.d.ts +290 -0
- package/dist/react/charts/unified/presets.js +999 -0
- package/dist/react/charts/unified/presets.js.map +1 -0
- package/dist/react/charts/unified/sync.d.ts +69 -0
- package/dist/react/charts/unified/sync.js +219 -0
- package/dist/react/charts/unified/sync.js.map +1 -0
- package/dist/react/charts/unified/theme.d.ts +447 -0
- package/dist/react/charts/unified/theme.js +562 -0
- package/dist/react/charts/unified/theme.js.map +1 -0
- package/dist/react/charts/unified/types.d.ts +826 -0
- package/dist/react/charts/unified/useChartStream.d.ts +58 -0
- package/dist/react/charts/unified/useChartStream.js +226 -0
- package/dist/react/charts/unified/useChartStream.js.map +1 -0
- package/dist/react/chatgpt/AppCard.d.ts +59 -0
- package/dist/react/chatgpt/AppCard.js +306 -0
- package/dist/react/chatgpt/AppCard.js.map +1 -0
- package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
- package/dist/react/chatgpt/index.d.ts +167 -0
- package/dist/react/chatgpt/index.js +166 -0
- package/dist/react/chatgpt/index.js.map +1 -0
- package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
- package/dist/react/context/DisplaySettingsContext.js +169 -0
- package/dist/react/context/DisplaySettingsContext.js.map +1 -0
- package/dist/react/context/index.d.ts +5 -0
- package/dist/react/core/ActivityPlanner.d.ts +45 -0
- package/dist/react/core/ActivityPlanner.js +532 -0
- package/dist/react/core/ActivityPlanner.js.map +1 -0
- package/dist/react/core/AppBar.d.ts +71 -0
- package/dist/react/core/AppBar.js +817 -0
- package/dist/react/core/AppBar.js.map +1 -0
- package/dist/react/core/AstroIcon.d.ts +84 -0
- package/dist/react/core/AstroIcon.js +1243 -0
- package/dist/react/core/AstroIcon.js.map +1 -0
- package/dist/react/core/Badge.d.ts +27 -0
- package/dist/react/core/Badge.js +134 -0
- package/dist/react/core/Badge.js.map +1 -0
- package/dist/react/core/Button.d.ts +26 -0
- package/dist/react/core/Button.js +306 -0
- package/dist/react/core/Button.js.map +1 -0
- package/dist/react/core/CardHeader.d.ts +34 -0
- package/dist/react/core/CardHeader.js +316 -0
- package/dist/react/core/CardHeader.js.map +1 -0
- package/dist/react/core/ChatPanel.d.ts +627 -0
- package/dist/react/core/ChatPanel.js +1144 -0
- package/dist/react/core/ChatPanel.js.map +1 -0
- package/dist/react/core/Checkbox.d.ts +26 -0
- package/dist/react/core/Checkbox.js +130 -0
- package/dist/react/core/Checkbox.js.map +1 -0
- package/dist/react/core/ColorPickerPanel.d.ts +25 -0
- package/dist/react/core/ColorPickerPanel.js +293 -0
- package/dist/react/core/ColorPickerPanel.js.map +1 -0
- package/dist/react/core/CommandBuilder.d.ts +74 -0
- package/dist/react/core/CommandBuilder.js +518 -0
- package/dist/react/core/CommandBuilder.js.map +1 -0
- package/dist/react/core/ConfirmDialog.d.ts +45 -0
- package/dist/react/core/ConfirmDialog.js +315 -0
- package/dist/react/core/ConfirmDialog.js.map +1 -0
- package/dist/react/core/ConnectionForm.d.ts +57 -0
- package/dist/react/core/ConnectionForm.js +496 -0
- package/dist/react/core/ConnectionForm.js.map +1 -0
- package/dist/react/core/Container.d.ts +51 -0
- package/dist/react/core/Container.js +670 -0
- package/dist/react/core/Container.js.map +1 -0
- package/dist/react/core/CopyButton.d.ts +39 -0
- package/dist/react/core/CopyButton.js +105 -0
- package/dist/react/core/CopyButton.js.map +1 -0
- package/dist/react/core/DataTable.d.ts +113 -0
- package/dist/react/core/DataTable.js +446 -0
- package/dist/react/core/DataTable.js.map +1 -0
- package/dist/react/core/DataValue.d.ts +64 -0
- package/dist/react/core/DataValue.js +545 -0
- package/dist/react/core/DataValue.js.map +1 -0
- package/dist/react/core/Dialog.d.ts +32 -0
- package/dist/react/core/Dialog.js +201 -0
- package/dist/react/core/Dialog.js.map +1 -0
- package/dist/react/core/FileExplorer.d.ts +65 -0
- package/dist/react/core/FileExplorer.js +520 -0
- package/dist/react/core/FileExplorer.js.map +1 -0
- package/dist/react/core/GlassCard.d.ts +129 -0
- package/dist/react/core/GlassCard.js +375 -0
- package/dist/react/core/GlassCard.js.map +1 -0
- package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
- package/dist/react/core/HeaderIconWithStatus.js +157 -0
- package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
- package/dist/react/core/HexViewer.d.ts +143 -0
- package/dist/react/core/HexViewer.js +1106 -0
- package/dist/react/core/HexViewer.js.map +1 -0
- package/dist/react/core/Icon.d.ts +32 -0
- package/dist/react/core/Icon.js +142 -0
- package/dist/react/core/Icon.js.map +1 -0
- package/dist/react/core/ImageGallery.d.ts +41 -0
- package/dist/react/core/ImageGallery.js +320 -0
- package/dist/react/core/ImageGallery.js.map +1 -0
- package/dist/react/core/Input.d.ts +38 -0
- package/dist/react/core/Input.js +288 -0
- package/dist/react/core/Input.js.map +1 -0
- package/dist/react/core/LimitsBar.d.ts +51 -0
- package/dist/react/core/LimitsBar.js +200 -0
- package/dist/react/core/LimitsBar.js.map +1 -0
- package/dist/react/core/LogViewer.d.ts +61 -0
- package/dist/react/core/LogViewer.js +599 -0
- package/dist/react/core/LogViewer.js.map +1 -0
- package/dist/react/core/MessageStream.d.ts +58 -0
- package/dist/react/core/MessageStream.js +455 -0
- package/dist/react/core/MessageStream.js.map +1 -0
- package/dist/react/core/MissionCalendar.d.ts +81 -0
- package/dist/react/core/MissionCalendar.js +1049 -0
- package/dist/react/core/MissionCalendar.js.map +1 -0
- package/dist/react/core/NumberInput.d.ts +85 -0
- package/dist/react/core/NumberInput.js +507 -0
- package/dist/react/core/NumberInput.js.map +1 -0
- package/dist/react/core/PacketViewer.d.ts +73 -0
- package/dist/react/core/PacketViewer.js +431 -0
- package/dist/react/core/PacketViewer.js.map +1 -0
- package/dist/react/core/Pagination.d.ts +30 -0
- package/dist/react/core/Pagination.js +190 -0
- package/dist/react/core/Pagination.js.map +1 -0
- package/dist/react/core/PinInput.d.ts +41 -0
- package/dist/react/core/PinInput.js +210 -0
- package/dist/react/core/PinInput.js.map +1 -0
- package/dist/react/core/Popover.d.ts +55 -0
- package/dist/react/core/Popover.js +288 -0
- package/dist/react/core/Popover.js.map +1 -0
- package/dist/react/core/Select.d.ts +42 -0
- package/dist/react/core/Select.js +303 -0
- package/dist/react/core/Select.js.map +1 -0
- package/dist/react/core/SideNav.d.ts +103 -0
- package/dist/react/core/SideNav.js +551 -0
- package/dist/react/core/SideNav.js.map +1 -0
- package/dist/react/core/SidePanel.d.ts +33 -0
- package/dist/react/core/SidePanel.js +199 -0
- package/dist/react/core/SidePanel.js.map +1 -0
- package/dist/react/core/Tabs.d.ts +47 -0
- package/dist/react/core/Tabs.js +129 -0
- package/dist/react/core/Tabs.js.map +1 -0
- package/dist/react/core/Toast.d.ts +56 -0
- package/dist/react/core/Toast.js +229 -0
- package/dist/react/core/Toast.js.map +1 -0
- package/dist/react/core/Toggle.d.ts +22 -0
- package/dist/react/core/Toggle.js +151 -0
- package/dist/react/core/Toggle.js.map +1 -0
- package/dist/react/core/Tooltip.d.ts +19 -0
- package/dist/react/core/Tooltip.js +179 -0
- package/dist/react/core/Tooltip.js.map +1 -0
- package/dist/react/core/Typography.d.ts +127 -0
- package/dist/react/core/Typography.js +187 -0
- package/dist/react/core/Typography.js.map +1 -0
- package/dist/react/core/index.d.ts +108 -0
- package/dist/react/core/layout/Box.d.ts +77 -0
- package/dist/react/core/layout/Box.js +126 -0
- package/dist/react/core/layout/Box.js.map +1 -0
- package/dist/react/core/layout/Center.d.ts +20 -0
- package/dist/react/core/layout/Center.js +34 -0
- package/dist/react/core/layout/Center.js.map +1 -0
- package/dist/react/core/layout/Divider.d.ts +16 -0
- package/dist/react/core/layout/Divider.js +108 -0
- package/dist/react/core/layout/Divider.js.map +1 -0
- package/dist/react/core/layout/Flex.d.ts +30 -0
- package/dist/react/core/layout/Flex.js +128 -0
- package/dist/react/core/layout/Flex.js.map +1 -0
- package/dist/react/core/layout/Grid.d.ts +36 -0
- package/dist/react/core/layout/Grid.js +142 -0
- package/dist/react/core/layout/Grid.js.map +1 -0
- package/dist/react/core/layout/Spacer.d.ts +8 -0
- package/dist/react/core/layout/Spacer.js +31 -0
- package/dist/react/core/layout/Spacer.js.map +1 -0
- package/dist/react/core/layout/Stack.d.ts +54 -0
- package/dist/react/core/layout/Stack.js +74 -0
- package/dist/react/core/layout/Stack.js.map +1 -0
- package/dist/react/core/layout/index.d.ts +38 -0
- package/dist/react/core/layout/responsive.d.ts +23 -0
- package/dist/react/core/layout/responsive.js +26 -0
- package/dist/react/core/layout/responsive.js.map +1 -0
- package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
- package/dist/react/core/layout/useBreakpoint.js +73 -0
- package/dist/react/core/layout/useBreakpoint.js.map +1 -0
- package/dist/react/core/propertyConfig.d.ts +443 -0
- package/dist/react/core/propertyConfig.js +399 -0
- package/dist/react/core/propertyConfig.js.map +1 -0
- package/dist/react/hooks/index.d.ts +21 -0
- package/dist/react/hooks/useAccessWindows.d.ts +66 -0
- package/dist/react/hooks/useCompactMode.d.ts +82 -0
- package/dist/react/hooks/useCompactMode.js +62 -0
- package/dist/react/hooks/useCompactMode.js.map +1 -0
- package/dist/react/hooks/useLiveSelection.d.ts +57 -0
- package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
- package/dist/react/hooks/useSimulationTime.d.ts +61 -0
- package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
- package/dist/react/hooks/useSpacecraftPosition.js +89 -0
- package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
- package/dist/react/hooks/useTelemetry.d.ts +55 -0
- package/dist/react/hooks/useTelemetry.js +73 -0
- package/dist/react/hooks/useTelemetry.js.map +1 -0
- package/dist/react/hooks/useZendirSession.d.ts +109 -0
- package/dist/react/hooks/useZendirSession.js +148 -0
- package/dist/react/hooks/useZendirSession.js.map +1 -0
- package/dist/react/index.d.ts +74 -0
- package/dist/react/shared/ErrorBoundary.d.ts +63 -0
- package/dist/react/shared/ErrorBoundary.js +142 -0
- package/dist/react/shared/ErrorBoundary.js.map +1 -0
- package/dist/react/shared/Skeleton.d.ts +110 -0
- package/dist/react/shared/Skeleton.js +324 -0
- package/dist/react/shared/Skeleton.js.map +1 -0
- package/dist/react/shared/index.d.ts +12 -0
- package/dist/react/theme/ThemeProvider.d.ts +385 -0
- package/dist/react/theme/ThemeProvider.js +1096 -0
- package/dist/react/theme/ThemeProvider.js.map +1 -0
- package/dist/react/theme/astro-tokens.d.ts +153 -0
- package/dist/react/theme/cardAccent.d.ts +75 -0
- package/dist/react/theme/cardAccent.js +137 -0
- package/dist/react/theme/cardAccent.js.map +1 -0
- package/dist/react/theme/config.d.ts +39 -0
- package/dist/react/theme/index.d.ts +9 -0
- package/dist/react/types.d.ts +360 -0
- package/dist/react/types.js +58 -0
- package/dist/react/types.js.map +1 -0
- package/dist/react/utils/index.d.ts +247 -0
- package/dist/react/utils/index.js +423 -0
- package/dist/react/utils/index.js.map +1 -0
- package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
- package/dist/react/visualizations/EclipseTimerCard.js +250 -0
- package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
- package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
- package/dist/react/visualizations/LinkBudgetCard.js +444 -0
- package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
- package/dist/react/visualizations/NavBallCard.d.ts +17 -0
- package/dist/react/visualizations/NavBallCard.js +243 -0
- package/dist/react/visualizations/NavBallCard.js.map +1 -0
- package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
- package/dist/react/visualizations/PropulsionCard.js +298 -0
- package/dist/react/visualizations/PropulsionCard.js.map +1 -0
- package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
- package/dist/react/visualizations/SensorFootprintCard.js +326 -0
- package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
- package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
- package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
- package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
- package/dist/react/visualizations/index.d.ts +17 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +421 -0
- package/dist/react.js.map +1 -0
- package/dist/shaders/atmosphere.frag.js +5 -0
- package/dist/shaders/atmosphere.frag.js.map +1 -0
- package/dist/shaders/atmosphere.vert.js +5 -0
- package/dist/shaders/atmosphere.vert.js.map +1 -0
- package/dist/shaders/stars.frag.js +5 -0
- package/dist/shaders/stars.frag.js.map +1 -0
- package/dist/shaders/stars.vert.js +5 -0
- package/dist/shaders/stars.vert.js.map +1 -0
- package/dist/style.css +143 -0
- package/dist/tokens/index.d.ts +296 -0
- package/dist/tokens/index.js +263 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/tokens.css +155 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +220 -0
- package/sdk-stub.js +22 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo, useState, useCallback, useMemo } from "react";
|
|
3
|
+
import { useTheme } from "../theme/ThemeProvider.js";
|
|
4
|
+
const CommandBuilder = memo(function CommandBuilder2({
|
|
5
|
+
target,
|
|
6
|
+
command,
|
|
7
|
+
description,
|
|
8
|
+
hazardous = false,
|
|
9
|
+
hazardousDescription,
|
|
10
|
+
parameters,
|
|
11
|
+
onSend,
|
|
12
|
+
history = [],
|
|
13
|
+
showHistory = true,
|
|
14
|
+
showPreview = true,
|
|
15
|
+
disabled = false,
|
|
16
|
+
height,
|
|
17
|
+
className = "",
|
|
18
|
+
bordered = true,
|
|
19
|
+
style: styleProp
|
|
20
|
+
}) {
|
|
21
|
+
const { tokens, theme } = useTheme();
|
|
22
|
+
const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
|
|
23
|
+
const [values, setValues] = useState(() => {
|
|
24
|
+
const defaults = {};
|
|
25
|
+
parameters.forEach((p) => {
|
|
26
|
+
var _a;
|
|
27
|
+
if (p.default !== void 0) defaults[p.name] = p.default;
|
|
28
|
+
else if (p.type === "boolean") defaults[p.name] = false;
|
|
29
|
+
else if (p.type === "enum" && ((_a = p.options) == null ? void 0 : _a.length)) defaults[p.name] = p.options[0];
|
|
30
|
+
else defaults[p.name] = "";
|
|
31
|
+
});
|
|
32
|
+
return defaults;
|
|
33
|
+
});
|
|
34
|
+
const [errors, setErrors] = useState({});
|
|
35
|
+
const [sending, setSending] = useState(false);
|
|
36
|
+
const [showConfirm, setShowConfirm] = useState(false);
|
|
37
|
+
const [showHistoryPanel, setShowHistoryPanel] = useState(false);
|
|
38
|
+
const setValue = useCallback((name, value) => {
|
|
39
|
+
setValues((prev) => ({ ...prev, [name]: value }));
|
|
40
|
+
setErrors((prev) => {
|
|
41
|
+
const next = { ...prev };
|
|
42
|
+
delete next[name];
|
|
43
|
+
return next;
|
|
44
|
+
});
|
|
45
|
+
}, []);
|
|
46
|
+
const validate = useCallback(() => {
|
|
47
|
+
const errs = {};
|
|
48
|
+
parameters.forEach((p) => {
|
|
49
|
+
const val = values[p.name];
|
|
50
|
+
const required = p.required !== false;
|
|
51
|
+
if (required && (val === void 0 || val === "" || val === null)) {
|
|
52
|
+
errs[p.name] = "Required";
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (val === "" || val === void 0) return;
|
|
56
|
+
if ((p.type === "int" || p.type === "uint" || p.type === "float") && typeof val === "string") {
|
|
57
|
+
const num = Number(val);
|
|
58
|
+
if (isNaN(num)) {
|
|
59
|
+
errs[p.name] = "Must be a number";
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (p.min !== void 0 && num < p.min) {
|
|
63
|
+
errs[p.name] = `Min: ${p.min}`;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (p.max !== void 0 && num > p.max) {
|
|
67
|
+
errs[p.name] = `Max: ${p.max}`;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (p.type === "uint" && num < 0) {
|
|
71
|
+
errs[p.name] = "Must be >= 0";
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (p.type === "int" && !Number.isInteger(num)) {
|
|
75
|
+
errs[p.name] = "Must be integer";
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (p.type === "string" && p.pattern && typeof val === "string") {
|
|
80
|
+
if (!new RegExp(p.pattern).test(val)) {
|
|
81
|
+
errs[p.name] = "Invalid format";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
setErrors(errs);
|
|
86
|
+
return Object.keys(errs).length === 0;
|
|
87
|
+
}, [parameters, values]);
|
|
88
|
+
const handleSend = useCallback(async () => {
|
|
89
|
+
if (!validate()) return;
|
|
90
|
+
if (hazardous && !showConfirm) {
|
|
91
|
+
setShowConfirm(true);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
setShowConfirm(false);
|
|
95
|
+
setSending(true);
|
|
96
|
+
try {
|
|
97
|
+
const processedValues = {};
|
|
98
|
+
parameters.forEach((p) => {
|
|
99
|
+
let val = values[p.name];
|
|
100
|
+
if ((p.type === "int" || p.type === "uint" || p.type === "float") && typeof val === "string") {
|
|
101
|
+
val = Number(val);
|
|
102
|
+
}
|
|
103
|
+
processedValues[p.name] = val;
|
|
104
|
+
});
|
|
105
|
+
await onSend(processedValues);
|
|
106
|
+
} finally {
|
|
107
|
+
setSending(false);
|
|
108
|
+
}
|
|
109
|
+
}, [validate, hazardous, showConfirm, parameters, values, onSend]);
|
|
110
|
+
const commandString = useMemo(() => {
|
|
111
|
+
const params = parameters.map((p) => `${p.name}=${JSON.stringify(values[p.name] ?? "")}`).join(", ");
|
|
112
|
+
return `cmd("${target} ${command}" ${params ? `with ${params}` : ""})`;
|
|
113
|
+
}, [target, command, parameters, values]);
|
|
114
|
+
const resetToDefaults = useCallback(() => {
|
|
115
|
+
const defaults = {};
|
|
116
|
+
parameters.forEach((p) => {
|
|
117
|
+
var _a;
|
|
118
|
+
if (p.default !== void 0) defaults[p.name] = p.default;
|
|
119
|
+
else if (p.type === "boolean") defaults[p.name] = false;
|
|
120
|
+
else if (p.type === "enum" && ((_a = p.options) == null ? void 0 : _a.length)) defaults[p.name] = p.options[0];
|
|
121
|
+
else defaults[p.name] = "";
|
|
122
|
+
});
|
|
123
|
+
setValues(defaults);
|
|
124
|
+
setErrors({});
|
|
125
|
+
}, [parameters]);
|
|
126
|
+
const inputStyle = {
|
|
127
|
+
background: tokens.colors.background.base,
|
|
128
|
+
color: tokens.colors.text.primary,
|
|
129
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
130
|
+
borderRadius: tokens.borderRadius.md,
|
|
131
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
132
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
133
|
+
outline: "none",
|
|
134
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
135
|
+
width: "100%",
|
|
136
|
+
minHeight: 40,
|
|
137
|
+
boxSizing: "border-box",
|
|
138
|
+
transition: "border-color 150ms ease"
|
|
139
|
+
};
|
|
140
|
+
return /* @__PURE__ */ jsxs(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
className: `command-builder ${className}`,
|
|
144
|
+
style: {
|
|
145
|
+
height: typeof height === "number" ? height : void 0,
|
|
146
|
+
background: tokens.colors.background.base,
|
|
147
|
+
...bordered ? tokens.colors.border.cardStyle ?? { border: `1px solid ${tokens.colors.border.muted}` } : { border: "none" },
|
|
148
|
+
borderRadius: tokens.borderRadius.lg,
|
|
149
|
+
overflow: "hidden",
|
|
150
|
+
display: "flex",
|
|
151
|
+
flexDirection: "column",
|
|
152
|
+
fontFamily: tokens.typography.fontFamily.primary,
|
|
153
|
+
color: tokens.colors.text.primary,
|
|
154
|
+
backdropFilter: isTransparentTheme ? "blur(10px)" : void 0,
|
|
155
|
+
WebkitBackdropFilter: isTransparentTheme ? "blur(10px)" : void 0,
|
|
156
|
+
...styleProp
|
|
157
|
+
},
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
160
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
161
|
+
borderBottom: `1px solid ${tokens.colors.border.muted}`,
|
|
162
|
+
background: hazardous ? `${tokens.colors.status.critical}12` : tokens.colors.background.surface,
|
|
163
|
+
display: "flex",
|
|
164
|
+
alignItems: "center",
|
|
165
|
+
justifyContent: "space-between"
|
|
166
|
+
}, children: [
|
|
167
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm }, children: [
|
|
168
|
+
hazardous && /* @__PURE__ */ jsx("span", { role: "img", "aria-label": "Hazardous command", style: { fontSize: tokens.typography.fontSize.lg }, children: "⚠" }),
|
|
169
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
170
|
+
background: `${tokens.colors.interactive.default}22`,
|
|
171
|
+
color: tokens.colors.interactive.default,
|
|
172
|
+
padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
|
|
173
|
+
borderRadius: tokens.borderRadius.md,
|
|
174
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
175
|
+
fontWeight: tokens.typography.fontWeight.medium
|
|
176
|
+
}, children: target }),
|
|
177
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: tokens.typography.fontWeight.bold, fontSize: tokens.typography.fontSize.sm }, children: command }),
|
|
178
|
+
hazardous && /* @__PURE__ */ jsx("span", { style: {
|
|
179
|
+
background: `${tokens.colors.status.critical}22`,
|
|
180
|
+
color: tokens.colors.status.critical,
|
|
181
|
+
padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
|
|
182
|
+
borderRadius: tokens.borderRadius.sm,
|
|
183
|
+
fontSize: tokens.typography.fontSize.micro,
|
|
184
|
+
fontWeight: tokens.typography.fontWeight.bold,
|
|
185
|
+
textTransform: "uppercase",
|
|
186
|
+
letterSpacing: "0.5px"
|
|
187
|
+
}, children: "Hazardous" })
|
|
188
|
+
] }),
|
|
189
|
+
showHistory && history.length > 0 && /* @__PURE__ */ jsxs(
|
|
190
|
+
"button",
|
|
191
|
+
{
|
|
192
|
+
onClick: () => setShowHistoryPanel((p) => !p),
|
|
193
|
+
"aria-expanded": showHistoryPanel,
|
|
194
|
+
"aria-label": `Command history (${history.length} entries)`,
|
|
195
|
+
style: {
|
|
196
|
+
background: tokens.colors.background.base,
|
|
197
|
+
color: tokens.colors.text.secondary,
|
|
198
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
199
|
+
borderRadius: tokens.borderRadius.md,
|
|
200
|
+
padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,
|
|
201
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
202
|
+
cursor: "pointer",
|
|
203
|
+
transition: "all 150ms ease"
|
|
204
|
+
},
|
|
205
|
+
children: [
|
|
206
|
+
"History (",
|
|
207
|
+
history.length,
|
|
208
|
+
")"
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
] }),
|
|
213
|
+
description && /* @__PURE__ */ jsx("div", { style: {
|
|
214
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
215
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
216
|
+
color: tokens.colors.text.secondary,
|
|
217
|
+
borderBottom: `1px solid ${tokens.colors.border.muted}`,
|
|
218
|
+
lineHeight: tokens.typography.lineHeight.normal
|
|
219
|
+
}, children: description }),
|
|
220
|
+
/* @__PURE__ */ jsx("div", { role: "form", "aria-label": `${target} ${command} parameters`, style: { flex: 1, overflow: "auto", padding: tokens.spacing.smd }, children: parameters.length === 0 ? /* @__PURE__ */ jsx("div", { style: {
|
|
221
|
+
color: tokens.colors.text.muted,
|
|
222
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
223
|
+
textAlign: "center",
|
|
224
|
+
padding: tokens.spacing.xl
|
|
225
|
+
}, children: "No parameters — command will be sent as-is" }) : /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: tokens.spacing.smd }, children: parameters.map((p) => {
|
|
226
|
+
var _a;
|
|
227
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
228
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
229
|
+
display: "flex",
|
|
230
|
+
alignItems: "center",
|
|
231
|
+
gap: tokens.spacing.sm,
|
|
232
|
+
marginBottom: tokens.spacing.xs
|
|
233
|
+
}, children: [
|
|
234
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: `cmd-param-${p.name}`, style: {
|
|
235
|
+
fontWeight: tokens.typography.fontWeight.medium,
|
|
236
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
237
|
+
color: tokens.colors.text.primary
|
|
238
|
+
}, children: [
|
|
239
|
+
p.name,
|
|
240
|
+
p.required !== false && /* @__PURE__ */ jsx("span", { "aria-label": "required", style: { color: tokens.colors.status.critical, marginLeft: tokens.spacing.xxs }, children: "*" })
|
|
241
|
+
] }),
|
|
242
|
+
/* @__PURE__ */ jsxs("span", { style: {
|
|
243
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
244
|
+
color: tokens.colors.text.muted,
|
|
245
|
+
background: tokens.colors.background.surface,
|
|
246
|
+
padding: `1px ${tokens.spacing.xs}`,
|
|
247
|
+
borderRadius: tokens.borderRadius.sm
|
|
248
|
+
}, children: [
|
|
249
|
+
p.type,
|
|
250
|
+
p.bitSize ? ` (${p.bitSize}b)` : ""
|
|
251
|
+
] }),
|
|
252
|
+
p.units && /* @__PURE__ */ jsxs("span", { style: { fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.interactive.default }, children: [
|
|
253
|
+
"[",
|
|
254
|
+
p.units,
|
|
255
|
+
"]"
|
|
256
|
+
] }),
|
|
257
|
+
p.hazardous && /* @__PURE__ */ jsx("span", { "aria-label": "Hazardous parameter", style: { fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.status.critical }, children: "⚠" })
|
|
258
|
+
] }),
|
|
259
|
+
p.description && /* @__PURE__ */ jsx("div", { id: `cmd-param-desc-${p.name}`, style: {
|
|
260
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
261
|
+
color: tokens.colors.text.muted,
|
|
262
|
+
marginBottom: tokens.spacing.xs,
|
|
263
|
+
lineHeight: tokens.typography.lineHeight.tight
|
|
264
|
+
}, children: p.description }),
|
|
265
|
+
p.type === "boolean" ? /* @__PURE__ */ jsxs("label", { style: {
|
|
266
|
+
display: "flex",
|
|
267
|
+
alignItems: "center",
|
|
268
|
+
gap: tokens.spacing.sm,
|
|
269
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
270
|
+
cursor: "pointer"
|
|
271
|
+
}, children: [
|
|
272
|
+
/* @__PURE__ */ jsx(
|
|
273
|
+
"input",
|
|
274
|
+
{
|
|
275
|
+
id: `cmd-param-${p.name}`,
|
|
276
|
+
type: "checkbox",
|
|
277
|
+
checked: !!values[p.name],
|
|
278
|
+
onChange: (e) => setValue(p.name, e.target.checked),
|
|
279
|
+
"aria-describedby": p.description ? `cmd-param-desc-${p.name}` : void 0,
|
|
280
|
+
style: { accentColor: tokens.colors.interactive.default }
|
|
281
|
+
}
|
|
282
|
+
),
|
|
283
|
+
values[p.name] ? "TRUE" : "FALSE"
|
|
284
|
+
] }) : p.type === "enum" ? /* @__PURE__ */ jsx(
|
|
285
|
+
"select",
|
|
286
|
+
{
|
|
287
|
+
id: `cmd-param-${p.name}`,
|
|
288
|
+
value: String(values[p.name] ?? ""),
|
|
289
|
+
onChange: (e) => setValue(p.name, e.target.value),
|
|
290
|
+
"aria-describedby": p.description ? `cmd-param-desc-${p.name}` : void 0,
|
|
291
|
+
style: inputStyle,
|
|
292
|
+
children: (_a = p.options) == null ? void 0 : _a.map((opt) => /* @__PURE__ */ jsx("option", { value: String(opt), children: String(opt) }, String(opt)))
|
|
293
|
+
}
|
|
294
|
+
) : /* @__PURE__ */ jsx(
|
|
295
|
+
"input",
|
|
296
|
+
{
|
|
297
|
+
id: `cmd-param-${p.name}`,
|
|
298
|
+
type: p.type === "int" || p.type === "uint" || p.type === "float" ? "number" : "text",
|
|
299
|
+
value: String(values[p.name] ?? ""),
|
|
300
|
+
onChange: (e) => setValue(p.name, e.target.value),
|
|
301
|
+
placeholder: p.default !== void 0 ? `Default: ${p.default}` : void 0,
|
|
302
|
+
min: p.min,
|
|
303
|
+
max: p.max,
|
|
304
|
+
step: p.type === "float" ? "any" : 1,
|
|
305
|
+
"aria-describedby": p.description ? `cmd-param-desc-${p.name}` : void 0,
|
|
306
|
+
"aria-invalid": !!errors[p.name],
|
|
307
|
+
style: {
|
|
308
|
+
...inputStyle,
|
|
309
|
+
borderColor: errors[p.name] ? tokens.colors.status.critical : tokens.colors.border.muted
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
),
|
|
313
|
+
errors[p.name] && /* @__PURE__ */ jsx("span", { role: "alert", style: {
|
|
314
|
+
display: "block",
|
|
315
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
316
|
+
color: tokens.colors.status.critical,
|
|
317
|
+
marginTop: tokens.spacing.xxs
|
|
318
|
+
}, children: errors[p.name] })
|
|
319
|
+
] }, p.name);
|
|
320
|
+
}) }) }),
|
|
321
|
+
showPreview && /* @__PURE__ */ jsx("div", { "aria-label": "Command preview", style: {
|
|
322
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
323
|
+
borderTop: `1px solid ${tokens.colors.border.muted}`,
|
|
324
|
+
background: tokens.colors.background.surface,
|
|
325
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
326
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
327
|
+
color: tokens.colors.text.muted,
|
|
328
|
+
overflow: "hidden",
|
|
329
|
+
textOverflow: "ellipsis",
|
|
330
|
+
whiteSpace: "nowrap"
|
|
331
|
+
}, children: commandString }),
|
|
332
|
+
showConfirm && /* @__PURE__ */ jsxs("div", { role: "alertdialog", "aria-label": "Confirm hazardous command", style: {
|
|
333
|
+
padding: tokens.spacing.smd,
|
|
334
|
+
borderTop: `1px solid ${tokens.colors.status.critical}44`,
|
|
335
|
+
background: `${tokens.colors.status.critical}12`
|
|
336
|
+
}, children: [
|
|
337
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
338
|
+
fontWeight: tokens.typography.fontWeight.bold,
|
|
339
|
+
color: tokens.colors.status.critical,
|
|
340
|
+
marginBottom: tokens.spacing.sm,
|
|
341
|
+
fontSize: tokens.typography.fontSize.sm
|
|
342
|
+
}, children: "Confirm Hazardous Command" }),
|
|
343
|
+
/* @__PURE__ */ jsx("p", { style: {
|
|
344
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
345
|
+
color: tokens.colors.text.secondary,
|
|
346
|
+
marginBottom: tokens.spacing.smd,
|
|
347
|
+
lineHeight: tokens.typography.lineHeight.normal
|
|
348
|
+
}, children: hazardousDescription || `Are you sure you want to send ${target} ${command}?` }),
|
|
349
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: tokens.spacing.sm }, children: [
|
|
350
|
+
/* @__PURE__ */ jsx(
|
|
351
|
+
"button",
|
|
352
|
+
{
|
|
353
|
+
onClick: handleSend,
|
|
354
|
+
style: {
|
|
355
|
+
background: tokens.colors.status.critical,
|
|
356
|
+
color: tokens.colors.text.inverse,
|
|
357
|
+
border: "none",
|
|
358
|
+
borderRadius: tokens.borderRadius.md,
|
|
359
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
|
|
360
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
361
|
+
fontWeight: tokens.typography.fontWeight.medium,
|
|
362
|
+
cursor: "pointer",
|
|
363
|
+
transition: "opacity 150ms ease"
|
|
364
|
+
},
|
|
365
|
+
children: "Confirm Send"
|
|
366
|
+
}
|
|
367
|
+
),
|
|
368
|
+
/* @__PURE__ */ jsx(
|
|
369
|
+
"button",
|
|
370
|
+
{
|
|
371
|
+
onClick: () => setShowConfirm(false),
|
|
372
|
+
style: {
|
|
373
|
+
background: tokens.colors.background.base,
|
|
374
|
+
color: tokens.colors.text.secondary,
|
|
375
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
376
|
+
borderRadius: tokens.borderRadius.md,
|
|
377
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,
|
|
378
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
379
|
+
cursor: "pointer",
|
|
380
|
+
transition: "opacity 150ms ease"
|
|
381
|
+
},
|
|
382
|
+
children: "Cancel"
|
|
383
|
+
}
|
|
384
|
+
)
|
|
385
|
+
] })
|
|
386
|
+
] }),
|
|
387
|
+
!showConfirm && /* @__PURE__ */ jsxs("div", { style: {
|
|
388
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
389
|
+
borderTop: `1px solid ${tokens.colors.border.muted}`,
|
|
390
|
+
background: tokens.colors.background.surface,
|
|
391
|
+
display: "flex",
|
|
392
|
+
alignItems: "center",
|
|
393
|
+
justifyContent: "space-between"
|
|
394
|
+
}, children: [
|
|
395
|
+
/* @__PURE__ */ jsx("button", { onClick: resetToDefaults, "aria-label": "Reset all parameters to defaults", style: {
|
|
396
|
+
background: "transparent",
|
|
397
|
+
color: tokens.colors.text.muted,
|
|
398
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
399
|
+
borderRadius: tokens.borderRadius.md,
|
|
400
|
+
padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,
|
|
401
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
402
|
+
cursor: "pointer",
|
|
403
|
+
transition: "all 150ms ease"
|
|
404
|
+
}, children: "Reset Defaults" }),
|
|
405
|
+
/* @__PURE__ */ jsx(
|
|
406
|
+
"button",
|
|
407
|
+
{
|
|
408
|
+
onClick: handleSend,
|
|
409
|
+
disabled: disabled || sending,
|
|
410
|
+
"aria-busy": sending,
|
|
411
|
+
style: {
|
|
412
|
+
background: hazardous ? tokens.colors.status.critical : tokens.colors.interactive.default,
|
|
413
|
+
color: tokens.colors.text.inverse,
|
|
414
|
+
border: "none",
|
|
415
|
+
borderRadius: tokens.borderRadius.md,
|
|
416
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.lg}`,
|
|
417
|
+
fontSize: tokens.typography.fontSize.sm,
|
|
418
|
+
fontWeight: tokens.typography.fontWeight.medium,
|
|
419
|
+
cursor: disabled || sending ? "not-allowed" : "pointer",
|
|
420
|
+
opacity: disabled || sending ? 0.5 : 1,
|
|
421
|
+
transition: "opacity 150ms ease"
|
|
422
|
+
},
|
|
423
|
+
children: sending ? "Sending..." : "Send Command"
|
|
424
|
+
}
|
|
425
|
+
)
|
|
426
|
+
] }),
|
|
427
|
+
showHistoryPanel && history.length > 0 && /* @__PURE__ */ jsxs("div", { role: "list", "aria-label": "Command history", style: {
|
|
428
|
+
borderTop: `1px solid ${tokens.colors.border.muted}`,
|
|
429
|
+
background: tokens.colors.background.surface,
|
|
430
|
+
maxHeight: 200,
|
|
431
|
+
overflow: "auto"
|
|
432
|
+
}, children: [
|
|
433
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
434
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
435
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
436
|
+
color: tokens.colors.text.muted,
|
|
437
|
+
fontWeight: tokens.typography.fontWeight.medium,
|
|
438
|
+
textTransform: "uppercase",
|
|
439
|
+
letterSpacing: "0.5px"
|
|
440
|
+
}, children: "Command History" }),
|
|
441
|
+
history.slice().reverse().map((h) => /* @__PURE__ */ jsx(
|
|
442
|
+
"div",
|
|
443
|
+
{
|
|
444
|
+
role: "listitem",
|
|
445
|
+
style: {
|
|
446
|
+
borderBottom: `1px solid ${tokens.colors.border.muted}`
|
|
447
|
+
},
|
|
448
|
+
children: /* @__PURE__ */ jsxs(
|
|
449
|
+
"button",
|
|
450
|
+
{
|
|
451
|
+
type: "button",
|
|
452
|
+
"aria-label": `${h.status} at ${h.timestamp.toLocaleTimeString()}`,
|
|
453
|
+
style: {
|
|
454
|
+
width: "100%",
|
|
455
|
+
textAlign: "left",
|
|
456
|
+
padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,
|
|
457
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
458
|
+
display: "flex",
|
|
459
|
+
alignItems: "center",
|
|
460
|
+
gap: tokens.spacing.sm,
|
|
461
|
+
cursor: "pointer",
|
|
462
|
+
transition: "background 150ms ease",
|
|
463
|
+
border: "none",
|
|
464
|
+
background: "transparent",
|
|
465
|
+
color: "inherit"
|
|
466
|
+
},
|
|
467
|
+
onClick: () => setValues(h.parameters),
|
|
468
|
+
children: [
|
|
469
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: {
|
|
470
|
+
width: 8,
|
|
471
|
+
height: 8,
|
|
472
|
+
flexShrink: 0,
|
|
473
|
+
...h.status === "success" ? {
|
|
474
|
+
borderRadius: tokens.borderRadius.full,
|
|
475
|
+
background: tokens.colors.status.normal
|
|
476
|
+
} : h.status === "error" ? {
|
|
477
|
+
borderRadius: 0,
|
|
478
|
+
background: tokens.colors.status.critical,
|
|
479
|
+
clipPath: "polygon(50% 100%, 0% 0%, 100% 0%)"
|
|
480
|
+
} : {
|
|
481
|
+
borderRadius: tokens.borderRadius.full,
|
|
482
|
+
background: "transparent",
|
|
483
|
+
border: `2px solid ${tokens.colors.status.standby}`
|
|
484
|
+
}
|
|
485
|
+
} }),
|
|
486
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
487
|
+
color: tokens.colors.text.muted,
|
|
488
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
489
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
490
|
+
flexShrink: 0
|
|
491
|
+
}, children: h.timestamp.toLocaleTimeString() }),
|
|
492
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
493
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
494
|
+
fontSize: tokens.typography.fontSize.xxs,
|
|
495
|
+
flex: 1,
|
|
496
|
+
overflow: "hidden",
|
|
497
|
+
textOverflow: "ellipsis",
|
|
498
|
+
whiteSpace: "nowrap"
|
|
499
|
+
}, children: Object.entries(h.parameters).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(", ") }),
|
|
500
|
+
h.error && /* @__PURE__ */ jsx("span", { style: {
|
|
501
|
+
fontSize: tokens.typography.fontSize.micro,
|
|
502
|
+
color: tokens.colors.status.critical
|
|
503
|
+
}, children: h.error })
|
|
504
|
+
]
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
},
|
|
508
|
+
h.id
|
|
509
|
+
))
|
|
510
|
+
] })
|
|
511
|
+
]
|
|
512
|
+
}
|
|
513
|
+
);
|
|
514
|
+
});
|
|
515
|
+
export {
|
|
516
|
+
CommandBuilder
|
|
517
|
+
};
|
|
518
|
+
//# sourceMappingURL=CommandBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandBuilder.js","sources":["../../../src/react/core/CommandBuilder.tsx"],"sourcesContent":["/**\n * @zendir/ui - CommandBuilder Component\n * \n * Dynamic command parameter form for spacecraft command construction and execution.\n * Builds a form from a command definition with type-appropriate inputs,\n * validation, hazardous warnings, and send/history functionality.\n * \n * Features:\n * - Auto-generated form from command parameter definitions\n * - Type-appropriate inputs (number, string, boolean, enum/state, hex)\n * - Validation with min/max/regex constraints\n * - Hazardous command warnings\n * - Command history with re-send\n * - Raw command preview\n * - Required/optional parameter indicators\n * - Default values\n * \n * @example\n * ```tsx\n * <CommandBuilder\n * target=\"INST\"\n * command=\"COLLECT\"\n * parameters={[\n * { name: 'TYPE', type: 'enum', options: ['NORMAL', 'SPECIAL'], required: true },\n * { name: 'DURATION', type: 'float', min: 0, max: 100, default: 1.0, units: 'sec' },\n * ]}\n * onSend={(params) => console.log('Send:', params)}\n * />\n * ```\n */\n\nimport React, { useState, useCallback, useMemo, memo } from 'react';\nimport { useTheme } from '../theme';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type CommandParamType = 'int' | 'uint' | 'float' | 'string' | 'boolean' | 'enum' | 'hex' | 'block';\n\nexport interface CommandParameter {\n /** Parameter name */\n name: string;\n /** Parameter type */\n type: CommandParamType;\n /** Description */\n description?: string;\n /** Default value */\n default?: unknown;\n /** Whether parameter is required (default: true) */\n required?: boolean;\n /** Minimum value (for numeric types) */\n min?: number;\n /** Maximum value (for numeric types) */\n max?: number;\n /** Bit size */\n bitSize?: number;\n /** Enum options (for enum type) */\n options?: (string | number)[];\n /** Units label */\n units?: string;\n /** Validation regex pattern (for string type) */\n pattern?: string;\n /** Whether this is a hazardous parameter */\n hazardous?: boolean;\n /** Hazardous description */\n hazardousDescription?: string;\n}\n\nexport interface CommandHistoryEntry {\n id: string;\n timestamp: Date;\n target: string;\n command: string;\n parameters: Record<string, unknown>;\n status: 'sent' | 'success' | 'error';\n error?: string;\n}\n\nexport interface CommandBuilderProps {\n /** Target name */\n target: string;\n /** Command name */\n command: string;\n /** Command description */\n description?: string;\n /** Whether this is a hazardous command */\n hazardous?: boolean;\n /** Hazardous warning text */\n hazardousDescription?: string;\n /** Command parameters */\n parameters: CommandParameter[];\n /** Called when command is sent */\n onSend: (params: Record<string, unknown>) => void | Promise<void>;\n /** Command history entries */\n history?: CommandHistoryEntry[];\n /** Show command history (default: true) */\n showHistory?: boolean;\n /** Show raw command preview (default: true) */\n showPreview?: boolean;\n /** Whether send is disabled */\n disabled?: boolean;\n /** Height (default: auto) */\n height?: number | string;\n /** CSS class */\n className?: string;\n /** Show outer container border (default: true). Set false when embedded inside a Container/card. */\n bordered?: boolean;\n /** Custom style overrides for the outer container */\n style?: React.CSSProperties;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport const CommandBuilder = memo(function CommandBuilder({\n target,\n command,\n description,\n hazardous = false,\n hazardousDescription,\n parameters,\n onSend,\n history = [],\n showHistory = true,\n showPreview = true,\n disabled = false,\n height,\n className = '',\n bordered = true,\n style: styleProp,\n}: CommandBuilderProps): React.ReactElement {\n const { tokens, theme } = useTheme();\n const isTransparentTheme =\n theme === 'transparent' || theme === 'transparent-bold' || theme === 'transparent-minimal';\n const [values, setValues] = useState<Record<string, unknown>>(() => {\n const defaults: Record<string, unknown> = {};\n parameters.forEach(p => {\n if (p.default !== undefined) defaults[p.name] = p.default;\n else if (p.type === 'boolean') defaults[p.name] = false;\n else if (p.type === 'enum' && p.options?.length) defaults[p.name] = p.options[0];\n else defaults[p.name] = '';\n });\n return defaults;\n });\n const [errors, setErrors] = useState<Record<string, string>>({});\n const [sending, setSending] = useState(false);\n const [showConfirm, setShowConfirm] = useState(false);\n const [showHistoryPanel, setShowHistoryPanel] = useState(false);\n\n const setValue = useCallback((name: string, value: unknown) => {\n setValues(prev => ({ ...prev, [name]: value }));\n setErrors(prev => {\n const next = { ...prev };\n delete next[name];\n return next;\n });\n }, []);\n\n const validate = useCallback((): boolean => {\n const errs: Record<string, string> = {};\n parameters.forEach(p => {\n const val = values[p.name];\n const required = p.required !== false;\n if (required && (val === undefined || val === '' || val === null)) {\n errs[p.name] = 'Required';\n return;\n }\n if (val === '' || val === undefined) return;\n if ((p.type === 'int' || p.type === 'uint' || p.type === 'float') && typeof val === 'string') {\n const num = Number(val);\n if (isNaN(num)) { errs[p.name] = 'Must be a number'; return; }\n if (p.min !== undefined && num < p.min) { errs[p.name] = `Min: ${p.min}`; return; }\n if (p.max !== undefined && num > p.max) { errs[p.name] = `Max: ${p.max}`; return; }\n if (p.type === 'uint' && num < 0) { errs[p.name] = 'Must be >= 0'; return; }\n if (p.type === 'int' && !Number.isInteger(num)) { errs[p.name] = 'Must be integer'; return; }\n }\n if (p.type === 'string' && p.pattern && typeof val === 'string') {\n if (!new RegExp(p.pattern).test(val)) { errs[p.name] = 'Invalid format'; }\n }\n });\n setErrors(errs);\n return Object.keys(errs).length === 0;\n }, [parameters, values]);\n\n const handleSend = useCallback(async () => {\n if (!validate()) return;\n if (hazardous && !showConfirm) {\n setShowConfirm(true);\n return;\n }\n setShowConfirm(false);\n setSending(true);\n try {\n const processedValues: Record<string, unknown> = {};\n parameters.forEach(p => {\n let val = values[p.name];\n if ((p.type === 'int' || p.type === 'uint' || p.type === 'float') && typeof val === 'string') {\n val = Number(val);\n }\n processedValues[p.name] = val;\n });\n await onSend(processedValues);\n } finally {\n setSending(false);\n }\n }, [validate, hazardous, showConfirm, parameters, values, onSend]);\n\n const commandString = useMemo(() => {\n const params = parameters.map(p => `${p.name}=${JSON.stringify(values[p.name] ?? '')}`).join(', ');\n return `cmd(\"${target} ${command}\" ${params ? `with ${params}` : ''})`;\n }, [target, command, parameters, values]);\n\n const resetToDefaults = useCallback(() => {\n const defaults: Record<string, unknown> = {};\n parameters.forEach(p => {\n if (p.default !== undefined) defaults[p.name] = p.default;\n else if (p.type === 'boolean') defaults[p.name] = false;\n else if (p.type === 'enum' && p.options?.length) defaults[p.name] = p.options[0];\n else defaults[p.name] = '';\n });\n setValues(defaults);\n setErrors({});\n }, [parameters]);\n\n const inputStyle: React.CSSProperties = {\n background: tokens.colors.background.base,\n color: tokens.colors.text.primary,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n fontSize: tokens.typography.fontSize.xs,\n outline: 'none',\n fontFamily: tokens.typography.fontFamily.mono,\n width: '100%',\n minHeight: 40,\n boxSizing: 'border-box' as const,\n transition: 'border-color 150ms ease',\n };\n\n return (\n <div\n className={`command-builder ${className}`}\n style={{\n height: typeof height === 'number' ? height : undefined,\n background: tokens.colors.background.base,\n ...(bordered ? (tokens.colors.border.cardStyle ?? { border: `1px solid ${tokens.colors.border.muted}` }) : { border: 'none' }),\n borderRadius: tokens.borderRadius.lg,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n fontFamily: tokens.typography.fontFamily.primary,\n color: tokens.colors.text.primary,\n backdropFilter: isTransparentTheme ? 'blur(10px)' : undefined,\n WebkitBackdropFilter: isTransparentTheme ? 'blur(10px)' : undefined,\n ...styleProp,\n }}\n >\n {/* Header */}\n <div style={{\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n background: hazardous ? `${tokens.colors.status.critical}12` : tokens.colors.background.surface,\n display: 'flex', alignItems: 'center', justifyContent: 'space-between',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: tokens.spacing.sm }}>\n {hazardous && <span role=\"img\" aria-label=\"Hazardous command\" style={{ fontSize: tokens.typography.fontSize.lg }}>⚠</span>}\n <span style={{\n background: `${tokens.colors.interactive.default}22`,\n color: tokens.colors.interactive.default,\n padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,\n borderRadius: tokens.borderRadius.md,\n fontSize: tokens.typography.fontSize.xxs,\n fontWeight: tokens.typography.fontWeight.medium,\n }}>\n {target}\n </span>\n <span style={{ fontWeight: tokens.typography.fontWeight.bold, fontSize: tokens.typography.fontSize.sm }}>{command}</span>\n {hazardous && (\n <span style={{\n background: `${tokens.colors.status.critical}22`,\n color: tokens.colors.status.critical,\n padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,\n borderRadius: tokens.borderRadius.sm,\n fontSize: tokens.typography.fontSize.micro,\n fontWeight: tokens.typography.fontWeight.bold,\n textTransform: 'uppercase',\n letterSpacing: '0.5px',\n }}>\n Hazardous\n </span>\n )}\n </div>\n {showHistory && history.length > 0 && (\n <button\n onClick={() => setShowHistoryPanel(p => !p)}\n aria-expanded={showHistoryPanel}\n aria-label={`Command history (${history.length} entries)`}\n style={{\n background: tokens.colors.background.base,\n color: tokens.colors.text.secondary,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n padding: `${tokens.spacing.xxs} ${tokens.spacing.sm}`,\n fontSize: tokens.typography.fontSize.xxs,\n cursor: 'pointer',\n transition: 'all 150ms ease',\n }}\n >\n History ({history.length})\n </button>\n )}\n </div>\n\n {description && (\n <div style={{\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary,\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n lineHeight: tokens.typography.lineHeight.normal,\n }}>\n {description}\n </div>\n )}\n\n {/* Parameters form */}\n <div role=\"form\" aria-label={`${target} ${command} parameters`} style={{ flex: 1, overflow: 'auto', padding: tokens.spacing.smd }}>\n {parameters.length === 0 ? (\n <div style={{\n color: tokens.colors.text.muted,\n fontSize: tokens.typography.fontSize.xs,\n textAlign: 'center',\n padding: tokens.spacing.xl,\n }}>\n No parameters — command will be sent as-is\n </div>\n ) : (\n <div style={{ display: 'flex', flexDirection: 'column', gap: tokens.spacing.smd }}>\n {parameters.map(p => (\n <div key={p.name}>\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacing.sm,\n marginBottom: tokens.spacing.xs,\n }}>\n <label htmlFor={`cmd-param-${p.name}`} style={{\n fontWeight: tokens.typography.fontWeight.medium,\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.primary,\n }}>\n {p.name}\n {p.required !== false && <span aria-label=\"required\" style={{ color: tokens.colors.status.critical, marginLeft: tokens.spacing.xxs }}>*</span>}\n </label>\n <span style={{\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.muted,\n background: tokens.colors.background.surface,\n padding: `1px ${tokens.spacing.xs}`,\n borderRadius: tokens.borderRadius.sm,\n }}>\n {p.type}{p.bitSize ? ` (${p.bitSize}b)` : ''}\n </span>\n {p.units && <span style={{ fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.interactive.default }}>[{p.units}]</span>}\n {p.hazardous && <span aria-label=\"Hazardous parameter\" style={{ fontSize: tokens.typography.fontSize.xxs, color: tokens.colors.status.critical }}>⚠</span>}\n </div>\n {p.description && (\n <div id={`cmd-param-desc-${p.name}`} style={{\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.muted,\n marginBottom: tokens.spacing.xs,\n lineHeight: tokens.typography.lineHeight.tight,\n }}>\n {p.description}\n </div>\n )}\n \n {/* Input by type */}\n {p.type === 'boolean' ? (\n <label style={{\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacing.sm,\n fontSize: tokens.typography.fontSize.xs,\n cursor: 'pointer',\n }}>\n <input\n id={`cmd-param-${p.name}`}\n type=\"checkbox\"\n checked={!!values[p.name]}\n onChange={e => setValue(p.name, e.target.checked)}\n aria-describedby={p.description ? `cmd-param-desc-${p.name}` : undefined}\n style={{ accentColor: tokens.colors.interactive.default }}\n />\n {values[p.name] ? 'TRUE' : 'FALSE'}\n </label>\n ) : p.type === 'enum' ? (\n <select\n id={`cmd-param-${p.name}`}\n value={String(values[p.name] ?? '')}\n onChange={e => setValue(p.name, e.target.value)}\n aria-describedby={p.description ? `cmd-param-desc-${p.name}` : undefined}\n style={inputStyle}\n >\n {p.options?.map(opt => (\n <option key={String(opt)} value={String(opt)}>{String(opt)}</option>\n ))}\n </select>\n ) : (\n <input\n id={`cmd-param-${p.name}`}\n type={p.type === 'int' || p.type === 'uint' || p.type === 'float' ? 'number' : 'text'}\n value={String(values[p.name] ?? '')}\n onChange={e => setValue(p.name, e.target.value)}\n placeholder={p.default !== undefined ? `Default: ${p.default}` : undefined}\n min={p.min} max={p.max}\n step={p.type === 'float' ? 'any' : 1}\n aria-describedby={p.description ? `cmd-param-desc-${p.name}` : undefined}\n aria-invalid={!!errors[p.name]}\n style={{\n ...inputStyle,\n borderColor: errors[p.name] ? tokens.colors.status.critical : tokens.colors.border.muted,\n }}\n />\n )}\n {errors[p.name] && (\n <span role=\"alert\" style={{\n display: 'block',\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.status.critical,\n marginTop: tokens.spacing.xxs,\n }}>\n {errors[p.name]}\n </span>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Command preview */}\n {showPreview && (\n <div aria-label=\"Command preview\" style={{\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n background: tokens.colors.background.surface,\n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.muted,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}>\n {commandString}\n </div>\n )}\n\n {/* Hazardous confirmation */}\n {showConfirm && (\n <div role=\"alertdialog\" aria-label=\"Confirm hazardous command\" style={{\n padding: tokens.spacing.smd,\n borderTop: `1px solid ${tokens.colors.status.critical}44`,\n background: `${tokens.colors.status.critical}12`,\n }}>\n <div style={{\n fontWeight: tokens.typography.fontWeight.bold,\n color: tokens.colors.status.critical,\n marginBottom: tokens.spacing.sm,\n fontSize: tokens.typography.fontSize.sm,\n }}>\n Confirm Hazardous Command\n </div>\n <p style={{\n fontSize: tokens.typography.fontSize.xs,\n color: tokens.colors.text.secondary,\n marginBottom: tokens.spacing.smd,\n lineHeight: tokens.typography.lineHeight.normal,\n }}>\n {hazardousDescription || `Are you sure you want to send ${target} ${command}?`}\n </p>\n <div style={{ display: 'flex', gap: tokens.spacing.sm }}>\n <button\n onClick={handleSend}\n style={{\n background: tokens.colors.status.critical,\n color: tokens.colors.text.inverse,\n border: 'none',\n borderRadius: tokens.borderRadius.md,\n padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,\n fontSize: tokens.typography.fontSize.xs,\n fontWeight: tokens.typography.fontWeight.medium,\n cursor: 'pointer',\n transition: 'opacity 150ms ease',\n }}\n >\n Confirm Send\n </button>\n <button\n onClick={() => setShowConfirm(false)}\n style={{\n background: tokens.colors.background.base,\n color: tokens.colors.text.secondary,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n padding: `${tokens.spacing.sm} ${tokens.spacing.md}`,\n fontSize: tokens.typography.fontSize.xs,\n cursor: 'pointer',\n transition: 'opacity 150ms ease',\n }}\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {/* Send button bar */}\n {!showConfirm && (\n <div style={{\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n background: tokens.colors.background.surface,\n display: 'flex', alignItems: 'center', justifyContent: 'space-between',\n }}>\n <button onClick={resetToDefaults} aria-label=\"Reset all parameters to defaults\" style={{\n background: 'transparent',\n color: tokens.colors.text.muted,\n border: `1px solid ${tokens.colors.border.muted}`,\n borderRadius: tokens.borderRadius.md,\n padding: `${tokens.spacing.xs} ${tokens.spacing.sm}`,\n fontSize: tokens.typography.fontSize.xxs,\n cursor: 'pointer',\n transition: 'all 150ms ease',\n }}>\n Reset Defaults\n </button>\n <button\n onClick={handleSend}\n disabled={disabled || sending}\n aria-busy={sending}\n style={{\n background: hazardous ? tokens.colors.status.critical : tokens.colors.interactive.default,\n color: tokens.colors.text.inverse,\n border: 'none',\n borderRadius: tokens.borderRadius.md,\n padding: `${tokens.spacing.sm} ${tokens.spacing.lg}`,\n fontSize: tokens.typography.fontSize.sm,\n fontWeight: tokens.typography.fontWeight.medium,\n cursor: disabled || sending ? 'not-allowed' : 'pointer',\n opacity: disabled || sending ? 0.5 : 1,\n transition: 'opacity 150ms ease',\n }}\n >\n {sending ? 'Sending...' : 'Send Command'}\n </button>\n </div>\n )}\n\n {/* History panel */}\n {showHistoryPanel && history.length > 0 && (\n <div role=\"list\" aria-label=\"Command history\" style={{\n borderTop: `1px solid ${tokens.colors.border.muted}`,\n background: tokens.colors.background.surface,\n maxHeight: 200, overflow: 'auto',\n }}>\n <div style={{\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n fontSize: tokens.typography.fontSize.xxs,\n color: tokens.colors.text.muted,\n fontWeight: tokens.typography.fontWeight.medium,\n textTransform: 'uppercase',\n letterSpacing: '0.5px',\n }}>\n Command History\n </div>\n {history.slice().reverse().map(h => (\n <div\n role=\"listitem\"\n key={h.id}\n style={{\n borderBottom: `1px solid ${tokens.colors.border.muted}`,\n }}\n >\n <button\n type=\"button\"\n aria-label={`${h.status} at ${h.timestamp.toLocaleTimeString()}`}\n style={{\n width: '100%',\n textAlign: 'left',\n padding: `${tokens.spacing.sm} ${tokens.spacing.smd}`,\n fontSize: tokens.typography.fontSize.xxs,\n display: 'flex',\n alignItems: 'center',\n gap: tokens.spacing.sm,\n cursor: 'pointer',\n transition: 'background 150ms ease',\n border: 'none',\n background: 'transparent',\n color: 'inherit',\n }}\n onClick={() => setValues(h.parameters)}\n >\n {/* Astro UX status shape */}\n <span aria-hidden=\"true\" style={{\n width: 8, height: 8, flexShrink: 0,\n ...(h.status === 'success' ? {\n borderRadius: tokens.borderRadius.full,\n background: tokens.colors.status.normal,\n } : h.status === 'error' ? {\n borderRadius: 0,\n background: tokens.colors.status.critical,\n clipPath: 'polygon(50% 100%, 0% 0%, 100% 0%)',\n } : {\n borderRadius: tokens.borderRadius.full,\n background: 'transparent',\n border: `2px solid ${tokens.colors.status.standby}`,\n }),\n }} />\n <span style={{\n color: tokens.colors.text.muted,\n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: tokens.typography.fontSize.xxs,\n flexShrink: 0,\n }}>\n {h.timestamp.toLocaleTimeString()}\n </span>\n <span style={{\n fontFamily: tokens.typography.fontFamily.mono,\n fontSize: tokens.typography.fontSize.xxs,\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}>\n {Object.entries(h.parameters).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(', ')}\n </span>\n {h.error && <span style={{\n fontSize: tokens.typography.fontSize.micro,\n color: tokens.colors.status.critical,\n }}>\n {h.error}\n </span>}\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n});\n\nexport default CommandBuilder;\n"],"names":["CommandBuilder"],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export type ConfirmStatus = 'normal' | 'caution' | 'serious' | 'critical';
|
|
4
|
+
export interface ConfirmOptions {
|
|
5
|
+
/** Dialog title */
|
|
6
|
+
title: string;
|
|
7
|
+
/** Description text (string or React node) */
|
|
8
|
+
message?: React.ReactNode;
|
|
9
|
+
/** Status level (determines icon/border color) */
|
|
10
|
+
status?: ConfirmStatus;
|
|
11
|
+
/** Confirm button label (default: "Confirm") */
|
|
12
|
+
confirmLabel?: string;
|
|
13
|
+
/** Cancel button label (default: "Cancel") */
|
|
14
|
+
cancelLabel?: string;
|
|
15
|
+
/** Destructive action styling (red confirm button) */
|
|
16
|
+
destructive?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ConfirmDialogProps extends ConfirmOptions {
|
|
19
|
+
/** Open state */
|
|
20
|
+
open: boolean;
|
|
21
|
+
/** Close handler */
|
|
22
|
+
onClose: () => void;
|
|
23
|
+
/** Confirm handler */
|
|
24
|
+
onConfirm: () => void;
|
|
25
|
+
}
|
|
26
|
+
export declare const ConfirmDialog: React.NamedExoticComponent<ConfirmDialogProps>;
|
|
27
|
+
/**
|
|
28
|
+
* Imperative confirmation hook.
|
|
29
|
+
* Must be used within `<ConfirmProvider>`.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const confirm = useConfirm();
|
|
34
|
+
* const ok = await confirm({ title: 'Delete?', status: 'critical', destructive: true });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function useConfirm(): (options: ConfirmOptions) => Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Provider for the useConfirm() hook.
|
|
40
|
+
* Renders the confirmation dialog as needed.
|
|
41
|
+
*/
|
|
42
|
+
export declare const ConfirmProvider: React.NamedExoticComponent<{
|
|
43
|
+
children: React.ReactNode;
|
|
44
|
+
}>;
|
|
45
|
+
export default ConfirmDialog;
|