Skip to content

Commit b7b0d5a

Browse files
committedFeb 5, 2025
fix: add experimental_subscribeToEvents
1 parent 228ff42 commit b7b0d5a

File tree

9 files changed

+77
-41
lines changed

9 files changed

+77
-41
lines changed
 

‎examples/react/table/src/main.tsx

+10-8
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,16 @@ function ReactTableVirtualized() {
5252
header: 'Profile Progress',
5353
size: 80,
5454
},
55-
{
56-
accessorKey: 'createdAt',
57-
header: 'Created At',
58-
cell: (info) => info.getValue<Date>().toLocaleString(),
59-
},
55+
// {
56+
// accessorKey: 'createdAt',
57+
// header: 'Created At',
58+
// cell: (info) => info.getValue<Date>().toLocaleString(),
59+
// },
6060
],
6161
[],
6262
)
6363

64-
const [data, setData] = React.useState(() => makeData(50_000))
64+
const [data] = React.useState(() => makeData(50_000))
6565

6666
const table = useReactTable({
6767
data,
@@ -82,10 +82,12 @@ function ReactTableVirtualized() {
8282
const virtualizer = useVirtualizer({
8383
count: rows.length,
8484
getScrollElement: () => parentRef.current,
85-
estimateSize: () => 34,
85+
estimateSize: () => 200,
8686
overscan: 20,
8787
})
8888

89+
console.log(virtualizer.isScrolling)
90+
8991
return (
9092
<div ref={parentRef} className="container">
9193
<div style={{ height: `${virtualizer.getTotalSize()}px` }}>
@@ -154,7 +156,7 @@ function ReactTableVirtualized() {
154156
</tbody>
155157
</table>
156158
</div>
157-
</div>
159+
// </div>
158160
)
159161
}
160162

‎examples/react/table/src/makeData.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ export type Person = {
88
visits: number
99
progress: number
1010
status: 'relationship' | 'complicated' | 'single'
11-
createdAt: Date
11+
// createdAt: Date
1212
}
1313

1414
const range = (len: number) => {
15-
const arr: number[] = []
15+
const arr: Array<number> = []
1616
for (let i = 0; i < len; i++) {
1717
arr.push(i)
1818
}
@@ -22,23 +22,23 @@ const range = (len: number) => {
2222
const newPerson = (index: number): Person => {
2323
return {
2424
id: index + 1,
25-
firstName: faker.name.firstName(),
26-
lastName: faker.name.lastName(),
25+
firstName: faker.person.firstName(),
26+
lastName: faker.person.lastName(),
2727
age: faker.number.int(40),
2828
visits: faker.number.int(1000),
2929
progress: faker.number.int(100),
30-
createdAt: faker.datatype.datetime({ max: new Date().getTime() }),
30+
// createdAt: faker.datatype.datetime({ max: new Date().getTime() }),
3131
status: faker.helpers.shuffle<Person['status']>([
3232
'relationship',
3333
'complicated',
3434
'single',
35-
])[0]!,
35+
])[0],
3636
}
3737
}
3838

39-
export function makeData(...lens: number[]) {
40-
const makeDataLevel = (depth = 0): Person[] => {
41-
const len = lens[depth]!
39+
export function makeData(...lens: Array<number>) {
40+
const makeDataLevel = (depth = 0): Array<Person> => {
41+
const len = lens[depth]
4242
return range(len).map((d): Person => {
4343
return {
4444
...newPerson(d),

‎packages/angular-virtual/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ function createVirtualizerBase<
4747
virtualizerSignal.set(virtualizer)
4848
virtualizer.setOptions({
4949
..._options,
50-
onChange: (instance, sync) => {
50+
onChange: (instance, sync, source) => {
5151
// update virtualizerSignal so that dependent computeds recompute.
5252
virtualizerSignal.set(instance)
53-
_options.onChange?.(instance, sync)
53+
_options.onChange?.(instance, sync, source)
5454
},
5555
})
5656
// update virtualizerSignal so that dependent computeds recompute.

‎packages/lit-virtual/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ class VirtualizerControllerBase<
2929

3030
const resolvedOptions: VirtualizerOptions<TScrollElement, TItemElement> = {
3131
...options,
32-
onChange: (instance, sync) => {
32+
onChange: (instance, sync, source) => {
3333
this.host.updateComplete.then(() => this.host.requestUpdate())
34-
options.onChange?.(instance, sync)
34+
options.onChange?.(instance, sync, source)
3535
},
3636
}
3737
this.virtualizer = new Virtualizer(resolvedOptions)

‎packages/react-virtual/src/index.tsx

+20-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import {
99
observeWindowRect,
1010
windowScroll,
1111
} from '@tanstack/virtual-core'
12-
import type { PartialKeys, VirtualizerOptions } from '@tanstack/virtual-core'
12+
import type {
13+
NotifySource,
14+
PartialKeys,
15+
VirtualizerOptions,
16+
} from '@tanstack/virtual-core'
1317

1418
export * from '@tanstack/virtual-core'
1519

@@ -20,19 +24,31 @@ function useVirtualizerBase<
2024
TScrollElement extends Element | Window,
2125
TItemElement extends Element,
2226
>(
23-
options: VirtualizerOptions<TScrollElement, TItemElement>,
27+
options: VirtualizerOptions<TScrollElement, TItemElement> & {
28+
_experimental_subscribeToEvents?: boolean | Array<NotifySource>
29+
},
2430
): Virtualizer<TScrollElement, TItemElement> {
2531
const rerender = React.useReducer(() => ({}), {})[1]
2632

2733
const resolvedOptions: VirtualizerOptions<TScrollElement, TItemElement> = {
2834
...options,
29-
onChange: (instance, sync) => {
35+
onChange: (instance, sync, source) => {
36+
const subscribeToEvents = options._experimental_subscribeToEvents ?? true
37+
38+
if (
39+
subscribeToEvents === false ||
40+
(Array.isArray(subscribeToEvents) &&
41+
!subscribeToEvents.includes(source))
42+
) {
43+
return
44+
}
45+
3046
if (sync) {
3147
flushSync(rerender)
3248
} else {
3349
rerender()
3450
}
35-
options.onChange?.(instance, sync)
51+
options.onChange?.(instance, sync, source)
3652
},
3753
}
3854

‎packages/solid-virtual/src/index.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import {
1616
onMount,
1717
} from 'solid-js'
1818
import { createStore, reconcile } from 'solid-js/store'
19-
import type { PartialKeys, VirtualizerOptions } from '@tanstack/virtual-core'
19+
import type {
20+
NotifySource,
21+
PartialKeys,
22+
VirtualizerOptions,
23+
} from '@tanstack/virtual-core'
2024

2125
export * from '@tanstack/virtual-core'
2226

@@ -69,6 +73,7 @@ function createVirtualizerBase<
6973
onChange: (
7074
instance: Virtualizer<TScrollElement, TItemElement>,
7175
sync: boolean,
76+
source: NotifySource,
7277
) => {
7378
instance._willUpdate()
7479
setVirtualItems(
@@ -77,7 +82,7 @@ function createVirtualizerBase<
7782
}),
7883
)
7984
setTotalSize(instance.getTotalSize())
80-
options.onChange?.(instance, sync)
85+
options.onChange?.(instance, sync, source)
8186
},
8287
}),
8388
)

‎packages/svelte-virtual/src/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import {
88
windowScroll,
99
} from '@tanstack/virtual-core'
1010
import { derived, writable } from 'svelte/store'
11-
import type { PartialKeys, VirtualizerOptions } from '@tanstack/virtual-core'
11+
import type {
12+
NotifySource,
13+
PartialKeys,
14+
VirtualizerOptions,
15+
} from '@tanstack/virtual-core'
1216
import type { Readable, Writable } from 'svelte/store'
1317

1418
export * from '@tanstack/virtual-core'
@@ -47,9 +51,10 @@ function createVirtualizerBase<
4751
onChange: (
4852
instance: Virtualizer<TScrollElement, TItemElement>,
4953
sync: boolean,
54+
source: NotifySource,
5055
) => {
5156
virtualizerWritable.set(instance)
52-
resolvedOptions.onChange?.(instance, sync)
57+
resolvedOptions.onChange?.(instance, sync, source)
5358
},
5459
})
5560
virtualizer._willUpdate()

‎packages/virtual-core/src/index.ts

+18-10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ export interface Rect {
4242
height: number
4343
}
4444

45+
export type NotifySource =
46+
| 'noScrollElement'
47+
| 'observeElementRect'
48+
| 'observeElementOffset'
49+
| 'measureItem'
50+
| 'resizeItem'
51+
| 'measure'
52+
4553
//
4654

4755
export const defaultKeyExtractor = (index: number) => index
@@ -303,6 +311,7 @@ export interface VirtualizerOptions<
303311
onChange?: (
304312
instance: Virtualizer<TScrollElement, TItemElement>,
305313
sync: boolean,
314+
source: NotifySource,
306315
) => void
307316
measureElement?: (
308317
element: TItemElement,
@@ -421,8 +430,8 @@ export class Virtualizer<
421430
}
422431
}
423432

424-
private notify = (sync: boolean) => {
425-
this.options.onChange?.(this, sync)
433+
private notify = (sync: boolean, source: NotifySource) => {
434+
this.options.onChange?.(this, sync, source)
426435
}
427436

428437
private maybeNotify = memo(
@@ -435,8 +444,8 @@ export class Virtualizer<
435444
this.range ? this.range.endIndex : null,
436445
]
437446
},
438-
(isScrolling) => {
439-
this.notify(isScrolling)
447+
(isScrolling) => (source: NotifySource) => {
448+
this.notify(isScrolling, source)
440449
},
441450
{
442451
key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
@@ -472,7 +481,7 @@ export class Virtualizer<
472481
this.cleanup()
473482

474483
if (!scrollElement) {
475-
this.maybeNotify()
484+
this.maybeNotify()('noScrollElement')
476485
return
477486
}
478487

@@ -496,7 +505,7 @@ export class Virtualizer<
496505
this.unsubs.push(
497506
this.options.observeElementRect(this, (rect) => {
498507
this.scrollRect = rect
499-
this.maybeNotify()
508+
this.maybeNotify()('observeElementRect')
500509
}),
501510
)
502511

@@ -510,8 +519,7 @@ export class Virtualizer<
510519
: null
511520
this.scrollOffset = offset
512521
this.isScrolling = isScrolling
513-
514-
this.maybeNotify()
522+
this.maybeNotify()('observeElementOffset')
515523
}),
516524
)
517525
}
@@ -795,7 +803,7 @@ export class Virtualizer<
795803
this.pendingMeasuredCacheIndexes.push(item.index)
796804
this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size))
797805

798-
this.notify(false)
806+
this.notify(false, 'resizeItem')
799807
}
800808
}
801809

@@ -1048,7 +1056,7 @@ export class Virtualizer<
10481056

10491057
measure = () => {
10501058
this.itemSizeCache = new Map()
1051-
this.notify(false)
1059+
this.notify(false, 'measure')
10521060
}
10531061
}
10541062

‎packages/vue-virtual/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ function useVirtualizerBase<
5050
(options) => {
5151
virtualizer.setOptions({
5252
...options,
53-
onChange: (instance, sync) => {
53+
onChange: (instance, sync, source) => {
5454
triggerRef(state)
55-
options.onChange?.(instance, sync)
55+
options.onChange?.(instance, sync, source)
5656
},
5757
})
5858

0 commit comments

Comments
 (0)
Please sign in to comment.