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.55k stars 3.03k forks source link

Issues when sortingFn is 'auto' and number of records is less than 10 #4908

Open hviranicitco opened 1 year ago

hviranicitco commented 1 year ago

Describe the bug

When you have less than 10 records and for a column if sortingFn is 'auto' which is default. The sorting does not work correctly.

This is happening because of this line in the code:

table-core/src/features/Sorting.ts

getAutoSortingFn: () => {
        const firstRows = table.getFilteredRowModel().flatRows.slice(10)
...
}

This should have been:

 const firstRows = table.getFilteredRowModel().flatRows.slice(0, 10)

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/optimistic-shadow-3z2j6c?file=%2Fsrc%2FmakeData.ts%3A1%2C1

Steps to reproduce

Check the sorting on the Status column

Expected behavior

The Status column should be sorted correctly.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

Windows with Chrome

react-table version

v8.9.2

TypeScript version

No response

Additional context

No response

Terms & Code of Conduct

supagu commented 11 months ago

I hit this problem also.

mjewell commented 3 months ago

In the latest version of react-table (8.15.3) you can fix this yourself until a fix is released by defining a custom feature that overrides the existing behaviour:

// Fixes auto sorting: https://github.com/TanStack/table/issues/4908

import {
  Column,
  reSplitAlphaNumeric,
  RowData,
  sortingFns,
  Table,
  TableFeature,
} from '@tanstack/react-table';

const SortingFixFeature: TableFeature = {
  createColumn: <TData extends RowData, TValue>(
    column: Column<TData, TValue>,
    table: Table<TData>,
  ): void => {
    // copied from https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSorting.ts
    column.getAutoSortingFn = () => {
      // slice(10) ==> slice(0, 10)
      const firstRows = table.getFilteredRowModel().flatRows.slice(0, 10);

      let isString = false;

      for (const row of firstRows) {
        const value = row?.getValue(column.id);

        if (Object.prototype.toString.call(value) === '[object Date]') {
          return sortingFns.datetime;
        }

        if (typeof value === 'string') {
          isString = true;

          if (value.split(reSplitAlphaNumeric).length > 1) {
            return sortingFns.alphanumeric;
          }
        }
      }

      if (isString) {
        return sortingFns.text;
      }

      return sortingFns.basic;
    };
  },
};

export default SortingFixFeature;

And then using it in your table

const table = useReactTable({
  _features: [SortingFixFeature],
  // columns, data, whatever else
});
evman182 commented 3 months ago

@tannerlinsley Was the intended behavior that it only try to choose a sort function if there's 10 or more rows, or that it make that decision based on up to the first 10 rows. If it's the latter, I'll open a PR based on @hviranicitco's suggestion above.