UNPKG

@medalsocial/meda

Version:

Shared Meda UI shell and runtime package.

76 lines (75 loc) 2.85 kB
import { jsx as _jsx } from "react/jsx-runtime"; function tokenize(value, level, key, indent, seen) { const out = []; const pad = ' '.repeat(level * indent); if (key !== null) { out.push({ kind: 'punct', text: pad }); out.push({ kind: 'key', text: `"${key}"` }); out.push({ kind: 'punct', text: ': ' }); } else { out.push({ kind: 'punct', text: pad }); } if (value === null) { out.push({ kind: 'literal', text: 'null' }); } else if (typeof value === 'string') { out.push({ kind: 'string', text: JSON.stringify(value) }); } else if (typeof value === 'number') { out.push({ kind: 'number', text: String(value) }); } else if (typeof value === 'boolean') { out.push({ kind: 'literal', text: String(value) }); } else if (Array.isArray(value)) { if (seen.has(value)) { out.push({ kind: 'literal', text: '"[Circular]"' }); } else { seen.add(value); out.push({ kind: 'punct', text: '[\n' }); value.forEach((v, i) => { out.push(...tokenize(v, level + 1, null, indent, seen)); out.push({ kind: 'punct', text: i < value.length - 1 ? ',\n' : '\n' }); }); out.push({ kind: 'punct', text: `${pad}]` }); } } else if (typeof value === 'object') { const obj = value; if (seen.has(obj)) { out.push({ kind: 'literal', text: '"[Circular]"' }); } else { seen.add(obj); out.push({ kind: 'punct', text: '{\n' }); const entries = Object.entries(obj); entries.forEach(([k, v], i) => { out.push(...tokenize(v, level + 1, k, indent, seen)); out.push({ kind: 'punct', text: i < entries.length - 1 ? ',\n' : '\n' }); }); out.push({ kind: 'punct', text: `${pad}}` }); } } else { out.push({ kind: 'literal', text: String(value) }); } return out; } // 700-shade variants for syntax tokens so 11px monospace text clears // WCAG AA (4.5:1) against the inspector's near-white background. const KIND_CLASS = { punct: 'text-muted-foreground', key: 'text-primary', string: 'text-emerald-700', number: 'text-amber-700', literal: 'text-amber-700', }; export function InspectorJSON({ data, indent = 2, className }) { const tokens = tokenize(data, 0, null, indent, new WeakSet()); return (_jsx("pre", { className: [ 'mt-1.5 overflow-x-auto rounded-md border border-border bg-background p-2.5 font-mono text-[11px] leading-relaxed text-foreground', className ?? '', ].join(' '), children: tokens.map((t, i) => (_jsx("span", { className: KIND_CLASS[t.kind], children: t.text }, i))) })); }