🐛 bug: dot

:%s
This commit is contained in:
unknown 2021-08-25 18:46:37 +07:00
parent b824893540
commit beb9b2e47c
4 changed files with 110 additions and 28 deletions

View File

@ -86,7 +86,7 @@ const dataTest = [{
export default function Home() { export default function Home() {
return ( return (
<> <>
<ProductCaroucel data={dataTest} itemKey="product-1" /> <ProductCaroucel data={dataTest} itemKey="product-1" isDot={true}/>
</> </>
) )
} }

View File

@ -1,25 +1,51 @@
@import '../../../styles/utilities'; @import '../../../styles/utilities';
.navigationWrapper{ .navigationWrapper {
@apply relative; @apply relative;
min-height: theme("caroucel.arrow-height") ; min-height: theme('caroucel.arrow-height');
.isPadding{ .isPadding {
@apply spacing-horizontal; @apply spacing-horizontal;
} }
:global(.customArrow) { :global(.customArrow) {
width: 64px; width: 64px;
height: 64px; height: 64px;
&:focus{ &:focus {
outline: none; outline: none;
} }
@apply absolute top-1/2 bg-background-arrow transform -translate-y-1/2 flex justify-center items-center transition duration-100; @apply absolute top-1/2 bg-background-arrow transform -translate-y-1/2 flex justify-center items-center transition duration-100;
&:global(.leftArrow){ &:global(.leftArrow) {
@apply left-0; @apply left-0;
} }
&:global(.rightArrow){ &:global(.rightArrow) {
@apply right-0; @apply right-0;
} }
&:global(.isDisabledArrow){ &:global(.isDisabledArrow) {
@apply hidden ; @apply hidden;
}
}
:global {
.dots {
display: flex;
padding: 10px 0;
justify-content: center;
}
.dot {
border: none;
width: 10px;
height: 10px;
background: #c5c5c5;
border-radius: 50%;
margin: 0 5px;
padding: 5px;
cursor: pointer;
}
.dot:focus {
outline: none;
}
.dot.active {
background: #000;
} }
} }
} }

View File

@ -1,14 +1,16 @@
import { useKeenSlider } from 'keen-slider/react' import { useKeenSlider } from 'keen-slider/react'
import React from 'react' import React, { useEffect } from 'react'
import 'keen-slider/keen-slider.min.css' import 'keen-slider/keen-slider.min.css'
import { CustomCarouselArrow } from './CustomArrow/CustomCarouselArrow' import { CustomCarouselArrow } from './CustomArrow/CustomCarouselArrow'
import s from './CaroucelCommon.module.scss' import s from './CaroucelCommon.module.scss'
import { TOptionsEvents } from 'keen-slider' import { TOptionsEvents } from 'keen-slider'
import classNames from 'classnames' import classNames from 'classnames'
import CustomDot from './CustomDot/CustomDot'
export interface CarouselCommonProps<T> { export interface CarouselCommonProps<T> {
data: T[] data: T[]
Component: React.ComponentType<T> Component: React.ComponentType<T>
isArrow?: Boolean isArrow?: Boolean
isDot?: Boolean
itemKey: String itemKey: String
option: TOptionsEvents option: TOptionsEvents
keenClassname?: string keenClassname?: string
@ -19,12 +21,18 @@ const CarouselCommon = <T,>({
data, data,
Component, Component,
itemKey, itemKey,
keenClassname,isPadding=false, keenClassname,
option: { slideChanged, ...sliderOption }, isPadding = false,
isArrow = true,
isDot = false,
option: { slideChanged,slidesPerView, ...sliderOption },
}: CarouselCommonProps<T>) => { }: CarouselCommonProps<T>) => {
const [currentSlide, setCurrentSlide] = React.useState(0) const [currentSlide, setCurrentSlide] = React.useState(0)
const [dotActive, setDotActive] = React.useState<number>(0)
const [dotArr, setDotArr] = React.useState<number[]>([])
const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({ const [sliderRef, slider] = useKeenSlider<HTMLDivElement>({
...sliderOption, ...sliderOption,
slidesPerView,
slideChanged(s) { slideChanged(s) {
setCurrentSlide(s.details().relativeSlide) setCurrentSlide(s.details().relativeSlide)
}, },
@ -33,19 +41,37 @@ const CarouselCommon = <T,>({
slider.next() slider.next()
} }
useEffect(() => {
if(isDot && slider){
console.log('f',Math.ceil(data.length/(Number(slider.details().slidesPerView)||1)))
setDotArr([...Array(Math.ceil(data.length/(Number(slider.details().slidesPerView)||1))).keys()])
}
}, [isDot,slider])
const handleLeftArrowClick = () => { const handleLeftArrowClick = () => {
slider.prev() slider.prev()
} }
const onDotClick = (index:number) => {
slider.moveToSlide(((Number(slider.details().slidesPerView)||1)*index))
setDotActive(index)
}
return ( return (
<div className={s.navigationWrapper}> <div className={s.navigationWrapper}>
<div ref={sliderRef} className={classNames('keen-slider', keenClassname,{[s.isPadding]:isPadding})}> <div
ref={sliderRef}
className={classNames('keen-slider', keenClassname, {
[s.isPadding]: isPadding,
})}
>
{data?.map((props, index) => ( {data?.map((props, index) => (
<div className="keen-slider__slide" key={`${itemKey}-${index}`}> <div className="keen-slider__slide" key={`${itemKey}-${index}`}>
<Component {...props} /> <Component {...props} />
</div> </div>
))} ))}
</div> </div>
{slider && ( {slider && isArrow && (
<> <>
<CustomCarouselArrow <CustomCarouselArrow
side="right" side="right"
@ -59,6 +85,15 @@ const CarouselCommon = <T,>({
/> />
</> </>
)} )}
{slider && isDot && (
<div className="dots">
{dotArr.map((index) => {
return (
<CustomDot key={`dot-${index}`} index={index} dotActive={dotActive} onClick={onDotClick}/>
)
})}
</div>
)}
</div> </div>
) )
} }

View File

@ -0,0 +1,21 @@
import React from 'react'
interface Props {
index: number
dotActive:number
onClick: (index: number) => void
}
const CustomDot = ({ index, onClick, dotActive }: Props) => {
const handleOnClick = () => {
onClick && onClick(index)
}
return (
<button
onClick={handleOnClick}
className={'dot' + (dotActive === index ? ' active' : '')}
/>
)
}
export default CustomDot