add page scrolling
This commit is contained in:
@@ -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",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user