aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
431 lines (428 loc) • 16.3 kB
JavaScript
'use client';
import { jsxs, jsx } from 'react/jsx-runtime';
import { useReducedMotion } from '../../hooks/useReducedMotion.js';
import { forwardRef, useState, useEffect, useMemo } from 'react';
import { motion } from 'framer-motion';
import '../../primitives/GlassCore.js';
import '../../primitives/glass/GlassAdvanced.js';
import { OptimizedGlassCore } from '../../primitives/OptimizedGlassCore.js';
import '../../primitives/glass/OptimizedGlassAdvanced.js';
import '../../primitives/MotionNative.js';
import '../../primitives/motion/MotionFramer.js';
import { useA11yId } from '../../utils/a11y.js';
import { useMotionPreference } from '../../hooks/useMotionPreference.js';
import { createGlassStyle } from '../../utils/createGlassStyle.js';
import { cn } from '../../lib/utilsComprehensive.js';
const phaseColors = {
0: '#FF6B6B',
// 0°
90: '#4ECDC4',
// 90°
180: '#45B7D1',
// 180°
270: '#96CEB4' // 270°
};
const getPhaseColor = phase => {
const normalizedPhase = phase % (2 * Math.PI) / (2 * Math.PI) * 360;
if (normalizedPhase < 45 || normalizedPhase >= 315) return phaseColors[0];
if (normalizedPhase < 135) return phaseColors[90];
if (normalizedPhase < 225) return phaseColors[180];
return phaseColors[270];
};
const GlassCoherenceIndicator = /*#__PURE__*/forwardRef(({
coherenceLevel = 0,
phase = 0,
decoherenceRate = 0.02,
entanglementStrength = 0,
historicalData = [],
showPhaseIndicator = true,
showWaveVisualization = true,
showDecoherenceRate = true,
showEntanglement = true,
realTimeMode = false,
coherenceThreshold = 0.3,
alertOnDecoherence = true,
animationSpeed = 1,
onCoherenceLoss,
onPhaseChange,
className = '',
...props
}, ref) => {
const prefersReducedMotion = useReducedMotion();
const normalizedCoherence = Number.isFinite(coherenceLevel) ? Math.max(0, Math.min(1, coherenceLevel)) : 0;
const normalizedPhase = Number.isFinite(phase) ? phase : 0;
const normalizedDecoherence = Number.isFinite(decoherenceRate) ? Math.max(0, decoherenceRate) : 0.02;
const normalizedEntanglement = Number.isFinite(entanglementStrength) ? Math.max(0, entanglementStrength) : 0;
const safeHistoricalData = Array.isArray(historicalData) ? historicalData : [];
const [currentCoherence, setCurrentCoherence] = useState(normalizedCoherence);
const [currentPhase, setCurrentPhase] = useState(normalizedPhase);
const [animationTime, setAnimationTime] = useState(0);
const [isDecohering, setIsDecohering] = useState(false);
const [coherenceHistory, setCoherenceHistory] = useState(safeHistoricalData);
useA11yId('glass-coherence-indicator');
const {
shouldAnimate
} = useMotionPreference();
// Real-time coherence simulation
useEffect(() => {
if (!realTimeMode) return;
const interval = setInterval(() => {
setCurrentCoherence(prev => {
const noise = (Math.random() - 0.5) * 0.1;
const decay = prev * (1 - normalizedDecoherence);
const newCoherence = Math.max(0, Math.min(1, decay + noise));
if (newCoherence < coherenceThreshold && prev >= coherenceThreshold) {
setIsDecohering(true);
if (alertOnDecoherence) {
onCoherenceLoss?.(newCoherence);
}
} else if (newCoherence >= coherenceThreshold) {
setIsDecohering(false);
}
return newCoherence;
});
setCurrentPhase(prev => {
const newPhase = (prev + 0.1 * animationSpeed) % (2 * Math.PI);
onPhaseChange?.(newPhase);
return newPhase;
});
setAnimationTime(prev => prev + 0.1 * animationSpeed);
}, 100);
return () => clearInterval(interval);
}, [realTimeMode, normalizedDecoherence, coherenceThreshold, alertOnDecoherence, animationSpeed, onCoherenceLoss, onPhaseChange]);
// Update historical data
useEffect(() => {
if (realTimeMode) {
const newDataPoint = {
timestamp: Date.now(),
coherence: currentCoherence,
phase: currentPhase,
amplitude: currentCoherence,
frequency: 1.0,
decoherenceRate: normalizedDecoherence,
entanglementStrength: normalizedEntanglement
};
setCoherenceHistory(prev => [...prev.slice(-49), newDataPoint] // Keep last 50 points
);
}
}, [currentCoherence, currentPhase, realTimeMode, normalizedDecoherence, normalizedEntanglement]);
const coherenceStatus = useMemo(() => {
if (currentCoherence >= 0.8) return {
label: 'Highly Coherent',
color: 'var(--glass-color-success)'
};
if (currentCoherence >= 0.5) return {
label: 'Moderately Coherent',
color: 'var(--glass-color-warning)'
};
if (currentCoherence >= 0.2) return {
label: 'Low Coherence',
color: 'var(--glass-color-danger)'
};
return {
label: 'Decoherent',
color: '#7F1D1D'
};
}, [currentCoherence]);
const WaveVisualization = () => {
const points = 100;
const waveData = useMemo(() => {
return Array.from({
length: points
}, (_, i) => {
const x = i / points * 4 * Math.PI;
const amplitude = currentCoherence;
const wave1 = amplitude * Math.sin(x + currentPhase);
const wave2 = normalizedEntanglement * amplitude * Math.sin(x + currentPhase + Math.PI / 2);
return {
x: i / points * 300,
y1: 50 + wave1 * 30,
y2: 50 + wave2 * 20,
combined: 50 + (wave1 + wave2 * 0.5) * 25
};
});
}, [currentCoherence, currentPhase, normalizedEntanglement, points]);
return jsxs("svg", {
width: "300",
height: "100",
className: cn("glass-border glass-border-primary glass-radius glass-surface-dark"),
children: [jsx("defs", {
children: jsx("pattern", {
id: "grid",
width: "20",
height: "20",
patternUnits: "userSpaceOnUse",
children: jsx("path", {
d: "M 20 0 L 0 0 0 20",
fill: "none",
stroke: "var(--glass-bg-default)",
strokeWidth: "1"
})
})
}), jsx("rect", {
width: "100%",
height: "100%",
fill: "url(#grid)"
}), jsx("line", {
x1: "0",
y1: "50",
x2: "300",
y2: "50",
stroke: "var(--glass-bg-hover)",
strokeWidth: "1",
strokeDasharray: "5,5"
}), jsx("path", {
d: `M ${waveData.map(p => `${p.x} ${p.y1}`).join(' L ')}`,
fill: "none",
stroke: getPhaseColor(currentPhase),
strokeWidth: "2",
opacity: currentCoherence
}), normalizedEntanglement > 0 && jsx("path", {
d: `M ${waveData.map(p => `${p.x} ${p.y2}`).join(' L ')}`,
fill: "none",
stroke: "#FF9FF3",
strokeWidth: "1.5",
opacity: normalizedEntanglement * 0.8,
strokeDasharray: "3,3"
}), normalizedEntanglement > 0.3 && jsx("path", {
d: `M ${waveData.map(p => `${p.x} ${p.combined}`).join(' L ')}`,
fill: "none",
stroke: "var(--glass-white)",
strokeWidth: "1",
opacity: 0.6
}), isDecohering && jsx("g", {
opacity: "0.7",
children: Array.from({
length: 20
}, (_, i) => jsx("circle", {
cx: Math.random() * 300,
cy: Math.random() * 100,
r: Math.random() * 3 + 1,
fill: "var(--glass-color-danger)",
opacity: Math.random() * 0.8,
children: jsx("animate", {
attributeName: "opacity",
values: "0;0.8;0",
dur: `${1 + Math.random()}s`,
repeatCount: "indefinite"
})
}, i))
})]
});
};
const PhaseIndicator = () => jsxs("div", {
className: cn("glass-relative glass-w-24 glass-h-24"),
children: [jsxs("svg", {
width: "96",
height: "96",
className: cn("glass-absolute glass-inset-0"),
children: [jsx("circle", {
cx: "48",
cy: "48",
r: "40",
fill: "none",
stroke: "var(--glass-bg-hover)",
strokeWidth: "2"
}), [0, 90, 180, 270].map(angle => jsxs("g", {
children: [jsx("line", {
x1: 48 + Math.cos(angle * Math.PI / 180) * 35,
y1: 48 + Math.sin(angle * Math.PI / 180) * 35,
x2: 48 + Math.cos(angle * Math.PI / 180) * 42,
y2: 48 + Math.sin(angle * Math.PI / 180) * 42,
stroke: "var(--glass-border-hover)",
strokeWidth: "2"
}), jsxs("text", {
x: 48 + Math.cos(angle * Math.PI / 180) * 30,
y: 48 + Math.sin(angle * Math.PI / 180) * 30 + 3,
textAnchor: "middle",
fontSize: "10",
fill: "rgba(var(--glass-color-white) / var(--glass-opacity-70))",
children: [angle, "\u00B0"]
})]
}, angle)), jsx(motion.line, {
x1: "48",
y1: "48",
x2: 48 + Math.cos(currentPhase - Math.PI / 2) * (30 * currentCoherence),
y2: 48 + Math.sin(currentPhase - Math.PI / 2) * (30 * currentCoherence),
stroke: getPhaseColor(currentPhase),
strokeWidth: "3",
strokeLinecap: "round",
animate: prefersReducedMotion ? {} : {
x2: 48 + Math.cos(currentPhase - Math.PI / 2) * (30 * currentCoherence),
y2: 48 + Math.sin(currentPhase - Math.PI / 2) * (30 * currentCoherence)
},
transition: shouldAnimate ? {
duration: 0.1
} : {
duration: 0
}
}), jsx("circle", {
cx: "48",
cy: "48",
r: "3",
fill: getPhaseColor(currentPhase)
})]
}), jsx("div", {
className: cn("glass-absolute glass-inset-0 glass-flex glass-items-center glass-justify-center"),
children: jsx("div", {
className: cn("glass-text-center"),
children: jsxs("div", {
className: cn("glass-text-xs glass-text-primary glass-font-medium"),
children: [(currentPhase * 180 / Math.PI).toFixed(0), "\u00B0"]
})
})
})]
});
return jsxs(OptimizedGlassCore, {
ref: ref,
variant: "frosted",
className: cn("glass-p-4 glass-space-y-4", className),
...props,
children: [jsxs("div", {
className: cn("glass-flex glass-items-center glass-justify-between"),
children: [jsxs("div", {
children: [jsx("h3", {
className: cn("glass-text-lg glass-font-semibold glass-text-primary"),
children: "Quantum Coherence"
}), jsx("p", {
className: cn("glass-text-sm glass-text-secondary"),
children: coherenceStatus.label
})]
}), jsxs("div", {
className: cn("glass-flex glass-items-center glass-space-x-4"),
children: [isDecohering && alertOnDecoherence && jsxs(motion.div, {
className: cn("glass-flex glass-items-center glass-space-x-1 glass-text-danger"),
animate: prefersReducedMotion ? {} : {
opacity: [1, 0.5, 1]
},
transition: prefersReducedMotion ? {
duration: 0
} : {
duration: 1,
repeat: Infinity
},
children: [jsx("span", {
children: "\u26A0\uFE0F"
}), jsx("span", {
className: cn("glass-text-xs glass-font-medium"),
children: "Decoherence"
})]
}), realTimeMode && jsxs("div", {
className: cn("glass-flex glass-items-center glass-space-x-1 glass-text-success"),
children: [jsx("div", {
className: cn("glass-w-2 glass-h-2 glass-surface-success glass-radius-full glass-animate-pulse")
}), jsx("span", {
className: cn("glass-text-xs"),
children: "Live"
})]
})]
})]
}), jsxs("div", {
className: cn("glass-flex glass-items-center glass-space-x-6"),
children: [jsxs("div", {
className: cn("glass-flex-1"),
children: [jsxs("div", {
className: cn("glass-flex glass-items-center glass-justify-between glass-mb-2"),
children: [jsx("span", {
className: cn("glass-text-sm glass-text-primary"),
children: "Coherence Level"
}), jsxs("span", {
className: cn("glass-text-sm glass-font-medium glass-text-primary"),
children: [(currentCoherence * 100).toFixed(1), "%"]
})]
}), jsxs("div", {
className: cn("glass-relative glass-h-4 glass-surface-subtle glass-radius-full glass-overflow-hidden"),
children: [jsx(motion.div, {
className: cn("glass-h-full glass-radius-full"),
style: {
background: `linear-gradient(90deg, ${coherenceStatus.color} 0%, ${coherenceStatus.color}80 100%)`
},
animate: {
width: `${currentCoherence * 100}%`
},
transition: shouldAnimate ? {
duration: 0.3
} : {
duration: 0
}
}), jsx("div", {
className: cn("glass-absolute glass-top-0 glass-h-full glass-w-0.5 glass-surface-muted"),
style: {
left: `${coherenceThreshold * 100}%`
}
})]
}), jsxs("div", {
className: cn("glass-flex glass-justify-between glass-mt-1 glass-text-xs glass-text-muted"),
children: [jsx("span", {
children: "0%"
}), jsxs("span", {
children: ["Threshold (", (coherenceThreshold * 100).toFixed(0), "%)"]
}), jsx("span", {
children: "100%"
})]
})]
}), showPhaseIndicator && jsx(PhaseIndicator, {})]
}), showWaveVisualization && jsxs("div", {
children: [jsx("h4", {
className: cn("glass-text-sm glass-font-medium glass-text-primary glass-mb-2"),
children: "Wave Function"
}), jsx(WaveVisualization, {})]
}), jsxs("div", {
className: cn("glass-p-3 glass-radius-lg glass-border glass-border-subtle glass-space-y-2", createGlassStyle({
blur: 'sm',
opacity: 0.6
}).background),
children: [jsxs("div", {
className: cn("glass-grid glass-grid-cols-2 md:glass-grid-cols-4 glass-gap-4 glass-text-sm"),
children: [jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Phase:"
}), jsxs("div", {
className: cn("glass-text-primary glass-font-medium"),
children: [(currentPhase * 180 / Math.PI).toFixed(1), "\u00B0"]
})]
}), showDecoherenceRate && jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Decoherence:"
}), jsxs("div", {
className: cn("glass-text-primary glass-font-medium"),
children: [(decoherenceRate * 100).toFixed(2), "%/s"]
})]
}), showEntanglement && entanglementStrength > 0 && jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Entanglement:"
}), jsxs("div", {
className: cn("glass-text-primary glass-font-medium"),
children: [(entanglementStrength * 100).toFixed(0), "%"]
})]
}), jsxs("div", {
children: [jsx("span", {
className: cn("glass-text-secondary"),
children: "Status:"
}), jsx("div", {
className: cn("glass-font-medium"),
style: {
color: coherenceStatus.color
},
children: currentCoherence >= coherenceThreshold ? 'Stable' : 'Unstable'
})]
})]
}), coherenceHistory.length > 10 && jsx("div", {
className: cn("glass-pt-2 glass-border-t glass-border-subtle"),
children: jsxs("div", {
className: cn("glass-flex glass-items-center glass-justify-between glass-text-xs glass-text-secondary"),
children: [jsx("span", {
children: "Avg Coherence (1m):"
}), jsxs("span", {
children: [(coherenceHistory.slice(-10).reduce((sum, d) => sum + d.coherence, 0) / 10 * 100).toFixed(1), "%"]
})]
})
})]
})]
});
});
export { GlassCoherenceIndicator };
//# sourceMappingURL=GlassCoherenceIndicator.js.map