This commit is contained in:
Bel Curcio 2021-06-01 16:45:12 -03:00
parent 113d186d0b
commit 2f17e7eba9
3 changed files with 74 additions and 87 deletions

View File

@ -91,6 +91,7 @@ body {
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
background-color: var(--primary); background-color: var(--primary);
color: var(--text-primary); color: var(--text-primary);
overscroll-behavior-x: none;
} }
body { body {

View File

@ -33,55 +33,26 @@
margin-right: -1px; margin-right: -1px;
} }
.thumb {
@apply transition-transform transition-colors ease-linear duration-75 overflow-hidden
inline-block cursor-pointer;
width: 275px;
}
.thumb:focus,
.thumb.selected {
@apply bg-white;
}
.thumb:hover {
transform: scale(1.02);
background-color: rgba(255, 255, 255, 0.08);
}
.album { .album {
@apply bg-violet-dark; @apply bg-violet-dark;
overflow: auto; overflow-y: hidden;
overflow-x: auto;
white-space: nowrap; white-space: nowrap;
} height: 275px;
.album > * {
@apply cursor-pointer;
display: inline-block;
width: 300px;
}
.album > div:hover {
@apply bg-violet-light;
}
.positionIndicatorsContainer {
@apply hidden;
@screen sm {
@apply block absolute bottom-6 left-1/2;
transform: translateX(-50%);
}
}
.positionIndicator {
@apply rounded-full p-2;
}
.dot {
@apply bg-hover-1 transition w-3 h-3 rounded-full;
}
.positionIndicator:hover .dot {
@apply bg-hover-2;
}
.positionIndicator:focus {
@apply outline-none;
}
.positionIndicator:focus .dot {
@apply shadow-outline-normal;
}
.positionIndicatorActive .dot {
@apply bg-white;
}
.positionIndicatorActive:hover .dot {
@apply bg-white;
} }

View File

@ -8,7 +8,7 @@ import React, {
useEffect, useEffect,
} from 'react' } from 'react'
import cn from 'classnames' import cn from 'classnames'
import { a } from '@react-spring/web'
import s from './ProductSlider.module.css' import s from './ProductSlider.module.css'
import { ChevronLeft, ChevronRight } from '@components/icons' import { ChevronLeft, ChevronRight } from '@components/icons'
@ -16,13 +16,26 @@ const ProductSlider: FC = ({ children }) => {
const [currentSlide, setCurrentSlide] = useState(0) const [currentSlide, setCurrentSlide] = useState(0)
const [isMounted, setIsMounted] = useState(false) const [isMounted, setIsMounted] = useState(false)
const sliderContainerRef = useRef<HTMLDivElement>(null) const sliderContainerRef = useRef<HTMLDivElement>(null)
const thumbsContainerRef = useRef<HTMLDivElement>(null)
const [ref, slider] = useKeenSlider<HTMLDivElement>({ const [ref, slider] = useKeenSlider<HTMLDivElement>({
loop: true, loop: true,
slidesPerView: 1, slidesPerView: 1,
mounted: () => setIsMounted(true), mounted: () => setIsMounted(true),
slideChanged(s) { slideChanged(s) {
setCurrentSlide(s.details().relativeSlide) const slideNumber = s.details().relativeSlide
setCurrentSlide(slideNumber)
if (thumbsContainerRef.current) {
const $el = document.getElementById(
`thumb-${s.details().relativeSlide}`
)
if (slideNumber >= 3) {
thumbsContainerRef.current.scrollLeft = $el!.offsetLeft
} else {
thumbsContainerRef.current.scrollLeft = 0
}
}
}, },
}) })
@ -67,22 +80,24 @@ const ProductSlider: FC = ({ children }) => {
className="relative keen-slider h-full transition-opacity duration-150" className="relative keen-slider h-full transition-opacity duration-150"
style={{ opacity: isMounted ? 1 : 0 }} style={{ opacity: isMounted ? 1 : 0 }}
> >
<div className={s.control}> {slider && (
<button <div className={s.control}>
onClick={slider?.prev} <button
className={cn(s.leftControl)} className={cn(s.leftControl)}
aria-label="Previous Product Image" onClick={slider.prev}
> aria-label="Previous Product Image"
<ChevronLeft /> >
</button> <ChevronLeft />
<button </button>
onClick={slider?.next} <button
className={cn(s.rightControl)} className={cn(s.rightControl)}
aria-label="Next Product Image" onClick={slider.next}
> aria-label="Next Product Image"
<ChevronRight /> >
</button> <ChevronRight />
</div> </button>
</div>
)}
{Children.map(children, (child) => { {Children.map(children, (child) => {
// Add the keen-slider__slide className to children // Add the keen-slider__slide className to children
if (isValidElement(child)) { if (isValidElement(child)) {
@ -98,29 +113,29 @@ const ProductSlider: FC = ({ children }) => {
} }
return child return child
})} })}
{slider && (
<div className={cn(s.positionIndicatorsContainer)}>
{[...Array(slider.details().size).keys()].map((idx) => {
return (
<button
aria-label="Position indicator"
key={idx}
className={cn(s.positionIndicator, {
[s.positionIndicatorActive]: currentSlide === idx,
})}
onClick={() => {
slider.moveToSlideRelative(idx)
}}
>
<div className={s.dot} />
</button>
)
})}
</div>
)}
</div> </div>
<div className={s.album}>{Children.map(children, (child) => child)}</div> <a.div className={s.album} ref={thumbsContainerRef}>
{slider &&
Children.map(children, (child, idx) => {
if (isValidElement(child)) {
return {
...child,
props: {
...child.props,
className: cn(child.props.className, s.thumb, {
[s.selected]: currentSlide === idx,
}),
id: `thumb-${idx}`,
onClick: () => {
slider.moveToSlideRelative(idx)
},
},
}
}
return child
})}
</a.div>
</div> </div>
) )
} }