Skip to main content Skip to footer

Customizing Indentation and Icons with a TreeGrid in React

Before and after customizing icons

Background:

There may be times when the default styling does not meet your applications needs, and you may want to adjust the style of your columns so you can more easily understand the hierarchy. This can be achieved with Wijmo by following this article.

Steps to Complete:

  1. Provide hierarchical data
  2. Adjust indentation with the formatItem event
  3. Apply custom icons with CSS

Getting Started:

Provide hierarchical data

FlexGrid becomes a TreeGrid automatically when you supply nested data using the property defined in childItemsPath.

const data = [
  {
    name: 'Electronics',
    sales: 120000,
    children: [
      { name: 'Phones', sales: 55000 },
      { name: 'Laptops', sales: 65000 }
    ]
  },
  {
    name: 'Home',
    sales: 95000,
    children: [
      { name: 'Furniture', sales: 50000 },
      { name: 'Kitchen', sales: 45000 }
    ]
  }
];

 

Adjust indentation with the formatItem event

This event fires whenever FlexGrid renders a cell. You use it to modify padding based on the row’s hierarchy level.

const onFormatItem = (s, e) => {
  const col = e.getColumn();
  const row = e.getRow();

  if (col.binding === 'name') {
    let padding = (row.level || 0) * 14;

    if (!row.hasChildren) {
      padding += 21;
    }

    e.cell.style.paddingLeft = `${padding}px`;
  }
};

 

Apply custom icons with CSS

Replacing the default Wijmo glyphs is done entirely with CSS.

.wj-flexgrid .wj-cell:has(.wj-glyph-down-right) {
  display: flex;
}
.wj-flexgrid .wj-cell:has(.wj-glyph-right) {
  display: flex;
  align-items: center;
}

.wj-glyph-down-right {
  background-image: url('data:image/png;base64,…');
  background-repeat: no-repeat;
  width: 20px;
  height: 20px;
}

.wj-glyph-right {
  background-image: url('data:image/png;base64,…');
  background-repeat: no-repeat;
  width: 20px;
  height: 20px;
}

 

You can of course accomplish more of the styling through the formatItem event if you prefer, this is just one way of adding customization.

I hope you found this article helpful. I will include the full code files at the end of this article.

Happy coding!

Files for reference:

App.jsx

import React, { useRef } from 'react';
import { FlexGrid, FlexGridColumn } from '@mescius/wijmo.react.grid';
import './App.css';

export default function App() {
  const gridRef = useRef(null);

  const data = [
    {
      name: 'Electronics',
      sales: 120000,
      children: [
        { name: 'Phones', sales: 55000 },
        { name: 'Laptops', sales: 65000 }
      ]
    },
    {
      name: 'Home',
      sales: 95000,
      children: [
        { name: 'Furniture', sales: 50000 },
        { name: 'Kitchen', sales: 45000 }
      ]
    }
  ];

  const onFormatItem = (s, e) => {
    const col = e.getColumn();
    const row = e.getRow();

    if (col.binding === 'name') {
      let padding = (row.level || 0) * 14;

      if (!row.hasChildren) {
        padding += 21;
      }

      e.cell.style.paddingLeft = `${padding}px`;
    }
  };

  return (
    <div style={{ padding: '20px' }}>
      <h2>React TreeGrid with Custom Indentation & Icons</h2>

      <FlexGrid
        ref={gridRef}
        itemsSource={data}
        childItemsPath="children"
        autoGenerateColumns={false}
        formatItem={onFormatItem}
      >
        <FlexGridColumn binding="name" header="Name" />
        <FlexGridColumn binding="sales" header="Sales" />
      </FlexGrid>
    </div>
  );
}

  

App.css

/* Ensure flex behavior when a cell contains a custom tree glyph */
.wj-flexgrid .wj-cell:has(.wj-glyph-down-right) {
  display: flex;
}

.wj-flexgrid .wj-cell:has(.wj-glyph-right) {
  display: flex;
  align-items: center;
}

/* Custom expand icon */
.wj-glyph-down-right {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAABm0lEQVR4nL2Ty0rDQBSGo0+gvoAbO9PW9gGE6tbqS4jgFQVBH6A7qy/QRZLqRlwI7UxAtK1IN2qrdCm+gVovoLtaTXrkjJcmmcSmgg4cCJPJl//M/x9F+c+VUlK9ejgX00JsEgufca9rkBbdG9Ao39AIu9UpB0cRfqNTls7E9/sDwfQQH9Mov5dAct2pITbaGUZ4MwBMFJ5V/aCfbQZRJinNeLWvU775Cxh8FEs7YOic24BsxPAFSO8Iqzvc36Isbj+wM3IID5dPUJyvSLDCzBk8Xj3DbqLg2FcjxvA3MEvyE/aXpcUqtMwWmA0TDqZP2/vzVTCbFlhmC0oLVZdBRrJtCDGSbiXHKxfiQwGdOoHiXEXA8EfltZqkXKVsvG1IOBfzuqvyak0A3homWK+WqKPlc897Ve0tixETEyAf/FIqYEveMI2wa1CgxxUblvZzFZUWZmWDbC6vSznEcGJIu84gYfXtQdbnOS04Rt2Mnk7ZS5bkE54wOzSQUsLqHWGKo32W9jIKDcA7823zp4XuYxww+KKGeFRy86/XO/G5aIX/VUs6AAAAAElFTkSuQmCC');
  background-repeat: no-repeat;
  width: 20px;
  height: 20px;
  border: none !important;
}

/* Custom collapse icon */
.wj-glyph-right {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAABZ0lEQVR4nNWTQS8DQRTHh4+BIzMiLkgEH8SBL+AblEX6PcwQm27dZGbbTSUOraYXB9yEUAQHDq20iYpD9cnbEnZ3Ztpr/8lL9vD2l/f+83+EDKx2xg/HOFObnMmyYPIe6+fb2Z/Ij/YNAgJDnMptztSHYAq0RWULwdhLbEqT9LCg6sAIihWn0rNCcbL4T8FqBdy5wAKWjs2zyJq55TK0P7/g9aIO7qwBSmVL66lgaivevDedg8fSC6BsUD7pbyTXDV8w2RyBnhugVJU0/qkHk08R6FkN3JkolDN1p1kZs6YH7k75UA2eQ2DtsgGZ+UK8p6qb8MQEu/WfQlj9qgHeQkEXn6JuQscKu25qYaL70qkEEJ++ewF/jfmVCnTaHXi7aYK3eGQK97tgakSbRd2Ux2unkF3Sw4zT/QrPSFCV7ff0BJOZnvccQnHS2PqJNalM9YSRf0JP8QIwtJizsKgscqrWjZ4NhL4BeNMpwMOfx2cAAAAASUVORK5CYII=');
  background-repeat: no-repeat;
  width: 20px;
  height: 20px;
  border: none !important;
}

Andrew Peterson

Technical Engagement Engineer