diff --git a/README.md b/README.md index 3df726b..db02100 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,9 @@ A RefreshControl that works the same way as a ScrollView's refreshControl. - **renderRow** (function)
`({key, index, data, disabled, active}) => renderable`
Takes a row key, row index, data entry from the data source and its statuses disabled, active and should return a renderable component to be rendered as the row. The child component will receive a method called `toggleRowActive` (only if `manuallyActivateRows={true}`) to manually activate the row. Useful if you have multiple touch responders in your view.
+- **renderHeader?** (function)
+`() => renderable`
+Renders returned component at the top of the list. - **renderFooter?** (function)
`() => renderable`
Renders returned component at the bottom of the list. diff --git a/src/SortableList.js b/src/SortableList.js index 69e93a0..6c53748 100644 --- a/src/SortableList.js +++ b/src/SortableList.js @@ -29,6 +29,7 @@ export default class SortableList extends Component { manuallyActivateRows: PropTypes.bool, renderRow: PropTypes.func.isRequired, + renderHeader: PropTypes.func, renderFooter: PropTypes.func, onChangeOrder: PropTypes.func, @@ -76,6 +77,11 @@ export default class SortableList extends Component { }); }); + if (this.props.renderHeader && !this.props.horizontal) { + this._headerLayout = new Promise((resolve) => { + this._resolveHeaderLayout = resolve; + }); + } if (this.props.renderFooter && !this.props.horizontal) { this._footerLayout = new Promise((resolve) => { this._resolveFooterLayout = resolve; @@ -200,6 +206,7 @@ export default class SortableList extends Component { scrollEventThrottle={2} scrollEnabled={scrollEnabled} onScroll={this._onScroll}> + {this._renderHeader()} {this._renderRows()} @@ -266,6 +273,20 @@ export default class SortableList extends Component { }); } + _renderHeader() { + if (!this.props.renderHeader || this.props.horizontal) { + return null; + } + + const {headerLayout} = this.state; + + return ( + + {this.props.renderHeader()} + + ); + } + _renderFooter() { if (!this.props.renderFooter || this.props.horizontal) { return null; @@ -281,8 +302,8 @@ export default class SortableList extends Component { } _onUpdateLayouts() { - Promise.all([this._footerLayout, ...Object.values(this._rowsLayouts)]) - .then(([footerLayout, ...rowsLayouts]) => { + Promise.all([this._headerLayout, this._footerLayout, ...Object.values(this._rowsLayouts)]) + .then(([headerLayout, footerLayout, ...rowsLayouts]) => { // Can get correct container’s layout only after rows’s layouts. this._container.measure((x, y, width, height, pageX, pageY) => { const rowsLayoutsByKey = {}; @@ -298,6 +319,7 @@ export default class SortableList extends Component { this.setState({ containerLayout: {x, y, width, height, pageX, pageY}, rowsLayouts: rowsLayoutsByKey, + headerLayout, footerLayout, contentHeight, contentWidth, @@ -524,6 +546,10 @@ export default class SortableList extends Component { this._resolveRowLayout[rowKey]({rowKey, layout}); } + _onLayoutHeader = ({nativeEvent: {layout}}) => { + this._resolveHeaderLayout(layout); + }; + _onLayoutFooter = ({nativeEvent: {layout}}) => { this._resolveFooterLayout(layout); };