UNPKG

react-router-hash-link-offset

Version:
129 lines (107 loc) 4.07 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; exports.genericHashLink = genericHashLink; exports.HashLink = HashLink; exports.NavHashLink = NavHashLink; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactRouterDom = require('react-router-dom'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } var hashFragment = ''; var observer = null; var asyncTimerId = null; var scrollFunction = null; function reset() { hashFragment = ''; if (observer !== null) observer.disconnect(); if (asyncTimerId !== null) { window.clearTimeout(asyncTimerId); asyncTimerId = null; } } function getElAndScroll(scrollOffset) { var element = document.getElementById(hashFragment); if (element !== null) { scrollFunction(element); // now account for the optional scroll offset var scrolledY = window.scrollY; if (scrolledY) { window.scrollTo(0, scrolledY + scrollOffset); } reset(); return true; } return false; } function hashLinkScroll(scrollOffset) { // Push onto callback queue so it runs after the DOM is updated window.setTimeout(function () { if (getElAndScroll(scrollOffset) === false) { if (observer === null) { observer = new MutationObserver(getElAndScroll.bind(scrollOffset)); } observer.observe(document, { attributes: true, childList: true, subtree: true }); // if the element doesn't show up in 10 seconds, stop checking asyncTimerId = window.setTimeout(function () { reset(); }, 10000); } }, 0); } function genericHashLink(props, As) { var scrollOffset = props.scrollOffset, scroll = props.scroll, smooth = props.smooth, otherProps = _objectWithoutProperties(props, ['scrollOffset', 'scroll', 'smooth']); function handleClick(e) { reset(); if (otherProps.onClick) otherProps.onClick(e); if (typeof otherProps.to === 'string') { hashFragment = otherProps.to.split('#').slice(1).join('#'); } else if (_typeof(otherProps.to) === 'object' && typeof otherProps.to.hash === 'string') { hashFragment = otherProps.to.hash.replace('#', ''); } if (hashFragment !== '') { scrollFunction = scroll || function (el) { return smooth ? el.scrollIntoView({ behavior: 'smooth' }) : el.scrollIntoView(); }; hashLinkScroll(); } } return _react2.default.createElement( As, _extends({}, otherProps, { onClick: handleClick }), props.children ); } function HashLink(props) { return genericHashLink(props, _reactRouterDom.Link); } function NavHashLink(props) { return genericHashLink(props, _reactRouterDom.NavLink); } var propTypes = { onClick: _propTypes2.default.func, children: _propTypes2.default.node, scrollOffset: _propTypes2.default.number, scroll: _propTypes2.default.func, smooth: _propTypes2.default.bool, to: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.object]) }; HashLink.defaultProps = { scrollOffset: 0, smooth: false }; HashLink.propTypes = propTypes; NavHashLink.propTypes = propTypes;