JSON Viewer
Data DisplayCollapsible JSON data tree viewer.
Preview
name: "ParamUI"
version: "1.0.0"
components: 187
categories:
0: "Base"
1: "Form"
2: "Layout"
3: "Navigation"
config:
theme: "auto"
responsive: true
Usage
example.jsx
import { JsonViewer } from "@/components/ui/json-viewer";
export default function Example() {
return <JsonViewer />;
}Source Code
Copy this file into components/ui/json-viewer.jsx in your project.
json-viewer.jsx
"use client";
import { forwardRef, useState } from "react";
import { cn } from "@/lib/utils";
const JsonNode = ({ name, value, level = 0 }) => {
const [open, setOpen] = useState(level < 2);
const isObj = value && typeof value === "object" && !Array.isArray(value);
const isArr = Array.isArray(value);
const isExpandable = isObj || isArr;
const renderValue = (v) => {
if (v === null) return <span className="text-muted-foreground">null</span>;
if (typeof v === "string") return <span className="text-green-600 dark:text-green-400">"{v}"</span>;
if (typeof v === "number") return <span className="text-blue-600 dark:text-blue-400">{v}</span>;
if (typeof v === "boolean") return <span className="text-purple-600 dark:text-purple-400">{v.toString()}</span>;
return null;
};
return (
<div style={{ paddingLeft: level > 0 ? 16 : 0 }}>
<div className="flex items-center gap-1">
{isExpandable && (
<button onClick={() => setOpen(!open)} className="h-4 w-4 shrink-0 text-muted-foreground hover:text-foreground">
<svg className={cn("h-3 w-3 transition-transform", open && "rotate-90")} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /></svg>
</button>
)}
{name !== undefined && <span className="text-sm font-medium text-foreground">{name}: </span>}
{!isExpandable && <span className="text-sm">{renderValue(value)}</span>}
{isExpandable && !open && <span className="text-xs text-muted-foreground">{isArr ? `Array(${value.length})` : `{${Object.keys(value).length}}`}</span>}
</div>
{isExpandable && open && (
<div>
{(isArr ? value.map((v, i) => [i, v]) : Object.entries(value)).map(([k, v]) => (
<JsonNode key={k} name={k} value={v} level={level + 1} />
))}
</div>
)}
</div>
);
};
const JsonViewer = forwardRef(({ className, data, ...props }, ref) => (
<div ref={ref} className={cn("rounded-md border bg-background p-3 font-mono", className)} {...props}>
<JsonNode value={data} />
</div>
));
JsonViewer.displayName = "JsonViewer";
export { JsonViewer };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge