UNPKG

14.1 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports["default"] = void 0;
7
8var _react = _interopRequireDefault(require("react"));
9
10var _propTypes = _interopRequireDefault(require("prop-types"));
11
12var _reactDom = require("react-dom");
13
14var _classnames2 = _interopRequireDefault(require("classnames"));
15
16var _util = require("../util");
17
18var _configProvider = _interopRequireDefault(require("../config-provider"));
19
20var _util2 = require("./util");
21
22function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
23
24function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
25
26function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
27
28function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
29
30function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
31
32function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
33
34function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
35
36function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
37
38function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
39
40function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
41
42function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
43
44function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
45
46function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
47
48function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
49
50function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
51
52/** Affix */
53var Affix = /*#__PURE__*/function (_React$Component) {
54 _inherits(Affix, _React$Component);
55
56 var _super = _createSuper(Affix);
57
58 function Affix(props, context) {
59 var _this;
60
61 _classCallCheck(this, Affix);
62
63 _this = _super.call(this, props, context);
64
65 _defineProperty(_assertThisInitialized(_this), "updatePosition", function () {
66 _this._updateNodePosition();
67 });
68
69 _defineProperty(_assertThisInitialized(_this), "_updateNodePosition", function () {
70 var _this$props = _this.props,
71 container = _this$props.container,
72 useAbsolute = _this$props.useAbsolute;
73 var affixContainer = container();
74
75 if (!affixContainer) {
76 return false;
77 }
78
79 var containerScrollTop = (0, _util2.getScroll)(affixContainer, true); // 容器在垂直位置上的滚动 offset
80
81 var affixOffset = _this._getOffset(_this.affixNode, affixContainer); // 目标节点当前相对于容器的 offset
82
83
84 var containerHeight = (0, _util2.getNodeHeight)(affixContainer); // 容器的高度
85
86 var affixHeight = _this.affixNode.offsetHeight;
87 var containerRect = (0, _util2.getRect)(affixContainer);
88 var affixChildHeight = _this.affixChildNode.offsetHeight;
89
90 var _assertThisInitialize = _assertThisInitialized(_this),
91 affixMode = _assertThisInitialize.affixMode;
92
93 var affixStyle = {
94 width: affixOffset.width
95 };
96 var containerStyle = {
97 width: affixOffset.width,
98 height: affixChildHeight
99 };
100
101 if (affixMode.top && containerScrollTop > affixOffset.top - affixMode.offset) {
102 // affix top
103 if (useAbsolute) {
104 affixStyle.position = 'absolute';
105 affixStyle.top = containerScrollTop - (affixOffset.top - affixMode.offset);
106 containerStyle.position = 'relative';
107 } else {
108 affixStyle.position = 'fixed';
109 affixStyle.top = affixMode.offset + containerRect.top;
110 }
111
112 _this._setAffixStyle(affixStyle, true);
113
114 _this._setContainerStyle(containerStyle);
115 } else if (affixMode.bottom && containerScrollTop < affixOffset.top + affixHeight + affixMode.offset - containerHeight) {
116 // affix bottom
117 affixStyle.height = affixHeight;
118
119 if (useAbsolute) {
120 affixStyle.position = 'absolute';
121 affixStyle.top = containerScrollTop - (affixOffset.top + affixHeight + affixMode.offset - containerHeight);
122 containerStyle.position = 'relative';
123 } else {
124 affixStyle.position = 'fixed';
125 affixStyle.bottom = affixMode.offset;
126 }
127
128 _this._setAffixStyle(affixStyle, true);
129
130 _this._setContainerStyle(containerStyle);
131 } else {
132 _this._setAffixStyle(null);
133
134 _this._setContainerStyle(null);
135 }
136 });
137
138 _defineProperty(_assertThisInitialized(_this), "_affixNodeRefHandler", function (ref) {
139 _this.affixNode = (0, _reactDom.findDOMNode)(ref);
140 });
141
142 _defineProperty(_assertThisInitialized(_this), "_affixChildNodeRefHandler", function (ref) {
143 _this.affixChildNode = (0, _reactDom.findDOMNode)(ref);
144 });
145
146 _this.state = {
147 style: null,
148 containerStyle: null
149 };
150 _this.affixMode = _this._getAffixMode(props);
151 return _this;
152 }
153
154 _createClass(Affix, [{
155 key: "componentDidMount",
156 value: function componentDidMount() {
157 var _this2 = this;
158
159 var container = this.props.container;
160
161 this._updateNodePosition(); // wait for parent rendered
162
163
164 this.timeout = setTimeout(function () {
165 _this2._setEventHandlerForContainer(container);
166 });
167 }
168 }, {
169 key: "UNSAFE_componentWillReceiveProps",
170 value: function UNSAFE_componentWillReceiveProps(nextProps) {
171 if ('offsetTop' in nextProps || 'offsetBottom' in nextProps) {
172 this.affixMode = this._getAffixMode(nextProps);
173
174 this._updateNodePosition();
175 }
176 }
177 }, {
178 key: "componentWillUnmount",
179 value: function componentWillUnmount() {
180 if (this.timeout) {
181 clearTimeout(this.timeout);
182 this.timeout = null;
183 }
184
185 var container = this.props.container;
186
187 this._removeEventHandlerForContainer(container);
188 }
189 }, {
190 key: "_setEventHandlerForContainer",
191 value: function _setEventHandlerForContainer(getContainer) {
192 var container = getContainer();
193
194 if (!container) {
195 return;
196 }
197
198 _util.events.on(container, 'scroll', this._updateNodePosition, false);
199
200 _util.events.on(container, 'resize', this._updateNodePosition, false);
201 }
202 }, {
203 key: "_removeEventHandlerForContainer",
204 value: function _removeEventHandlerForContainer(getContainer) {
205 var container = getContainer();
206
207 if (container) {
208 _util.events.off(container, 'scroll', this._updateNodePosition);
209
210 _util.events.off(container, 'resize', this._updateNodePosition);
211 }
212 }
213 }, {
214 key: "_getAffixMode",
215 value: function _getAffixMode(nextProps) {
216 var props = nextProps || this.props;
217 var offsetTop = props.offsetTop,
218 offsetBottom = props.offsetBottom;
219 var affixMode = {
220 top: false,
221 bottom: false,
222 offset: 0
223 };
224
225 if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') {
226 // set default
227 affixMode.top = true;
228 } else if (typeof offsetTop === 'number') {
229 affixMode.top = true;
230 affixMode.bottom = false;
231 affixMode.offset = offsetTop;
232 } else if (typeof offsetBottom === 'number') {
233 affixMode.bottom = true;
234 affixMode.top = false;
235 affixMode.offset = offsetBottom;
236 }
237
238 return affixMode;
239 }
240 }, {
241 key: "_setAffixStyle",
242 value: function _setAffixStyle(affixStyle) {
243 var affixed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
244
245 if (_util.obj.shallowEqual(affixStyle, this.state.style)) {
246 return;
247 }
248
249 this.setState({
250 style: affixStyle
251 });
252 var onAffix = this.props.onAffix;
253
254 if (affixed) {
255 onAffix(true);
256 } else if (!affixStyle) {
257 onAffix(false);
258 }
259 }
260 }, {
261 key: "_setContainerStyle",
262 value: function _setContainerStyle(containerStyle) {
263 if (_util.obj.shallowEqual(containerStyle, this.state.containerStyle)) {
264 return;
265 }
266
267 this.setState({
268 containerStyle: containerStyle
269 });
270 }
271 }, {
272 key: "_getOffset",
273 value: function _getOffset(affixNode, affixContainer) {
274 var affixRect = affixNode.getBoundingClientRect(); // affix 元素 相对浏览器窗口的位置
275
276 var containerRect = (0, _util2.getRect)(affixContainer); // affix 容器 相对浏览器窗口的位置
277
278 var containerScrollTop = (0, _util2.getScroll)(affixContainer, true);
279 var containerScrollLeft = (0, _util2.getScroll)(affixContainer, false);
280 return {
281 top: affixRect.top - containerRect.top + containerScrollTop,
282 left: affixRect.left - containerRect.left + containerScrollLeft,
283 width: affixRect.width,
284 height: affixRect.height
285 };
286 }
287 }, {
288 key: "render",
289 value: function render() {
290 var _classnames;
291
292 var _this$props2 = this.props,
293 prefix = _this$props2.prefix,
294 className = _this$props2.className,
295 style = _this$props2.style,
296 children = _this$props2.children;
297 var state = this.state;
298 var classNames = (0, _classnames2["default"])((_classnames = {}, _defineProperty(_classnames, "".concat(prefix, "affix"), state.style), _defineProperty(_classnames, "".concat(prefix, "affix-top"), !state.style && this.affixMode.top), _defineProperty(_classnames, "".concat(prefix, "affix-bottom"), !state.style && this.affixMode.bottom), _defineProperty(_classnames, className, className), _classnames));
299
300 var combinedStyle = _objectSpread(_objectSpread({}, state.containerStyle), style);
301
302 return /*#__PURE__*/_react["default"].createElement("div", {
303 ref: this._affixNodeRefHandler,
304 style: combinedStyle
305 }, /*#__PURE__*/_react["default"].createElement("div", {
306 ref: this._affixChildNodeRefHandler,
307 className: classNames,
308 style: state.style
309 }, children));
310 }
311 }]);
312
313 return Affix;
314}(_react["default"].Component);
315
316_defineProperty(Affix, "propTypes", {
317 prefix: _propTypes["default"].string,
318
319 /**
320 * 设置 Affix 需要监听滚动事件的容器元素
321 * @return {ReactElement} 目标容器元素的实例
322 */
323 container: _propTypes["default"].func,
324
325 /**
326 * 距离窗口顶部达到指定偏移量后触发
327 */
328 offsetTop: _propTypes["default"].number,
329
330 /**
331 * 距离窗口底部达到制定偏移量后触发
332 */
333 offsetBottom: _propTypes["default"].number,
334
335 /**
336 * 当元素的样式发生固钉样式变化时触发的回调函数
337 * @param {Boolean} 元素是否被固钉
338 */
339 onAffix: _propTypes["default"].func,
340
341 /**
342 * 是否启用绝对布局实现 affix
343 * @param {Boolean} 是否启用绝对布局
344 */
345 useAbsolute: _propTypes["default"].bool,
346 className: _propTypes["default"].string,
347 style: _propTypes["default"].object,
348 children: _propTypes["default"].any
349});
350
351_defineProperty(Affix, "defaultProps", {
352 prefix: 'next-',
353 container: function container() {
354 return window;
355 },
356 onAffix: _util.func.noop
357});
358
359var _default = _configProvider["default"].config(Affix);
360
361exports["default"] = _default;
\No newline at end of file