Skip to content

Commit 34186d0

Browse files
authored
SortableList - Pass from and to indexes of changed item (#3153)
* on change sents from and to index of the change item * updated api * updated tests * changed type of swap object * changed from to to info object * changed api description
1 parent 9e1185b commit 34186d0

File tree

5 files changed

+13
-9
lines changed

5 files changed

+13
-9
lines changed

src/components/sortableList/SortableList.api.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
},
1717
{
1818
"name": "onOrderChange",
19-
"type": "(data: ItemT[]) => void",
20-
"description": "A callback to get the new order (or swapped items).",
19+
"type": "(data: ItemT[], info: OrderChangeInfo) => void",
20+
"description": "A callback to get the new order (or swapped items) and info about the change (from and to indices).",
2121
"required": true
2222
},
2323
{

src/components/sortableList/SortableListItem.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const SortableListItem = (props: Props) => {
5454
const id: string = data[index].id;
5555
const locked: boolean = data[index].locked;
5656
const initialIndex = useSharedValue<number>(map(data, 'id').indexOf(id));
57+
const lastSwap = useSharedValue({from: -1, to: -1});
5758
const currIndex = useSharedValue(initialIndex.value);
5859
const translation = useSharedValue<number>(0);
5960

@@ -102,6 +103,7 @@ const SortableListItem = (props: Props) => {
102103
.onStart(() => {
103104
isDragging.value = true;
104105
translation.value = getTranslationByIndexChange(currIndex.value, initialIndex.value, itemSize.value);
106+
lastSwap.value = {...lastSwap.value, from: currIndex.value};
105107
tempTranslation.value = translation.value;
106108
tempItemsOrder.value = itemsOrder.value;
107109
})
@@ -140,6 +142,7 @@ const SortableListItem = (props: Props) => {
140142
newItemsOrder[newIndex] = id;
141143
newItemsOrder[oldIndex] = itemIdToSwap;
142144
itemsOrder.value = newItemsOrder;
145+
lastSwap.value = {...lastSwap.value, to: newIndex};
143146
}
144147
}
145148
})
@@ -150,7 +153,7 @@ const SortableListItem = (props: Props) => {
150153

151154
translation.value = withTiming(tempTranslation.value + _translation, animationConfig, () => {
152155
if (tempItemsOrder.value.toString() !== itemsOrder.value.toString()) {
153-
runOnJS(onChange)();
156+
runOnJS(onChange)({...lastSwap.value});
154157
}
155158
});
156159
})

src/components/sortableList/__tests__/index.spec.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ describe('SortableList', () => {
5353
{id: '1', text: '1'},
5454
{id: '3', text: '3'},
5555
{id: '4', text: '4'}
56-
]);
56+
], {from: 1, to: 2});
5757
});
5858

5959
it('SortableList onOrderChange is called - up', async () => {
@@ -72,6 +72,6 @@ describe('SortableList', () => {
7272
{id: '1', text: '1'},
7373
{id: '2', text: '2'},
7474
{id: '3', text: '3'}
75-
]);
75+
], {from: 4, to: 1});
7676
});
7777
});

src/components/sortableList/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {LogService} from 'services';
88
import SortableListContext from './SortableListContext';
99
import SortableListItem, {DEFAULT_LIST_ITEM_SIZE} from './SortableListItem';
1010
import {useDidUpdate, useThemeProps} from 'hooks';
11-
import {SortableListProps, SortableListItemProps} from './types';
11+
import type {SortableListProps, SortableListItemProps, OrderChangeInfo} from './types';
1212
import type {Dictionary} from '../../typings/common';
1313

1414
export {SortableListProps, SortableListItemProps};
@@ -46,7 +46,7 @@ const SortableList = <ItemT extends SortableListItemProps>(props: SortableListPr
4646
itemsOrder.value = generateItemsOrder(data);
4747
}, [data]);
4848

49-
const onChange = useCallback(() => {
49+
const onChange = useCallback((info: OrderChangeInfo) => {
5050
const newData: ItemT[] = [];
5151
const dataByIds = mapKeys(data, 'id');
5252
if (data?.length) {
@@ -55,7 +55,7 @@ const SortableList = <ItemT extends SortableListItemProps>(props: SortableListPr
5555
});
5656
}
5757

58-
onOrderChange?.(newData);
58+
onOrderChange?.(newData, info);
5959
}, [onOrderChange, data]);
6060

6161
const onItemLayout = useCallback((event: LayoutChangeEvent) => {

src/components/sortableList/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface SortableListItemProps {
99

1010
// Internal
1111
export type Data<ItemT extends SortableListItemProps> = FlatListProps<ItemT>['data'];
12+
export type OrderChangeInfo = {from: number, to: number};
1213

1314
export interface SortableListProps<ItemT extends SortableListItemProps>
1415
extends Omit<FlatListProps<ItemT>, 'extraData' | 'data'>,
@@ -21,7 +22,7 @@ export interface SortableListProps<ItemT extends SortableListItemProps>
2122
/**
2223
* A callback to get the new order (or swapped items).
2324
*/
24-
onOrderChange: (data: ItemT[] /* TODO: add more data? */) => void;
25+
onOrderChange: (data: ItemT[], info: OrderChangeInfo /* TODO: add more data? */) => void;
2526
/**
2627
* Whether to enable the haptic feedback
2728
* (please note that react-native-haptic-feedback does not support the specific haptic type on Android starting on an unknown version, you can use 1.8.2 for it to work properly)

0 commit comments

Comments
 (0)