From 74d249e2b9098e38fb2cf55f4672bd6a5c5dfa79 Mon Sep 17 00:00:00 2001 From: Joey Miller <9375730+itsmejoeeey@users.noreply.github.com> Date: Wed, 4 Oct 2023 12:16:32 +1300 Subject: [PATCH 1/2] Fix alphanumeric sort bool support (fix #5108) --- packages/table-core/__tests__/Sorting.test.ts | 45 +++++++++++++++++++ packages/table-core/src/sortingFns.ts | 3 ++ 2 files changed, 48 insertions(+) create mode 100644 packages/table-core/__tests__/Sorting.test.ts diff --git a/packages/table-core/__tests__/Sorting.test.ts b/packages/table-core/__tests__/Sorting.test.ts new file mode 100644 index 0000000000..ed198b0f91 --- /dev/null +++ b/packages/table-core/__tests__/Sorting.test.ts @@ -0,0 +1,45 @@ +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) + }) + }) + }) +}) diff --git a/packages/table-core/src/sortingFns.ts b/packages/table-core/src/sortingFns.ts index 5cb88dac5f..b3987407c8 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 '' From a271441695218d77aad541f6c1aaa0f410e1d38c Mon Sep 17 00:00:00 2001 From: Joey Miller <9375730+itsmejoeeey@users.noreply.github.com> Date: Wed, 4 Oct 2023 12:16:59 +1300 Subject: [PATCH 2/2] Fix alphanumeric sort float support (fix #5108) --- packages/table-core/__tests__/Sorting.test.ts | 35 +++++++++++++++++++ packages/table-core/src/sortingFns.ts | 7 ++++ 2 files changed, 42 insertions(+) diff --git a/packages/table-core/__tests__/Sorting.test.ts b/packages/table-core/__tests__/Sorting.test.ts index ed198b0f91..c7898d6601 100644 --- a/packages/table-core/__tests__/Sorting.test.ts +++ b/packages/table-core/__tests__/Sorting.test.ts @@ -41,5 +41,40 @@ describe('Sorting', () => { 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 b3987407c8..287a6e36ed 100644 --- a/packages/table-core/src/sortingFns.ts +++ b/packages/table-core/src/sortingFns.ts @@ -74,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)