UNPKG

recyclerlistview

Version:

The listview that you need and deserve. It was built for performance, uses cell recycling to achieve smooth scrolling.

232 lines 12.8 kB
"use strict"; /** * Created by ananya.chandra on 14/09/18. */ var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var PropTypes = require("prop-types"); var react_native_1 = require("react-native"); var StickyHeader_1 = require("./sticky/StickyHeader"); var StickyFooter_1 = require("./sticky/StickyFooter"); var CustomError_1 = require("./exceptions/CustomError"); var RecyclerListViewExceptions_1 = require("./exceptions/RecyclerListViewExceptions"); var ComponentCompat_1 = require("../utils/ComponentCompat"); // Constant to check if React version is 19 or higher var isReact19OrHigher = (function () { // Check React version by examining React.version if available if (React.version) { var majorVersion = parseInt(React.version.split(".")[0], 10); return majorVersion >= 19; } return false; })(); var StickyContainer = /** @class */ (function (_super) { __extends(StickyContainer, _super); function StickyContainer(props, context) { var _this = _super.call(this, props, context) || this; _this._recyclerRef = undefined; _this._stickyHeaderRef = null; _this._stickyFooterRef = null; _this._visibleIndicesAll = []; _this._windowCorrection = { startCorrection: 0, endCorrection: 0, windowShift: 0, }; _this._rlvRowRenderer = function (type, data, index, extendedState) { if (_this.props.alwaysStickyFooter) { var rlvDimension = _this._getRLVRenderedSize(); var contentDimension = _this._getContentDimension(); var isScrollable = false; if (rlvDimension && contentDimension) { isScrollable = contentDimension.height > rlvDimension.height; } if (!isScrollable && _this.props.stickyFooterIndices && index === _this.props.stickyFooterIndices[0]) { return null; } } return _this._rowRenderer(type, data, index, extendedState); }; _this._getRecyclerRef = function (recycler) { _this._recyclerRef = recycler; var childRef = isReact19OrHigher ? _this.props.children.props.ref : _this.props.children.ref; if (childRef) { if (typeof childRef === "function") { childRef(recycler); } else { throw new CustomError_1.default(RecyclerListViewExceptions_1.default.refNotAsFunctionException); } } }; _this._getCurrentWindowCorrection = function () { return _this._windowCorrection; }; _this._getStickyHeaderRef = function (stickyHeaderRef) { if (_this._stickyHeaderRef !== stickyHeaderRef) { _this._stickyHeaderRef = stickyHeaderRef; // TODO: Resetting state once ref is initialized. Can look for better solution. _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); } }; _this._getStickyFooterRef = function (stickyFooterRef) { if (_this._stickyFooterRef !== stickyFooterRef) { _this._stickyFooterRef = stickyFooterRef; // TODO: Resetting state once ref is initialized. Can look for better solution. _this._callStickyObjectsOnVisibleIndicesChanged(_this._visibleIndicesAll); } }; _this._onVisibleIndicesChanged = function (all, now, notNow) { _this._visibleIndicesAll = all; _this._callStickyObjectsOnVisibleIndicesChanged(all); if (_this.props.children && _this.props.children.props && _this.props.children.props.onVisibleIndicesChanged) { _this.props.children.props.onVisibleIndicesChanged(all, now, notNow); } }; _this._callStickyObjectsOnVisibleIndicesChanged = function (all) { if (_this._stickyHeaderRef) { _this._stickyHeaderRef.onVisibleIndicesChanged(all); } if (_this._stickyFooterRef) { _this._stickyFooterRef.onVisibleIndicesChanged(all); } }; _this._onScroll = function (rawEvent, offsetX, offsetY) { _this._getWindowCorrection(offsetX, offsetY, _this.props); if (_this._stickyHeaderRef) { _this._stickyHeaderRef.onScroll(offsetY); } if (_this._stickyFooterRef) { _this._stickyFooterRef.onScroll(offsetY); } if (_this.props.children && _this.props.children.props.onScroll) { _this.props.children.props.onScroll(rawEvent, offsetX, offsetY); } }; _this._assertChildType = function () { if (React.Children.count(_this.props.children) !== 1 || !_this._isChildRecyclerInstance()) { throw new CustomError_1.default(RecyclerListViewExceptions_1.default.wrongStickyChildTypeException); } }; _this._isChildRecyclerInstance = function () { return (_this.props.children.props.dataProvider && _this.props.children.props.rowRenderer && _this.props.children.props.layoutProvider); }; _this._getLayoutForIndex = function (index) { if (_this._recyclerRef) { return _this._recyclerRef.getLayout(index); } return undefined; }; _this._getDataForIndex = function (index) { return _this._dataProvider.getDataForIndex(index); }; _this._getLayoutTypeForIndex = function (index) { return _this._layoutProvider.getLayoutTypeForIndex(index); }; _this._getExtendedState = function () { return _this._extendedState; }; _this._getRowRenderer = function () { return _this._rowRenderer; }; _this._getRLVRenderedSize = function () { if (_this._recyclerRef) { return _this._recyclerRef.getRenderedSize(); } return undefined; }; _this._getContentDimension = function () { if (_this._recyclerRef) { return _this._recyclerRef.getContentDimension(); } return undefined; }; _this._applyWindowCorrection = function (offsetX, offsetY, windowCorrection) { if (_this.props.applyWindowCorrection) { _this.props.applyWindowCorrection(offsetX, offsetY, windowCorrection); } }; _this._initParams = function (props) { var childProps = props.children.props; _this._dataProvider = childProps.dataProvider; _this._layoutProvider = childProps.layoutProvider; _this._extendedState = childProps.extendedState; _this._rowRenderer = childProps.rowRenderer; }; _this._assertChildType(); var childProps = props.children.props; _this._dataProvider = childProps.dataProvider; _this._layoutProvider = childProps.layoutProvider; _this._extendedState = childProps.extendedState; _this._rowRenderer = childProps.rowRenderer; _this._getWindowCorrection(0, 0, props); return _this; } StickyContainer.prototype.componentWillReceivePropsCompat = function (newProps) { this._initParams(newProps); }; StickyContainer.prototype.renderCompat = function () { var _this = this; this._assertChildType(); var recycler = React.cloneElement(this.props.children, __assign(__assign({}, this.props.children.props), { ref: this._getRecyclerRef, onVisibleIndicesChanged: this._onVisibleIndicesChanged, onScroll: this._onScroll, applyWindowCorrection: this._applyWindowCorrection, rowRenderer: this._rlvRowRenderer })); return (React.createElement(react_native_1.View, { style: this.props.style ? this.props.style : { flex: 1 } }, recycler, this.props.stickyHeaderIndices ? (React.createElement(StickyHeader_1.default, { ref: function (stickyHeaderRef) { return _this._getStickyHeaderRef(stickyHeaderRef); }, stickyIndices: this.props.stickyHeaderIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, overrideRowRenderer: this.props.overrideRowRenderer, renderContainer: this.props.renderStickyContainer, getWindowCorrection: this._getCurrentWindowCorrection })) : null, this.props.stickyFooterIndices ? (React.createElement(StickyFooter_1.default, { ref: function (stickyFooterRef) { return _this._getStickyFooterRef(stickyFooterRef); }, stickyIndices: this.props.stickyFooterIndices, getLayoutForIndex: this._getLayoutForIndex, getDataForIndex: this._getDataForIndex, getLayoutTypeForIndex: this._getLayoutTypeForIndex, getExtendedState: this._getExtendedState, getRLVRenderedSize: this._getRLVRenderedSize, getContentDimension: this._getContentDimension, getRowRenderer: this._getRowRenderer, overrideRowRenderer: this.props.overrideRowRenderer, renderContainer: this.props.renderStickyContainer, getWindowCorrection: this._getCurrentWindowCorrection, alwaysStickBottom: this.props.alwaysStickyFooter })) : null)); }; StickyContainer.prototype._getWindowCorrection = function (offsetX, offsetY, props) { return (props.applyWindowCorrection && props.applyWindowCorrection(offsetX, offsetY, this._windowCorrection)) || this._windowCorrection; }; StickyContainer.propTypes = {}; return StickyContainer; }(ComponentCompat_1.ComponentCompat)); exports.default = StickyContainer; StickyContainer.propTypes = { // Mandatory to pass a single child of RecyclerListView or any of its children classes. Exception will be thrown otherwise. children: PropTypes.element.isRequired, // Provide an array of indices whose corresponding items need to be stuck to the top of the recyclerView once the items scroll off the top. // Every subsequent sticky index view will push the previous sticky view off the top to take its place. // Note - Needs to be sorted ascending stickyHeaderIndices: PropTypes.arrayOf(PropTypes.number), // Works same as sticky headers, but for views to be stuck at the bottom of the recyclerView. // Note - Needs to be sorted ascending stickyFooterIndices: PropTypes.arrayOf(PropTypes.number), // Will be called instead of rowRenderer for all sticky items. Any changes to the item for when they are stuck can be done here. overrideRowRenderer: PropTypes.func, // For all practical purposes, pass the style that is applied to the RecyclerListView component here. style: PropTypes.object, // For providing custom container to StickyHeader and StickyFooter allowing user extensibility to stylize these items accordingly. renderStickyContainer: PropTypes.func, // Used when the logical offsetY differs from actual offsetY of recyclerlistview, could be because some other component is overlaying the recyclerlistview. // For e.x. toolbar within CoordinatorLayout are overlapping the recyclerlistview. // This method exposes the windowCorrection object of RecyclerListView, user can modify the values in realtime. applyWindowCorrection: PropTypes.func, }; //# sourceMappingURL=StickyContainer.js.map