import React, { useEffect, useMemo, useState } from 'react'; import { useI18n } from '@/utils/chromeI18n'; import { formatBytes } from '@/utils/format'; import CopyButton from '@/components/CopyButton'; import TextInputArea from '@/components/TextInputArea'; import { validateJson } from '@/utils/jsonFormatter'; import { cn } from '@/lib/utils'; export interface ConvertResult { output: string; originalBytes: number; outputBytes: number; } export type ConvertFunction = (text: string) => ConvertResult; interface JsonConvertSectionProps extends React.HTMLAttributes { translationPrefix: string; convertFunction: ConvertFunction; } export default function JsonConvertSection({ translationPrefix, convertFunction, className, ...props }: JsonConvertSectionProps) { const { t } = useI18n('jsonFormat'); const [input, setInput] = useState(''); const [debouncedInput, setDebouncedInput] = useState(''); const pk = translationPrefix; // Debounce input useEffect(() => { const handle = setTimeout(() => { setDebouncedInput(input); }, 250); return () => clearTimeout(handle); }, [input]); const error = useMemo(() => { return validateJson(debouncedInput); }, [debouncedInput]); const conversionPipeline = useMemo(() => { const trimmed = debouncedInput.trim(); if (!trimmed || error) return null; try { return convertFunction(debouncedInput); } catch (e) { // 捕获可能从外部转换器(如 YAML.stringify)中抛出的底层异常 return { isRuntimeError: true, errorMessage: e instanceof Error ? e.message : String(e), }; } }, [debouncedInput, error, convertFunction]); const runtimeError = conversionPipeline && 'isRuntimeError' in conversionPipeline ? conversionPipeline.errorMessage : null; const result = conversionPipeline && !('isRuntimeError' in conversionPipeline) ? (conversionPipeline as ConvertResult) : null; return (
{/* 输入区 */} setInput('')} /> {/* Result display */} {result && result.output ? (
{t(`jsonFormat:${pk}OutputLabel`)}
{t('jsonFormat:originalSize')}:{' '} {formatBytes(result.originalBytes)} | {t('jsonFormat:formattedSize')}:{' '} {formatByteSize(result.outputBytes)}
{result.output}
) : (

{error ? t('jsonFormat:fixErrorHint') : t(`jsonFormat:${pk}EmptyHint`)}

)}
); }