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"
mode
Two different item drop position indicators.default
shows position using background color below target item orexpands
that expands other items to show where item will be droppedstyle
container view style of FlatListdata
items for FlatList these have to implementItem
typerenderItem
function({item, move})
for rendering your item into FlatList. Callmove
to start item draggingonMoveEnd
called when item is moved into new position. Newitems
data is as argument.flyingItemStyle
style 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>
);
};