Build a carousel postcard like Instagram with Reactjs, Material-UI, and Swiperjs

Build a carousel postcard like Instagram with Reactjs, Material-UI, and Swiperjs

In this blog, you will learn how to build a carousel postcard like instagram with Reactjs, Material-UI, and Swiperjs.

Live demo

You can demo the website from here

Video Tutorial

I have already made a video about it on my youtube channel. Check that out for more details.

Note:

The application is built with Material-UI V4. The current version is 5. But don't worry. You can still use the code. You only need to change the import paths of components. Everything else will be the same. Check their docs for more details.

Setup from scratch

Create a create-react-app

1npx create-react-app <app>
2cd <app>

Install packages

1yarn add @material-ui/core @material-ui/icons swiper

Start from minimal setup

1git clone git@github.com:thatanjan/insta-carousel-yt.git
2cd insta-carousel-yt
3git fetch
4git checkout scratch

Create the container and title of the application

1// App.js
2import Grid from '@material-ui/core/Grid'
3import Typography from '@material-ui/core/Typography'
4
5import PostCard from './PostCard'
6
7function App() {
8 return (
9 <div className='App'>
10 <Grid container>
11 <Grid
12 iem
13 xs={12}
14 style={{ height: '25vh', display: 'grid', placeItems: 'center' }}
15 >
16 <Typography variant='h3'>Insta Carousel</Typography>
17 </Grid>
18
19 <Grid item container xs={12} justifyContent='center'>
20 <Grid item xs={3}>
21 <PostCard />{' '}
22 </Grid>
23 </Grid>
24 </Grid>
25 </div>
26 )
27}
28
29export default App

Explanation:

  • Created a title that will be centered.
  • Made a container containing the post card which will take 3grid space out of 12. If you don't about the Material UI grid you can the following video.
1import React from 'react'
2import { Swiper, SwiperSlide } from 'swiper/react'
3import { makeStyles } from '@material-ui/core/styles'
4import Card from '@material-ui/core/Card'
5import CardHeader from '@material-ui/core/CardHeader'
6import CardMedia from '@material-ui/core/CardMedia'
7import CardContent from '@material-ui/core/CardContent'
8import CardActions from '@material-ui/core/CardActions'
9import Avatar from '@material-ui/core/Avatar'
10import IconButton from '@material-ui/core/IconButton'
11import Typography from '@material-ui/core/Typography'
12import FavoriteIcon from '@material-ui/icons/Favorite'
13import ShareIcon from '@material-ui/icons/Share'
14import MoreVertIcon from '@material-ui/icons/MoreVert'
15import CommentIcon from '@material-ui/icons/Comment'
16
17import SwiperCore, {
18 Keyboard,
19 Scrollbar,
20 Pagination,
21 Navigation,
22} from 'swiper/core'
23
24import 'swiper/swiper.min.css'
25import 'swiper/components/pagination/pagination.min.css'
26import 'swiper/components/navigation/navigation.min.css'
27import 'swiper/components/scrollbar/scrollbar.min.css'
28
29import avatarImage from './media/postAvatar.jpg'
30import ts_1 from './media/carousels/ts_1.jpg'
31import ts_2 from './media/carousels/ts_2.jpg'
32import ts_3 from './media/carousels/ts_3.jpg'
33import ts_4 from './media/carousels/ts_4.jpg'
34import ts_5 from './media/carousels/ts_5.jpg'
35
36const useStyles = akeStyles({
37 media: {
38 height: 0,
39 paddingTop: '100%',
40 },
41 swiperContainer: {
42 paddingBottom: '3rem',
43 '& .swiper-pagination-bullet': {
44 background: 'blue',
45 },
46 '& .swiper-button-next:after': {
47 fontSize: '2rem !important',
48 },
49 '& .swiper-button-prev:after': {
50 fontSize: '2rem !important',
51 },
52 },
53})
54
55SwiperCore.use([Keyboard, Scrollbar, Pagination, Navigation])
56
57const images = [ts_1, ts_2, ts_3, ts_4, ts_5]
58
59const PostCard = () => {
60 const { media, swiperContainer } = useStyles()
61 return (
62 <Card>
63 <CardHeader
64 avatar={<Avatar src={avatarImage} />}
65 title='Just a Carousel'
66 subheader={new Date().toDateString()}
67 action={
68 <IconButton>
69 <MoreVertIcon />
70 </IconButton>
71 }
72 />
73
74 <Swiper
75 grabCursor
76 keyboard={{ enabled: true }}
77 pagination={{ clickable: true }}
78 navigation
79 loop
80 className={swiperContainer}
81 >
82 {images.map((image, index) => (
83 <SwiperSlide key={index}>
84 <CardMedia className={media} image={image} />
85 </SwiperSlide>
86 ))}
87 </Swiper>
88
89 <CardActions disableSpacing>
90 <IconButton>
91 <FavoriteIcon />
92 </IconButton>
93 <IconButton>
94 <CommentIcon />
95 </IconButton>
96 <IconButton>
97 <ShareIcon />
98 </IconButton>
99 </CardActions>
100
101 <CardContent>
102 <Typography variant='body2' color='textSecondary' component='p'>
103 Adipisicing eaque temporibus elit incidunt obcaecati. Aut eum excepturi id
104 aut consequatur ex? Incidunt debitis at consequuntur accusamus rerum
105 Tempora veritatis maiores quam molestias aut placeat qui. Iure neque libero
106 voluptas aliquid!
107 </Typography>
108 </CardContent>
109 </Card>
110 )
111}
112
113export default PostCard

Explaination:

  • We have used card, cardHeader, and other components from Material UI.
  • CardMedia component will have our image. It has a little bit of custom style so that it stays responsive on every screen size and it will always maintain the aspect ratio.
  • We have imported Keyboard, Scrollbar, Pagination, Navigation modules from Swiperjs. To have navigation, navigation with keyboard and so on.
  • We added custom styles to the Swiper component to modify the icons of Swiper component.

And the project is ready. Please watch the video for more details.

Shameless Plug

I have made an Xbox landing page clone with React and Styled components. I hope you will enjoy it. Please consider like this video and subscribe to my channel.

That's it for this blog. I have tried to explain things simply. If you get stuck, you can ask me questions.

Contacts

Blogs you might want to read:

Videos might you might want to watch:

Previous PostWhat is Static Site Generation?
Next PostTypewriter effect with React and Typed.js