Mantine Json Tree

Undolog

@gfazioli/mantine-json-tree

A Mantine extension component that renders interactive JSON trees with syntax highlighting, collapsible nodes, copy-to-clipboard, and configurable expansion depth.

Installation

yarn add @gfazioli/mantine-json-tree

After installation import package styles at the root of your application:

import '@gfazioli/mantine-json-tree/styles.css';

You can import styles within a layer @layer mantine-json-tree by importing @gfazioli/mantine-json-tree/styles.layer.css file.

import '@gfazioli/mantine-json-tree/styles.layer.css';

Usage

The JsonTree is interactive JSON tree viewer component built with Mantine's Tree component. Features collapsible nodes, syntax highlighting with type-specific colors, copy-to-clipboard functionality, item count badges, configurable expansion depth, and smooth animations. Perfect for debugging API responses, exploring complex data structures, and developer tools.

  • {
    • name:"John Doe"
    • age:30
    • isAdmin:false
    • courses:[...]
    • wife:null
    • onClick:[Function: onClick]
    • address:{...}
    • action:{...}
    • projects:[...]
Size
import { JsonTree } from "@gfazioli/mantine-json-tree";
import { data } from './data';

function Demo() {
  return <JsonTree data={data} maxDepth={1} defaultExpanded/>;
}

Syntax Highlighting values

Below is an example of syntax highlighting for different JSON value types: strings, numbers, booleans, nulls, objects, and arrays. Each type is displayed in a distinct color for better readability.

Simple string
  • "Hello, World!"
Number value
  • 42
Boolean value (true)
  • true
Boolean value (false)
  • false
Null value
  • null
Object value
  • {
    • key1:"value1"
    • key2:123
    • key3:false
    • key4:null
Array value
  • [
    • 0:"string"
    • 1:456
    • 2:true
    • 3:null
    • 4:{
      • nestedKey:"nestedValue"
import { JsonTree } from "@gfazioli/mantine-json-tree";
import { Paper, Stack } from '@mantine/core';
import { data } from './data';

function Demo() {
  return (
    <Stack>
      <Paper withBorder>
        <JsonTree data="Hello, World!" defaultExpanded title="Simple string" />
      </Paper>
      <Paper withBorder>
        <JsonTree data={42} defaultExpanded title="Number value" />
      </Paper>
      <Paper withBorder>
        <JsonTree data={true} defaultExpanded title="Boolean value (true)" />
      </Paper>
      <Paper withBorder>
        <JsonTree data={false} defaultExpanded title="Boolean value (false)" />
      </Paper>
      <Paper withBorder>
        <JsonTree data={null} defaultExpanded title="Null value" />
      </Paper>
      <Paper withBorder>
        <JsonTree data={{ key1: 'value1', key2: 123, key3: false, key4: null }} defaultExpanded title="Object value" />
      </Paper>
      <Paper withBorder>
        <JsonTree data={['string', 456, true, null, { nestedKey: 'nestedValue' }]} defaultExpanded title="Array value" />
      </Paper>
    </Stack>
  );
}

Indent Guides

Display vertical lines to visualize nesting levels, similar to Visual Studio Code. The guides use 5 distinct colors that cycle for deeper nesting levels.

JSON with Indent Guides
  • {
    • name:"John Doe"
    • age:30
    • isAdmin:false
    • courses:[
      • 0:"html"
      • 1:"css"
      • 2:"js"
    • wife:null
    • onClick:[Function: onClick]
    • address:{
      • street:"123 Main St"
      • city:"Anytown"
      • zip:"12345"
    • action:{
      • type:"click"
      • payload:undefined
    • projects:[
      • 0:{
        • name:"Project A"
        • status:"completed"
      • 1:{
        • name:"Project B"
        • status:"in progress"
import { JsonTree } from "@gfazioli/mantine-json-tree";
import { data } from './data';

function Demo() {
  return (
    <JsonTree 
      data={data} 
      defaultExpanded 
      maxDepth={-1}
      showIndentGuides
      title="JSON with Indent Guides"
    />
  );
}

Sticky Header

You may enable sticky headers for better context when scrolling through large JSON structures. When enabled, the header of each expanded node remains visible at the top of the scrollable area as you navigate through its child elements. You can also set an offset to accommodate fixed headers in your layout.

data.json
  • {
    • name:"John Doe"
    • age:30
    • isAdmin:false
    • courses:[
      • 0:"html"
      • 1:"css"
      • 2:"js"
    • wife:null
    • onClick:[Function: onClick]
    • address:{
      • street:"123 Main St"
      • city:"Anytown"
      • zip:"12345"
    • action:{
      • type:"click"
      • payload:undefined
    • projects:[
      • 0:{...}
      • 1:{...}
Sticky header offset
import { JsonTree } from "@gfazioli/mantine-json-tree";
import { ScrollArea } from '@mantine/core';
import { data } from './data';

function Demo() {
  return (
    <ScrollArea style={{ height: 300 }}>
      <JsonTree stickyHeader
        data={data}
        title="data.json"
        defaultExpanded
        withExpandAll
        styles={{
          header: { backgroundColor: 'var(--mantine-color-default)' },
        }}
      />
    </ScrollArea>
  );
}

Icons

You can customize the expand/collapse icons used in the JsonTree component by providing your own icons via the expandControlIcon and collapseControlIcon props. The default icons are simple chevrons, but you can replace them with any React component or icon of your choice.

Note: If only the expandControlIcon is provided, the component will automatically use it for both expand and collapse states, by rotating (90deg) it accordingly. If only the collapseControlIcon is provided, the default expand icon will be used. Of course, you can provide both icons for complete customization.

Only Expand Icons

demo.json
  • {...}

Only Collapse Icons

demo.json
  • {...}

Both Expand and Collapse Icons

demo.json
  • {...}
import { JsonTree } from "@gfazioli/mantine-json-tree";
import { Paper, SimpleGrid, Text, Title } from '@mantine/core';
import { data } from './data';

function Demo() {
  return (
    <SimpleGrid cols={3}>
      <Paper withBorder p="md">
        <Title order={4}>Only Expand Icons</Title>
        <JsonTree
          title="demo.json"
          showIndentGuides
          data={data}
          expandControlIcon={<span>👉</span>}
        />
      </Paper>
      <Paper withBorder p="md">
        <Title order={4}>Only Collapse Icons</Title>
        <JsonTree
          title="demo.json"
          showIndentGuides
          data={data}
          collapseControlIcon={<span>👇</span>}
        />
      </Paper>
      <Paper withBorder p="md">
        <Title order={4}>Both Expand and Collapse Icons</Title>
        <JsonTree
          title="demo.json"
          showIndentGuides
          data={data}
          expandControlIcon={
            <Text fz={24} c="red">
              ⊕
            </Text>
          }
          collapseControlIcon={<Text fz={24}>⊖</Text>}
        />
      </Paper>
    </SimpleGrid>
  );
}

Function Display

By default, functions in JSON data are displayed as strings (e.g., [Function: name]). You can control how functions are handled using the displayFunctions prop:

  • as-string (default): Display functions as formatted strings showing their name
  • hide: Completely omit functions from the tree
  • as-object: Treat functions as objects and display their properties
as-string
  • {
    • name:"UserProfile"
    • age:25
    • onClick:[Function: onClick]
    • calculate:[Function: calculate]
    • methods:{
      • fetchData:[Function: fetchData]
      • process:[Function: process]
    • data:[
      • 0:1
      • 1:2
      • 2:3
    • isActive:true
hide
  • {
    • name:"UserProfile"
    • age:25
    • methods:[object Object]
    • data:[
      • 0:1
      • 1:2
      • 2:3
    • isActive:true
as-object
  • {
    • name:"UserProfile"
    • age:25
    • onClick:{
      • length:0
      • name:"onClick"
      • prototype:[object Object]
    • calculate:{
      • length:2
      • name:"calculate"
    • methods:{
      • fetchData:{...}
      • process:{...}
    • data:[
      • 0:1
      • 1:2
      • 2:3
    • isActive:true
import { JsonTree } from '@gfazioli/mantine-json-tree';
import { Code, Paper, Stack } from '@mantine/core';

const dataWithFunctions = {
  name: 'UserProfile',
  age: 25,
  onClick: function handleClick() {
    console.log('clicked');
  },
  calculate: (a: number, b: number) => a + b,
  methods: {
    async fetchData() {
      return 'data';
    },
    process: function process(value: string) {
      return value.toUpperCase();
    },
  },
  data: [1, 2, 3],
  isActive: true,
};

function Demo() {
  return (
    <Stack>
      <Paper withBorder p="sm">
        <Code>as-string</Code>
        <JsonTree data={dataWithFunctions} defaultExpanded displayFunctions="as-string" mb="md" />
      </Paper>
      <Paper withBorder p="sm">
        <Code>hide</Code>
        <JsonTree data={dataWithFunctions} defaultExpanded displayFunctions="hide" mb="md" />
      </Paper>
      <Paper withBorder p="sm">
        <Code>as-object</Code>
        <JsonTree data={dataWithFunctions} defaultExpanded displayFunctions="as-object" />
      </Paper>
    </Stack>
  );
}

Style the component with classNames

You can style the JsonTree component using the classNames prop to target specific inner elements. This allows for granular customization of the component's appearance.

demo.json
  • {
    • name:"John Doe"
    • age:30
    • isAdmin:false
    • courses:[...]
      3
    • wife:null
    • onClick:[Function: onClick]
    • address:{...}
      3
    • action:{...}
      2
    • projects:[...]
      2
import { JsonTree } from "@gfazioli/mantine-json-tree";
import { data } from './data';
import classes from './JsonTree.module.css';

function Demo() {
  return (
    <JsonTree
      classNames={classes}
      title="demo.json"
      showIndentGuides
      defaultExpanded
      showItemsCount
      maxDepth={1}
      data={data}
    />
  );
}

Styles API

JsonTree supports Styles API, you can add styles to any inner element of the component with classNames prop. Follow Styles API documentation to learn more.

You can customize the appearance of the JsonTree component using the Styles API. This allows you to modify styles for various parts of the component, such as keys, values, brackets, and more.

demo.json
  • {
    • name:"John Doe"
    • age:30
    • isAdmin:false
    • courses:[...]
      3
    • wife:null
    • onClick:[Function: onClick]
    • address:{...}
      3
    • action:{...}
      2
    • projects:[...]
      2

Component Styles API

Hover over selectors to highlight corresponding elements

/*
 * Hover over selectors to apply outline styles
 *
 */