From a37a9c80237772a31ea694397b993a2a40a1add1 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Tue, 28 Jan 2025 09:02:53 +0200 Subject: [PATCH] docs: fix sidebar navigation in API reference (#11179) --- .../components/Tags/Section/Schema/index.tsx | 4 +-- .../components/Tags/Section/index.tsx | 35 +++++++++---------- .../src/hooks/use-active-on-scroll/index.tsx | 34 ++++++++++++------ .../src/hooks/use-scroll-utils/index.tsx | 1 + 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx index 30d7c3f4f5..f2e908a160 100644 --- a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx @@ -30,10 +30,8 @@ export type TagSectionSchemaProps = { } const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { - const paramsRef = useRef(null) const { addItems, setActivePath, activePath } = useSidebar() const { displayedArea } = useArea() - const tagSlugName = useMemo(() => getSectionId([tagName]), [tagName]) const formattedName = useMemo( () => singular(tagName).replaceAll(" ", ""), [tagName] @@ -129,7 +127,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => { root={root} threshold={0.1} > - + diff --git a/www/apps/api-reference/components/Tags/Section/index.tsx b/www/apps/api-reference/components/Tags/Section/index.tsx index 1af2397587..ac17dc0255 100644 --- a/www/apps/api-reference/components/Tags/Section/index.tsx +++ b/www/apps/api-reference/components/Tags/Section/index.tsx @@ -23,7 +23,7 @@ import clsx from "clsx" import { Feedback, Loading, Link } from "docs-ui" import { usePathname, useRouter } from "next/navigation" import { PathsObject, SchemaObject, TagObject } from "@/types/openapi" -import { TagSectionSchemaProps } from "./Schema" +import TagSectionSchema from "./Schema" import checkElementInViewport from "../../../utils/check-element-in-viewport" import TagPaths from "../Paths" import useSWR from "swr" @@ -37,10 +37,6 @@ const Section = dynamic( async () => import("../../Section") ) as React.FC -const TagSectionSchema = dynamic( - async () => import("./Schema") -) as React.FC - const MDXContentClient = dynamic( async () => import("../../MDXContent/Client"), { @@ -117,21 +113,22 @@ const TagSectionComponent = ({ tag }: TagSectionProps) => { rootMargin={`112px 0px 112px 0px`} root={root} onChange={(inView) => { - if (inView) { - if (!loadData) { - setLoadData(true) + if (!inView) { + return + } + if (!loadData) { + setLoadData(true) + } + // ensure that the hash link doesn't change if it links to an inner path + const currentHashArr = location.hash.replace("#", "").split("_") + if (currentHashArr.length < 2 || currentHashArr[0] !== slugTagName) { + if (location.hash !== slugTagName) { + router.push(`#${slugTagName}`, { + scroll: false, + }) } - // ensure that the hash link doesn't change if it links to an inner path - const currentHashArr = location.hash.replace("#", "").split("_") - if (currentHashArr.length < 2 || currentHashArr[0] !== slugTagName) { - if (location.hash !== slugTagName) { - router.push(`#${slugTagName}`, { - scroll: false, - }) - } - if (activePath !== slugTagName) { - setActivePath(slugTagName) - } + if (activePath !== slugTagName) { + setActivePath(slugTagName) } } }} diff --git a/www/packages/docs-ui/src/hooks/use-active-on-scroll/index.tsx b/www/packages/docs-ui/src/hooks/use-active-on-scroll/index.tsx index c468355b4c..4e23994b3a 100644 --- a/www/packages/docs-ui/src/hooks/use-active-on-scroll/index.tsx +++ b/www/packages/docs-ui/src/hooks/use-active-on-scroll/index.tsx @@ -98,6 +98,18 @@ export const useActiveOnScroll = ({ if (!enable) { return } + const rootBoundingRectElm = + root && "getBoundingClientRect" in root + ? root.getBoundingClientRect() + : root?.body.getBoundingClientRect() + + if ( + rootBoundingRectElm === undefined || + (rootBoundingRectElm.top < 0 && rootBoundingRectElm.bottom < 0) + ) { + setActiveItemId("") + return + } const headings = getHeadingsInElm() let selectedHeadingByHash: HTMLHeadingElement | undefined = undefined const hash = location.hash.replace("#", "") @@ -129,17 +141,19 @@ export const useActiveOnScroll = ({ } }) - const negativeDistanceToHalfway = Math.abs( - halfway + closestNegativeDistance - ) - const positiveDistanceToHalfway = Math.abs( - halfway - closestPositiveDistance - ) + const negativeDistanceToHalfway = closestNegativeDistance + ? Math.abs(halfway + closestNegativeDistance) + : 0 + const positiveDistanceToHalfway = closestPositiveDistance + ? Math.abs(halfway - closestPositiveDistance) + : 0 const chosenClosest = - negativeDistanceToHalfway > positiveDistanceToHalfway - ? closestNegativeHeading - : closestPositiveHeading + !negativeDistanceToHalfway && !positiveDistanceToHalfway + ? undefined + : negativeDistanceToHalfway > positiveDistanceToHalfway + ? closestNegativeHeading + : closestPositiveHeading setActiveItemId( chosenClosest @@ -152,7 +166,7 @@ export const useActiveOnScroll = ({ : "" : "" ) - }, [getHeadingsInElm, items, enable]) + }, [getHeadingsInElm, items, enable, root]) useEffect(() => { if (!scrollableElement || !enable) { diff --git a/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx b/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx index 9b6085dc59..add1a33106 100644 --- a/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx +++ b/www/packages/docs-ui/src/hooks/use-scroll-utils/index.tsx @@ -106,6 +106,7 @@ function useScrollControllerContextValue({ // 56 is the height of the navbar // might need a better way to determine it. top: top - parentOffsetTop - 56, + behavior: "instant", }) }