-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
48749bd
commit 7f0b056
Showing
7 changed files
with
283 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
import React from 'react'; | ||
|
||
import { | ||
ColumnDef, | ||
flexRender, | ||
getCoreRowModel, | ||
getSortedRowModel, | ||
SortingFn, | ||
SortingState, | ||
useReactTable, | ||
} from '@tanstack/react-table'; | ||
import { makeData, Person } from './demoData'; | ||
import { | ||
TdsTable, | ||
TdsTableHeader, | ||
TdsHeaderCell, | ||
TdsTableBody, | ||
TdsTableBodyRow, | ||
TdsBodyCell, | ||
} from '@scania/tegel-react'; | ||
|
||
//custom sorting logic for one of our enum columns | ||
const sortStatusFn: SortingFn<Person> = (rowA, rowB, _columnId) => { | ||
const statusA = rowA.original.status; | ||
const statusB = rowB.original.status; | ||
const statusOrder = ['single', 'complicated', 'relationship']; | ||
return statusOrder.indexOf(statusA) - statusOrder.indexOf(statusB); | ||
}; | ||
|
||
const Tanstack = () => { | ||
const rerender = React.useReducer(() => ({}), {})[1]; | ||
|
||
const [sorting, setSorting] = React.useState<SortingState>([]); | ||
|
||
const columns = React.useMemo<ColumnDef<Person>[]>( | ||
() => [ | ||
{ | ||
accessorKey: 'firstName', | ||
cell: (info) => info.getValue(), | ||
//this column will sort in ascending order by default since it is a string column | ||
}, | ||
{ | ||
accessorFn: (row) => row.lastName, | ||
id: 'lastName', | ||
cell: (info) => info.getValue(), | ||
header: () => <span>Last Name</span>, | ||
sortUndefined: 'last', //force undefined values to the end | ||
sortDescFirst: false, //first sort order will be ascending (nullable values can mess up auto detection of sort order) | ||
}, | ||
{ | ||
accessorKey: 'age', | ||
header: () => 'Age', | ||
//this column will sort in descending order by default since it is a number column | ||
}, | ||
{ | ||
accessorKey: 'visits', | ||
header: () => <span>Visits</span>, | ||
sortUndefined: 'last', //force undefined values to the end | ||
}, | ||
{ | ||
accessorKey: 'status', | ||
header: 'Status', | ||
sortingFn: sortStatusFn, //use our custom sorting function for this enum column | ||
}, | ||
{ | ||
accessorKey: 'progress', | ||
header: 'Profile Progress', | ||
// enableSorting: false, //disable sorting for this column | ||
}, | ||
{ | ||
accessorKey: 'rank', | ||
header: 'Rank', | ||
invertSorting: true, //invert the sorting order (golf score-like where smaller is better) | ||
}, | ||
], | ||
[], | ||
); | ||
|
||
const [data, setData] = React.useState(() => makeData(1_000)); | ||
const refreshData = () => setData(() => makeData(100_000)); //stress test with 100k rows | ||
|
||
const table = useReactTable({ | ||
columns, | ||
data, | ||
debugTable: true, | ||
getCoreRowModel: getCoreRowModel(), | ||
getSortedRowModel: getSortedRowModel(), //client-side sorting | ||
onSortingChange: setSorting, //optionally control sorting state in your own scope for easy access | ||
// sortingFns: { | ||
// sortStatusFn, //or provide our custom sorting function globally for all columns to be able to use | ||
// }, | ||
//no need to pass pageCount or rowCount with client-side pagination as it is calculated automatically | ||
state: { | ||
sorting, | ||
}, | ||
// autoResetPageIndex: false, // turn off page index reset when sorting or filtering - default on/true | ||
// enableMultiSort: false, //Don't allow shift key to sort multiple columns - default on/true | ||
// enableSorting: false, // - default on/true | ||
// enableSortingRemoval: false, //Don't allow - default on/true | ||
// isMultiSortEvent: (e) => true, //Make all clicks multi-sort - default requires `shift` key | ||
// maxMultiSortColCount: 3, // only allow 3 columns to be sorted at once - default is Infinity | ||
}); | ||
|
||
//access sorting state from the table instance | ||
console.log(table.getState().sorting); | ||
|
||
return ( | ||
<div className="p-2"> | ||
<div className="h-2" /> | ||
<TdsTable verticalDividers={true} responsive={true} compactDesign={true}> | ||
{table.getHeaderGroups().map((headerGroup) => ( | ||
<TdsTableHeader key={headerGroup.id}> | ||
{headerGroup.headers.map((header) => { | ||
return ( | ||
<TdsHeaderCell key={header.id}> | ||
{header.isPlaceholder ? null : ( | ||
<div | ||
className={header.column.getCanSort() ? 'cursor-pointer select-none' : ''} | ||
onClick={header.column.getToggleSortingHandler()} | ||
title={ | ||
header.column.getCanSort() | ||
? header.column.getNextSortingOrder() === 'asc' | ||
? 'Sort ascending' | ||
: header.column.getNextSortingOrder() === 'desc' | ||
? 'Sort descending' | ||
: 'Clear sort' | ||
: undefined | ||
} | ||
> | ||
{flexRender(header.column.columnDef.header, header.getContext())} | ||
{{ | ||
asc: ' 🔼', | ||
desc: ' 🔽', | ||
}[header.column.getIsSorted() as string] ?? null} | ||
</div> | ||
)} | ||
</TdsHeaderCell> | ||
); | ||
})} | ||
</TdsTableHeader> | ||
))} | ||
|
||
<TdsTableBody> | ||
{table | ||
.getRowModel() | ||
.rows.slice(0, 10) | ||
.map((row) => { | ||
return ( | ||
<TdsTableBodyRow key={row.id}> | ||
{row.getVisibleCells().map((cell) => { | ||
return ( | ||
<TdsBodyCell key={cell.id}> | ||
{flexRender(cell.column.columnDef.cell, cell.getContext())} | ||
</TdsBodyCell> | ||
); | ||
})} | ||
</TdsTableBodyRow> | ||
); | ||
})} | ||
</TdsTableBody> | ||
</TdsTable> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Tanstack; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { faker } from '@faker-js/faker'; | ||
|
||
export type Person = { | ||
firstName: string; | ||
lastName: string | undefined; | ||
age: number; | ||
visits: number | undefined; | ||
progress: number; | ||
status: 'relationship' | 'complicated' | 'single'; | ||
rank: number; | ||
subRows?: Person[]; | ||
}; | ||
|
||
const range = (len: number) => { | ||
const arr: number[] = []; | ||
for (let i = 0; i < len; i++) { | ||
arr.push(i); | ||
} | ||
return arr; | ||
}; | ||
|
||
const newPerson = (): Person => { | ||
return { | ||
firstName: faker.person.firstName(), | ||
lastName: Math.random() < 0.1 ? undefined : faker.person.lastName(), | ||
age: faker.number.int(40), | ||
visits: Math.random() < 0.1 ? undefined : faker.number.int(1000), | ||
progress: faker.number.int(100), | ||
status: faker.helpers.shuffle<Person['status']>(['relationship', 'complicated', 'single'])[0]!, | ||
rank: faker.number.int(100), | ||
}; | ||
}; | ||
|
||
export function makeData(...lens: number[]) { | ||
const makeDataLevel = (depth = 0): Person[] => { | ||
const len = lens[depth]!; | ||
return range(len).map((_d): Person => { | ||
return { | ||
...newPerson(), | ||
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined, | ||
}; | ||
}); | ||
}; | ||
|
||
return makeDataLevel(); | ||
} |