jsx import { jsx } from "@emotion/react" ; import { RowBetween } from "../Flex/Row" ; import { Col } from "../Flex/Col" ; import { style } from "./style" ; import { swiperStyle } from "./swiperStyle" ; import { Clickable } from "../Clickable" ; import Swiper from "swiper" ; import React , { useCallback , useEffect , useRef , useState } from "react" ; export type OptionType = { value : string | number ; label ? : React . ReactNode ; [ key ] : any ; } ; export interface PickerWrapperProps { options : OptionType [ ] ; defaultValue ? : number ; renderOption ? : ( option : OptionType , index : number ) => React . ReactNode ; onConfirm ? : ( option : OptionType , index : number ) => void ; onCancel ? : ( ) => void ; renderCancel ? : ( ) => React . ReactNode ; renderConfirm ? : ( ) => React . ReactNode ; showTitle ? : boolean ; renderTitle ? : ( option : OptionType , index : number ) => React . ReactNode ; } export function Wrapper ( props ) { const { onConfirm , onCancel , renderCancel , renderConfirm , options , renderOption , showTitle = true , renderTitle , defaultValue , } = props ; const getInitialSlide = useCallback < ( ) => number > ( ( ) => { let initialSlide = 0 ; if ( Array . isArray ( options ) ) { let findIndex = options . findIndex ( ( option ) => option . value === defaultValue ) ; if ( findIndex >= 0 ) { initialSlide = findIndex ; } } return initialSlide ; } , [ options , defaultValue ] ) ; const swiperRef = useRef < HTMLDivElement | null > ( null ) ; const [ index , setIndex ] = useState < number > ( getInitialSlide ( ) ) ; useEffect ( ( ) => { const swiper = new Swiper ( swiperRef . current ! , { initialSlide : getInitialSlide ( ) , direction : "vertical" , slidesPerView : 5 , centeredSlides : true , freeMode : true , freeModeSticky : true , } ) ; swiper . on ( "init" , ( ) => { setIndex ( swiper . realIndex ) ; } ) ; swiper . on ( "slideChange" , ( ) => { setIndex ( swiper . realIndex ) ; } ) ; return ( ) => { swiper . destroy ( ) ; } ; } , [ getInitialSlide ] ) ; const showTitleContent = ( ) => { if ( showTitle ) { const option = options [ index ] ; if ( typeof renderTitle === "function" ) { return < div css = { style . title } > { renderTitle ( option , index ) } < /div>; } else { return ( < Col css = { style . title } > < span css = { style . titleLabel } > 当前选择 < /span> < span css = { style . titleContent } > { option . label } < /span> < /Col>); } } } ; const showCancel = ( ) => { return renderCancel ?. ( ) ?? < div css = { [ style . btn , style . btnCancel ] } > 取消 < /div>; } ; const showConfirm = ( ) => { return renderConfirm ?. ( ) ?? < div css = { [ style . btn , style . btnConfirm ] } > 确定 < /div>; } ; returns const showOptions = ( ) => { if ( Array . isArray ( options ) ) { return options . map ( ( option , index ) => { let content = option . label ; if ( typeof renderOption === "function" ) { content = renderOption ( option , index ) ; } return ( < div className = "swiper-slide" key = { option . value } > { content } < /div>); } ) ; } } ; return ( < div css = { [ style . container ] } > { } < RowBetween css = { style . header } > { showTitleContent ( ) } < Clickable css = { style . btnBox } onClick = { onCancel } > { showCancel ( ) } < /Clickable> < Clickable css = { style . btnBox } onClick = { ( ) => onConfirm ?. ( options [ index ] , index ) } > { showConfirm ( ) } < /Clickable> < /RowBetween> { } < div css = { [ swiperStyle , style . body ] } > < div className = "swiper" css = { style . swiper } ref = { swiperRef } > { } < div className = "swiper-wrapper" > { showOptions ( ) } < /div> { } < div css = { [ style . mask , style . maskTop ] } /> < div css = { [ style . mask , style . maskBottom ] } / > < /div> < /div> < /div>); }