Skip to content

Commit c4ea82d

Browse files
committed
update readme, tweak scroll logic
1 parent 867d4c0 commit c4ea82d

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
# React Native Draggable FlatList
22

3+
![Draggable FlatList demo](https://i.imgur.com/XmUcN4Z.gif)
4+
35
## Install
46

57
1. `npm install react-native-draggable-flatlist` or `yarn add react-native-draggable-flatlist`
68
2. `import DraggableFlatlist from 'react-native-draggable-flatlist'`
79

810
## Api
911

10-
### DraggableFlatList
11-
1212
Props:
13-
- `data` (Array)
13+
- `data` (Array) Items to be rendered.
1414
- `renderItem` (Function) `({ item, index, move, moveEnd, isActive }) => <Component />`. Call `move` when the row should become active (in an `onPress`, `onLongPress`, etc). Call `moveEnd` when the gesture is complete (in `onPressOut`).
1515
- `keyExtractor` (Function) `(item, index) => string`
1616
- `contentContainerStyle` (Object)
1717
- `scrollPercent` (Number) Sets where scrolling begins. A value of `5` will scroll up if the finger is in the top 5% of the FlatList container and scroll down in the bottom 5%.
18+
- `onMoveEnd` (Function) `({ data, to, from, row }) => void` Returns updated ordering of `data`
19+
- `onMoveBegin` (Function) `(index) => void` Called when row becomes active.
20+
1821

1922

2023
## Example
@@ -24,9 +27,12 @@ import React, { Component } from 'react'
2427
import { View, TouchableOpacity, Text } from 'react-native'
2528
import DraggableFlatList from 'react-native-draggable-flatlist'
2629

27-
const data = [1, 2, 3, 4, 5]
28-
2930
class Example extends Component {
31+
32+
state = {
33+
data: [0, 1, 2, 3, 4, 5]
34+
}
35+
3036
renderItem = ({ item, index, move, moveEnd, isActive }) => {
3137
return (
3238
<TouchableOpacity
@@ -43,11 +49,12 @@ class Example extends Component {
4349
return (
4450
<View style={{ flex: 1 }}>
4551
<DraggableFlatList
46-
data={data}
52+
data={this.state.data}
4753
renderItem={this.renderItem}
4854
keyExtractor={(item, index) => `draggable-item-${item}`}
4955
contentContainerStyle={{ padding: 10 }}
5056
scrollPercent={5}
57+
onMoveEnd={({ data }) => this.setState({ data })}
5158
/>
5259
</View>
5360
)

index.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ class SortableFlatList extends Component {
5858
}), false)
5959
this._androidStatusBarOffset = isTranslucent ? StatusBar.currentHeight : 0
6060
}
61-
6261
this._offset.setValue((this._additionalOffset + this._containerOffset - this._androidStatusBarOffset) * -1)
6362
return false
6463
},
@@ -67,7 +66,6 @@ class SortableFlatList extends Component {
6766
const shouldSet = activeRow > -1
6867
this._moveYAnim.setValue(gestureState.moveY)
6968
if (shouldSet) {
70-
this.props.onRowActive && this.props.onRowActive(activeRow)
7169
this.setState({ showHoverComponent: true })
7270
// Kick off recursive row animation
7371
this.animate()
@@ -88,7 +86,7 @@ class SortableFlatList extends Component {
8886
const activeMeasurements = this._measurements[activeRow]
8987
const spacerMeasurements = this._measurements[spacerIndex]
9088
const lastElementMeasurements = this._measurements[data.length - 1]
91-
const sortedData = this.getSortedList(this.props.data, activeRow, spacerIndex)
89+
const sortedData = this.getSortedList(data, activeRow, spacerIndex)
9290

9391
// If user flings row up and lets go in the middle of an animation measurements can error out.
9492
// Give layout animations some time to complete and animate element into place before calling onMoveEnd
@@ -114,7 +112,7 @@ class SortableFlatList extends Component {
114112
this.props.onMoveEnd && this.props.onMoveEnd({
115113
row: this.props.data[activeRow],
116114
from: activeRow,
117-
to: spacerIndex,
115+
to: spacerIndex - (isAfterActive ? 1 : 0),
118116
data: sortedData,
119117
})
120118
}))
@@ -138,7 +136,7 @@ class SortableFlatList extends Component {
138136

139137
animate = () => {
140138
const { activeRow } = this.state
141-
const { scrollPercent } = this.props
139+
const { scrollPercent, data } = this.props
142140
const scrollRatio = scrollPercent / 100
143141
if (activeRow === -1) return
144142
const nextSpacerIndex = this.getSpacerIndex(this._moveY, activeRow)
@@ -149,19 +147,22 @@ class SortableFlatList extends Component {
149147
}
150148

151149
// Scroll if hovering in top or bottom of container and have set a scroll %
150+
const isLastItem = activeRow === data.length - 1
151+
const isFirstItem = activeRow === 0
152152
const hoverItemTopPosition = Math.max(0, this._moveY - (this._additionalOffset + this._containerOffset))
153153
const hoverItemBottomPosition = Math.min(this._containerHeight, hoverItemTopPosition + this._measurements[activeRow].height)
154154
const fingerPosition = Math.max(0, this._moveY - this._containerOffset)
155-
const shouldScrollUp = fingerPosition < (this._containerHeight * scrollRatio)
156-
const shouldScrollDown = fingerPosition > (this._containerHeight * (1 - scrollRatio))
155+
const shouldScrollUp = !isFirstItem && fingerPosition < (this._containerHeight * scrollRatio)
156+
const shouldScrollDown = !isLastItem && fingerPosition > (this._containerHeight * (1 - scrollRatio))
157157
if (shouldScrollUp) this.scroll(-5, nextSpacerIndex)
158158
else if (shouldScrollDown) this.scroll(5, nextSpacerIndex)
159159

160160
requestAnimationFrame(this.animate)
161161
}
162162

163163
scroll = (scrollAmt, spacerIndex) => {
164-
if (spacerIndex > this.props.data.length - 1) return
164+
if (spacerIndex >= this.props.data.length) return this._flatList.scrollToEnd()
165+
if (spacerIndex === -1) return
165166
const currentScrollOffset = this._scrollOffset
166167
const newOffset = currentScrollOffset + scrollAmt
167168
const offset = Math.max(0, newOffset)

0 commit comments

Comments
 (0)