feat(dees-pdf-viewer): improve scrolling behavior and styles for better user experience
This commit is contained in:
		| @@ -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 }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user