import { useEffect, useMemo, useState } from 'react'; import { formatJson, type JsonFormatOptions, type JsonFormatResult, validateJson, } from '@/utils/jsonFormatter'; import EmptyPlaceholder from '@/components/EmptyPlaceholder'; import SwitchButtonGroup from '@/components/SwitchButtonGroup'; import TextInputArea from '@/components/TextInputArea'; import JsonResultPanel from './JsonResultPanel'; import { Checkbox } from '@/components/ui/checkbox'; import { Label } from '@/components/ui/label'; export default function JsonFormatSection() { const [input, setInput] = useState(''); const [debouncedInput, setDebouncedInput] = useState(''); const [indentSize, setIndentSize] = useState(2); const [sortKeys, setSortKeys] = useState(false); useEffect(() => { const handle = setTimeout(() => { setDebouncedInput(input); }, 250); return () => clearTimeout(handle); }, [input]); const error = useMemo(() => { return validateJson(debouncedInput); }, [debouncedInput]); const { result, runtimeError } = useMemo((): { result: JsonFormatResult | null; runtimeError: string | null; } => { const trimmed = debouncedInput.trim(); if (!trimmed || error) return { result: null, runtimeError: null }; try { const options: JsonFormatOptions = { indentSize, sortKeys }; return { result: formatJson(debouncedInput, options), runtimeError: null }; } catch (e) { return { result: null, runtimeError: e instanceof SyntaxError ? e.message : String(e), }; } }, [debouncedInput, error, indentSize, sortKeys]); return (
缩进 setIndentSize(Number(v))} options={[2, 4, 6, 8].map((size) => ({ value: size, label: String(size) }))} size="small" />
setSortKeys(!sortKeys)} className="flex items-center gap-2 cursor-pointer select-none group py-1" > e.stopPropagation()} onCheckedChange={(checked) => setSortKeys(checked === true)} className="h-3.5 w-3.5 rounded border-input data-[state=checked]:bg-primary shadow-sm" />
setInput('')} /> {result?.formatted ? ( ) : ( {error ? '请修正上方 JSON 的语法错误以开启实时流式格式化' : '输入 JSON 后点击格式化'} )}
); }