import { Tree, Typography } from 'antd' import type { DataNode } from 'antd/es/tree' import { useMemo } from 'react' export type JsonViewerProps = { value: unknown height?: number defaultExpandAll?: boolean } function isRecord(value: unknown): value is Record { return !!value && typeof value === 'object' && !Array.isArray(value) } function preview(value: unknown) { if (value === null) return 'null' if (value === undefined) return 'undefined' if (typeof value === 'string') return JSON.stringify(value) if (typeof value === 'number' || typeof value === 'boolean') return String(value) if (Array.isArray(value)) return `[${value.length}]` if (isRecord(value)) return `{${Object.keys(value).length}}` return String(value) } function toTreeData(value: unknown, path: string): DataNode[] { if (Array.isArray(value)) { return value.map((item, idx) => { const nextPath = `${path}[${idx}]` const hasChildren = Array.isArray(item) || isRecord(item) return { key: nextPath, title: ( {idx} {preview(item)} ), children: hasChildren ? toTreeData(item, nextPath) : undefined, } }) } if (isRecord(value)) { return Object.entries(value).map(([k, v]) => { const nextPath = path ? `${path}.${k}` : k const hasChildren = Array.isArray(v) || isRecord(v) return { key: nextPath, title: ( {k} {preview(v)} ), children: hasChildren ? toTreeData(v, nextPath) : undefined, } }) } return [ { key: path || 'value', title: {preview(value)}, }, ] } export default function JsonViewer({ value, height = 360, defaultExpandAll = true, }: JsonViewerProps) { const treeData = useMemo(() => toTreeData(value, ''), [value]) if (value === null || value === undefined) { return çİş } return ( ) }