Changing column width in react-table
Asked Answered
T

6

31

I have a react-table and I am trying to change the column size. I've tried editing the "width" value within the columns, editing the values in the scss stylesheet, and adding inline styling, but nothing is working. Where do I make css changes to this react-table ? Any help would be appreciated. Any example I see changes it within the column area as I've tried.

import React, {useState, Fragment} from "react";
import {useTable, useFilters, useGlobalFilter, useRowSelect} from "react-table";
import dataSet from "../data";
import {IndeterminateCheckbox} from './TableCheckbox';


function DeployTable() {

    function DefaultColumnFilter({
                                     column: { filterValue, preFilteredRows, setFilter },
                                 }) {
        const count = preFilteredRows.length

        return (
            <input
                value={filterValue || ''}
                onChange={e => {
                    setFilter(e.target.value || undefined) // Set undefined to remove the filter entirely
                }}
                placeholder={`Search ${count} records...`}
            />
        )
    }

    const [data] = useState(dataSet);

    const [columns] = useState([

        {
            width:'20',
            Header: "Deploy Id",
            accessor: "deploy_id"
        },
        {

            Header: "Requestor",
            accessor: "requestor",
            filter: "fuzzyText"
        },
        {
            Header: "Market",
            accessor: "market"
        },
        {
            Header: "Email",
            minWidth: 50,
            maxWidth: 50,
            accessor: "email"
        },
        {
            Header: "Environment",
            accessor: "environment"
        },
        {
            Header: "Completed Date",
            accessor: "completed_date"
        },
        {
            Header: "Deploy Group",
            accessor: "deploy_group"
        },
        {
            Header: "Job Status",
            accessor: "job_status"
        },
        {
            Header: "CRQ",
            accessor: "crq"
        }

    ]);
    const defaultColumn = React.useMemo(
        () => ({
            // Let's set up our default Filter UI
            Filter: DefaultColumnFilter,
        }),
        []
    )
    const filterTypes = React.useMemo(
        () => ({
            text: (rows, id, filterValue) => {
                return rows.filter(row => {
                    const rowValue = row.values[id];
                    return rowValue !== undefined
                        ? String(rowValue)
                            .toLowerCase()
                            .startsWith(String(filterValue).toLowerCase())
                        : true;
                });
            }
        }),
        []
    );
    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow
    } = useTable({
            columns,
            data,
            defaultColumn,
            filterTypes
        },
        useFilters,
        useGlobalFilter,
        useRowSelect,
        // Here we will use a plugin to add our selection column
        hooks => {
            hooks.visibleColumns.push(columns => {
                return [
                    {
                        id: 'selection',
                        // Make this column a groupByBoundary. This ensures that groupBy columns
                        // are placed after it
                        groupByBoundary: true,
                        // The header can use the table's getToggleAllRowsSelectedProps method
                        // to render a checkbox
                        Header: ({ getToggleAllRowsSelectedProps }) => (
                            <div>
                                <IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
                            </div>
                        ),
                        // The cell can use the individual row's getToggleRowSelectedProps method
                        // to the render a checkbox
                        Cell: ({ row }) => (
                            <div>
                                <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
                            </div>
                        ),
                    },
                    ...columns,
                ]
            })
        });

    return (
        <Fragment>
            <table {...getTableProps()}  >
                <thead>
                {headerGroups.map(headerGroup => (
                    <tr {...headerGroup.getHeaderGroupProps()}>
                        {headerGroup.headers.map(column => (
                            <th {...column.getHeaderProps()}>{column.render("Header")}
                                <div>{column.canFilter ? column.render('Filter') : null}</div></th>
                        ))}
                    </tr>
                ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                {rows.map((row, i) => {
                    prepareRow(row);
                    return (
                        <tr {...row.getRowProps()}>
                            {row.cells.map(cell => {
                                return <td {...cell.getCellProps()}>{cell.render("Cell")}</td>;
                            })}
                        </tr>
                    );
                })}
                </tbody>
            </table>
        </Fragment>
    );
}

export default DeployTable;

Here in the stylesheet.

    .Button {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  padding: 10px;
  font-size: 14px;
}
body {
  background-color: #d1e5f0;
  font: 14px sans-serif;
}

#container {
  width: 100%;
  height: 100%;
  position: relative;
}

#title {
  font: 26px sans-serif;
  position: absolute;
  top: -40px;
  left: 450px;
}

