All files / web/src/components/toys/euclid/proof CitationBadge.tsx

0% Statements 0/112
0% Branches 0/1
0% Functions 0/1
0% Lines 0/112

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                                                                                                                                                                                                                                 
'use client'

import type React from 'react'
import { PROOF_COLORS, PROOF_FONTS } from './styles'

/** Determine badge color from citation key */
export function citationColor(key: string | null): string {
  if (!key) return PROOF_COLORS.citationDefault
  if (key === 'Given') return PROOF_COLORS.citationGiven
  if (key.startsWith('Post.')) return PROOF_COLORS.citationPostulate
  if (key.startsWith('I.')) return PROOF_COLORS.citationProposition
  return PROOF_COLORS.citationDefault
}

interface CitationBadgeProps {
  citationKey: string | null
  /** Override label (for progressive disclosure abbreviation) */
  label?: string | null
  /** Show definition text after badge */
  showText?: boolean
  /** Citation definition text to show */
  citationText?: string | null
  /** Wrap in <a> if provided */
  href?: string | null
  onPointerEnter?: (e: React.PointerEvent) => void
  onPointerLeave?: () => void
  onPointerDown?: (e: React.PointerEvent) => void
  fontSize?: number
  /** Color override (for step-level vs fact-level badges) */
  color?: string
  /** Whether to apply link-style underline decoration */
  linkStyle?: boolean
}

export function CitationBadge({
  citationKey,
  label,
  showText,
  citationText,
  href,
  onPointerEnter,
  onPointerLeave,
  onPointerDown,
  fontSize = 10,
  color,
  linkStyle,
}: CitationBadgeProps) {
  if (!citationKey) return null

  const displayLabel = label ?? citationKey
  const badgeColor = color ?? citationColor(citationKey)

  const badgeStyle: React.CSSProperties = {
    fontWeight: 600,
    fontStyle: 'normal',
    fontSize,
    color: badgeColor,
    ...(linkStyle
      ? {
          textDecoration: 'underline',
          textDecorationColor: PROOF_COLORS.citationUnderline,
          cursor: 'pointer',
        }
      : {}),
  }

  const textStyle: React.CSSProperties = {
    fontWeight: 400,
    fontStyle: 'italic',
    fontFamily: PROOF_FONTS.serif,
    color: PROOF_COLORS.textMuted,
    marginLeft: 4,
  }

  if (href) {
    return (
      <span>
        <a
          href={href}
          target="_blank"
          rel="noopener noreferrer"
          onPointerEnter={onPointerEnter}
          onPointerLeave={onPointerLeave}
          onPointerDown={onPointerDown}
          style={{
            ...badgeStyle,
            textDecoration: 'underline',
            textDecorationColor: PROOF_COLORS.citationUnderline,
            cursor: 'pointer',
          }}
        >
          [{displayLabel}]
        </a>
        {showText && citationText && <span style={textStyle}>— {citationText}</span>}
      </span>
    )
  }

  return (
    <span>
      <span
        style={badgeStyle}
        onPointerEnter={onPointerEnter}
        onPointerLeave={onPointerLeave}
        onPointerDown={onPointerDown}
      >
        [{displayLabel}]
      </span>
      {showText && citationText && <span style={textStyle}>— {citationText}</span>}
    </span>
  )
}