import { Check, ChevronRight, Copy } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import { cn } from "~/lib/utils.ts"; /** * 只读 JSON 展示:等宽、自动换行、限高滚动,右上角复制。 * label 存在时可折叠(defaultOpen 控制初始展开)。null/undefined 显示"无"。 */ export function JsonView({ value, label, defaultOpen = true, maxHeight = "20rem", tone = "neutral", className, }: { value: unknown; label?: string; defaultOpen?: boolean; maxHeight?: string; /** destructive:错误负载 */ tone?: "neutral" | "destructive"; className?: string; }) { const [open, setOpen] = useState(defaultOpen); const [copied, setCopied] = useState(false); const empty = value === null || value === undefined; const text = empty ? "" : typeof value === "string" ? value : JSON.stringify(value, null, 2); const copy = async () => { try { await navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 1200); } catch { toast.error("复制失败"); } }; return (
无
) : (
{text}