demo D27
JSON and structured values in React
A nested object in a cell, summarised inline and expandable
type: 'json'
This grid holds a nested object in a single cell, summarised inline and expandable to see the full structure. It lets you keep source data in its natural shape, an address or a permissions map, without flattening it into extra columns first.
This is the React version. The grid mounts through the createLatticeGrid adapter, which takes its configuration as ordinary props and hands back the live grid through a ref. The grid below is the same one every other tab runs.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">
<div id="grid"></div>
<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
import { createGrid } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/react.esm.min.js';
const LatticeGrid = createLatticeGrid({ React, createGrid });
const columns = [
{ field: 'hostname', title: 'Hostname', layout: { width: 260, pin: 'start' } },
{
field: 'config', title: 'Config', type: 'json', layout: { flex: 1, min: 260 },
// Short objects print in full; anything longer collapses to a count,
// because a cell that wraps six lines of JSON is not a cell. The full
// document is on the tooltip and in the editor.
cell: {
props: { inlineLimit: 44 },
tooltip: (p) => {
try { return JSON.stringify(p.value, null, 2); } catch { return ''; }
},
},
},
{
field: 'config', id: 'interfaces', title: 'Interfaces', type: 'json', layout: { width: 200 },
value: { deps: ['config'], pure: true, compute: (d) => d.config?.interfaces ?? null },
},
{
id: 'asn', title: 'BGP ASN', type: 'number', layout: { width: 130 },
// Pulling a leaf out of the document gives you a real number column: it
// sorts, it filters as a range, it totals. The object stays whole
// underneath.
value: { deps: ['config'], pure: true, compute: (d) => d.config?.bgp?.asn ?? null },
filter: { type: 'number' },
},
{
id: 'mtu', title: 'Max MTU', type: 'number', layout: { width: 130 },
value: {
deps: ['config'], pure: true,
compute: (d) => {
const list = d.config?.interfaces ?? [];
return list.length ? Math.max(...list.map((i) => i.mtu)) : null;
},
},
},
{
id: 'snmp', title: 'SNMP', layout: { width: 110 },
value: { deps: ['config'], pure: true, compute: (d) => d.config?.snmp?.version ?? null },
filter: { type: 'set' },
},
{ field: 'hardware', title: 'Hardware', type: 'json', layout: { width: 240 } },
];
const rows = [/* nodes, each with a nested config object */];
function App() {
return (
<LatticeGrid
rowKey="id"
toolPanel={{ side: 'left', panels: ['columns', 'filters', 'views', 'quick'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'], exportName: 'lattice-demo' }}
columns={columns}
rows={rows}
style={{ height: '540px' }}
/>
);
}
createRoot(document.getElementById('grid')).render(<App />);
</script>
Rendering nested JSON in a grid cell
Source data is not always flat. An order row might carry a shipping address as a nested object, or a user record might embed a permissions map, and a JavaScript data grid that only accepts scalars forces a flattening step before the data can be displayed at all. Lattice Grid’s type: 'json' column renders that structure directly: the cell shows a compact inline summary of the object, and expands on demand to a formatted, indented view of the full value, so nesting depth is never lost to a stringified blob. A developer reaches for this type wherever an API response is stored as-is rather than normalised into separate columns, which keeps the column definition stable even when the shape of the nested data grows a new key.
Because the summary is generated from the object rather than pre-rendered per row, a json column pays no layout cost until a cell is actually expanded: collapsed rows contribute a single-line label to the row height calculation, so a grid holding thousands of records with deeply nested payloads scrolls at the same frame rate as one holding plain strings. Expansion is keyboard-operable, so the nested view is reachable without a pointer, which matters for any grid built to pass an accessibility audit rather than merely look right under a mouse.
How do you display a JSON object in a data grid cell?
Set the column’s type to 'json'. Lattice Grid shows a condensed one-line summary of the object in the collapsed cell and an indented, formatted view when the cell is expanded, so nested values stay inspectable without a custom renderer or a separate detail panel.