UNPKG

yantd

Version:

React component library

228 lines (227 loc) 9.79 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import * as React from 'react'; import classNames from 'classnames'; import addEventListener from 'rc-util/lib/Dom/addEventListener'; import { ConfigContext } from '../config-provider'; import scrollTo from '../_util/scrollTo'; import getScroll from '../_util/getScroll'; import AnchorContext from './context'; function getDefaultContainer() { return window; } function getOffsetTop(element, container) { if (!element.getClientRects().length) { return 0; } var rect = element.getBoundingClientRect(); if (rect.width || rect.height) { if (container === window) { container = element.ownerDocument.documentElement; return rect.top - container.clientTop; } return rect.top - container.getBoundingClientRect().top; } return rect.top; } var sharpMatcherRegx = /#(\S+)$/; var Anchor = /** @class */ (function (_super) { __extends(Anchor, _super); function Anchor() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { activeLink: null, }; _this.wrapperRef = React.createRef(); _this.links = []; // Context _this.registerLink = function (link) { if (!_this.links.includes(link)) { _this.links.push(link); } }; _this.unregisterLink = function (link) { var index = _this.links.indexOf(link); if (index !== -1) { _this.links.splice(index, 1); } }; _this.getContainer = function () { var getTargetContainer = _this.context.getTargetContainer; var getContainer = _this.props.getContainer; var getFunc = getContainer || getTargetContainer || getDefaultContainer; return getFunc(); }; _this.handleScrollTo = function (link) { var _a = _this.props, offsetTop = _a.offsetTop, targetOffset = _a.targetOffset; _this.setCurrentActiveLink(link); var container = _this.getContainer(); var scrollTop = getScroll(container, true); var sharpLinkMatch = sharpMatcherRegx.exec(link); if (!sharpLinkMatch) { return; } var targetElement = document.getElementById(sharpLinkMatch[1]); if (!targetElement) { return; } var eleOffsetTop = getOffsetTop(targetElement, container); var y = scrollTop + eleOffsetTop; y -= targetOffset !== undefined ? targetOffset : offsetTop || 0; _this.animating = true; scrollTo(y, { callback: function () { _this.animating = false; }, getContainer: _this.getContainer, }); }; _this.saveInkNode = function (node) { _this.inkNode = node; }; _this.setCurrentActiveLink = function (link) { var activeLink = _this.state.activeLink; var onChange = _this.props.onChange; if (activeLink !== link) { _this.setState({ activeLink: link, }); onChange === null || onChange === void 0 ? void 0 : onChange(link); } }; _this.handleScroll = function () { if (_this.animating) { return; } var _a = _this.props, offsetTop = _a.offsetTop, bounds = _a.bounds, targetOffset = _a.targetOffset; var currentActiveLink = _this.getCurrentAnchor(targetOffset !== undefined ? targetOffset : offsetTop || 0, bounds); _this.setCurrentActiveLink(currentActiveLink); }; _this.updateInk = function () { var _a = _this, prefixCls = _a.prefixCls, wrapperRef = _a.wrapperRef; var anchorNode = wrapperRef.current; var linkNode = anchorNode === null || anchorNode === void 0 ? void 0 : anchorNode.getElementsByClassName(prefixCls + "-link-title-active")[0]; if (linkNode) { _this.inkNode.style.top = linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5 + "px"; } }; _this.render = function () { var _a; var _b = _this.context, getPrefixCls = _b.getPrefixCls, direction = _b.direction; var _c = _this.props, customizePrefixCls = _c.prefixCls, _d = _c.className, className = _d === void 0 ? '' : _d, style = _c.style, offsetTop = _c.offsetTop, affix = _c.affix, showInkInFixed = _c.showInkInFixed, children = _c.children; var activeLink = _this.state.activeLink; var prefixCls = getPrefixCls('anchor', customizePrefixCls); // To support old version react. // Have to add prefixCls on the instance. // https://github.com/facebook/react/issues/12397 _this.prefixCls = prefixCls; var inkClass = classNames(prefixCls + "-ink-ball", { visible: activeLink, }); var wrapperClass = classNames(prefixCls + "-wrapper", (_a = {}, _a[prefixCls + "-rtl"] = direction === 'rtl', _a), className); var anchorClass = classNames(prefixCls, { fixed: !affix && !showInkInFixed, }); var wrapperStyle = __assign({ maxHeight: offsetTop ? "calc(100vh - " + offsetTop + "px)" : '100vh' }, style); var anchorContent = (React.createElement("div", { ref: _this.wrapperRef, className: wrapperClass, style: wrapperStyle }, React.createElement("div", { className: anchorClass }, React.createElement("div", { className: prefixCls + "-ink" }, React.createElement("span", { className: inkClass, ref: _this.saveInkNode })), children))); return (React.createElement(AnchorContext.Provider, { value: { registerLink: _this.registerLink, unregisterLink: _this.unregisterLink, activeLink: _this.state.activeLink, scrollTo: _this.handleScrollTo, onClick: _this.props.onClick, } }, anchorContent)); }; return _this; } Anchor.prototype.componentDidMount = function () { this.scrollContainer = this.getContainer(); this.scrollEvent = addEventListener(this.scrollContainer, 'scroll', this.handleScroll); this.handleScroll(); }; Anchor.prototype.componentDidUpdate = function () { if (this.scrollEvent) { var currentContainer = this.getContainer(); if (this.scrollContainer !== currentContainer) { this.scrollContainer = currentContainer; this.scrollEvent.remove(); this.scrollEvent = addEventListener(this.scrollContainer, 'scroll', this.handleScroll); this.handleScroll(); } } this.updateInk(); }; Anchor.prototype.componentWillUnmount = function () { if (this.scrollEvent) { this.scrollEvent.remove(); } }; Anchor.prototype.getCurrentAnchor = function (offsetTop, bounds) { if (offsetTop === void 0) { offsetTop = 0; } if (bounds === void 0) { bounds = 5; } var getCurrentAnchor = this.props.getCurrentAnchor; if (typeof getCurrentAnchor === 'function') { return getCurrentAnchor(); } var linkSections = []; var container = this.getContainer(); this.links.forEach(function (link) { var sharpLinkMatch = sharpMatcherRegx.exec(link.toString()); if (!sharpLinkMatch) { return; } var target = document.getElementById(sharpLinkMatch[1]); if (target) { var top_1 = getOffsetTop(target, container); if (top_1 < offsetTop + bounds) { linkSections.push({ link: link, top: top_1, }); } } }); if (linkSections.length) { var maxSection = linkSections.reduce(function (prev, curr) { return (curr.top > prev.top ? curr : prev); }); return maxSection.link; } return ''; }; Anchor.defaultProps = { affix: true, showInkInFixed: false, }; Anchor.contextType = ConfigContext; return Anchor; }(React.Component)); export default Anchor;