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 | 'use client' /** * Renders text with entity markers as hoverable highlighted spans. * * Generic version of GeometricText — parameterized on entity ref type * via EntityMarkerConfig. */ import React, { useMemo } from 'react' import type { EntityMarkerConfig } from './types' import { parseEntityMarkers } from './parseEntityMarkers' interface MarkedTextProps<TEntityRef> { text: string markers: EntityMarkerConfig<TEntityRef> onHighlight: (entity: TEntityRef | null) => void /** Optional custom renderer per entity. When absent, uses default blue/bold styling. */ renderEntity?: (entity: TEntityRef, displayText: string, index: number) => React.ReactNode } export function MarkedText<TEntityRef>({ text, markers, onHighlight, renderEntity, }: MarkedTextProps<TEntityRef>) { const segments = useMemo(() => parseEntityMarkers(text, markers), [text, markers]) return ( <> {segments.map((seg, i) => { if (seg.kind === 'text') { return <span key={i}>{seg.text}</span> } if (renderEntity) { return <React.Fragment key={i}>{renderEntity(seg.entity, seg.text, i)}</React.Fragment> } return ( <span key={i} data-element="entity-ref" style={{ color: '#4E79A7', fontWeight: 600, cursor: 'pointer', borderBottom: '1px dotted rgba(78, 121, 167, 0.4)', }} onMouseEnter={() => onHighlight(seg.entity)} onMouseLeave={() => onHighlight(null)} > {seg.text} </span> ) })} </> ) } |