import * as React from 'react' ; import ClassNames from 'classnames' ; import { SwipeActionProps , BtnProps } from './interface' ; import './style' ; const prefixCls = 'cp-ui-swipe-action' ; const destoryTouchEvent = ( ) => { document . body . removeEventListener ( 'touchmove' , ( ) => { } ) ; } ; const onSiderContentTouchCancel = ( e , isMoving , setIsMoving , setStartTouchX ) => { e . preventDefault ( ) ; if ( ! isMoving ) { return ; } setIsMoving ( false ) ; setStartTouchX ( 0 ) ; } ; const onSiderContentTouchEnd = ( e , props , directionRef , sliderContentRef , isMoving , setIsMoving ) => { e . preventDefault ( ) ; const { onOpen , onClose , disabled } = props ; if ( disabled || ! isMoving ) { return ; } setIsMoving ( false ) ; const sliderButton = document . getElementsByClassName ( `${ prefixCls }-button` ) [ 0 ] ; const sliderButtonWidth = ( sliderButton as HTMLAnchorElement ) . offsetWidth * 2 ; const sliderContentComponent = sliderContentRef . current ; if ( ! sliderContentComponent ) { return ; } if ( directionRef . current === 'left' ) { sliderContentComponent . style . left = `-${ sliderButtonWidth }px` ; onOpen && onOpen ( ) ; } else if ( directionRef . current === 'right' ) { sliderContentComponent . style . left = '0px' ; onClose && onClose ( ) ; } sliderContentComponent . style . transition = '0.3s all ease-in' ; } ; const onSiderContentTouchStart = ( e , setStartTouchX ) => { e . preventDefault ( ) ; const startTouchX = e . targetTouches [ 0 ] . pageX ; setStartTouchX ( startTouchX ) ; } ; const onSiderContentTouchMove = ( e , props , directionRef , sliderContentRef , isMoving , setIsMoving , prevX , setPrevX , startTouchX ) => { const { right , disabled } = props ; const length = right . length ; e . preventDefault ( ) ; if ( disabled || ! isMoving ) { setIsMoving ( true ) ; return ; } let currentComponent = sliderContentRef . current ; if ( ! currentComponent ) { return ; } const sliderButton = document . getElementsByClassName ( `${ prefixCls }-button` ) [ 0 ] ; let sliderButtonWidth = ( sliderButton as HTMLAnchorElement ) . offsetWidth * length ; const currentX = e . targetTouches [ 0 ] . pageX - startTouchX ; currentComponent . style . transition = '' ; let currentComponentOffset = currentComponent . offsetLeft ; if ( currentComponentOffset > 0 && directionRef . current === 'right' ) { currentComponentOffset = 0 ; } else if ( currentComponentOffset < - sliderButtonWidth && directionRef . current === 'left' ) { currentComponentOffset = - sliderButtonWidth ; } if ( prevX ) { if ( currentComponentOffset <= 0 && currentComponentOffset >= - sliderButtonWidth ) { if ( currentX < prevX ) { directionRef . current = 'left' ; currentComponent . style . left = currentComponentOffset - 1 + 'px' ; } else { directionRef . current = 'right' ; currentComponent . style . left = currentComponentOffset + 1 + 'px' ; } } } setPrevX ( currentX ) ; } ; const handleSliderButtonClick = ( e , props , item , sliderContentRef ) => { e . preventDefault ( ) ; const { autoClose } = props ; if ( autoClose && sliderContentRef . current ) { sliderContentRef . current . style . transition = '0.5s all ease-in' ; window . setTimeout ( ( ) => { if ( sliderContentRef . current ) { sliderContentRef . current . style . left = '0px' ; } } , 10 ) ; } item . onPress && item . onPress ( ) ; } ; const { useRef , useEffect , useState } = React ; const defaultProps = { prefixCls : prefixCls , autoClose : true } ; const SwipeAction = props => { const [ prevX , setPrevX ] = useState ( 0 ) ; const [ isMoving , setIsMoving ] = useState < boolean > ( false ) ; const [ startTouchX , setStartTouchX ] = useState < number > ( 0 ) ; const sliderWrapRef = useRef < HTMLDivElement | null > ( null ) ; const sliderContentRef = useRef < HTMLDivElement | null > ( null ) ; const directionRef = useRef < string > ( '' ) ; const { prefixCls , right } = props ; useEffect ( ( ) => { return ( ) => { destoryTouchEvent ( ) ; } ; } , [ ] ) ; return ( < div className = { ClassNames ( prefixCls , `${ prefixCls } - wrap `)} ref={sliderWrapRef}>
      <div className={` $ { prefixCls } - content `} ref={sliderContentRef} onTouchStart={e => {
            onSiderContentTouchStart(e, setStartTouchX);
        }} onTouchMove={e => {
            onSiderContentTouchMove(e, props, directionRef, sliderContentRef, isMoving, setIsMoving, prevX, setPrevX, startTouchX);
        }} onTouchEnd={e => {
            onSiderContentTouchEnd(e, props, directionRef, sliderContentRef, isMoving, setIsMoving);
        }} onTouchCancel={e => {
            onSiderContentTouchCancel(e, isMoving, setIsMoving, setStartTouchX);
        }}>
        {props.children}
      </div>
      {right.map((item, index) => {
            return (<a key={` $ { prefixCls } - button - $ { index } `} onClick={e => {
                    handleSliderButtonClick(e, props, item, sliderContentRef);
                }} style={{ right: 70 * index }} className={ClassNames(` $ { prefixCls } - button `, item.style)}>
            <div className={` $ { prefixCls } - btn - text `}> {item.text}</div>
          </a>);
        })}
    </div>);
};
SwipeAction.defaultProps = defaultProps;
export default SwipeAction;
