From 3b3fd8b35ccabc52711f13b18ce0fac401a7cc8d Mon Sep 17 00:00:00 2001 From: aits2026 Date: Fri, 6 Mar 2026 19:47:49 +0800 Subject: [PATCH] fix(export): keep session row actions sticky in viewport --- src/pages/ExportPage.scss | 4 +++- src/pages/ExportPage.tsx | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/pages/ExportPage.scss b/src/pages/ExportPage.scss index b77812b..79f4367 100644 --- a/src/pages/ExportPage.scss +++ b/src/pages/ExportPage.scss @@ -2480,11 +2480,13 @@ align-items: flex-end; gap: 4px; width: var(--contacts-action-col-width); + min-width: var(--contacts-action-col-width); flex-shrink: 0; position: sticky; right: 0; - z-index: 6; + z-index: 10; background: var(--bg-primary); + will-change: transform; &::before { content: ''; diff --git a/src/pages/ExportPage.tsx b/src/pages/ExportPage.tsx index 38d01a5..b43ba34 100644 --- a/src/pages/ExportPage.tsx +++ b/src/pages/ExportPage.tsx @@ -1513,6 +1513,7 @@ function ExportPage() { const [nowTick, setNowTick] = useState(Date.now()) const [isContactsListAtTop, setIsContactsListAtTop] = useState(true) const [isContactsHeaderDragging, setIsContactsHeaderDragging] = useState(false) + const [contactsHorizontalScrollLeft, setContactsHorizontalScrollLeft] = useState(0) const [contactsHorizontalScrollMetrics, setContactsHorizontalScrollMetrics] = useState({ viewportWidth: 0, contentWidth: 0 @@ -5632,6 +5633,19 @@ function ExportPage() { const contactsBottomScrollbarInnerStyle = useMemo(() => ({ width: `${Math.max(contactsHorizontalScrollMetrics.contentWidth, contactsHorizontalScrollMetrics.viewportWidth)}px` }), [contactsHorizontalScrollMetrics.contentWidth, contactsHorizontalScrollMetrics.viewportWidth]) + const contactsActionStickyStyle = useMemo(() => { + const maxScrollLeft = Math.max(0, contactsHorizontalScrollMetrics.contentWidth - contactsHorizontalScrollMetrics.viewportWidth) + if (maxScrollLeft <= 0) return {} + + const compensatedTranslateX = Math.min(0, contactsHorizontalScrollLeft - maxScrollLeft) + return Math.abs(compensatedTranslateX) > 0.5 + ? { transform: `translateX(${compensatedTranslateX}px)` } + : {} + }, [ + contactsHorizontalScrollLeft, + contactsHorizontalScrollMetrics.contentWidth, + contactsHorizontalScrollMetrics.viewportWidth + ]) const nonExportBackgroundTasks = useMemo(() => ( backgroundTasks.filter(task => task.sourcePage !== 'export') ), [backgroundTasks]) @@ -5687,6 +5701,10 @@ function ExportPage() { bottomScrollbar.scrollLeft = scrollLeft } + setContactsHorizontalScrollLeft(prev => ( + Math.abs(prev - scrollLeft) > 1 ? scrollLeft : prev + )) + window.requestAnimationFrame(() => { if (contactsScrollSyncSourceRef.current === source) { contactsScrollSyncSourceRef.current = null @@ -5774,6 +5792,9 @@ function ExportPage() { if (Math.abs(viewport.scrollLeft - clampedScrollLeft) > 1) { viewport.scrollLeft = clampedScrollLeft } + setContactsHorizontalScrollLeft(prev => ( + Math.abs(prev - clampedScrollLeft) > 1 ? clampedScrollLeft : prev + )) const bottomScrollbar = contactsBottomScrollbarRef.current if (bottomScrollbar) { @@ -5995,7 +6016,7 @@ function ExportPage() { )} )} -
+