Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 5x 5x 5x 6x 5x 6x 11x 5x 4x 5x 6x 6x 4x 4x 6x 6x 6x 4x 4x 4x 4x 6x | import { useLayoutEffect, useState } from "react";
export type DetailsSidebarLink = {
id: string;
href: string;
displayName: string;
};
const BASE_SIDEBAR_LINKS: DetailsSidebarLink[] = [
{
id: "package_details",
href: "#package_details",
displayName: "Package Details",
},
{
id: "package_activity",
href: "#package_activity",
displayName: "Package Activity",
},
];
const ADMIN_CHANGES_LINK: DetailsSidebarLink = {
id: "administrative_package_changes",
href: "#administrative_package_changes",
displayName: "Administrative Package Changes",
};
const getSidebarLinks = (root: ParentNode = document) => {
return root.querySelector(`#${ADMIN_CHANGES_LINK.id}`)
? [...BASE_SIDEBAR_LINKS, ADMIN_CHANGES_LINK]
: BASE_SIDEBAR_LINKS;
};
const areSidebarLinksEqual = (
current: DetailsSidebarLink[],
next: DetailsSidebarLink[],
): boolean => {
return (
current.length === next.length &&
current.every(
(link, index) =>
link.id === next[index]?.id &&
link.href === next[index]?.href &&
link.displayName === next[index]?.displayName,
)
);
};
const getSidebarObserverRoot = (): HTMLElement => {
return (
document.getElementById("package_details_page") ??
document.getElementById("package_details")?.parentElement ??
document.body
);
};
export const useDetailsSidebarLinks = (): DetailsSidebarLink[] => {
const [sideBarLinks, setSideBarLinks] = useState<DetailsSidebarLink[]>(BASE_SIDEBAR_LINKS);
useLayoutEffect(() => {
const observerRoot = getSidebarObserverRoot();
const updateLinks = () => {
setSideBarLinks((current) => {
const next = getSidebarLinks(observerRoot);
return areSidebarLinksEqual(current, next) ? current : next;
});
};
updateLinks();
const observer = new MutationObserver(updateLinks);
observer.observe(observerRoot, { childList: true, subtree: true });
return () => observer.disconnect();
}, []);
return sideBarLinks;
};
|