Skip to content

Commit 14c7d82

Browse files
MatiPl01Copilot
andauthored
feat: Reverse items stacking order (#535)
## Description This PR adds a possibility to reverse items stacking order (render items with lower index below items with higher index). ## Changes showcase https://github.com/user-attachments/assets/0be26017-7188-4c06-a36b-f2cc15b932a7 <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} stackingOrder='desc' /> </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> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent fb0be4e commit 14c7d82

File tree

6 files changed

+29
-5
lines changed

6 files changed

+29
-5
lines changed

packages/react-native-sortables/src/constants/props.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ export const DEFAULT_SHARED_PROPS = {
6262
showDropIndicator: false,
6363
snapOffsetX: '50%',
6464
snapOffsetY: '50%',
65-
sortEnabled: true
65+
sortEnabled: true,
66+
stackingOrder: 'asc'
6667
} satisfies DefaultSharedProps;
6768

6869
export const DEFAULT_SORTABLE_GRID_PROPS = {

packages/react-native-sortables/src/providers/shared/CommonValuesProvider.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
ItemDragSettings,
1818
ItemSizes,
1919
ItemsLayoutTransitionMode,
20+
ItemsStackingOrder,
2021
Vector
2122
} from '../../types';
2223
import { DragActivationState } from '../../types';
@@ -35,6 +36,7 @@ type CommonValuesProviderProps = PropsWithChildren<
3536
controlledContainerDimensions: ControlledDimensions;
3637
controlledItemDimensions: ControlledDimensions;
3738
itemsLayoutTransitionMode: ItemsLayoutTransitionMode;
39+
stackingOrder: ItemsStackingOrder;
3840
}
3941
>;
4042

@@ -59,7 +61,8 @@ const { CommonValuesContext, CommonValuesProvider, useCommonValuesContext } =
5961
itemsLayoutTransitionMode,
6062
snapOffsetX: _snapOffsetX,
6163
snapOffsetY: _snapOffsetY,
62-
sortEnabled: _sortEnabled
64+
sortEnabled: _sortEnabled,
65+
stackingOrder
6366
}) => {
6467
const { getKeys, subscribeKeys } = useItemsContext();
6568

@@ -165,6 +168,7 @@ const { CommonValuesContext, CommonValuesProvider, useCommonValuesContext } =
165168
inactiveItemOpacity,
166169
inactiveItemScale,
167170
indexToKey,
171+
isStackingOrderDesc: stackingOrder === 'desc',
168172
itemHeights,
169173
itemPositions,
170174
itemsLayoutTransitionMode,

packages/react-native-sortables/src/providers/shared/SharedProvider.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export type SharedProviderProps = PropsWithChildren<
4040
| 'itemsLayoutTransitionMode'
4141
| 'measureDebounceDelay'
4242
| 'sortEnabled'
43+
| 'stackingOrder'
4344
>
4445
> &
4546
Required<SortableCallbacks> & {

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

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

1318
return useDerivedValue<number>(() => {
1419
const itemCount = indexToKey.value.length;
@@ -17,7 +22,10 @@ export default function useItemZIndex(
1722
return 2 * itemCount + 1;
1823
}
1924

20-
const orderZIndex = keyToIndex.value[key] ?? 0;
25+
const realIndex = keyToIndex.value[key] ?? 0;
26+
const orderZIndex = isStackingOrderDesc
27+
? itemCount - realIndex - 1
28+
: realIndex;
2129

2230
if (activationAnimationProgress.value > 0) {
2331
if (prevActiveItemKey.value === key) {

packages/react-native-sortables/src/types/props/shared.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ export type Offset = `${number}%` | number;
5959
export type OverDrag = 'both' | 'horizontal' | 'none' | 'vertical';
6060
/** Position of the reordering trigger point */
6161
export type ReorderTriggerOrigin = 'center' | 'touch';
62+
/** Strategy for setting zIndex of items */
63+
export type ItemsStackingOrder = 'asc' | 'desc';
6264

6365
export type ItemDragSettings = AnimatableProps<{
6466
/** Delay in ms before drag gesture is activated */
@@ -337,6 +339,13 @@ export type SharedProps = Simplify<
337339
* @default true
338340
*/
339341
bringToFrontWhenActive: boolean;
342+
/**
343+
* Strategy for setting zIndex of items
344+
* - 'asc' - items with higher index have higher zIndex (default)
345+
* - 'desc' - items with higher index have lower zIndex
346+
* @default 'asc'
347+
*/
348+
stackingOrder: ItemsStackingOrder;
340349
}
341350
>
342351
>;

packages/react-native-sortables/src/types/providers/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export type CommonValuesContextType =
9696
shouldAnimateLayout: SharedValue<boolean>; // is set to false on web when the browser window is resized
9797
animateLayoutOnReorderOnly: SharedValue<boolean>;
9898
customHandle: boolean;
99+
isStackingOrderDesc: boolean;
99100
};
100101

101102
// MEASUREMENTS

0 commit comments

Comments
 (0)