UNPKG

zent

Version:

一套前端设计语言和基于React的实现

228 lines (227 loc) 10.1 kB
import { __extends } from "tslib"; import { jsx as _jsx } from "react/jsx-runtime"; import { Children, cloneElement, createRef, PureComponent } from 'react'; import { addEventListener } from '../utils/component/event-handler'; import { isForwardRef } from 'react-is'; import { computeOffsetPixels } from './offset'; import isDOMElement from '../utils/isDOMElement'; import { getCurrentPosition } from './position'; import isBrowser from '../utils/isBrowser'; import defer from '../utils/defer'; import { parseBorderWidth, parseFontSize } from './cssom'; var DEFAULT_OFFSET = 0; var Waypoint = (function (_super) { __extends(Waypoint, _super); function Waypoint() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.refElement = createRef(); _this.previousPosition = 4; _this.handleScroll = function (event) { if (!_this.refElement.current) { return; } var bounds = _this.getBounds(); var currentPosition = getCurrentPosition(bounds); var previousPosition = _this.previousPosition; var _a = _this.props, onPositionChange = _a.onPositionChange, onEnter = _a.onEnter, onLeave = _a.onLeave, fireOnRapidScroll = _a.fireOnRapidScroll; _this.previousPosition = currentPosition; if (previousPosition === currentPosition) { return; } var callbackArg = { currentPosition: currentPosition, previousPosition: previousPosition, event: event, waypointTop: bounds.waypointTop, waypointBottom: bounds.waypointBottom, viewportTop: bounds.viewportTop, viewportBottom: bounds.viewportBottom, }; onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(callbackArg); if (currentPosition === 1) { onEnter === null || onEnter === void 0 ? void 0 : onEnter(callbackArg); } else if (previousPosition === 1 || previousPosition === 4) { onLeave === null || onLeave === void 0 ? void 0 : onLeave(callbackArg); } var isRapidScrollDown = previousPosition === 2 && currentPosition === 0; var isRapidScrollUp = previousPosition === 0 && currentPosition === 2; if (fireOnRapidScroll && (isRapidScrollDown || isRapidScrollUp)) { onEnter === null || onEnter === void 0 ? void 0 : onEnter({ currentPosition: 1, previousPosition: previousPosition, event: event, waypointTop: bounds.waypointTop, waypointBottom: bounds.waypointBottom, viewportTop: bounds.viewportTop, viewportBottom: bounds.viewportBottom, }); onLeave === null || onLeave === void 0 ? void 0 : onLeave({ currentPosition: currentPosition, previousPosition: 1, event: event, waypointTop: bounds.waypointTop, waypointBottom: bounds.waypointBottom, viewportTop: bounds.viewportTop, viewportBottom: bounds.viewportBottom, }); } }; return _this; } Waypoint.prototype.componentDidMount = function () { var _this = this; if (!isBrowser) { return; } this.cancelOnNextTick = defer(function () { _this.cancelOnNextTick = null; var children = _this.props.children; ensureRefIsUsedByChild(children, _this.refElement.current); _this.scrollableAncestor = _this.findScrollableAncestor(); _this.scrollEventListenerUnsubscribe = addEventListener(_this.scrollableAncestor, 'scroll', _this.handleScroll, { passive: true }); _this.resizeEventListenerUnsubscribe = addEventListener(window, 'resize', _this.handleScroll, { passive: true }); _this.handleScroll(null); }); }; Waypoint.prototype.componentDidUpdate = function () { var _this = this; if (!isBrowser) { return; } if (!this.scrollableAncestor) { return; } if (this.cancelOnNextTick) { return; } this.cancelOnNextTick = defer(function () { _this.cancelOnNextTick = null; _this.handleScroll(null); }); }; Waypoint.prototype.componentWillUnmount = function () { var _a, _b, _c; if (!isBrowser) { return; } (_a = this.scrollEventListenerUnsubscribe) === null || _a === void 0 ? void 0 : _a.call(this); (_b = this.resizeEventListenerUnsubscribe) === null || _b === void 0 ? void 0 : _b.call(this); (_c = this.cancelOnNextTick) === null || _c === void 0 ? void 0 : _c.cancel(); }; Waypoint.prototype.findScrollableAncestor = function () { var _a = this.props, horizontal = _a.horizontal, scrollableAncestor = _a.scrollableAncestor; if (scrollableAncestor) { return scrollableAncestor; } var node = this.refElement.current; while (node.parentNode) { node = node.parentNode; if (node === document.body) { return window; } var style = getComputedStyle(node); var overflowDirec = horizontal ? style.getPropertyValue('overflow-x') : style.getPropertyValue('overflow-y'); var overflow = overflowDirec || style.getPropertyValue('overflow'); if (overflow === 'auto' || overflow === 'scroll') { return node; } } return window; }; Waypoint.prototype.getBounds = function () { var horizontal = this.props.horizontal; var _a = this.refElement.current.getBoundingClientRect(), left = _a.left, top = _a.top, right = _a.right, bottom = _a.bottom; var waypointTop = horizontal ? left : top; var waypointBottom = horizontal ? right : bottom; var contextHeight; var contextScrollTop; if (this.scrollableAncestor === window) { contextHeight = horizontal ? window.innerWidth : window.innerHeight; contextScrollTop = 0; } else { var node = this.scrollableAncestor; var boundingBox = node.getBoundingClientRect(); contextHeight = horizontal ? boundingBox.width : boundingBox.height; contextScrollTop = horizontal ? boundingBox.left : boundingBox.top; } var topOffsetPx = this.getOffset('top', contextHeight); var bottomOffsetPx = this.getOffset('bottom', contextHeight); var contextBottom = contextScrollTop + contextHeight; return { waypointTop: waypointTop, waypointBottom: waypointBottom, viewportTop: contextScrollTop + topOffsetPx, viewportBottom: contextBottom - bottomOffsetPx, }; }; Waypoint.prototype.getOffset = function (pos, contextHeight) { var _a, _b; var horizontal = this.props.horizontal; var prop = pos + "Offset"; var border = pos === 'top' ? "border" + (horizontal ? 'Left' : 'Top') + "Width" : "border" + (horizontal ? 'Right' : 'Bottom') + "Width"; var propOffset = this.props[prop]; if (propOffset !== 'auto') { return computeOffsetPixels(propOffset, contextHeight); } if (this.scrollableAncestor === window) { var styles_1 = getComputedStyle(document.documentElement); var getFontSize = function () { return parseFontSize(styles_1.fontSize); }; return ((_a = parseBorderWidth(styles_1[border], getFontSize, getFontSize)) !== null && _a !== void 0 ? _a : DEFAULT_OFFSET); } else { var styles_2 = getComputedStyle(this.scrollableAncestor); var getFontSize = function () { return parseFontSize(styles_2.fontSize); }; var getRootFontSize = function () { return parseFontSize(getComputedStyle(document.documentElement).fontSize); }; return ((_b = parseBorderWidth(styles_2[border], getFontSize, getRootFontSize)) !== null && _b !== void 0 ? _b : DEFAULT_OFFSET); } }; Waypoint.prototype.render = function () { var _this = this; var children = this.props.children; if (!children) { return (_jsx("span", { ref: this.refElement, style: { fontSize: 0 }, className: "zent-waypoint-marker", "data-zv": '10.0.17' }, void 0)); } var child = Children.only(children); if (isDOMElement(child) || isForwardRef(child)) { var ref = function (node) { _this.refElement.current = node; var chRef = child.ref; if (chRef) { if (typeof chRef === 'function') { chRef(node); } else { chRef.current = node; } } }; return cloneElement(child, { ref: ref }); } return cloneElement(child, { innerRef: this.refElement }); }; Waypoint.defaultProps = { topOffset: DEFAULT_OFFSET, bottomOffset: DEFAULT_OFFSET, horizontal: false, fireOnRapidScroll: true, }; return Waypoint; }(PureComponent)); export { Waypoint }; function ensureRefIsUsedByChild(children, ref) { if (children && !isDOMElement(children) && !ref) { throw new Error('<Waypoint> needs a DOM element to compute boundaries. The child you passed is neither a ' + 'DOM element (e.g. <div>) nor does it use the innerRef prop.\n'); } }