Skip to content
Data Display

JsonViewer

A JSON tree you can actually read: collapsible, searchable, and coloured with the same --code-* tokens as CodeBlock, so a payload in a docs page and a payload in a debug panel look like the same language.

Walkthrough

1. Basic

Give it any value. depth decides how many levels start open — a collapsed node still says what is inside it rather than showing an opaque {…}.

$ : { 3 keys
ok : true
order : { 5 keys
id : "ord_8f21"
total : 24500
currency : "IQD"
customer : { name, phone, repeat } 3 keys
items : [ {…}, {…} ] 2 items
}
delivered_at : null
}
<script lang="ts">	import { JsonViewer } from 'omaris';​	const RESPONSE = {		ok: true,		order: {			id: 'ord_8f21',			total: 24500,			currency: 'IQD',			customer: { name: 'Lina Aziz', phone: '+964 750 000 0000', repeat: true },			items: [				{ sku: 'lamb-quzi', qty: 1, price: 15000 },				{ sku: 'tea', qty: 2, price: 1500 }			]		},		delivered_at: null	};</script>​<JsonViewer value={RESPONSE} depth={2} class="w-full" />

2. Search and variants

search filters the tree and keeps a match's ancestors, so a hit five levels down arrives with the path that leads to it. Try warn. The three variants are the same ones CodeBlock has.

config : { 5 keys
service : "checkout"
region : "eu-west-1"
logging : { level, sinks, sample } 3 keys
limits : { rps, burst, timeout_ms } 3 keys
flags : { warn_on_retry, new_pricing } 2 keys
}
<script lang="ts">	import { JsonViewer, SegmentedButton, type JsonViewerVariant } from 'omaris';​	const CONFIG = {		service: 'checkout',		region: 'eu-west-1',		logging: { level: 'warn', sinks: ['stdout', 'file'], sample: 0.25 },		limits: { rps: 200, burst: 400, timeout_ms: 3000 },		flags: { warn_on_retry: true, new_pricing: false }	};​	let variant = $state<JsonViewerVariant>('outlined');</script>​<div class="flex w-full flex-col gap-3">	<SegmentedButton		label="Variant"		size="sm"		value={variant}		onchange={(next) => (variant = next as JsonViewerVariant)}		items={[			{ value: 'outlined', label: 'Outlined' },			{ value: 'filled', label: 'Filled' },			{ value: 'ghost', label: 'Ghost' }		]}	/>​	<JsonViewer value={CONFIG} name="config" depth={1} search {variant} height="14rem" /></div>

3. Overridden

height is a custom property, not a class, so height="auto" lets the tree grow with its content and a max-h-* on classes.viewport really replaces it. indent tightens the levels and copy={false} drops the buttons.

event : { 4 keys
type : "deploy.finished"
build : 4821
duration_s : 96.4
commit : { 3 keys
sha : "dafc5ae"
author : "omer"
message : "Ship the docs demos"
}
}
<script lang="ts">	import { JsonViewer } from 'omaris';​	const EVENT = {		type: 'deploy.finished',		build: 4821,		duration_s: 96.4,		commit: { sha: 'dafc5ae', author: 'omer', message: 'Ship the docs demos' }	};</script>​<JsonViewer	value={EVENT}	name="event"	depth={Infinity}	copy={false}	indent={22}	height="auto"	size="sm"	variant="ghost"	classes={{		root: 'rounded-shape-lg bg-surface-container-low',		viewport: 'max-h-none py-2',		key: 'font-semibold'	}}	class="w-full"/>