react-native-reorderable-list
Version:
Reorderable list for React Native applications, powered by Reanimated
212 lines (198 loc) • 7.17 kB
text/typescript
import type {
FlatListProps,
MatrixTransform,
PerspectiveTransform,
RotateTransform,
RotateXTransform,
RotateYTransform,
RotateZTransform,
ScaleTransform,
ScaleXTransform,
ScaleYTransform,
ScrollViewProps,
SkewXTransform,
SkewYTransform,
TranslateXTransform,
TranslateYTransform,
ViewStyle,
} from 'react-native';
import {PanGesture} from 'react-native-gesture-handler';
import {SharedValue, useAnimatedScrollHandler} from 'react-native-reanimated';
import {ItemLayoutAnimation, MaximumOneOf, SharedValueOrType} from './misc';
export interface ReorderableListReorderEvent {
/**
* Index of the dragged item.
*/
from: number;
/**
* Index where the dragged item was released.
*/
to: number;
}
export interface ReorderableListDragStartEvent {
/**
* Index of the dragged item.
*/
index: number;
}
export interface ReorderableListIndexChangeEvent {
/**
* Index of the dragged item.
*/
index: number;
}
export interface ReorderableListDragEndEvent {
/**
* Index of the dragged item.
*/
from: number;
/**
* Index where the dragged item was released.
*/
to: number;
}
type OmittedProps =
| 'horizontal'
| 'onScroll'
| 'scrollEventThrottle'
| 'removeClippedSubviews'
| 'CellRendererComponent'
| 'numColumns';
export interface ReorderableListProps<T>
extends Omit<FlatListProps<T>, OmittedProps> {
data: T[];
/**
* Threshold at the extremety of the list which 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 of the list will trigger autoscroll
* when an item is dragged to it. Min value: `0`. Max value: `0.4`. Default: `0.1`.
*/
autoscrollThreshold?: number;
/**
* Amount by which the threshold is offset at the extremety of the list.
* For example, setting `{top: 50}` will make the autoscroll trigger 50 pixels earlier at the top.
*/
autoscrollThresholdOffset?: {top?: number; bottom?: number};
/**
* Scales the autoscroll spreed at which the list scrolls when an item is dragged to the scroll areas. Default: `1`.
*/
autoscrollSpeedScale?: number;
/**
* Delay in between autoscroll triggers. Can be used to tune the autoscroll smoothness.
* Default Android: `0`.
* Default iOS: `100`.
*/
autoscrollDelay?: number;
/**
* Allows configuring the delta for autoscroll activation when dragging an item in the same direction as the autoscroll.
* This is particularly useful when an item is dragged within the autoscroll area to account for minor unintentional movements.
* Default: `5`.
*/
autoscrollActivationDelta?: number;
/**
* Duration of the animations in milliseconds.
* Be aware that users won't be able to drag a new item until the dragged item is released and
* its animation to its new position ends.
* Default: `200`.
*/
animationDuration?: number;
/**
* Allows passing an object with values and/or shared values that can animate a cell, for example by using the `onDragStart` and `onDragEnd` events. Supports view style properties. Override opacity and/or transform to disable the default animation, e.g. `{opacity: 1, transform: []}`.
*/
cellAnimations?: ReorderableListCellAnimations;
/**
* Whether dragging items is enabled. Default: `true`.
*/
dragEnabled?: boolean;
/**
* Whether the active item should be updated. Enables usage of `useIsActive` hook. Default: `false`.
*/
shouldUpdateActiveItem?: boolean;
/**
* Custom instance of pan gesture. See [GestureHandler docs](https://docs.swmansion.com/react-native-gesture-handler) for further info.
*/
panGesture?: PanGesture;
/**
* Whether the pan gestures necessary for dragging are enabled. Default: `true`.
*
* @deprecated In favor of `panGesture` prop.
*/
panEnabled?: boolean;
/**
* Duration in milliseconds of the long press on the list before the pan gesture for dragging is allowed to activate.
*
* @deprecated In favor of `panGesture` prop.
*/
panActivateAfterLongPress?: number;
/**
* Layout animation when the item is added to and/or removed from the view hierarchy. To skip entering or exiting animations use the LayoutAnimationConfig component from [Reanimated](https://docs.swmansion.com/react-native-reanimated).
*/
itemLayoutAnimation?: ItemLayoutAnimation;
/**
* Event fired after an item is released and the list is reordered.
*/
onReorder: (event: ReorderableListReorderEvent) => void;
/**
* An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
*/
onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
/**
* Event fired when an item is dragged. Needs to be a `worklet`. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
*/
onDragStart?: (event: ReorderableListDragStartEvent) => void;
/**
* Event fired when the dragged item is released. Needs to be a `worklet`. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
*/
onDragEnd?: (event: ReorderableListDragEndEvent) => void;
/**
* Event fired when the index of the dragged item changes. Needs to be a `worklet`. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
*/
onIndexChange?: (event: ReorderableListIndexChangeEvent) => void;
}
export type Transforms = PerspectiveTransform &
RotateTransform &
RotateXTransform &
RotateYTransform &
RotateZTransform &
ScaleTransform &
ScaleXTransform &
ScaleYTransform &
TranslateXTransform &
TranslateYTransform &
SkewXTransform &
SkewYTransform &
MatrixTransform;
export type ReorderableListCellAnimatedStyles = Omit<
{
[StyleKey in keyof ViewStyle]?:
| SharedValue<ViewStyle[StyleKey]>
| ViewStyle[StyleKey];
},
// omit custom type and type with JSDoc
'transform' | 'opacity'
>;
export interface ReorderableListCellAnimations
extends ReorderableListCellAnimatedStyles {
/**
* Transform animations for a dragged item.
* Disable default animation by overriding transform, e.g. `[]` or `[{ scale: customSharedValue }]`.
*/
transform?: Readonly<MaximumOneOf<SharedValueOrType<Transforms>>[]>;
/**
* Shared value to animate the opacity of a dragged item.
* Disable default animation by overriding opacity, e.g `1`.
*/
opacity?: SharedValue<number> | number;
}
export interface ScrollViewContainerProps
extends Omit<ScrollViewProps, 'onScroll'> {
/**
* An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
*/
onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
}
export interface NestedReorderableListProps<T> extends ReorderableListProps<T> {
/**
* Whether the nested list is scrollable or not. If the nested list has a fixed height and it's scrollable it should be set to `true`, otherwise `false`. Default: `false`.
*/
scrollable?: boolean;
}