themesberg / flowbite-react

Official React components built for Flowbite and Tailwind CSS
https://flowbite-react.com
MIT License
1.89k stars 421 forks source link

Nextjs server components with carousel as child client component does not work on first render #956

Open rubenstolk opened 1 year ago

rubenstolk commented 1 year ago

Steps to reproduce

  1. Create a simple nextjs app having a main page (server component) with a child element that is "use client" and renders a simple Carousel
  2. Try to navigate the carousel, everything seems to work except the scrolling of the items, so visibly it looks like the carousel doesn't work at all

Current behavior

No scroll of the carousel visible at first render, when browsing to another page and coming back to the page with the carousel, it suddenly works fine.

Expected behavior

Should scroll

pochka15 commented 1 year ago

I could reproduce it in a cloned repository by opening the http://localhost:3000/docs/components/carousel

I've also tried to find there the bug is and looks like it's in this line of code:

  const navigateTo = useCallback(
    (item: number) => () => {
      if (!items) return;
      item = (item + items.length) % items.length;
      if (carouselContainer.current) {

        // -------------------------------- HERE --------------------------------
        carouselContainer.current.scrollLeft = carouselContainer.current.clientWidth * item;

      }
      setActiveItem(item);
    },
    [items],
  );

But I don't understand what magic is happening behind the scenes. Indeed when we set scrollLeft to any value it has no effect until we jump to another page and get back 🤷‍♂️

pochka15 commented 1 year ago

Okay, I've found the problem, it's in the overflow-x: hidden. Looks like it should be set to scroll as it's stated on the MDN but I still don't understand why it works after jumping between pages

https://github.com/themesberg/flowbite-react/assets/24525928/3807cd91-ac95-4556-ba91-c9df6d0a7337

pochka15 commented 1 year ago

In some sense showing scrollbars does the job (but you'll see a scrollbar :) ). Styles are a bit broken here

https://github.com/themesberg/flowbite-react/assets/24525928/8eaac0be-dcaf-4fe7-9dc1-5b77525248ab

vdwalia commented 1 year ago

Any update on this ?

rluders commented 1 year ago

@vdwalia give it a try: https://www.npmjs.com/package/flowbite-react/v/0.7.0-beta.3

vdwalia commented 1 year ago

@vdwalia give it a try: https://www.npmjs.com/package/flowbite-react/v/0.7.0-beta.3

Nope that doesn't work Although this is what i have tried and it worked on chrome as well as in firefox

"use client";

import "./globals.css";
import {Carousel} from "flowbite-react";
import {useState} from "react";

export default function Home() {
    const [isHide, setIsHide] = useState(true);
    setTimeout(() => setIsHide(false), 1000);
    return (
        <div className="px-4 pt-6">
            <div className="h-72 w-full">
                {!isHide ? (
                    <Carousel>
                        <img
                            alt="banner-1"
                            src="/images/homepage_slider_images/banner1.webp"
                        />
                        <img
                            alt="banner-2"
                            src="/images/homepage_slider_images/banner2.webp"
                        />
                        <img
                            alt="banner-3"
                            src="/images/homepage_slider_images/banner3.webp"
                        />
                        <img
                            alt="banner-4"
                            src="/banner4.webp"
                        />
                    </Carousel>
                ) : null}
            </div>
        </div>
    );
}

But i don't think this patch is the stable solution. Also is there any way we can set number of items per slide ? i did tried to changing styles from here src/flowbite-theme.ts and it works with items styles but that isn't responsive and indicator isn't working accordingly so is it possible for us to add one more prop to existing Carousel component ?

Screenshot 2023-10-13 at 3 24 59 PM

pochka15 commented 1 year ago

Any update on this ?

I've personally fixed the problem by adding some CSS

 <Carousel  className={styles.hackChild} >
      {children}
    </Carousel>
.hackChild > :first-child {
  overflow: auto;
}

@vdwalia

vdwalia commented 1 year ago

Any update on this ?

I've personally fixed the problem by adding some CSS

 <Carousel  className={styles.hackChild} >
      {children}
    </Carousel>
.hackChild > :first-child {
  overflow: auto;
}

@vdwalia

It worked with chrome and firefox, thx alot for that but having issue in safari, i can see vertical and horizontal scroll bars. I guess we are 90% there...

joornby commented 9 months ago

Okay, I've found the problem, it's in the overflow-x: hidden. Looks like it should be set to scroll as it's stated on the MDN but I still don't understand why it works after jumping between pages

Looking at the CSS inheritance tree, the react-indiana-drag-scroll library specifies the overflow to be hidden when you hide the scroll bars, which had a higher css specificity. I already was using a custom theme, so I changed the scroll container class to be !overflow-x-scroll which overrides the specificity and it seems to work now.