npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-swipe-list-view1

v1.0.1

Published

A ListView with rows that swipe open and closed.

Downloads

5

Readme

npm npm

react-native-swipe-list-view

💥🔥Breaking Changes in v1.0.0:🔥💥

SwipeListView now supports FlatList! (and SectionList)

Please see the section Migrating To FlatList for all details.

Migrating to SectionList is very similar. Please see example.js for a full usage example.

You can continue to use the (deprecated) ListView component, however there are some BREAKING CHANGES that are explained in that section as well


Use Case

  • 侧滑删除

<SwipeListView> is a ListView with rows that swipe open and closed. Handles default native behavior such as closing rows when ListView is scrolled or when other rows are opened.

Also includes <SwipeRow> if you want to use a swipeable row outside of the <SwipeListView>

Example

    

Try it out! https://snack.expo.io/@jemise111/react-native-swipe-list-view

(What's a Snack?)

Installation

npm install --save react-native-swipe-list-view

Running the example

The application under ./SwipeListExample will produce the above example. To run execute the following:

  • git clone https://github.com/jemise111/react-native-swipe-list-view.git
  • cd react-native-swipe-list-view
  • cd SwipeListExample
  • yarn
  • react-native run-ios | react-native run-android

Usage

import { SwipeListView } from 'react-native-swipe-list-view';

render() {
    return (
        <SwipeListView
            useFlatList
            data={this.state.listViewData}
            renderItem={ (data, rowMap) => (
                <View style={styles.rowFront}>
                    <Text>I am {data.item} in a SwipeListView</Text>
                </View>
            )}
            renderHiddenItem={ (data, rowMap) => (
                <View style={styles.rowBack}>
                    <Text>Left</Text>
                    <Text>Right</Text>
                </View>
            )}
            leftOpenValue={75}
            rightOpenValue={-75}
        />
    )
}

See example.js for full usage guide (including using <SwipeRow> by itself)

Note:

If your row is touchable (TouchableOpacity, TouchableHighlight, etc.) with an onPress function make sure renderItem returns the Touchable as the topmost element.

GOOD:

renderItem={ data => (
    <TouchableHighlight onPress={this.doSomething.bind(this)}>
        <View>
            <Text>I am {data.item} in a SwipeListView</Text>
        </View>
    </TouchableHighlight>
)}

BAD:

renderItem={ data => (
    <View>
        <TouchableHighlight onPress={this.doSomething.bind(this)}>
            <Text>I am {data.item} in a SwipeListView</Text>
        </TouchableHighlight>
    </View>
)}

Manually closing rows:

If your row or hidden row renders a touchable child and you'd like that touchable to close the row note that the renderItem and renderHiddenItem functions are passed rowData, rowMap. The rowMap is an object that looks like:

{
    row_key_1: ref_to_row_1,
    row_key_2: ref_to_row_2
}

Where each row_key is the same key used by the FlatList taken either from the key property on your data objects or using the keyExtractor prop.

Each row's ref has a public method called closeRow that will swipe the row closed. So you can do something like:

<SwipeListView
    renderHiddenItem={ (rowData, rowMap) => {
        <TouchableOpacity onPress={ _ => rowMap[rowData.item.key].closeRow() }>
            <Text>I close the row</Text>
        </TouchableOpacity>
    }}
/>

If you are using the standalone <SwipeRow> you can just keep a ref to the component and call closeRow() on that ref.

Per row behavior:

If you need rows to behave independently you can return a <SwipeRow> in the renderItem function. Make sure you import the <SwipeRow> in addition to the <SwipeListView>. See the example below and the docs under API for how to implement a custom <SwipeRow>. There is also a full example in example.js.

The following values can be dynamic by passing them as props on the <SwipeRow>:

  • leftOpenValue
  • rightOpenValue
  • stopLeftSwipe
  • stopRightSwipe
  • closeOnRowPress
  • disableLeftSwipe
  • disableRightSwipe
  • recalculateHiddenLayout
  • directionalDistanceChangeThreshold
import { SwipeListView, SwipeRow } from 'react-native-swipe-list-view';

<SwipeListView
    dataSource={dataSource.cloneWithRows(data)}
    renderItem={ (rowData, rowMap) => (
        <SwipeRow
            disableRightSwipe={parseInt(rowId) % 2 !== 0}
            disableLeftSwipe={parseInt(rowId) % 2 === 0}
            leftOpenValue={20 + parseInt(rowId) * 5}
            rightOpenValue={-150}
        >
            <View style={styles.rowBack}>
                <Text>Left Hidden</Text>
                <Text>Right Hidden</Text>
            </View>
            <View style={styles.rowFront}>
                <Text>Row front | {data.item.key}</Text>
            </View>
        </SwipeRow>
    )}
/>

Setting per row behavior using data

You can also customize your individual rows by passing in your row's data next props:

  • leftOpenValue
  • rightOpenValue
  • closeOnRowPress
  • disableLeftSwipe
  • disableRightSwipe
  • stopLeftSwipe
  • stopRightSwipe

Example:

const dataSource = [
    {
        name: 'Andy',
        age: 12,
        disableRightSwipe: true,
    },
    {
        name: 'Betty',
        age: 11,
        leftOpenValue: 150,
    },
    {
        name: 'Carl',
        age: 11,
    },
];

UI based on swipe values (the gmail effect)

class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            listViewData: Array(20).fill('').map((_,i) => ({key: `${i}`, text: `item #${i}`})),
        };

        this.rowSwipeAnimatedValues = {};
        Array(20).fill('').forEach((_, i) => {
            this.rowSwipeAnimatedValues[`${i}`] = new Animated.Value(0);
        });
    }

    onSwipeValueChange = (swipeData) => {
        const { key, value } = swipeData;
        this.rowSwipeAnimatedValues[key].setValue(Math.abs(value));
    }

    render() {
        return (
            <SwipeListView
                renderHiddenItem={ (data, rowMap) => (
                    <View style={styles.rowBack}>
                        <TouchableOpacity onPress={ _ => this.deleteRow(rowMap, data.item.key) }>
                            <Animated.View
                                style={[
                                    styles.trash,
                                    {

                                        transform: [
                                            {
                                                scale: this.rowSwipeAnimatedValues[data.item.key].interpolate({
                                                    inputRange: [45, 90],
                                                    outputRange: [0, 1],
                                                    extrapolate: 'clamp',
                                                }),
                                            }
                                        ],
                                    }
                                ]}
                            >
                                <Image source={require('./images/trash.png')} style={styles.trash} />
                            </Animated.View>
                        </TouchableOpacity>
                    </View>
                )}
                leftOpenValue={75}
                rightOpenValue={-150}
                ...

Migrating To FlatList

In most ways migrating your SwipeListView is no different than migrating your typical RN ListView (renderRow -> renderItem, renderHiddenRow -> renderHiddenItem). The biggest difference is the identifier used to keep track of row ref's. Previously this was done using a unique hash for each row that looked like ${secId}${rowId}. Now, since FlatList requires the use of a unique key for each piece of data, the SwipeListView uses this unique key to keep track of row refs in place of the unique hash.

The biggest breaking change you will find is the signature of certain callback functions used to pass the secId and rowId as two separate arguments, whereas now they will pass one argument, the row's unique key.

e.g.

onRowOpen(secId, rowId, rowMap) {
    // Grab reference to this row
    const rowRef = rowMap[`${secId}${rowId}`];

    // Do something with the row
    rowRef.closeRow();
}

would now look like:

onRowOpen(rowKey, rowMap, toValue) {
    // Grab reference to this row
    const rowRef = rowMap[rowKey];

    // Do something with the row
    rowRef.closeRow();
}

The other breaking change introduced is how to do a slideout preview. If you'd like to do a slide out preview for one of the rows simply use the new prop previewRowKey and pass the key corrseponding with that row.

Here is a typical migration example:

BEFORE:

<SwipeListView
    dataSource={this.ds.cloneWithRows(this.state.listViewData)}
    renderRow={ (data, secId, rowId, rowMap) => (
        <View>
            <Text>I am {data} in a SwipeListView</Text>
        </View>
    )}
    renderHiddenRow={ (data, secId, rowId, rowMap) => (
        <View style={styles.rowBack}>
            <TouchableOpacity onPress={ _ => rowMap[`${secId}${rowId}`].closeRow() }>
                <Text>Close</Text>
            </TouchableOpacity>
        </View>
    )}
    leftOpenValue={75}
    rightOpenValue={-150}
    onRowOpen={(secId, rowId, rowMap) => {
        setTimeout(() => {
            rowMap[`${secId}${rowId}`].closeRow()
        }, 2000)
    }}
    previewFirstRow={true}
/>

AFTER (Using FlatList):

<SwipeListView
    useFlatList={true}
    data={this.state.flatListData}
    renderItem={ (rowData, rowMap) => (
        <View>
            <Text>I am {rowData.item.text} in a SwipeListView</Text>
        </View>
    )}
    renderHiddenItem={ (rowData, rowMap) => (
        <View style={styles.rowBack}>
            <TouchableOpacity onPress={ _ => rowMap[rowData.item.key].closeRow() }>
                <Text>Close</Text>
            </TouchableOpacity>
        </View>
    )}
    leftOpenValue={75}
    rightOpenValue={-150}
    onRowOpen={(rowKey, rowMap) => {
        setTimeout(() => {
            rowMap[rowKey].closeRow()
        }, 2000)
    }}
    previewRowKey={this.state.flatListData[0].key}
/>

API

SwipeListView (component)

ListView that renders SwipeRows.

Props

useFlatList

Render list using React Native's FlatList

type: bool

defaultValue: false

useSectionList

Render list using React Native's SectionList

type: bool

defaultValue: false

closeOnRowPress

Should open rows be closed when a row is pressed

type: bool

defaultValue: true

closeOnScroll

Should open rows be closed when the listView begins scrolling(当按下一行时,关闭打开的行)

type: bool

defaultValue: true

closeOnRowBeginSwipe

Should open rows be closed when a row begins to swipe open(当行开始滑动打开时,关闭打开的行)

type: bool

defaultValue: false

closeOnRowOpen

Should open rows be closed when another row is opened(当其他行开始滑动打开时,关闭打开的行)

type: bool

defaultValue: true

directionalDistanceChangeThreshold

Change the sensitivity of the row

type: number

defaultValue: 2

leftOpenValue

TranslateX value for opening the row to the left (positive number)(左侧侧滑X的偏移量(正数))

type: number

defaultValue: 0

stopLeftSwipe

TranslateX value for stop the row to the left (positive number)

This number is the stop value corresponding to the leftOpenValue (while the row is swiping in the right direction)

type: number

stopRightSwipe

TranslateX value for stop the row to the right (negative number)

This number is the stop value corresponding to the rightOpenValue (while the row is swiping in the left direction)

type: number

renderHiddenItem

How to render a hidden row in a FlatList (renders behind the row). Should return a valid React Element. This is required unless renderItem returns a <SwipeRow> (see Per Row Behavior).

type: func

params: (rowData, rowMap)

renderItem

How to render a row in a FlatList. Should return a valid React Element.

type: func

params: (rowData, rowMap)

renderHiddenRow [DEPRECATED]

How to render a hidden row (renders behind the row). Should return a valid React Element. This is required unless renderRow returns a <SwipeRow> (see Per Row Behavior).

type: func

params: (rowData, secId, rowId, rowMap)

renderRow [DEPRECATED]

How to render a row. Should return a valid React Element.

type: func

params: (rowData, secId, rowId, rowMap)

rightOpenValue

TranslateX value for opening the row to the right (negative number)

type: number

defaultValue: 0

swipeToOpenPercent

What % of the left/right openValue does the user need to swipe past to trigger the row opening.

type: number

defaultValue: 50

swipeToOpenVelocityContribution

Describes how much the ending velocity of the gesture affects whether the swipe will result in the item being closed or open. A velocity factor of 0 (the default) means that the velocity will have no bearing on whether the swipe settles on a closed or open position and it'll just take into consideration the swipeToOpenPercent. Ideal values for this prop tend to be between 5 and 15.

type: number

defaultValue: 0

swipeToClosePercent

What % of the left/right openValue does the user need to swipe past to trigger the row closing.

type: number

defaultValue: 50

disableLeftSwipe

Disable ability to swipe the row left

type: bool

defaultValue: false

disableRightSwipe

Disable ability to swipe the row right

type: bool

defaultValue: false

recalculateHiddenLayout

Enable hidden row onLayout calculations to run always.

By default, hidden row size calculations are only done on the first onLayout event for performance reasons. Passing true here will cause calculations to run on every onLayout event. You may want to do this if your rows' sizes can change. One case is a SwipeListView with rows of different heights and an options to delete rows.

type: bool

defaultValue: false

swipeGestureBegan

Called when a swipe row is animating swipe

type: func

params: (rowKey)

onRowClose

Called when a swipe row is animating closed

type: func

params: (rowKey, rowMap)

onRowDidClose

Called when a swipe row has animated closed

type: func

params: (rowKey, rowMap)

onRowOpen

Called when a swipe row is animating open.

This has a param of toValue which is the new X value the row (after it has opened). This can be used to calculate which direction the row has been swiped open.

type: func

params: (rowKey, rowMap, toValue)

onRowDidOpen

Called when a swipe row has animated open

type: func

params: (rowKey, rowMap, toValue)

onScrollEnabled

Called when scrolling has been enabled/disabled

type: func

params: (isEnabled)

swipeRowStyle

Styles for the parent wrapper View of the SwipeRow

type: object

listViewRef

Called when the ListView ref is set and passes a ref to the ListView e.g. listViewRef={ ref => this._swipeListViewRef = ref }

type: func

params: (ref)

previewRowKey

Should the row with this key do a slide out preview to show that the list is swipeable

type: string

previewFirstRow [DEPRECATED]

Should the first SwipeRow do a slide out preview to show that the list is swipeable

type: bool

defaultValue: false

previewRowIndex [DEPRECATED]

Should the specified rowId do a slide out preview to show that the list is swipeable

  • Note: This ID will be passed to this function to get the correct row index
  • https://facebook.github.io/react-native/docs/listviewdatasource.html#getrowidforflatindex

type: number

previewDuration

Duration of the slide out preview animation

type: number

previewOpenValue

TranslateX value for the slide out preview animation Default: 0.5 * props.rightOpenValue

type: number

previewOpenDelay

Add some delay before opening the preview row. Can be Usefull when you have enter animation.

type: number

friction

Friction for the open / close animation.
Controls "bounciness"/overshoot.

type: number
defaultValue: 7

tension

Tension for the open / close animation.
Controls speed.

type: number
defaultValue: 40

More on friction and tension

onSwipeValueChange

Callback invoked any time the translateX value of a row changes

type: func

params: (swipeData)

where swipeData looks like:

{
    key: string,
    value: number,
    direction: 'left' | 'right',
    isOpen: bool
}

SwipeRow (component)

Row that is generally used in a SwipeListView. If you are rendering a SwipeRow explicitly you must pass the SwipeRow exactly two children. The first will be rendered behind the second. e.g.

<SwipeRow>
    <View style={hiddenRowStyle} />
    <View style={visibleRowStyle} />
</SwipeRow>

Props

closeOnRowPress

Should the row be closed when it is tapped

type: bool

defaultValue: true

directionalDistanceChangeThreshold

Change the sensitivity of the row

type: number

defaultValue: 2

friction

Friction for the open / close animation.
Controls "bounciness"/overshoot.

type: number
defaultValue: 7

leftOpenValue

TranslateX value for opening the row to the left (positive number)

type: number

defaultValue: 0

stopLeftSwipe

TranslateX value for stop the row to the left (positive number)

This number is the stop value corresponding to the leftOpenValue (while the row is swiping in the right direction)

type: number

stopRightSwipe

TranslateX value for stop the row to the right (negative number)

This number is the stop value corresponding to the rightOpenValue (while the row is swiping in the left direction)

type: number

onRowPress

Called when a swipe row is pressed.

type: func

params: ()

onRowOpen

Called when a swipe row is animating open. Used by the SwipeListView to keep references to open rows.

type: func

params: (toValue)

onRowClose

Called when a swipe row is animating closed

type: func

params: ()

rightOpenValue

TranslateX value for opening the row to the right (negative number)

type: number

defaultValue: 0

swipeToOpenPercent

What % of the left/right openValue does the user need to swipe past to trigger the row opening.

type: number

defaultValue: 50

swipeToClosePercent

What % of the left/right openValue does the user need to swipe past to trigger the row closing.

type: number

defaultValue: 50

setScrollEnabled

Used by the SwipeListView to close rows on scroll events. You shouldn't need to use this prop explicitly.

type: func

tension

Tension for the open / close animation

type: number

disableLeftSwipe

Disable ability to swipe the row left

type: bool

defaultValue: false

disableRightSwipe

Disable ability to swipe the row right

type: bool

defaultValue: false

recalculateHiddenLayout

Enable hidden row onLayout calculations to run always

type: bool

defaultValue: false

style

Styles for the parent wrapper View of the SwipeRow

type: object

preview

Should the row do a slide out preview to show that it is swipeable

type: bool

defaultValue: false

previewDuration

Duration of the slide out preview animation

type: number

defaultValue: 300

previewOpenValue

TranslateX value for the slide out preview animation Default: 0.5 * props.rightOpenValue

type: number

onSwipeValueChange

Callback invoked any time the translateX value of the row changes

type: func

params: (swipeData)

where swipeData looks like:

{
    value: number,
    direction: 'left' | 'right',
    isOpen: bool
}

Note: Core Support

RN Core added a SwipeList component as of v0.27.0

It is actively being worked on and has no documentation yet. So I will continue to maintain this component until a future date.

License

MIT