import { useEffect, useMemo, useState } from 'react'; import { Button } from '@/components/ui/button'; import { useLazyTranslation } from '@/utils/useLazyTranslation'; import { formatByteSize } from '@/utils/textStatistics'; import CopyButton from '@/components/CopyButton'; import TextInputArea from '@/components/TextInputArea'; import { validateJson } from '@/utils/jsonFormatter'; /** 转换结果通用接口 */ export interface ConvertResult { /** 转换后的输出字符串 */ output: string; /** 原始输入的字节大小 */ originalBytes: number; /** 转换后的字节大小 */ outputBytes: number; } /** 转换函数类型 */ export type ConvertFunction = (text: string) => ConvertResult; /** * JSON 转换工具区域组件属性 */ interface JsonConvertSectionProps { /** i18n 命名空间内翻译键的前缀,如 'yamlMode' / 'tomlMode' / 'minifyMode' */ translationPrefix: string; /** 转换函数 */ convertFunction: ConvertFunction; /** 转换按钮的翻译键后缀,默认 'convertButton' */ convertButtonKey?: string; } /** * JSON 转换工具共享组件 * * 适用于 JSON->YAML、JSON->TOML、JSON 压缩等场景, * 提供输入区域、转换按钮和结果展示(含一键复制)。 */ export default function JsonConvertSection({ translationPrefix, convertFunction, convertButtonKey = 'convertButton', }: JsonConvertSectionProps) { const { t } = useLazyTranslation('jsonFormat'); const [input, setInput] = useState(''); const [error, setError] = useState(null); const [result, setResult] = useState(null); const pk = translationPrefix; // 防抖校验输入 useEffect(() => { const handle = setTimeout(() => { setError(validateJson(input)); }, 300); return () => clearTimeout(handle); }, [input]); const canConvert = useMemo(() => { return input.trim() !== '' && !error; }, [input, error]); const handleConvert = () => { const validationError = validateJson(input); if (validationError) { setError(validationError); setResult(null); return; } try { const convertResult = convertFunction(input); setResult(convertResult); } catch (e) { setError(e instanceof Error ? e.message : String(e)); setResult(null); } }; const handleClear = () => { setInput(''); setError(null); setResult(null); }; return (
{/* 工具栏 */}
{/* 输入区 */} { setResult(null); }} /> {/* 转换结果 */} {result && result.output ? (
{/* 结果头部 */}
{t(`jsonFormat:${pk}OutputLabel`)} {t('jsonFormat:originalSize')}: {formatByteSize(result.originalBytes)} {t('jsonFormat:formattedSize')}: {formatByteSize(result.outputBytes)}
{/* 转换内容 */}
{result.output}
) : (

{t(`jsonFormat:${pk}EmptyHint`)}

)}
); }