@medalsocial/meda
Version:
Shared Meda UI shell and runtime package.
76 lines (75 loc) • 2.85 kB
JavaScript
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))) }));
}