@@ -21,18 +21,29 @@ import { devWarning } from '../utils/dev-log';
21
21
import { noop } from '../utils' ;
22
22
import { getRect } from '../hooks/get-rect' ;
23
23
import useMountedRef from '../hooks/use-mounted-ref' ;
24
+ import { mergeFuncProps } from '../utils/with-func-props' ;
24
25
25
26
function modulus ( value : number , division : number ) {
26
27
const remainder = value % division ;
27
28
return remainder < 0 ? remainder + division : remainder ;
28
29
}
29
30
31
+ const eventToPropRecord = {
32
+ mousedown : 'onMouseDown' ,
33
+ mousemove : 'onMouseMove' ,
34
+ mouseup : 'onMouseUp' ,
35
+ } as const ;
36
+
37
+ let currentUid : undefined | { } ;
38
+
30
39
const Swiper = forwardRef < SwiperInstance , SwiperProps > ( ( props , ref ) => {
31
40
const { prefixCls, createNamespace } = useContext ( ConfigProviderContext ) ;
32
41
const [ bem ] = createNamespace ( 'swiper' , prefixCls ) ;
33
42
34
43
const { loop : outerLoop , autoplay, direction, autoplayInterval } = props ;
35
44
45
+ const [ uid ] = useState ( { } ) ;
46
+
36
47
const lock = useRef < boolean > ( false ) ;
37
48
const trackRef = useRef < HTMLDivElement > ( null ) ;
38
49
const [ root , setRoot ] = useState < HTMLDivElement > ( null ) ;
@@ -123,10 +134,24 @@ const Swiper = forwardRef<SwiperInstance, SwiperProps>((props, ref) => {
123
134
[ count ] ,
124
135
) ;
125
136
137
+ const dragCancelRef = useRef < ( ( ) => void ) | null > ( null ) ;
138
+ function forceCancelDrag ( ) {
139
+ dragCancelRef . current ?.( ) ;
140
+ draggingRef . current = false ;
141
+ }
142
+
126
143
const bind = useDrag (
127
144
( state ) => {
128
- if ( lock . current ) return ;
145
+ dragCancelRef . current = state . cancel ;
146
+ if ( ! state . intentional ) return ;
147
+ if ( state . first && ! currentUid ) {
148
+ currentUid = uid ;
149
+ }
150
+ if ( currentUid !== uid ) return ;
151
+ currentUid = state . last ? undefined : uid ;
129
152
const slidePixels = getSlidePixels ( ) ;
153
+
154
+ if ( lock . current ) return ;
130
155
if ( ! slidePixels ) return ;
131
156
const paramIndex = isVertical ? 1 : 0 ;
132
157
const offset = state . offset [ paramIndex ] ;
@@ -203,6 +228,7 @@ const Swiper = forwardRef<SwiperInstance, SwiperProps>((props, ref) => {
203
228
if ( draggingRef . current ) {
204
229
e . stopPropagation ( ) ;
205
230
}
231
+ forceCancelDrag ( ) ;
206
232
} ;
207
233
208
234
function swipeTo ( index : number , immediate = false ) {
@@ -260,6 +286,19 @@ const Swiper = forwardRef<SwiperInstance, SwiperProps>((props, ref) => {
260
286
devWarning ( 'Swiper' , '`Swiper` needs at least one child.' ) ;
261
287
}
262
288
289
+ const dragProps = { ...( props . allowTouchMove ? bind ( ) : { } ) } ;
290
+
291
+ const stopPropagationProps : Partial < Record < any , any > > = { } ;
292
+ props . stopPropagation . forEach ( key => {
293
+ const prop = eventToPropRecord [ key ] ;
294
+ stopPropagationProps [ prop ] = function ( e : Event ) {
295
+ e . stopPropagation ( ) ;
296
+ } ;
297
+ } )
298
+
299
+
300
+ const mergedProps = mergeFuncProps ( dragProps , stopPropagationProps ) ;
301
+
263
302
return (
264
303
< div
265
304
ref = { setRoot }
@@ -274,7 +313,7 @@ const Swiper = forwardRef<SwiperInstance, SwiperProps>((props, ref) => {
274
313
} ) ,
275
314
) }
276
315
onClickCapture = { onClickCapture }
277
- { ...( props . allowTouchMove ? bind ( ) : { } ) }
316
+ { ...mergedProps }
278
317
>
279
318
< div
280
319
className = { classnames (
@@ -318,6 +357,7 @@ Swiper.defaultProps = {
318
357
slideSize : 100 ,
319
358
stuckAtBoundary : false ,
320
359
trackOffset : 0 ,
360
+ stopPropagation : [ ] ,
321
361
} ;
322
362
323
363
Swiper . displayName = 'Swiper' ;
0 commit comments