Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 1x 1x | 'use client'
/**
* BeadTooltipContent - Shared tooltip content for bead instruction overlays
*
* Extracted from TutorialPlayer for reuse in practice help overlay.
* Ensures consistent tooltip display across tutorial and practice modes.
*/
import * as Tooltip from '@radix-ui/react-tooltip'
import { PedagogicalDecompositionDisplay } from '../tutorial/PedagogicalDecompositionDisplay'
export interface BeadTooltipContentProps {
/** Whether to show celebration state (step completed) */
showCelebration?: boolean
/** The bead diff summary (e.g., "add 2 earth beads in tens") */
currentStepSummary: string | null
/** Whether the decomposition is pedagogically meaningful */
isMeaningfulDecomposition?: boolean
/** Rendered decomposition with highlighted term (from renderHighlightedDecomposition) */
decomposition?: {
before: string
highlighted: string
after: string
} | null
/** Which side the tooltip appears on */
side: 'top' | 'left'
/** Theme: 'light' or 'dark' */
theme?: 'light' | 'dark'
}
/**
* Tooltip content that matches TutorialPlayer's exact implementation
*
* Shows either:
* - Celebration state with 🎉 emoji
* - Instructions with optional decomposition display and bead diff summary
*/
export function BeadTooltipContent({
showCelebration = false,
currentStepSummary,
isMeaningfulDecomposition = false,
decomposition,
side,
theme = 'light',
}: BeadTooltipContentProps) {
const isDark = theme === 'dark'
return (
<Tooltip.Provider>
<Tooltip.Root open={true}>
<Tooltip.Trigger asChild>
<div style={{ width: '1px', height: '1px', opacity: 0 }} />
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content
side={side}
align="center"
sideOffset={20}
style={{
background: showCelebration
? 'linear-gradient(135deg, rgba(34, 197, 94, 0.95) 0%, rgba(21, 128, 61, 0.95) 100%)'
: isDark
? '#1e40af'
: '#1e3a8a',
color: '#ffffff',
padding: '12px 16px',
borderRadius: '8px',
fontSize: '14px',
fontWeight: 700,
boxShadow: showCelebration
? '0 8px 25px rgba(34, 197, 94, 0.4), 0 0 0 2px rgba(255, 255, 255, 0.2)'
: isDark
? '0 4px 12px rgba(0,0,0,0.3)'
: '0 4px 12px rgba(0,0,0,0.2)',
whiteSpace: 'normal',
maxWidth: '200px',
minWidth: '150px',
wordBreak: 'break-word',
zIndex: 50,
opacity: 0.95,
transition: 'all 0.3s ease',
transform: showCelebration ? 'scale(1.05)' : 'scale(1)',
animation: showCelebration ? 'celebrationPulse 0.6s ease-out' : 'none',
}}
onMouseEnter={(e) => {
e.currentTarget.style.opacity = '1'
}}
onMouseLeave={(e) => {
e.currentTarget.style.opacity = '0.85'
}}
>
<div style={{ fontSize: '12px', opacity: 0.9 }}>
{showCelebration ? (
<div
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
fontSize: '14px',
fontWeight: 'bold',
}}
>
<span style={{ fontSize: '18px' }}>🎉</span>
<span>Excellent work!</span>
</div>
) : (
<>
{isMeaningfulDecomposition && decomposition && (
<PedagogicalDecompositionDisplay
variant="tooltip"
showLabel={true}
decomposition={decomposition}
/>
)}
<span style={{ fontSize: '18px' }}>💡</span> {currentStepSummary}
</>
)}
</div>
<Tooltip.Arrow
style={{
fill: showCelebration ? '#15803d' : '#1e40af',
}}
/>
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>
)
}
export default BeadTooltipContent
|