UNPKG

react-windowed-list

Version:

A fast, versatile virtual-render list component for React

191 lines (156 loc) 6.43 kB
'use strict'; exports.__esModule = true; exports.componentWillUnmount = exports.componentDidUpdate = exports.getSnapshotBeforeUpdate = exports.componentWillReceiveProps = exports.getDerivedStateFromProps = exports.componentDidMount = exports.onConstruct = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // external dependencies // constants // utils var _raf = require('raf'); var _raf2 = _interopRequireDefault(_raf); var _reactDom = require('react-dom'); var _constants = require('./constants'); var _utils = require('./utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @function onConstruct * * @description * on construction, set the initial state * * @param {ReactComponent} instance the component instance */ var onConstruct = exports.onConstruct = function onConstruct(instance) { var props = instance.props, setReconcileFrameAfterUpdate = instance.setReconcileFrameAfterUpdate, state = instance.state; var itemsPerRow = 1; setReconcileFrameAfterUpdate(); instance.state = _extends({}, state, (0, _utils.getFromAndSize)(props.initialIndex, 0, itemsPerRow, props), { itemsPerRow: itemsPerRow }); }; /** * @function componentDidMount * * @description * on mount, update the frame with the desired scroll position * * @param {ReactComponent} instance the component instance */ var componentDidMount = exports.componentDidMount = function componentDidMount(instance) { instance.outerContainer = (0, _reactDom.findDOMNode)(instance); if (!instance.props.isHidden) { (0, _raf2.default)(function () { return instance.updateFrame(instance.scrollTo); }); } }; /** * @function getDerivedStateFromProps * * @description * get the next state based on the next props * * @param {Object} nextProps the next props passed * @param {number} from the first index to render * @param {number} itemsPerRow the number of items per row * @param {number} size the number of items to render * @returns {Object|null} the next state, if applicable */ var getDerivedStateFromProps = exports.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, _ref) { var from = _ref.from, itemsPerRow = _ref.itemsPerRow, size = _ref.size; var fromAndSize = (0, _utils.getFromAndSize)(from, size, itemsPerRow, nextProps); return fromAndSize.from === from && fromAndSize.size === size ? null : fromAndSize; }; /** * @function componentWillReceiveProps * * @description * when props are received, set the state if the next calculated state is different * * @param {number} debounceReconciler the debounce reconciler in props * @param {function} setReconcileFrameAfterUpdate the method to set the reconciler frame * @param {function} setStateIfAppropriate the method to set the state if changed * @param {number} from the first index to render * @param {number} itemsPerRow the number of items per row * @param {number} size the number of items to render * @param {Object} nextProps the incoming props */ var componentWillReceiveProps = exports.componentWillReceiveProps = function componentWillReceiveProps(_ref2, _ref3) { var debounceReconciler = _ref2.props.debounceReconciler, setReconcileFrameAfterUpdate = _ref2.setReconcileFrameAfterUpdate, setStateIfAppropriate = _ref2.setStateIfAppropriate, _ref2$state = _ref2.state, from = _ref2$state.from, itemsPerRow = _ref2$state.itemsPerRow, size = _ref2$state.size; var nextProps = _ref3[0]; if (debounceReconciler !== nextProps.debounceReconciler) { setReconcileFrameAfterUpdate(); } setStateIfAppropriate((0, _utils.getFromAndSize)(from, size, itemsPerRow, nextProps), _utils.noop); }; /** * @function getSnapshotBeforeUpdate * * @description * update the debounce reconciler if the values have changed in props * * @param {number} debounceReconciler the delay to wait before reconciling in props * @param {function} setReconcileFrameAfterUpdate the method to set the reconciler frame * @param {Object} previousProps the previous props values * @returns {void} */ var getSnapshotBeforeUpdate = exports.getSnapshotBeforeUpdate = function getSnapshotBeforeUpdate(_ref4, _ref5) { var debounceReconciler = _ref4.props.debounceReconciler, setReconcileFrameAfterUpdate = _ref4.setReconcileFrameAfterUpdate; var previousProps = _ref5[0]; return debounceReconciler !== previousProps.debounceReconciler && setReconcileFrameAfterUpdate(); }; /** * @function componentDidUpdate * * @description * update the frame position, cutting off after a certain point if unstable * * @param {ReactComponent} instance the component instance * @returns {void} */ var componentDidUpdate = exports.componentDidUpdate = function componentDidUpdate(instance) { if (instance.unstableTimeoutId || ++instance.updateCounter > _constants.MAX_SYNC_UPDATES) { clearTimeout(instance.unstableTimeoutId); if (!instance.unstableTimeoutId) { console.error(_constants.UNSTABLE_MESSAGE); // eslint-disable-line no-console } instance.unstableTimeoutId = setTimeout(function () { instance.unstableTimeoutId = null; instance.updateCounter = 0; }, _constants.UNSTABLE_TIMEOUT); return; } if (!instance.updateCounterTimeoutId) { instance.updateCounterTimeoutId = (0, _raf2.default)(function () { instance.updateCounter = 0; instance.updateCounterTimeoutId = null; }); } if (!instance.props.isHidden) { instance.reconcileFrameAfterUpdate(instance.updateFrame); } }; /** * @function componentWillUnmount * * @description * before unmount, remove any listeners applied to the scroll container * * @param {ReactComponent} instance the component instance */ var componentWillUnmount = exports.componentWillUnmount = function componentWillUnmount(instance) { if (instance.scrollParent) { instance.scrollParent.removeEventListener('scroll', instance.updateFrame, _constants.ADD_EVENT_LISTENER_OPTIONS); instance.scrollParent.removeEventListener('mousewheel', _utils.noop, _constants.ADD_EVENT_LISTENER_OPTIONS); } instance.outerContainer = null; };