UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

935 lines (932 loc) 31.8 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { useReducedMotion } from '../../hooks/useReducedMotion.js'; import { useRef, useState, useEffect, useCallback, useContext, createContext } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { cn } from '../../lib/utilsComprehensive.js'; // Neural network simulation for prediction class PredictiveNeuralNet { constructor(inputSize, hiddenSize, outputSize) { this.learningRate = 0.01; // Initialize weights and biases this.weights = [Array.from({ length: hiddenSize }, () => Array.from({ length: inputSize }, () => Math.random() * 2 - 1)), Array.from({ length: outputSize }, () => Array.from({ length: hiddenSize }, () => Math.random() * 2 - 1))]; this.biases = [Array(hiddenSize).fill(0).map(() => Math.random() * 2 - 1), Array(outputSize).fill(0).map(() => Math.random() * 2 - 1)]; } sigmoid(x) { return 1 / (1 + Math.exp(-x)); } relu(x) { return Math.max(0, x); } forward(inputs) { // Hidden layer const hidden = this.weights[0].map((neuronWeights, i) => { const sum = neuronWeights.reduce((acc, weight, j) => acc + weight * inputs[j], 0) + this.biases[0][i]; return this.relu(sum); }); // Output layer const output = this.weights[1].map((neuronWeights, i) => { const sum = neuronWeights.reduce((acc, weight, j) => acc + weight * hidden[j], 0) + this.biases[1][i]; return this.sigmoid(sum); }); return output; } train(inputs, expectedOutputs) { const outputs = this.forward(inputs); // Simple gradient descent (simplified) const outputErrors = outputs.map((output, i) => expectedOutputs[i] - output); // Update weights (simplified backpropagation) for (let i = 0; i < this.weights[1].length; i++) { for (let j = 0; j < this.weights[1][i].length; j++) { this.weights[1][i][j] += this.learningRate * outputErrors[i] * outputs[i] * (1 - outputs[i]); } } } } // Main predictive engine class class PredictiveUIEngine { constructor() { this.interactions = []; this.patterns = new Map(); this.predictions = []; this.insights = []; this.sessionStartTime = Date.now(); this.neuralNet = new PredictiveNeuralNet(10, 20, 5); // Input, hidden, output sizes this.loadStoredData(); } loadStoredData() { try { const stored = localStorage.getItem("auraglass-predictive-data"); if (stored) { const data = JSON.parse(stored); this.patterns = new Map(data.patterns); // Load recent interactions this.interactions = data.interactions.slice(-1000); // Keep last 1000 } } catch (error) { console.warn("Failed to load predictive data:", error); } } saveData() { try { const data = { patterns: Array.from(this.patterns.entries()), interactions: this.interactions.slice(-100), // Save last 100 timestamp: Date.now() }; localStorage.setItem("auraglass-predictive-data", JSON.stringify(data)); } catch (error) { console.warn("Failed to save predictive data:", error); } } recordInteraction(interaction) { this.interactions.push(interaction); // Keep only recent interactions in memory if (this.interactions.length > 2000) { this.interactions = this.interactions.slice(-1000); } this.analyzePatterns(); this.generatePredictions(); this.saveData(); } analyzePatterns() { const recent = this.interactions.slice(-50); // Analyze sequential patterns this.analyzeSequentialPatterns(recent); // Analyze temporal patterns this.analyzeTemporalPatterns(recent); // Analyze spatial patterns this.analyzeSpatialPatterns(recent); // Analyze contextual patterns this.analyzeContextualPatterns(recent); } analyzeSequentialPatterns(interactions) { for (let i = 0; i < interactions.length - 2; i++) { const sequence = interactions.slice(i, i + 3); const pattern = sequence.map(int => int.element).join(" -> "); const patternId = `seq_${pattern}`; const existing = this.patterns.get(patternId); if (existing) { existing.frequency++; existing.lastSeen = Date.now(); existing.confidence = Math.min(0.95, existing.confidence + 0.05); } else { this.patterns.set(patternId, { id: patternId, type: "sequence", confidence: 0.3, frequency: 1, lastSeen: Date.now(), pattern: sequence.map(int => int.element), prediction: sequence.length > 2 ? "next_in_sequence" : "unknown" }); } } } analyzeTemporalPatterns(interactions) { const timeGroups = new Map(); interactions.forEach(interaction => { const hour = new Date(interaction.timestamp).getHours(); if (!timeGroups.has(hour)) { timeGroups.set(hour, []); } timeGroups.get(hour).push(interaction); }); timeGroups.forEach((hourInteractions, hour) => { const commonElements = this.findCommonElements(hourInteractions); commonElements.forEach(element => { const patternId = `temporal_${hour}_${element}`; const existing = this.patterns.get(patternId); if (existing) { existing.frequency++; existing.confidence = Math.min(0.9, existing.confidence + 0.1); } else { this.patterns.set(patternId, { id: patternId, type: "temporal", confidence: 0.4, frequency: 1, lastSeen: Date.now(), pattern: [hour, element], prediction: "time_based_usage" }); } }); }); } analyzeSpatialPatterns(interactions) { const spatialGroups = new Map(); interactions.forEach(interaction => { if (interaction.context.location) { const region = this.getScreenRegion(interaction.context.location); if (!spatialGroups.has(region)) { spatialGroups.set(region, []); } spatialGroups.get(region).push(interaction); } }); spatialGroups.forEach((regionInteractions, region) => { const commonSequences = this.findSpatialSequences(regionInteractions); commonSequences.forEach((sequence, index) => { const patternId = `spatial_${region}_${index}`; this.patterns.set(patternId, { id: patternId, type: "spatial", confidence: 0.6, frequency: sequence.length, lastSeen: Date.now(), pattern: sequence, prediction: "spatial_flow" }); }); }); } analyzeContextualPatterns(interactions) { const deviceGroups = new Map(); interactions.forEach(interaction => { const device = interaction.context.deviceType; if (!deviceGroups.has(device)) { deviceGroups.set(device, []); } deviceGroups.get(device).push(interaction); }); deviceGroups.forEach((deviceInteractions, device) => { const commonPatterns = this.findContextualPatterns(deviceInteractions); commonPatterns.forEach((pattern, index) => { const patternId = `contextual_${device}_${index}`; this.patterns.set(patternId, { id: patternId, type: "contextual", confidence: 0.7, frequency: pattern.frequency, lastSeen: Date.now(), pattern: pattern.elements, prediction: "context_adaptation" }); }); }); } generatePredictions() { this.predictions = []; const now = Date.now(); // Generate predictions from patterns this.patterns.forEach(pattern => { if (pattern.confidence > 0.5 && now - pattern.lastSeen < 86400000) { // 24 hours const prediction = this.createPredictiveAction(pattern); if (prediction) { this.predictions.push(prediction); } } }); // Use neural network for complex predictions const recentInteractions = this.interactions.slice(-10); if (recentInteractions.length >= 5) { const neuralPredictions = this.generateNeuralPredictions(recentInteractions); this.predictions.push(...neuralPredictions); } // Generate insights this.generateInsights(); // Sort predictions by confidence and timing this.predictions.sort((a, b) => { const confidenceSort = b.confidence - a.confidence; if (Math.abs(confidenceSort) < 0.1) { return a.timing - b.timing; // Sooner is better if confidence is similar } return confidenceSort; }); } createPredictiveAction(pattern) { const actionId = `pred_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; switch (pattern.type) { case "sequence": if (pattern.pattern.length >= 2) { return { id: actionId, type: "preload", target: pattern.pattern[pattern.pattern.length - 1], confidence: pattern.confidence, timing: 500, metadata: { sequence: pattern.pattern } }; } break; case "temporal": const [hour, element] = pattern.pattern; const currentHour = new Date().getHours(); if (Math.abs(currentHour - hour) <= 1) { return { id: actionId, type: "suggest", target: element, confidence: pattern.confidence, timing: 0, metadata: { timeContext: hour } }; } break; case "spatial": return { id: actionId, type: "animate", target: "spatial_indicator", confidence: pattern.confidence, timing: 200, metadata: { spatialPattern: pattern.pattern } }; case "contextual": return { id: actionId, type: "optimize", target: "interface", confidence: pattern.confidence, timing: 0, metadata: { contextPattern: pattern.pattern } }; } return null; } generateNeuralPredictions(interactions) { const predictions = []; // Convert interactions to neural network input const input = this.interactionsToVector(interactions); const output = this.neuralNet.forward(input); // Interpret neural network output as predictions output.forEach((confidence, index) => { if (confidence > 0.6) { predictions.push({ id: `neural_${Date.now()}_${index}`, type: ["preload", "suggest", "animate", "optimize", "pre-render"][index], target: "neural_prediction", confidence, timing: 100 + index * 100, metadata: { neuralOutput: output, inputVector: input } }); } }); return predictions; } generateInsights() { this.insights = []; const interactions = this.interactions.slice(-100); // Performance insights const avgResponseTime = this.calculateAverageResponseTime(interactions); if (avgResponseTime > 200) { this.insights.push({ id: "perf_response_time", category: "performance", insight: `Average interaction response time is ${avgResponseTime}ms`, confidence: 0.9, impact: 0.8, recommendation: "Consider preloading frequently accessed components" }); } // Usability insights const abandonmentRate = this.calculateAbandonmentRate(interactions); if (abandonmentRate > 0.3) { this.insights.push({ id: "usability_abandonment", category: "usability", insight: `High abandonment rate detected: ${(abandonmentRate * 100).toFixed(1)}%`, confidence: 0.85, impact: 0.9, recommendation: "Simplify navigation flow and reduce friction points" }); } // Engagement insights const sessionDuration = Date.now() - this.sessionStartTime; if (sessionDuration > 600000 && interactions.length > 50) { this.insights.push({ id: "engagement_high", category: "engagement", insight: "High engagement session detected", confidence: 0.95, impact: 0.7, recommendation: "Capture user preferences for future personalization" }); } } // Helper methods findCommonElements(interactions) { const elementCount = new Map(); interactions.forEach(int => { elementCount.set(int.element, (elementCount.get(int.element) || 0) + 1); }); return Array.from(elementCount.entries()).filter(([_, count]) => count >= 2).map(([element]) => element); } getScreenRegion(location) { const { x, y } = location; const screenWidth = window.innerWidth; const screenHeight = window.innerHeight; const col = x < screenWidth / 3 ? "left" : x < screenWidth * 2 / 3 ? "center" : "right"; const row = y < screenHeight / 3 ? "top" : y < screenHeight * 2 / 3 ? "middle" : "bottom"; return `${row}_${col}`; } findSpatialSequences(interactions) { const sequences = []; for (let i = 0; i < interactions.length - 1; i++) { const sequence = [interactions[i].element, interactions[i + 1].element]; sequences.push(sequence); } return sequences; } findContextualPatterns(interactions) { const patterns = []; const elementCount = new Map(); interactions.forEach(int => { elementCount.set(int.element, (elementCount.get(int.element) || 0) + 1); }); elementCount.forEach((frequency, element) => { if (frequency >= 2) { patterns.push({ elements: [element], frequency }); } }); return patterns; } interactionsToVector(interactions) { const vector = new Array(10).fill(0); interactions.forEach((interaction, index) => { if (index < 5) { vector[index] = this.hashString(interaction.element) % 100 / 100; vector[index + 5] = interaction.context.timeOfDay / 24; } }); return vector; } hashString(str) { let hash = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; // Convert to 32-bit integer } return Math.abs(hash); } calculateAverageResponseTime(interactions) { const times = interactions.filter(int => int.metadata.responseTime).map(int => int.metadata.responseTime); return times.length > 0 ? times.reduce((sum, time) => sum + time, 0) / times.length : 0; } calculateAbandonmentRate(interactions) { const sequences = []; let currentSequence = []; interactions.forEach(int => { if (int.type === "navigate") { if (currentSequence.length > 0) { sequences.push(currentSequence); } currentSequence = [int]; } else { currentSequence.push(int); } }); if (currentSequence.length > 0) { sequences.push(currentSequence); } const abandonedSequences = sequences.filter(seq => seq.length < 3 && seq[seq.length - 1]?.metadata?.completed !== true); return sequences.length > 0 ? abandonedSequences.length / sequences.length : 0; } // Public API getPredictions() { return [...this.predictions]; } getInsights() { return [...this.insights]; } getPatterns() { return Array.from(this.patterns.values()); } async generateWorkflowSuggestions(context) { // Generate workflow suggestions based on current board state const suggestions = []; // Analyze interaction patterns to suggest workflow improvements const recentInteractions = this.interactions.slice(-20); const taskMovement = recentInteractions.filter(i => i.type === "click" && i.element === "card"); if (taskMovement.length > 5) { suggestions.push({ type: "reorganize", title: "Consider reorganizing your workflow", description: "High card movement suggests your current organization may need optimization", priority: "medium" }); } // Suggest based on completion patterns const completionPatterns = recentInteractions.filter(i => i.metadata?.action === "complete"); if (completionPatterns.length > 0) { suggestions.push({ type: "automation", title: "Consider automating repetitive tasks", description: "Detected repetitive completion patterns that could be automated", priority: "low" }); } return suggestions; } async analyzeBoardPerformance(context) { // Analyze board performance metrics const recentInteractions = this.interactions.slice(-50); const avgResponseTime = recentInteractions.reduce((sum, i) => sum + (i.metadata?.responseTime || 0), 0) / recentInteractions.length; const abandonmentRate = this.calculateAbandonmentRate(recentInteractions); return { averageResponseTime: avgResponseTime || 0, abandonmentRate: abandonmentRate, interactionCount: recentInteractions.length, efficiency: Math.max(0, 1 - abandonmentRate), suggestions: await this.generateWorkflowSuggestions(context) }; } trainFromFeedback(actionId, wasAccurate) { const action = this.predictions.find(p => p.id === actionId); if (action && action.metadata?.inputVector) { const target = new Array(5).fill(0); target[["preload", "suggest", "animate", "optimize", "pre-render"].indexOf(action.type)] = wasAccurate ? 1 : 0; this.neuralNet.train(action.metadata.inputVector, target); } } } // React Context for the predictive engine const PredictiveEngineContext = /*#__PURE__*/createContext({ engine: null, recordInteraction: () => {}, predictions: [], insights: [] }); // Provider component function GlassPredictiveEngineProvider({ children, onPrediction, onInsight }) { useReducedMotion(); const engineRef = useRef(); const [predictions, setPredictions] = useState([]); const [insights, setInsights] = useState([]); // Initialize engine useEffect(() => { engineRef.current = new PredictiveUIEngine(); }, []); const recordInteraction = useCallback(interaction => { if (!engineRef.current) return; const fullInteraction = { ...interaction, timestamp: Date.now() }; engineRef.current.recordInteraction(fullInteraction); // Update predictions and insights const newPredictions = engineRef.current.getPredictions(); const newInsights = engineRef.current.getInsights(); setPredictions(newPredictions); setInsights(newInsights); // Trigger callbacks for new items newPredictions.forEach(prediction => onPrediction?.(prediction)); newInsights.forEach(insight => onInsight?.(insight)); }, [onPrediction, onInsight]); // Auto-record viewport changes and device type useEffect(() => { const getDeviceType = () => { const width = window.innerWidth; if (width < 768) return "mobile"; if (width < 1024) return "tablet"; return "desktop"; }; const handleResize = () => { recordInteraction({ type: "resize", element: "viewport", context: { viewport: { width: window.innerWidth, height: window.innerHeight }, timeOfDay: new Date().getHours(), deviceType: getDeviceType() }, metadata: { trigger: "resize" } }); }; window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, [recordInteraction]); const value = { engine: engineRef.current || null, recordInteraction, predictions, insights }; return jsx(PredictiveEngineContext.Provider, { value: value, children: children }); } // Hook to use the predictive engine function usePredictiveEngine() { const context = useContext(PredictiveEngineContext); if (!context) { throw new Error("usePredictiveEngine must be used within GlassPredictiveEngineProvider"); } return context; } // Component to display predictions function GlassPredictionIndicator({ className, showInsights = true, maxPredictions = 5 }) { const prefersReducedMotion = useReducedMotion(); const { predictions, insights } = usePredictiveEngine(); const [showPanel, setShowPanel] = useState(false); const topPredictions = predictions.slice(0, maxPredictions); const topInsights = insights.slice(0, 3); return jsxs("div", { className: cn("fixed top-4 right-4 z-50", className), children: [jsx(motion.button, { className: cn("w-12 h-12 glass-radius-full glass-surface-primary glass-elev-3", "flex items-center justify-center glass-text-primary", "transition-all duration-300 hover:scale-105", predictions.length > 0 && "animate-pulse"), onClick: () => setShowPanel(!showPanel), whileHover: { scale: 1.05 }, whileTap: { scale: 0.95 }, children: jsxs("div", { className: 'relative', children: ["\uD83E\uDDE0", predictions.length > 0 && jsx(motion.div, { className: 'absolute glass-top-1 -right-1 w-3 h-3 glass-surface-blue glass-radius-full glass-text-xs text-primary glass-flex glass-items-center glass-justify-center', initial: { scale: 0 }, animate: prefersReducedMotion ? {} : { scale: 1 }, transition: prefersReducedMotion ? { duration: 0 } : { duration: 0.3 }, children: predictions.length })] }) }), jsx(AnimatePresence, { children: showPanel && jsxs(motion.div, { className: cn("absolute top-14 right-0 w-80 max-h-96 overflow-y-auto", "glass-surface-primary glass-elev-4 glass-radius-lg glass-p-4 glass-gap-3"), initial: { opacity: 0, y: -10, scale: 0.95 }, animate: prefersReducedMotion ? {} : { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: -10, scale: 0.95 }, transition: prefersReducedMotion ? { duration: 0 } : { duration: 0.2 }, children: [jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsx("h3", { className: 'glass-text-sm font-medium text-primary', children: "AI Predictions" }), jsx("button", { onClick: () => setShowPanel(false), className: 'glass-text-xs glass-text-secondary hover:text-primary glass-focus glass-touch-target glass-contrast-guard', children: "\u2715" })] }), topPredictions.length > 0 && jsxs("div", { className: "glass-gap-2", children: [jsx("h4", { className: 'glass-text-xs font-medium glass-text-secondary uppercase tracking-wide', children: "Predictions" }), topPredictions.map(prediction => jsx(motion.div, { className: "glass-p-2 glass-surface-secondary glass-radius-md", initial: { opacity: 0, x: -10 }, animate: prefersReducedMotion ? {} : { opacity: 1, x: 0 }, transition: prefersReducedMotion ? { duration: 0 } : { duration: 0.3 }, children: jsxs("div", { className: "glass-flex glass-items-center glass-justify-between", children: [jsxs("span", { className: 'glass-text-sm text-primary capitalize', children: [prediction.type, ": ", prediction.target] }), jsxs("div", { className: "glass-flex glass-items-center glass-gap-1", children: [jsx("div", { className: 'w-2 h-2 glass-radius-full', style: { backgroundColor: prediction.confidence > 0.8 ? "var(--glass-color-success)" : prediction.confidence > 0.6 ? "var(--glass-color-warning)" : "var(--glass-color-danger)" } }), jsxs("span", { className: "glass-text-xs glass-text-secondary", children: [(prediction.confidence * 100).toFixed(0), "%"] })] })] }) }, prediction.id))] }), showInsights && topInsights.length > 0 && jsxs("div", { className: "glass-gap-2", children: [jsx("h4", { className: 'glass-text-xs font-medium glass-text-secondary uppercase tracking-wide', children: "AI Insights" }), topInsights.map(insight => jsxs(motion.div, { className: "glass-p-2 glass-surface-secondary glass-radius-md", initial: { opacity: 0, x: -10 }, animate: prefersReducedMotion ? {} : { opacity: 1, x: 0 }, transition: prefersReducedMotion ? { duration: 0 } : { duration: 0.3 }, children: [jsx("div", { className: 'glass-text-sm text-primary mb-1', children: insight.insight }), jsx("div", { className: "glass-text-xs glass-text-secondary", children: insight.recommendation }), jsxs("div", { className: "glass-flex glass-items-center glass-justify-between glass-mt-1", children: [jsx("span", { className: 'glass-text-xs glass-text-tertiary capitalize', children: insight.category }), jsxs("span", { className: "glass-text-xs glass-text-secondary", children: ["Impact: ", (insight.impact * 100).toFixed(0), "%"] })] })] }, insight.id))] }), predictions.length === 0 && insights.length === 0 && jsx("div", { className: 'text-center glass-text-sm glass-text-secondary glass-py-4', children: "Learning your behavior..." })] }) })] }); } // Hook to automatically record common interactions function useInteractionRecorder(elementId) { const { recordInteraction } = usePredictiveEngine(); const recordClick = useCallback(event => { recordInteraction({ type: "click", element: elementId || event.currentTarget.id || "unknown", context: { viewport: { width: window.innerWidth, height: window.innerHeight }, timeOfDay: new Date().getHours(), deviceType: window.innerWidth < 768 ? "mobile" : window.innerWidth < 1024 ? "tablet" : "desktop", location: { x: event.clientX, y: event.clientY } }, metadata: { button: event.button, ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey } }); }, [recordInteraction, elementId]); const recordHover = useCallback(event => { recordInteraction({ type: "hover", element: elementId || event.currentTarget.id || "unknown", context: { viewport: { width: window.innerWidth, height: window.innerHeight }, timeOfDay: new Date().getHours(), deviceType: window.innerWidth < 768 ? "mobile" : window.innerWidth < 1024 ? "tablet" : "desktop", location: { x: event.clientX, y: event.clientY } }, metadata: { trigger: "hover" } }); }, [recordInteraction, elementId]); const recordFocus = useCallback(event => { recordInteraction({ type: "focus", element: elementId || event.currentTarget.id || "unknown", context: { viewport: { width: window.innerWidth, height: window.innerHeight }, timeOfDay: new Date().getHours(), deviceType: window.innerWidth < 768 ? "mobile" : window.innerWidth < 1024 ? "tablet" : "desktop" }, metadata: { trigger: "focus" } }); }, [recordInteraction, elementId]); return { recordClick, recordHover, recordFocus }; } // Presets for different prediction modes const predictiveEnginePresets = { conservative: { neuralNetConfig: { inputSize: 8, hiddenSize: 12, outputSize: 3 }, confidenceThreshold: 0.8, maxPredictions: 3 }, balanced: { neuralNetConfig: { inputSize: 10, hiddenSize: 20, outputSize: 5 }, confidenceThreshold: 0.6, maxPredictions: 5 }, aggressive: { neuralNetConfig: { inputSize: 12, hiddenSize: 30, outputSize: 8 }, confidenceThreshold: 0.4, maxPredictions: 10 }, experimental: { neuralNetConfig: { inputSize: 15, hiddenSize: 50, outputSize: 12 }, confidenceThreshold: 0.3, maxPredictions: 15 } }; function PredictiveEngineSummary() { const { predictions, insights } = usePredictiveEngine(); const topPrediction = predictions[0]; return jsxs("div", { className: cn("glass-surface-primary glass-radius-2xl glass-p-6 glass-space-y-4", "glass-border glass-border-white/10 glass-shadow-soft-lg"), "data-testid": "glass-predictive-engine-summary", children: [jsxs("div", { children: [jsx("p", { className: "glass-text-xs glass-text-tertiary uppercase tracking-wide", children: "Predictive Engine" }), jsx("h2", { className: "glass-text-2xl glass-text-primary font-semibold", children: topPrediction ? topPrediction.type : "Monitoring behavior" }), jsx("p", { className: "glass-text-sm glass-text-secondary", children: topPrediction ? topPrediction.target : "Collecting interaction data" })] }), jsxs("div", { className: "glass-grid glass-grid-cols-2 glass-gap-3", children: [jsxs("div", { className: "glass-surface-subtle glass-radius-xl glass-p-4", children: [jsx("p", { className: "glass-text-xs glass-text-tertiary mb-1", children: "Predictions" }), jsx("p", { className: "glass-text-lg glass-text-primary font-semibold", children: predictions.length })] }), jsxs("div", { className: "glass-surface-subtle glass-radius-xl glass-p-4", children: [jsx("p", { className: "glass-text-xs glass-text-tertiary mb-1", children: "Insights" }), jsx("p", { className: "glass-text-lg glass-text-primary font-semibold", children: insights.length })] })] }), jsx("div", { className: "glass-text-xs glass-text-secondary", children: insights[0]?.insight || "Awaiting actionable recommendations." })] }); } const GlassPredictiveEngine = ({ onPrediction, onInsight, className, children, showIndicator = true, ...rest }) => jsx(GlassPredictiveEngineProvider, { onPrediction: onPrediction, onInsight: onInsight, children: jsxs("div", { className: cn("glass-predictive-engine glass-relative glass-space-y-4", className), ...rest, children: [children ?? jsx(PredictiveEngineSummary, {}), showIndicator && jsx(GlassPredictionIndicator, {})] }) }); export { GlassPredictionIndicator, GlassPredictiveEngine, GlassPredictiveEngineProvider, GlassPredictiveEngine as default, predictiveEnginePresets, useInteractionRecorder, usePredictiveEngine }; //# sourceMappingURL=GlassPredictiveEngine.js.map