diff --git a/ts_web/elements/dees-pdf-viewer/component.ts b/ts_web/elements/dees-pdf-viewer/component.ts index 31978b1..0823619 100644 --- a/ts_web/elements/dees-pdf-viewer/component.ts +++ b/ts_web/elements/dees-pdf-viewer/component.ts @@ -528,10 +528,16 @@ export class DeesPdfViewer extends DeesElement { const isBelow = thumbnailRect.bottom > sidebarRect.bottom; if (isAbove || isBelow) { - // Scroll the thumbnail into view, centering it if possible - thumbnail.scrollIntoView({ - behavior: 'smooth', - block: 'center' + // Calculate the scroll position to center the thumbnail + const thumbnailOffset = thumbnail.offsetTop; + const thumbnailHeight = thumbnail.offsetHeight; + const sidebarHeight = sidebarContent.clientHeight; + const targetScrollTop = thumbnailOffset - (sidebarHeight / 2) + (thumbnailHeight / 2); + + // Scroll the sidebar to center the thumbnail + sidebarContent.scrollTo({ + top: Math.max(0, targetScrollTop), + behavior: 'smooth' }); } } @@ -541,10 +547,23 @@ export class DeesPdfViewer extends DeesElement { await this.updateComplete; const pageWrapper = this.shadowRoot?.querySelector(`.page-wrapper[data-page="${pageNum}"]`) as HTMLElement; if (pageWrapper && this.viewerMain) { - pageWrapper.scrollIntoView({ - behavior: smooth ? 'smooth' : 'auto', - block: 'start' - }); + // Calculate the offset of the page wrapper relative to the viewer + const pageRect = pageWrapper.getBoundingClientRect(); + const viewerRect = this.viewerMain.getBoundingClientRect(); + const currentScrollTop = this.viewerMain.scrollTop; + + // Calculate the target scroll position + const targetScrollTop = currentScrollTop + (pageRect.top - viewerRect.top) - this.viewerMain.clientTop; + + // Scroll to the calculated position + if (smooth) { + this.viewerMain.scrollTo({ + top: targetScrollTop, + behavior: 'smooth' + }); + } else { + this.viewerMain.scrollTop = targetScrollTop; + } // Update current page this.currentPage = pageNum; @@ -661,11 +680,6 @@ export class DeesPdfViewer extends DeesElement { } } - private async goToPage(pageNum: number) { - if (pageNum >= 1 && pageNum <= this.totalPages) { - await this.scrollToPage(pageNum); - } - } private handleThumbnailClick(e: Event) { const target = e.currentTarget as HTMLElement; @@ -809,6 +823,28 @@ export class DeesPdfViewer extends DeesElement { }); this.resizeObserver.observe(this.viewerMain); this.measureViewportDimensions(); + + // Prevent scroll propagation to parent when scrolling inside viewer + this.viewerMain.addEventListener('wheel', (e) => { + const element = e.currentTarget as HTMLElement; + const scrollTop = element.scrollTop; + const scrollHeight = element.scrollHeight; + const clientHeight = element.clientHeight; + const deltaY = e.deltaY; + + // Check if we're at the boundaries + const isAtTop = scrollTop === 0; + const isAtBottom = Math.abs(scrollTop + clientHeight - scrollHeight) < 1; + + // Prevent propagation if we're scrolling within bounds + if ((deltaY < 0 && !isAtTop) || (deltaY > 0 && !isAtBottom)) { + e.stopPropagation(); + } else if ((deltaY < 0 && isAtTop) || (deltaY > 0 && isAtBottom)) { + // Prevent default and propagation when at boundaries + e.preventDefault(); + e.stopPropagation(); + } + }, { passive: false }); } } diff --git a/ts_web/elements/dees-pdf-viewer/styles.ts b/ts_web/elements/dees-pdf-viewer/styles.ts index 70e2ac7..4b2468b 100644 --- a/ts_web/elements/dees-pdf-viewer/styles.ts +++ b/ts_web/elements/dees-pdf-viewer/styles.ts @@ -9,6 +9,7 @@ export const viewerStyles = [ height: 600px; position: relative; font-family: 'Geist Sans', sans-serif; + contain: layout style; } .pdf-viewer { @@ -17,6 +18,8 @@ export const viewerStyles = [ display: flex; flex-direction: column; background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(215 20% 10%)')}; + position: relative; + overflow: hidden; } .toolbar { @@ -109,6 +112,7 @@ export const viewerStyles = [ display: flex; overflow: hidden; position: relative; + min-height: 0; } .sidebar { @@ -160,6 +164,8 @@ export const viewerStyles = [ display: flex; flex-direction: column; gap: 12px; + overscroll-behavior: contain; + min-height: 0; } .thumbnail { @@ -210,6 +216,9 @@ export const viewerStyles = [ overflow-x: hidden; padding: 20px; scroll-behavior: smooth; + overscroll-behavior: contain; + min-height: 0; + position: relative; } .loading-container {