Borislav Stefanov
Borislav Stefanov

Reputation: 731

React material-table: Color rows in data-tree

I am using material-table in my React project. I have 3 levels of the data tree. Here it is the first one:

enter image description here

Is it possible when I click the first of the 2 items on 1st Level in data tree table to color it so it would be easier to see that values under it are child elements. Like this: enter image description here

Also I would be even happier if it is possible to color it when I am passing data to it. Here it is how I am passing data:

data={[
        {
          id: 1, // MAIN ELEMENT 
          name: "Parent",
          value: `Parent`,
        },
        {
          id: 2, //CHILD OF THE MAIN ELEMENT
          name: "Child",
          value: `Child`,
          parentId: 1,
        }]}

Is there an option to color parent Element even before opening it, so it would be clear that it is PARENT and other is CHILD?

UPDATE:

Here is codesandbox example. As you can see when you open Parent1 Parent2 seems to be under Parent1. I want to make it clear that it is NOT under it.

https://codesandbox.io/s/jolly-germain-6fncr?file=/src/App.js

Upvotes: 1

Views: 9595

Answers (3)

Victor Gamez
Victor Gamez

Reputation: 1

Thats how my tree view looks like. Thanks to the left: `var(--left-before, ${0}px), i could positioning the :befores wherever i want

https://i.ibb.co/Wp9XJcc/childscapture.png

viewTableTree.styles.js

import { makeStyles } from '@material-ui/core/styles';

export const useViewTableTreeStyles = makeStyles(theme => ({
  root: {
    '& .MuiPaper-root': {
      boxShadow: 'none'
    },
    '& .MuiTable-root': {
      position: 'relative',
      overflow: 'hidden'
    },
    '& .MuiTableRow-root': {
      '&:hover': { backgroundColor: 'rgba(0, 0, 0, 0.04)' },
      '&:before': {
        content: '""',
        fontWeight: theme.font.weight.black,
        fontSize: theme.font.size.xxl,
        position: 'absolute',
        left: `var(--left-before, ${0}px)`,  //important trick here!
        width: '1px',
        height: '3.2rem',
        backgroundColor: theme.palette.basic.bright
      }
    }
  }
}));

then in the MaterialTable component

ViewTableTree.js

  <div className={classes.root}>
      <MaterialTable
        icons={tableIcons}
        data={rows}
        columns={cells}
        localization={{
          header: {
            actions: ''
          }
        }}
        options={{
          selection: false,
          paging: false,
          search: false,
          showTitle: false,
          toolbar: false,
          actionsColumnIndex: -1,
          rowStyle: rowData => {
            let styles = { transition: 'transform 300ms' };
            const levels = rowData.tableData.path.length === 1 ? 0 : rowData.tableData.path.length;
            styles = { ...styles, '--left-before': `${levels * 6}px` };

            return rowData.tableData.isTreeExpanded
              ? {
                  ...styles,
                  fontWeight: 600,
                  backgroundColor: 'rgba(77, 93, 241, 0.08)'
                }
              : styles;
          }
        }}
        {...props}
      />
    </div>

Upvotes: 0

Arthur Rubens
Arthur Rubens

Reputation: 4706

Ok, using CSS selectors it is not so easy to implement onExapnd color change. Here you will have to write check for parent TR check and sub Button rotate(90deg) check. To change the colors without onClick check you can use the following CSS:

tr[level="0"] {
  background-color: #FF0000;
}

tr[level="1"] {
  background-color: #FF0033;
}

tr[level="2"] {
  background-color: #FF0066;
}

In JS way you can use the following code (of course you will have to add it in every table or extend the table or use util lib with ready rowStyle method..)

import React from "react";
import MaterialTable from "material-table";
import SearchIcon from "@material-ui/icons/Search";
import RotateLeftIcon from "@material-ui/icons/RotateLeft";
import { ArrowUpward, ChevronRight } from "@material-ui/icons";

//import './styles.css';

export default () => {
  const constPathColors = {
    1: '#FFFF00',
    2: '#FFFF33',
    3: '#FFFF66',
    4: '#FFFF99',
    5: '#FFFFCC'
  };
  return (
    <MaterialTable
      style={{ width: "100%", margin: "3%" }}
      title="Income Statement"
      icons={{
        Filter: React.forwardRef((props, ref) => <SearchIcon ref={ref} />),
        Search: React.forwardRef((props, ref) => <SearchIcon ref={ref} />),
        ResetSearch: React.forwardRef((props, ref) => (
          <RotateLeftIcon ref={ref} />
        )),
        SortArrow: ArrowUpward,
        DetailPanel: ChevronRight
      }}
      columns={[
        {
          field: "name",
          title: "Category"
        },
        {
          field: "value",
          title: "Value",

          cellStyle: {
            textAlign: "center"
          }
        }
      ]}
      data={[
        {
          id: 1, // MAIN ELEMENT
          name: "Parent 1",
          value: `SomeParentValue`
        },
        {
          id: 2, //CHILD OF THE MAIN ELEMENT
          name: "Child 1-1",
          value: `Child Value`,
          parentId: 1
        },
        {
          id: 3, //CHILD OF THE MAIN ELEMENT
          name: "Child 1-2",
          value: `Child Value`,
          parentId: 1
        },
        {
          id: 4, //CHILD OF THE CHILD ELEMENT
          name: "Child 1-2-1",
          value: `Child Value`,
          parentId: 3
        },
        {
          id: 5, // MAIN ELEMENT
          name: "Parent 2",
          value: `SomeParentValue`
        }
      ]}
      parentChildData={(row, rows) => rows.find(a => a.id === row.parentId)}
      options={{
        paging: false,
        headerStyle: {
          backgroundColor: "#378FC3",
          color: "#FFF",
          fontSize: "17px",
          textAlign: "center",
          fontWeight: "bold"
        },
        rowStyle: rowData => {
          if(rowData.tableData.isTreeExpanded === false && rowData.tableData.path.length === 1) {
            return {};
          }
          const rowBackgroundColor = constPathColors[rowData.tableData.path.length];
          return {backgroundColor: rowBackgroundColor};
        }
      }}
    />
  );
};

The row has default color before the expanding:

enter image description here

After expanding it has yellow (gradient depend on level) background color:

enter image description here

Upvotes: 3

ShinaBR2
ShinaBR2

Reputation: 2705

Let we talk about this problem first. It's neither programmatic nor css problem. It's just the problem how you show data, in other words, UX only.

There are several ways to achive, this is my work example: https://codesandbox.io/s/withered-dust-hb882?file=/src/App.js

Basically I just add one first column for parent only, that's it.

Upvotes: 5

Related Questions