In this tutorial, we will see how to use Carousel Slider component in react mantine. We will create horizontal and vertical carousel slider component, carousel slider indicator, carousel with image and card using react mantine.
Install & Setup Vite + React + Typescript + Mantine UI
React Mantine UI Carousel Slider Example
To use Carousel Slider you need to install @mantine/carousel
Install with yarn:
yarn add embla-carousel-react @mantine/carousel
Install with npm:
npm install embla-carousel-react @mantine/carousel
1. react mantine carousel slider with indicator.
import { Carousel } from "@mantine/carousel";
export default function Slider() {
return (
<>
<Carousel sx={{ maxWidth: 600 }} mx="auto" withIndicators height={200}>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
Slider 1
</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
Slider 2
</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
Slider 3
</Carousel.Slide>
</Carousel>
</>
);
}
2. react mantine Set slideSize and slideGap on Carousel component to control size and gap of every slide:
import { Carousel } from "@mantine/carousel";
export default function Slider() {
return (
<>
<Carousel
sx={{ maxWidth: 600 }}
mx="auto"
withIndicators
height={200}
slideSize="33.333333%"
slideGap="md"
loop
align="start"
slidesToScroll={3}
>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>1</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>2</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>3</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>4</Carousel.Slide>
</Carousel>
</>
);
}
3. react mantine responsive carousel slider.
import { Carousel } from "@mantine/carousel";
export default function Slider() {
return (
<>
<Carousel
withIndicators
height={200}
slideSize="33.333333%"
slideGap="md"
breakpoints={[
{ maxWidth: "md", slideSize: "50%" },
{ maxWidth: "sm", slideSize: "100%", slideGap: 0 },
]}
loop
align="start"
>
<Carousel.Slide>1</Carousel.Slide>
<Carousel.Slide>2</Carousel.Slide>
<Carousel.Slide>3</Carousel.Slide>
</Carousel>
</>
);
}
4. react mantine vertical carousel slider.
{ Carousel } from "@mantine/carousel";
export default function Slider() {
return (
<>
<Carousel
orientation="vertical"
height={200}
withIndicators
sx={{ maxWidth: 600 }}
mx="auto"
>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
vertical Slider 1
</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
vertical Slider 2
</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
vertical Slider 3
</Carousel.Slide>
<Carousel.Slide sx={{ backgroundColor: "#eee" }}>
vertical Slider 4
</Carousel.Slide>
</Carousel>
</>
);
}
5. react mantine Progress bar carousel slider.
import { useCallback, useEffect, useState } from "react";
import { Carousel, Embla } from "@mantine/carousel";
import { Progress } from "@mantine/core";
export default function Slider() {
const [scrollProgress, setScrollProgress] = useState(0);
const [embla, setEmbla] = useState<Embla | null>(null);
const handleScroll = useCallback(() => {
if (!embla) return;
const progress = Math.max(0, Math.min(1, embla.scrollProgress()));
setScrollProgress(progress * 100);
}, [embla, setScrollProgress]);
useEffect(() => {
if (embla) {
embla.on("scroll", handleScroll);
handleScroll();
}
}, [embla]);
return (
<>
<Carousel
dragFree
slideSize="50%"
slideGap="md"
height={200}
getEmblaApi={setEmbla}
initialSlide={2}
>
<Carousel.Slide>1</Carousel.Slide>
<Carousel.Slide>2</Carousel.Slide>
<Carousel.Slide>3</Carousel.Slide>
<Carousel.Slide>4</Carousel.Slide>
</Carousel>
<Progress
value={scrollProgress}
styles={{ bar: { transitionDuration: "0ms" }, root: { maxWidth: 320 } }}
size="sm"
mt="xl"
mx="auto"
/>
</>
);
}
6. react mantine carousel slider with images.
import { Carousel } from "@mantine/carousel";
import { Image } from "@mantine/core";
const images = [
"https://cdn.pixabay.com/photo/2017/09/25/13/12/puppy-2785074__340.jpg",
"https://cdn.pixabay.com/photo/2016/12/13/05/15/puppy-1903313__340.jpg",
"https://cdn.pixabay.com/photo/2018/10/01/09/21/pets-3715733__340.jpg",
];
export default function Slider() {
const slides = images.map((url) => (
<Carousel.Slide key={url}>
<Image src={url} />
</Carousel.Slide>
));
return (
<>
<Carousel sx={{ maxWidth: 320 }} mx="auto" withIndicators>
{slides}
</Carousel>
</>
);
}
7. react mantine cards carousel slider.
import { Carousel } from "@mantine/carousel";
import { useMediaQuery } from "@mantine/hooks";
import {
createStyles,
Paper,
Text,
Title,
Button,
useMantineTheme,
} from "@mantine/core";
const useStyles = createStyles((theme) => ({
card: {
height: 440,
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
alignItems: "flex-start",
backgroundSize: "cover",
backgroundPosition: "center",
},
title: {
fontFamily: `Greycliff CF, ${theme.fontFamily}`,
fontWeight: 900,
color: theme.white,
lineHeight: 1.2,
fontSize: 32,
marginTop: theme.spacing.xs,
},
category: {
color: theme.white,
opacity: 0.7,
fontWeight: 700,
textTransform: "uppercase",
},
}));
interface CardProps {
image: string;
title: string;
category: string;
}
function Card({ image, title, category }: CardProps) {
const { classes } = useStyles();
return (
<Paper
shadow="md"
p="xl"
radius="md"
sx={{ backgroundImage: `url(${image})` }}
className={classes.card}
>
<div>
<Text className={classes.category} size="xs">
{category}
</Text>
<Title order={3} className={classes.title}>
{title}
</Title>
</div>
<Button variant="white" color="dark">
Read article
</Button>
</Paper>
);
}
const data = [
{
image:
"https://images.unsplash.com/photo-1508193638397-1c4234db14d8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80",
title: "Best forests to visit in North America",
category: "nature",
},
{
image:
"https://images.unsplash.com/photo-1559494007-9f5847c49d94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80",
title: "Hawaii beaches review: better than you think",
category: "beach",
},
{
image:
"https://images.unsplash.com/photo-1608481337062-4093bf3ed404?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80",
title: "Mountains at night: 12 best locations to enjoy the view",
category: "nature",
},
{
image:
"https://images.unsplash.com/photo-1507272931001-fc06c17e4f43?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80",
title: "Aurora in Norway: when to visit for best experience",
category: "nature",
},
{
image:
"https://images.unsplash.com/photo-1510798831971-661eb04b3739?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80",
title: "Best places to visit this winter",
category: "tourism",
},
{
image:
"https://images.unsplash.com/photo-1582721478779-0ae163c05a60?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80",
title: "Active volcanos reviews: travel at your own risk",
category: "nature",
},
];
export default function Slider() {
const theme = useMantineTheme();
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm}px)`);
const slides = data.map((item) => (
<Carousel.Slide key={item.title}>
<Card {...item} />
</Carousel.Slide>
));
return (
<Carousel
slideSize="50%"
breakpoints={[{ maxWidth: "sm", slideSize: "100%", slideGap: 2 }]}
slideGap="xl"
align="start"
slidesToScroll={mobile ? 1 : 2}
>
{slides}
</Carousel>
);
}