omahili / react-native-reorderable-list

A reorderable list for React Native applications, powered by Reanimated šŸš€
MIT License
120 stars 5 forks source link
dnd drag-and-drop flatlist list react react-native reanimated reanimated2 reorderable reorderable-list sortable sortable-list

React Native Reorderable List

A reorderable list for React Native applications, powered by Reanimated šŸš€

Playlist Example

Index

Install

Npm:

npm install --save react-native-reorderable-list

Yarn:

yarn add react-native-reorderable-list

Then you need to install these two peer dependencies:

Components

ReorderableList

This component uses a FlatList and it extends its props:

Props Type Required Default Description
autoscrollThreshold number No 0.1 Threshold at the extremity of the list that triggers autoscroll when an item is dragged to it. A value of 0.1 means that 10% of the area at the top and 10% at the bottom will trigger autoscroll. Min value: 0. Max value: 0.4.
autoscrollSpeedScale number No 1 Scales the autoscroll speed at which the list scrolls when an item is dragged to the scroll areas.
autoscrollDelay number No 0 (Android), 100 (iOS) Delay in between autoscroll triggers. Can be used to tune the autoscroll smoothness. Default values differ between platforms: 0 for Android and 100 for iOS.
dragReorderThreshold number No 0.2 Specifies the fraction of an item's size at which it will shift when a dragged item crosses over it. For example, 0.2 means the item shifts when the dragged item passes 20% of its height (in a vertical list).
animationDuration number No 200 Duration of the animations in milliseconds. Users won't be able to drag a new item until the dragged item is released and its animation to its new position ends.
onReorder (event: { from: number, to: number }) => void Yes N/A Event fired after an item is released and the list is reordered.
onScroll (event: NativeScrollEvent) => void No N/A Event fired at most once per frame during scrolling. Needs to be a worklet. See Reanimated docs for further info.

The following props from FlatList are not supported:

ReorderableListItem

This component allows you to animate the item when it's dragged. It currently supports two animations: scale and opacity. Using this component is optional.

Props Type Required Default Description
scaleAnimationConfig { enabled?: boolean, valueEnd?: number, valueStart?: number, easingEnd?: EasingFunction, easingStart?: EasingFunction, duration?: number } false { enabled: true, valueEnd: 1, valueStart: 1.025, easingStart: Easing.in(Easing.ease), easingEnd: Easing.out(Easing.ease), duration: 200 } Configures the scale animation of the reorderable item.
opacityAnimationConfig { enabled?: boolean, valueEnd?: number, valueStart?: number, easingEnd?: EasingFunction, easingStart?: EasingFunction, duration?: number } false { enabled: true, valueEnd: 1, valueStart: 0.75, easingStart: Easing.in(Easing.ease), easingEnd: Easing.out(Easing.ease), duration: 200, } Configures the opacity animation of the reorderable item.

Hooks

useReorderableDrag

This hook creates a function that triggers the drag of a list item. It's usually called on a long press event. This hook can only be used inside of a list item component.

Returns

useReorderableDragStart

This hook allows handling the drag start event of a list item. It receives a worklet callback that is called when the drag starts. It's recommended to wrap the handler function in a useCallback as follows: useReorderableDragStart(useCallback(...)). This hook can only be used inside of a list item component.

Parameters

useReorderableDragEnd**

This hook allows handling the drag end event of a list item. It receives a worklet callback that is called when the drag ends. It's recommended to wrap the handler function in a useCallback as follows: useReorderableDragEnd(useCallback(...)). This hook can only be used inside of a list item component.

Parameters

Utils

Example

Here is an example of how to use this component. More examples can be found in the example directory of the repository.

import React, {useState} from 'react';
import {ListRenderItemInfo, Pressable, StyleSheet, Text} from 'react-native';
import ReorderableList, {
  ReorderableListItem,
  ReorderableListReorderEvent,
  reorderItems,
  useReorderableDrag,
} from 'react-native-reorderable-list';

interface CardProps {
  id: string;
  color: string;
  height: number;
}

const list: CardProps[] = [
  {id: '0', color: 'red', height: 100},
  {id: '1', color: 'blue', height: 150},
  {id: '2', color: 'green', height: 80},
  {id: '3', color: 'violet', height: 100},
  {id: '4', color: 'orange', height: 120},
  {id: '5', color: 'coral', height: 100},
  {id: '6', color: 'purple', height: 110},
  {id: '7', color: 'chocolate', height: 80},
  {id: '8', color: 'crimson', height: 90},
  {id: '9', color: 'seagreen', height: 90},
];

const Card: React.FC<CardProps> = React.memo(({id, color, height}) => {
  const drag = useReorderableDrag();

  return (
    <ReorderableListItem>
      <Pressable style={[styles.card, {height}]} onLongPress={drag}>
        <Text style={[styles.text, {color}]}>Card {id}</Text>
      </Pressable>
    </ReorderableListItem>
  );
});

const App = () => {
  const [data, setData] = useState(list);

  const renderItem = ({item}: ListRenderItemInfo<CardProps>) => (
    <Card {...item} />
  );

  const handleReorder = ({from, to}: ReorderableListReorderEvent) => {
    const newData = reorderItems(data, from, to);
    setData(newData);
  };

  return (
    <ReorderableList
      data={data}
      onReorder={handleReorder}
      renderItem={renderItem}
      keyExtractor={item => item.id}
    />
  );
};

const styles = StyleSheet.create({
  card: {
    justifyContent: 'center',
    alignItems: 'center',
    margin: 6,
    borderRadius: 5,
    backgroundColor: 'white',
    borderWidth: 1,
    borderColor: '#ddd',
  },
  text: {
    fontSize: 20,
  },
});

export default App;

License

MIT


Made with create-react-native-library