43
loading...
This website collects cookies to deliver better user experience
<Carousel
heading="demo"
n={2}
g="12px"
>
{[...Array(10)].map((_val,index) => {
return(
<FlexBoxTitleCard
title={`item ${index+1}`}
key={`item ${index+1}`}
/>
)
})}
</Carousel>
import { useRef, useState } from 'react'
interface CarouselProps {
heading:string,
children:JSX.Element[]
n?:number,
g?:string,
}
export const Carousel = (props:CarouselProps) => {
const [active,setActive] = useState(0)
const carouselRef = useRef<HTMLDivElement>(null)
const scrollToNextElement= () => {
if(carouselRef.current){
if(active < carouselRef.current.childNodes.length - (props.n?props.n:3)){
carouselRef.current.scrollLeft = (carouselRef.current.childNodes[active + 1] as HTMLElement).offsetLeft - (carouselRef.current.parentNode as HTMLElement).offsetLeft;
setActive(active +1)
}
}
}
const scrollToPreviousElement = () => {
console.log(active);
if(carouselRef.current){
if(active > 0) {
carouselRef.current.scrollLeft = (carouselRef.current.childNodes[active - 1] as HTMLElement).offsetLeft - (carouselRef.current.parentNode as HTMLElement).offsetLeft ;
setActive(active - 1)
}
}
}
return(
<div>
<div>
<p>{props.heading}</p>
<div>
<span className="nav-button cursor_pointer" onClick={scrollToPreviousElement} style={{marginRight:"32px"}}>{"<"}</span>
<span className="nav-button cursor_pointer" onClick={scrollToNextElement}>{">"}</span>
</div>
</div>
<div
className="carousel-slides"
ref={carouselRef}
style={{
gridAutoColumns:`calc((100% - (${props.n?props.n:3} - 1)*${props.g?props.g:"32px"})/${props.n?props.n:3})`,
gridGap:props.g
}}
>
{props.children}
</div>
</div>
)
}
.carousel-slides {
display: grid;
grid-auto-flow: column;
/* grid-auto-columns: calc((100% - (var(--n) - 1) * var(--g)) / var(--n));
grid-gap: var(--g); */
overflow: hidden;
scroll-behavior: smooth;
padding: 40px 0;
}
.carousel-slides::-webkit-scrollbar {
display: none;
}
.nav-button {
padding: 8px;
border: 1px solid black;
border-radius: 100%;
}
interface CarouselProps {
heading:string,
children:JSX.Element[]
n?:number,
g?:string,
}
JSX.Element
or JSX.Element[]
const [active,setActive] = useState(0)
const carouselRef = useRef<HTMLDivElement>(null)
active
which denotes the left most element in the JSX.Element arraycarouselRef
const scrollToNextElement= () => {
if(carouselRef.current){
if(active < carouselRef.current.childNodes.length - (props.n?props.n:3)){
carouselRef.current.scrollLeft = (carouselRef.current.childNodes[active + 1] as HTMLElement).offsetLeft - (carouselRef.current.parentNode as HTMLElement).offsetLeft;
setActive(active +1)
}
}
}
scrollToNextElement
function lets you scroll to next element in the carousel. Using carouselRef
I am able to access the child nodes and I just change scroll left of the wrapper element to the next elements offset left, it's important substract the parent offsetleft to avoid scrolling the extra padding outside the parent elementgridAutoColumns:`calc((100% - (${props.n?props.n:3} - 1)*${props.g?props.g:"32px"})/${props.n?props.n:3})`
scrollToPreviousElement
uses the same logicscrollToNextElement
and scrollToPreviousElement
and change to scrollToElement
which accepts a number and skips to that element