#FilterableTable {
  width: 90%;
  height: 90%;
  position: absolute;
  top: 40px;
  left: 20px;
}

.SearchBar {
  display: inline;
  position: relative;
  left: 1%;
}

.SearchBar input {
  position: relative;
  left: 2%;
}

.Button {
  display: inline;
  position: relative;
  left: 1%;
}


table {
  empty-cells: show;
  position: initial;
  top: 40px;
  left: 20px;
  border-collapse: collapse;
  margin-bottom: 20px;
  margin-top: 20px;
}

table a:link, a:visited { text-decoration: none; }

table a:hover, a:active { text-decoration: underline; }

table, th, td { border: 1px solid black; }
table, th, tr { border: 1px solid black; }

td, th {
  padding: 5px;
  text-align: center;
  height: 20px;
}

th {
  background-color: #4393c3;
  color: #d9f0a3;
}

td { background-color: #92c5de; }

tr { background-color: #92c5de; }

tr:hover td { background-color: #edf8b1; }
tr:hover tr { background-color: #edf8b1; }

/*
This query will take effect for any screen smaller than 480px.
    */
@media only screen and (max-device-width: 480px) {



  /* Force table to not be like tables anymore */
  table, thead, tbody, th, td, tr {
    display: block;
  }
  table{
    border: none;
    width: 100%;
    left: 0px;
    padding-right: 40px;
    height: 400px;
    overflow-y: scroll;
  }
  tbody{
    border: none;
    width: 100%;
    left: 0px;

  }
  /* Hide table headers (but not display: none;, for accessibility) */
  thead tr {
    position: absolute;
    top: -9999px;
    left: -9999px;
  }

  tr {
    margin: 0 0 1rem 0;
  }
  .ReactTable .rt-thead {
    overflow-y: scroll;
  }


  td {
    /* Behave  like a "row" */
    border: none;
    border-bottom: 1px solid #eee;
    position: relative;
    padding-left: 50%;
  }

  td:before {
    /* Now like a table header */
    position: absolute;
    /* Top/left values mimic padding */
    top: 0;
    left: 6px;
    width: 45%;
    padding-right: 10px;
    white-space: nowrap;
  }
  td:nth-of-type(1):before { content: "Select"; }
  td:nth-of-type(2):before { content: "Deploy ID"; }
  td:nth-of-type(3):before { content: "Requestor"; }
  td:nth-of-type(4):before { content: "Market"; }
  td:nth-of-type(5):before { content: "Env"; }
  td:nth-of-type(6):before { content: "Group"; }
  td:nth-of-type(7):before { content: "Deploy Date"; }
  td:nth-of-type(8):before { content: "Approver"; }
  td:nth-of-type(9):before { content: "Completed Date"; }
  td:nth-of-type(10):before { content: "CRQ"; }
  td:nth-of-type(11):before { content: "Job Status"; }
}
Transponder answered 2/6, 2020 at 12:47 Comment(1)
Please try codesandbox.io/s/k9n3y82wov?file=/index.js:768-769Snubnosed
N
52

In react-table v7 you need to use a layout hook (useBlockLayout, useAbsoluteLayout or useFlexLayout) so the specified width is applied. Important: all those hooks set a default column width to 150px. You can see an example in Full Width Resizable Table.

In react-table v8 you can use the attributes size, minSize and maxSize on the columns definition (see the example below) or define the default value on tableOptions.defaultColumn. You can read more in Column Sizing.


In react-table v7 if you don't want to use a layout hook, you can use getHeaderProps and getCellProps according to your needs, acessing minWidth and width values, as the example below.

In v8 you need to replace width, minWidth and maxWidth to size, minSize and maxSize, as mentioned in the Migrating to V8 docs.

function Table({ data }) {
  const columns = useMemo(
    () => [
      {
        Header: 'Name',
        accessor: 'name',
        maxWidth: 400,
        minWidth: 140,
        width: 200,
      },
      {
        Header: 'Qty',
        accessor: 'quantity',
        maxWidth: 70,
        minWidth: 50,
        width: 60,
      },
    ],
    [],
  );

  const {
    getTableBodyProps,
    getTableProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable({ columns, data, getRowId });

  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map(headerGroup => (
          <tr {...headerGroup.getHeaderGroupProps()}>
            {headerGroup.headers.map(column => (
              <th
                {...column.getHeaderProps({
                  style: { minWidth: column.minWidth, width: column.width },
                })}
              >
                <span>{column.render('Header')}</span>
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map(row => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map(cell => {
                return (
                  <td {...cell.getCellProps({
                      style: {
                        minWidth: cell.column.minWidth,
                        width: cell.column.width,
                      },
                    })>
                    {cell.render('Cell')}
                  </td>
                );
              })}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}
Naught answered 25/3, 2021 at 17:30 Comment(2)
will this really works for docx tablesOtic
Thank you! Do anyone know how to change the default width (150px)? I tried this width: cell.column.width || "200px" but no luck.Kagera
I
11

Try this: You can style rows, cells, columns in the same way (it's known as prop getter pattern)

In your code: search for ...column.getHeaderProps()

Pass an object with style to column.getHeaderProps() & you can also add more props if required along with style:

...column.getHeaderProps({
                          style: {width: '200px'}
                         })

or

<th {...column.getHeaderProps()}
style= {{ ...column.getHeaderProps.style, ...getColumnStyle(column) }} >

In above code, getColumnStyle(column) is my custom function where I return style for that particular column.

Explanation: It is a headless UI library. means, It only provides logic and no UI (build your own UI), We can style table however we want, It is called prop getter pattern. You can read more on here: https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters

For styling cells & rows: https://github.com/tannerlinsley/react-table/discussions/2186

Ideomotor answered 8/6, 2020 at 19:52 Comment(0)
D
6

By default width is 150, given in docs. Since width is an int property, don't use single quotes.

columns: [
          {
            Header: "First Name",
            accessor: "firstName",
            width: 90
          },
          {
            Header: "Last Name",
            accessor: "lastName"
          }
        ]
Dehaven answered 6/1, 2021 at 12:50 Comment(0)
B
4

I am using TanStack Table v8. I defined a size in columns and used it to change the width of the table like this.

const columns = [
  {
    header: 'Name',
    cell: (info) => info.getValue(),
    accessorKey: 'title',
    size: 100,
  },
  {
    header: 'Category',
    cell: (info) => info.getValue(),
    accessorKey: 'category',
    size: 100,
  },
  {
    header: 'Description',
    cell: (info) => info.getValue(),
    accessorKey: 'description',
  },
];

table

<table style={{ width: '100%' }}>
  <thead>
    {table.getHeaderGroups().map((headerGroup) => (
      <tr key={headerGroup.id}>
        {headerGroup.headers.map((header) => (
          <th
            key={header.id}
            colSpan={header.colSpan}
            style={{
              width:
                header.getSize() !== 150 ? header.getSize() : undefined,
            }}
          >
            {flexRender(
              header.column.columnDef.header,
              header.getContext(),
            )}
          </th>
        ))}
      </tr>
    ))}
  </thead>
  <tbody>
    ...
  </tbody>
</table>

It didnt work for me. But I set table-layout: fixed as said here.

<table style={{ tableLayout: 'fixed', width: '100%' }}>

Now it works fine.

Benelux answered 10/3, 2023 at 13:18 Comment(2)
Removing tableLayout: 'fixed'solved it for me.Demise
I've spent a couple of hours but not luck. Finally, this worked for me.Hali
S
3

In TanStack Table v8 (the successor to this React Table v7), to set width you can set size in column definitions e.g.

columnHelper.accessor('myCol', {
  size: 70,
  cell: (info) => info.getValue(),
  footer: (info) => info.column.id,
})

Ref: https://tanstack.com/table/v8/docs/api/features/column-sizing#size

Semination answered 23/1, 2023 at 13:55 Comment(0)
C
3

In TanStack Table V8, the default column width is 150. We can override it by using the defaultColumn property.

const table = useReactTable({
    defaultColumn: {
      size: 100
    }
});
Corelative answered 27/7, 2023 at 10:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.