@@ -36,8 +36,8 @@ import {
36
36
import { defaultListItemLongPressDelay } from './params' ;
37
37
38
38
interface Shift {
39
- targetValue : number ;
40
- animatedValue : Animated . Value ;
39
+ targetValue : Position ;
40
+ animatedValue : Animated . ValueXY ;
41
41
}
42
42
43
43
interface ListItemPayload {
@@ -137,8 +137,8 @@ export const DraxList = <T extends unknown>(
137
137
itemMeasurements . push ( undefined ) ;
138
138
registrations . push ( undefined ) ;
139
139
shifts . push ( {
140
- targetValue : 0 ,
141
- animatedValue : new Animated . Value ( 0 ) ,
140
+ targetValue : { x : 0 , y : 0 } ,
141
+ animatedValue : new Animated . ValueXY ( { x : 0 , y : 0 } ) ,
142
142
} ) ;
143
143
}
144
144
}
@@ -171,14 +171,15 @@ export const DraxList = <T extends unknown>(
171
171
) ;
172
172
173
173
// Get shift transform for list item at index.
174
- const getShiftTransform = useCallback (
174
+ const getShiftTransformStyle = useCallback (
175
175
( index : number ) => {
176
- const shift = shiftsRef . current [ index ] ?. animatedValue ?? 0 ;
177
- return horizontal
178
- ? [ { translateX : shift } ]
179
- : [ { translateY : shift } ] ;
176
+ const shift = shiftsRef . current [ index ] ?. animatedValue ;
177
+ const transform = shift
178
+ ? [ { translateX : shift . x } , { translateY : shift . y } ]
179
+ : [ ] ;
180
+ return { transform } ;
180
181
} ,
181
- [ horizontal ] ,
182
+ [ ] ,
182
183
) ;
183
184
184
185
// Set the currently dragged list item.
@@ -210,7 +211,7 @@ export const DraxList = <T extends unknown>(
210
211
} = itemStyles ?? { } ;
211
212
return (
212
213
< DraxView
213
- style = { [ itemStyle , { transform : getShiftTransform ( originalIndex ) } ] }
214
+ style = { [ itemStyle , getShiftTransformStyle ( originalIndex ) ] }
214
215
draggingStyle = { draggingStyle }
215
216
dragReleasedStyle = { dragReleasedStyle }
216
217
{ ...otherStyleProps }
@@ -243,7 +244,7 @@ export const DraxList = <T extends unknown>(
243
244
originalIndexes ,
244
245
itemStyles ,
245
246
viewPropsExtractor ,
246
- getShiftTransform ,
247
+ getShiftTransformStyle ,
247
248
resetDraggedItem ,
248
249
itemsDraggable ,
249
250
renderItemContent ,
@@ -368,8 +369,8 @@ export const DraxList = <T extends unknown>(
368
369
( ) => {
369
370
shiftsRef . current . forEach ( ( shift ) => {
370
371
// eslint-disable-next-line no-param-reassign
371
- shift . targetValue = 0 ;
372
- shift . animatedValue . setValue ( 0 ) ;
372
+ shift . targetValue = { x : 0 , y : 0 } ;
373
+ shift . animatedValue . setValue ( { x : 0 , y : 0 } ) ;
373
374
} ) ;
374
375
} ,
375
376
[ ] ,
@@ -380,18 +381,36 @@ export const DraxList = <T extends unknown>(
380
381
(
381
382
{ index : fromIndex , originalIndex : fromOriginalIndex } : ListItemPayload ,
382
383
{ index : toIndex } : ListItemPayload ,
384
+ horizontalShift : boolean
383
385
) => {
386
+ const contentSize = contentSizeRef . current ;
384
387
const { width = 50 , height = 50 } = itemMeasurementsRef . current [ fromOriginalIndex ] ?? { } ;
385
- const offset = horizontal ? width : height ;
388
+ const posOffset = horizontalShift && contentSize && width < contentSize . x
389
+ ? { x : width , y : 0 }
390
+ : { x : 0 , y : height } ;
391
+ const negOffset = {
392
+ x : posOffset . x * - 1 ,
393
+ y : posOffset . y * - 1 ,
394
+ } ;
386
395
originalIndexes . forEach ( ( originalIndex , index ) => {
396
+ const { width : itemWidth = 0 , height : itemHeight = 0 } = itemMeasurementsRef . current [ originalIndex ] ?? { } ;
387
397
const shift = shiftsRef . current [ originalIndex ] ;
388
- let newTargetValue = 0 ;
398
+ if ( ! shift ) {
399
+ return ;
400
+ }
401
+ let newTargetValue = { x : 0 , y : 0 } ;
389
402
if ( index > fromIndex && index <= toIndex ) {
390
- newTargetValue = - offset ;
403
+ newTargetValue = negOffset ;
391
404
} else if ( index < fromIndex && index >= toIndex ) {
392
- newTargetValue = offset ;
405
+ newTargetValue = posOffset ;
406
+ }
407
+ // Keep from shifting full width items horizontally
408
+ if ( contentSize && itemWidth >= contentSize . x ) {
409
+ if ( ! itemHeight ) return ;
410
+ newTargetValue . x = 0 ;
393
411
}
394
- if ( shift . targetValue !== newTargetValue ) {
412
+ if ( itemHeight && ( shift . targetValue . x !== newTargetValue . x
413
+ || shift . targetValue . y !== newTargetValue . y ) ) {
395
414
shift . targetValue = newTargetValue ;
396
415
Animated . timing ( shift . animatedValue , {
397
416
duration : 200 ,
@@ -401,7 +420,7 @@ export const DraxList = <T extends unknown>(
401
420
}
402
421
} ) ;
403
422
} ,
404
- [ originalIndexes , horizontal ] ,
423
+ [ originalIndexes ] ,
405
424
) ;
406
425
407
426
// Calculate absolute position of list item for snapback.
@@ -573,7 +592,7 @@ export const DraxList = <T extends unknown>(
573
592
// Monitor drags to react with item shifts and auto-scrolling.
574
593
const onMonitorDragOver = useCallback (
575
594
( eventData : DraxMonitorEventData ) => {
576
- const { dragged, receiver, monitorOffsetRatio } = eventData ;
595
+ const { dragTranslation , dragged, receiver, monitorOffsetRatio } = eventData ;
577
596
// First, check if we need to shift items.
578
597
if ( reorderable && dragged . parentId === id ) {
579
598
// One of our list items is being dragged.
@@ -597,8 +616,10 @@ export const DraxList = <T extends unknown>(
597
616
draggedToIndex . current = toIndex ;
598
617
}
599
618
619
+ const horizontalShift = ( Math . abs ( dragTranslation . x ) > Math . abs ( dragTranslation . y ) )
620
+
600
621
// Update shift transforms for items in the list.
601
- updateShifts ( fromPayload , toPayload ?? fromPayload ) ;
622
+ updateShifts ( fromPayload , toPayload ?? fromPayload , horizontalShift ) ;
602
623
}
603
624
604
625
// Next, see if we need to auto-scroll.
0 commit comments