UNPKG

organism-react-scroll-nav

Version:
178 lines (170 loc) 5.72 kB
"use strict"; var _interopRequireDefault = require("reshow-runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("reshow-runtime/helpers/interopRequireWildcard"); exports.__esModule = true; exports["default"] = void 0; var _objectSpread2 = _interopRequireDefault(require("reshow-runtime/helpers/objectSpread2")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("reshow-runtime/helpers/objectWithoutPropertiesLoose")); var React = _interopRequireWildcard(require("react")); var _smoothScrollTo = _interopRequireDefault(require("smooth-scroll-to")); var _getoffset = _interopRequireWildcard(require("getoffset")); var _callFunc = _interopRequireDefault(require("call-func")); var _winDoc = require("win-doc"); var _anchorLib = require("anchor-lib"); var _index = require("../../index.js"); var _scrollStore = _interopRequireDefault(require("../../stores/scrollStore.js")); var _fastScrollStore = _interopRequireDefault(require("../../stores/fastScrollStore.js")); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["targetId", "scrollRefLoc", "scrollRefId", "scrollMargin", "style", "preventDefault", "noDelay", "onClick"]; // @ts-check var useEffect = React.useEffect, useState = React.useState, useCallback = React.useCallback, useRef = React.useRef; var scollTimer = null; var resetTimer = function resetTimer() { if (scollTimer) { clearTimeout(scollTimer); scollTimer = null; } }; /** * @typedef {object} SmoothScrollLinkProps */ /** * @param {SmoothScrollLinkProps} props */ var useSmoothScrollLink = function useSmoothScrollLink(props) { var targetId = props.targetId, _props$scrollRefLoc = props.scrollRefLoc, scrollRefLoc = _props$scrollRefLoc === void 0 ? "bottom" : _props$scrollRefLoc, _props$scrollRefId = props.scrollRefId, scrollRefId = _props$scrollRefId === void 0 ? "" : _props$scrollRefId, scrollMargin = props.scrollMargin, style = props.style, _props$preventDefault = props.preventDefault, preventDefault = _props$preventDefault === void 0 ? true : _props$preventDefault, _props$noDelay = props.noDelay, noDelay = _props$noDelay === void 0 ? false : _props$noDelay, onClick = props.onClick, restProps = (0, _objectWithoutPropertiesLoose2["default"])(props, _excluded); /** * @type {[scrollRefElement, setScrollRefElement]} */ var _useState = useState(), scrollRefElement = _useState[0], setScrollRefElement = _useState[1]; /** @type {any} */ var lastScroll = useRef(null); /** * @param {number=} duringTime */ var _scrollTo = function scrollTo(duringTime) { var getStore = function getStore() { return noDelay ? _fastScrollStore["default"] : _scrollStore["default"]; }; var offset = getStore().scroller.getOffset(targetId); if (offset) { var margin = getMargin(); var to = offset.top - margin; /** * Let user could cancel scroll with different direction. */ if (lastScroll.current === to) { return; } setTimeout(function () { return lastScroll.current = to; }); (0, _smoothScrollTo["default"])(to, duringTime, undefined, function () { resetTimer(); scollTimer = setTimeout(function () { return _scrollTo(duringTime); }, 800); }); } }; useEffect(function () { var dom = (0, _winDoc.doc)().getElementById(scrollRefId); if (dom) { setScrollRefElement(dom); } if ((0, _anchorLib.getAnchorPath)().anchor.substring(1) === targetId) { setTimeout(function () { return _scrollTo(1); }); } return function () { resetTimer(); }; }, []); /** * When modify getMargin number, should also take care store isActive logic. * * https://github.com/react-atomic/organism-react-scroll-nav/blob/main/src/stores/scrollStore.js#L119 */ var getMargin = useCallback(function () { var margin = 0; if (scrollRefElement) { var refOffset = /**@type OffsetType*/(0, _getoffset["default"])(scrollRefElement); switch (scrollRefLoc) { case "bottom": margin += refOffset.bottom - refOffset.top; break; default: case "top": break; } } if (!isNaN(scrollMargin)) { margin += scrollMargin; } margin -= 2; return margin; }, [scrollRefLoc, scrollMargin, scrollRefElement]); var handler = { /** * @param {object} e */ click: function click(e) { lastScroll.current = null; if (preventDefault) { e.preventDefault(); } (0, _callFunc["default"])(onClick); _scrollTo(); } }; return { restProps: restProps, handler: handler, targetId: targetId, margin: getMargin(), style: style }; }; /** * @param {SmoothScrollLinkProps} props */ var SmoothScrollLink = function SmoothScrollLink(props) { var _useSmoothScrollLink = useSmoothScrollLink(props), restProps = _useSmoothScrollLink.restProps, handler = _useSmoothScrollLink.handler, margin = _useSmoothScrollLink.margin, style = _useSmoothScrollLink.style, targetId = _useSmoothScrollLink.targetId; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.ScrollReceiver, (0, _objectSpread2["default"])((0, _objectSpread2["default"])({ atom: "a" }, restProps), {}, { targetId: targetId, scrollMargin: margin, style: (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, Styles.link), style), onClick: handler.click })); }; var _default = exports["default"] = SmoothScrollLink; var Styles = { link: { cursor: "pointer" } }; module.exports = exports.default;