diff --git a/packages/table-core/__tests__/Sorting.test.ts b/packages/table-core/__tests__/Sorting.test.ts new file mode 100644 index 0000000000..c7898d6601 --- /dev/null +++ b/packages/table-core/__tests__/Sorting.test.ts @@ -0,0 +1,80 @@ +import { + ColumnDef, + createTable, + getCoreRowModel, + getSortedRowModel, +} from '../src' + +describe('Sorting', () => { + describe('alphanumeric sort booleans ascending', () => { + it('should return rows in correct ascending order', () => { + const data = [ + { value: false }, + { value: true }, + { value: false }, + { value: true }, + ] + const columns: ColumnDef<{value: boolean}>[] = [{ + accessorKey: "value", + header: "Value", + sortingFn: "alphanumeric" + }] + + const table = createTable({ + onStateChange() {}, + renderFallbackValue: '', + data, + state: { sorting: [{ + id: "value", + desc: false, + }]}, + columns, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + }) + + const rowModel = table.getSortedRowModel() + + expect(rowModel.rows[0].getValue("value")).toBe(false) + expect(rowModel.rows[1].getValue("value")).toBe(false) + expect(rowModel.rows[2].getValue("value")).toBe(true) + expect(rowModel.rows[3].getValue("value")).toBe(true) + }) + }) + + describe('alphanumeric sort floats ascending', () => { + it('should return rows in correct ascending order', () => { + const data = [ + { value: 0.85 }, + { value: 0.001000000047 }, + { value: 0.2000016 }, + { value: 0.002002 }, + ] + const columns: ColumnDef<{value: number}>[] = [{ + accessorKey: "value", + header: "Value", + sortingFn: "alphanumeric" + }] + + const table = createTable({ + onStateChange() {}, + renderFallbackValue: '', + data, + state: { sorting: [{ + id: "value", + desc: false, + }]}, + columns, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + }) + + const rowModel = table.getSortedRowModel() + + expect(rowModel.rows[0].getValue("value")).toBe(0.001000000047) + expect(rowModel.rows[1].getValue("value")).toBe(0.002002) + expect(rowModel.rows[2].getValue("value")).toBe(0.2000016) + expect(rowModel.rows[3].getValue("value")).toBe(0.85) + }) + }) +}) diff --git a/packages/table-core/src/sortingFns.ts b/packages/table-core/src/sortingFns.ts index 5cb88dac5f..287a6e36ed 100644 --- a/packages/table-core/src/sortingFns.ts +++ b/packages/table-core/src/sortingFns.ts @@ -55,6 +55,9 @@ function compareBasic(a: any, b: any) { } function toString(a: any) { + if (typeof a === 'boolean') { + return String(a) + } if (typeof a === 'number') { if (isNaN(a) || a === Infinity || a === -Infinity) { return '' @@ -71,6 +74,13 @@ function toString(a: any) { // It handles numbers, mixed alphanumeric combinations, and even // null, undefined, and Infinity function compareAlphanumeric(aStr: string, bStr: string) { + // Check if the string contains only a number + const aFloat = parseFloat(aStr); + const bFloat = parseFloat(bStr); + if(!isNaN(aFloat) && !isNaN(bFloat)) { + return compareBasic(aFloat, bFloat) + } + // Split on number groups, but keep the delimiter // Then remove falsey split values const a = aStr.split(reSplitAlphaNumeric).filter(Boolean)