mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-07 02:07:45 +02:00
[eric] onboarding: hovering a starter prompt shows a translucent ghost chat preview with the message as a user bubble
This commit is contained in:
@@ -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>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user