UNPKG

antd

Version:

An enterprise-class UI design language and React components implementation

227 lines (226 loc) 9.73 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"]; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classnames = _interopRequireDefault(require("classnames")); var _addEventListener = _interopRequireDefault(require("rc-util/lib/Dom/addEventListener")); var React = _interopRequireWildcard(require("react")); var _affix = _interopRequireDefault(require("../affix")); var _configProvider = require("../config-provider"); var _getScroll = _interopRequireDefault(require("../_util/getScroll")); var _scrollTo = _interopRequireDefault(require("../_util/scrollTo")); var _context = _interopRequireDefault(require("./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 AnchorContent = function AnchorContent(props) { var _a; var prefixCls = props.anchorPrefixCls, _props$className = props.className, className = _props$className === void 0 ? '' : _props$className, style = props.style, offsetTop = props.offsetTop, _props$affix = props.affix, affix = _props$affix === void 0 ? true : _props$affix, _props$showInkInFixed = props.showInkInFixed, showInkInFixed = _props$showInkInFixed === void 0 ? false : _props$showInkInFixed, children = props.children, bounds = props.bounds, targetOffset = props.targetOffset, onClick = props.onClick, onChange = props.onChange, getContainer = props.getContainer, getCurrentAnchor = props.getCurrentAnchor; var _React$useState = React.useState([]), _React$useState2 = (0, _slicedToArray2["default"])(_React$useState, 2), links = _React$useState2[0], setLinks = _React$useState2[1]; var _React$useState3 = React.useState(null), _React$useState4 = (0, _slicedToArray2["default"])(_React$useState3, 2), activeLink = _React$useState4[0], setActiveLink = _React$useState4[1]; var activeLinkRef = React.useRef(activeLink); var wrapperRef = React.useRef(null); var spanLinkNode = React.useRef(null); var animating = React.useRef(false); var _React$useContext = React.useContext(_configProvider.ConfigContext), direction = _React$useContext.direction, getTargetContainer = _React$useContext.getTargetContainer; var getCurrentContainer = (_a = getContainer !== null && getContainer !== void 0 ? getContainer : getTargetContainer) !== null && _a !== void 0 ? _a : getDefaultContainer; var dependencyListItem = JSON.stringify(links); var registerLink = React.useCallback(function (link) { if (!links.includes(link)) { setLinks(function (prev) { return [].concat((0, _toConsumableArray2["default"])(prev), [link]); }); } }, [dependencyListItem]); var unregisterLink = React.useCallback(function (link) { if (links.includes(link)) { setLinks(function (prev) { return prev.filter(function (i) { return i !== link; }); }); } }, [dependencyListItem]); var updateInk = function updateInk() { var _a; var linkNode = (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(".".concat(prefixCls, "-link-title-active")); if (linkNode && spanLinkNode.current) { spanLinkNode.current.style.top = "".concat(linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5, "px"); } }; var getInternalCurrentAnchor = function getInternalCurrentAnchor(_links) { var _offsetTop = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var _bounds = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5; var linkSections = []; var container = getCurrentContainer(); _links.forEach(function (link) { var sharpLinkMatch = sharpMatcherRegx.exec(link === null || link === void 0 ? void 0 : link.toString()); if (!sharpLinkMatch) { return; } var target = document.getElementById(sharpLinkMatch[1]); if (target) { var top = getOffsetTop(target, container); if (top < _offsetTop + _bounds) { linkSections.push({ link: link, top: top }); } } }); if (linkSections.length) { var maxSection = linkSections.reduce(function (prev, curr) { return curr.top > prev.top ? curr : prev; }); return maxSection.link; } return ''; }; var setCurrentActiveLink = function setCurrentActiveLink(link) { if (activeLinkRef.current === link) { return; } // https://github.com/ant-design/ant-design/issues/30584 var newLink = typeof getCurrentAnchor === 'function' ? getCurrentAnchor(link) : link; setActiveLink(newLink); activeLinkRef.current = newLink; // onChange should respect the original link (which may caused by // window scroll or user click), not the new link onChange === null || onChange === void 0 ? void 0 : onChange(link); }; var handleScroll = React.useCallback(function () { if (animating.current) { return; } var currentActiveLink = getInternalCurrentAnchor(links, targetOffset !== undefined ? targetOffset : offsetTop || 0, bounds); setCurrentActiveLink(currentActiveLink); }, [dependencyListItem, targetOffset, offsetTop]); var handleScrollTo = React.useCallback(function (link) { setCurrentActiveLink(link); var container = getCurrentContainer(); var scrollTop = (0, _getScroll["default"])(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; animating.current = true; (0, _scrollTo["default"])(y, { getContainer: getCurrentContainer, callback: function callback() { animating.current = false; } }); }, [targetOffset, offsetTop]); var inkClass = (0, _classnames["default"])((0, _defineProperty2["default"])({}, "".concat(prefixCls, "-ink-ball-visible"), activeLink), "".concat(prefixCls, "-ink-ball")); var wrapperClass = (0, _classnames["default"])("".concat(prefixCls, "-wrapper"), (0, _defineProperty2["default"])({}, "".concat(prefixCls, "-rtl"), direction === 'rtl'), className); var anchorClass = (0, _classnames["default"])(prefixCls, (0, _defineProperty2["default"])({}, "".concat(prefixCls, "-fixed"), !affix && !showInkInFixed)); var wrapperStyle = (0, _extends2["default"])({ maxHeight: offsetTop ? "calc(100vh - ".concat(offsetTop, "px)") : '100vh' }, style); var anchorContent = /*#__PURE__*/React.createElement("div", { ref: wrapperRef, className: wrapperClass, style: wrapperStyle }, /*#__PURE__*/React.createElement("div", { className: anchorClass }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-ink") }, /*#__PURE__*/React.createElement("span", { className: inkClass, ref: spanLinkNode })), children)); React.useEffect(function () { var scrollContainer = getCurrentContainer(); var scrollEvent = (0, _addEventListener["default"])(scrollContainer, 'scroll', handleScroll); handleScroll(); return function () { scrollEvent === null || scrollEvent === void 0 ? void 0 : scrollEvent.remove(); }; }, [dependencyListItem]); React.useEffect(function () { if (typeof getCurrentAnchor === 'function') { setCurrentActiveLink(getCurrentAnchor(activeLinkRef.current || '')); } }, [getCurrentAnchor]); React.useEffect(function () { updateInk(); }, [getCurrentAnchor, dependencyListItem, activeLink]); var memoizedContextValue = React.useMemo(function () { return { registerLink: registerLink, unregisterLink: unregisterLink, scrollTo: handleScrollTo, activeLink: activeLink, onClick: onClick }; }, [activeLink, onClick, handleScrollTo]); return /*#__PURE__*/React.createElement(_context["default"].Provider, { value: memoizedContextValue }, affix ? ( /*#__PURE__*/React.createElement(_affix["default"], { offsetTop: offsetTop, target: getCurrentContainer }, anchorContent)) : anchorContent); }; var Anchor = function Anchor(props) { var customizePrefixCls = props.prefixCls; var _React$useContext2 = React.useContext(_configProvider.ConfigContext), getPrefixCls = _React$useContext2.getPrefixCls; var anchorPrefixCls = getPrefixCls('anchor', customizePrefixCls); return /*#__PURE__*/React.createElement(AnchorContent, (0, _extends2["default"])({}, props, { anchorPrefixCls: anchorPrefixCls })); }; var _default = exports["default"] = Anchor;