KevinVandy / mantine-react-table

A fully featured Mantine V5 implementation of TanStack React Table V8, forked from Material React Table
https://www.mantine-react-table.com/
MIT License
807 stars 137 forks source link

Resize column with enableRowVirtualization, when there is only 1 single row data, the resize cause that row disappear #374

Open quangkhuat1995 opened 2 months ago

quangkhuat1995 commented 2 months ago

mantine-react-table version

v1.3.4

react & react-dom versions

18.2.0

Describe the bug and the steps to reproduce it

First of all, I understand that the document has already mentioned to use virtual only when there are many data, like at least 50 rows. However, here is the use case that we have.

We have a table that render data from our server, the table has total 24 columns (not all visibility at once so we don't use virtual column) and can render pagination from 50-100-250-1000 rows per page. We have a form to create filters/search to build our API query for the table data. So most of the time we will have a lot of things and we use enableRowVirtualization.

Since we have many columns so we also use enableColumnResizing.

But, if user searches for something that return only 1 item, for example exact full name. And then performs a resize column, that single row data will disappear. With more than 1 item (eg: 2), everything works fine. I can replicate that with the code sandbox from document page.

Minimal, Reproducible Example - (Optional, but Recommended)

https://codesandbox.io/p/devbox/mantine-react-table-example-enable-row-virtualization-6scmjq?file=%2Fsrc%2FTS.tsx%3A59%2C36

This is the sandbox from this document

Please change these to replicate the issue:

Repeat again, but now with setData(makeData(2)), you won't see error anymore.

Screenshots or Videos (Optional)

image

Do you intend to try to help solve this bug with your own PR?

No, because I do not have time to dig into it

Terms

sspencer-arine commented 1 month ago

@quangkhuat1995 did you happen to find a workaround for this?

quangkhuat1995 commented 1 month ago

Yes this is my workaround:

General idea: If the response is only 1 item, I will add another fake row. SO the table now will have 2 row and the resize column will not cause disappear anymore.

      if (response.length === 1 && !screenMobile) {
        setData([...response, FAKE_ROW]); // FAKE_ROW = { id: 'fakeId' };
      } else {
        // mobile doesn't have resize feature
        setData(response);
      }

1. Modify the columns

And in your columns, ignore the rendering value of that fake row in every column, even for row action column

const columns = [
      {
          id: "firstName",
          accessorFn: (row) => {
                if (row?.id === "fakeId") return null; // render nothing for this row
                return (
                <p>{row.firstName}</p>
                );
              },
          ....
      },
      {
          id: "lastName",
          accessorFn: (row) => {
                if (row?.id === "fakeId") return null; // render nothing for this row
                return (
                <p>{row.lastName}</p>
                );
              },
          ....
      },
      ....
]

2. Do not render action buttons for fake row

 renderRowActions: ({ row }) => {
      if (row.original.id === "fakeId") return null;
      return (
        // your buttons
      );
    }

3. Everyplace that you interact with your row data, you should filter out the fake one, for example:

const handleExportCSV = () => {
    const newData = data
      .filter((row) => row.id !== "fakeId") // remove fake data
      .map((row) => {
        return {
          // your data
        };
      });

   // do something with your true data
  };

This is the result, you will have a blank row at the bottom, but I think it's ok for this edge case

image