Skip to content

Commit 83e6e6e

Browse files
committed
fix: 💩 Improved reactivity of the virtualizer and options
The virtualizer will now be re created when args changes
1 parent 329f6e3 commit 83e6e6e

File tree

1 file changed

+78
-71
lines changed

1 file changed

+78
-71
lines changed

src/createVirtualizedList.ts

Lines changed: 78 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -118,75 +118,82 @@ export function createVirtualizedList<T extends Primitive | ObjectWithKey>(args:
118118
return undefined;
119119
});
120120

121-
const options: VirtualizerOptions<Element, Element> = mergeProps({
122-
get count() {
123-
return count()
124-
},
125-
getScrollElement,
126-
estimateSize: estimateSize(),
127-
overscan: args?.overscan ?? 5,
128-
horizontal: horizontal(),
129-
paddingStart: args?.paddingStart ?? 0,
130-
paddingEnd: args?.paddingEnd ?? 10,
131-
scrollPaddingStart: args?.scrollPaddingStart ?? 0,
132-
scrollPaddingEnd: args?.scrollPaddingEnd ?? 0,
133-
initialRect: args?.initialRect ?? initialRect(),
134-
initialOffset: args?.initialOffset ?? 0,
135-
onChange: args.onChange,
136-
scrollToFn: args?.scrollToFn ?? ((offset, { behavior }) => {
137-
const scrollElement = getScrollElement();
138-
if (scrollElement) {
139-
scrollElement.scrollTo({
140-
[horizontal() ? 'left' : 'top']: offset,
141-
behavior,
121+
const reactiveArgs = createMemo(() => args)
122+
123+
const options: () => VirtualizerOptions<Element, Element> = createMemo(() => {
124+
const currentArgs = reactiveArgs()
125+
126+
return mergeProps({
127+
get count() {
128+
return count()
129+
},
130+
getScrollElement,
131+
estimateSize: estimateSize(),
132+
overscan: currentArgs?.overscan ?? 5,
133+
horizontal: horizontal(),
134+
paddingStart: currentArgs?.paddingStart ?? 0,
135+
paddingEnd: currentArgs?.paddingEnd ?? 10,
136+
scrollPaddingStart: currentArgs?.scrollPaddingStart ?? 0,
137+
scrollPaddingEnd: currentArgs?.scrollPaddingEnd ?? 0,
138+
initialRect: currentArgs?.initialRect ?? initialRect(),
139+
initialOffset: currentArgs?.initialOffset ?? 0,
140+
onChange: currentArgs.onChange,
141+
scrollToFn: currentArgs?.scrollToFn ?? ((offset, { behavior }) => {
142+
const scrollElement = getScrollElement();
143+
if (scrollElement) {
144+
scrollElement.scrollTo({
145+
[horizontal() ? 'left' : 'top']: offset,
146+
behavior,
147+
});
148+
}
149+
}),
150+
observeElementRect: currentArgs?.observeElementRect ?? ((instance, cb) => {
151+
const scrollElement = getScrollElement();
152+
if (!scrollElement) return;
153+
154+
const resizeObserver = new ResizeObserver(() => {
155+
const rect = scrollElement.getBoundingClientRect();
156+
cb(rect);
142157
});
143-
}
144-
}),
145-
observeElementRect: args?.observeElementRect ?? ((instance, cb) => {
146-
const scrollElement = getScrollElement();
147-
if (!scrollElement) return;
148-
149-
const resizeObserver = new ResizeObserver(() => {
150-
const rect = scrollElement.getBoundingClientRect();
151-
cb(rect);
152-
});
153-
154-
resizeObserver.observe(scrollElement);
155-
156-
return () => resizeObserver.disconnect();
157-
}),
158-
observeElementOffset: args?.observeElementOffset ?? ((instance, cb) => {
159-
const scrollElement = getScrollElement();
160-
if (!scrollElement) return;
161-
162-
const handleScroll = () => {
163-
const offset = horizontal()
164-
? scrollElement.scrollLeft
165-
: scrollElement.scrollTop;
166-
cb(offset, true);
167-
};
168-
169-
scrollElement.addEventListener('scroll', handleScroll, {
170-
passive: true,
171-
});
172-
173-
return () => scrollElement.removeEventListener('scroll', handleScroll);
174-
}),
175-
debug: args?.debug,
176-
measureElement: measureElement(),
177-
getItemKey: (index: number) => determineKey(data()[index], index),
178-
rangeExtractor: args?.rangeExtractor,
179-
scrollMargin: args?.scrollMargin,
180-
gap: args?.gap,
181-
indexAttribute: args?.indexAttribute,
182-
initialMeasurementsCache: args?.initialMeasurementsCache,
183-
lanes: args?.lanes,
184-
isScrollingResetDelay: args?.isScrollingResetDelay,
185-
enabled: args?.enabled,
186-
isRtl: args?.isRtl,
187-
}, args)
158+
159+
resizeObserver.observe(scrollElement);
160+
161+
return () => resizeObserver.disconnect();
162+
}),
163+
observeElementOffset: currentArgs?.observeElementOffset ?? ((instance, cb) => {
164+
const scrollElement = getScrollElement();
165+
if (!scrollElement) return;
166+
167+
const handleScroll = () => {
168+
const offset = horizontal()
169+
? scrollElement.scrollLeft
170+
: scrollElement.scrollTop;
171+
cb(offset, true);
172+
};
173+
174+
scrollElement.addEventListener('scroll', handleScroll, {
175+
passive: true,
176+
});
177+
178+
return () => scrollElement.removeEventListener('scroll', handleScroll);
179+
}),
180+
debug: currentArgs?.debug,
181+
measureElement: measureElement(),
182+
getItemKey: (index: number) => determineKey(data()[index], index),
183+
rangeExtractor: currentArgs?.rangeExtractor,
184+
scrollMargin: currentArgs?.scrollMargin,
185+
gap: currentArgs?.gap,
186+
indexAttribute: currentArgs?.indexAttribute,
187+
initialMeasurementsCache: currentArgs?.initialMeasurementsCache,
188+
lanes: currentArgs?.lanes,
189+
isScrollingResetDelay: currentArgs?.isScrollingResetDelay,
190+
enabled: currentArgs?.enabled,
191+
isRtl: currentArgs?.isRtl,
192+
}, currentArgs)
193+
}
194+
)
188195

189-
const virtualizer = createVirtualizer(options);
196+
const virtualizer = createMemo(() => createVirtualizer(options()))
190197

191198
const rootProps = createMemo(() => {
192199
const defaultStyle = {
@@ -211,8 +218,8 @@ export function createVirtualizedList<T extends Primitive | ObjectWithKey>(args:
211218
const containerId = generateId('list');
212219
const defaultStyle = {
213220
position: 'relative',
214-
height: horizontal() ? '100%' : `${virtualizer.getTotalSize()}px`,
215-
width: horizontal() ? `${virtualizer.getTotalSize()}px` : '100%',
221+
height: horizontal() ? '100%' : `${virtualizer().getTotalSize()}px`,
222+
width: horizontal() ? `${virtualizer().getTotalSize()}px` : '100%',
216223
};
217224

218225
return mergeProps({
@@ -239,7 +246,7 @@ export function createVirtualizedList<T extends Primitive | ObjectWithKey>(args:
239246
'data-index': virtualItem.index,
240247
key,
241248
ref: mergeRefs((el: Element) => {
242-
if (el) virtualizer.measureElement(el);
249+
if (el) virtualizer().measureElement(el);
243250
}, args.itemProps?.ref),
244251
}, args?.itemProps ?? {});
245252

@@ -273,7 +280,7 @@ export function createVirtualizedList<T extends Primitive | ObjectWithKey>(args:
273280
},
274281
items: itemWrapper,
275282
get item() {
276-
return virtualizer.getVirtualItems()
283+
return virtualizer().getVirtualItems()
277284
}
278285
};
279286
}

0 commit comments

Comments
 (0)