davidjerleke / embla-carousel

A lightweight carousel library with fluid motion and great swipe precision.
https://www.embla-carousel.com
MIT License
5.8k stars 175 forks source link

How to create a horizontal scroll slides with each slide contains several sub-slides that can be scrolled vertically? #296

Closed xnslx closed 2 years ago

xnslx commented 2 years ago

I came across Zara's website the other day, https://www.zara.com/us/, it is very interesting to see a horizontal carousel that for each container/slide that items in it can be scrolled vertically? I am trying to mimic the same carousel. But I am quite getting stuck.🤯 Here is the codesandbox, https://codesandbox.io/s/awesome-babbage-xf2gyh

davidjerleke commented 2 years ago

Hi @xnslx,

Here’s a CodeSandbox with nested carousels. I haven’t tried exactly what you want to achieve, but it should be doable using a similar approach.

Remember to set the axis option to y on your nested carousels and change their CSS to stack the slides vertically. Here’s one way to stack them vertically.

Kindly, David

xnslx commented 2 years ago

@davidjerleke Wow. Thank you for such a quick reply on weekend! I will take a look! Thank you! Have a nice weekend!! 🌞

xnslx commented 2 years ago

@davidjerleke Hey David, it is working like a charm! Thank you for helping out. I get exactly what i am looking for! Thank you! Have a wonderful week!

davidjerleke commented 2 years ago

@xnslx I’m happy you got it sorted. Cheers and enjoy!

Best, David

xnslx commented 2 years ago

Hey David, I am trying to import the related code to my application.

import React, { useState, useEffect, useCallback } from 'react';
import { PrevButton, NextButton } from "../EmblaCarouselButton";
import useEmblaCarousel from "embla-carousel-react";
import EmblaCarousel from 'embla-carousel';

import { useNestedEmblaCarousel } from '../useNestedEmblaCarousel'
import NestedCarousel from '../NestedCarousel';

const Carousels = (props) => {
    console.log('carousels', props)
    const { carousels, _key, _type } = props

    const [viewportRef, embla] = useEmblaCarousel();
    const setLockParentScroll = useNestedEmblaCarousel(embla);
    const [prevBtnEnabled, setPrevBtnEnabled] = useState(false);
    const [nextBtnEnabled, setNextBtnEnabled] = useState(false);
    const scrollPrev = useCallback(() => embla && embla.scrollPrev(), [embla]);
    const scrollNext = useCallback(() => embla && embla.scrollNext(), [embla]);
    const onSelect = useCallback(() => {
        if (!embla) return;
        setPrevBtnEnabled(embla.canScrollPrev());
        setNextBtnEnabled(embla.canScrollNext());
    }, [embla]);

    useEffect(() => {
        if (!embla) return;
        embla.on("select", onSelect);
        onSelect();
    }, [embla, onSelect]);

    return (
        <>
        <div className="embla">
            <div className="embla__viewport" ref={viewportRef}>
            <div className="embla__container">
                {carousels.map((s, index) => {
                console.log('s',s)
                return Object.values(s).map((j, index) => {
                    return (
                    <div className="embla__slide" key={index}>
                        <div>
                        {Object.keys(s).map((i, index) => {
                            return <span>{i}</span>;
                        })}
                        </div>
                        <div>
                        <NestedCarousel
                            slides={j}
                            setLockParentScroll={setLockParentScroll}
                        />
                        </div>
                    </div>
                    );
                });
                })}
            </div>
            </div>
            <PrevButton onClick={scrollPrev} enabled={prevBtnEnabled} />
            <NextButton onClick={scrollNext} enabled={nextBtnEnabled} />
        </div>
        </>
    );
}

export default Carousels

I always get error that

Screen Shot 2022-03-29 at 4 50 39 PM

Do you have any idea how to fix it? it seems fine when it is in the codesandbox.

Many thanks! Have a nice evening!

Xian

davidjerleke commented 2 years ago

Hi @xnslx,

It's hard to know what's happening without your full setup and just seeing fragments of code. What do you have in your package.json file? I found one thing when skimming the code. Remove the following import:

import EmblaCarousel from 'embla-carousel'; 

And remember to remove embla-carousel from your package.json, because embla-carousel-react already installs embla-carousel as a dependency.

import React, { useState, useEffect, useCallback } from 'react';
import { PrevButton, NextButton } from "../EmblaCarouselButton";
import useEmblaCarousel from "embla-carousel-react";
import EmblaCarousel from 'embla-carousel'; // You shouldn't import this because you already have useEmblaCarousel

🚨 Note! I've just updated the nested carousel CodeSandbox to work with the latest version of Embla.

Best, David

xnslx commented 2 years ago

Hey @davidjerleke I reproduce the bug in the codesandbox When you swipe the slide up, the bug will occur. It never happen when I am importing as embla-carousel/react and when I update and import it as embla-carousel-react then the application becomes very buggy, not matter in the codesandbox or in my own application. Many thanks. You are so helpful! Have a wonderful day!!

Xian

davidjerleke commented 2 years ago

Hi @xnslx,

Please read my comment again 🙂. I’ve updated the nested carousel CodeSandbox to work with the latest version of Embla, which means that I've changed some code in it (the red emoji light in the comment 🚨). You should update your nested carousel code with the code changes I made in the CodeSandbox.

xnslx commented 2 years ago

@davidjerleke Hey David, it is working like a charm! Many many thanks! Have a nice weekend!

Xian