SwipeableListViewDataSource({
      getRowData: (data, sectionID, rowID) => data[sectionID][rowID],
      getSectionHeaderData: (data, sectionID) => data[sectionID],
      rowHasChanged: (row1, row2) => row1 !== row2,
      sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
    });
  }

  static propTypes = {
    /**
     * To alert the user that swiping is possible, the first row can bounce
     * on component mount.
     */
    bounceFirstRowOnMount: PropTypes.bool.isRequired,
    /**
     * Use `SwipeableListView.getNewDataSource()` to get a data source to use,
     * then use it just like you would a normal ListView data source
     */
    dataSource: PropTypes.instanceOf(SwipeableListViewDataSource).isRequired,
    // Maximum distance to open to after a swipe
    maxSwipeDistance: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.func,
    ]).isRequired,
    // Callback method to render the swipeable view
    renderRow: PropTypes.func.isRequired,
    // Callback method to render the view that will be unveiled on swipe
    renderQuickActions: PropTypes.func.isRequired,
  };

  static defaultProps = {
    bounceFirstRowOnMount: false,
    renderQuickActions: () => null,
  };

  constructor(props: Props, context: any): void {
    super(props, context);

    this._shouldBounceFirstRowOnMount = this.props.bounceFirstRowOnMount;
    this.state = {
      dataSource: this.props.dataSource,
    };
  }

  componentWillReceiveProps(nextProps: Props): void {
    if (this.state.dataSource.getDataSource() !== nextProps.dataSource.getDataSource()) {
      this.setState({
        dataSource: nextProps.dataSource,
      });
    }
  }

  render(): React.Node {
    return (
      <ListView
        {...this.props}
        ref={(ref) => {
          this._listViewRef = ref;
        }}
        dataSource={this.state.dataSource.getDataSource()}
        onScroll={this._onScroll}
        renderRow={this._renderRow}
      />
    );
  }
A container component that renders multiple SwipeableRow's in a ListView
implementation. This is designed to be a drop-in replacement for the
standard React Native `ListView`, so use it as if it were a ListView, but
with extra props, i.e.

let ds = SwipeableListView.getNewDataSource();
ds.cloneWithRowsAndSections(dataBlob, ?sectionIDs, ?rowIDs);
// ..
<SwipeableListView renderRow={..} renderQuickActions={..} {..ListView props} />

SwipeableRow can be used independently of this component, but the main
benefit of using this component is

- It ensures that at most 1 row is swiped open (auto closes others)
- It can bounce the 1st row of the list so users know it's swipeable
- More to come