TanStack / table

🤖 Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table
https://tanstack.com/table
MIT License
24.49k stars 3.03k forks source link

Column ordering weird behavior on grouped columns #5577

Closed nurbek-mirai closed 1 month ago

nurbek-mirai commented 1 month ago

TanStack Table version

V8.17.3

Framework/Library version

React ^18

Describe the bug and the steps to reproduce it

When implementing Column ordering DnD I encountered 2 issues:

  1. Initial column ordering is wrong when there is grouped columns (The Names grouped column appears last in the order even though it's second column in columns variable)
  2. When drag and dropping grouped columns cause weird behavior

columnOrder variable shows correct order but on the UI it's wrong.

I think these issues are similar: #4872 #5179

Your Minimal, Reproducible Example - (Sandbox Highly Recommended)

https://stackblitz.com/edit/tanstack-table-gu9mzb?file=src%2Fmain.tsx

Screenshots or Videos (Optional)

No response

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 & Code of Conduct

KevinVandy commented 1 month ago

Sorry, closing v7 issues. The version you listed does not match the code sandbox

nurbek-mirai commented 1 month ago

Am I missing something? It seems like the version is correct. I took it from the official example: https://tanstack.com/table/v8/docs/framework/react/examples/column-dnd image

mgryal commented 3 weeks ago

I have the same problem with v8, did you solve it?

nurbek-mirai commented 2 weeks ago

@mgryal No, I did not. @KevinVandy Could you please take a look again, the bug is in the v8.

mgryal commented 2 weeks ago

@nurbek-mirai I think I found something. Instead of mapping the column IDs, try this.

function getColumns(column: any) {
    if (column.columns) {
      return column.columns.map(getColumns) as string[];
    }
    return (column.id as string) || (column.accessorKey as string);
  }
function getColumnsId(columns) {
  const columnsArray = [];
  columns?.forEach((column) => {
    const columnsId = getColumns(column);
    if (typeof columnsId == 'string') columnsArray.push(columnsId);
    else columnsArray.push(...columnsId);
  });
  console.log(columnsArray);
  return columnsArray;
}

And replace the columnOrder state

 const [columnOrder, setColumnOrder] = React.useState<string[]>(() =>
    getColumnsId(columns)
  );

It's only for two levels of header grouping, but you can extrapolate the code.