mirror of
https://github.com/vercel/commerce.git
synced 2025-07-04 20:21:21 +00:00
🐛 bug: dot
:%s
This commit is contained in:
parent
b824893540
commit
beb9b2e47c
@ -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}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
:global(.customArrow) {
|
@apply absolute top-1/2 bg-background-arrow transform -translate-y-1/2 flex justify-center items-center transition duration-100;
|
||||||
width: 64px;
|
&:global(.leftArrow) {
|
||||||
height: 64px;
|
@apply left-0;
|
||||||
&:focus{
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
@apply absolute top-1/2 bg-background-arrow transform -translate-y-1/2 flex justify-center items-center transition duration-100;
|
|
||||||
&:global(.leftArrow){
|
|
||||||
@apply left-0;
|
|
||||||
}
|
|
||||||
&:global(.rightArrow){
|
|
||||||
@apply right-0;
|
|
||||||
}
|
|
||||||
&:global(.isDisabledArrow){
|
|
||||||
@apply hidden ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
&:global(.rightArrow) {
|
||||||
|
@apply right-0;
|
||||||
|
}
|
||||||
|
&:global(.isDisabledArrow) {
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
21
src/components/common/CarouselCommon/CustomDot/CustomDot.tsx
Normal file
21
src/components/common/CarouselCommon/CustomDot/CustomDot.tsx
Normal 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
|
Loading…
x
Reference in New Issue
Block a user