react-sticky-17
Version:
Sticky component for React
162 lines (131 loc) • 5.86 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _reactDom = _interopRequireDefault(require("react-dom"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var Sticky =
/*#__PURE__*/
function (_Component) {
(0, _inherits2.default)(Sticky, _Component);
function Sticky() {
var _getPrototypeOf2;
var _this;
(0, _classCallCheck2.default)(this, Sticky);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(Sticky)).call.apply(_getPrototypeOf2, [this].concat(args)));
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {
isSticky: false,
wasSticky: false,
style: {}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleContainerEvent", function (_ref) {
var distanceFromTop = _ref.distanceFromTop,
distanceFromBottom = _ref.distanceFromBottom,
eventSource = _ref.eventSource;
var parent = _this.context.getParent();
var preventingStickyStateChanges = false;
if (_this.props.relative) {
preventingStickyStateChanges = eventSource !== parent;
distanceFromTop = -(eventSource.scrollTop + eventSource.offsetTop) + _this.placeholder.offsetTop;
}
var placeholderClientRect = _this.placeholder.getBoundingClientRect();
var contentClientRect = _this.content.getBoundingClientRect();
var calculatedHeight = contentClientRect.height;
var bottomDifference = distanceFromBottom - _this.props.bottomOffset - calculatedHeight;
var wasSticky = !!_this.state.isSticky;
var isSticky = preventingStickyStateChanges ? wasSticky : distanceFromTop <= -_this.props.topOffset && distanceFromBottom > -_this.props.bottomOffset;
distanceFromBottom = (_this.props.relative ? parent.scrollHeight - parent.scrollTop : distanceFromBottom) - calculatedHeight;
var style = !isSticky ? {} : {
position: "fixed",
top: bottomDifference > 0 ? _this.props.relative ? parent.offsetTop - parent.offsetParent.scrollTop : 0 : bottomDifference,
left: placeholderClientRect.left,
width: placeholderClientRect.width
};
if (!_this.props.disableHardwareAcceleration) {
style.transform = "translateZ(0)";
}
_this.setState({
isSticky: isSticky,
wasSticky: wasSticky,
distanceFromTop: distanceFromTop,
distanceFromBottom: distanceFromBottom,
calculatedHeight: calculatedHeight,
style: style
});
});
return _this;
}
(0, _createClass2.default)(Sticky, [{
key: "componentDidMount",
value: function componentDidMount() {
if (!this.context.subscribe) throw new TypeError("Expected Sticky to be mounted within StickyContainer");
this.context.subscribe(this.handleContainerEvent);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.context.unsubscribe(this.handleContainerEvent);
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate() {
this.placeholder.style.paddingBottom = this.props.disableCompensation ? 0 : "".concat(this.state.isSticky ? this.state.calculatedHeight : 0, "px");
}
}, {
key: "render",
value: function render() {
var _this2 = this;
var element = _react.default.cloneElement(this.props.children({
isSticky: this.state.isSticky,
wasSticky: this.state.wasSticky,
distanceFromTop: this.state.distanceFromTop,
distanceFromBottom: this.state.distanceFromBottom,
calculatedHeight: this.state.calculatedHeight,
style: this.state.style
}), {
ref: function ref(content) {
_this2.content = _reactDom.default.findDOMNode(content);
}
});
return _react.default.createElement("div", null, _react.default.createElement("div", {
ref: function ref(placeholder) {
return _this2.placeholder = placeholder;
}
}), element);
}
}]);
return Sticky;
}(_react.Component);
exports.default = Sticky;
(0, _defineProperty2.default)(Sticky, "propTypes", {
topOffset: _propTypes.default.number,
bottomOffset: _propTypes.default.number,
relative: _propTypes.default.bool,
children: _propTypes.default.func.isRequired
});
(0, _defineProperty2.default)(Sticky, "defaultProps", {
relative: false,
topOffset: 0,
bottomOffset: 0,
disableCompensation: false,
disableHardwareAcceleration: false
});
(0, _defineProperty2.default)(Sticky, "contextTypes", {
subscribe: _propTypes.default.func,
unsubscribe: _propTypes.default.func,
getParent: _propTypes.default.func
});