← Components/Code

JsonViewer

jsonviewer-1779394345565.tsx
'use client'
import { useState } from 'react'

const SAMPLE = { user:{ name:'Alice', role:'admin', active:true }, plan:'pro', components:17500, tags:['react','typescript','tailwind'] }

function JsonNode({ data, depth = 0 }) {
  const [open, setOpen] = useState(depth < 2)
  if (Array.isArray(data)) {
    return (
      <span>
        <span onClick={()=>setOpen(!open)} style={{ cursor:'pointer', color:'#94a3b8' }}>{open?'▾':'▸'} [{data.length}]</span>
        {open && <div style={{ marginLeft:'16px' }}>{data.map((v,i)=><div key={i}><span style={{color:'#94a3b8'}}>{i}: </span><JsonNode data={v} depth={depth+1}/></div>)}</div>}
      </span>
    )
  }
  if (data && typeof data === 'object') {
    return (
      <span>
        <span onClick={()=>setOpen(!open)} style={{ cursor:'pointer', color:'#94a3b8' }}>{open?'▾':'▸'} {'{'}{Object.keys(data).length}{'}'}</span>
        {open && <div style={{ marginLeft:'16px' }}>{Object.entries(data).map(([k,v])=>(
          <div key={k}><span style={{color:'#7c3aed'}}>{k}</span><span style={{color:'#94a3b8'}}>: </span><JsonNode data={v} depth={depth+1}/></div>
        ))}</div>}
      </span>
    )
  }
  const color = typeof data === 'string' ? '#10b981' : typeof data === 'number' ? '#f59e0b' : typeof data === 'boolean' ? '#3b82f6' : '#94a3b8'
  return <span style={{ color }}>{typeof data === 'string' ? '"' + data + '"' : String(data)}</span>
}

export default function JsonViewer({ data = SAMPLE }) {
  const [copied, setCopied] = useState(false)
  return (
    <div style={{ background:'#1e1e2e', borderRadius:'14px', overflow:'hidden', maxWidth:'400px' }}>
      <div style={{ display:'flex', justifyContent:'space-between', padding:'10px 16px', background:'#16162a', borderBottom:'1px solid #2d2d3d' }}>
        <span style={{ color:'#94a3b8', fontSize:'12px', fontWeight:600 }}>JSON</span>
        <button onClick={()=>{navigator.clipboard.writeText(JSON.stringify(data,null,2));setCopied(true);setTimeout(()=>setCopied(false),2000)}}
          style={{ background:'none', border:'none', color:copied?'#10b981':'#94a3b8', cursor:'pointer', fontSize:'12px' }}>
          {copied?'✓ Copied':'Copy'}
        </button>
      </div>
      <div style={{ padding:'16px', fontFamily:'monospace', fontSize:'13px', lineHeight:1.8, overflowX:'auto' }}>
        <JsonNode data={data} />
      </div>
    </div>
  )
}

Component info

CategoryCode
Frameworkreact
TierFREE
Views0
Copies0

About

Collapsible JSON tree viewer with syntax coloring and copy

More from Code

'use client'
import { useState } from 'react'

const EXAMPLES = {
  tsx: {
    label: 'TypeScript',
    code: `import { useState } from 'react'

interface ButtonProps {
  variant?: 'primary' | 'ghost'
  children: React.ReactNode
  onClick?: () => voi
CodeBlock
Code
'use client';
import { useState, useRef, useEffect } from 'react';

export default function TerminalPrompt() {
  const [history, setHistory] = useState([
    { type: 'output', text: 'Welcome to Empire Terminal v2.0.0' },
    { type: 'output', text: '
TerminalPrompt
Code
'use client'
import { useState, useEffect } from 'react'

const SEQUENCE = [
  { type:'input', text:'npm install empire-ui', delay:80 },
  { type:'output', text:'Installing dependencies...', delay:0 },
  { type:'output', text:'✓ Added 1 package in 0.
CommandLine
Code
'use client'
import { useState } from 'react'

const DEFAULT = `<div style="padding:20px;background:linear-gradient(135deg,#6d28d9,#2563eb);borderRadius:12px;color:#fff;textAlign:center">
  <h2>Live Preview ✨</h2>
  <p>Edit the code on the left!</p>
LiveCodeEditor
Code