@embedpdf/plugin-scroll 1.0.25 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/types.ts","../src/lib/strategies/base-strategy.ts","../src/lib/strategies/vertical-strategy.ts","../src/lib/strategies/horizontal-strategy.ts","../src/lib/actions.ts","../src/lib/selectors.ts","../src/lib/scroll-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePluginConfig, Emitter, EventHook } from '@embedpdf/core';\nimport { PdfPageObject, Rect, Rotation } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { VirtualItem } from './types/virtual-item';\n\nexport interface ScrollState extends ScrollMetrics {\n virtualItems: VirtualItem[];\n totalPages: number;\n totalContentSize: { width: number; height: number };\n desiredScrollPosition: { x: number; y: number };\n strategy: ScrollStrategy;\n pageGap: number;\n scale: number;\n}\n\nexport interface ScrollerLayout {\n startSpacing: number;\n endSpacing: number;\n totalWidth: number;\n totalHeight: number;\n pageGap: number;\n strategy: ScrollState['strategy'];\n items: VirtualItem[];\n}\n\nexport enum ScrollStrategy {\n Vertical = 'vertical',\n Horizontal = 'horizontal',\n}\n\nexport interface PageVisibilityMetrics {\n pageNumber: number;\n viewportX: number;\n viewportY: number;\n visiblePercentage: number;\n original: {\n pageX: number;\n pageY: number;\n visibleWidth: number;\n visibleHeight: number;\n scale: number;\n };\n scaled: {\n pageX: number;\n pageY: number;\n visibleWidth: number;\n visibleHeight: number;\n scale: number;\n };\n}\n\nexport interface ScrollMetrics {\n currentPage: number;\n visiblePages: number[];\n pageVisibilityMetrics: PageVisibilityMetrics[];\n renderedPageIndexes: number[];\n scrollOffset: { x: number; y: number };\n startSpacing: number;\n endSpacing: number;\n}\n\nexport interface ScrollStrategyInterface {\n initialize(container: HTMLElement, innerDiv: HTMLElement): void;\n destroy(): void;\n updateLayout(viewport: ViewportMetrics, pdfPageObject: PdfPageObject[][]): void;\n handleScroll(viewport: ViewportMetrics): void;\n getVirtualItems(): VirtualItem[];\n scrollToPage(pageNumber: number, behavior?: ScrollBehavior): void;\n calculateDimensions(pdfPageObject: PdfPageObject[][]): void;\n}\n\nexport interface ScrollPluginConfig extends BasePluginConfig {\n strategy?: ScrollStrategy;\n initialPage?: number;\n bufferSize?: number;\n pageGap?: number;\n}\n\nexport type LayoutChangePayload = Pick<ScrollState, 'virtualItems' | 'totalContentSize'>;\n\nexport interface ScrollToPageOptions {\n pageNumber: number;\n pageCoordinates?: { x: number; y: number };\n behavior?: ScrollBehavior;\n center?: boolean;\n}\n\nexport interface PageChangePayload {\n pageNumber: number;\n totalPages: number;\n}\n\nexport interface ScrollCapability {\n onScrollerData: EventHook<ScrollerLayout>;\n onStateChange: EventHook<ScrollState>;\n onScroll: EventHook<ScrollMetrics>;\n getCurrentPage(): number;\n getTotalPages(): number;\n onPageChange: EventHook<PageChangePayload>;\n onLayoutChange: EventHook<LayoutChangePayload>;\n onLayoutReady: EventHook<boolean>;\n scrollToPage(options: ScrollToPageOptions): void;\n scrollToNextPage(behavior?: ScrollBehavior): void;\n scrollToPreviousPage(behavior?: ScrollBehavior): void;\n getMetrics(viewport?: ViewportMetrics): ScrollMetrics;\n getLayout(): LayoutChangePayload;\n getScrollerLayout(): ScrollerLayout;\n getRectPositionForPage(\n page: number,\n rect: Rect,\n scale?: number,\n rotation?: Rotation,\n ): Rect | null;\n setScrollStrategy(strategy: ScrollStrategy): void;\n getPageGap(): number;\n}\n","import {\n PdfPageObjectWithRotatedSize,\n Position,\n Rect,\n Rotation,\n scalePosition,\n transformPosition,\n transformRect,\n} from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { VirtualItem } from '../types/virtual-item';\nimport { ScrollMetrics } from '../types';\n\nexport interface ScrollStrategyConfig {\n pageGap?: number;\n viewportGap?: number;\n bufferSize?: number;\n}\n\nexport abstract class BaseScrollStrategy {\n protected pageGap: number;\n protected viewportGap: number;\n protected bufferSize: number;\n\n constructor(config: ScrollStrategyConfig) {\n this.pageGap = config.pageGap ?? 20;\n this.viewportGap = config.viewportGap ?? 20;\n this.bufferSize = config.bufferSize ?? 2;\n }\n\n abstract createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[];\n abstract getTotalContentSize(virtualItems: VirtualItem[]): { width: number; height: number };\n protected abstract getScrollOffset(viewport: ViewportMetrics): number;\n protected abstract getClientSize(viewport: ViewportMetrics): number;\n\n protected getVisibleRange(\n viewport: ViewportMetrics,\n virtualItems: VirtualItem[],\n scale: number,\n ): { start: number; end: number } {\n const scrollOffset = this.getScrollOffset(viewport);\n const clientSize = this.getClientSize(viewport);\n const viewportStart = scrollOffset;\n const viewportEnd = scrollOffset + clientSize;\n\n let startIndex = 0;\n while (\n startIndex < virtualItems.length &&\n (virtualItems[startIndex].offset + virtualItems[startIndex].height) * scale <= viewportStart\n ) {\n startIndex++;\n }\n\n let endIndex = startIndex;\n while (endIndex < virtualItems.length && virtualItems[endIndex].offset * scale <= viewportEnd) {\n endIndex++;\n }\n\n return {\n start: Math.max(0, startIndex - this.bufferSize),\n end: Math.min(virtualItems.length - 1, endIndex + this.bufferSize - 1),\n };\n }\n\n handleScroll(\n viewport: ViewportMetrics,\n virtualItems: VirtualItem[],\n scale: number,\n ): ScrollMetrics {\n const range = this.getVisibleRange(viewport, virtualItems, scale);\n const visibleItems = virtualItems.slice(range.start, range.end + 1);\n const pageVisibilityMetrics = this.calculatePageVisibility(visibleItems, viewport, scale);\n const visiblePages = pageVisibilityMetrics.map((m) => m.pageNumber);\n const renderedPageIndexes = virtualItems\n .slice(range.start, range.end + 1)\n .flatMap((item) => item.index);\n const currentPage = this.determineCurrentPage(pageVisibilityMetrics);\n const first = virtualItems[range.start];\n const last = virtualItems[range.end];\n const startSpacing = first ? first.offset * scale : 0;\n const endSpacing = last\n ? (virtualItems[virtualItems.length - 1].offset + // end of content\n virtualItems[virtualItems.length - 1].height) *\n scale - // minus\n (last.offset + last.height) * scale // end of last rendered\n : 0;\n\n return {\n currentPage,\n visiblePages,\n pageVisibilityMetrics,\n renderedPageIndexes,\n scrollOffset: { x: viewport.scrollLeft, y: viewport.scrollTop },\n startSpacing,\n endSpacing,\n };\n }\n\n protected calculatePageVisibility(\n virtualItems: VirtualItem[],\n viewport: ViewportMetrics,\n scale: number,\n ): ScrollMetrics['pageVisibilityMetrics'] {\n const visibilityMetrics: ScrollMetrics['pageVisibilityMetrics'] = [];\n\n virtualItems.forEach((item) => {\n item.pageLayouts.forEach((page) => {\n const itemX = item.x * scale;\n const itemY = item.y * scale;\n const pageX = itemX + page.x * scale;\n const pageY = itemY + page.y * scale;\n const pageWidth = page.rotatedWidth * scale;\n const pageHeight = page.rotatedHeight * scale;\n\n const viewportLeft = viewport.scrollLeft;\n const viewportTop = viewport.scrollTop;\n const viewportRight = viewportLeft + viewport.clientWidth;\n const viewportBottom = viewportTop + viewport.clientHeight;\n\n const intersectionLeft = Math.max(pageX, viewportLeft);\n const intersectionTop = Math.max(pageY, viewportTop);\n const intersectionRight = Math.min(pageX + pageWidth, viewportRight);\n const intersectionBottom = Math.min(pageY + pageHeight, viewportBottom);\n\n if (intersectionLeft < intersectionRight && intersectionTop < intersectionBottom) {\n const visibleWidth = intersectionRight - intersectionLeft;\n const visibleHeight = intersectionBottom - intersectionTop;\n const totalArea = pageWidth * pageHeight;\n const visibleArea = visibleWidth * visibleHeight;\n\n visibilityMetrics.push({\n pageNumber: page.pageNumber,\n viewportX: intersectionLeft - viewportLeft,\n viewportY: intersectionTop - viewportTop,\n visiblePercentage: (visibleArea / totalArea) * 100,\n original: {\n pageX: (intersectionLeft - pageX) / scale,\n pageY: (intersectionTop - pageY) / scale,\n visibleWidth: visibleWidth / scale,\n visibleHeight: visibleHeight / scale,\n scale: 1,\n },\n scaled: {\n pageX: intersectionLeft - pageX,\n pageY: intersectionTop - pageY,\n visibleWidth,\n visibleHeight,\n scale,\n },\n });\n }\n });\n });\n\n return visibilityMetrics;\n }\n\n protected determineCurrentPage(\n visibilityMetrics: ScrollMetrics['pageVisibilityMetrics'],\n ): number {\n if (visibilityMetrics.length === 0) return 1;\n\n const maxVisibility = Math.max(...visibilityMetrics.map((m) => m.visiblePercentage));\n const mostVisiblePages = visibilityMetrics.filter((m) => m.visiblePercentage === maxVisibility);\n\n return mostVisiblePages.length === 1\n ? mostVisiblePages[0].pageNumber\n : mostVisiblePages.sort((a, b) => a.pageNumber - b.pageNumber)[0].pageNumber;\n }\n\n private getRectLocationForPage(pageNumber: number, virtualItems: VirtualItem[]): Rect | null {\n // Find the virtual item containing the page\n const item = virtualItems.find((item) => item.pageNumbers.includes(pageNumber));\n if (!item) return null;\n\n // Find the specific page layout for the requested page number\n const pageLayout = item.pageLayouts.find((layout) => layout.pageNumber === pageNumber);\n if (!pageLayout) return null;\n\n return {\n origin: {\n x: item.x + pageLayout.x,\n y: item.y + pageLayout.y,\n },\n size: {\n width: pageLayout.width,\n height: pageLayout.height,\n },\n };\n }\n\n getScrollPositionForPage(\n pageNumber: number,\n virtualItems: VirtualItem[],\n scale: number,\n rotation: Rotation,\n pageCoordinates?: { x: number; y: number },\n ): Position | null {\n // Find the virtual item containing the page\n const pageRect = this.getRectLocationForPage(pageNumber, virtualItems);\n if (!pageRect) return null;\n\n const scaledBasePosition = scalePosition(pageRect.origin, scale);\n\n // If specific page coordinates are provided, add them to the base position\n if (pageCoordinates) {\n const rotatedSize = transformPosition(\n {\n width: pageRect.size.width,\n height: pageRect.size.height,\n },\n {\n x: pageCoordinates.x,\n y: pageCoordinates.y,\n },\n rotation,\n scale,\n );\n\n return {\n x: scaledBasePosition.x + rotatedSize.x + this.viewportGap,\n y: scaledBasePosition.y + rotatedSize.y + this.viewportGap,\n };\n }\n\n return {\n x: scaledBasePosition.x + this.viewportGap,\n y: scaledBasePosition.y + this.viewportGap,\n };\n }\n\n getRectPositionForPage(\n pageNumber: number,\n virtualItems: VirtualItem[],\n scale: number,\n rotation: Rotation,\n rect: Rect,\n ): Rect | null {\n const pageRect = this.getRectLocationForPage(pageNumber, virtualItems);\n if (!pageRect) return null;\n\n const scaledBasePosition = scalePosition(pageRect.origin, scale);\n\n const rotatedSize = transformRect(\n {\n width: pageRect.size.width,\n height: pageRect.size.height,\n },\n rect,\n rotation,\n scale,\n );\n\n return {\n origin: {\n x: scaledBasePosition.x + rotatedSize.origin.x,\n y: scaledBasePosition.y + rotatedSize.origin.y,\n },\n size: rotatedSize.size,\n };\n }\n}\n","import { PdfPageObjectWithRotatedSize } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { BaseScrollStrategy, ScrollStrategyConfig } from './base-strategy';\nimport { VirtualItem, PageLayout } from '../types/virtual-item';\nimport { ScrollMetrics } from '../types';\n\nexport class VerticalScrollStrategy extends BaseScrollStrategy {\n constructor(config: ScrollStrategyConfig) {\n super(config);\n }\n\n createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[] {\n let yOffset = 0;\n return pdfPageObject.map((pagesInSpread, index) => {\n let pageX = 0;\n const pageLayouts: PageLayout[] = pagesInSpread.map((page) => {\n const layout: PageLayout = {\n pageNumber: page.index + 1,\n pageIndex: page.index,\n x: pageX,\n y: 0,\n width: page.size.width,\n height: page.size.height,\n rotatedWidth: page.rotatedSize.width,\n rotatedHeight: page.rotatedSize.height,\n };\n pageX += page.rotatedSize.width + this.pageGap;\n return layout;\n });\n const width = pagesInSpread.reduce(\n (sum, page, i) =>\n sum + page.rotatedSize.width + (i < pagesInSpread.length - 1 ? this.pageGap : 0),\n 0,\n );\n const height = Math.max(...pagesInSpread.map((p) => p.rotatedSize.height));\n const item: VirtualItem = {\n id: `item-${index}`,\n x: 0,\n y: yOffset,\n offset: yOffset,\n width,\n height,\n pageLayouts,\n pageNumbers: pagesInSpread.map((p) => p.index + 1),\n index,\n };\n yOffset += height + this.pageGap;\n return item;\n });\n }\n\n getTotalContentSize(virtualItems: VirtualItem[]): { width: number; height: number } {\n if (virtualItems.length === 0) return { width: 0, height: 0 };\n const maxWidth = Math.max(...virtualItems.map((item) => item.width));\n const totalHeight =\n virtualItems[virtualItems.length - 1].y + virtualItems[virtualItems.length - 1].height;\n return {\n width: maxWidth,\n height: totalHeight,\n };\n }\n\n protected getScrollOffset(viewport: ViewportMetrics): number {\n return viewport.scrollTop;\n }\n\n protected getClientSize(viewport: ViewportMetrics): number {\n return viewport.clientHeight;\n }\n}\n","import { PdfPageObjectWithRotatedSize } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { BaseScrollStrategy, ScrollStrategyConfig } from './base-strategy';\nimport { VirtualItem, PageLayout } from '../types/virtual-item';\n\nexport class HorizontalScrollStrategy extends BaseScrollStrategy {\n constructor(config: ScrollStrategyConfig) {\n super(config);\n }\n\n createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[] {\n let xOffset = 0;\n return pdfPageObject.map((pagesInSpread, index) => {\n let pageX = 0;\n const pageLayouts: PageLayout[] = pagesInSpread.map((page) => {\n const layout: PageLayout = {\n pageNumber: page.index + 1,\n pageIndex: page.index,\n x: pageX,\n y: 0,\n width: page.size.width,\n height: page.size.height,\n rotatedWidth: page.rotatedSize.width,\n rotatedHeight: page.rotatedSize.height,\n };\n pageX += page.rotatedSize.width + this.pageGap;\n return layout;\n });\n const width = pagesInSpread.reduce(\n (sum, page, i) =>\n sum + page.rotatedSize.width + (i < pagesInSpread.length - 1 ? this.pageGap : 0),\n 0,\n );\n const height = Math.max(...pagesInSpread.map((p) => p.rotatedSize.height));\n const item: VirtualItem = {\n id: `item-${index}`,\n x: xOffset,\n y: 0,\n offset: xOffset,\n width,\n height,\n pageLayouts,\n pageNumbers: pagesInSpread.map((p) => p.index + 1),\n index,\n };\n xOffset += width + this.pageGap;\n return item;\n });\n }\n\n getTotalContentSize(virtualItems: VirtualItem[]): { width: number; height: number } {\n if (virtualItems.length === 0) return { width: 0, height: 0 };\n const totalWidth =\n virtualItems[virtualItems.length - 1].x + virtualItems[virtualItems.length - 1].width;\n const maxHeight = Math.max(...virtualItems.map((item) => item.height));\n return {\n width: totalWidth,\n height: maxHeight,\n };\n }\n\n protected getScrollOffset(viewport: ViewportMetrics): number {\n return viewport.scrollLeft;\n }\n\n protected getClientSize(viewport: ViewportMetrics): number {\n return viewport.clientWidth;\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { ScrollState } from './types';\n\nexport const UPDATE_SCROLL_STATE = 'UPDATE_SCROLL_STATE';\nexport const SET_DESIRED_SCROLL_POSITION = 'SET_DESIRED_SCROLL_POSITION';\nexport const UPDATE_TOTAL_PAGES = 'UPDATE_TOTAL_PAGES';\n\nexport interface UpdateScrollStateAction extends Action {\n type: typeof UPDATE_SCROLL_STATE;\n payload: Partial<ScrollState>;\n}\n\nexport interface SetDesiredScrollPositionAction extends Action {\n type: typeof SET_DESIRED_SCROLL_POSITION;\n payload: { x: number; y: number };\n}\n\nexport interface UpdateTotalPagesAction extends Action {\n type: typeof UPDATE_TOTAL_PAGES;\n payload: number;\n}\n\nexport type ScrollAction =\n | UpdateScrollStateAction\n | SetDesiredScrollPositionAction\n | UpdateTotalPagesAction;\n\nexport function updateScrollState(payload: Partial<ScrollState>): UpdateScrollStateAction {\n return { type: UPDATE_SCROLL_STATE, payload };\n}\n\nexport function setDesiredScrollPosition(payload: {\n x: number;\n y: number;\n}): SetDesiredScrollPositionAction {\n return { type: SET_DESIRED_SCROLL_POSITION, payload };\n}\n\nexport function updateTotalPages(payload: number): UpdateTotalPagesAction {\n return { type: UPDATE_TOTAL_PAGES, payload };\n}\n","import { ScrollerLayout, ScrollState } from './types';\n\nexport const getScrollerLayout = (state: ScrollState, scale: number): ScrollerLayout => {\n return {\n startSpacing: state.startSpacing,\n endSpacing: state.endSpacing,\n totalWidth: state.totalContentSize.width * scale,\n totalHeight: state.totalContentSize.height * scale,\n pageGap: state.pageGap * scale,\n strategy: state.strategy,\n items: state.renderedPageIndexes.map((idx) => {\n return {\n ...state.virtualItems[idx],\n pageLayouts: state.virtualItems[idx].pageLayouts.map((layout) => {\n return {\n ...layout,\n rotatedWidth: layout.rotatedWidth * scale,\n rotatedHeight: layout.rotatedHeight * scale,\n width: layout.width * scale,\n height: layout.height * scale,\n };\n }),\n };\n }),\n };\n};\n","import {\n BasePlugin,\n CoreState,\n PluginRegistry,\n SET_DOCUMENT,\n SET_PAGES,\n SET_ROTATION,\n StoreState,\n createBehaviorEmitter,\n createEmitter,\n getPagesWithRotatedSize,\n} from '@embedpdf/core';\nimport {\n PdfPageObject,\n PdfPageObjectWithRotatedSize,\n Position,\n Rect,\n restoreRect,\n rotateRect,\n Rotation,\n transformRect,\n} from '@embedpdf/models';\nimport { ViewportCapability, ViewportMetrics, ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport {\n ScrollCapability,\n ScrollPluginConfig,\n ScrollStrategy,\n ScrollMetrics,\n ScrollState,\n LayoutChangePayload,\n ScrollerLayout,\n ScrollToPageOptions,\n PageChangePayload,\n} from './types';\nimport { BaseScrollStrategy, ScrollStrategyConfig } from './strategies/base-strategy';\nimport { VerticalScrollStrategy } from './strategies/vertical-strategy';\nimport { HorizontalScrollStrategy } from './strategies/horizontal-strategy';\nimport { updateScrollState, ScrollAction, updateTotalPages } from './actions';\nimport { VirtualItem } from './types/virtual-item';\nimport { getScrollerLayout } from './selectors';\n\ntype PartialScroll = Partial<ScrollState>;\ntype Emits = {\n layout?: LayoutChangePayload;\n metrics?: ScrollMetrics;\n};\n\nexport class ScrollPlugin extends BasePlugin<\n ScrollPluginConfig,\n ScrollCapability,\n ScrollState,\n ScrollAction\n> {\n static readonly id = 'scroll' as const;\n private viewport: ViewportCapability;\n private strategy: BaseScrollStrategy;\n private strategyConfig: ScrollStrategyConfig;\n private currentScale: number = 1;\n private currentRotation: Rotation = Rotation.Degree0;\n private initialPage?: number;\n private currentPage: number = 1;\n private layoutReady: boolean = false;\n\n private readonly layout$ = createBehaviorEmitter<LayoutChangePayload>();\n private readonly scroll$ = createBehaviorEmitter<ScrollMetrics>();\n private readonly state$ = createBehaviorEmitter<ScrollState>();\n private readonly scrollerLayout$ = createBehaviorEmitter<ScrollerLayout>();\n private readonly pageChange$ = createBehaviorEmitter<PageChangePayload>();\n private readonly layoutReady$ = createBehaviorEmitter<boolean>();\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n private config?: ScrollPluginConfig,\n ) {\n super(id, registry);\n\n this.viewport = this.registry.getPlugin<ViewportPlugin>('viewport')!.provides();\n\n this.strategyConfig = {\n pageGap: this.config?.pageGap ?? 10,\n viewportGap: this.viewport.getViewportGap(),\n bufferSize: this.config?.bufferSize ?? 2,\n };\n\n this.strategy =\n this.config?.strategy === ScrollStrategy.Horizontal\n ? new HorizontalScrollStrategy(this.strategyConfig)\n : new VerticalScrollStrategy(this.strategyConfig);\n\n this.initialPage = this.config?.initialPage;\n this.currentScale = this.coreState.core.scale;\n this.currentRotation = this.coreState.core.rotation;\n // Subscribe to viewport and page manager events\n this.viewport.onViewportChange((vp) => this.commitMetrics(this.computeMetrics(vp)), {\n mode: 'throttle',\n wait: 100,\n });\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n const totalPages = state.core.pages.length;\n this.dispatch(updateTotalPages(totalPages));\n this.pageChange$.emit({ pageNumber: this.currentPage, totalPages });\n this.refreshAll(getPagesWithRotatedSize(state.core), this.viewport.getMetrics());\n });\n this.coreStore.onAction(SET_ROTATION, (_action, state) =>\n this.refreshAll(getPagesWithRotatedSize(state.core), this.viewport.getMetrics()),\n );\n this.coreStore.onAction(SET_PAGES, (_action, state) =>\n this.refreshAll(getPagesWithRotatedSize(state.core), this.viewport.getMetrics()),\n );\n }\n\n /* ------------------------------------------------------------------ */\n /* ᴄᴏᴍᴘᴜᴛᴇʀs */\n /* ------------------------------------------------------------------ */\n\n private computeLayout(pages: PdfPageObjectWithRotatedSize[][]) {\n const virtualItems = this.strategy.createVirtualItems(pages);\n const totalContentSize = this.strategy.getTotalContentSize(virtualItems);\n return { virtualItems, totalContentSize };\n }\n\n private computeMetrics(vp: ViewportMetrics, items: VirtualItem[] = this.state.virtualItems) {\n return this.strategy.handleScroll(vp, items, this.currentScale);\n }\n\n /* ------------------------------------------------------------------ */\n /* ᴄᴏᴍᴍɪᴛ (single source of truth) */\n /* ------------------------------------------------------------------ */\n\n private commit(stateDelta: PartialScroll, emit?: Emits) {\n /* update Redux-like store */\n this.dispatch(updateScrollState(stateDelta));\n\n /* fire optional events */\n if (emit?.layout) this.layout$.emit(emit.layout);\n if (emit?.metrics) {\n this.scroll$.emit(emit.metrics);\n\n if (emit.metrics.currentPage !== this.currentPage) {\n this.currentPage = emit.metrics.currentPage;\n this.pageChange$.emit({ pageNumber: this.currentPage, totalPages: this.state.totalPages });\n }\n }\n\n /* keep scroller-layout reactive */\n this.scrollerLayout$.emit(this.getScrollerLayoutFromState());\n }\n\n /* convenience wrappers */\n private commitMetrics(metrics: ScrollMetrics) {\n this.commit(metrics, { metrics });\n }\n\n /* full re-compute after page-spread or initialisation */\n private refreshAll(pages: PdfPageObjectWithRotatedSize[][], vp: ViewportMetrics) {\n const layout = this.computeLayout(pages);\n const metrics = this.computeMetrics(vp, layout.virtualItems);\n\n this.commit({ ...layout, ...metrics }, { layout, metrics });\n }\n\n private getVirtualItemsFromState(): VirtualItem[] {\n return this.state.virtualItems || [];\n }\n\n private getScrollerLayoutFromState(): ScrollerLayout {\n const scale = this.coreState.core.scale;\n return getScrollerLayout(this.state, scale);\n }\n\n private pushScrollLayout() {\n this.scrollerLayout$.emit(this.getScrollerLayoutFromState());\n }\n\n override onStoreUpdated(_prevState: ScrollState, _newState: ScrollState): void {\n this.pushScrollLayout();\n }\n\n override onCoreStoreUpdated(\n prevState: StoreState<CoreState>,\n newState: StoreState<CoreState>,\n ): void {\n if (prevState.core.scale !== newState.core.scale) {\n this.currentScale = newState.core.scale;\n this.commitMetrics(this.computeMetrics(this.viewport.getMetrics()));\n }\n if (prevState.core.rotation !== newState.core.rotation) {\n this.currentRotation = newState.core.rotation;\n }\n }\n\n /**\n * Change the scroll strategy at runtime (e.g., vertical <-> horizontal)\n * @param newStrategy ScrollStrategy.Horizontal or ScrollStrategy.Vertical\n */\n private setScrollStrategy(newStrategy: ScrollStrategy) {\n // Only update if the strategy is actually changing\n if (\n (newStrategy === ScrollStrategy.Horizontal &&\n this.strategy instanceof HorizontalScrollStrategy) ||\n (newStrategy === ScrollStrategy.Vertical && this.strategy instanceof VerticalScrollStrategy)\n ) {\n return;\n }\n\n this.strategy =\n newStrategy === ScrollStrategy.Horizontal\n ? new HorizontalScrollStrategy(this.strategyConfig)\n : new VerticalScrollStrategy(this.strategyConfig);\n\n // Update state with new strategy\n this.dispatch(\n updateScrollState({\n strategy: newStrategy,\n }),\n );\n\n // Recalculate layout and scroll metrics\n const pages = getPagesWithRotatedSize(this.coreState.core);\n this.refreshAll(pages, this.viewport.getMetrics());\n }\n\n public setLayoutReady() {\n if (this.layoutReady) return;\n\n this.layoutReady = true;\n this.layoutReady$.emit(true);\n }\n\n protected buildCapability(): ScrollCapability {\n return {\n onStateChange: this.state$.on,\n onLayoutChange: this.layout$.on,\n onScroll: this.scroll$.on,\n onPageChange: this.pageChange$.on,\n onScrollerData: this.scrollerLayout$.on,\n onLayoutReady: this.layoutReady$.on,\n getCurrentPage: () => this.currentPage,\n getTotalPages: () => this.state.totalPages,\n scrollToPage: (options: ScrollToPageOptions) => {\n const { pageNumber, behavior = 'smooth', pageCoordinates, center = false } = options;\n const virtualItems = this.getVirtualItemsFromState();\n const position = this.strategy.getScrollPositionForPage(\n pageNumber,\n virtualItems,\n this.currentScale,\n this.currentRotation,\n pageCoordinates,\n );\n if (position) {\n this.viewport.scrollTo({ ...position, behavior, center });\n }\n },\n scrollToNextPage: (behavior = 'smooth') => {\n const virtualItems = this.getVirtualItemsFromState();\n const currentItemIndex = virtualItems.findIndex((item) =>\n item.pageNumbers.includes(this.currentPage),\n );\n if (currentItemIndex >= 0 && currentItemIndex < virtualItems.length - 1) {\n const nextItem = virtualItems[currentItemIndex + 1];\n const position = this.strategy.getScrollPositionForPage(\n nextItem.pageNumbers[0],\n virtualItems,\n this.currentScale,\n this.currentRotation,\n );\n if (position) {\n this.viewport.scrollTo({ ...position, behavior });\n }\n }\n },\n scrollToPreviousPage: (behavior = 'smooth') => {\n const virtualItems = this.getVirtualItemsFromState();\n const currentItemIndex = virtualItems.findIndex((item) =>\n item.pageNumbers.includes(this.currentPage),\n );\n if (currentItemIndex > 0) {\n const prevItem = virtualItems[currentItemIndex - 1];\n const position = this.strategy.getScrollPositionForPage(\n prevItem.pageNumbers[0],\n virtualItems,\n this.currentScale,\n this.currentRotation,\n );\n if (position) {\n this.viewport.scrollTo({ ...position, behavior });\n }\n }\n },\n getMetrics: this.getMetrics.bind(this),\n getLayout: this.getLayout.bind(this),\n getRectPositionForPage: this.getRectPositionForPage.bind(this),\n getPageGap: () => this.state.pageGap,\n getScrollerLayout: () => this.getScrollerLayoutFromState(),\n setScrollStrategy: (strategy: ScrollStrategy) => this.setScrollStrategy(strategy),\n };\n }\n\n private getMetrics(viewport?: ViewportMetrics): ScrollMetrics {\n const metrics = viewport || this.viewport.getMetrics();\n const virtualItems = this.getVirtualItemsFromState();\n return this.strategy.handleScroll(metrics, virtualItems, this.currentScale);\n }\n\n private getLayout(): LayoutChangePayload {\n return {\n virtualItems: this.state.virtualItems,\n totalContentSize: this.state.totalContentSize,\n };\n }\n\n private getRectPositionForPage(\n pageIndex: number,\n rect: Rect,\n scale?: number,\n rotation?: Rotation,\n ): Rect | null {\n return this.strategy.getRectPositionForPage(\n pageIndex + 1,\n this.state.virtualItems,\n scale ?? this.currentScale,\n rotation ?? this.currentRotation,\n rect,\n );\n }\n\n async initialize(): Promise<void> {\n // No DOM initialization needed; state drives rendering\n }\n\n async destroy(): Promise<void> {\n this.layout$.clear();\n this.scroll$.clear();\n this.pageChange$.clear();\n this.state$.clear();\n this.scrollerLayout$.clear();\n this.layoutReady$.clear();\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { ScrollPluginConfig } from './types';\n\nexport const SCROLL_PLUGIN_ID = 'scroll';\n\nexport const manifest: PluginManifest<ScrollPluginConfig> = {\n id: SCROLL_PLUGIN_ID,\n name: 'Scroll Plugin',\n version: '1.0.0',\n provides: ['scroll'],\n requires: ['viewport'],\n optional: [],\n defaultConfig: {\n enabled: true,\n pageGap: 10,\n },\n};\n","import { Reducer, CoreState, SET_SCALE, SetScaleAction } from '@embedpdf/core';\nimport { ScrollState, ScrollStrategy, ScrollPluginConfig, ScrollMetrics } from './types';\nimport {\n ScrollAction,\n UPDATE_SCROLL_STATE,\n SET_DESIRED_SCROLL_POSITION,\n UPDATE_TOTAL_PAGES,\n} from './actions';\n\nexport const defaultScrollMetrics: ScrollMetrics = {\n currentPage: 1,\n visiblePages: [],\n pageVisibilityMetrics: [],\n renderedPageIndexes: [],\n scrollOffset: { x: 0, y: 0 },\n startSpacing: 0,\n endSpacing: 0,\n};\n\nexport const initialState: (coreState: CoreState, config: ScrollPluginConfig) => ScrollState = (\n coreState,\n config,\n) => ({\n virtualItems: [],\n totalPages: coreState.pages.length,\n totalContentSize: { width: 0, height: 0 },\n desiredScrollPosition: { x: 0, y: 0 },\n strategy: config.strategy ?? ScrollStrategy.Vertical,\n pageGap: config.pageGap ?? 10,\n scale: coreState.scale,\n ...defaultScrollMetrics,\n});\n\nexport const scrollReducer: Reducer<ScrollState, ScrollAction | SetScaleAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case UPDATE_TOTAL_PAGES:\n return { ...state, totalPages: action.payload };\n case SET_SCALE:\n return { ...state, scale: action.payload };\n case UPDATE_SCROLL_STATE:\n return { ...state, ...action.payload };\n case SET_DESIRED_SCROLL_POSITION:\n return { ...state, desiredScrollPosition: action.payload };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { ScrollPlugin } from './scroll-plugin';\nimport { manifest, SCROLL_PLUGIN_ID } from './manifest';\nimport { ScrollPluginConfig, ScrollState } from './types';\nimport { scrollReducer, initialState } from './reducer';\nimport { ScrollAction } from './actions';\n\nexport const ScrollPluginPackage: PluginPackage<\n ScrollPlugin,\n ScrollPluginConfig,\n ScrollState,\n ScrollAction\n> = {\n manifest,\n create: (registry, config) => new ScrollPlugin(SCROLL_PLUGIN_ID, registry, config),\n reducer: scrollReducer,\n initialState: (coreState, config) => initialState(coreState, config),\n};\n\nexport * from './scroll-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './types/virtual-item';\n"],"names":["ScrollStrategy","item"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/types.ts","../src/lib/strategies/base-strategy.ts","../src/lib/strategies/vertical-strategy.ts","../src/lib/strategies/horizontal-strategy.ts","../src/lib/actions.ts","../src/lib/selectors.ts","../src/lib/scroll-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePluginConfig, Emitter, EventHook } from '@embedpdf/core';\nimport { PdfPageObject, Rect, Rotation } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { VirtualItem } from './types/virtual-item';\n\nexport type ScrollBehavior = 'instant' | 'smooth' | 'auto';\n\nexport interface ScrollState extends ScrollMetrics {\n virtualItems: VirtualItem[];\n totalPages: number;\n totalContentSize: { width: number; height: number };\n desiredScrollPosition: { x: number; y: number };\n strategy: ScrollStrategy;\n pageGap: number;\n scale: number;\n}\n\nexport interface ScrollerLayout {\n startSpacing: number;\n endSpacing: number;\n totalWidth: number;\n totalHeight: number;\n pageGap: number;\n strategy: ScrollState['strategy'];\n items: VirtualItem[];\n}\n\nexport enum ScrollStrategy {\n Vertical = 'vertical',\n Horizontal = 'horizontal',\n}\n\nexport interface PageVisibilityMetrics {\n pageNumber: number;\n viewportX: number;\n viewportY: number;\n visiblePercentage: number;\n original: {\n pageX: number;\n pageY: number;\n visibleWidth: number;\n visibleHeight: number;\n scale: number;\n };\n scaled: {\n pageX: number;\n pageY: number;\n visibleWidth: number;\n visibleHeight: number;\n scale: number;\n };\n}\n\nexport interface ScrollMetrics {\n currentPage: number;\n visiblePages: number[];\n pageVisibilityMetrics: PageVisibilityMetrics[];\n renderedPageIndexes: number[];\n scrollOffset: { x: number; y: number };\n startSpacing: number;\n endSpacing: number;\n}\n\nexport interface ScrollStrategyInterface {\n initialize(container: HTMLElement, innerDiv: HTMLElement): void;\n destroy(): void;\n updateLayout(viewport: ViewportMetrics, pdfPageObject: PdfPageObject[][]): void;\n handleScroll(viewport: ViewportMetrics): void;\n getVirtualItems(): VirtualItem[];\n scrollToPage(pageNumber: number, behavior?: ScrollBehavior): void;\n calculateDimensions(pdfPageObject: PdfPageObject[][]): void;\n}\n\nexport interface ScrollPluginConfig extends BasePluginConfig {\n strategy?: ScrollStrategy;\n initialPage?: number;\n bufferSize?: number;\n pageGap?: number;\n}\n\nexport type LayoutChangePayload = Pick<ScrollState, 'virtualItems' | 'totalContentSize'>;\n\nexport interface ScrollToPageOptions {\n pageNumber: number;\n pageCoordinates?: { x: number; y: number };\n behavior?: ScrollBehavior;\n center?: boolean;\n}\n\nexport interface PageChangePayload {\n pageNumber: number;\n totalPages: number;\n}\n\nexport interface ScrollCapability {\n onStateChange: EventHook<ScrollState>;\n onScroll: EventHook<ScrollMetrics>;\n getCurrentPage(): number;\n getTotalPages(): number;\n onPageChange: EventHook<PageChangePayload>;\n onLayoutChange: EventHook<LayoutChangePayload>;\n onLayoutReady: EventHook<boolean>;\n scrollToPage(options: ScrollToPageOptions): void;\n scrollToNextPage(behavior?: ScrollBehavior): void;\n scrollToPreviousPage(behavior?: ScrollBehavior): void;\n getMetrics(viewport?: ViewportMetrics): ScrollMetrics;\n getLayout(): LayoutChangePayload;\n getRectPositionForPage(\n page: number,\n rect: Rect,\n scale?: number,\n rotation?: Rotation,\n ): Rect | null;\n setScrollStrategy(strategy: ScrollStrategy): void;\n getPageGap(): number;\n}\n","import {\n PdfPageObjectWithRotatedSize,\n Position,\n Rect,\n Rotation,\n scalePosition,\n Size,\n transformPosition,\n transformRect,\n} from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { VirtualItem } from '../types/virtual-item';\nimport { ScrollMetrics } from '../types';\n\nexport interface ScrollStrategyConfig {\n pageGap?: number;\n viewportGap?: number;\n bufferSize?: number;\n}\n\nexport abstract class BaseScrollStrategy {\n protected pageGap: number;\n protected viewportGap: number;\n protected bufferSize: number;\n\n constructor(config: ScrollStrategyConfig) {\n this.pageGap = config.pageGap ?? 20;\n this.viewportGap = config.viewportGap ?? 20;\n this.bufferSize = config.bufferSize ?? 2;\n }\n\n abstract createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[];\n abstract getTotalContentSize(virtualItems: VirtualItem[]): Size;\n protected abstract getScrollOffset(viewport: ViewportMetrics): number;\n protected abstract getClientSize(viewport: ViewportMetrics): number;\n\n protected getVisibleRange(\n viewport: ViewportMetrics,\n virtualItems: VirtualItem[],\n scale: number,\n ): { start: number; end: number } {\n const scrollOffset = this.getScrollOffset(viewport);\n const clientSize = this.getClientSize(viewport);\n const viewportStart = scrollOffset;\n const viewportEnd = scrollOffset + clientSize;\n\n let startIndex = 0;\n while (\n startIndex < virtualItems.length &&\n (virtualItems[startIndex].offset + virtualItems[startIndex].height) * scale <= viewportStart\n ) {\n startIndex++;\n }\n\n let endIndex = startIndex;\n while (endIndex < virtualItems.length && virtualItems[endIndex].offset * scale <= viewportEnd) {\n endIndex++;\n }\n\n return {\n start: Math.max(0, startIndex - this.bufferSize),\n end: Math.min(virtualItems.length - 1, endIndex + this.bufferSize - 1),\n };\n }\n\n handleScroll(\n viewport: ViewportMetrics,\n virtualItems: VirtualItem[],\n scale: number,\n ): ScrollMetrics {\n const range = this.getVisibleRange(viewport, virtualItems, scale);\n const visibleItems = virtualItems.slice(range.start, range.end + 1);\n const pageVisibilityMetrics = this.calculatePageVisibility(visibleItems, viewport, scale);\n const visiblePages = pageVisibilityMetrics.map((m) => m.pageNumber);\n const renderedPageIndexes = virtualItems\n .slice(range.start, range.end + 1)\n .flatMap((item) => item.index);\n const currentPage = this.determineCurrentPage(pageVisibilityMetrics);\n const first = virtualItems[range.start];\n const last = virtualItems[range.end];\n const startSpacing = first ? first.offset * scale : 0;\n const endSpacing = last\n ? (virtualItems[virtualItems.length - 1].offset + // end of content\n virtualItems[virtualItems.length - 1].height) *\n scale - // minus\n (last.offset + last.height) * scale // end of last rendered\n : 0;\n\n return {\n currentPage,\n visiblePages,\n pageVisibilityMetrics,\n renderedPageIndexes,\n scrollOffset: { x: viewport.scrollLeft, y: viewport.scrollTop },\n startSpacing,\n endSpacing,\n };\n }\n\n protected calculatePageVisibility(\n virtualItems: VirtualItem[],\n viewport: ViewportMetrics,\n scale: number,\n ): ScrollMetrics['pageVisibilityMetrics'] {\n const visibilityMetrics: ScrollMetrics['pageVisibilityMetrics'] = [];\n\n virtualItems.forEach((item) => {\n item.pageLayouts.forEach((page) => {\n const itemX = item.x * scale;\n const itemY = item.y * scale;\n const pageX = itemX + page.x * scale;\n const pageY = itemY + page.y * scale;\n const pageWidth = page.rotatedWidth * scale;\n const pageHeight = page.rotatedHeight * scale;\n\n const viewportLeft = viewport.scrollLeft;\n const viewportTop = viewport.scrollTop;\n const viewportRight = viewportLeft + viewport.clientWidth;\n const viewportBottom = viewportTop + viewport.clientHeight;\n\n const intersectionLeft = Math.max(pageX, viewportLeft);\n const intersectionTop = Math.max(pageY, viewportTop);\n const intersectionRight = Math.min(pageX + pageWidth, viewportRight);\n const intersectionBottom = Math.min(pageY + pageHeight, viewportBottom);\n\n if (intersectionLeft < intersectionRight && intersectionTop < intersectionBottom) {\n const visibleWidth = intersectionRight - intersectionLeft;\n const visibleHeight = intersectionBottom - intersectionTop;\n const totalArea = pageWidth * pageHeight;\n const visibleArea = visibleWidth * visibleHeight;\n\n visibilityMetrics.push({\n pageNumber: page.pageNumber,\n viewportX: intersectionLeft - viewportLeft,\n viewportY: intersectionTop - viewportTop,\n visiblePercentage: (visibleArea / totalArea) * 100,\n original: {\n pageX: (intersectionLeft - pageX) / scale,\n pageY: (intersectionTop - pageY) / scale,\n visibleWidth: visibleWidth / scale,\n visibleHeight: visibleHeight / scale,\n scale: 1,\n },\n scaled: {\n pageX: intersectionLeft - pageX,\n pageY: intersectionTop - pageY,\n visibleWidth,\n visibleHeight,\n scale,\n },\n });\n }\n });\n });\n\n return visibilityMetrics;\n }\n\n protected determineCurrentPage(\n visibilityMetrics: ScrollMetrics['pageVisibilityMetrics'],\n ): number {\n if (visibilityMetrics.length === 0) return 1;\n\n const maxVisibility = Math.max(...visibilityMetrics.map((m) => m.visiblePercentage));\n const mostVisiblePages = visibilityMetrics.filter((m) => m.visiblePercentage === maxVisibility);\n\n return mostVisiblePages.length === 1\n ? mostVisiblePages[0].pageNumber\n : mostVisiblePages.sort((a, b) => a.pageNumber - b.pageNumber)[0].pageNumber;\n }\n\n private getRectLocationForPage(\n pageNumber: number,\n virtualItems: VirtualItem[],\n totalContentSize?: Size,\n ): Rect | null {\n // Find the virtual item containing the page\n const item = virtualItems.find((item) => item.pageNumbers.includes(pageNumber));\n if (!item) return null;\n\n // Find the specific page layout for the requested page number\n const pageLayout = item.pageLayouts.find((layout) => layout.pageNumber === pageNumber);\n if (!pageLayout) return null;\n\n // Calculate centering offset for items that are narrower than the maximum width\n let centeringOffsetX = 0;\n if (totalContentSize) {\n const maxWidth = totalContentSize.width;\n if (item.width < maxWidth) {\n centeringOffsetX = (maxWidth - item.width) / 2;\n }\n }\n\n return {\n origin: {\n x: item.x + pageLayout.x + centeringOffsetX,\n y: item.y + pageLayout.y,\n },\n size: {\n width: pageLayout.width,\n height: pageLayout.height,\n },\n };\n }\n\n getScrollPositionForPage(\n pageNumber: number,\n virtualItems: VirtualItem[],\n scale: number,\n rotation: Rotation,\n pageCoordinates?: { x: number; y: number },\n ): Position | null {\n const totalContentSize = this.getTotalContentSize(virtualItems);\n const pageRect = this.getRectLocationForPage(pageNumber, virtualItems, totalContentSize);\n if (!pageRect) return null;\n\n const scaledBasePosition = scalePosition(pageRect.origin, scale);\n\n // If specific page coordinates are provided, add them to the base position\n if (pageCoordinates) {\n const rotatedSize = transformPosition(\n {\n width: pageRect.size.width,\n height: pageRect.size.height,\n },\n {\n x: pageCoordinates.x,\n y: pageCoordinates.y,\n },\n rotation,\n scale,\n );\n\n return {\n x: scaledBasePosition.x + rotatedSize.x + this.viewportGap,\n y: scaledBasePosition.y + rotatedSize.y + this.viewportGap,\n };\n }\n\n return {\n x: scaledBasePosition.x + this.viewportGap,\n y: scaledBasePosition.y + this.viewportGap,\n };\n }\n\n getRectPositionForPage(\n pageNumber: number,\n virtualItems: VirtualItem[],\n scale: number,\n rotation: Rotation,\n rect: Rect,\n ): Rect | null {\n const totalContentSize = this.getTotalContentSize(virtualItems);\n const pageRect = this.getRectLocationForPage(pageNumber, virtualItems, totalContentSize);\n if (!pageRect) return null;\n\n const scaledBasePosition = scalePosition(pageRect.origin, scale);\n\n const rotatedSize = transformRect(\n {\n width: pageRect.size.width,\n height: pageRect.size.height,\n },\n rect,\n rotation,\n scale,\n );\n\n return {\n origin: {\n x: scaledBasePosition.x + rotatedSize.origin.x,\n y: scaledBasePosition.y + rotatedSize.origin.y,\n },\n size: rotatedSize.size,\n };\n }\n}\n","import { PdfPageObjectWithRotatedSize } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { BaseScrollStrategy, ScrollStrategyConfig } from './base-strategy';\nimport { VirtualItem, PageLayout } from '../types/virtual-item';\nimport { ScrollMetrics } from '../types';\n\nexport class VerticalScrollStrategy extends BaseScrollStrategy {\n constructor(config: ScrollStrategyConfig) {\n super(config);\n }\n\n createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[] {\n let yOffset = 0;\n return pdfPageObject.map((pagesInSpread, index) => {\n let pageX = 0;\n const pageLayouts: PageLayout[] = pagesInSpread.map((page) => {\n const layout: PageLayout = {\n pageNumber: page.index + 1,\n pageIndex: page.index,\n x: pageX,\n y: 0,\n width: page.size.width,\n height: page.size.height,\n rotatedWidth: page.rotatedSize.width,\n rotatedHeight: page.rotatedSize.height,\n };\n pageX += page.rotatedSize.width + this.pageGap;\n return layout;\n });\n const width = pagesInSpread.reduce(\n (sum, page, i) =>\n sum + page.rotatedSize.width + (i < pagesInSpread.length - 1 ? this.pageGap : 0),\n 0,\n );\n const height = Math.max(...pagesInSpread.map((p) => p.rotatedSize.height));\n const item: VirtualItem = {\n id: `item-${index}`,\n x: 0,\n y: yOffset,\n offset: yOffset,\n width,\n height,\n pageLayouts,\n pageNumbers: pagesInSpread.map((p) => p.index + 1),\n index,\n };\n yOffset += height + this.pageGap;\n return item;\n });\n }\n\n getTotalContentSize(virtualItems: VirtualItem[]): { width: number; height: number } {\n if (virtualItems.length === 0) return { width: 0, height: 0 };\n const maxWidth = Math.max(...virtualItems.map((item) => item.width));\n const totalHeight =\n virtualItems[virtualItems.length - 1].y + virtualItems[virtualItems.length - 1].height;\n return {\n width: maxWidth,\n height: totalHeight,\n };\n }\n\n protected getScrollOffset(viewport: ViewportMetrics): number {\n return viewport.scrollTop;\n }\n\n protected getClientSize(viewport: ViewportMetrics): number {\n return viewport.clientHeight;\n }\n}\n","import { PdfPageObjectWithRotatedSize } from '@embedpdf/models';\nimport { ViewportMetrics } from '@embedpdf/plugin-viewport';\nimport { BaseScrollStrategy, ScrollStrategyConfig } from './base-strategy';\nimport { VirtualItem, PageLayout } from '../types/virtual-item';\n\nexport class HorizontalScrollStrategy extends BaseScrollStrategy {\n constructor(config: ScrollStrategyConfig) {\n super(config);\n }\n\n createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[] {\n let xOffset = 0;\n return pdfPageObject.map((pagesInSpread, index) => {\n let pageX = 0;\n const pageLayouts: PageLayout[] = pagesInSpread.map((page) => {\n const layout: PageLayout = {\n pageNumber: page.index + 1,\n pageIndex: page.index,\n x: pageX,\n y: 0,\n width: page.size.width,\n height: page.size.height,\n rotatedWidth: page.rotatedSize.width,\n rotatedHeight: page.rotatedSize.height,\n };\n pageX += page.rotatedSize.width + this.pageGap;\n return layout;\n });\n const width = pagesInSpread.reduce(\n (sum, page, i) =>\n sum + page.rotatedSize.width + (i < pagesInSpread.length - 1 ? this.pageGap : 0),\n 0,\n );\n const height = Math.max(...pagesInSpread.map((p) => p.rotatedSize.height));\n const item: VirtualItem = {\n id: `item-${index}`,\n x: xOffset,\n y: 0,\n offset: xOffset,\n width,\n height,\n pageLayouts,\n pageNumbers: pagesInSpread.map((p) => p.index + 1),\n index,\n };\n xOffset += width + this.pageGap;\n return item;\n });\n }\n\n getTotalContentSize(virtualItems: VirtualItem[]): { width: number; height: number } {\n if (virtualItems.length === 0) return { width: 0, height: 0 };\n const totalWidth =\n virtualItems[virtualItems.length - 1].x + virtualItems[virtualItems.length - 1].width;\n const maxHeight = Math.max(...virtualItems.map((item) => item.height));\n return {\n width: totalWidth,\n height: maxHeight,\n };\n }\n\n protected getScrollOffset(viewport: ViewportMetrics): number {\n return viewport.scrollLeft;\n }\n\n protected getClientSize(viewport: ViewportMetrics): number {\n return viewport.clientWidth;\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { ScrollState } from './types';\n\nexport const UPDATE_SCROLL_STATE = 'UPDATE_SCROLL_STATE';\nexport const SET_DESIRED_SCROLL_POSITION = 'SET_DESIRED_SCROLL_POSITION';\nexport const UPDATE_TOTAL_PAGES = 'UPDATE_TOTAL_PAGES';\n\nexport interface UpdateScrollStateAction extends Action {\n type: typeof UPDATE_SCROLL_STATE;\n payload: Partial<ScrollState>;\n}\n\nexport interface SetDesiredScrollPositionAction extends Action {\n type: typeof SET_DESIRED_SCROLL_POSITION;\n payload: { x: number; y: number };\n}\n\nexport interface UpdateTotalPagesAction extends Action {\n type: typeof UPDATE_TOTAL_PAGES;\n payload: number;\n}\n\nexport type ScrollAction =\n | UpdateScrollStateAction\n | SetDesiredScrollPositionAction\n | UpdateTotalPagesAction;\n\nexport function updateScrollState(payload: Partial<ScrollState>): UpdateScrollStateAction {\n return { type: UPDATE_SCROLL_STATE, payload };\n}\n\nexport function setDesiredScrollPosition(payload: {\n x: number;\n y: number;\n}): SetDesiredScrollPositionAction {\n return { type: SET_DESIRED_SCROLL_POSITION, payload };\n}\n\nexport function updateTotalPages(payload: number): UpdateTotalPagesAction {\n return { type: UPDATE_TOTAL_PAGES, payload };\n}\n","import { ScrollerLayout, ScrollState } from './types';\n\nexport const getScrollerLayout = (state: ScrollState, scale: number): ScrollerLayout => {\n return {\n startSpacing: state.startSpacing,\n endSpacing: state.endSpacing,\n totalWidth: state.totalContentSize.width * scale,\n totalHeight: state.totalContentSize.height * scale,\n pageGap: state.pageGap * scale,\n strategy: state.strategy,\n items: state.renderedPageIndexes.map((idx) => {\n return {\n ...state.virtualItems[idx],\n pageLayouts: state.virtualItems[idx].pageLayouts.map((layout) => {\n return {\n ...layout,\n rotatedWidth: layout.rotatedWidth * scale,\n rotatedHeight: layout.rotatedHeight * scale,\n width: layout.width * scale,\n height: layout.height * scale,\n };\n }),\n };\n }),\n };\n};\n","import {\n BasePlugin,\n CoreState,\n PluginRegistry,\n SET_DOCUMENT,\n SET_PAGES,\n SET_ROTATION,\n StoreState,\n Unsubscribe,\n createBehaviorEmitter,\n getPagesWithRotatedSize,\n} from '@embedpdf/core';\nimport { PdfPageObjectWithRotatedSize, Rect, Rotation } from '@embedpdf/models';\nimport { ViewportCapability, ViewportMetrics, ViewportPlugin } from '@embedpdf/plugin-viewport';\nimport {\n ScrollCapability,\n ScrollPluginConfig,\n ScrollStrategy,\n ScrollMetrics,\n ScrollState,\n LayoutChangePayload,\n ScrollerLayout,\n ScrollToPageOptions,\n PageChangePayload,\n ScrollBehavior,\n} from './types';\nimport { BaseScrollStrategy, ScrollStrategyConfig } from './strategies/base-strategy';\nimport { VerticalScrollStrategy } from './strategies/vertical-strategy';\nimport { HorizontalScrollStrategy } from './strategies/horizontal-strategy';\nimport { updateScrollState, ScrollAction, updateTotalPages } from './actions';\nimport { VirtualItem } from './types/virtual-item';\nimport { getScrollerLayout } from './selectors';\n\ntype PartialScroll = Partial<ScrollState>;\ntype Emits = {\n layout?: LayoutChangePayload;\n metrics?: ScrollMetrics;\n};\n\nexport class ScrollPlugin extends BasePlugin<\n ScrollPluginConfig,\n ScrollCapability,\n ScrollState,\n ScrollAction\n> {\n static readonly id = 'scroll' as const;\n private viewport: ViewportCapability;\n private strategy: BaseScrollStrategy;\n private strategyConfig: ScrollStrategyConfig;\n private currentScale: number = 1;\n private currentRotation: Rotation = Rotation.Degree0;\n private initialPage?: number;\n private currentPage: number = 1;\n private layoutReady: boolean = false;\n\n private readonly layout$ = createBehaviorEmitter<LayoutChangePayload>();\n private readonly scroll$ = createBehaviorEmitter<ScrollMetrics>();\n private readonly state$ = createBehaviorEmitter<ScrollState>();\n private readonly scrollerLayout$ = createBehaviorEmitter<ScrollerLayout>();\n private readonly pageChange$ = createBehaviorEmitter<PageChangePayload>();\n private readonly layoutReady$ = createBehaviorEmitter<boolean>();\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n private config?: ScrollPluginConfig,\n ) {\n super(id, registry);\n\n this.viewport = this.registry.getPlugin<ViewportPlugin>('viewport')!.provides();\n\n this.strategyConfig = {\n pageGap: this.config?.pageGap ?? 10,\n viewportGap: this.viewport.getViewportGap(),\n bufferSize: this.config?.bufferSize ?? 2,\n };\n\n this.strategy =\n this.config?.strategy === ScrollStrategy.Horizontal\n ? new HorizontalScrollStrategy(this.strategyConfig)\n : new VerticalScrollStrategy(this.strategyConfig);\n\n this.initialPage = this.config?.initialPage;\n this.currentScale = this.coreState.core.scale;\n this.currentRotation = this.coreState.core.rotation;\n // Subscribe to viewport and page manager events\n this.viewport.onViewportChange((vp) => this.commitMetrics(this.computeMetrics(vp)), {\n mode: 'throttle',\n wait: 100,\n });\n this.coreStore.onAction(SET_DOCUMENT, (_action, state) => {\n const totalPages = state.core.pages.length;\n this.dispatch(updateTotalPages(totalPages));\n this.pageChange$.emit({ pageNumber: this.currentPage, totalPages });\n this.refreshAll(getPagesWithRotatedSize(state.core), this.viewport.getMetrics());\n });\n this.coreStore.onAction(SET_ROTATION, (_action, state) =>\n this.refreshAll(getPagesWithRotatedSize(state.core), this.viewport.getMetrics()),\n );\n this.coreStore.onAction(SET_PAGES, (_action, state) =>\n this.refreshAll(getPagesWithRotatedSize(state.core), this.viewport.getMetrics()),\n );\n }\n\n /* ------------------------------------------------------------------ */\n /* ᴄᴏᴍᴘᴜᴛᴇʀs */\n /* ------------------------------------------------------------------ */\n\n private computeLayout(pages: PdfPageObjectWithRotatedSize[][]) {\n const virtualItems = this.strategy.createVirtualItems(pages);\n const totalContentSize = this.strategy.getTotalContentSize(virtualItems);\n return { virtualItems, totalContentSize };\n }\n\n private computeMetrics(vp: ViewportMetrics, items: VirtualItem[] = this.state.virtualItems) {\n return this.strategy.handleScroll(vp, items, this.currentScale);\n }\n\n /* ------------------------------------------------------------------ */\n /* ᴄᴏᴍᴍɪᴛ (single source of truth) */\n /* ------------------------------------------------------------------ */\n\n private commit(stateDelta: PartialScroll, emit?: Emits) {\n /* update Redux-like store */\n this.dispatch(updateScrollState(stateDelta));\n\n /* fire optional events */\n if (emit?.layout) this.layout$.emit(emit.layout);\n if (emit?.metrics) {\n this.scroll$.emit(emit.metrics);\n\n if (emit.metrics.currentPage !== this.currentPage) {\n this.currentPage = emit.metrics.currentPage;\n this.pageChange$.emit({ pageNumber: this.currentPage, totalPages: this.state.totalPages });\n }\n }\n\n /* keep scroller-layout reactive */\n this.scrollerLayout$.emit(this.getScrollerLayout());\n }\n\n /* convenience wrappers */\n private commitMetrics(metrics: ScrollMetrics) {\n this.commit(metrics, { metrics });\n }\n\n /* full re-compute after page-spread or initialisation */\n private refreshAll(pages: PdfPageObjectWithRotatedSize[][], vp: ViewportMetrics) {\n const layout = this.computeLayout(pages);\n const metrics = this.computeMetrics(vp, layout.virtualItems);\n\n this.commit({ ...layout, ...metrics }, { layout, metrics });\n }\n\n private getVirtualItemsFromState(): VirtualItem[] {\n return this.state.virtualItems || [];\n }\n\n public onScrollerData(callback: (layout: ScrollerLayout) => void): Unsubscribe {\n return this.scrollerLayout$.on(callback);\n }\n\n public getScrollerLayout(): ScrollerLayout {\n const scale = this.coreState.core.scale;\n return getScrollerLayout(this.state, scale);\n }\n\n private pushScrollLayout() {\n this.scrollerLayout$.emit(this.getScrollerLayout());\n }\n\n override onStoreUpdated(_prevState: ScrollState, _newState: ScrollState): void {\n this.pushScrollLayout();\n }\n\n override onCoreStoreUpdated(\n prevState: StoreState<CoreState>,\n newState: StoreState<CoreState>,\n ): void {\n if (prevState.core.scale !== newState.core.scale) {\n this.currentScale = newState.core.scale;\n this.commitMetrics(this.computeMetrics(this.viewport.getMetrics()));\n }\n if (prevState.core.rotation !== newState.core.rotation) {\n this.currentRotation = newState.core.rotation;\n }\n }\n\n /**\n * Change the scroll strategy at runtime (e.g., vertical <-> horizontal)\n * @param newStrategy ScrollStrategy.Horizontal or ScrollStrategy.Vertical\n */\n private setScrollStrategy(newStrategy: ScrollStrategy) {\n // Only update if the strategy is actually changing\n if (\n (newStrategy === ScrollStrategy.Horizontal &&\n this.strategy instanceof HorizontalScrollStrategy) ||\n (newStrategy === ScrollStrategy.Vertical && this.strategy instanceof VerticalScrollStrategy)\n ) {\n return;\n }\n\n this.strategy =\n newStrategy === ScrollStrategy.Horizontal\n ? new HorizontalScrollStrategy(this.strategyConfig)\n : new VerticalScrollStrategy(this.strategyConfig);\n\n // Update state with new strategy\n this.dispatch(\n updateScrollState({\n strategy: newStrategy,\n }),\n );\n\n // Recalculate layout and scroll metrics\n const pages = getPagesWithRotatedSize(this.coreState.core);\n this.refreshAll(pages, this.viewport.getMetrics());\n }\n\n public setLayoutReady() {\n if (this.layoutReady) return;\n\n this.layoutReady = true;\n this.layoutReady$.emit(true);\n\n if (this.initialPage) {\n this.scrollToPage({ pageNumber: this.initialPage, behavior: 'instant' });\n }\n }\n\n protected buildCapability(): ScrollCapability {\n return {\n onStateChange: this.state$.on,\n onLayoutChange: this.layout$.on,\n onScroll: this.scroll$.on,\n onPageChange: this.pageChange$.on,\n onLayoutReady: this.layoutReady$.on,\n getCurrentPage: () => this.currentPage,\n getTotalPages: () => this.state.totalPages,\n scrollToPage: this.scrollToPage.bind(this),\n scrollToNextPage: this.scrollToNextPage.bind(this),\n scrollToPreviousPage: this.scrollToPreviousPage.bind(this),\n getMetrics: this.getMetrics.bind(this),\n getLayout: this.getLayout.bind(this),\n getRectPositionForPage: this.getRectPositionForPage.bind(this),\n getPageGap: () => this.state.pageGap,\n setScrollStrategy: (strategy: ScrollStrategy) => this.setScrollStrategy(strategy),\n };\n }\n\n private scrollToPage(options: ScrollToPageOptions) {\n const { pageNumber, behavior = 'smooth', pageCoordinates, center = false } = options;\n const virtualItems = this.getVirtualItemsFromState();\n const position = this.strategy.getScrollPositionForPage(\n pageNumber,\n virtualItems,\n this.currentScale,\n this.currentRotation,\n pageCoordinates,\n );\n if (position) {\n this.viewport.scrollTo({ ...position, behavior, center });\n }\n }\n\n private scrollToNextPage(behavior: ScrollBehavior = 'smooth') {\n const virtualItems = this.getVirtualItemsFromState();\n const currentItemIndex = virtualItems.findIndex((item) =>\n item.pageNumbers.includes(this.currentPage),\n );\n if (currentItemIndex >= 0 && currentItemIndex < virtualItems.length - 1) {\n const nextItem = virtualItems[currentItemIndex + 1];\n const position = this.strategy.getScrollPositionForPage(\n nextItem.pageNumbers[0],\n virtualItems,\n this.currentScale,\n this.currentRotation,\n );\n if (position) {\n this.viewport.scrollTo({ ...position, behavior });\n }\n }\n }\n\n private scrollToPreviousPage(behavior: ScrollBehavior = 'smooth') {\n const virtualItems = this.getVirtualItemsFromState();\n const currentItemIndex = virtualItems.findIndex((item) =>\n item.pageNumbers.includes(this.currentPage),\n );\n if (currentItemIndex > 0) {\n const prevItem = virtualItems[currentItemIndex - 1];\n const position = this.strategy.getScrollPositionForPage(\n prevItem.pageNumbers[0],\n virtualItems,\n this.currentScale,\n this.currentRotation,\n );\n if (position) {\n this.viewport.scrollTo({ ...position, behavior });\n }\n }\n }\n\n private getMetrics(viewport?: ViewportMetrics): ScrollMetrics {\n const metrics = viewport || this.viewport.getMetrics();\n const virtualItems = this.getVirtualItemsFromState();\n return this.strategy.handleScroll(metrics, virtualItems, this.currentScale);\n }\n\n private getLayout(): LayoutChangePayload {\n return {\n virtualItems: this.state.virtualItems,\n totalContentSize: this.state.totalContentSize,\n };\n }\n\n private getRectPositionForPage(\n pageIndex: number,\n rect: Rect,\n scale?: number,\n rotation?: Rotation,\n ): Rect | null {\n return this.strategy.getRectPositionForPage(\n pageIndex + 1,\n this.state.virtualItems,\n scale ?? this.currentScale,\n rotation ?? this.currentRotation,\n rect,\n );\n }\n\n async initialize(): Promise<void> {\n // No DOM initialization needed; state drives rendering\n }\n\n async destroy(): Promise<void> {\n this.layout$.clear();\n this.scroll$.clear();\n this.pageChange$.clear();\n this.state$.clear();\n this.scrollerLayout$.clear();\n this.layoutReady$.clear();\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { ScrollPluginConfig } from './types';\n\nexport const SCROLL_PLUGIN_ID = 'scroll';\n\nexport const manifest: PluginManifest<ScrollPluginConfig> = {\n id: SCROLL_PLUGIN_ID,\n name: 'Scroll Plugin',\n version: '1.0.0',\n provides: ['scroll'],\n requires: ['viewport'],\n optional: [],\n defaultConfig: {\n enabled: true,\n pageGap: 10,\n },\n};\n","import { Reducer, CoreState, SET_SCALE, SetScaleAction } from '@embedpdf/core';\nimport { ScrollState, ScrollStrategy, ScrollPluginConfig, ScrollMetrics } from './types';\nimport {\n ScrollAction,\n UPDATE_SCROLL_STATE,\n SET_DESIRED_SCROLL_POSITION,\n UPDATE_TOTAL_PAGES,\n} from './actions';\n\nexport const defaultScrollMetrics: ScrollMetrics = {\n currentPage: 1,\n visiblePages: [],\n pageVisibilityMetrics: [],\n renderedPageIndexes: [],\n scrollOffset: { x: 0, y: 0 },\n startSpacing: 0,\n endSpacing: 0,\n};\n\nexport const initialState: (coreState: CoreState, config: ScrollPluginConfig) => ScrollState = (\n coreState,\n config,\n) => ({\n virtualItems: [],\n totalPages: coreState.pages.length,\n totalContentSize: { width: 0, height: 0 },\n desiredScrollPosition: { x: 0, y: 0 },\n strategy: config.strategy ?? ScrollStrategy.Vertical,\n pageGap: config.pageGap ?? 10,\n scale: coreState.scale,\n ...defaultScrollMetrics,\n});\n\nexport const scrollReducer: Reducer<ScrollState, ScrollAction | SetScaleAction> = (\n state,\n action,\n) => {\n switch (action.type) {\n case UPDATE_TOTAL_PAGES:\n return { ...state, totalPages: action.payload };\n case SET_SCALE:\n return { ...state, scale: action.payload };\n case UPDATE_SCROLL_STATE:\n return { ...state, ...action.payload };\n case SET_DESIRED_SCROLL_POSITION:\n return { ...state, desiredScrollPosition: action.payload };\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { ScrollPlugin } from './scroll-plugin';\nimport { manifest, SCROLL_PLUGIN_ID } from './manifest';\nimport { ScrollPluginConfig, ScrollState } from './types';\nimport { scrollReducer, initialState } from './reducer';\nimport { ScrollAction } from './actions';\n\nexport const ScrollPluginPackage: PluginPackage<\n ScrollPlugin,\n ScrollPluginConfig,\n ScrollState,\n ScrollAction\n> = {\n manifest,\n create: (registry, config) => new ScrollPlugin(SCROLL_PLUGIN_ID, registry, config),\n reducer: scrollReducer,\n initialState: (coreState, config) => initialState(coreState, config),\n};\n\nexport * from './scroll-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './types/virtual-item';\n"],"names":["ScrollStrategy","item"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { BasePlugin, CoreState, PluginRegistry, StoreState } from '@embedpdf/core';
2
- import { ScrollCapability, ScrollPluginConfig, ScrollState } from './types';
1
+ import { BasePlugin, CoreState, PluginRegistry, StoreState, Unsubscribe } from '@embedpdf/core';
2
+ import { ScrollCapability, ScrollPluginConfig, ScrollState, ScrollerLayout } from './types';
3
3
  import { ScrollAction } from './actions';
4
4
  export declare class ScrollPlugin extends BasePlugin<ScrollPluginConfig, ScrollCapability, ScrollState, ScrollAction> {
5
5
  readonly id: string;
@@ -26,7 +26,8 @@ export declare class ScrollPlugin extends BasePlugin<ScrollPluginConfig, ScrollC
26
26
  private commitMetrics;
27
27
  private refreshAll;
28
28
  private getVirtualItemsFromState;
29
- private getScrollerLayoutFromState;
29
+ onScrollerData(callback: (layout: ScrollerLayout) => void): Unsubscribe;
30
+ getScrollerLayout(): ScrollerLayout;
30
31
  private pushScrollLayout;
31
32
  onStoreUpdated(_prevState: ScrollState, _newState: ScrollState): void;
32
33
  onCoreStoreUpdated(prevState: StoreState<CoreState>, newState: StoreState<CoreState>): void;
@@ -37,6 +38,9 @@ export declare class ScrollPlugin extends BasePlugin<ScrollPluginConfig, ScrollC
37
38
  private setScrollStrategy;
38
39
  setLayoutReady(): void;
39
40
  protected buildCapability(): ScrollCapability;
41
+ private scrollToPage;
42
+ private scrollToNextPage;
43
+ private scrollToPreviousPage;
40
44
  private getMetrics;
41
45
  private getLayout;
42
46
  private getRectPositionForPage;
@@ -1,4 +1,4 @@
1
- import { PdfPageObjectWithRotatedSize, Position, Rect, Rotation } from '@embedpdf/models';
1
+ import { PdfPageObjectWithRotatedSize, Position, Rect, Rotation, Size } from '@embedpdf/models';
2
2
  import { ViewportMetrics } from '@embedpdf/plugin-viewport';
3
3
  import { VirtualItem } from '../types/virtual-item';
4
4
  import { ScrollMetrics } from '../types';
@@ -13,10 +13,7 @@ export declare abstract class BaseScrollStrategy {
13
13
  protected bufferSize: number;
14
14
  constructor(config: ScrollStrategyConfig);
15
15
  abstract createVirtualItems(pdfPageObject: PdfPageObjectWithRotatedSize[][]): VirtualItem[];
16
- abstract getTotalContentSize(virtualItems: VirtualItem[]): {
17
- width: number;
18
- height: number;
19
- };
16
+ abstract getTotalContentSize(virtualItems: VirtualItem[]): Size;
20
17
  protected abstract getScrollOffset(viewport: ViewportMetrics): number;
21
18
  protected abstract getClientSize(viewport: ViewportMetrics): number;
22
19
  protected getVisibleRange(viewport: ViewportMetrics, virtualItems: VirtualItem[], scale: number): {
@@ -2,6 +2,7 @@ import { BasePluginConfig, EventHook } from '@embedpdf/core';
2
2
  import { PdfPageObject, Rect, Rotation } from '@embedpdf/models';
3
3
  import { ViewportMetrics } from '@embedpdf/plugin-viewport';
4
4
  import { VirtualItem } from './types/virtual-item';
5
+ export type ScrollBehavior = 'instant' | 'smooth' | 'auto';
5
6
  export interface ScrollState extends ScrollMetrics {
6
7
  virtualItems: VirtualItem[];
7
8
  totalPages: number;
@@ -92,7 +93,6 @@ export interface PageChangePayload {
92
93
  totalPages: number;
93
94
  }
94
95
  export interface ScrollCapability {
95
- onScrollerData: EventHook<ScrollerLayout>;
96
96
  onStateChange: EventHook<ScrollState>;
97
97
  onScroll: EventHook<ScrollMetrics>;
98
98
  getCurrentPage(): number;
@@ -105,7 +105,6 @@ export interface ScrollCapability {
105
105
  scrollToPreviousPage(behavior?: ScrollBehavior): void;
106
106
  getMetrics(viewport?: ViewportMetrics): ScrollMetrics;
107
107
  getLayout(): LayoutChangePayload;
108
- getScrollerLayout(): ScrollerLayout;
109
108
  getRectPositionForPage(page: number, rect: Rect, scale?: number, rotation?: Rotation): Rect | null;
110
109
  setScrollStrategy(strategy: ScrollStrategy): void;
111
110
  getPageGap(): number;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-scroll");require("preact");const r=require("preact/hooks"),i=require("preact/jsx-runtime"),o=()=>e.usePlugin(t.ScrollPlugin.id),l=()=>e.useCapability(t.ScrollPlugin.id);exports.Scroller=function({renderPage:a,overlayElements:n,...s}){const{provides:c}=l(),{plugin:g}=o(),{registry:u}=e.useRegistry(),[p,d]=r.useState((()=>(null==c?void 0:c.getScrollerLayout())??null));if(r.useEffect((()=>{if(c)return c.onScrollerData(d)}),[c]),r.useEffect((()=>{g&&g.setLayoutReady()}),[g]),!p)return null;if(!u)return null;const h=u.getStore().getState();return i.jsxs("div",{...s,style:{width:`${p.totalWidth}px`,height:`${p.totalHeight}px`,position:"relative",boxSizing:"border-box",margin:"0 auto",...p.strategy===t.ScrollStrategy.Horizontal&&{display:"flex",flexDirection:"row"}},children:[i.jsx("div",{style:{...p.strategy===t.ScrollStrategy.Horizontal?{width:p.startSpacing,height:"100%",flexShrink:0}:{height:p.startSpacing,width:"100%"}}}),i.jsx("div",{style:{gap:p.pageGap,display:"flex",alignItems:"center",position:"relative",boxSizing:"border-box",...p.strategy===t.ScrollStrategy.Horizontal?{flexDirection:"row",minHeight:"100%"}:{flexDirection:"column",minWidth:"fit-content"}},children:p.items.map((e=>i.jsx("div",{style:{display:"flex",justifyContent:"center",gap:p.pageGap},children:e.pageLayouts.map((e=>i.jsx("div",{style:{width:`${e.rotatedWidth}px`,height:`${e.rotatedHeight}px`},children:a({...e,rotation:h.core.rotation,scale:h.core.scale,document:h.core.document})},e.pageNumber)))},e.pageNumbers[0])))}),i.jsx("div",{style:{...p.strategy===t.ScrollStrategy.Horizontal?{width:p.endSpacing,height:"100%",flexShrink:0}:{height:p.endSpacing,width:"100%"}}}),n]})},exports.useScroll=()=>{const{provides:e}=l(),[t,i]=r.useState(1),[o,a]=r.useState(1);return r.useEffect((()=>{if(e)return e.onPageChange((({pageNumber:e,totalPages:t})=>{i(e),a(t)}))}),[e]),{...e,currentPage:t,totalPages:o}},exports.useScrollCapability=l,exports.useScrollPlugin=o,Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("preact");const e=require("preact/hooks"),t=require("@embedpdf/core/preact"),r=require("@embedpdf/plugin-scroll"),o=require("preact/jsx-runtime"),l=()=>t.usePlugin(r.ScrollPlugin.id),s=()=>t.useCapability(r.ScrollPlugin.id);exports.Scroller=function({renderPage:s,overlayElements:n,...i}){const{plugin:a}=l(),{registry:c}=t.useRegistry(),[g,u]=e.useState((()=>(null==a?void 0:a.getScrollerLayout())??null));if(e.useEffect((()=>{if(a)return a.onScrollerData(u)}),[a]),e.useEffect((()=>{a&&a.setLayoutReady()}),[a]),!g)return null;if(!c)return null;const d=c.getStore().getState();return o.jsxs("div",{...i,style:{width:`${g.totalWidth}px`,height:`${g.totalHeight}px`,position:"relative",boxSizing:"border-box",margin:"0 auto",...g.strategy===r.ScrollStrategy.Horizontal&&{display:"flex",flexDirection:"row"}},children:[o.jsx("div",{style:{...g.strategy===r.ScrollStrategy.Horizontal?{width:g.startSpacing,height:"100%",flexShrink:0}:{height:g.startSpacing,width:"100%"}}}),o.jsx("div",{style:{gap:g.pageGap,display:"flex",alignItems:"center",position:"relative",boxSizing:"border-box",...g.strategy===r.ScrollStrategy.Horizontal?{flexDirection:"row",minHeight:"100%"}:{flexDirection:"column",minWidth:"fit-content"}},children:g.items.map((e=>o.jsx("div",{style:{display:"flex",justifyContent:"center",gap:g.pageGap},children:e.pageLayouts.map((e=>o.jsx("div",{style:{width:`${e.rotatedWidth}px`,height:`${e.rotatedHeight}px`},children:s({...e,rotation:d.core.rotation,scale:d.core.scale,document:d.core.document})},e.pageNumber)))},e.pageNumbers[0])))}),o.jsx("div",{style:{...g.strategy===r.ScrollStrategy.Horizontal?{width:g.endSpacing,height:"100%",flexShrink:0}:{height:g.endSpacing,width:"100%"}}}),n]})},exports.useScroll=()=>{const{provides:t}=s(),[r,o]=e.useState(1),[l,n]=e.useState(1);return e.useEffect((()=>{if(t)return t.onPageChange((({pageNumber:e,totalPages:t})=>{o(e),n(t)}))}),[t]),{provides:t,state:{currentPage:r,totalPages:l},get currentPage(){return console.warn("Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead."),r},get totalPages(){return console.warn("Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead."),l},get scrollToPage(){return(null==t?void 0:t.scrollToPage)&&console.warn("Accessing 'scrollToPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPage instead."),null==t?void 0:t.scrollToPage},get scrollToNextPage(){return(null==t?void 0:t.scrollToNextPage)&&console.warn("Accessing 'scrollToNextPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToNextPage instead."),null==t?void 0:t.scrollToNextPage},get scrollToPreviousPage(){return(null==t?void 0:t.scrollToPreviousPage)&&console.warn("Accessing 'scrollToPreviousPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPreviousPage instead."),null==t?void 0:t.scrollToPreviousPage},get getMetrics(){return(null==t?void 0:t.getMetrics)&&console.warn("Accessing 'getMetrics' directly on useScroll() is deprecated. Use useScroll().provides.getMetrics instead."),null==t?void 0:t.getMetrics},get onPageChange(){return(null==t?void 0:t.onPageChange)&&console.warn("Accessing 'onPageChange' directly on useScroll() is deprecated. Use useScroll().provides.onPageChange instead."),null==t?void 0:t.onPageChange},get onScroll(){return(null==t?void 0:t.onScroll)&&console.warn("Accessing 'onScroll' directly on useScroll() is deprecated. Use useScroll().provides.onScroll instead."),null==t?void 0:t.onScroll},get onLayoutChange(){return(null==t?void 0:t.onLayoutChange)&&console.warn("Accessing 'onLayoutChange' directly on useScroll() is deprecated. Use useScroll().provides.onLayoutChange instead."),null==t?void 0:t.onLayoutChange},get getCurrentPage(){return(null==t?void 0:t.getCurrentPage)&&console.warn("Accessing 'getCurrentPage' directly on useScroll() is deprecated. Use useScroll().provides.getCurrentPage instead."),null==t?void 0:t.getCurrentPage},get getTotalPages(){return(null==t?void 0:t.getTotalPages)&&console.warn("Accessing 'getTotalPages' directly on useScroll() is deprecated. Use useScroll().provides.getTotalPages instead."),null==t?void 0:t.getTotalPages}}},exports.useScrollCapability=s,exports.useScrollPlugin=l,Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-scroll.ts","../../src/shared/components/scroller.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ScrollPlugin } from '@embedpdf/plugin-scroll';\nimport { useEffect, useState } from '@framework';\n\nexport const useScrollPlugin = () => usePlugin<ScrollPlugin>(ScrollPlugin.id);\nexport const useScrollCapability = () => useCapability<ScrollPlugin>(ScrollPlugin.id);\n\nexport const useScroll = () => {\n const { provides: scroll } = useScrollCapability();\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(1);\n\n useEffect(() => {\n if (!scroll) return;\n return scroll.onPageChange(({ pageNumber, totalPages }) => {\n setCurrentPage(pageNumber);\n setTotalPages(totalPages);\n });\n }, [scroll]);\n\n return {\n ...scroll,\n currentPage,\n totalPages,\n };\n};\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { ScrollStrategy, ScrollerLayout, PageLayout } from '@embedpdf/plugin-scroll';\nimport { useRegistry } from '@embedpdf/core/@framework';\nimport { PdfDocumentObject, Rotation } from '@embedpdf/models';\n\nimport { useScrollCapability, useScrollPlugin } from '../hooks';\n\nexport interface RenderPageProps extends PageLayout {\n rotation: Rotation;\n scale: number;\n document: PdfDocumentObject | null;\n}\n\ntype ScrollerProps = HTMLAttributes<HTMLDivElement> & {\n renderPage: (props: RenderPageProps) => ReactNode;\n overlayElements?: ReactNode[];\n};\n\nexport function Scroller({ renderPage, overlayElements, ...props }: ScrollerProps) {\n const { provides: scrollProvides } = useScrollCapability();\n const { plugin: scrollPlugin } = useScrollPlugin();\n const { registry } = useRegistry();\n const [scrollerLayout, setScrollerLayout] = useState<ScrollerLayout | null>(\n () => scrollProvides?.getScrollerLayout() ?? null,\n );\n\n useEffect(() => {\n if (!scrollProvides) return;\n\n return scrollProvides.onScrollerData(setScrollerLayout);\n }, [scrollProvides]);\n\n useEffect(() => {\n if (!scrollPlugin) return;\n\n scrollPlugin.setLayoutReady();\n }, [scrollPlugin]);\n\n if (!scrollerLayout) return null;\n if (!registry) return null;\n\n const coreState = registry.getStore().getState();\n\n return (\n <div\n {...props}\n style={{\n width: `${scrollerLayout.totalWidth}px`,\n height: `${scrollerLayout.totalHeight}px`,\n position: 'relative',\n boxSizing: 'border-box',\n margin: '0 auto',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal && {\n display: 'flex',\n flexDirection: 'row',\n }),\n }}\n >\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.startSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.startSpacing,\n width: '100%',\n }),\n }}\n />\n <div\n style={{\n gap: scrollerLayout.pageGap,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n flexDirection: 'row',\n minHeight: '100%',\n }\n : {\n flexDirection: 'column',\n minWidth: 'fit-content',\n }),\n }}\n >\n {scrollerLayout.items.map((item) => (\n <div\n key={item.pageNumbers[0]}\n style={{\n display: 'flex',\n justifyContent: 'center',\n gap: scrollerLayout.pageGap,\n }}\n >\n {item.pageLayouts.map((layout) => (\n <div\n key={layout.pageNumber}\n style={{\n width: `${layout.rotatedWidth}px`,\n height: `${layout.rotatedHeight}px`,\n }}\n >\n {renderPage({\n ...layout,\n rotation: coreState.core.rotation,\n scale: coreState.core.scale,\n document: coreState.core.document,\n })}\n </div>\n ))}\n </div>\n ))}\n </div>\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.endSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.endSpacing,\n width: '100%',\n }),\n }}\n />\n {overlayElements}\n </div>\n );\n}\n"],"names":["useScrollPlugin","usePlugin","ScrollPlugin","id","useScrollCapability","useCapability","renderPage","overlayElements","props","provides","scrollProvides","plugin","scrollPlugin","registry","useRegistry","scrollerLayout","setScrollerLayout","useState","getScrollerLayout","useEffect","onScrollerData","setLayoutReady","coreState","getStore","getState","jsxRuntime","jsxs","style","width","totalWidth","height","totalHeight","position","boxSizing","margin","strategy","ScrollStrategy","Horizontal","display","flexDirection","children","jsx","startSpacing","flexShrink","gap","pageGap","alignItems","minHeight","minWidth","items","map","item","justifyContent","pageLayouts","layout","rotatedWidth","rotatedHeight","rotation","core","scale","document","pageNumber","pageNumbers","endSpacing","scroll","currentPage","setCurrentPage","totalPages","setTotalPages","onPageChange"],"mappings":"gPAIaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,qBCa3E,UAAkBG,WAAEA,EAAAC,gBAAYA,KAAoBC,IACzD,MAAQC,SAAUC,GAAmBN,KAC7BO,OAAQC,GAAiBZ,KAC3Ba,SAAEA,GAAaC,iBACdC,EAAgBC,GAAqBC,EAAAA,UAC1C,WAAMP,WAAgBQ,sBAAuB,OAe3C,GAZJC,EAAAA,WAAU,KACR,GAAKT,EAEE,OAAAA,EAAeU,eAAeJ,EAAiB,GACrD,CAACN,IAEJS,EAAAA,WAAU,KACHP,GAELA,EAAaS,gBAAe,GAC3B,CAACT,KAECG,EAAuB,OAAA,KACxB,IAACF,EAAiB,OAAA,KAEtB,MAAMS,EAAYT,EAASU,WAAWC,WAGpC,OAAAC,EAAAC,KAAC,MAAA,IACKlB,EACJmB,MAAO,CACLC,MAAO,GAAGb,EAAec,eACzBC,OAAQ,GAAGf,EAAegB,gBAC1BC,SAAU,WACVC,UAAW,aACXC,OAAQ,YACJnB,EAAeoB,WAAaC,EAAAA,eAAeC,YAAc,CAC3DC,QAAS,OACTC,cAAe,QAInBC,SAAA,CAAAf,EAAAgB,IAAC,MAAA,CACCd,MAAO,IACDZ,EAAeoB,WAAaC,EAAAA,eAAeC,WAC3C,CACET,MAAOb,EAAe2B,aACtBZ,OAAQ,OACRa,WAAY,GAEd,CACEb,OAAQf,EAAe2B,aACvBd,MAAO,WAIjBH,EAAAgB,IAAC,MAAA,CACCd,MAAO,CACLiB,IAAK7B,EAAe8B,QACpBP,QAAS,OACTQ,WAAY,SACZd,SAAU,WACVC,UAAW,gBACPlB,EAAeoB,WAAaC,EAAAA,eAAeC,WAC3C,CACEE,cAAe,MACfQ,UAAW,QAEb,CACER,cAAe,SACfS,SAAU,gBAIjBR,SAAezB,EAAAkC,MAAMC,KAAKC,GACzB1B,EAAAgB,IAAC,MAAA,CAECd,MAAO,CACLW,QAAS,OACTc,eAAgB,SAChBR,IAAK7B,EAAe8B,SAGrBL,SAAKW,EAAAE,YAAYH,KAAKI,GACrB7B,EAAAgB,IAAC,MAAA,CAECd,MAAO,CACLC,MAAO,GAAG0B,EAAOC,iBACjBzB,OAAQ,GAAGwB,EAAOE,mBAGnBhB,SAAWlC,EAAA,IACPgD,EACHG,SAAUnC,EAAUoC,KAAKD,SACzBE,MAAOrC,EAAUoC,KAAKC,MACtBC,SAAUtC,EAAUoC,KAAKE,YAVtBN,EAAOO,eATXV,EAAKW,YAAY,QA0B5BrC,EAAAgB,IAAC,MAAA,CACCd,MAAO,IACDZ,EAAeoB,WAAaC,EAAAA,eAAeC,WAC3C,CACET,MAAOb,EAAegD,WACtBjC,OAAQ,OACRa,WAAY,GAEd,CACEb,OAAQf,EAAegD,WACvBnC,MAAO,WAIhBrB,IAGP,oBDhIyB,KACvB,MAAQE,SAAUuD,GAAW5D,KACtB6D,EAAaC,GAAkBjD,EAAAA,SAAS,IACxCkD,EAAYC,GAAiBnD,EAAAA,SAAS,GAUtC,OARPE,EAAAA,WAAU,KACR,GAAK6C,EACL,OAAOA,EAAOK,cAAa,EAAGR,aAAYM,WAAAA,MACxCD,EAAeL,GACfO,EAAcD,EAAU,GACzB,GACA,CAACH,IAEG,IACFA,EACHC,cACAE,aACF"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-scroll.ts","../../src/shared/components/scroller.tsx"],"sourcesContent":["import { useState, useEffect } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ScrollCapability, ScrollPlugin } from '@embedpdf/plugin-scroll';\n\nexport const useScrollPlugin = () => usePlugin<ScrollPlugin>(ScrollPlugin.id);\nexport const useScrollCapability = () => useCapability<ScrollPlugin>(ScrollPlugin.id);\n\n// Define the return type explicitly to maintain type safety\ninterface UseScrollReturn {\n provides: ScrollCapability | null;\n state: {\n currentPage: number;\n totalPages: number;\n };\n // Deprecated properties (for backward compatibility)\n readonly currentPage: number;\n readonly totalPages: number;\n readonly scrollToPage: ScrollCapability['scrollToPage'] | undefined;\n readonly scrollToNextPage: ScrollCapability['scrollToNextPage'] | undefined;\n readonly scrollToPreviousPage: ScrollCapability['scrollToPreviousPage'] | undefined;\n readonly getMetrics: ScrollCapability['getMetrics'] | undefined;\n readonly onPageChange: ScrollCapability['onPageChange'] | undefined;\n readonly onScroll: ScrollCapability['onScroll'] | undefined;\n readonly onLayoutChange: ScrollCapability['onLayoutChange'] | undefined;\n readonly getCurrentPage: ScrollCapability['getCurrentPage'] | undefined;\n readonly getTotalPages: ScrollCapability['getTotalPages'] | undefined;\n}\n\nexport const useScroll = (): UseScrollReturn => {\n const { provides } = useScrollCapability();\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(1);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onPageChange(({ pageNumber, totalPages }) => {\n setCurrentPage(pageNumber);\n setTotalPages(totalPages);\n });\n }, [provides]);\n\n return {\n // New format (preferred)\n provides,\n state: {\n currentPage,\n totalPages,\n },\n\n // Deprecated properties with getters that show warnings\n get currentPage() {\n console.warn(\n `Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead.`,\n );\n return currentPage;\n },\n\n get totalPages() {\n console.warn(\n `Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead.`,\n );\n return totalPages;\n },\n\n get scrollToPage() {\n if (provides?.scrollToPage) {\n console.warn(\n `Accessing 'scrollToPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPage instead.`,\n );\n }\n return provides?.scrollToPage;\n },\n\n get scrollToNextPage() {\n if (provides?.scrollToNextPage) {\n console.warn(\n `Accessing 'scrollToNextPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToNextPage instead.`,\n );\n }\n return provides?.scrollToNextPage;\n },\n\n get scrollToPreviousPage() {\n if (provides?.scrollToPreviousPage) {\n console.warn(\n `Accessing 'scrollToPreviousPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPreviousPage instead.`,\n );\n }\n return provides?.scrollToPreviousPage;\n },\n\n get getMetrics() {\n if (provides?.getMetrics) {\n console.warn(\n `Accessing 'getMetrics' directly on useScroll() is deprecated. Use useScroll().provides.getMetrics instead.`,\n );\n }\n return provides?.getMetrics;\n },\n\n get onPageChange() {\n if (provides?.onPageChange) {\n console.warn(\n `Accessing 'onPageChange' directly on useScroll() is deprecated. Use useScroll().provides.onPageChange instead.`,\n );\n }\n return provides?.onPageChange;\n },\n\n get onScroll() {\n if (provides?.onScroll) {\n console.warn(\n `Accessing 'onScroll' directly on useScroll() is deprecated. Use useScroll().provides.onScroll instead.`,\n );\n }\n return provides?.onScroll;\n },\n\n get onLayoutChange() {\n if (provides?.onLayoutChange) {\n console.warn(\n `Accessing 'onLayoutChange' directly on useScroll() is deprecated. Use useScroll().provides.onLayoutChange instead.`,\n );\n }\n return provides?.onLayoutChange;\n },\n\n get getCurrentPage() {\n if (provides?.getCurrentPage) {\n console.warn(\n `Accessing 'getCurrentPage' directly on useScroll() is deprecated. Use useScroll().provides.getCurrentPage instead.`,\n );\n }\n return provides?.getCurrentPage;\n },\n\n get getTotalPages() {\n if (provides?.getTotalPages) {\n console.warn(\n `Accessing 'getTotalPages' directly on useScroll() is deprecated. Use useScroll().provides.getTotalPages instead.`,\n );\n }\n return provides?.getTotalPages;\n },\n };\n};\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { ScrollStrategy, ScrollerLayout, PageLayout } from '@embedpdf/plugin-scroll';\nimport { useRegistry } from '@embedpdf/core/@framework';\nimport { PdfDocumentObject, Rotation } from '@embedpdf/models';\n\nimport { useScrollPlugin } from '../hooks';\n\nexport interface RenderPageProps extends PageLayout {\n rotation: Rotation;\n scale: number;\n document: PdfDocumentObject | null;\n}\n\ntype ScrollerProps = HTMLAttributes<HTMLDivElement> & {\n renderPage: (props: RenderPageProps) => ReactNode;\n overlayElements?: ReactNode[];\n};\n\nexport function Scroller({ renderPage, overlayElements, ...props }: ScrollerProps) {\n const { plugin: scrollPlugin } = useScrollPlugin();\n const { registry } = useRegistry();\n const [scrollerLayout, setScrollerLayout] = useState<ScrollerLayout | null>(\n () => scrollPlugin?.getScrollerLayout() ?? null,\n );\n\n useEffect(() => {\n if (!scrollPlugin) return;\n\n return scrollPlugin.onScrollerData(setScrollerLayout);\n }, [scrollPlugin]);\n\n useEffect(() => {\n if (!scrollPlugin) return;\n\n scrollPlugin.setLayoutReady();\n }, [scrollPlugin]);\n\n if (!scrollerLayout) return null;\n if (!registry) return null;\n\n const coreState = registry.getStore().getState();\n\n return (\n <div\n {...props}\n style={{\n width: `${scrollerLayout.totalWidth}px`,\n height: `${scrollerLayout.totalHeight}px`,\n position: 'relative',\n boxSizing: 'border-box',\n margin: '0 auto',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal && {\n display: 'flex',\n flexDirection: 'row',\n }),\n }}\n >\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.startSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.startSpacing,\n width: '100%',\n }),\n }}\n />\n <div\n style={{\n gap: scrollerLayout.pageGap,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n flexDirection: 'row',\n minHeight: '100%',\n }\n : {\n flexDirection: 'column',\n minWidth: 'fit-content',\n }),\n }}\n >\n {scrollerLayout.items.map((item) => (\n <div\n key={item.pageNumbers[0]}\n style={{\n display: 'flex',\n justifyContent: 'center',\n gap: scrollerLayout.pageGap,\n }}\n >\n {item.pageLayouts.map((layout) => (\n <div\n key={layout.pageNumber}\n style={{\n width: `${layout.rotatedWidth}px`,\n height: `${layout.rotatedHeight}px`,\n }}\n >\n {renderPage({\n ...layout,\n rotation: coreState.core.rotation,\n scale: coreState.core.scale,\n document: coreState.core.document,\n })}\n </div>\n ))}\n </div>\n ))}\n </div>\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.endSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.endSpacing,\n width: '100%',\n }),\n }}\n />\n {overlayElements}\n </div>\n );\n}\n"],"names":["useScrollPlugin","usePlugin","ScrollPlugin","id","useScrollCapability","useCapability","renderPage","overlayElements","props","plugin","scrollPlugin","registry","useRegistry","scrollerLayout","setScrollerLayout","useState","getScrollerLayout","useEffect","onScrollerData","setLayoutReady","coreState","getStore","getState","jsxRuntime","jsxs","style","width","totalWidth","height","totalHeight","position","boxSizing","margin","strategy","ScrollStrategy","Horizontal","display","flexDirection","children","jsx","startSpacing","flexShrink","gap","pageGap","alignItems","minHeight","minWidth","items","map","item","justifyContent","pageLayouts","layout","rotatedWidth","rotatedHeight","rotation","core","scale","document","pageNumber","pageNumbers","endSpacing","provides","currentPage","setCurrentPage","totalPages","setTotalPages","onPageChange","state","console","warn","scrollToPage","scrollToNextPage","scrollToPreviousPage","getMetrics","onScroll","onLayoutChange","getCurrentPage","getTotalPages"],"mappings":"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"}
@@ -1,39 +1,126 @@
1
+ import "preact";
2
+ import { useState, useEffect } from "preact/hooks";
1
3
  import { usePlugin, useCapability, useRegistry } from "@embedpdf/core/preact";
2
4
  import { ScrollPlugin, ScrollStrategy } from "@embedpdf/plugin-scroll";
3
5
  export * from "@embedpdf/plugin-scroll";
4
- import "preact";
5
- import { useState, useEffect } from "preact/hooks";
6
6
  import { jsxs, jsx } from "preact/jsx-runtime";
7
7
  const useScrollPlugin = () => usePlugin(ScrollPlugin.id);
8
8
  const useScrollCapability = () => useCapability(ScrollPlugin.id);
9
9
  const useScroll = () => {
10
- const { provides: scroll } = useScrollCapability();
10
+ const { provides } = useScrollCapability();
11
11
  const [currentPage, setCurrentPage] = useState(1);
12
12
  const [totalPages, setTotalPages] = useState(1);
13
13
  useEffect(() => {
14
- if (!scroll) return;
15
- return scroll.onPageChange(({ pageNumber, totalPages: totalPages2 }) => {
14
+ if (!provides) return;
15
+ return provides.onPageChange(({ pageNumber, totalPages: totalPages2 }) => {
16
16
  setCurrentPage(pageNumber);
17
17
  setTotalPages(totalPages2);
18
18
  });
19
- }, [scroll]);
19
+ }, [provides]);
20
20
  return {
21
- ...scroll,
22
- currentPage,
23
- totalPages
21
+ // New format (preferred)
22
+ provides,
23
+ state: {
24
+ currentPage,
25
+ totalPages
26
+ },
27
+ // Deprecated properties with getters that show warnings
28
+ get currentPage() {
29
+ console.warn(
30
+ `Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead.`
31
+ );
32
+ return currentPage;
33
+ },
34
+ get totalPages() {
35
+ console.warn(
36
+ `Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead.`
37
+ );
38
+ return totalPages;
39
+ },
40
+ get scrollToPage() {
41
+ if (provides == null ? void 0 : provides.scrollToPage) {
42
+ console.warn(
43
+ `Accessing 'scrollToPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPage instead.`
44
+ );
45
+ }
46
+ return provides == null ? void 0 : provides.scrollToPage;
47
+ },
48
+ get scrollToNextPage() {
49
+ if (provides == null ? void 0 : provides.scrollToNextPage) {
50
+ console.warn(
51
+ `Accessing 'scrollToNextPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToNextPage instead.`
52
+ );
53
+ }
54
+ return provides == null ? void 0 : provides.scrollToNextPage;
55
+ },
56
+ get scrollToPreviousPage() {
57
+ if (provides == null ? void 0 : provides.scrollToPreviousPage) {
58
+ console.warn(
59
+ `Accessing 'scrollToPreviousPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPreviousPage instead.`
60
+ );
61
+ }
62
+ return provides == null ? void 0 : provides.scrollToPreviousPage;
63
+ },
64
+ get getMetrics() {
65
+ if (provides == null ? void 0 : provides.getMetrics) {
66
+ console.warn(
67
+ `Accessing 'getMetrics' directly on useScroll() is deprecated. Use useScroll().provides.getMetrics instead.`
68
+ );
69
+ }
70
+ return provides == null ? void 0 : provides.getMetrics;
71
+ },
72
+ get onPageChange() {
73
+ if (provides == null ? void 0 : provides.onPageChange) {
74
+ console.warn(
75
+ `Accessing 'onPageChange' directly on useScroll() is deprecated. Use useScroll().provides.onPageChange instead.`
76
+ );
77
+ }
78
+ return provides == null ? void 0 : provides.onPageChange;
79
+ },
80
+ get onScroll() {
81
+ if (provides == null ? void 0 : provides.onScroll) {
82
+ console.warn(
83
+ `Accessing 'onScroll' directly on useScroll() is deprecated. Use useScroll().provides.onScroll instead.`
84
+ );
85
+ }
86
+ return provides == null ? void 0 : provides.onScroll;
87
+ },
88
+ get onLayoutChange() {
89
+ if (provides == null ? void 0 : provides.onLayoutChange) {
90
+ console.warn(
91
+ `Accessing 'onLayoutChange' directly on useScroll() is deprecated. Use useScroll().provides.onLayoutChange instead.`
92
+ );
93
+ }
94
+ return provides == null ? void 0 : provides.onLayoutChange;
95
+ },
96
+ get getCurrentPage() {
97
+ if (provides == null ? void 0 : provides.getCurrentPage) {
98
+ console.warn(
99
+ `Accessing 'getCurrentPage' directly on useScroll() is deprecated. Use useScroll().provides.getCurrentPage instead.`
100
+ );
101
+ }
102
+ return provides == null ? void 0 : provides.getCurrentPage;
103
+ },
104
+ get getTotalPages() {
105
+ if (provides == null ? void 0 : provides.getTotalPages) {
106
+ console.warn(
107
+ `Accessing 'getTotalPages' directly on useScroll() is deprecated. Use useScroll().provides.getTotalPages instead.`
108
+ );
109
+ }
110
+ return provides == null ? void 0 : provides.getTotalPages;
111
+ }
24
112
  };
25
113
  };
26
114
  function Scroller({ renderPage, overlayElements, ...props }) {
27
- const { provides: scrollProvides } = useScrollCapability();
28
115
  const { plugin: scrollPlugin } = useScrollPlugin();
29
116
  const { registry } = useRegistry();
30
117
  const [scrollerLayout, setScrollerLayout] = useState(
31
- () => (scrollProvides == null ? void 0 : scrollProvides.getScrollerLayout()) ?? null
118
+ () => (scrollPlugin == null ? void 0 : scrollPlugin.getScrollerLayout()) ?? null
32
119
  );
33
120
  useEffect(() => {
34
- if (!scrollProvides) return;
35
- return scrollProvides.onScrollerData(setScrollerLayout);
36
- }, [scrollProvides]);
121
+ if (!scrollPlugin) return;
122
+ return scrollPlugin.onScrollerData(setScrollerLayout);
123
+ }, [scrollPlugin]);
37
124
  useEffect(() => {
38
125
  if (!scrollPlugin) return;
39
126
  scrollPlugin.setLayoutReady();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-scroll.ts","../../src/shared/components/scroller.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ScrollPlugin } from '@embedpdf/plugin-scroll';\nimport { useEffect, useState } from '@framework';\n\nexport const useScrollPlugin = () => usePlugin<ScrollPlugin>(ScrollPlugin.id);\nexport const useScrollCapability = () => useCapability<ScrollPlugin>(ScrollPlugin.id);\n\nexport const useScroll = () => {\n const { provides: scroll } = useScrollCapability();\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(1);\n\n useEffect(() => {\n if (!scroll) return;\n return scroll.onPageChange(({ pageNumber, totalPages }) => {\n setCurrentPage(pageNumber);\n setTotalPages(totalPages);\n });\n }, [scroll]);\n\n return {\n ...scroll,\n currentPage,\n totalPages,\n };\n};\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { ScrollStrategy, ScrollerLayout, PageLayout } from '@embedpdf/plugin-scroll';\nimport { useRegistry } from '@embedpdf/core/@framework';\nimport { PdfDocumentObject, Rotation } from '@embedpdf/models';\n\nimport { useScrollCapability, useScrollPlugin } from '../hooks';\n\nexport interface RenderPageProps extends PageLayout {\n rotation: Rotation;\n scale: number;\n document: PdfDocumentObject | null;\n}\n\ntype ScrollerProps = HTMLAttributes<HTMLDivElement> & {\n renderPage: (props: RenderPageProps) => ReactNode;\n overlayElements?: ReactNode[];\n};\n\nexport function Scroller({ renderPage, overlayElements, ...props }: ScrollerProps) {\n const { provides: scrollProvides } = useScrollCapability();\n const { plugin: scrollPlugin } = useScrollPlugin();\n const { registry } = useRegistry();\n const [scrollerLayout, setScrollerLayout] = useState<ScrollerLayout | null>(\n () => scrollProvides?.getScrollerLayout() ?? null,\n );\n\n useEffect(() => {\n if (!scrollProvides) return;\n\n return scrollProvides.onScrollerData(setScrollerLayout);\n }, [scrollProvides]);\n\n useEffect(() => {\n if (!scrollPlugin) return;\n\n scrollPlugin.setLayoutReady();\n }, [scrollPlugin]);\n\n if (!scrollerLayout) return null;\n if (!registry) return null;\n\n const coreState = registry.getStore().getState();\n\n return (\n <div\n {...props}\n style={{\n width: `${scrollerLayout.totalWidth}px`,\n height: `${scrollerLayout.totalHeight}px`,\n position: 'relative',\n boxSizing: 'border-box',\n margin: '0 auto',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal && {\n display: 'flex',\n flexDirection: 'row',\n }),\n }}\n >\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.startSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.startSpacing,\n width: '100%',\n }),\n }}\n />\n <div\n style={{\n gap: scrollerLayout.pageGap,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n flexDirection: 'row',\n minHeight: '100%',\n }\n : {\n flexDirection: 'column',\n minWidth: 'fit-content',\n }),\n }}\n >\n {scrollerLayout.items.map((item) => (\n <div\n key={item.pageNumbers[0]}\n style={{\n display: 'flex',\n justifyContent: 'center',\n gap: scrollerLayout.pageGap,\n }}\n >\n {item.pageLayouts.map((layout) => (\n <div\n key={layout.pageNumber}\n style={{\n width: `${layout.rotatedWidth}px`,\n height: `${layout.rotatedHeight}px`,\n }}\n >\n {renderPage({\n ...layout,\n rotation: coreState.core.rotation,\n scale: coreState.core.scale,\n document: coreState.core.document,\n })}\n </div>\n ))}\n </div>\n ))}\n </div>\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.endSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.endSpacing,\n width: '100%',\n }),\n }}\n />\n {overlayElements}\n </div>\n );\n}\n"],"names":["totalPages"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-scroll.ts","../../src/shared/components/scroller.tsx"],"sourcesContent":["import { useState, useEffect } from '@framework';\nimport { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { ScrollCapability, ScrollPlugin } from '@embedpdf/plugin-scroll';\n\nexport const useScrollPlugin = () => usePlugin<ScrollPlugin>(ScrollPlugin.id);\nexport const useScrollCapability = () => useCapability<ScrollPlugin>(ScrollPlugin.id);\n\n// Define the return type explicitly to maintain type safety\ninterface UseScrollReturn {\n provides: ScrollCapability | null;\n state: {\n currentPage: number;\n totalPages: number;\n };\n // Deprecated properties (for backward compatibility)\n readonly currentPage: number;\n readonly totalPages: number;\n readonly scrollToPage: ScrollCapability['scrollToPage'] | undefined;\n readonly scrollToNextPage: ScrollCapability['scrollToNextPage'] | undefined;\n readonly scrollToPreviousPage: ScrollCapability['scrollToPreviousPage'] | undefined;\n readonly getMetrics: ScrollCapability['getMetrics'] | undefined;\n readonly onPageChange: ScrollCapability['onPageChange'] | undefined;\n readonly onScroll: ScrollCapability['onScroll'] | undefined;\n readonly onLayoutChange: ScrollCapability['onLayoutChange'] | undefined;\n readonly getCurrentPage: ScrollCapability['getCurrentPage'] | undefined;\n readonly getTotalPages: ScrollCapability['getTotalPages'] | undefined;\n}\n\nexport const useScroll = (): UseScrollReturn => {\n const { provides } = useScrollCapability();\n const [currentPage, setCurrentPage] = useState(1);\n const [totalPages, setTotalPages] = useState(1);\n\n useEffect(() => {\n if (!provides) return;\n return provides.onPageChange(({ pageNumber, totalPages }) => {\n setCurrentPage(pageNumber);\n setTotalPages(totalPages);\n });\n }, [provides]);\n\n return {\n // New format (preferred)\n provides,\n state: {\n currentPage,\n totalPages,\n },\n\n // Deprecated properties with getters that show warnings\n get currentPage() {\n console.warn(\n `Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead.`,\n );\n return currentPage;\n },\n\n get totalPages() {\n console.warn(\n `Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead.`,\n );\n return totalPages;\n },\n\n get scrollToPage() {\n if (provides?.scrollToPage) {\n console.warn(\n `Accessing 'scrollToPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPage instead.`,\n );\n }\n return provides?.scrollToPage;\n },\n\n get scrollToNextPage() {\n if (provides?.scrollToNextPage) {\n console.warn(\n `Accessing 'scrollToNextPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToNextPage instead.`,\n );\n }\n return provides?.scrollToNextPage;\n },\n\n get scrollToPreviousPage() {\n if (provides?.scrollToPreviousPage) {\n console.warn(\n `Accessing 'scrollToPreviousPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPreviousPage instead.`,\n );\n }\n return provides?.scrollToPreviousPage;\n },\n\n get getMetrics() {\n if (provides?.getMetrics) {\n console.warn(\n `Accessing 'getMetrics' directly on useScroll() is deprecated. Use useScroll().provides.getMetrics instead.`,\n );\n }\n return provides?.getMetrics;\n },\n\n get onPageChange() {\n if (provides?.onPageChange) {\n console.warn(\n `Accessing 'onPageChange' directly on useScroll() is deprecated. Use useScroll().provides.onPageChange instead.`,\n );\n }\n return provides?.onPageChange;\n },\n\n get onScroll() {\n if (provides?.onScroll) {\n console.warn(\n `Accessing 'onScroll' directly on useScroll() is deprecated. Use useScroll().provides.onScroll instead.`,\n );\n }\n return provides?.onScroll;\n },\n\n get onLayoutChange() {\n if (provides?.onLayoutChange) {\n console.warn(\n `Accessing 'onLayoutChange' directly on useScroll() is deprecated. Use useScroll().provides.onLayoutChange instead.`,\n );\n }\n return provides?.onLayoutChange;\n },\n\n get getCurrentPage() {\n if (provides?.getCurrentPage) {\n console.warn(\n `Accessing 'getCurrentPage' directly on useScroll() is deprecated. Use useScroll().provides.getCurrentPage instead.`,\n );\n }\n return provides?.getCurrentPage;\n },\n\n get getTotalPages() {\n if (provides?.getTotalPages) {\n console.warn(\n `Accessing 'getTotalPages' directly on useScroll() is deprecated. Use useScroll().provides.getTotalPages instead.`,\n );\n }\n return provides?.getTotalPages;\n },\n };\n};\n","import { ReactNode, useEffect, useState, HTMLAttributes } from '@framework';\nimport { ScrollStrategy, ScrollerLayout, PageLayout } from '@embedpdf/plugin-scroll';\nimport { useRegistry } from '@embedpdf/core/@framework';\nimport { PdfDocumentObject, Rotation } from '@embedpdf/models';\n\nimport { useScrollPlugin } from '../hooks';\n\nexport interface RenderPageProps extends PageLayout {\n rotation: Rotation;\n scale: number;\n document: PdfDocumentObject | null;\n}\n\ntype ScrollerProps = HTMLAttributes<HTMLDivElement> & {\n renderPage: (props: RenderPageProps) => ReactNode;\n overlayElements?: ReactNode[];\n};\n\nexport function Scroller({ renderPage, overlayElements, ...props }: ScrollerProps) {\n const { plugin: scrollPlugin } = useScrollPlugin();\n const { registry } = useRegistry();\n const [scrollerLayout, setScrollerLayout] = useState<ScrollerLayout | null>(\n () => scrollPlugin?.getScrollerLayout() ?? null,\n );\n\n useEffect(() => {\n if (!scrollPlugin) return;\n\n return scrollPlugin.onScrollerData(setScrollerLayout);\n }, [scrollPlugin]);\n\n useEffect(() => {\n if (!scrollPlugin) return;\n\n scrollPlugin.setLayoutReady();\n }, [scrollPlugin]);\n\n if (!scrollerLayout) return null;\n if (!registry) return null;\n\n const coreState = registry.getStore().getState();\n\n return (\n <div\n {...props}\n style={{\n width: `${scrollerLayout.totalWidth}px`,\n height: `${scrollerLayout.totalHeight}px`,\n position: 'relative',\n boxSizing: 'border-box',\n margin: '0 auto',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal && {\n display: 'flex',\n flexDirection: 'row',\n }),\n }}\n >\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.startSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.startSpacing,\n width: '100%',\n }),\n }}\n />\n <div\n style={{\n gap: scrollerLayout.pageGap,\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n boxSizing: 'border-box',\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n flexDirection: 'row',\n minHeight: '100%',\n }\n : {\n flexDirection: 'column',\n minWidth: 'fit-content',\n }),\n }}\n >\n {scrollerLayout.items.map((item) => (\n <div\n key={item.pageNumbers[0]}\n style={{\n display: 'flex',\n justifyContent: 'center',\n gap: scrollerLayout.pageGap,\n }}\n >\n {item.pageLayouts.map((layout) => (\n <div\n key={layout.pageNumber}\n style={{\n width: `${layout.rotatedWidth}px`,\n height: `${layout.rotatedHeight}px`,\n }}\n >\n {renderPage({\n ...layout,\n rotation: coreState.core.rotation,\n scale: coreState.core.scale,\n document: coreState.core.document,\n })}\n </div>\n ))}\n </div>\n ))}\n </div>\n <div\n style={{\n ...(scrollerLayout.strategy === ScrollStrategy.Horizontal\n ? {\n width: scrollerLayout.endSpacing,\n height: '100%',\n flexShrink: 0,\n }\n : {\n height: scrollerLayout.endSpacing,\n width: '100%',\n }),\n }}\n />\n {overlayElements}\n </div>\n );\n}\n"],"names":["totalPages"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),t=require("@embedpdf/plugin-scroll"),r=require("react"),i=require("react/jsx-runtime"),o=()=>e.usePlugin(t.ScrollPlugin.id),l=()=>e.useCapability(t.ScrollPlugin.id);exports.Scroller=function({renderPage:a,overlayElements:n,...s}){const{provides:c}=l(),{plugin:g}=o(),{registry:u}=e.useRegistry(),[d,p]=r.useState((()=>(null==c?void 0:c.getScrollerLayout())??null));if(r.useEffect((()=>{if(c)return c.onScrollerData(p)}),[c]),r.useEffect((()=>{g&&g.setLayoutReady()}),[g]),!d)return null;if(!u)return null;const h=u.getStore().getState();return i.jsxs("div",{...s,style:{width:`${d.totalWidth}px`,height:`${d.totalHeight}px`,position:"relative",boxSizing:"border-box",margin:"0 auto",...d.strategy===t.ScrollStrategy.Horizontal&&{display:"flex",flexDirection:"row"}},children:[i.jsx("div",{style:{...d.strategy===t.ScrollStrategy.Horizontal?{width:d.startSpacing,height:"100%",flexShrink:0}:{height:d.startSpacing,width:"100%"}}}),i.jsx("div",{style:{gap:d.pageGap,display:"flex",alignItems:"center",position:"relative",boxSizing:"border-box",...d.strategy===t.ScrollStrategy.Horizontal?{flexDirection:"row",minHeight:"100%"}:{flexDirection:"column",minWidth:"fit-content"}},children:d.items.map((e=>i.jsx("div",{style:{display:"flex",justifyContent:"center",gap:d.pageGap},children:e.pageLayouts.map((e=>i.jsx("div",{style:{width:`${e.rotatedWidth}px`,height:`${e.rotatedHeight}px`},children:a({...e,rotation:h.core.rotation,scale:h.core.scale,document:h.core.document})},e.pageNumber)))},e.pageNumbers[0])))}),i.jsx("div",{style:{...d.strategy===t.ScrollStrategy.Horizontal?{width:d.endSpacing,height:"100%",flexShrink:0}:{height:d.endSpacing,width:"100%"}}}),n]})},exports.useScroll=()=>{const{provides:e}=l(),[t,i]=r.useState(1),[o,a]=r.useState(1);return r.useEffect((()=>{if(e)return e.onPageChange((({pageNumber:e,totalPages:t})=>{i(e),a(t)}))}),[e]),{...e,currentPage:t,totalPages:o}},exports.useScrollCapability=l,exports.useScrollPlugin=o,Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),t=require("@embedpdf/core/react"),r=require("@embedpdf/plugin-scroll"),o=require("react/jsx-runtime"),l=()=>t.usePlugin(r.ScrollPlugin.id),s=()=>t.useCapability(r.ScrollPlugin.id);exports.Scroller=function({renderPage:s,overlayElements:n,...i}){const{plugin:a}=l(),{registry:c}=t.useRegistry(),[g,u]=e.useState((()=>(null==a?void 0:a.getScrollerLayout())??null));if(e.useEffect((()=>{if(a)return a.onScrollerData(u)}),[a]),e.useEffect((()=>{a&&a.setLayoutReady()}),[a]),!g)return null;if(!c)return null;const d=c.getStore().getState();return o.jsxs("div",{...i,style:{width:`${g.totalWidth}px`,height:`${g.totalHeight}px`,position:"relative",boxSizing:"border-box",margin:"0 auto",...g.strategy===r.ScrollStrategy.Horizontal&&{display:"flex",flexDirection:"row"}},children:[o.jsx("div",{style:{...g.strategy===r.ScrollStrategy.Horizontal?{width:g.startSpacing,height:"100%",flexShrink:0}:{height:g.startSpacing,width:"100%"}}}),o.jsx("div",{style:{gap:g.pageGap,display:"flex",alignItems:"center",position:"relative",boxSizing:"border-box",...g.strategy===r.ScrollStrategy.Horizontal?{flexDirection:"row",minHeight:"100%"}:{flexDirection:"column",minWidth:"fit-content"}},children:g.items.map((e=>o.jsx("div",{style:{display:"flex",justifyContent:"center",gap:g.pageGap},children:e.pageLayouts.map((e=>o.jsx("div",{style:{width:`${e.rotatedWidth}px`,height:`${e.rotatedHeight}px`},children:s({...e,rotation:d.core.rotation,scale:d.core.scale,document:d.core.document})},e.pageNumber)))},e.pageNumbers[0])))}),o.jsx("div",{style:{...g.strategy===r.ScrollStrategy.Horizontal?{width:g.endSpacing,height:"100%",flexShrink:0}:{height:g.endSpacing,width:"100%"}}}),n]})},exports.useScroll=()=>{const{provides:t}=s(),[r,o]=e.useState(1),[l,n]=e.useState(1);return e.useEffect((()=>{if(t)return t.onPageChange((({pageNumber:e,totalPages:t})=>{o(e),n(t)}))}),[t]),{provides:t,state:{currentPage:r,totalPages:l},get currentPage(){return console.warn("Accessing 'currentPage' directly on useScroll() is deprecated. Use useScroll().state.currentPage instead."),r},get totalPages(){return console.warn("Accessing 'totalPages' directly on useScroll() is deprecated. Use useScroll().state.totalPages instead."),l},get scrollToPage(){return(null==t?void 0:t.scrollToPage)&&console.warn("Accessing 'scrollToPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPage instead."),null==t?void 0:t.scrollToPage},get scrollToNextPage(){return(null==t?void 0:t.scrollToNextPage)&&console.warn("Accessing 'scrollToNextPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToNextPage instead."),null==t?void 0:t.scrollToNextPage},get scrollToPreviousPage(){return(null==t?void 0:t.scrollToPreviousPage)&&console.warn("Accessing 'scrollToPreviousPage' directly on useScroll() is deprecated. Use useScroll().provides.scrollToPreviousPage instead."),null==t?void 0:t.scrollToPreviousPage},get getMetrics(){return(null==t?void 0:t.getMetrics)&&console.warn("Accessing 'getMetrics' directly on useScroll() is deprecated. Use useScroll().provides.getMetrics instead."),null==t?void 0:t.getMetrics},get onPageChange(){return(null==t?void 0:t.onPageChange)&&console.warn("Accessing 'onPageChange' directly on useScroll() is deprecated. Use useScroll().provides.onPageChange instead."),null==t?void 0:t.onPageChange},get onScroll(){return(null==t?void 0:t.onScroll)&&console.warn("Accessing 'onScroll' directly on useScroll() is deprecated. Use useScroll().provides.onScroll instead."),null==t?void 0:t.onScroll},get onLayoutChange(){return(null==t?void 0:t.onLayoutChange)&&console.warn("Accessing 'onLayoutChange' directly on useScroll() is deprecated. Use useScroll().provides.onLayoutChange instead."),null==t?void 0:t.onLayoutChange},get getCurrentPage(){return(null==t?void 0:t.getCurrentPage)&&console.warn("Accessing 'getCurrentPage' directly on useScroll() is deprecated. Use useScroll().provides.getCurrentPage instead."),null==t?void 0:t.getCurrentPage},get getTotalPages(){return(null==t?void 0:t.getTotalPages)&&console.warn("Accessing 'getTotalPages' directly on useScroll() is deprecated. Use useScroll().provides.getTotalPages instead."),null==t?void 0:t.getTotalPages}}},exports.useScrollCapability=s,exports.useScrollPlugin=l,Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
2
2
  //# sourceMappingURL=index.cjs.map