From 0dbdc63dc79bf261b1695f1e74bcd9b0f0b1a1b4 Mon Sep 17 00:00:00 2001 From: Meiyer Jaimes Date: Fri, 23 Aug 2024 17:02:25 -0500 Subject: [PATCH] feat: keep scroll view --- src/components/ApiReader.jsx | 6 +++++- src/components/Code.jsx | 26 +------------------------- src/hooks/usePreventLayoutShift.jsx | 26 ++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 26 deletions(-) create mode 100644 src/hooks/usePreventLayoutShift.jsx diff --git a/src/components/ApiReader.jsx b/src/components/ApiReader.jsx index 580eb37..d78b86e 100644 --- a/src/components/ApiReader.jsx +++ b/src/components/ApiReader.jsx @@ -1,10 +1,11 @@ import { useState } from 'react' -import { Disclosure, Transition } from '@headlessui/react' +import { Disclosure } from '@headlessui/react' import ReactMarkdown from 'react-markdown' import clsx from 'clsx' import { PlusIcon } from '@heroicons/react/24/outline' import { Properties, Property } from './mdx' import { useLocale } from './LocaleProvider' +import { usePreventLayoutShift } from '@/hooks/usePreventLayoutShift' const TITLES = { request: { @@ -33,6 +34,7 @@ const ParentProperty = ({ isRequired = false, isChild = false, }) => { + const {positionRef, preventLayoutShift} = usePreventLayoutShift(); const properties = property.properties ?? property.items?.properties ?? null const requireds = property.required ?? property.items?.required ?? [] const title = property.title ?? property.items?.title ?? null @@ -66,6 +68,8 @@ const ParentProperty = ({ {withChilds && ( <> preventLayoutShift(() => void 0)} className={clsx( '-mx-2 -my-1 flex cursor-pointer items-center gap-1 px-2 py-1 text-2xs font-medium text-gray-500 transition hover:text-gray-600 dark:text-gray-400 hover:dark:text-gray-300', { 'mt-2': property.description } diff --git a/src/components/Code.jsx b/src/components/Code.jsx index 83f1f67..2ed6a70 100644 --- a/src/components/Code.jsx +++ b/src/components/Code.jsx @@ -11,6 +11,7 @@ import clsx from 'clsx' import { create } from 'zustand' import { Tag } from '@/components/Tag' +import { usePreventLayoutShift } from '@/hooks/usePreventLayoutShift' const languageNames = { js: 'JavaScript', @@ -218,31 +219,6 @@ function CodeGroupPanels({ children, selectedIndex, ...props }) { return {content} } -function usePreventLayoutShift() { - let positionRef = useRef() - let rafRef = useRef() - - useEffect(() => { - return () => { - window.cancelAnimationFrame(rafRef.current) - } - }, []) - - return { - positionRef, - preventLayoutShift(callback) { - let initialTop = positionRef.current.getBoundingClientRect().top - - callback() - - rafRef.current = window.requestAnimationFrame(() => { - let newTop = positionRef.current.getBoundingClientRect().top - window.scrollBy(0, newTop - initialTop) - }) - }, - } -} - const usePreferredLanguageStore = create((set) => ({ preferredLanguages: [], addPreferredLanguage: (language) => diff --git a/src/hooks/usePreventLayoutShift.jsx b/src/hooks/usePreventLayoutShift.jsx new file mode 100644 index 0000000..5821e3a --- /dev/null +++ b/src/hooks/usePreventLayoutShift.jsx @@ -0,0 +1,26 @@ +import { useEffect, useRef } from "react" + +export function usePreventLayoutShift() { + let positionRef = useRef() + let rafRef = useRef() + + useEffect(() => { + return () => { + window.cancelAnimationFrame(rafRef.current) + } + }, []) + + return { + positionRef, + preventLayoutShift(callback) { + let initialTop = positionRef.current.getBoundingClientRect().top + + callback() + + rafRef.current = window.requestAnimationFrame(() => { + let newTop = positionRef.current.getBoundingClientRect().top + window.scrollBy(0, newTop - initialTop) + }) + }, + } +}