UNPKG

react-virtualized

Version:

React components for efficiently rendering large, scrollable lists and tabular data

229 lines (167 loc) 8.14 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var React = _interopRequireWildcard(_react); var _detectElementResize = require('../vendor/detectElementResize'); var _detectElementResize2 = _interopRequireDefault(_detectElementResize); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var AutoSizer = function (_React$PureComponent) { (0, _inherits3.default)(AutoSizer, _React$PureComponent); function AutoSizer() { var _ref; var _temp, _this, _ret; (0, _classCallCheck3.default)(this, AutoSizer); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = AutoSizer.__proto__ || (0, _getPrototypeOf2.default)(AutoSizer)).call.apply(_ref, [this].concat(args))), _this), _this.state = { height: _this.props.defaultHeight || 0, width: _this.props.defaultWidth || 0 }, _this._onResize = function () { var _this$props = _this.props, disableHeight = _this$props.disableHeight, disableWidth = _this$props.disableWidth, onResize = _this$props.onResize; if (_this._parentNode) { // Guard against AutoSizer component being removed from the DOM immediately after being added. // This can result in invalid style values which can result in NaN values if we don't handle them. // See issue #150 for more context. var _height = _this._parentNode.offsetHeight || 0; var _width = _this._parentNode.offsetWidth || 0; var win = _this._window || window; var _style = win.getComputedStyle(_this._parentNode) || {}; var paddingLeft = parseInt(_style.paddingLeft, 10) || 0; var paddingRight = parseInt(_style.paddingRight, 10) || 0; var paddingTop = parseInt(_style.paddingTop, 10) || 0; var paddingBottom = parseInt(_style.paddingBottom, 10) || 0; var newHeight = _height - paddingTop - paddingBottom; var newWidth = _width - paddingLeft - paddingRight; if (!disableHeight && _this.state.height !== newHeight || !disableWidth && _this.state.width !== newWidth) { _this.setState({ height: _height - paddingTop - paddingBottom, width: _width - paddingLeft - paddingRight }); onResize({ height: _height, width: _width }); } } }, _this._setRef = function (autoSizer) { _this._autoSizer = autoSizer; }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret); } // uses any instead of Window because Flow doesn't have window type (0, _createClass3.default)(AutoSizer, [{ key: 'componentDidMount', value: function componentDidMount() { var nonce = this.props.nonce; if (this._autoSizer && this._autoSizer.parentNode && this._autoSizer.parentNode.ownerDocument && this._autoSizer.parentNode.ownerDocument.defaultView && this._autoSizer.parentNode instanceof this._autoSizer.parentNode.ownerDocument.defaultView.HTMLElement) { // Delay access of parentNode until mount. // This handles edge-cases where the component has already been unmounted before its ref has been set, // As well as libraries like react-lite which have a slightly different lifecycle. this._parentNode = this._autoSizer.parentNode; this._window = this._autoSizer.parentNode.ownerDocument.defaultView; // Defer requiring resize handler in order to support server-side rendering. // See issue #41 this._detectElementResize = (0, _detectElementResize2.default)(nonce, this._window); this._detectElementResize.addResizeListener(this._parentNode, this._onResize); this._onResize(); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { if (this._detectElementResize && this._parentNode) { this._detectElementResize.removeResizeListener(this._parentNode, this._onResize); } } }, { key: 'render', value: function render() { var _props = this.props, children = _props.children, className = _props.className, disableHeight = _props.disableHeight, disableWidth = _props.disableWidth, style = _props.style; var _state = this.state, height = _state.height, width = _state.width; // Outer div should not force width/height since that may prevent containers from shrinking. // Inner component should overflow and use calculated width/height. // See issue #68 for more information. var outerStyle = { overflow: 'visible' }; var childParams = {}; if (!disableHeight) { outerStyle.height = 0; childParams.height = height; } if (!disableWidth) { outerStyle.width = 0; childParams.width = width; } /** * TODO: Avoid rendering children before the initial measurements have been collected. * At best this would just be wasting cycles. * Add this check into version 10 though as it could break too many ref callbacks in version 9. * Note that if default width/height props were provided this would still work with SSR. if ( height !== 0 && width !== 0 ) { child = children({ height, width }) } */ return React.createElement( 'div', { className: className, ref: this._setRef, style: (0, _extends3.default)({}, outerStyle, style) }, children(childParams) ); } }]); return AutoSizer; }(React.PureComponent); AutoSizer.defaultProps = { onResize: function onResize() {}, disableHeight: false, disableWidth: false, style: {} }; AutoSizer.propTypes = process.env.NODE_ENV === 'production' ? null : { /** Function responsible for rendering children.*/ children: _propTypes2.default.func.isRequired, /** Optional custom CSS class name to attach to root AutoSizer element. */ className: _propTypes2.default.string, /** Default height to use for initial render; useful for SSR */ defaultHeight: _propTypes2.default.number, /** Default width to use for initial render; useful for SSR */ defaultWidth: _propTypes2.default.number, /** Disable dynamic :height property */ disableHeight: _propTypes2.default.bool.isRequired, /** Disable dynamic :width property */ disableWidth: _propTypes2.default.bool.isRequired, /** Nonce of the inlined stylesheet for Content Security Policy */ nonce: _propTypes2.default.string, /** Callback to be invoked on-resize */ onResize: _propTypes2.default.func.isRequired, /** Optional inline style */ style: _propTypes2.default.object }; exports.default = AutoSizer;