reactjstypescriptreact-data-grid

How can one set different styles for cells in selected rows in react-data-grid?


I use react-data-grid from adazzle in version 7.0.0-beta.28. My problem is that I have a table where one column should not be editable. Therefore, I want to visualise this by making the background of this column grey. Additionally, I want to have a colour visualising a selected row. My question is: how can I change the colour of the grey cells if they are selected while the other cells in the selected row are in a different colour? In the following picture you see an example, where the left "Numbers" column should not be editable and is coloured grey. The second row is selected, but only "Banana" is coloured in blue marking the selection of the row and "2" is still grey. I want to have that the "2" cell is in another colour than the rest of the "Numbers" column.

enter image description here

I set the grey colour with cellClass in the columns definition like this:

    const columns = [
      {key: "numbers", name: "Numbers", editable: false, cellClass: "text-bg-secondary"},
      {key: "things", name: "Things", editable: true},
    ];

The selection is implemented as follows:

    const [selectedRows, setSelectedRows] = useState<ReadonlySet<number>>(() => new Set([1]));

    const handleRowClick = (args: CellClickArgs<RowType, any>) => {
      setSelectedRows(new Set([args.row.id]));
    };

    const rowKeyGetter = (row: RowType) => row.id;

    function App() {
      return <DataGrid columns={columns} rows={rows} rowKeyGetter={rowKeyGetter} selectedRows={selectedRows} onSelectedRowsChange={setSelectedRows} onCellClick={handleRowClick}/>;
    }

I know that I can change the colour of a row with a RowRenderer, but I do not see how to change the cells individually here. Otherwise, one can build cells in the RowRenderer with div tags, but I do not know how to keep the default formatting of the cells there. And with a CellFormatter one can change the cell content but then one cannot paint the whole background because the cell content has margins from the outer cell div tag.

I looked deep into the code of the library but could not find a way to solve my simple problem. Is it really not possible or do I miss something?


Solution

  • I finally found a solution to my problem. I use now the fact that cellClass can be a function getting the current row. Additionally, I added a boolean to my row type holding the information if a row is selected which can be used in the function from cellClass.

    type RowType = { id: number, title: string, isSelected: boolean }
    
    const columns = [
      { key: 'numbers', name: 'Numbers', cellClass: (row: RowType) => row.isSelected ? "text-bg-light" : "text-bg-secondary" },
      { key: 'things', name: 'Things' }
    ];
    
    const rows = [
      {numbers: 1, things: "Apple", isSelected: false},
      {numbers: 2, things: "Banana", isSelected: true},
      {numbers: 3, things: "Tomato", isSelected: false},
      {numbers: 4, things: "Salad", isSelected: false},
      {numbers: 5, things: "Carrot", isSelected: false}
    ];
    
    const handleRowClick = (args: CellClickArgs<RowType, any>) => {
      setSelectedRows(new Set([args.row.id]));
      rows.map((row: RowType) => { if(row.id == args.row.id) row.isSelected = true; else row.isSelected = false });
    };
    

    Here in handleRowClick, I need to set the actual selection by setting isSelected of each row. This leads then to the correct result as seen below where "2" now has another colour than the other cells in the "Numbers" column. enter image description here