11'use client' ;
22
3- import React , { useEffect , useState } from 'react' ;
4- import { useRef } from 'react' ;
3+ import React , { useCallback } from 'react' ;
54import Image from 'next/image' ;
6- import { Arrow } from '@egjs/flicking-plugins' ;
7- import type { FlickingOptions , FlickingProps } from '@egjs/react-flicking' ;
8- import Flicking from '@egjs/react-flicking' ;
5+ import useEmblaCarousel from 'embla-carousel-react' ;
96import { cn } from '@gitanimals/ui-tailwind' ;
107
11- // TODO: 후에 공통으로 사용할 수 있을 것 같다.
128function AnimalSliderContainer ( { children } : { children : React . ReactNode } ) {
13- const flicking = useRef < Flicking | null > ( null ) ;
9+ const [ emblaRef , emblaApi ] = useEmblaCarousel ( {
10+ align : 'start' ,
11+ loop : false ,
12+ skipSnaps : false ,
13+ } ) ;
1414
15- // TODO: useMounted hook으로 분리
16- const [ isMounted , setIsMounted ] = useState ( false ) ;
17- useEffect ( ( ) => setIsMounted ( true ) , [ ] ) ;
18-
19- const wrapperRef = useRef < HTMLDivElement > ( null ) ;
20- const plugins = [ new Arrow ( { parentEl : wrapperRef . current } ) ] ;
21-
22- const sliderOptions : Partial < FlickingProps & FlickingOptions > = {
23- panelsPerView : 1 ,
24- plugins : isMounted ? plugins : undefined ,
25- } ;
15+ const scrollPrev = useCallback ( ( ) => emblaApi ?. scrollPrev ( ) , [ emblaApi ] ) ;
16+ const scrollNext = useCallback ( ( ) => emblaApi ?. scrollNext ( ) , [ emblaApi ] ) ;
2617
2718 return (
2819 < div >
29- < div ref = { wrapperRef } className = { sliderContainer } >
30- < Flicking ref = { flicking } { ...sliderOptions } >
31- { children }
32- </ Flicking >
33- < span className = { cn ( 'flicking-arrow-prev' , 'is-outside' , sliderArrowStyle , prevArrowStyle ) } >
20+ < div className = { sliderContainer } >
21+ < div className = "overflow-hidden" ref = { emblaRef } >
22+ < div className = "flex" >
23+ { React . Children . map ( children , ( child , index ) => (
24+ < div key = { index } className = "flex-[0_0_100%] min-w-0" >
25+ { child }
26+ </ div >
27+ ) ) }
28+ </ div >
29+ </ div >
30+ < span className = { cn ( sliderArrowStyle , prevArrowStyle ) } onClick = { scrollPrev } >
3431 < Image src = "/icon/circle-arrow.svg" alt = "arrow" width = { 40 } height = { 40 } />
3532 </ span >
36- < span className = { cn ( 'flicking-arrow-next' , 'is-outside' , sliderArrowStyle , nextArrowStyle ) } >
33+ < span className = { cn ( sliderArrowStyle , nextArrowStyle ) } onClick = { scrollNext } >
3734 < Image src = "/icon/circle-arrow.svg" alt = "arrow" width = { 40 } height = { 40 } />
3835 </ span >
3936 </ div >
@@ -44,10 +41,9 @@ function AnimalSliderContainer({ children }: { children: React.ReactNode }) {
4441export default AnimalSliderContainer ;
4542
4643const sliderArrowStyle = cn (
47- 'translate-x-10 w-10 h-10' ,
44+ 'w-10 h-10 cursor-pointer ' ,
4845 'absolute block top-0 bottom-0 my-auto z-floating' ,
49- '[&.flicking-arrow-disabled]:translate-x-9 [&.flicking-arrow-disabled]:w-9 [&.flicking-arrow-disabled]:h-9' ,
50- '[&.flicking-arrow-disabled]:cursor-not-allowed [&.flicking-arrow-disabled]:brightness-50' ,
46+ '[&_img]:w-full [&_img]:h-full' ,
5147) ;
5248
5349const prevArrowStyle = cn ( 'rotate-180 -left-6' ) ;
0 commit comments