'use client'
import React, { useMemo } from 'react'
interface SyllableBowProps {
word: string
syllables: string[]
onSyllableClick?: (syllable: string, index: number) => void
isDark: boolean
size?: 'sm' | 'md' | 'lg'
}
/**
* SyllableBow — Renders a word with SVG arcs under each syllable.
*
* Uses pyphen syllable data from the backend.
* Each syllable is clickable (triggers TTS for that syllable).
*/
export function SyllableBow({ word, syllables, onSyllableClick, isDark, size = 'md' }: SyllableBowProps) {
const fontSize = size === 'sm' ? 20 : size === 'md' ? 32 : 44
const charWidth = fontSize * 0.6
const bowHeight = size === 'sm' ? 12 : size === 'md' ? 18 : 24
const gap = 4
const layout = useMemo(() => {
let x = 0
return syllables.map((syl) => {
const width = syl.length * charWidth
const entry = { syllable: syl, x, width }
x += width + gap
return entry
})
}, [syllables, charWidth])
const totalWidth = layout.length > 0
? layout[layout.length - 1].x + layout[layout.length - 1].width
: 0
const svgHeight = bowHeight + 6
return (
{/* Letters */}
{layout.map((item, idx) => (
onSyllableClick?.(item.syllable, idx)}
className={`font-bold cursor-pointer select-none transition-colors ${
onSyllableClick
? (isDark ? 'hover:text-blue-300' : 'hover:text-blue-600')
: ''
} ${isDark ? 'text-white' : 'text-slate-900'}`}
style={{ fontSize: `${fontSize}px`, letterSpacing: '0.02em' }}
>
{item.syllable}
))}
{/* SVG Bows */}
)
}
/**
* Simple client-side syllable splitting fallback.
* For accurate results, use the backend pyphen endpoint.
*/
export function simpleSyllableSplit(word: string): string[] {
// Very basic vowel-based heuristic for display purposes
const vowels = /[aeiouyäöü]/i
const chars = word.split('')
const syllables: string[] = []
let current = ''
for (let i = 0; i < chars.length; i++) {
current += chars[i]
if (
vowels.test(chars[i]) &&
i < chars.length - 1 &&
current.length >= 2
) {
// Check if next char starts a new consonant cluster
if (!vowels.test(chars[i + 1]) && i + 2 < chars.length && vowels.test(chars[i + 2])) {
syllables.push(current)
current = ''
}
}
}
if (current) syllables.push(current)
return syllables.length > 0 ? syllables : [word]
}