react mantine carousel slider example

React Mantine Carousel Slider Example

February 1, 2023 By Aaronn

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>
    </>
  );
}
mantine carousel slider

mantine carousel slider

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>
    </>
  );
}
mantine vertical carousel slider

mantine vertical carousel slider

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>
    </>
  );
}
mantine carousel slider with images

mantine carousel slider with images


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>
  );
}