1
1
import classNames from 'classnames'
2
2
import PropTypes , { InferProps } from 'prop-types'
3
3
import React from 'react'
4
+ import Taro from '@tarojs/taro'
4
5
import { Text , View , MovableArea , MovableView } from '@tarojs/components'
5
6
import { CommonEvent } from '@tarojs/components/types/common'
6
7
import {
7
8
AtSwipeActionProps ,
8
9
AtSwipeActionState ,
9
10
SwipeActionOption
10
11
} from '../../../types/swipe-action'
11
- import { uuid } from '../../common/utils'
12
+ import { uuid , delayGetClientRect } from '../../common/utils'
12
13
import AtSwipeActionOptions from './options/index'
13
14
14
15
export default class AtSwipeAction extends React . Component <
@@ -18,48 +19,86 @@ export default class AtSwipeAction extends React.Component<
18
19
public static defaultProps : AtSwipeActionProps
19
20
public static propTypes : InferProps < AtSwipeActionProps >
20
21
21
- private maxOffsetSize : number
22
22
private moveX : number
23
- private eleWidth : number
24
23
private moveRatio : number
25
24
26
25
public constructor ( props : AtSwipeActionProps ) {
27
26
super ( props )
28
- const { isOpened, maxDistance, areaWidth, moveRatio } = props
29
- this . maxOffsetSize = maxDistance
27
+ const { isOpened, moveRatio } = props
30
28
this . state = {
31
29
componentId : uuid ( ) ,
32
30
// eslint-disable-next-line no-extra-boolean-cast
33
- offsetSize : ! ! isOpened ? - this . maxOffsetSize : 0 ,
31
+ offsetSize : 0 ,
34
32
_isOpened : ! ! isOpened ,
35
- needAnimation : false
33
+ needAnimation : false ,
34
+ eleWidth : 0 ,
35
+ maxOffsetSize : 0
36
36
}
37
37
this . moveX = this . state . offsetSize
38
- this . eleWidth = areaWidth
39
38
this . moveRatio = moveRatio || 0.5
40
39
}
41
40
41
+ public componentDidMount ( ) : void {
42
+ this . getAreaWidth ( )
43
+ }
44
+
45
+ // 当 eleWidth 发生变化时,需要重新计算 maxOffsetSize
46
+ public componentDidUpdate ( _ , prevState : AtSwipeActionState ) : void {
47
+ const { eleWidth } = this . state
48
+ if ( prevState . eleWidth !== eleWidth ) {
49
+ this . getMaxOffsetSize ( )
50
+ }
51
+ }
52
+
42
53
public UNSAFE_componentWillReceiveProps ( nextProps : AtSwipeActionProps ) : void {
43
54
const { isOpened } = nextProps
44
- const { _isOpened } = this . state
55
+ const { _isOpened, maxOffsetSize } = this . state
45
56
46
57
if ( isOpened !== _isOpened ) {
47
- this . moveX = isOpened ? 0 : this . maxOffsetSize
58
+ this . moveX = isOpened ? 0 : maxOffsetSize
48
59
this . _reset ( ! ! isOpened ) // TODO: Check behavior
49
60
}
50
61
}
51
62
63
+ /**
64
+ * 获取滑动区域宽度
65
+ */
66
+ private async getAreaWidth ( ) : Promise < void > {
67
+ const systemInfo = await Taro . getSystemInfo ( )
68
+ this . setState ( {
69
+ eleWidth : systemInfo . windowWidth
70
+ } )
71
+ }
72
+
73
+ /**
74
+ * 获取最大偏移量
75
+ */
76
+ private async getMaxOffsetSize ( ) : Promise < void > {
77
+ const { componentId } = this . state
78
+
79
+ const actionOptionsRect = await delayGetClientRect ( {
80
+ selectorStr : `#swipeActionOptions-${ componentId } `
81
+ } )
82
+
83
+ const maxOffsetSize = actionOptionsRect [ 0 ] . width
84
+
85
+ this . setState ( {
86
+ maxOffsetSize
87
+ } )
88
+ }
89
+
52
90
private _reset ( isOpened : boolean ) : void {
53
91
if ( isOpened ) {
92
+ const { maxOffsetSize } = this . state
54
93
if ( process . env . TARO_ENV === 'jd' ) {
55
94
this . setState ( {
56
95
_isOpened : true ,
57
- offsetSize : - this . maxOffsetSize + 0.01
96
+ offsetSize : - maxOffsetSize + 0.01
58
97
} )
59
98
} else {
60
99
this . setState ( {
61
100
_isOpened : true ,
62
- offsetSize : - this . maxOffsetSize
101
+ offsetSize : - maxOffsetSize
63
102
} )
64
103
}
65
104
} else {
@@ -108,7 +147,8 @@ export default class AtSwipeAction extends React.Component<
108
147
}
109
148
110
149
onTouchEnd = e => {
111
- if ( this . moveX === - this . maxOffsetSize ) {
150
+ const { maxOffsetSize } = this . state
151
+ if ( this . moveX === - maxOffsetSize ) {
112
152
this . _reset ( true )
113
153
this . handleOpened ( e )
114
154
return
@@ -123,7 +163,7 @@ export default class AtSwipeAction extends React.Component<
123
163
this . handleClosed ( e )
124
164
return
125
165
}
126
- if ( Math . abs ( this . moveX ) < this . maxOffsetSize * this . moveRatio ) {
166
+ if ( Math . abs ( this . moveX ) < maxOffsetSize * this . moveRatio ) {
127
167
this . _reset ( false )
128
168
this . handleClosed ( e )
129
169
} else {
@@ -137,7 +177,8 @@ export default class AtSwipeAction extends React.Component<
137
177
}
138
178
139
179
public render ( ) : JSX . Element {
140
- const { componentId, offsetSize } = this . state
180
+ const { componentId, maxOffsetSize, eleWidth, offsetSize } = this . state
181
+
141
182
const { options, disabled } = this . props
142
183
const rootClass = classNames ( 'at-swipe-action' , this . props . className )
143
184
@@ -146,14 +187,13 @@ export default class AtSwipeAction extends React.Component<
146
187
id = { `swipeAction-${ componentId } ` }
147
188
className = { rootClass }
148
189
style = { {
149
- width : `${ this . eleWidth } px`
190
+ width : `${ eleWidth } px`
150
191
} }
151
192
>
152
193
< MovableArea
153
194
className = 'at-swipe-action__area'
154
195
style = { {
155
- width : `${ this . eleWidth + this . maxOffsetSize } px` ,
156
- transform : `translate(-${ this . maxOffsetSize } px, 0)`
196
+ width : `${ eleWidth } px`
157
197
} }
158
198
>
159
199
< MovableView
@@ -165,8 +205,7 @@ export default class AtSwipeAction extends React.Component<
165
205
onChange = { this . onChange }
166
206
disabled = { disabled }
167
207
style = { {
168
- width : `${ this . eleWidth } px` ,
169
- left : `${ this . maxOffsetSize } px`
208
+ width : `${ eleWidth + maxOffsetSize } px`
170
209
} }
171
210
>
172
211
{ this . props . children }
@@ -175,8 +214,7 @@ export default class AtSwipeAction extends React.Component<
175
214
options = { options }
176
215
componentId = { componentId }
177
216
customStyle = { {
178
- transform : `translate(${ this . maxOffsetSize } px, 0)` ,
179
- opacity : 1
217
+ opacity : maxOffsetSize ? 1 : 0
180
218
} }
181
219
>
182
220
{ options . map ( ( item , key ) => (
0 commit comments