/**
* Modern Status Indicator Component
* Enhanced status indicators with true color and Unicode support
* Requirements: 12.1, 12.2, 12.3
*/
const React = require("react");
const { Box, Text } = require("ink");
const useModernTerminal = require("../../hooks/useModernTerminal.js");
/**
* Modern status indicator with enhanced visuals
*/
const ModernStatusIndicator = ({
status = "idle",
label = "",
showLabel = true,
size = "medium",
animated = false,
customColor,
customIcon,
...props
}) => {
const { colors, unicode, utils, capabilities } = useModernTerminal();
const [animationFrame, setAnimationFrame] = React.useState(0);
// Status configurations
const statusConfig = {
success: {
color: "#00FF00",
icon: "checkMark",
fallback: "✓",
label: "Success",
},
error: {
color: "#FF0000",
icon: "crossMark",
fallback: "✗",
label: "Error",
},
warning: {
color: "#FFFF00",
icon: "warning",
fallback: "!",
label: "Warning",
},
info: {
color: "#00FFFF",
icon: "info",
fallback: "i",
label: "Info",
},
loading: {
color: "#0080FF",
icon: "spinner",
fallback: "...",
label: "Loading",
animated: true,
},
idle: {
color: "#808080",
icon: "circle",
fallback: "○",
label: "Idle",
},
connected: {
color: "#00FF00",
icon: "filledCircle",
fallback: "●",
label: "Connected",
},
disconnected: {
color: "#FF0000",
icon: "circle",
fallback: "○",
label: "Disconnected",
},
processing: {
color: "#FF8000",
icon: "spinner",
fallback: "⟳",
label: "Processing",
animated: true,
},
};
const config = statusConfig[status] || statusConfig.idle;
const shouldAnimate = animated || config.animated;
// Animation effect
React.useEffect(() => {
if (!shouldAnimate) return;
const interval = setInterval(() => {
setAnimationFrame((frame) => (frame + 1) % 8);
}, 200);
return () => clearInterval(interval);
}, [shouldAnimate]);
// Generate status icon
const generateIcon = () => {
let icon;
if (customIcon) {
icon = customIcon;
} else if (config.icon === "spinner" && shouldAnimate) {
icon = utils.createSpinner(animationFrame);
} else {
icon = unicode.getChar("symbols", config.icon, config.fallback);
}
const iconColor =
customColor ||
(capabilities.trueColor
? colors.getInkColor(config.color)
: config.color.toLowerCase().replace("#", ""));
const sizeStyle = {
small: {},
medium: { bold: true },
large: { bold: true },
};
return (
{icon}
);
};
// Generate status label
const generateLabel = () => {
if (!showLabel) return null;
const labelText = label || config.label;
const labelColor = capabilities.trueColor
? colors.getInkColor("#FFFFFF")
: "white";
return (
{labelText}
);
};
return (
{generateIcon()}
{generateLabel()}
);
};
/**
* Connection status indicator with pulse animation
*/
const ModernConnectionStatus = ({
isConnected = false,
label = "",
showDetails = false,
details = {},
...props
}) => {
const { colors, unicode, capabilities } = useModernTerminal();
const [pulseFrame, setPulseFrame] = React.useState(0);
// Pulse animation for connected state
React.useEffect(() => {
if (!isConnected) return;
const interval = setInterval(() => {
setPulseFrame((frame) => (frame + 1) % 6);
}, 300);
return () => clearInterval(interval);
}, [isConnected]);
const generateConnectionIcon = () => {
if (isConnected) {
// Pulsing connected indicator
const intensity = Math.sin((pulseFrame / 6) * Math.PI * 2) * 0.3 + 0.7;
const baseColor = capabilities.trueColor ? "#00FF00" : "green";
// For true color terminals, we could adjust brightness
// For now, just use the base color
const icon = unicode.getChar("symbols", "filledCircle", "●");
return (
{icon}
);
} else {
// Disconnected indicator
const icon = unicode.getChar("symbols", "circle", "○");
const color = capabilities.trueColor
? colors.getInkColor("#FF0000")
: "red";
return {icon};
}
};
const generateDetails = () => {
if (!showDetails || !details) return null;
return (
{Object.entries(details).map(([key, value]) => (
{key}: {value}
))}
);
};
return (
{generateConnectionIcon()}
{label || (isConnected ? "Connected" : "Disconnected")}
{generateDetails()}
);
};
/**
* Multi-state status indicator
*/
const ModernMultiStateIndicator = ({
states = [],
currentState = 0,
showProgress = false,
orientation = "horizontal",
...props
}) => {
const { colors, unicode, capabilities } = useModernTerminal();
const generateStateIndicators = () => {
return states.map((state, index) => {
const isActive = index === currentState;
const isCompleted = index < currentState;
const isPending = index > currentState;
let icon, color;
if (isCompleted) {
icon = unicode.getChar("symbols", "checkMark", "✓");
color = capabilities.trueColor
? colors.getInkColor("#00FF00")
: "green";
} else if (isActive) {
icon = unicode.getChar("symbols", "pointer", "►");
color = capabilities.trueColor ? colors.getInkColor("#0080FF") : "blue";
} else {
icon = unicode.getChar("symbols", "circle", "○");
color = capabilities.trueColor ? colors.getInkColor("#808080") : "gray";
}
const connector =
index < states.length - 1 ? (
{orientation === "horizontal" ? "─" : "│"}
) : null;
return (
{icon}
{state.label || `State ${index + 1}`}
{connector}
);
});
};
const generateProgress = () => {
if (!showProgress) return null;
const progress = ((currentState + 1) / states.length) * 100;
return (
Progress: {Math.round(progress)}% ({currentState + 1}/{states.length})
);
};
return (
{generateStateIndicators()}
{generateProgress()}
);
};
/**
* Health status indicator with metrics
*/
const ModernHealthIndicator = ({
health = "unknown",
metrics = {},
showMetrics = false,
thresholds = {},
...props
}) => {
const { colors, unicode, utils, capabilities } = useModernTerminal();
// Health status configurations
const healthConfig = {
healthy: {
color: "#00FF00",
icon: "checkMark",
label: "Healthy",
},
degraded: {
color: "#FFFF00",
icon: "warning",
label: "Degraded",
},
unhealthy: {
color: "#FF0000",
icon: "crossMark",
label: "Unhealthy",
},
unknown: {
color: "#808080",
icon: "info",
label: "Unknown",
},
};
const config = healthConfig[health] || healthConfig.unknown;
const generateHealthIcon = () => {
const icon = unicode.getChar("symbols", config.icon, "?");
const color = capabilities.trueColor
? colors.getInkColor(config.color)
: config.color.toLowerCase().replace("#", "");
return (
{icon}
);
};
const generateMetrics = () => {
if (!showMetrics || !metrics) return null;
return (
{Object.entries(metrics).map(([key, value]) => {
const threshold = thresholds[key];
let metricColor = "white";
if (threshold) {
if (value > threshold.critical) {
metricColor = "red";
} else if (value > threshold.warning) {
metricColor = "yellow";
} else {
metricColor = "green";
}
}
return (
{key}: {value}
);
})}
);
};
return (
{generateHealthIcon()}
{config.label}
{generateMetrics()}
);
};
module.exports = {
ModernStatusIndicator,
ModernConnectionStatus,
ModernMultiStateIndicator,
ModernHealthIndicator,
};