<ImageCarousel />
A slideshow component for cycling through images like a carousel.Component
1import React, { useState } from "react";2import "./Styles/_imagecarousel.scss";34export default function ImageCarousel({ ...props }) {5 const { children } = props;6 const [currentImg, setCurrentImage] = useState(0);78 const childrenWithProps = React.Children.map(children, (child, index) => {9 if (React.isValidElement(child)) {10 return React.cloneElement(child, { currentImg, index });11 }12 return child;13 });1415 const prev = () => setCurrentImage((currentImg) => currentImg - 1);16 const next = () => setCurrentImage((currentImg) => currentImg + 1);1718 return (19 <div className="Image-Carousel">20 {currentImg > 0 && (21 <button onClick={prev} className="prev">22 <i className="fas fa-chevron-circle-left" />23 </button>24 )}2526 {currentImg < children.length - 1 && (27 <button onClick={next} className="next">28 <i className="fas fa-chevron-circle-right" />29 </button>30 )}3132 <div>33 {children.map((element, idx, array) => (34 <button35 key={idx}36 onClick={() => setCurrentImage(idx)}37 className={idx === currentImg ? "isActive" : ""}38 />39 ))}40 </div>41 <ul>{childrenWithProps}</ul>42 </div>43 );44}4546export { CarouselItem } from "./Components/CarouselItem";
Styles
1$properties: (2 Nav-Btn-Position: 0.5rem,3);45.Image-Carousel {6 width: 700px;7 height: 500px;8 position: relative;910 & > div {11 position: absolute;12 background-color: white;13 border-radius: 5px;14 z-index: 2;15 bottom: 5px;16 left: 50%;17 transform: translateX(-50%);1819 & button {20 border: none;21 border-radius: 50%;22 width: 10px;23 height: 10px;24 background: hsl(0, 0%, 66%);25 margin: 0px 4px;26 cursor: pointer;27 padding: 0;2829 &.isActive {30 background: hsl(0, 0%, 15%);31 }32 }33 }3435 & > button {36 position: absolute;37 background: none;38 z-index: 2;39 border: none;40 color: white;41 font-size: 1.25rem;42 top: 50%;43 transform: translateY(-50%);44 cursor: pointer;4546 &:hover,47 &:focus {48 color: white;49 }5051 &.prev {52 left: map-get($properties, Nav-Btn-Position);53 }5455 &.next {56 right: map-get($properties, Nav-Btn-Position);57 }58 }5960 & ul {61 margin: 0;62 padding: 0;63 list-style: none;64 }6566 & li {67 position: absolute;68 inset: 0;69 opacity: 0;70 transition: 200ms opacity ease-in-out;71 transition-delay: 200ms;7273 & > img {74 display: block;75 width: 100%;76 height: 100%;77 object-fit: cover;78 object-position: center;79 }8081 &.isActive {82 opacity: 1;83 z-index: 1;84 transition-delay: 0ms;85 }86 }87}
Usage
1