From 594516da25e5e370e91e7dc7bf36888980364897 Mon Sep 17 00:00:00 2001 From: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Date: Thu, 12 Feb 2026 18:27:08 +0800 Subject: [PATCH] fix: scroll back in short height --- .../plugins/marketplace/description/index.tsx | 51 +++++++++++++++++++ .../plugins/marketplace/list/list-wrapper.tsx | 7 ++- .../plugins/marketplace/search-page/index.tsx | 7 ++- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/web/app/components/plugins/marketplace/description/index.tsx b/web/app/components/plugins/marketplace/description/index.tsx index 8d01edf612..0fe37676d3 100644 --- a/web/app/components/plugins/marketplace/description/index.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -36,6 +36,7 @@ export const Description = ({ const heroSubtitleKey = isTemplatesView ? 'marketplace.templatesHeroSubtitle' : 'marketplace.pluginsHeroSubtitle' const rafRef = useRef(null) const lastProgressRef = useRef(0) + const headerRef = useRef(null) const titleContentRef = useRef(null) const progress = useMotionValue(0) const titleHeight = useMotionValue(72) @@ -113,8 +114,58 @@ export const Description = ({ const paddingTop = useTransform(smoothProgress, [0, 1], [marketplaceNav ? COLLAPSED_PADDING_TOP : EXPANDED_PADDING_TOP, COLLAPSED_PADDING_TOP]) const paddingBottom = useTransform(smoothProgress, [0, 1], [EXPANDED_PADDING_BOTTOM, COLLAPSED_PADDING_BOTTOM]) + useEffect(() => { + const container = document.getElementById(scrollContainerId) + const header = headerRef.current + if (!container || !header) + return + + let maxHeaderHeight = 0 + let lastAppliedOffset = 0 + const updateOffset = () => { + const currentHeaderHeight = Math.round(header.getBoundingClientRect().height) + maxHeaderHeight = Math.max(maxHeaderHeight, currentHeaderHeight) + const collapsedHeight = Math.max(0, maxHeaderHeight - currentHeaderHeight) + const currentScrollableTop = container.scrollHeight - container.clientHeight + const baseScrollableTop = Math.max(0, currentScrollableTop - lastAppliedOffset) + const shouldCompensate = baseScrollableTop <= maxHeaderHeight + const nextOffset = shouldCompensate ? collapsedHeight : 0 + const offsetDelta = nextOffset - lastAppliedOffset + + if (nextOffset > 0) { + // Only compensate when content is short enough that header collapse can clamp scrollTop. + container.style.setProperty('--marketplace-header-collapse-offset', `${nextOffset}px`) + if (offsetDelta !== 0 && container.scrollTop > 0) + container.scrollTop = Math.max(0, container.scrollTop + offsetDelta) + } + else { + container.style.removeProperty('--marketplace-header-collapse-offset') + } + + lastAppliedOffset = nextOffset + } + + updateOffset() + + if (typeof ResizeObserver === 'undefined') { + return () => { + container.style.removeProperty('--marketplace-header-collapse-offset') + } + } + + const observer = new ResizeObserver(updateOffset) + observer.observe(header) + observer.observe(container) + + return () => { + observer.disconnect() + container.style.removeProperty('--marketplace-header-collapse-offset') + } + }, [scrollContainerId]) + return ( { return (
{isSearchMode && }
diff --git a/web/app/components/plugins/marketplace/search-page/index.tsx b/web/app/components/plugins/marketplace/search-page/index.tsx index d1540546ec..e94f078caf 100644 --- a/web/app/components/plugins/marketplace/search-page/index.tsx +++ b/web/app/components/plugins/marketplace/search-page/index.tsx @@ -242,8 +242,11 @@ const SearchPage = () => { return (