diff --git a/demo-app/package-lock.json b/demo-app/package-lock.json index 5d57831..2bf65a0 100644 --- a/demo-app/package-lock.json +++ b/demo-app/package-lock.json @@ -19,7 +19,7 @@ "react-dom": "^17.0.2", "react-router-dom": "^6.0.2", "react-scripts": "4.0.3", - "react-ui-scrollspy": "file:react-ui-scrollspy-2.2.0.tgz", + "react-ui-scrollspy": "file:react-ui-scrollspy-2.3.1.tgz", "typescript": "^4.4.4", "web-vitals": "^1.1.2" }, @@ -4202,6 +4202,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", @@ -16486,13 +16497,12 @@ } }, "node_modules/react-ui-scrollspy": { - "version": "2.2.0", - "resolved": "file:react-ui-scrollspy-2.2.0.tgz", - "integrity": "sha512-zbD9AYc+et7LsPCC6d+hwZEsrhkxCQjOPpTwP84prHhdMpcvH/NCaUJC5fLVVUFZ8fu/ufH9xJD2k2Cor3RGnw==", - "license": "MIT", + "version": "2.3.1", + "resolved": "file:react-ui-scrollspy-2.3.1.tgz", + "integrity": "sha512-96y32DZzLKeZxnCdvgQiSE1iNaGM2OnFuDxrSnkg5eZZJrpbowlBbC14VvongkL1GP6FLh87zdm7CII/rvPLyw==", "peerDependencies": { - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, "node_modules/read-pkg": { @@ -19330,9 +19340,11 @@ } }, "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -24612,6 +24624,13 @@ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "requires": { "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + } } }, "ansi-html": { @@ -34098,8 +34117,8 @@ } }, "react-ui-scrollspy": { - "version": "file:react-ui-scrollspy-2.2.0.tgz", - "integrity": "sha512-zbD9AYc+et7LsPCC6d+hwZEsrhkxCQjOPpTwP84prHhdMpcvH/NCaUJC5fLVVUFZ8fu/ufH9xJD2k2Cor3RGnw==", + "version": "file:react-ui-scrollspy-2.3.1.tgz", + "integrity": "sha512-96y32DZzLKeZxnCdvgQiSE1iNaGM2OnFuDxrSnkg5eZZJrpbowlBbC14VvongkL1GP6FLh87zdm7CII/rvPLyw==", "requires": {} }, "read-pkg": { @@ -36346,9 +36365,11 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "peer": true }, "type-is": { "version": "1.6.18", diff --git a/demo-app/package.json b/demo-app/package.json index 31872f7..adbae91 100644 --- a/demo-app/package.json +++ b/demo-app/package.json @@ -15,7 +15,7 @@ "react-dom": "^17.0.2", "react-router-dom": "^6.0.2", "react-scripts": "4.0.3", - "react-ui-scrollspy": "file:react-ui-scrollspy-2.2.0.tgz", + "react-ui-scrollspy": "file:react-ui-scrollspy-2.3.1.tgz", "typescript": "^4.4.4", "web-vitals": "^1.1.2" }, diff --git a/dist/ScrollSpy/ScrollSpy.js b/dist/ScrollSpy/ScrollSpy.js new file mode 100644 index 0000000..0dcc8b4 --- /dev/null +++ b/dist/ScrollSpy/ScrollSpy.js @@ -0,0 +1,149 @@ +"use client"; +Object.defineProperty(exports, '__esModule', { value: true }); + +var React = require('react'); +var throttle = require('../utils/throttle.js'); + +function _interopNamespace(e) { + if (e && e.__esModule) return e; + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + if (k !== 'default') { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty(n, k, d.get ? d : { + enumerable: true, + get: function () { return e[k]; } + }); + } + }); + } + n["default"] = e; + return Object.freeze(n); +} + +var React__namespace = /*#__PURE__*/_interopNamespace(React); + +var ScrollSpy = function (_a) { + var children = _a.children, + // refs + navContainerRef = _a.navContainerRef, parentScrollContainerRef = _a.parentScrollContainerRef, + // throttle + _b = _a.scrollThrottle, + // throttle + scrollThrottle = _b === void 0 ? 300 : _b, + // callback + onUpdateCallback = _a.onUpdateCallback, + // offsets + _c = _a.offsetTop, + // offsets + offsetTop = _c === void 0 ? 0 : _c, _d = _a.offsetBottom, offsetBottom = _d === void 0 ? 0 : _d, + // customize attributes + _e = _a.useDataAttribute, + // customize attributes + useDataAttribute = _e === void 0 ? "to-scrollspy-id" : _e, _f = _a.activeClass, activeClass = _f === void 0 ? "active-scroll-spy" : _f, _g = _a.useBoxMethod, useBoxMethod = _g === void 0 ? true : _g, _h = _a.updateHistoryStack, updateHistoryStack = _h === void 0 ? true : _h; + var scrollContainerRef = React.useRef(null); + var _j = React.useState(), navContainerItems = _j[0], setNavContainerItems = _j[1]; // prettier-ignore + // keeps track of the Id in navcontainer which is active + // so as to not update classLists unless it has been updated + var prevIdTracker = React.useRef(""); + // To get the nav container items depending on whether the parent ref for the nav container is passed or not + React.useEffect(function () { + var _a; + navContainerRef + ? setNavContainerItems((_a = navContainerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("[data-".concat(useDataAttribute, "]"))) + : setNavContainerItems(document.querySelectorAll("[data-".concat(useDataAttribute, "]"))); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [navContainerRef]); + // fire once after nav container items are set + React.useEffect(function () { + checkAndUpdateActiveScrollSpy(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [navContainerItems]); + var isVisible = function (el) { + var rectInView = el.getBoundingClientRect(); + if (useBoxMethod) { + var useHeight = (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current) + ? parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current.offsetHeight + : window.innerHeight; + var hitbox_top = useHeight; + var element_top = rectInView.top; + var element_bottom = rectInView.top + useHeight; + return (hitbox_top < element_bottom + offsetBottom && + hitbox_top > element_top - offsetTop); + } + else { + // this decides how much of the element should be visible + var leniency = (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current) + ? (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current.offsetHeight) * 0.5 + : window.innerHeight * 0.5; + var useHeight = (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current) + ? parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current.offsetHeight + : window.innerHeight; + return (rectInView.top + leniency + offsetTop >= 0 && + rectInView.bottom - leniency - offsetBottom <= useHeight); + } + }; + var checkAndUpdateActiveScrollSpy = function () { + var scrollParentContainer = scrollContainerRef.current; + // if there are no children, return + if (!(scrollParentContainer && navContainerItems)) + return; + var _loop_1 = function (i) { + // get child element + var useChild = scrollParentContainer.children.item(i); + var elementIsVisible = isVisible(useChild); + // check if the element is in the viewport + if (elementIsVisible) { + // if so, get its ID + var changeHighlightedItemId_1 = useChild.id; + // if the element was same as the one currently active ignore it + if (prevIdTracker.current === changeHighlightedItemId_1) + return { value: void 0 }; + // now loop over each element in the nav Container + navContainerItems.forEach(function (el) { + var attrId = el.getAttribute("data-".concat(useDataAttribute)); + // if the element contains 'active' the class remove it + if (el.classList.contains(activeClass)) { + el.classList.remove(activeClass); + } + // check if its ID matches the ID we got from the viewport + // also make sure it does not already contain the 'active' class + if (attrId === changeHighlightedItemId_1 && + !el.classList.contains(activeClass)) { + el.classList.add(activeClass); + if (onUpdateCallback) { + onUpdateCallback(changeHighlightedItemId_1); + } + prevIdTracker.current = changeHighlightedItemId_1; + if (updateHistoryStack) { + window.history.replaceState({}, "", "#".concat(changeHighlightedItemId_1)); + } + } + }); + return "break"; + } + }; + // loop over all children in scroll container + for (var i = 0; i < scrollParentContainer.children.length; i++) { + var state_1 = _loop_1(i); + if (typeof state_1 === "object") + return state_1.value; + if (state_1 === "break") + break; + } + }; + React.useEffect(function () { + var _a; + // listen for scroll event + parentScrollContainerRef + ? // if ref for scrollable div is provided + (_a = parentScrollContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener("scroll", throttle.throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)) + : // else listen for scroll in window + window.addEventListener("scroll", throttle.throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)); + }); + return React__namespace.createElement("div", { ref: scrollContainerRef }, children); +}; + +exports["default"] = ScrollSpy; +//# sourceMappingURL=ScrollSpy.js.map diff --git a/dist/ScrollSpy/ScrollSpy.js.map b/dist/ScrollSpy/ScrollSpy.js.map new file mode 100644 index 0000000..17233b0 --- /dev/null +++ b/dist/ScrollSpy/ScrollSpy.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ScrollSpy.js","sources":["../../src/ScrollSpy/ScrollSpy.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport {\n MutableRefObject,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { throttle } from \"../utils/throttle\";\n\ninterface ScrollSpyProps {\n children: ReactNode;\n\n // refs\n navContainerRef?: MutableRefObject;\n parentScrollContainerRef?: MutableRefObject;\n\n // throttle\n scrollThrottle?: number;\n\n // callback\n onUpdateCallback?: (id: string) => void;\n\n // offsets\n offsetTop?: number;\n offsetBottom?: number;\n\n // customize attributes\n useDataAttribute?: string;\n activeClass?: string;\n\n useBoxMethod?: boolean;\n updateHistoryStack?: boolean;\n}\n\nconst ScrollSpy = ({\n children,\n\n // refs\n navContainerRef,\n parentScrollContainerRef,\n\n // throttle\n scrollThrottle = 300,\n\n // callback\n onUpdateCallback,\n\n // offsets\n offsetTop = 0,\n offsetBottom = 0,\n\n // customize attributes\n useDataAttribute = \"to-scrollspy-id\",\n activeClass = \"active-scroll-spy\",\n\n useBoxMethod = true,\n updateHistoryStack = true,\n}: ScrollSpyProps) => {\n const scrollContainerRef = useRef(null);\n const [navContainerItems, setNavContainerItems] = useState | undefined>(); // prettier-ignore\n\n // keeps track of the Id in navcontainer which is active\n // so as to not update classLists unless it has been updated\n const prevIdTracker = useRef(\"\");\n\n // To get the nav container items depending on whether the parent ref for the nav container is passed or not\n useEffect(() => {\n navContainerRef\n ? setNavContainerItems(\n navContainerRef.current?.querySelectorAll(\n `[data-${useDataAttribute}]`\n )\n )\n : setNavContainerItems(\n document.querySelectorAll(`[data-${useDataAttribute}]`)\n );\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [navContainerRef]);\n\n // fire once after nav container items are set\n useEffect(() => {\n checkAndUpdateActiveScrollSpy();\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [navContainerItems]);\n\n const isVisible = (el: HTMLElement) => {\n const rectInView = el.getBoundingClientRect();\n\n if (useBoxMethod) {\n const useHeight = parentScrollContainerRef?.current\n ? parentScrollContainerRef?.current.offsetHeight\n : window.innerHeight;\n const hitbox_top = useHeight;\n const element_top = rectInView.top;\n const element_bottom = rectInView.top + useHeight;\n\n return (\n hitbox_top < element_bottom + offsetBottom &&\n hitbox_top > element_top - offsetTop\n );\n } else {\n // this decides how much of the element should be visible\n const leniency = parentScrollContainerRef?.current\n ? parentScrollContainerRef?.current.offsetHeight * 0.5\n : window.innerHeight * 0.5;\n\n const useHeight = parentScrollContainerRef?.current\n ? parentScrollContainerRef?.current.offsetHeight\n : window.innerHeight;\n\n return (\n rectInView.top + leniency + offsetTop >= 0 &&\n rectInView.bottom - leniency - offsetBottom <= useHeight\n );\n }\n };\n\n const checkAndUpdateActiveScrollSpy = () => {\n const scrollParentContainer = scrollContainerRef.current;\n\n // if there are no children, return\n if (!(scrollParentContainer && navContainerItems)) return;\n\n // loop over all children in scroll container\n for (let i = 0; i < scrollParentContainer.children.length; i++) {\n // get child element\n const useChild = scrollParentContainer.children.item(i) as HTMLDivElement;\n\n const elementIsVisible = isVisible(useChild);\n\n // check if the element is in the viewport\n if (elementIsVisible) {\n // if so, get its ID\n const changeHighlightedItemId = useChild.id;\n\n // if the element was same as the one currently active ignore it\n if (prevIdTracker.current === changeHighlightedItemId) return;\n\n // now loop over each element in the nav Container\n navContainerItems.forEach((el) => {\n const attrId = el.getAttribute(`data-${useDataAttribute}`);\n\n // if the element contains 'active' the class remove it\n if (el.classList.contains(activeClass)) {\n el.classList.remove(activeClass);\n }\n\n // check if its ID matches the ID we got from the viewport\n // also make sure it does not already contain the 'active' class\n if (\n attrId === changeHighlightedItemId &&\n !el.classList.contains(activeClass)\n ) {\n el.classList.add(activeClass);\n\n if (onUpdateCallback) {\n onUpdateCallback(changeHighlightedItemId);\n }\n\n prevIdTracker.current = changeHighlightedItemId;\n if (updateHistoryStack) {\n window.history.replaceState(\n {},\n \"\",\n `#${changeHighlightedItemId}`\n );\n }\n }\n });\n break;\n }\n }\n };\n\n useEffect(() => {\n // listen for scroll event\n parentScrollContainerRef\n ? // if ref for scrollable div is provided\n parentScrollContainerRef.current?.addEventListener(\n \"scroll\",\n throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)\n )\n : // else listen for scroll in window\n window.addEventListener(\n \"scroll\",\n throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)\n );\n });\n\n return
{children}
;\n};\n\nexport default ScrollSpy;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAqCM;AACJ;;;;;;;;AAUA;;;;;;;;;AAaA;;;;AAKA;;AAGA;;;AAEI;AAKA;;AAKJ;;AAGA;AACE;;AAGF;;AAGE;AAEA;;;AAGI;;AAEF;AACA;AAEA;AAEE;AAEH;AAAM;;;AAGH;AACA;;;AAIA;;;AAMH;AACH;AAEA;AACE;;AAGA;;;;;AAOE;;AAGA;;AAEE;;AAGA;AAA8D;;AAG9D;;;;AAKI;AACD;;;;;AAQC;AAEA;;AAEC;AAED;AACA;AACE;AAKD;AACF;AACH;;AAED;;;AA9CH;;;;;;AA+CC;AACH;AAEA;;;;AAGI;AACE;AAIF;AACE;AAIN;AAEA;AACF;;"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 83ffe0a..9a05a84 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,160 +1,8 @@ Object.defineProperty(exports, '__esModule', { value: true }); -var React = require('react'); +var ScrollSpy = require('./ScrollSpy/ScrollSpy.js'); -function _interopNamespace(e) { - if (e && e.__esModule) return e; - var n = Object.create(null); - if (e) { - Object.keys(e).forEach(function (k) { - if (k !== 'default') { - var d = Object.getOwnPropertyDescriptor(e, k); - Object.defineProperty(n, k, d.get ? d : { - enumerable: true, - get: function () { return e[k]; } - }); - } - }); - } - n["default"] = e; - return Object.freeze(n); -} -var React__namespace = /*#__PURE__*/_interopNamespace(React); -var throttle = function (callback, limit) { - var tick = false; - return function () { - if (!tick) { - callback(); - tick = true; - setTimeout(function () { - tick = false; - }, limit); - } - }; -}; - -var ScrollSpy = function (_a) { - var children = _a.children, - // refs - navContainerRef = _a.navContainerRef, parentScrollContainerRef = _a.parentScrollContainerRef, - // throttle - _b = _a.scrollThrottle, - // throttle - scrollThrottle = _b === void 0 ? 300 : _b, - // callback - onUpdateCallback = _a.onUpdateCallback, - // offsets - _c = _a.offsetTop, - // offsets - offsetTop = _c === void 0 ? 0 : _c, _d = _a.offsetBottom, offsetBottom = _d === void 0 ? 0 : _d, - // customize attributes - _e = _a.useDataAttribute, - // customize attributes - useDataAttribute = _e === void 0 ? "to-scrollspy-id" : _e, _f = _a.activeClass, activeClass = _f === void 0 ? "active-scroll-spy" : _f, _g = _a.useBoxMethod, useBoxMethod = _g === void 0 ? true : _g, _h = _a.updateHistoryStack, updateHistoryStack = _h === void 0 ? true : _h; - var scrollContainerRef = React.useRef(null); - var _j = React.useState(), navContainerItems = _j[0], setNavContainerItems = _j[1]; // prettier-ignore - // keeps track of the Id in navcontainer which is active - // so as to not update classLists unless it has been updated - var prevIdTracker = React.useRef(""); - // To get the nav container items depending on whether the parent ref for the nav container is passed or not - React.useEffect(function () { - var _a; - navContainerRef - ? setNavContainerItems((_a = navContainerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("[data-".concat(useDataAttribute, "]"))) - : setNavContainerItems(document.querySelectorAll("[data-".concat(useDataAttribute, "]"))); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [navContainerRef]); - // fire once after nav container items are set - React.useEffect(function () { - checkAndUpdateActiveScrollSpy(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [navContainerItems]); - var isVisible = function (el) { - var rectInView = el.getBoundingClientRect(); - if (useBoxMethod) { - var useHeight = (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current) - ? parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current.offsetHeight - : window.innerHeight; - var hitbox_top = useHeight; - var element_top = rectInView.top; - var element_bottom = rectInView.top + useHeight; - return (hitbox_top < element_bottom + offsetBottom && - hitbox_top > element_top - offsetTop); - } - else { - // this decides how much of the element should be visible - var leniency = (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current) - ? (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current.offsetHeight) * 0.5 - : window.innerHeight * 0.5; - var useHeight = (parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current) - ? parentScrollContainerRef === null || parentScrollContainerRef === void 0 ? void 0 : parentScrollContainerRef.current.offsetHeight - : window.innerHeight; - return (rectInView.top + leniency + offsetTop >= 0 && - rectInView.bottom - leniency - offsetBottom <= useHeight); - } - }; - var checkAndUpdateActiveScrollSpy = function () { - var scrollParentContainer = scrollContainerRef.current; - // if there are no children, return - if (!(scrollParentContainer && navContainerItems)) - return; - var _loop_1 = function (i) { - // get child element - var useChild = scrollParentContainer.children.item(i); - var elementIsVisible = isVisible(useChild); - // check if the element is in the viewport - if (elementIsVisible) { - // if so, get its ID - var changeHighlightedItemId_1 = useChild.id; - // if the element was same as the one currently active ignore it - if (prevIdTracker.current === changeHighlightedItemId_1) - return { value: void 0 }; - // now loop over each element in the nav Container - navContainerItems.forEach(function (el) { - var attrId = el.getAttribute("data-".concat(useDataAttribute)); - // if the element contains 'active' the class remove it - if (el.classList.contains(activeClass)) { - el.classList.remove(activeClass); - } - // check if its ID matches the ID we got from the viewport - // also make sure it does not already contain the 'active' class - if (attrId === changeHighlightedItemId_1 && - !el.classList.contains(activeClass)) { - el.classList.add(activeClass); - if (onUpdateCallback) { - onUpdateCallback(changeHighlightedItemId_1); - } - prevIdTracker.current = changeHighlightedItemId_1; - if (updateHistoryStack) { - window.history.replaceState({}, "", "#".concat(changeHighlightedItemId_1)); - } - } - }); - return "break"; - } - }; - // loop over all children in scroll container - for (var i = 0; i < scrollParentContainer.children.length; i++) { - var state_1 = _loop_1(i); - if (typeof state_1 === "object") - return state_1.value; - if (state_1 === "break") - break; - } - }; - React.useEffect(function () { - var _a; - // listen for scroll event - parentScrollContainerRef - ? // if ref for scrollable div is provided - (_a = parentScrollContainerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener("scroll", throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)) - : // else listen for scroll in window - window.addEventListener("scroll", throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)); - }); - return React__namespace.createElement("div", { ref: scrollContainerRef }, children); -}; - -exports["default"] = ScrollSpy; +exports["default"] = ScrollSpy["default"]; //# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map index ecb12ea..8a81f37 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/utils/throttle.ts","../src/ScrollSpy/ScrollSpy.tsx"],"sourcesContent":["export const throttle = (callback: () => void, limit: number) => {\n var tick = false;\n\n return () => {\n if (!tick) {\n callback();\n tick = true;\n setTimeout(function () {\n tick = false;\n }, limit);\n }\n };\n};\n","import * as React from \"react\";\nimport {\n MutableRefObject,\n ReactNode,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { throttle } from \"../utils/throttle\";\n\ninterface ScrollSpyProps {\n children: ReactNode;\n\n // refs\n navContainerRef?: MutableRefObject;\n parentScrollContainerRef?: MutableRefObject;\n\n // throttle\n scrollThrottle?: number;\n\n // callback\n onUpdateCallback?: (id: string) => void;\n\n // offsets\n offsetTop?: number;\n offsetBottom?: number;\n\n // customize attributes\n useDataAttribute?: string;\n activeClass?: string;\n\n useBoxMethod?: boolean;\n updateHistoryStack?: boolean;\n}\n\nconst ScrollSpy = ({\n children,\n\n // refs\n navContainerRef,\n parentScrollContainerRef,\n\n // throttle\n scrollThrottle = 300,\n\n // callback\n onUpdateCallback,\n\n // offsets\n offsetTop = 0,\n offsetBottom = 0,\n\n // customize attributes\n useDataAttribute = \"to-scrollspy-id\",\n activeClass = \"active-scroll-spy\",\n\n useBoxMethod = true,\n updateHistoryStack = true,\n}: ScrollSpyProps) => {\n const scrollContainerRef = useRef(null);\n const [navContainerItems, setNavContainerItems] = useState | undefined>(); // prettier-ignore\n\n // keeps track of the Id in navcontainer which is active\n // so as to not update classLists unless it has been updated\n const prevIdTracker = useRef(\"\");\n\n // To get the nav container items depending on whether the parent ref for the nav container is passed or not\n useEffect(() => {\n navContainerRef\n ? setNavContainerItems(\n navContainerRef.current?.querySelectorAll(\n `[data-${useDataAttribute}]`\n )\n )\n : setNavContainerItems(\n document.querySelectorAll(`[data-${useDataAttribute}]`)\n );\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [navContainerRef]);\n\n // fire once after nav container items are set\n useEffect(() => {\n checkAndUpdateActiveScrollSpy();\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [navContainerItems]);\n\n const isVisible = (el: HTMLElement) => {\n const rectInView = el.getBoundingClientRect();\n\n if (useBoxMethod) {\n const useHeight = parentScrollContainerRef?.current\n ? parentScrollContainerRef?.current.offsetHeight\n : window.innerHeight;\n const hitbox_top = useHeight;\n const element_top = rectInView.top;\n const element_bottom = rectInView.top + useHeight;\n\n return (\n hitbox_top < element_bottom + offsetBottom &&\n hitbox_top > element_top - offsetTop\n );\n } else {\n // this decides how much of the element should be visible\n const leniency = parentScrollContainerRef?.current\n ? parentScrollContainerRef?.current.offsetHeight * 0.5\n : window.innerHeight * 0.5;\n\n const useHeight = parentScrollContainerRef?.current\n ? parentScrollContainerRef?.current.offsetHeight\n : window.innerHeight;\n\n return (\n rectInView.top + leniency + offsetTop >= 0 &&\n rectInView.bottom - leniency - offsetBottom <= useHeight\n );\n }\n };\n\n const checkAndUpdateActiveScrollSpy = () => {\n const scrollParentContainer = scrollContainerRef.current;\n\n // if there are no children, return\n if (!(scrollParentContainer && navContainerItems)) return;\n\n // loop over all children in scroll container\n for (let i = 0; i < scrollParentContainer.children.length; i++) {\n // get child element\n const useChild = scrollParentContainer.children.item(i) as HTMLDivElement;\n\n const elementIsVisible = isVisible(useChild);\n\n // check if the element is in the viewport\n if (elementIsVisible) {\n // if so, get its ID\n const changeHighlightedItemId = useChild.id;\n\n // if the element was same as the one currently active ignore it\n if (prevIdTracker.current === changeHighlightedItemId) return;\n\n // now loop over each element in the nav Container\n navContainerItems.forEach((el) => {\n const attrId = el.getAttribute(`data-${useDataAttribute}`);\n\n // if the element contains 'active' the class remove it\n if (el.classList.contains(activeClass)) {\n el.classList.remove(activeClass);\n }\n\n // check if its ID matches the ID we got from the viewport\n // also make sure it does not already contain the 'active' class\n if (\n attrId === changeHighlightedItemId &&\n !el.classList.contains(activeClass)\n ) {\n el.classList.add(activeClass);\n\n if (onUpdateCallback) {\n onUpdateCallback(changeHighlightedItemId);\n }\n\n prevIdTracker.current = changeHighlightedItemId;\n if (updateHistoryStack) {\n window.history.replaceState(\n {},\n \"\",\n `#${changeHighlightedItemId}`\n );\n }\n }\n });\n break;\n }\n }\n };\n\n useEffect(() => {\n // listen for scroll event\n parentScrollContainerRef\n ? // if ref for scrollable div is provided\n parentScrollContainerRef.current?.addEventListener(\n \"scroll\",\n throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)\n )\n : // else listen for scroll in window\n window.addEventListener(\n \"scroll\",\n throttle(checkAndUpdateActiveScrollSpy, scrollThrottle)\n );\n });\n\n return
{children}
;\n};\n\nexport default ScrollSpy;\n"],"names":["useRef","useState","useEffect","React"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAO,IAAM,QAAQ,GAAG,UAAC,QAAoB,EAAE,KAAa,EAAA;IAC1D,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,OAAO,YAAA;QACL,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,QAAQ,EAAE,CAAC;YACX,IAAI,GAAG,IAAI,CAAC;AACZ,YAAA,UAAU,CAAC,YAAA;gBACT,IAAI,GAAG,KAAK,CAAC;aACd,EAAE,KAAK,CAAC,CAAC;AACX,SAAA;AACH,KAAC,CAAC;AACJ,CAAC;;ACuBK,IAAA,SAAS,GAAG,UAAC,EAuBF,EAAA;AAtBf,IAAA,IAAA,QAAQ,GAAA,EAAA,CAAA,QAAA;;IAGR,eAAe,GAAA,EAAA,CAAA,eAAA,EACf,wBAAwB,GAAA,EAAA,CAAA,wBAAA;;IAGxB,EAAoB,GAAA,EAAA,CAAA,cAAA;;IAApB,cAAc,GAAA,EAAA,KAAA,KAAA,CAAA,GAAG,GAAG,GAAA,EAAA;;AAGpB,IAAA,gBAAgB,GAAA,EAAA,CAAA,gBAAA;;IAGhB,EAAa,GAAA,EAAA,CAAA,SAAA;;IAAb,SAAS,GAAA,EAAA,KAAA,KAAA,CAAA,GAAG,CAAC,GAAA,EAAA,EACb,oBAAgB,EAAhB,YAAY,GAAG,EAAA,KAAA,KAAA,CAAA,GAAA,CAAC,GAAA,EAAA;;IAGhB,EAAoC,GAAA,EAAA,CAAA,gBAAA;;IAApC,gBAAgB,GAAA,EAAA,KAAA,KAAA,CAAA,GAAG,iBAAiB,GAAA,EAAA,EACpC,mBAAiC,EAAjC,WAAW,GAAG,EAAA,KAAA,KAAA,CAAA,GAAA,mBAAmB,GAAA,EAAA,EAEjC,oBAAmB,EAAnB,YAAY,GAAG,EAAA,KAAA,KAAA,CAAA,GAAA,IAAI,GAAA,EAAA,EACnB,0BAAyB,EAAzB,kBAAkB,GAAG,EAAA,KAAA,KAAA,CAAA,GAAA,IAAI,GAAA,EAAA,CAAA;AAEzB,IAAA,IAAM,kBAAkB,GAAGA,YAAM,CAAwB,IAAI,CAAC,CAAC;IACzD,IAAA,EAAA,GAA4CC,cAAQ,EAAmC,EAAtF,iBAAiB,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,oBAAoB,GAAA,EAAA,CAAA,CAAA,CAA+C,CAAC;;;AAI9F,IAAA,IAAM,aAAa,GAAGD,YAAM,CAAC,EAAE,CAAC,CAAC;;AAGjC,IAAAE,eAAS,CAAC,YAAA;;QACR,eAAe;AACb,cAAE,oBAAoB,CAClB,CAAA,EAAA,GAAA,eAAe,CAAC,OAAO,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,gBAAgB,CACvC,QAAA,CAAA,MAAA,CAAS,gBAAgB,EAAA,GAAA,CAAG,CAC7B,CACF;AACH,cAAE,oBAAoB,CAClB,QAAQ,CAAC,gBAAgB,CAAC,QAAA,CAAA,MAAA,CAAS,gBAAgB,EAAA,GAAA,CAAG,CAAC,CACxD,CAAC;;AAGR,KAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;;AAGtB,IAAAA,eAAS,CAAC,YAAA;AACR,QAAA,6BAA6B,EAAE,CAAC;;AAGlC,KAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAExB,IAAM,SAAS,GAAG,UAAC,EAAe,EAAA;AAChC,QAAA,IAAM,UAAU,GAAG,EAAE,CAAC,qBAAqB,EAAE,CAAC;AAE9C,QAAA,IAAI,YAAY,EAAE;YAChB,IAAM,SAAS,GAAG,CAAA,wBAAwB,aAAxB,wBAAwB,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAxB,wBAAwB,CAAE,OAAO;kBAC/C,wBAAwB,KAAxB,IAAA,IAAA,wBAAwB,uBAAxB,wBAAwB,CAAE,OAAO,CAAC,YAAY;AAChD,kBAAE,MAAM,CAAC,WAAW,CAAC;YACvB,IAAM,UAAU,GAAG,SAAS,CAAC;AAC7B,YAAA,IAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;AACnC,YAAA,IAAM,cAAc,GAAG,UAAU,CAAC,GAAG,GAAG,SAAS,CAAC;AAElD,YAAA,QACE,UAAU,GAAG,cAAc,GAAG,YAAY;AAC1C,gBAAA,UAAU,GAAG,WAAW,GAAG,SAAS,EACpC;AACH,SAAA;AAAM,aAAA;;YAEL,IAAM,QAAQ,GAAG,CAAA,wBAAwB,aAAxB,wBAAwB,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAxB,wBAAwB,CAAE,OAAO;AAChD,kBAAE,CAAA,wBAAwB,KAAA,IAAA,IAAxB,wBAAwB,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAxB,wBAAwB,CAAE,OAAO,CAAC,YAAY,IAAG,GAAG;AACtD,kBAAE,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC;YAE7B,IAAM,SAAS,GAAG,CAAA,wBAAwB,aAAxB,wBAAwB,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAxB,wBAAwB,CAAE,OAAO;kBAC/C,wBAAwB,KAAxB,IAAA,IAAA,wBAAwB,uBAAxB,wBAAwB,CAAE,OAAO,CAAC,YAAY;AAChD,kBAAE,MAAM,CAAC,WAAW,CAAC;YAEvB,QACE,UAAU,CAAC,GAAG,GAAG,QAAQ,GAAG,SAAS,IAAI,CAAC;gBAC1C,UAAU,CAAC,MAAM,GAAG,QAAQ,GAAG,YAAY,IAAI,SAAS,EACxD;AACH,SAAA;AACH,KAAC,CAAC;AAEF,IAAA,IAAM,6BAA6B,GAAG,YAAA;AACpC,QAAA,IAAM,qBAAqB,GAAG,kBAAkB,CAAC,OAAO,CAAC;;AAGzD,QAAA,IAAI,EAAE,qBAAqB,IAAI,iBAAiB,CAAC;YAAE,OAAO;gCAGjD,CAAC,EAAA;;YAER,IAAM,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAmB,CAAC;AAE1E,YAAA,IAAM,gBAAgB,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;;AAG7C,YAAA,IAAI,gBAAgB,EAAE;;AAEpB,gBAAA,IAAM,yBAAuB,GAAG,QAAQ,CAAC,EAAE,CAAC;;AAG5C,gBAAA,IAAI,aAAa,CAAC,OAAO,KAAK,yBAAuB;AAAS,oBAAA,OAAA,EAAA,KAAA,EAAA,KAAA,CAAA,EAAA,CAAA;;AAG9D,gBAAA,iBAAiB,CAAC,OAAO,CAAC,UAAC,EAAE,EAAA;oBAC3B,IAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,OAAQ,CAAA,MAAA,CAAA,gBAAgB,CAAE,CAAC,CAAC;;oBAG3D,IAAI,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE;AACtC,wBAAA,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAClC,qBAAA;;;oBAID,IACE,MAAM,KAAK,yBAAuB;wBAClC,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,EACnC;AACA,wBAAA,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAE9B,wBAAA,IAAI,gBAAgB,EAAE;4BACpB,gBAAgB,CAAC,yBAAuB,CAAC,CAAC;AAC3C,yBAAA;AAED,wBAAA,aAAa,CAAC,OAAO,GAAG,yBAAuB,CAAC;AAChD,wBAAA,IAAI,kBAAkB,EAAE;AACtB,4BAAA,MAAM,CAAC,OAAO,CAAC,YAAY,CACzB,EAAE,EACF,EAAE,EACF,GAAA,CAAA,MAAA,CAAI,yBAAuB,CAAE,CAC9B,CAAC;AACH,yBAAA;AACF,qBAAA;AACH,iBAAC,CAAC,CAAC;;AAEJ,aAAA;;;AA9CH,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAA;kCAArD,CAAC,CAAA,CAAA;;;;;AA+CT,SAAA;AACH,KAAC,CAAC;AAEF,IAAAA,eAAS,CAAC,YAAA;;;QAER,wBAAwB;AACtB;AACE,gBAAA,CAAA,EAAA,GAAA,wBAAwB,CAAC,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,gBAAgB,CAChD,QAAQ,EACR,QAAQ,CAAC,6BAA6B,EAAE,cAAc,CAAC,CACxD;AACH;AACE,gBAAA,MAAM,CAAC,gBAAgB,CACrB,QAAQ,EACR,QAAQ,CAAC,6BAA6B,EAAE,cAAc,CAAC,CACxD,CAAC;AACR,KAAC,CAAC,CAAC;AAEH,IAAA,OAAOC,wCAAK,GAAG,EAAE,kBAAkB,EAAG,EAAA,QAAQ,CAAO,CAAC;AACxD;;;;"} \ No newline at end of file +{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"} \ No newline at end of file diff --git a/dist/utils/isVisible.d.ts b/dist/utils/isVisible.d.ts deleted file mode 100644 index 2c1fe97..0000000 --- a/dist/utils/isVisible.d.ts +++ /dev/null @@ -1 +0,0 @@ -export declare const isVisible: (el: HTMLElement, offsetTop: number, offsetBottom: number, scrollableComponentRef?: HTMLDivElement | null | undefined) => boolean; diff --git a/dist/utils/throttle.js b/dist/utils/throttle.js new file mode 100644 index 0000000..7aa6ac8 --- /dev/null +++ b/dist/utils/throttle.js @@ -0,0 +1,17 @@ +Object.defineProperty(exports, '__esModule', { value: true }); + +var throttle = function (callback, limit) { + var tick = false; + return function () { + if (!tick) { + callback(); + tick = true; + setTimeout(function () { + tick = false; + }, limit); + } + }; +}; + +exports.throttle = throttle; +//# sourceMappingURL=throttle.js.map diff --git a/dist/utils/throttle.js.map b/dist/utils/throttle.js.map new file mode 100644 index 0000000..704e8f4 --- /dev/null +++ b/dist/utils/throttle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"throttle.js","sources":["../../src/utils/throttle.ts"],"sourcesContent":["export const throttle = (callback: () => void, limit: number) => {\n var tick = false;\n\n return () => {\n if (!tick) {\n callback();\n tick = true;\n setTimeout(function () {\n tick = false;\n }, limit);\n }\n };\n};\n"],"names":[],"mappings":";;AAAa,IAAA,QAAQ,GAAG,UAAC,QAAoB,EAAE,KAAa,EAAA;IAC1D,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,OAAO,YAAA;QACL,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,QAAQ,EAAE,CAAC;YACX,IAAI,GAAG,IAAI,CAAC;AACZ,YAAA,UAAU,CAAC,YAAA;gBACT,IAAI,GAAG,KAAK,CAAC;aACd,EAAE,KAAK,CAAC,CAAC;AACX,SAAA;AACH,KAAC,CAAC;AACJ;;;;"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5939562..aed7e92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,30 +1,37 @@ { "name": "react-ui-scrollspy", - "version": "2.2.0", + "version": "2.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "react-ui-scrollspy", - "version": "2.2.0", + "version": "2.3.1", "license": "MIT", "devDependencies": { "@types/react": "^17.0.33", "@types/react-dom": "^17.0.10", "babel-core": "^6.26.3", "babel-runtime": "^6.26.0", - "react": "^18.0.2", - "react-dom": "^18.0.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", "rollup": "^2.59.0", + "rollup-plugin-preserve-directives": "^0.4.0", "rollup-plugin-typescript2": "^0.31.0", "tslib": "^2.4.1", "typescript": "^4.9.4" }, "peerDependencies": { - "react": "^18.0.2", - "react-dom": "^18.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" } }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "node_modules/@rollup/pluginutils": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", @@ -38,6 +45,12 @@ "node": ">= 8.0.0" } }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -648,6 +661,15 @@ "loose-envify": "cli.js" } }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -909,6 +931,41 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-preserve-directives": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-preserve-directives/-/rollup-plugin-preserve-directives-0.4.0.tgz", + "integrity": "sha512-gx4nBxYm5BysmEQS+e2tAMrtFxrGvk+Pe5ppafRibQi0zlW7VYAbEGk6IKDw9sJGPdFWgVTE0o4BU4cdG0Fylg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "magic-string": "^0.30.5" + }, + "peerDependencies": { + "rollup": "2.x || 3.x || 4.x" + } + }, + "node_modules/rollup-plugin-preserve-directives/node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/rollup-plugin-typescript2": { "version": "0.31.2", "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.31.2.tgz", @@ -1077,6 +1134,12 @@ } }, "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, "@rollup/pluginutils": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", @@ -1087,6 +1150,12 @@ "picomatch": "^2.2.2" } }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, "@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -1598,6 +1667,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1784,6 +1862,29 @@ "fsevents": "~2.3.2" } }, + "rollup-plugin-preserve-directives": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-preserve-directives/-/rollup-plugin-preserve-directives-0.4.0.tgz", + "integrity": "sha512-gx4nBxYm5BysmEQS+e2tAMrtFxrGvk+Pe5ppafRibQi0zlW7VYAbEGk6IKDw9sJGPdFWgVTE0o4BU4cdG0Fylg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.1.0", + "magic-string": "^0.30.5" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + } + } + }, "rollup-plugin-typescript2": { "version": "0.31.2", "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.31.2.tgz", diff --git a/package.json b/package.json index 6bda005..7bb0189 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "react-ui-scrollspy", - "version": "2.3.0", + "version": "2.3.1", "description": "Simple, Easy To Use and Customisable ScrollSpy component for react with callback, typescript and throttle support among others", - "main": "dist/index.js", + "main": "dist", "scripts": { "build": "rollup -c", "start": "rollup -c -w" @@ -43,6 +43,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "rollup": "^2.59.0", + "rollup-plugin-preserve-directives": "^0.4.0", "rollup-plugin-typescript2": "^0.31.0", "tslib": "^2.4.1", "typescript": "^4.9.4" diff --git a/rollup.config.js b/rollup.config.js index 75b5288..3aa8ffd 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,3 +1,4 @@ +import preserveDirectives from "rollup-plugin-preserve-directives"; import typescript from "rollup-plugin-typescript2"; import pkg from "./package.json"; @@ -6,13 +7,14 @@ export default { input: "src/index.tsx", output: [ { - file: pkg.main, + dir: pkg.main, format: "cjs", exports: "named", sourcemap: true, strict: false, + preserveModules: true, }, ], - plugins: [typescript()], + plugins: [typescript(), preserveDirectives()], external: ["react", "react-dom"], }; diff --git a/src/ScrollSpy/ScrollSpy.tsx b/src/ScrollSpy/ScrollSpy.tsx index 5bc6beb..4b28fd2 100644 --- a/src/ScrollSpy/ScrollSpy.tsx +++ b/src/ScrollSpy/ScrollSpy.tsx @@ -1,3 +1,5 @@ +"use client"; + import * as React from "react"; import { MutableRefObject,