@uiw/react-affix
Version:
Affix component
178 lines (177 loc) • 7.22 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _utils = require("@uiw/utils");
var _utils2 = require("./utils");
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["prefixCls", "className", "children", "offsetTop", "offsetBottom", "target", "onChange"];
var Affix = exports["default"] = /*#__PURE__*/function (_React$Component) {
(0, _inherits2["default"])(Affix, _React$Component);
var _super = (0, _createSuper2["default"])(Affix);
function Affix(props) {
var _this;
(0, _classCallCheck2["default"])(this, Affix);
_this = _super.call(this, props);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", {
placeholderStyle: undefined,
affixStyle: undefined
});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "box", void 0);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "target", void 0);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "events", ['resize', 'scroll', 'touchstart', 'touchmove', 'touchend', 'pageshow', 'load']);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "eventHandlers", {});
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "timeout", void 0);
(0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "getInstance", function (node) {
if (node) {
_this.box = node;
}
});
_this.updatePosition = _this.updatePosition.bind((0, _assertThisInitialized2["default"])(_this));
return _this;
}
(0, _createClass2["default"])(Affix, [{
key: "componentDidMount",
value: function componentDidMount() {
var _this2 = this;
var target = this.props.target || _utils2.getDefaultTarget;
// Wait for parent component ref has its value
this.timeout = window.setTimeout(function () {
_this2.target = target();
_this2.setTargetEventListeners();
});
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.clearEventListeners();
clearTimeout(this.timeout);
}
}, {
key: "updatePosition",
value: function updatePosition() {
var offsetTop = this.props.offsetTop;
var offsetBottom = this.props.offsetBottom;
if (!this.box || !this.box.offsetParent) {
return;
}
var elemSize = {
width: this.box.clientWidth,
height: this.box.clientHeight
};
var offsetMode = {
top: true,
bottom: false
};
if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') {
offsetMode.top = true;
offsetTop = 0;
}
if (typeof offsetBottom === 'number') {
offsetMode.top = false;
offsetMode.bottom = true;
}
var elemOffset = (0, _utils2.getOffset)(this.box, this.target);
var box = this.box.getBoundingClientRect();
var bottom = document.documentElement.clientHeight - box.y - elemOffset.height;
if (offsetMode.top && box.y < 0) {
this.setPlaceholderStyle((0, _objectSpread2["default"])({}, elemSize));
this.setAffixStyle({
position: 'fixed',
top: offsetTop || 0,
left: elemOffset.left,
width: elemOffset.width
});
} else if (offsetMode.bottom && bottom < 0) {
this.setPlaceholderStyle((0, _objectSpread2["default"])({}, elemSize));
this.setAffixStyle({
position: 'fixed',
bottom: offsetBottom || 0,
left: elemOffset.left,
width: elemOffset.width
});
} else {
this.setPlaceholderStyle();
this.setAffixStyle();
}
}
}, {
key: "setAffixStyle",
value: function setAffixStyle(affixStyle) {
var onChange = this.props.onChange;
var affixed = !!this.state.affixStyle;
this.setState({
affixStyle: affixStyle
}, function () {
onChange && onChange(affixed);
});
}
}, {
key: "setPlaceholderStyle",
value: function setPlaceholderStyle(placeholderStyle) {
this.setState({
placeholderStyle: placeholderStyle
});
}
// 设置监听事件
}, {
key: "setTargetEventListeners",
value: function setTargetEventListeners() {
var _this3 = this;
this.clearEventListeners();
this.events.forEach(function (eventName) {
_this3.eventHandlers[eventName] = _this3.updatePosition;
_this3.target && _this3.target.addEventListener(eventName, _this3.updatePosition, false);
});
}
}, {
key: "clearEventListeners",
value: function clearEventListeners() {
var _this4 = this;
this.events.forEach(function (eventName) {
var handler = _this4.eventHandlers[eventName];
_this4.target && _this4.target.removeEventListener(eventName, handler, false);
});
}
}, {
key: "render",
value: function render() {
var _this$props = this.props,
prefixCls = _this$props.prefixCls,
className = _this$props.className,
children = _this$props.children,
offsetTop = _this$props.offsetTop,
offsetBottom = _this$props.offsetBottom,
target = _this$props.target,
onChange = _this$props.onChange,
resetProps = (0, _objectWithoutProperties2["default"])(_this$props, _excluded);
var cls = [className, prefixCls].filter(Boolean).join(' ').trim();
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, resetProps), {}, {
ref: this.getInstance,
style: (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, this.state.placeholderStyle), this.props.style),
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: cls,
style: this.state.affixStyle,
children: children
})
}));
}
}]);
return Affix;
}(_react["default"].Component);
(0, _defineProperty2["default"])(Affix, "defaultProps", {
prefixCls: 'w-affix',
onChange: _utils.noop
});
module.exports = exports.default;