[eric] onboarding: hovering a starter prompt shows a translucent ghost chat preview with the message as a user bubble

This commit is contained in:
ciregenz
2026-06-11 01:19:27 -07:00
parent d31bbf0af7
commit 6a5e80fcd9
@@ -72,6 +72,7 @@ const DashboardEmptyState: React.FC<{
const navigate = useNavigate();
const [launching, setLaunching] = React.useState(false);
const [expanded, setExpanded] = React.useState<string | null>(null);
const [hoveredPrompt, setHoveredPrompt] = React.useState<string | null>(null);
const currentCategory = STARTER_CATEGORIES.find((cat) => cat.id === expanded);
const currentPrompts = currentCategory?.prompts ?? [];
@@ -193,12 +194,16 @@ const DashboardEmptyState: React.FC<{
>
<ArrowLeft size={15} /> back
</Box>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.9, width: '100%', maxWidth: 480 }}>
<Box
onMouseLeave={() => setHoveredPrompt(null)}
sx={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 0.9, width: '100%', maxWidth: 480 }}
>
{currentPrompts.map((prompt) => (
<Box
component="button"
key={prompt}
onClick={() => launch(prompt)}
onMouseEnter={() => setHoveredPrompt(prompt)}
disabled={launching}
sx={{
textAlign: 'left',
@@ -218,6 +223,45 @@ const DashboardEmptyState: React.FC<{
{prompt}
</Box>
))}
{/* Hover preview: a translucent ghost of the chat that would open,
so the user sees their message land before committing. Pure
divs (not the heavy AgentChat), so it costs nothing to render. */}
<AnimatePresence>
{hoveredPrompt && (
<Box
component={motion.div}
key="ghost"
initial={{ opacity: 0, x: -8 }}
animate={{ opacity: 0.72, x: 0 }}
exit={{ opacity: 0, x: -8 }}
transition={{ duration: 0.16 }}
sx={{
position: 'absolute',
left: '100%', top: '50%', ml: 3,
transform: 'translateY(-50%)',
width: 300,
pointerEvents: 'none',
bgcolor: c.bg.surface,
border: `1px solid ${c.border.medium}`,
borderRadius: 3,
boxShadow: c.shadow.md,
p: 1.5,
}}
>
<Typography sx={{ fontSize: '0.8rem', fontWeight: 600, color: c.text.tertiary, mb: 1.2 }}>
New chat
</Typography>
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<Box sx={{ maxWidth: '88%', bgcolor: c.bg.elevated, borderRadius: 2.5, px: 1.4, py: 0.9 }}>
<Typography sx={{ fontSize: '0.85rem', color: c.text.primary, lineHeight: 1.4 }}>
{hoveredPrompt}
</Typography>
</Box>
</Box>
</Box>
)}
</AnimatePresence>
</Box>
</motion.div>
)}