jsx import { jsx } from "@emotion/react" ; import React , { useCallback , useEffect , useRef , useLayoutEffect } from "react" ; import { style } from "./style" ; import Swiper from "swiper" ; import { RowCenter } from "../Flex/Row" ; import { swiperStyle } from "../Picker/swiperStyle" ; export interface ColumnItem { label : React . ReactNode ; value : string | number ; } export interface ColumnProps { columnOptions : ColumnItem [ ] ; defaultValue ? : string | number ; updateColumns : ( value : string | number ) => void ; } export function Column ( props ) { const { columnOptions , defaultValue , updateColumns } = props ; const swiperRef = useRef < HTMLDivElement | null > ( null ) ; const usedColumnOptions = useRef ( columnOptions ) ; useLayoutEffect ( ( ) => { usedColumnOptions . current = columnOptions ; } , [ columnOptions ] ) ; const getInitialSlide = useCallback < ( ) => number > ( ( ) => { let initialSlide = 0 ; if ( Array . isArray ( columnOptions ) ) { let findIndex = columnOptions . findIndex ( ( option ) => option . value === defaultValue ) ; if ( findIndex >= 0 ) { initialSlide = findIndex ; } } return initialSlide ; } , [ columnOptions , defaultValue ] ) ; const transitionEnd = useRef ( true ) ; useEffect ( ( ) => { var swiper = new Swiper ( swiperRef . current ! , { initialSlide : getInitialSlide ( ) , direction : "vertical" , slidesPerView : 5 , centeredSlides : true , freeMode : true , freeModeSticky : true , observer : true , } ) ; swiper . on ( "slideChange" , ( ) => { if ( ! transitionEnd . current ) { return ; } const selectedValue = usedColumnOptions . current [ swiper . realIndex ] ?. value ; updateColumns ( selectedValue ) ; } ) ; swiper . on ( "observerUpdate" , ( ) => { transitionEnd . current = false ; swiper . slideTo ( 0 , 0 , false ) ; transitionEnd . current = true ; } ) ; return ( ) => { swiper . destroy ( ) ; } ; } , [ ] ) ; return ( < div css = { [ swiperStyle , style . body ] } > < div className = "swiper" ref = { swiperRef } css = { style . swiper } > < div className = "swiper-wrapper" > { columnOptions . map ( ( item ) => { return ( < RowCenter className = "swiper-slide" key = { item . value } > { item . label } < /RowCenter>); } ) } < /div> < div css = { [ style . mask , style . maskTop ] } > < /div> < div css = { [ style . mask , style . maskBottom ] } > < /div> < /div> < /div>); }