material-tailwind icon indicating copy to clipboard operation
material-tailwind copied to clipboard

Carousel doesn't load images with next/image <Image fill />

Open TristanWasTaken opened this issue 1 year ago • 1 comments

When I try to use next/image <Image fill /> instead of <img /> the carousel component won't load that image. Though this seems to be only the case with some images/ in some situations.

Steps to reproduce: Required packages: next. sharp, react,

  1. copy paste the Carousel Custom Navigation code from the carousel docs with "use client" in L1
  2. Download the image files, move them to some local folder and import them
  3. Replace <img /> with Next's <Image /> and add the fill (fill={true}) option to all three images
  4. the carousel is either completely invisible or can't load/hides the images with fill=true option

There are some variations too where I set img2 to fill=false and img1 was able to load but img3 wasn't (see carousel.tsx and second carousel.tsx code)

code: app/layout.tsx:

import type {ReactNode, JSX} from "react";
import type {Metadata} from 'next';
import { Open_Sans } from 'next/font/google';
import {NextFont} from 'next/dist/compiled/@next/font';
import {cn} from '../lib/utils';
import './globals.css';

const inter: NextFont = Open_Sans({
	subsets: ['latin']
});

export const metadata: Metadata = {
	title: 'Test'
}

export default function RootLayout({children}: {children: ReactNode}): JSX.Element {
	return (
		<html lang="en">
		<body className={cn(
			inter.className,
			"bg-black"
		)}>
			{children}
		</body>
		</html>
	)
}

app/page.tsx

import {JSX} from "react";
import {Carousel} from "../components/carousel";

export default function Page(): JSX.Element {
	return (
		<Carousel />
	);
}

components/carousel.tsx

"use client";

import {JSX} from "react";
import Image from "next/image";
import {Carousel as MTCarousel, IconButton as MTIconButton} from "@material-tailwind/react";
import img1 from "../public/photo-1497436072909-60f360e1d4b1.jpg";
import img2 from "../public/photo-1493246507139-91e8fad9978e.jpg";
import img3 from "../public/photo-1518623489648-a173ef7824f3.jpg";

export const Carousel = (): JSX.Element => {
	return (
		<MTCarousel
			className="rounded-xl flex relative h-full w-full overflow-hidden"
			prevArrow={({ handlePrev }) => (
				<MTIconButton
					variant="text"
					color="white"
					size="lg"
					onClick={handlePrev}
					className="!absolute top-2/4 left-4 -translate-y-2/4"
				>
					<svg
						xmlns="http://www.w3.org/2000/svg"
						fill="none"
						viewBox="0 0 24 24"
						strokeWidth={2}
						stroke="currentColor"
						className="h-6 w-6"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"
						/>
					</svg>
				</MTIconButton>
			)}
			nextArrow={({ handleNext }) => (
				<MTIconButton
					variant="text"
					color="white"
					size="lg"
					onClick={handleNext}
					className="!absolute top-2/4 !right-4 -translate-y-2/4"
				>
					<svg
						xmlns="http://www.w3.org/2000/svg"
						fill="none"
						viewBox="0 0 24 24"
						strokeWidth={2}
						stroke="currentColor"
						className="h-6 w-6"
					>
						<path
							strokeLinecap="round"
							strokeLinejoin="round"
							d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3"
						/>
					</svg>
				</MTIconButton>
			)}
			navigation={({ setActiveIndex, activeIndex, length }) => (
				<div className="absolute bottom-4 left-2/4 z-50 flex -translate-x-2/4 gap-2">
					{new Array(length).fill("").map((_, i) => (
						<span
							key={i}
							className={`block h-1 cursor-pointer rounded-2xl transition-all content-[''] ${
								activeIndex === i ? "w-8 bg-white" : "w-4 bg-white/50"
							}`}
							onClick={() => setActiveIndex(i)}
						/>
					))}
				</div>
			)}
		>
			<Image
				src={img1}
				alt="image 1"
				className="h-full w-full object-cover"
				fill
			/>
			<Image
				src={img2}
				alt="image 2"
				className="h-full w-full object-cover"
				fill
			/>
			<Image
				src={img3}
				alt="image 3"
				className="h-full w-full object-cover"
				fill
			/>
		</MTCarousel>
	);
}

carousel.tsx only img3 doesn't load:

<MTCarousel>
	<Image
		src={img1}
		alt="image 1"
		className="h-full w-full object-cover"
		fill
	/>
	<Image
		src={img2}
		alt="image 2"
		className="h-full w-full object-cover"
		fill={false}
	/>
	<Image
		src={img3}
		alt="image 3"
		className="h-full w-full object-cover"
		fill
	/>
</MTCarousel>

TristanWasTaken avatar Oct 02 '23 12:10 TristanWasTaken

I wrapped the carousel inside another div with a fixed height and it worked fine for me.

girdhariag avatar Nov 01 '23 06:11 girdhariag