add page scrolling

This commit is contained in:
2025-12-11 14:58:19 +00:00
parent f86aebc00b
commit de464461e6

View File

@@ -88,6 +88,9 @@ export class DeDocumentViewer extends DeesElement {
@state()
accessor displayZoom: number = 100;
@state()
accessor currentPageDisplay: string = "1 / 1";
public static styles = [
cssManager.defaultStyles,
css`
@@ -328,6 +331,19 @@ export class DeDocumentViewer extends DeesElement {
gap: 2px;
}
.page-nav {
display: flex;
align-items: center;
gap: 2px;
}
.page-indicator {
font-size: 12px;
color: var(--text-secondary);
min-width: 45px;
text-align: center;
}
.spacing-slider-container {
display: flex;
align-items: center;
@@ -585,6 +601,27 @@ export class DeDocumentViewer extends DeesElement {
<div class="controls__divider"></div>
<!-- Page Navigation -->
<div class="page-nav">
<button
class="controls__button"
@click=${() => this.handlePreviousPage()}
title="Previous Page"
>
<dees-icon icon="lucide:chevronUp"></dees-icon>
</button>
<span class="page-indicator">${this.currentPageDisplay}</span>
<button
class="controls__button"
@click=${() => this.handleNextPage()}
title="Next Page"
>
<dees-icon icon="lucide:chevronDown"></dees-icon>
</button>
</div>
<div class="controls__divider"></div>
<!-- Print Button -->
<button
class="controls__button"
@@ -669,6 +706,27 @@ export class DeDocumentViewer extends DeesElement {
this.pageGap = parseInt((e.target as HTMLInputElement).value, 10);
}
private handlePreviousPage(): void {
const current = this.getCurrentPage();
if (current > 1) {
this.scrollToPage(current - 1);
}
}
private handleNextPage(): void {
const current = this.getCurrentPage();
const total = this.getPageCount();
if (current < total) {
this.scrollToPage(current + 1);
}
}
private updatePageIndicator(): void {
const current = this.getCurrentPage();
const total = this.getPageCount();
this.currentPageDisplay = `${current} / ${total || 1}`;
}
private async handlePrint(): Promise<void> {
// Create a print-specific container - hidden on screen, visible only in print
const printContainer = document.createElement("div");
@@ -803,8 +861,11 @@ export class DeDocumentViewer extends DeesElement {
super.updated(changedProperties);
if (changedProperties.has("letterData")) {
// Update display zoom after document renders
setTimeout(() => this.updateDisplayZoom(), 100);
// Update display zoom and page indicator after document renders
setTimeout(() => {
this.updateDisplayZoom();
this.updatePageIndicator();
}, 100);
}
}
@@ -823,9 +884,10 @@ export class DeDocumentViewer extends DeesElement {
setTimeout(() => this.updateDisplayZoom(), 200);
}
// Handle viewport resize to update display zoom in auto mode
// Handle viewport resize and scroll
const viewport = this.shadowRoot?.querySelector(".viewport");
if (viewport) {
// Resize observer for zoom updates
const resizeObserver = new ResizeObserver(() => {
if (this.zoomMode === "auto" || this.zoomMode === "fit-width") {
this.updateDisplayZoom();
@@ -833,7 +895,17 @@ export class DeDocumentViewer extends DeesElement {
});
resizeObserver.observe(viewport);
this.registerGarbageFunction(() => resizeObserver.disconnect());
// Scroll listener for page indicator
const scrollHandler = () => {
this.updatePageIndicator();
};
viewport.addEventListener("scroll", scrollHandler);
this.registerGarbageFunction(() => viewport.removeEventListener("scroll", scrollHandler));
}
// Initial page indicator update
setTimeout(() => this.updatePageIndicator(), 300);
}
// ============================================
@@ -928,19 +1000,27 @@ export class DeDocumentViewer extends DeesElement {
* @param smooth - Whether to use smooth scrolling (default: true)
*/
public scrollToPage(pageNumber: number, smooth: boolean = true): void {
const viewport = this.shadowRoot?.querySelector(".viewport");
const doc = this.shadowRoot?.querySelector("dedocument-dedocument");
if (!doc) return;
if (!viewport || !doc) return;
const pages = doc.shadowRoot?.querySelectorAll("dedocument-page");
if (!pages || pages.length === 0) return;
const targetIndex = Math.min(Math.max(0, pageNumber - 1), pages.length - 1);
const targetPage = pages[targetIndex];
const targetPage = pages[targetIndex] as HTMLElement;
if (targetPage) {
targetPage.scrollIntoView({
// Calculate scroll position relative to viewport
// Account for the document's position within the viewport
const docRect = doc.getBoundingClientRect();
const pageRect = targetPage.getBoundingClientRect();
const pageOffsetFromDoc = pageRect.top - docRect.top;
// Scroll to the page position
viewport.scrollTo({
top: pageOffsetFromDoc,
behavior: smooth ? "smooth" : "instant",
block: "start",
});
}
}