Open tilap opened 1 month ago
I have a development on this, but I can't add it right now because I don't have the time, but I will do it as soon as possible.
I forked locally and succeed in having 10.000 items by slicing the data
in the Swiper component before rendering, and adjusting the SwipableCard index.
It works like a charm as long as I dont have to call programmatically the swipeLeft/swipeRight, nor call the swipeBack.
@Skipperlla If you have any recommandations or even a plan to finalize it, I'll be happy to create the PR and save you time.
I don't have a plan for the moment, since I'm very busy, I can usually update this library every 2 or 3 months in bulk, if you open the feature you want as a pr, I can spare time to read and merge the pr. @tilap
@Skipperlla @tilap I made a fork of the library which only renders 2 next and 2 previous cards. I'll make a PR when I have time. Using this method we can also implement loop features (#37)
@Skipperlla @tilap I made a fork of the library which only renders 2 next and 2 previous cards. I'll make a PR when I have time. Using this method we can also implement loop features (#37)
Any updates? Will appreciate looking at your pr
this weekend I will look at this and all other issues and pr's and close them, I apologize to all of you one by one for keeping you waiting so long @tilap @vanenshi @NeroN7F @umangloria
@Skipperlla @tilap I made a fork of the library which only renders 2 next and 2 previous cards. I'll make a PR when I have time. Using this method we can also implement loop features (#37)
Any updates? Will appreciate looking at your pr
Very sorry @NeroN7F, I am a little busy right now, I am just going to share the code here.
import { fixedForwardRef } from '@/utils/ref';
import React, {
RefObject,
useEffect,
useImperativeHandle,
useMemo,
type ForwardedRef,
} from 'react';
import {
SwiperCardOptions,
SwiperCardRefType,
SwiperOptions,
SwiperRefType,
} from '.';
import { SwipeableCard } from './SwiperCard';
import { useSwipeControls } from './hooks/useSwipeControls';
const renderSwipeable = <T,>(
item: T | undefined,
index: number,
renderCard: (item: T, index: number) => JSX.Element,
keyExtractor: ((item: T) => string) | undefined,
ref: RefObject<SwiperCardRefType> | undefined,
additionalProps: Omit<SwiperCardOptions, 'index'>,
) => {
if (!item) return null;
const key = keyExtractor ? keyExtractor(item) : index;
return (
<SwipeableCard key={key} ref={ref} index={index} {...additionalProps}>
{renderCard(item, index)}
</SwipeableCard>
);
};
const SwiperComponent = <T,>(
{
data,
onSwipedAll,
onIndexChange,
renderCard,
keyExtractor,
OverlayLabelBottom,
OverlayLabelLeft,
OverlayLabelRight,
OverlayLabelTop,
cardStyle,
disableBottomSwipe,
disableLeftSwipe,
disableRightSwipe,
disableTopSwipe,
inputOverlayLabelBottomOpacityRange,
inputOverlayLabelLeftOpacityRange,
inputOverlayLabelRightOpacityRange,
inputOverlayLabelTopOpacityRange,
outputOverlayLabelBottomOpacityRange,
onSwipeActive,
onSwipeBottom,
onSwipeEnd,
onSwipeLeft,
onSwipeRight,
onSwipeStart,
onSwipeTop,
outputOverlayLabelLeftOpacityRange,
outputOverlayLabelRightOpacityRange,
outputOverlayLabelTopOpacityRange,
rotateInputRange,
rotateOutputRange,
translateXRange,
translateYRange,
}: SwiperOptions<T>,
ref: ForwardedRef<SwiperRefType>,
) => {
const {
activeIndex,
setActiveIndex,
refs,
swipeRight,
swipeLeft,
swipeBack,
swipeTop,
swipeBottom,
jumpToCard,
} = useSwipeControls(data);
useImperativeHandle(
ref,
() => ({
swipeLeft,
swipeRight,
swipeBack,
swipeTop,
swipeBottom,
jumpToCard,
}),
[swipeLeft, swipeRight, swipeBack, swipeTop, swipeBottom, jumpToCard],
);
useEffect(() => {
if (activeIndex >= data.length) onSwipedAll?.();
}, [activeIndex, data.length, onIndexChange, onSwipedAll]);
useEffect(() => {
onIndexChange?.(activeIndex);
}, [activeIndex, onIndexChange]);
const cards = useMemo(() => {
const cardRenderingProps = {
activeIndex,
setActiveIndex,
OverlayLabelBottom,
OverlayLabelLeft,
OverlayLabelRight,
OverlayLabelTop,
cardStyle,
disableBottomSwipe,
disableLeftSwipe,
disableRightSwipe,
disableTopSwipe,
inputOverlayLabelBottomOpacityRange,
inputOverlayLabelLeftOpacityRange,
inputOverlayLabelRightOpacityRange,
inputOverlayLabelTopOpacityRange,
outputOverlayLabelBottomOpacityRange,
onSwipeActive,
onSwipeBottom,
onSwipeEnd,
onSwipeLeft,
onSwipeRight,
onSwipeStart,
onSwipeTop,
outputOverlayLabelLeftOpacityRange,
outputOverlayLabelRightOpacityRange,
outputOverlayLabelTopOpacityRange,
rotateInputRange,
rotateOutputRange,
translateXRange,
translateYRange,
} satisfies Omit<SwiperCardOptions, 'index'>;
return [
renderSwipeable(
data[activeIndex - 1],
activeIndex - 1,
renderCard,
keyExtractor,
refs[activeIndex - 1],
cardRenderingProps,
),
renderSwipeable(
data[activeIndex],
activeIndex,
renderCard,
keyExtractor,
refs[activeIndex],
cardRenderingProps,
),
renderSwipeable(
data[activeIndex + 1],
activeIndex + 1,
renderCard,
keyExtractor,
refs[activeIndex + 1],
cardRenderingProps,
),
renderSwipeable(
data[activeIndex + 2],
activeIndex + 2,
renderCard,
keyExtractor,
refs[activeIndex + 2],
cardRenderingProps,
),
].filter(Boolean);
}, [
activeIndex,
setActiveIndex,
OverlayLabelBottom,
OverlayLabelLeft,
OverlayLabelRight,
OverlayLabelTop,
cardStyle,
disableBottomSwipe,
disableLeftSwipe,
disableRightSwipe,
disableTopSwipe,
inputOverlayLabelBottomOpacityRange,
inputOverlayLabelLeftOpacityRange,
inputOverlayLabelRightOpacityRange,
inputOverlayLabelTopOpacityRange,
outputOverlayLabelBottomOpacityRange,
onSwipeActive,
onSwipeBottom,
onSwipeEnd,
onSwipeLeft,
onSwipeRight,
onSwipeStart,
onSwipeTop,
outputOverlayLabelLeftOpacityRange,
outputOverlayLabelRightOpacityRange,
outputOverlayLabelTopOpacityRange,
rotateInputRange,
rotateOutputRange,
translateXRange,
translateYRange,
data,
renderCard,
keyExtractor,
refs,
]);
return cards;
};
export const Swiper = fixedForwardRef(SwiperComponent);
it's very basic, I am sure @Skipperlla can make a better version of it 😁
a very important note: I had to change the activeIndex
from shared value to a state, since in this version, sometimes the change of the activeIndex is not cause render and causes bad animation
When mounting , it process
renderCard
over all the item we provide indata
.We quickly encounter performance issues (and even app crashs) if we have a lot of data (a lot = 100 or above).
It would be great to have an option to avoid rendering cards depending on the current active index for example.