Skip to content

Commit fb0be4e

Browse files
authored
fix: Add item zIndex preserving based on the order of items (#534)
## Description In the previous implementation, the zIndex was only changed for the active/previously active item. This was fine for most cases apart from these in which the items were implemented in such a way that they were overlapping each other. In this case, after changing the order of items, they were no longer overlapping properly (see recording in the section below). This PR sets `zIndex` based on the relative order of items so that the overlapping is preserved after the items are reordered. ## Changes showcase You can see that in the **Before** recording the previously active item stays above remaining ones (look at the red squares) | Before | After | |-|-| | <video src="https://github.com/user-attachments/assets/dd1749d3-99be-48b1-8d1a-eeffcea199e1" /> | <video src="https://github.com/user-attachments/assets/6f1d8a6b-c74d-44c3-9a49-3c66c74bfa98" /> | <details> <summary>Example source code</summary> ```tsx import { useCallback } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import type { SortableGridRenderItem } from 'react-native-sortables'; import Sortable from 'react-native-sortables'; import { ScrollScreen } from '@/components'; import { colors, radius, sizes, spacing, text } from '@/theme'; const DATA = Array.from({ length: 5 }, (_, index) => `Item ${index + 1}`); export default function PlaygroundExample() { const renderItem = useCallback<SortableGridRenderItem<string>>( ({ item }) => ( <View style={styles.card}> <Text style={styles.text}>{item}</Text> <View style={{ backgroundColor: 'red', height: 40, position: 'absolute', right: -20, top: -20, width: 40 }} /> </View> ), [] ); return ( <ScrollScreen contentContainerStyle={styles.container} includeNavBarHeight> <Sortable.Grid columnGap={10} columns={3} data={DATA} renderItem={renderItem} rowGap={10} /> </ScrollScreen> ); } const styles = StyleSheet.create({ card: { alignItems: 'center', backgroundColor: '#36877F', borderRadius: radius.md, height: sizes.xl, justifyContent: 'center' }, container: { padding: spacing.md }, text: { ...text.label2, color: colors.white } }); ``` </details>
1 parent ecc4512 commit fb0be4e

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

packages/react-native-sortables/src/providers/shared/hooks/useItemZIndex.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,26 @@ export default function useItemZIndex(
77
key: string,
88
activationAnimationProgress: SharedValue<number>
99
): SharedValue<number> {
10-
const { activeItemKey, prevActiveItemKey } = useCommonValuesContext();
10+
const { activeItemKey, indexToKey, keyToIndex, prevActiveItemKey } =
11+
useCommonValuesContext();
1112

1213
return useDerivedValue<number>(() => {
14+
const itemCount = indexToKey.value.length;
15+
1316
if (activeItemKey.value === key) {
14-
return 3;
15-
}
16-
if (prevActiveItemKey.value === key) {
17-
return 2;
17+
return 2 * itemCount + 1;
1818
}
19+
20+
const orderZIndex = keyToIndex.value[key] ?? 0;
21+
1922
if (activationAnimationProgress.value > 0) {
20-
return 1;
23+
if (prevActiveItemKey.value === key) {
24+
return 2 * itemCount;
25+
}
26+
27+
return itemCount + orderZIndex;
2128
}
22-
return 0;
29+
30+
return orderZIndex;
2331
});
2432
}

0 commit comments

Comments
 (0)