React Native FlatList component whose items can be drag into new positions. This component does NOT use React Native Reanimated or React Native Gesture Handler and that is why this works also on React Native Windows.
Tested on platforms: Windows, iOS, Web, (not yet Android)
Not tested in production.
Currently you have to copy files DraggableFlatList.tsx and DraggableItem.tsx into your typescript project. This repo is mainly example application project that contains these components.
"typescript": "^4.5.5"
"react": "17.0.2",
"react-native": "^0.65.0",
"react-native-windows": "0.65.8"
modeTwo different item drop position indicators.defaultshows position using background color below target item orexpandsthat expands other items to show where item will be droppedstylecontainer view style of FlatListdataitems for FlatList these have to implementItemtyperenderItemfunction({item, move})for rendering your item into FlatList. Callmoveto start item draggingonMoveEndcalled when item is moved into new position. Newitemsdata is as argument.flyingItemStylestyle for item that is under dragging and is flying on FlatList
type MyItem = DraggableFlatListItem & {
title?: string;
};
const App = () => {
const [data, setData] = useState<MyItem[]>(INITIAL_DATA);
// Item move done and new item array received
const handleMove = useCallback(
({ items }: { items: DraggableFlatListItem[] }) => {
setData(items);
},
[]
);
// Your custom FlatList item
const MyListItem = React.memo(
({ item, move }: { item: MyItem; move: (key: string) => void }) => {
// Long press fires 'move' to start item dragging
const handleLongPress = useCallback(() => {
move(item.key);
}, [move, item.key]);
return (
<TouchableOpacity
onLongPress={handleLongPress}
style={styles.itemContainer}
key={item.key}>
<Text style={styles.item}>{item.title}</Text>
</TouchableOpacity>
);
},
);
const renderItem = useCallback(
({ item, move }: { item: MyItem; move: (key: string) => void }) => {
return <MyListItem item={item} move={move} />;
},
[],
);
return (
<View style={styles.container}>
<View style={styles.header} />
<DraggableFlatList
mode={'expands'} // default or expands
style={styles.list}
data={data}
renderItem={renderItem}
onMoveEnd={handleMoveEnd}
itemHeight={50}
flyingItemStyle={styles.flying}
/>
<View style={styles.footer} />
</View>
);
};