@tanstack/table-core 8.0.0-alpha.86 → 8.0.0-alpha.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@tanstack/table-core",
3
3
  "author": "Tanner Linsley",
4
- "version": "8.0.0-alpha.86",
5
- "description": "Hooks for building lightweight, fast and extendable datagrids for React",
4
+ "version": "8.0.0-alpha.89",
5
+ "description": "Headless UI for building powerful tables & datagrids for TS/JS.",
6
6
  "license": "MIT",
7
- "homepage": "https://github.com/tanstack/react-table#readme",
7
+ "homepage": "https://github.com/tanstack/table#readme",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/tanstack/react-table.git"
10
+ "url": "git+https://github.com/tanstack/table.git"
11
11
  },
12
12
  "publishConfig": {
13
13
  "registry": "https://registry.npmjs.org/"
package/src/core/cell.ts CHANGED
@@ -19,8 +19,8 @@ export function createCell<TGenerics extends TableGenerics>(
19
19
  row,
20
20
  column,
21
21
  getValue: () => row.getValue(columnId),
22
- renderCell: () =>
23
- column.columnDef.cell
22
+ renderCell: () => {
23
+ return column.columnDef.cell
24
24
  ? instance._render(column.columnDef.cell, {
25
25
  instance,
26
26
  column,
@@ -28,7 +28,8 @@ export function createCell<TGenerics extends TableGenerics>(
28
28
  cell: cell as Cell<TGenerics>,
29
29
  getValue: cell.getValue,
30
30
  })
31
- : null,
31
+ : null
32
+ },
32
33
  }
33
34
 
34
35
  instance._features.forEach(feature => {
@@ -98,7 +98,6 @@ export function createColumn<TGenerics extends TableGenerics>(
98
98
  }
99
99
 
100
100
  let column: CoreColumn<TGenerics> = {
101
- ...columnDef,
102
101
  id: `${id}`,
103
102
  accessorFn,
104
103
  parent: parent as any,
@@ -131,8 +131,12 @@ export const Expanding: TableFeature = {
131
131
  const expanded = instance.getState().expanded
132
132
 
133
133
  // If expanded is true, save some cycles and return true
134
- if (expanded === true) {
135
- return true
134
+ if (typeof expanded === 'boolean') {
135
+ return expanded === true
136
+ }
137
+
138
+ if (!Object.keys(expanded).length) {
139
+ return false
136
140
  }
137
141
 
138
142
  // If any row is not expanded, return false
@@ -26,6 +26,10 @@ export type ColumnSort = {
26
26
 
27
27
  export type SortingState = ColumnSort[]
28
28
 
29
+ export type SortingTableState = {
30
+ sorting: SortingState
31
+ }
32
+
29
33
  export type SortingFn<TGenerics extends TableGenerics> = {
30
34
  (rowA: Row<TGenerics>, rowB: Row<TGenerics>, columnId: string): number
31
35
  }
@@ -35,10 +39,6 @@ export type CustomSortingFns<TGenerics extends TableGenerics> = Record<
35
39
  SortingFn<TGenerics>
36
40
  >
37
41
 
38
- export type SortingTableState = {
39
- sorting: SortingState
40
- }
41
-
42
42
  export type SortingFnOption<TGenerics extends TableGenerics> =
43
43
  | 'auto'
44
44
  | BuiltInSortingFn
@@ -58,6 +58,7 @@ export type SortingColumn<TGenerics extends TableGenerics> = {
58
58
  getAutoSortingFn: () => SortingFn<TGenerics>
59
59
  getAutoSortDir: () => SortDirection
60
60
  getSortingFn: () => SortingFn<TGenerics>
61
+ getNextSortingOrder: () => SortDirection | false
61
62
  getCanSort: () => boolean
62
63
  getCanMultiSort: () => boolean
63
64
  getSortIndex: () => number
@@ -191,6 +192,9 @@ export const Sorting: TableFeature = {
191
192
  // return
192
193
  // }
193
194
 
195
+ // this needs to be outside of instance.setSorting to be in sync with rerender
196
+ const nextSortingOrder = column.getNextSortingOrder()
197
+
194
198
  instance.setSorting(old => {
195
199
  // Find any existing sorting for this column
196
200
  const existingSorting = old?.find(d => d.id === column.id)
@@ -200,7 +204,7 @@ export const Sorting: TableFeature = {
200
204
  let newSorting: SortingState = []
201
205
 
202
206
  // What should we do with this sort action?
203
- let sortAction
207
+ let sortAction: 'add' | 'remove' | 'toggle' | 'replace'
204
208
 
205
209
  if (column.getCanMultiSort() && multi) {
206
210
  if (existingSorting) {
@@ -219,20 +223,13 @@ export const Sorting: TableFeature = {
219
223
  }
220
224
  }
221
225
 
222
- const sortDescFirst =
223
- column.columnDef.sortDescFirst ??
224
- instance.options.sortDescFirst ??
225
- column.getAutoSortDir() === 'desc'
226
-
227
226
  // Handle toggle states that will remove the sorting
228
227
  if (
229
228
  sortAction === 'toggle' && // Must be toggling
230
229
  (instance.options.enableSortingRemoval ?? true) && // If enableSortRemove, enable in general
231
230
  !hasDescDefined && // Must not be setting desc
232
231
  (multi ? instance.options.enableMultiRemove ?? true : true) && // If multi, don't allow if enableMultiRemove
233
- (existingSorting?.desc // Finally, detect if it should indeed be removed
234
- ? !sortDescFirst
235
- : sortDescFirst)
232
+ !nextSortingOrder // Finally, detect if it should indeed be removed
236
233
  ) {
237
234
  sortAction = 'remove'
238
235
  }
@@ -241,7 +238,7 @@ export const Sorting: TableFeature = {
241
238
  newSorting = [
242
239
  {
243
240
  id: column.id,
244
- desc: hasDescDefined ? desc! : !!sortDescFirst,
241
+ desc: hasDescDefined ? desc! : nextSortingOrder! === 'desc',
245
242
  },
246
243
  ]
247
244
  } else if (sortAction === 'add' && old?.length) {
@@ -249,7 +246,7 @@ export const Sorting: TableFeature = {
249
246
  ...old,
250
247
  {
251
248
  id: column.id,
252
- desc: hasDescDefined ? desc! : !!sortDescFirst,
249
+ desc: hasDescDefined ? desc! : nextSortingOrder! === 'desc',
253
250
  },
254
251
  ]
255
252
  // Take latest n columns
@@ -265,7 +262,7 @@ export const Sorting: TableFeature = {
265
262
  if (d.id === column.id) {
266
263
  return {
267
264
  ...d,
268
- desc: hasDescDefined ? desc! : !existingSorting?.desc,
265
+ desc: hasDescDefined ? desc! : nextSortingOrder! === 'desc',
269
266
  }
270
267
  }
271
268
  return d
@@ -278,6 +275,24 @@ export const Sorting: TableFeature = {
278
275
  })
279
276
  },
280
277
 
278
+ getNextSortingOrder: () => {
279
+ const sortDescFirst =
280
+ column.columnDef.sortDescFirst ??
281
+ instance.options.sortDescFirst ??
282
+ column.getAutoSortDir() === 'desc'
283
+ const firstSortDirection = sortDescFirst ? 'desc' : 'asc'
284
+
285
+ const isSorted = column.getIsSorted()
286
+ if (!isSorted) {
287
+ return firstSortDirection
288
+ }
289
+ if (isSorted === firstSortDirection) {
290
+ return isSorted === 'desc' ? 'asc' : 'desc'
291
+ } else {
292
+ return false
293
+ }
294
+ },
295
+
281
296
  getCanSort: () => {
282
297
  return (
283
298
  (column.columnDef.enableSorting ?? true) &&
@@ -112,15 +112,9 @@ export const Visibility: TableFeature = {
112
112
  ): VisibilityRow<TGenerics> => {
113
113
  return {
114
114
  _getAllVisibleCells: memo(
115
- () => [
116
- row
117
- .getAllCells()
118
- .filter(cell => cell.column.getIsVisible())
119
- .map(d => d.id)
120
- .join('_'),
121
- ],
122
- _ => {
123
- return row.getAllCells().filter(cell => cell.column.getIsVisible())
115
+ () => [row.getAllCells(), instance.getState().columnVisibility],
116
+ cells => {
117
+ return cells.filter(cell => cell.column.getIsVisible())
124
118
  },
125
119
  {
126
120
  key:
package/src/index.ts CHANGED
@@ -5,7 +5,6 @@ export * from './core/column'
5
5
  export * from './core/headers'
6
6
  export * from './core/row'
7
7
  export * from './features/ColumnSizing'
8
- export * from './features/ColumnSizing'
9
8
  export * from './features/Expanding'
10
9
  export * from './features/Filters'
11
10
  export * from './features/Grouping'
@@ -15,7 +14,6 @@ export * from './features/Pinning'
15
14
  export * from './features/RowSelection'
16
15
  export * from './features/Sorting'
17
16
  export * from './features/Visibility'
18
- export * from './features/Expanding'
19
17
  export * from './filterFns'
20
18
  export * from './sortingFns'
21
19
  export * from './aggregationFns'
package/src/sortingFns.ts CHANGED
@@ -1,40 +1,69 @@
1
- import { TableGenerics, Row } from './types'
1
+ import { SortingFn } from './features/Sorting'
2
2
 
3
3
  export const reSplitAlphaNumeric = /([0-9]+)/gm
4
4
 
5
- export const sortingFns = {
6
- alphanumeric,
7
- alphanumericCaseSensitive,
8
- text,
9
- textCaseSensitive,
10
- datetime,
11
- basic,
5
+ const alphanumeric: SortingFn<any> = (rowA, rowB, columnId) => {
6
+ return compareAlphanumeric(
7
+ toString(rowA.getValue(columnId)).toLowerCase(),
8
+ toString(rowB.getValue(columnId)).toLowerCase()
9
+ )
12
10
  }
13
11
 
14
- export type BuiltInSortingFn = keyof typeof sortingFns
15
-
16
- function alphanumeric<TGenerics extends TableGenerics>(
17
- rowA: Row<TGenerics>,
18
- rowB: Row<TGenerics>,
19
- columnId: string
20
- ) {
12
+ const alphanumericCaseSensitive: SortingFn<any> = (rowA, rowB, columnId) => {
21
13
  return compareAlphanumeric(
14
+ toString(rowA.getValue(columnId)),
15
+ toString(rowB.getValue(columnId))
16
+ )
17
+ }
18
+
19
+ // The text filter is more basic (less numeric support)
20
+ // but is much faster
21
+ const text: SortingFn<any> = (rowA, rowB, columnId) => {
22
+ return compareBasic(
22
23
  toString(rowA.getValue(columnId)).toLowerCase(),
23
24
  toString(rowB.getValue(columnId)).toLowerCase()
24
25
  )
25
26
  }
26
27
 
27
- function alphanumericCaseSensitive<TGenerics extends TableGenerics>(
28
- rowA: Row<TGenerics>,
29
- rowB: Row<TGenerics>,
30
- columnId: string
31
- ) {
32
- return compareAlphanumeric(
28
+ // The text filter is more basic (less numeric support)
29
+ // but is much faster
30
+ const textCaseSensitive: SortingFn<any> = (rowA, rowB, columnId) => {
31
+ return compareBasic(
33
32
  toString(rowA.getValue(columnId)),
34
33
  toString(rowB.getValue(columnId))
35
34
  )
36
35
  }
37
36
 
37
+ const datetime: SortingFn<any> = (rowA, rowB, columnId) => {
38
+ return compareBasic(
39
+ (rowA.getValue(columnId) as Date).getTime(),
40
+ (rowB.getValue(columnId) as Date).getTime()
41
+ )
42
+ }
43
+
44
+ const basic: SortingFn<any> = (rowA, rowB, columnId) => {
45
+ return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId))
46
+ }
47
+
48
+ // Utils
49
+
50
+ function compareBasic(a: any, b: any) {
51
+ return a === b ? 0 : a > b ? 1 : -1
52
+ }
53
+
54
+ function toString(a: any) {
55
+ if (typeof a === 'number') {
56
+ if (isNaN(a) || a === Infinity || a === -Infinity) {
57
+ return ''
58
+ }
59
+ return String(a)
60
+ }
61
+ if (typeof a === 'string') {
62
+ return a
63
+ }
64
+ return ''
65
+ }
66
+
38
67
  // Mixed sorting is slow, but very inclusive of many edge cases.
39
68
  // It handles numbers, mixed alphanumeric combinations, and even
40
69
  // null, undefined, and Infinity
@@ -82,66 +111,15 @@ function compareAlphanumeric(aStr: string, bStr: string) {
82
111
  return a.length - b.length
83
112
  }
84
113
 
85
- // The text filter is more basic (less numeric support)
86
- // but is much faster
87
- function text<TGenerics extends TableGenerics>(
88
- rowA: Row<TGenerics>,
89
- rowB: Row<TGenerics>,
90
- columnId: string
91
- ) {
92
- return compareBasic(
93
- toString(rowA.getValue(columnId)).toLowerCase(),
94
- toString(rowB.getValue(columnId)).toLowerCase()
95
- )
96
- }
97
-
98
- // The text filter is more basic (less numeric support)
99
- // but is much faster
100
- function textCaseSensitive<TGenerics extends TableGenerics>(
101
- rowA: Row<TGenerics>,
102
- rowB: Row<TGenerics>,
103
- columnId: string
104
- ) {
105
- return compareBasic(
106
- toString(rowA.getValue(columnId)),
107
- toString(rowB.getValue(columnId))
108
- )
109
- }
110
-
111
- function datetime<TGenerics extends TableGenerics>(
112
- rowA: Row<TGenerics>,
113
- rowB: Row<TGenerics>,
114
- columnId: string
115
- ) {
116
- return compareBasic(
117
- (rowA.getValue(columnId) as Date).getTime(),
118
- (rowB.getValue(columnId) as Date).getTime()
119
- )
120
- }
121
-
122
- function basic<TGenerics extends TableGenerics>(
123
- rowA: Row<TGenerics>,
124
- rowB: Row<TGenerics>,
125
- columnId: string
126
- ) {
127
- return compareBasic(rowA.getValue(columnId), rowB.getValue(columnId))
128
- }
129
-
130
- // Utils
114
+ // Exports
131
115
 
132
- function compareBasic(a: any, b: any) {
133
- return a === b ? 0 : a > b ? 1 : -1
116
+ export const sortingFns = {
117
+ alphanumeric,
118
+ alphanumericCaseSensitive,
119
+ text,
120
+ textCaseSensitive,
121
+ datetime,
122
+ basic,
134
123
  }
135
124
 
136
- function toString(a: any) {
137
- if (typeof a === 'number') {
138
- if (isNaN(a) || a === Infinity || a === -Infinity) {
139
- return ''
140
- }
141
- return String(a)
142
- }
143
- if (typeof a === 'string') {
144
- return a
145
- }
146
- return ''
147
- }
125
+ export type BuiltInSortingFn = keyof typeof sortingFns
@@ -21,20 +21,14 @@ export function getCoreRowModel<TGenerics extends TableGenerics>(): (
21
21
  rowsById: {},
22
22
  }
23
23
 
24
- let rows
25
- let row
26
- let originalRow
27
-
28
24
  const accessRows = (
29
25
  originalRows: TGenerics['Row'][],
30
26
  depth = 0,
31
27
  parent?: Row<TGenerics>
32
28
  ): Row<TGenerics>[] => {
33
- rows = []
29
+ const rows = [] as Row<TGenerics>[]
34
30
 
35
31
  for (let i = 0; i < originalRows.length; i++) {
36
- originalRow = originalRows[i]
37
-
38
32
  // This could be an expensive check at scale, so we should move it somewhere else, but where?
39
33
  // if (!id) {
40
34
  // if (process.env.NODE_ENV !== 'production') {
@@ -43,10 +37,10 @@ export function getCoreRowModel<TGenerics extends TableGenerics>(): (
43
37
  // }
44
38
 
45
39
  // Make the row
46
- row = createRow(
40
+ const row = createRow(
47
41
  instance,
48
- instance._getRowId(originalRow, i, parent),
49
- originalRow,
42
+ instance._getRowId(originalRows[i], i, parent),
43
+ originalRows[i],
50
44
  i,
51
45
  depth
52
46
  )
@@ -60,7 +54,10 @@ export function getCoreRowModel<TGenerics extends TableGenerics>(): (
60
54
 
61
55
  // Get the original subrows
62
56
  if (instance.options.getSubRows) {
63
- row.originalSubRows = instance.options.getSubRows(originalRow, i)
57
+ row.originalSubRows = instance.options.getSubRows(
58
+ originalRows[i],
59
+ i
60
+ )
64
61
 
65
62
  // Then recursively access them
66
63
  if (row.originalSubRows?.length) {