11import classNames from 'classnames'
2- import _inRange from 'lodash/inRange'
3- import _isEmpty from 'lodash/isEmpty'
42import PropTypes , { InferProps } from 'prop-types'
53import React from 'react'
6- import { Text , View } from '@tarojs/components'
7- import { CommonEvent , ITouchEvent } from '@tarojs/components/types/common'
4+ import { Text , View , MovableArea , MovableView } from '@tarojs/components'
5+ import { CommonEvent } from '@tarojs/components/types/common'
86import {
97 AtSwipeActionProps ,
108 AtSwipeActionState ,
119 SwipeActionOption
1210} from '../../../types/swipe-action'
13- import {
14- delayGetClientRect ,
15- delayGetScrollOffset ,
16- uuid
17- } from '../../common/utils'
11+ import { uuid } from '../../common/utils'
1812import AtSwipeActionOptions from './options/index'
1913
2014export default class AtSwipeAction extends React . Component <
@@ -24,48 +18,22 @@ export default class AtSwipeAction extends React.Component<
2418 public static defaultProps : AtSwipeActionProps
2519 public static propTypes : InferProps < AtSwipeActionProps >
2620
27- private endValue : number
28- private startX : number
29- private startY : number
3021 private maxOffsetSize : number
31- private domInfo : any
32- private isMoving : boolean
33- private isTouching : boolean
22+ private moveX : number
23+ private eleWidth : number
3424
3525 public constructor ( props : AtSwipeActionProps ) {
3626 super ( props )
37- const { isOpened } = props
38- this . endValue = 0
39- this . startX = 0
40- this . startY = 0
41- this . maxOffsetSize = 0
42- this . domInfo = {
43- top : 0 ,
44- bottom : 0 ,
45- left : 0 ,
46- right : 0
47- }
48- this . isMoving = false
49- this . isTouching = false
27+ const { isOpened, maxDistance, areaWidth } = props
28+ this . maxOffsetSize = maxDistance
5029 this . state = {
5130 componentId : uuid ( ) ,
5231 offsetSize : 0 ,
53- _isOpened : ! ! isOpened
32+ _isOpened : ! ! isOpened ,
33+ needAnimation : false
5434 }
55- }
56-
57- private getDomInfo ( ) : Promise < void > {
58- return Promise . all ( [
59- delayGetClientRect ( {
60- delayTime : 0 ,
61- selectorStr : `#swipeAction-${ this . state . componentId } `
62- } ) ,
63- delayGetScrollOffset ( { delayTime : 0 } )
64- ] ) . then ( ( [ rect , scrollOffset ] ) => {
65- rect [ 0 ] . top += scrollOffset [ 0 ] . scrollTop
66- rect [ 0 ] . bottom += scrollOffset [ 0 ] . scrollTop
67- this . domInfo = rect [ 0 ]
68- } )
35+ this . moveX = 0
36+ this . eleWidth = areaWidth
6937 }
7038
7139 public UNSAFE_componentWillReceiveProps ( nextProps : AtSwipeActionProps ) : void {
@@ -78,118 +46,40 @@ export default class AtSwipeAction extends React.Component<
7846 }
7947
8048 private _reset ( isOpened : boolean ) : void {
81- this . isMoving = false
82- this . isTouching = false
83-
8449 if ( isOpened ) {
85- this . endValue = - this . maxOffsetSize
8650 this . setState ( {
8751 _isOpened : true ,
88- offsetSize : - this . maxOffsetSize
52+ offsetSize : 0
8953 } )
9054 } else {
91- this . endValue = 0
92- this . setState ( {
93- offsetSize : 0 ,
94- _isOpened : false
95- } )
55+ this . setState (
56+ {
57+ offsetSize : this . moveX
58+ } ,
59+ ( ) => {
60+ this . setState ( {
61+ offsetSize : this . maxOffsetSize ,
62+ _isOpened : false
63+ } )
64+ }
65+ )
9666 }
9767 }
9868
99- private computeTransform = ( value : number ) : string | null =>
100- // if (Taro.getEnv() === Taro.ENV_TYPE.ALIPAY) {
101- // return !_isNil(value) ? `translate3d(${value}px,0,0)` : null
102- // }
103- value ? `translate3d(${ value } px,0,0)` : null
104-
10569 private handleOpened = ( event : CommonEvent ) : void => {
10670 const { onOpened } = this . props
107- if ( typeof onOpened === 'function' && this . state . _isOpened ) {
71+ if ( typeof onOpened === 'function' ) {
10872 onOpened ( event )
10973 }
11074 }
11175
11276 private handleClosed = ( event : CommonEvent ) : void => {
11377 const { onClosed } = this . props
114- if ( typeof onClosed === 'function' && ! this . state . _isOpened ) {
78+ if ( typeof onClosed === 'function' ) {
11579 onClosed ( event )
11680 }
11781 }
11882
119- private handleTouchStart = ( e : ITouchEvent ) : void => {
120- const { clientX, clientY } = e . touches [ 0 ]
121-
122- if ( this . props . disabled ) return
123-
124- this . getDomInfo ( )
125-
126- this . startX = clientX
127- this . startY = clientY
128- this . isTouching = true
129- }
130-
131- private handleTouchMove = ( e : ITouchEvent ) : void => {
132- if ( _isEmpty ( this . domInfo ) ) {
133- return
134- }
135-
136- const { startX, startY } = this
137- const { top, bottom, left, right } = this . domInfo
138- const { clientX, clientY, pageX, pageY } = e . touches [ 0 ]
139-
140- const x = Math . abs ( clientX - startX )
141- const y = Math . abs ( clientY - startY )
142-
143- const inDom = _inRange ( pageX , left , right ) && _inRange ( pageY , top , bottom )
144-
145- if ( ! this . isMoving && inDom ) {
146- this . isMoving =
147- y === 0 ||
148- x / y >= Number . parseFloat ( Math . tan ( ( 45 * Math . PI ) / 180 ) . toFixed ( 2 ) )
149- }
150-
151- if ( this . isTouching && this . isMoving ) {
152- e . preventDefault ( )
153-
154- const offsetSize = clientX - this . startX
155- const isRight = offsetSize > 0
156-
157- if ( this . state . offsetSize === 0 && isRight ) return
158-
159- const value = this . endValue + offsetSize
160- this . setState ( {
161- offsetSize : value >= 0 ? 0 : value
162- } )
163- }
164- }
165-
166- private handleTouchEnd = ( event : ITouchEvent ) : void => {
167- this . isTouching = false
168-
169- const { offsetSize } = this . state
170-
171- this . endValue = offsetSize
172-
173- const breakpoint = this . maxOffsetSize / 2
174- const absOffsetSize = Math . abs ( offsetSize )
175-
176- if ( absOffsetSize > breakpoint ) {
177- this . _reset ( true )
178- this . handleOpened ( event )
179- return
180- }
181-
182- this . _reset ( false ) // TODO: Check behavior
183- this . handleClosed ( event )
184- }
185-
186- private handleDomInfo = ( { width } : { width : number } ) : void => {
187- const { _isOpened } = this . state
188-
189- this . maxOffsetSize = width
190- this . _reset ( _isOpened )
191- }
192-
19383 private handleClick = (
19484 item : SwipeActionOption ,
19585 index : number ,
@@ -206,51 +96,93 @@ export default class AtSwipeAction extends React.Component<
20696 }
20797 }
20898
99+ onTouchEnd = e => {
100+ if ( this . moveX === 0 ) {
101+ this . _reset ( true )
102+ this . handleOpened ( e )
103+ return
104+ }
105+ if ( this . moveX === this . maxOffsetSize ) {
106+ this . _reset ( false )
107+ this . handleClosed ( e )
108+ return
109+ }
110+ if ( this . state . _isOpened && this . moveX > 0 ) {
111+ this . _reset ( false )
112+ this . handleClosed ( e )
113+ return
114+ }
115+ if ( this . maxOffsetSize - this . moveX < this . maxOffsetSize * 0.4 ) {
116+ this . _reset ( false )
117+ this . handleClosed ( e )
118+ } else {
119+ this . _reset ( true )
120+ this . handleOpened ( e )
121+ }
122+ }
123+
124+ onChange = e => {
125+ this . moveX = e . detail . x
126+ }
127+
209128 public render ( ) : JSX . Element {
210- const { offsetSize , componentId } = this . state
129+ const { componentId , offsetSize } = this . state
211130 const { options } = this . props
212131 const rootClass = classNames ( 'at-swipe-action' , this . props . className )
213- const transform = this . computeTransform ( offsetSize )
214- const transformStyle : React . CSSProperties = transform ? { transform } : { }
215132
216133 return (
217134 < View
218135 id = { `swipeAction-${ componentId } ` }
219136 className = { rootClass }
220- onTouchMove = { this . handleTouchMove }
221- onTouchEnd = { this . handleTouchEnd }
222- onTouchStart = { this . handleTouchStart }
137+ style = { {
138+ width : ` $ {this . eleWidth } px`
139+ } }
223140 >
224- < View
225- className = { classNames ( 'at-swipe-action__content' , {
226- animtion : ! this . isTouching
227- } ) }
228- style = { transformStyle }
141+ < MovableArea
142+ className = 'at-swipe-action__area'
143+ style = { {
144+ width : `${ this . eleWidth + this . maxOffsetSize } px` ,
145+ transform : `translate(-${ this . maxOffsetSize } px, 0)`
146+ } }
229147 >
230- { this . props . children }
231- </ View >
232-
233- { Array . isArray ( options ) && options . length > 0 ? (
234- < AtSwipeActionOptions
235- options = { options }
236- componentId = { componentId }
237- onQueryedDom = { this . handleDomInfo }
148+ < MovableView
149+ className = 'at-swipe-action__content'
150+ direction = 'horizontal'
151+ damping = { 50 }
152+ x = { offsetSize }
153+ onTouchEnd = { this . onTouchEnd }
154+ onChange = { this . onChange }
155+ style = { {
156+ width : `${ this . eleWidth } px`
157+ } }
238158 >
239- { options . map ( ( item , key ) => (
240- < View
241- key = { ` ${ item . text } - ${ key } ` }
242- style = { item . style }
243- onClick = { ( e ) : void => this . handleClick ( item , key , e ) }
244- className = { classNames (
245- 'at-swipe-action__option' ,
246- item . className
247- ) }
159+ { this . props . children }
160+ { Array . isArray ( options ) && options . length > 0 ? (
161+ < AtSwipeActionOptions
162+ options = { options }
163+ componentId = { componentId }
164+ customStyle = { {
165+ transform : `translate( ${ this . maxOffsetSize } px, 0)` ,
166+ opacity : 1
167+ } }
248168 >
249- < Text className = 'option__text' > { item . text } </ Text >
250- </ View >
251- ) ) }
252- </ AtSwipeActionOptions >
253- ) : null }
169+ { options . map ( ( item , key ) => (
170+ < View
171+ key = { `${ item . text } -${ key } ` }
172+ style = { item . style }
173+ onClick = { ( e ) : void => this . handleClick ( item , key , e ) }
174+ className = { classNames (
175+ 'at-swipe-action__option' ,
176+ item . className
177+ ) }
178+ >
179+ < Text className = 'option__text' > { item . text } </ Text >
180+ </ View >
181+ ) ) }
182+ </ AtSwipeActionOptions >
183+ ) : null }
184+ </ MovableView >
185+ </ MovableArea >
254186 </ View >
255187 )
256188 }
@@ -260,7 +192,9 @@ AtSwipeAction.defaultProps = {
260192 options : [ ] ,
261193 isOpened : false ,
262194 disabled : false ,
263- autoClose : false
195+ autoClose : false ,
196+ maxDistance : 0 ,
197+ areaWidth : 0
264198}
265199
266200AtSwipeAction . propTypes = {
0 commit comments