1 | 'use strict';
|
2 |
|
3 | exports.__esModule = true;
|
4 |
|
5 | var _extends2 = require('babel-runtime/helpers/extends');
|
6 |
|
7 | var _extends3 = _interopRequireDefault(_extends2);
|
8 |
|
9 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
10 |
|
11 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
12 |
|
13 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
14 |
|
15 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
16 |
|
17 | var _inherits2 = require('babel-runtime/helpers/inherits');
|
18 |
|
19 | var _inherits3 = _interopRequireDefault(_inherits2);
|
20 |
|
21 | var _class, _temp;
|
22 |
|
23 | var _react = require('react');
|
24 |
|
25 | var _react2 = _interopRequireDefault(_react);
|
26 |
|
27 | var _propTypes = require('prop-types');
|
28 |
|
29 | var _propTypes2 = _interopRequireDefault(_propTypes);
|
30 |
|
31 | var _classnames2 = require('classnames');
|
32 |
|
33 | var _classnames3 = _interopRequireDefault(_classnames2);
|
34 |
|
35 | var _reactDom = require('react-dom');
|
36 |
|
37 | var _reactLifecyclesCompat = require('react-lifecycles-compat');
|
38 |
|
39 | var _resizeObserverPolyfill = require('resize-observer-polyfill');
|
40 |
|
41 | var _resizeObserverPolyfill2 = _interopRequireDefault(_resizeObserverPolyfill);
|
42 |
|
43 | var _util = require('../util');
|
44 |
|
45 | var _configProvider = require('../config-provider');
|
46 |
|
47 | var _configProvider2 = _interopRequireDefault(_configProvider);
|
48 |
|
49 | var _util2 = require('./util');
|
50 |
|
51 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
52 |
|
53 |
|
54 | var Affix = (_temp = _class = function (_React$Component) {
|
55 | (0, _inherits3.default)(Affix, _React$Component);
|
56 |
|
57 | Affix._getAffixMode = function _getAffixMode(nextProps) {
|
58 | var affixMode = {
|
59 | top: false,
|
60 | bottom: false,
|
61 | offset: 0
|
62 | };
|
63 | if (!nextProps) {
|
64 | return affixMode;
|
65 | }
|
66 | var offsetTop = nextProps.offsetTop,
|
67 | offsetBottom = nextProps.offsetBottom;
|
68 |
|
69 |
|
70 | if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') {
|
71 |
|
72 | affixMode.top = true;
|
73 | } else if (typeof offsetTop === 'number') {
|
74 | affixMode.top = true;
|
75 | affixMode.bottom = false;
|
76 | affixMode.offset = offsetTop;
|
77 | } else if (typeof offsetBottom === 'number') {
|
78 | affixMode.bottom = true;
|
79 | affixMode.top = false;
|
80 | affixMode.offset = offsetBottom;
|
81 | }
|
82 |
|
83 | return affixMode;
|
84 | };
|
85 |
|
86 | function Affix(props, context) {
|
87 | (0, _classCallCheck3.default)(this, Affix);
|
88 |
|
89 | var _this = (0, _possibleConstructorReturn3.default)(this, _React$Component.call(this, props, context));
|
90 |
|
91 | _this._clearContainerEvent = function () {
|
92 | if (_this.timeout) {
|
93 | clearTimeout(_this.timeout);
|
94 | _this.timeout = null;
|
95 | }
|
96 | var container = _this.props.container;
|
97 |
|
98 | _this._removeEventHandlerForContainer(container);
|
99 | };
|
100 |
|
101 | _this.updatePosition = function () {
|
102 | _this._updateNodePosition();
|
103 | };
|
104 |
|
105 | _this._updateNodePosition = function () {
|
106 | var affixMode = _this.state.affixMode;
|
107 | var _this$props = _this.props,
|
108 | container = _this$props.container,
|
109 | useAbsolute = _this$props.useAbsolute;
|
110 |
|
111 | var affixContainer = container();
|
112 |
|
113 | if (!affixContainer || !_this.affixNode) {
|
114 | return false;
|
115 | }
|
116 | var containerScrollTop = (0, _util2.getScroll)(affixContainer, true);
|
117 | var affixOffset = _this._getOffset(_this.affixNode, affixContainer);
|
118 | var containerHeight = (0, _util2.getNodeHeight)(affixContainer);
|
119 | var affixHeight = _this.affixNode.offsetHeight;
|
120 | var containerRect = (0, _util2.getRect)(affixContainer);
|
121 |
|
122 | var affixChildHeight = _this.affixChildNode.offsetHeight;
|
123 |
|
124 | var affixStyle = {
|
125 | width: affixOffset.width
|
126 | };
|
127 | var containerStyle = {
|
128 | width: affixOffset.width,
|
129 | height: affixChildHeight
|
130 | };
|
131 | var positionStyle = null;
|
132 | if (affixMode.top && containerScrollTop > affixOffset.top - affixMode.offset) {
|
133 |
|
134 | if (useAbsolute) {
|
135 | affixStyle.position = 'absolute';
|
136 | affixStyle.top = containerScrollTop - (affixOffset.top - affixMode.offset);
|
137 | positionStyle = 'relative';
|
138 | } else {
|
139 | affixStyle.position = 'fixed';
|
140 | affixStyle.top = affixMode.offset + containerRect.top;
|
141 | }
|
142 | _this._setAffixStyle(affixStyle, true);
|
143 | _this._setContainerStyle(containerStyle);
|
144 | } else if (affixMode.bottom && containerScrollTop < affixOffset.top + affixHeight + affixMode.offset - containerHeight) {
|
145 |
|
146 | affixStyle.height = affixHeight;
|
147 | if (useAbsolute) {
|
148 | affixStyle.position = 'absolute';
|
149 | affixStyle.top = containerScrollTop - (affixOffset.top + affixHeight + affixMode.offset - containerHeight);
|
150 | positionStyle = 'relative';
|
151 | } else {
|
152 | affixStyle.position = 'fixed';
|
153 | affixStyle.bottom = affixMode.offset;
|
154 | }
|
155 | _this._setAffixStyle(affixStyle, true);
|
156 | _this._setContainerStyle(containerStyle);
|
157 | } else {
|
158 | _this._setAffixStyle(null);
|
159 | _this._setContainerStyle(null);
|
160 | }
|
161 |
|
162 | if (_this.state.positionStyle !== positionStyle) {
|
163 | _this.setState({ positionStyle: positionStyle });
|
164 | }
|
165 | };
|
166 |
|
167 | _this._affixNodeRefHandler = function (ref) {
|
168 | _this.affixNode = ref;
|
169 | };
|
170 |
|
171 | _this._affixChildNodeRefHandler = function (ref) {
|
172 | _this.affixChildNode = ref;
|
173 | };
|
174 |
|
175 | _this.state = {
|
176 | style: null,
|
177 | containerStyle: null,
|
178 | positionStyle: null,
|
179 | affixMode: Affix._getAffixMode(props)
|
180 | };
|
181 | _this.resizeObserver = new _resizeObserverPolyfill2.default(_this._updateNodePosition);
|
182 | return _this;
|
183 | }
|
184 |
|
185 | Affix.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
|
186 | if ('offsetTop' in nextProps || 'offsetBottom' in nextProps) {
|
187 | return {
|
188 | affixMode: Affix._getAffixMode(nextProps)
|
189 | };
|
190 | }
|
191 | return null;
|
192 | };
|
193 |
|
194 | Affix.prototype.componentDidMount = function componentDidMount() {
|
195 | var _this2 = this;
|
196 |
|
197 | var container = this.props.container;
|
198 |
|
199 |
|
200 | this.timeout = setTimeout(function () {
|
201 | _this2._updateNodePosition();
|
202 | _this2._setEventHandlerForContainer(container);
|
203 | });
|
204 | };
|
205 |
|
206 | Affix.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState, snapshot) {
|
207 | var _this3 = this;
|
208 |
|
209 | if (prevProps.container() !== this.props.container()) {
|
210 | this._clearContainerEvent();
|
211 |
|
212 | this.timeout = setTimeout(function () {
|
213 | _this3._setEventHandlerForContainer(_this3.props.container);
|
214 | });
|
215 | }
|
216 |
|
217 | setTimeout(this._updateNodePosition);
|
218 | };
|
219 |
|
220 | Affix.prototype.componentWillUnmount = function componentWillUnmount() {
|
221 | this._clearContainerEvent();
|
222 | };
|
223 |
|
224 | Affix.prototype._setEventHandlerForContainer = function _setEventHandlerForContainer(getContainer) {
|
225 | var container = getContainer();
|
226 | if (!container) {
|
227 | return;
|
228 | }
|
229 | _util.events.on(container, 'scroll', this._updateNodePosition, false);
|
230 | this.resizeObserver.observe(this.affixNode);
|
231 | };
|
232 |
|
233 | Affix.prototype._removeEventHandlerForContainer = function _removeEventHandlerForContainer(getContainer) {
|
234 | var container = getContainer();
|
235 | if (container) {
|
236 | _util.events.off(container, 'scroll', this._updateNodePosition);
|
237 | this.resizeObserver.disconnect();
|
238 | }
|
239 | };
|
240 |
|
241 | Affix.prototype._setAffixStyle = function _setAffixStyle(affixStyle) {
|
242 | var affixed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
243 |
|
244 | if (_util.obj.shallowEqual(affixStyle, this.state.style)) {
|
245 | return;
|
246 | }
|
247 |
|
248 | this.setState({
|
249 | style: affixStyle
|
250 | });
|
251 |
|
252 | var onAffix = this.props.onAffix;
|
253 |
|
254 |
|
255 | if (affixed) {
|
256 | setTimeout(function () {
|
257 | return onAffix(true);
|
258 | });
|
259 | } else if (!affixStyle) {
|
260 | setTimeout(function () {
|
261 | return onAffix(false);
|
262 | });
|
263 | }
|
264 | };
|
265 |
|
266 | Affix.prototype._setContainerStyle = function _setContainerStyle(containerStyle) {
|
267 | if (_util.obj.shallowEqual(containerStyle, this.state.containerStyle)) {
|
268 | return;
|
269 | }
|
270 | this.setState({ containerStyle: containerStyle });
|
271 | };
|
272 |
|
273 | Affix.prototype._getOffset = function _getOffset(affixNode, affixContainer) {
|
274 | var affixRect = affixNode.getBoundingClientRect();
|
275 | var containerRect = (0, _util2.getRect)(affixContainer);
|
276 | var containerScrollTop = (0, _util2.getScroll)(affixContainer, true);
|
277 | var containerScrollLeft = (0, _util2.getScroll)(affixContainer, false);
|
278 |
|
279 | return {
|
280 | top: affixRect.top - containerRect.top + containerScrollTop,
|
281 | left: affixRect.left - containerRect.left + containerScrollLeft,
|
282 | width: affixRect.width,
|
283 | height: affixRect.height
|
284 | };
|
285 | };
|
286 |
|
287 | Affix.prototype.render = function render() {
|
288 | var _classnames;
|
289 |
|
290 | var _state = this.state,
|
291 | affixMode = _state.affixMode,
|
292 | positionStyle = _state.positionStyle;
|
293 | var _props = this.props,
|
294 | prefix = _props.prefix,
|
295 | className = _props.className,
|
296 | style = _props.style,
|
297 | children = _props.children;
|
298 |
|
299 | var state = this.state;
|
300 | var classNames = (0, _classnames3.default)((_classnames = {}, _classnames[prefix + 'affix'] = state.style, _classnames[prefix + 'affix-top'] = !state.style && affixMode.top, _classnames[prefix + 'affix-bottom'] = !state.style && affixMode.bottom, _classnames[className] = className, _classnames));
|
301 | var wrapperStyle = (0, _extends3.default)({}, style, { position: positionStyle });
|
302 |
|
303 | return _react2.default.createElement(
|
304 | 'div',
|
305 | { ref: this._affixNodeRefHandler, style: wrapperStyle },
|
306 | state.style && _react2.default.createElement('div', { style: state.containerStyle, 'aria-hidden': 'true' }),
|
307 | _react2.default.createElement(
|
308 | 'div',
|
309 | { ref: this._affixChildNodeRefHandler, className: classNames, style: state.style },
|
310 | children
|
311 | )
|
312 | );
|
313 | };
|
314 |
|
315 | return Affix;
|
316 | }(_react2.default.Component), _class.propTypes = {
|
317 | prefix: _propTypes2.default.string,
|
318 | |
319 |
|
320 |
|
321 |
|
322 | container: _propTypes2.default.func,
|
323 | |
324 |
|
325 |
|
326 | offsetTop: _propTypes2.default.number,
|
327 | |
328 |
|
329 |
|
330 | offsetBottom: _propTypes2.default.number,
|
331 | |
332 |
|
333 |
|
334 |
|
335 | onAffix: _propTypes2.default.func,
|
336 | |
337 |
|
338 |
|
339 |
|
340 | useAbsolute: _propTypes2.default.bool,
|
341 | className: _propTypes2.default.string,
|
342 | style: _propTypes2.default.object,
|
343 | children: _propTypes2.default.any
|
344 | }, _class.defaultProps = {
|
345 | prefix: 'next-',
|
346 | container: function container() {
|
347 | return window;
|
348 | },
|
349 | onAffix: _util.func.noop
|
350 | }, _temp);
|
351 | Affix.displayName = 'Affix';
|
352 | exports.default = _configProvider2.default.config((0, _reactLifecyclesCompat.polyfill)(Affix));
|
353 | module.exports = exports['default']; |
\ | No newline at end of file |