import { Children, cloneElement, Fragment, isValidElement } from 'react' import { cn } from '@/lib/utils' import type { ReactNode } from 'react' export const formatUIString = (text: string, language: string): string => (language === 'ain' || language === 'ain-Kana') ? text.replace (/[ \t\r\n]+/g, '\u3000') : text const splitAinuText = (text: string): string[] => { const parts: string[] = [] let part = '' let boundary = false for (const character of text) { // Keep punctuation runs and closing brackets/quotes with the preceding word. if (boundary && !/[\u3000、,,。.\p{Pe}\p{Pf}]/u.test (character)) { parts.push (part) part = '' boundary = false } part += character if (/[\u3000、,,。.]/u.test (character)) boundary = true } if (part !== '') parts.push (part) return parts } export const localiseUIChildren = (children: ReactNode, language: string): ReactNode => { if (language !== 'ain' && language !== 'ain-Kana') return children return Children.map (children, child => { if (typeof child === 'string') { const parts = splitAinuText (formatUIString (child, language)) return parts.map ((part, index) => { const spaces = part.match (/\u3000+$/u)?.[0] ?? '' const word = part.slice (0, part.length - spaces.length) return ( {word !== '' && {word}} {spaces} {index < parts.length - 1 && } ) }) } if (isValidElement<{ children?: ReactNode; lang?: string }> (child)) { // Only traverse inline formatting owned by the renderer. Components, // links and code retain their own children and behaviour. const inline = child.type === Fragment || (typeof child.type === 'string' && ['span', 'em', 'strong', 'del', 's', 'b', 'i', 'u', 'small', 'mark', 'sup', 'sub'].includes (child.type)) if (!inline || (child.props.lang != null && !(child.props.lang.startsWith ('ain')))) return child return cloneElement (child, { }, localiseUIChildren (child.props.children, language)) } return child }) } const LocalisedText = ( { children, language, className }: { children: ReactNode language: string className?: string }, ) => ( {localiseUIChildren (children, language)} ) export default LocalisedText