rcbyr / keen-slider

The HTML touch slider carousel with the most native feeling you will get.
https://keen-slider.io/
MIT License
4.67k stars 214 forks source link

moveToIdx does not work in certain conditions #415

Open Reg93 opened 6 months ago

Reg93 commented 6 months ago

Hello! I have component of match where users can change scores of their games. Keen-slider works good! But i have one issue.

When i add new set of match or remove one of existing sliders has to move to indexes of last set. But it does not happen.

Func of moving slides:

const changeSlidesInSlider = useCallback((sets, index, tiebreak) => {
        if (sets.length > 0) {
            const lastSliderIndex = sliderLenght.length - 1
            const activeSet = getActiveSet(sets, index)
            const { score1, score2, tie_break_score1, tie_break_score2 } = activeSet

            let leftCurrentSlide = tiebreak ? tie_break_score1 : score1
            let rightCurrentSlide = tiebreak ? tie_break_score2 : score2

            if (leftCurrentSlide > lastSliderIndex) {
                leftCurrentSlide = 10
            } else if (!leftCurrentSlide && tiebreak && tier === 'tier2') {
                leftCurrentSlide = 7
            } else if (!leftCurrentSlide && tiebreak && tier === 'tier1') {
                leftCurrentSlide = 0
            }

            if (rightCurrentSlide > lastSliderIndex) {
                rightCurrentSlide = 10
            } else if (!rightCurrentSlide && tiebreak && tier === 'tier2') {
                rightCurrentSlide = 7
            } else if (!rightCurrentSlide && tiebreak && tier === 'tier1') {
                rightCurrentSlide = 0
            }

            if (!leftCurrentSlide && !rightCurrentSlide) {
                instanceRef1.current.moveToIdx(0)
                instanceRef2.current.moveToIdx(0)
            } else {
                instanceRef1.current.moveToIdx(leftCurrentSlide)
                instanceRef2.current.moveToIdx(rightCurrentSlide)
            }
        } else {
            instanceRef1.current.moveToIdx(0)
            instanceRef2.current.moveToIdx(0)
        }
    }, [sliderLenght, tier, instanceRef1, instanceRef2])

func where i add new set:

    const handleAddSet = useCallback(() => {
        const newSet = tier === 'tier1' ? newSetT1 : newSetT2
        const addedSet = {
            ...newSet,
            'order_number': matchState.sets.length + 1,
        }

        const sets = [...matchState.sets, addedSet]
        setMatchState(prev => { return { ...prev, sets } })

        const lastSetIndex = sets.length - 1
        setActiveSetIndex(lastSetIndex)

        changeSlidesInSlider(sets, lastSetIndex, tiebreak)
    }, [matchState.sets, tier, changeSlidesInSlider, tiebreak])

instances of sliders are same, for first one:

    const [sliderRef1, instanceRef1] = useKeenSlider(
        {
            animationEnded(slider) {
                setIndexOfSlider1(slider.track.details.rel)
            },
            created() {
                setLoaded1(true)
            },
            dragStarted() {
                setTouched(1)
            },
            initial: getInitialSlide(matchState, 1),
            loop: true,
            vertical: true,
            slides: {
                origin: 'center',
                spacing: 0,
                perView: 3
            },
            centeredSlides: true,
            mode: 'free-snap',
        },
    )

elements:

{loaded1 && instanceRef1.current && (
    <div className="keen-slider__buttons">
        <button
            onClick={(e) => {
                e.stopPropagation() || instanceRef1.current?.prev()
                setTouched(1)
            }}
            className="slider__button"
        >
            <Plus className="slider__button-icon" />
        </button>

        <button
            onClick={(e) => {
                e.stopPropagation() || instanceRef1.current?.next()
                setTouched(1)
            }}
            className="slider__button"
        >
            <Minus className="slider__button-icon" />
        </button>
    </div>
)}

<div className="sliders_container">
    <div ref={sliderRef1} className="keen-slider slider">
        {sliderLenght.map((item, index) => (
            <div key={index} className="keen-slider__slide slider-slide">
                {item}
            </div>
        ))}
</div>

Also i noticed that if i remove line setMatchState(prev => { return { ...prev, sets } }), sliders move fine. Or i have wrap in setTimeouts moveToIdx funcs in changeSlidesInSlider.

How can i fix it?

Reg93 commented 6 months ago

Sorry for the view of code. No idea why part of that is not marked as code

BenceSzalai commented 5 months ago

Multiline code should be wrapped in tripple backticks: ``` /* multiline code here */ ``` That way they will be shown fine. You can also add file extension for highlighting, like: ```js /* multiline code here */ ``` or ```html /* multiline code here */ ```

You can go back and edit your comment, so i'll become readable, because in its current state it's kind of hard to comprehend.

Reg93 commented 4 months ago

Multiline code should be wrapped in tripple backticks: ``` /* multiline code here */ ``` That way they will be shown fine. You can also add file extension for highlighting, like: ```js /* multiline code here */ ``` or ```html /* multiline code here */ ```

You can go back and edit your comment, so i'll become readable, because in its current state it's kind of hard to comprehend.

Thank you for answer. Corrected it