milanHrabos
milanHrabos

Reputation: 1965

Tanstack table v8 not resizing columns

Having this react component:

import rawd from '../../data.json';
import { flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"
import { useState } from "react";

const columns = [
  {
    accessorKey: 'id',
    id: 'id',
    header: 'Id',
    cell: props => <p>{props.getValue()}</p>
  },
  {
    accessorKey: 'mail',
    id: 'email',
    header: 'Email',
    cell: props => <p>{props.getValue()}</p>
  },
  {
    accessorKey: 'name.first_name',
    id: 'first_name',
    header: 'First Name',
    cell: props => <p>{props.getValue()}</p>
  },
  {
    accessorKey: 'name.last_name',
    id: 'last_name',
    header: 'Last Name',
    cell: props => <p>{props.getValue()}</p>
  },
  {
    accessorKey: 'date_of_birth',
    id: 'date_of_birth',
    header: 'Date of birth',
    cell: props => <p>{props.getValue()}</p>
  },
];


function NikitaDev() {
  const [data] = useState(rawd);

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    columnResizeMode: 'onChange'
  });

  console.log(table.getHeaderGroups());
  return (
    <div className="overflow-x-auto flex flex-col m-[1rem]">
      <table className='w-full text-left text-sm text-gray-500'>
        <thead className='text-xs text-gray-700 uppercase bg-gray-50'>
          {table.getHeaderGroups().map(hg => (
            <tr key={hg.id}>
              {hg.headers.map(h => (
                <th key={h.id} className='relative border px-6 py-3'>
                  {h.column.columnDef.header}
                  <div
                    onMouseDown={h.getResizeHandler()}
                    onTouchStart={h.getResizeHandler()}
                    className="absolute top-0 right-0 h-full w-[5px] hover:bg-gray-300 cursor-col-resize"
                  >
                  </div>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody>
          {table.getRowModel().rows.map(row => (
            <tr id={row.id} className='odd:bg-white even:bg-gray-50'>
              {row.getVisibleCells().map(c => (
                <td key={c.id} className='border p-[0.25rem]'>
                  {flexRender(
                    c.column.columnDef.cell,
                    c.getContext()
                  )}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  )
}

export default NikitaDev

I would expect that by dragging the table header's on the edge - this div:

<div
                    onMouseDown={h.getResizeHandler()}
                    onTouchStart={h.getResizeHandler()}
                    className="absolute top-0 right-0 h-full w-[5px] hover:bg-gray-300 cursor-col-resize"
                  >
</div>

should resize the column. But it doesn't. Why?

Upvotes: 1

Views: 2108

Answers (2)

Mahan Mashoof
Mahan Mashoof

Reputation: 189

Try adding this css:

table {
  table-layout: fixed;
  width: 100%;
}

th, td {
  overflow: hidden
  text-overflow: ellipsis; (optional)
  white-space: nowrap;
}

Upvotes: 3

Wongjn
Wongjn

Reputation: 24343

It seems you haven't passed the column sizing definitions into the table. As per the documentation:

These event handlers are just convenience functions that call other internal APIs to update the column sizing state and re-render the table.

If we read a bit earlier in the documentation:

Column Size APIs

To apply the size of a column to the column head cells, data cells, or footer cells, you can use the following APIs:

header.getSize()
column.getSize()
cell.column.getSize()

How you apply these size styles to your markup is up to you, but it is pretty common to use either CSS variables or inline styles to apply the column sizes.

<th
  key={header.id}
  colSpan={header.colSpan}
  style={{ width: `${header.getSize()}px` }}

Thus, we could add the header.getSize() call to your table headers so that the column sizing state is reflected in the interface:

{hg.headers.map(h => (
  <th
    key={h.id}
    className='relative border px-6 py-3'>
    style={{ width: `${header.getSize()}px` }}
  >
    {h.column.columnDef.header}

See an example of this working in this StackBlitz project.

Upvotes: 3

Related Questions