All files / web/src/components/shared BeadTooltipContent.tsx

84.09% Statements 111/132
14.28% Branches 1/7
33.33% Functions 1/3
84.09% Lines 111/132

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 1331x 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