Options & methods
Public options and methods. Types omitted for brevity are exported from the package.
PptxViewer
Opinionated single-canvas viewer. Hand it a <canvas>; it owns parsing, rendering and the current slide.
new PptxViewer(canvas: HTMLCanvasElement, options?: PptxViewerOptions) Options
| Name | Type | Default | Description |
|---|---|---|---|
| Properties | |||
width | number | 960 | Canvas CSS width in px; height is derived from the slide aspect ratio. |
dpr | number | devicePixelRatio | Device pixel ratio for the backing store (crispness on HiDPI). |
useGoogleFonts | boolean | false | Load metric-compatible webfonts and non-Latin script fallbacks (Noto Arabic / CJK KR·SC·TC·JP / Cyrillic / Hebrew / Thai / Devanagari) from Google Fonts so layout matches Office and non-Latin text never falls back to tofu. Off by default for privacy. |
password | string | undefined | Password for an Agile-encrypted OOXML file. Available on self-loading Viewer constructors and headless load(); borrowed fromDocument(), fromPresentation(), and fromWorkbook() factories omit load-only options because their engine is already loaded. |
enableTextSelection | boolean | false | Overlay a transparent text layer so users can select & copy slide text. |
enableElementSelection | boolean | false | Enable read-only slide-element selection with a non-editable outline and element context; no editor model is exposed. |
elementHitTolerance | number | 6 | Straight-line hit tolerance in CSS pixels for element context clicks. |
findHighlightColors | { match?: string; active?: string } | yellow / orange | CSS backgrounds for ordinary and active find matches. Values are applied verbatim; use an alpha color to keep the canvas text visible through the overlay. |
enableMediaPlayback | boolean | false | Make embedded audio/video interactive (the viewer draws its own play chrome). |
hiddenSlideMode | 'show' | 'skip' | 'dim' | 'show' | How hidden slides (<p:sld show="0">, §19.3.1.38) are presented. show draws them like any other slide; skip makes sequential navigation (nextSlide/prevSlide and the initial load) jump over them while keeping absolute indices unchanged (an explicit goToSlide to a hidden slide is still honored); dim draws them under a translucent overlay (the PowerPoint thumbnail look). |
hiddenSlideDim | Partial<DimOptions> | { color: '#ffffff', opacity: 0.6 } | Overrides for the dim overlay, merged over the default white 60% wash. A partial so it stays in sync if DimOptions gains a field. |
maxZipEntryBytes | number | resource policy default | Deprecated compatibility alias for resourceLimits.maxArchiveEntryBytes. It is scheduled for removal in a future breaking release; new code should use resourceLimits. Existing positive values retain their per-entry meaning; zero / negative values fall back to the standard default. |
resourceLimits | OoxmlResourceLimits | 128 MiB per entry / 256 MiB distinct total / 4,096 entries | Shared DOCX/XLSX/PPTX package budgets. maxArchiveEntryBytes caps each package part; maxTotalInflatedBytes counts the largest amount read from every distinct part without charging repeat reads twice; maxArchiveEntries bounds central-directory entries before ZIP index allocation. Supply positive safe integers, or null to disable one configurable budget (internal hard ceilings remain). Violations reject with OoxmlResourceLimitError. These deterministic counters reduce OOM risk but do not measure or guarantee peak memory. Error fields → |
imageResources | ImageResourceOptions | { decodedByteBudget: 128 MiB, strategy: 'adaptive', resolution: 'native-if-fit' } | Decoded-raster policy shared by DOCX, XLSX and PPTX paints. Ordinary browser rasters receive a geometry-weighted share of decodedByteBudget before source extraction, allowing each source to flow directly into decode. A source keeps native resolution when it fits its share and otherwise uses up to a 2x canvas/DPR grid when that share has headroom. If the complete set of display grids exceeds the budget, adaptive mode reduces them by one uniform quality ratio. Set resolution: 'display' to minimize retained pixels. Natural-size consumers, pixel effects that require the authored grid, and non-resizable formats retain their guarded source-specific paths. Set strategy: 'strict' to preserve requested targets and receive OoxmlDecodedImageLimitError on an aggregate crossing. The budget accepts 4 bytes through 512 MiB; encoded-source, per-axis and per-surface hard safety ceilings remain non-disableable. Safety boundaries → |
debug | boolean | false | Print one content-free, Ratatui-inspired resource report when the measured load or Node session finishes or fails. Browser DevTools use typography-only %c styling to keep Unicode borders and gauges aligned without changing foreground or background colours; Node and Worker consoles receive one plain argument. Use onResourceMetrics instead for production collection. |
math | MathRenderer | undefined | Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Import it from the separate @silurus/ooxml/math entry — import { math } from "@silurus/ooxml/math" — and pass it to render equations in either mode. Omit it and equations are skipped; the MathJax asset is not fetched. When passed, that standalone asset is fetched lazily the first time a document contains an equation. |
threeD | ChartThreeDRenderer | undefined | Opt-in model-space 3-D chart renderer. Import threeD from the separate @silurus/ooxml/three-d entry and inject it once. Omit it to use the canonical 2-D fallback and avoid loading or evaluating the mesh/camera implementation in main mode. The self-contained worker asset retains the worker-side implementation. It renders the view angle authored in OOXML in main and worker modes. |
regionMap | ChartRegionMapRenderer | undefined | Opt-in offline ChartEx Region Map renderer using a pinned, public-domain Natural Earth country asset. Import regionMap from @silurus/ooxml/region-map and inject it once. Unsupported cached or sub-country views fail closed. The built-in renderer works in main and worker modes. |
chartEx | ChartExRenderer | undefined | Opt-in renderer for Microsoft ChartEx (cx:*) chart families. Import chartEx from @silurus/ooxml/chart-ex and inject it once. Classic 2-D charts stay in the default format entries; ChartEx is opt-in. The built-in renderer works in main and worker modes. |
tiff | TiffRenderer | undefined | Opt-in TIFF image codec shared by DOCX, XLSX and PPTX. Import tiff from @silurus/ooxml/tiff and inject it once. The bounded codec accepts stripped TIFF 6.0 bilevel, grayscale, RGB, RGBA and process-CMYK images, plus CCITT Group 4 bilevel images. Omit it to keep the implementation out of ordinary format bundles; recognized TIFF images then use an unavailable-image placeholder while the rest of the document keeps rendering. Unsupported or malformed input makes standalone codec calls and DOCX/PPTX rendering report TiffDecodeError; XLSX rendering, including XlsxViewer, contains it at that picture and shows the placeholder. The built-in codec works in main and worker modes. |
mode | 'main' | 'worker' | 'main' | Use 'main' for ordinary previews, the smallest worker download or custom renderer objects. Use 'worker' when rendering larger or more complex documents would compete with scrolling, navigation or other application UI. Worker mode requires Worker and OffscreenCanvas, downloads a larger render worker and transfers an ImageBitmap per frame. Viewer navigation, zoom, virtualized scrolling, selection, find, hyperlinks and the built-in math, ChartEx, 3-D, Region Map and TIFF renderers remain available in both modes. |
progressiveLayout | boolean | false | Resolve load() when the opening slide is paintable and continue sequential preflight in the background. slideCount and the ScrollViewer extent are final from first paint; availableSlideCount is the paintable opening prefix. Works in main and worker modes. Progressive layout guide → |
zoomMin / zoomMax | number | 0.1 / 4 | Zoom factor bounds for setScale / fitWidth / fitPage (10%–400%). |
enableHyperlinks | boolean | true | Master switch for hyperlink interactivity. Set false to disable it entirely: no hit-testing, no pointer cursor over links, no default navigation, and onHyperlinkClick is never called. Links still render exactly as authored but are inert, like plain text. |
| Event handlers | |||
onSelectionContextChange | (context: PptxSelectionContext | null) => void | — | Receive bounded detached text-selection or element-click context for AI/MCP handoff. Text selection takes precedence; this callback does not enable element hit-testing. |
onContextMenu | (event: ViewerContextMenuEvent<PptxSelectionContext>) => void | — | Called synchronously for the native contextmenu event. Use originalEvent.preventDefault() before returning to replace the browser menu; getContext() starts one memoized target lookup on first call. Omit the callback to keep native browser behavior unchanged. |
onResourceMetrics | (metrics: OoxmlResourceMetrics) => void | — | Receives the content-free initial-load report used by the debug card, without enabling console output. It reports the configured public policy, timing checkpoints, format/mode, success or typed failure discriminants, source bytes, and observed archive counters when available. It does not wait for a Viewer's first paint. On success, call getResourceMetrics() on the engine or Viewer for a fresh snapshot after lazy package work. Callback exceptions never change load results. |
onLayoutProgress | (progress: Readonly<{ committedUnits: number }>) => void | — | Called as the sequential preflight commits each paintable slide. committedUnits counts slides. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onLayoutPartial | (progress: Readonly<{ availableUnits: number; totalUnits?: number; exact: boolean }>) => void | — | Called for each additional paintable prefix after load() resolves. availableUnits counts paintable slides, totalUnits is the final slide count, and exact is false until completion. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onLayoutComplete | (error?: unknown) => void | — | Called once every slide is paintable, or with the background failure. It fires only when progressiveLayout deferred work after load() resolved. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onScaleChange | (scale: number) => void | — | Called when the zoom factor changes (setScale / fitWidth / fitPage / zoomIn / zoomOut), with the clamped factor (1 = 100%). |
onHyperlinkClick | (target: HyperlinkTarget) => void | — | Called when a hyperlink is clicked. target is { kind: 'external', url } or { kind: 'internal', ref, slideIndex? }. When supplied, the callback fully owns the click (the default external-open / internal-navigation is not run). External URLs are scheme-sanitized (http / https / mailto / tel only); internal targets resolve to a docx bookmark, pptx slide jump, or xlsx defined name / cell reference. XLSX switches sheets before scrolling the destination into view and uses the first cell of a range. |
onSlideChange | (index: number, total: number, layoutComplete: boolean) => void | — | Called after a slide finishes rendering and again when progressive availability changes completion state. |
onError | (err: Error) => void | — | Receives Viewer-managed failures that have no directly awaitable result, such as virtualized rendering or embedded-media playback. load(), navigation, and other awaitable operations reject their own Promise whether or not this callback is supplied; the same failure is never delivered twice. Background failures are logged with console.error when the callback is omitted. Narrow stable cases with OoxmlError, OoxmlResourceLimitError, OoxmlDecodedImageLimitError or TiffDecodeError; other failures remain Error values and message text is not a stable discriminator. Error reference → |
Methods
static fromPresentation(canvas, presentation, options?): Omit<PptxViewer, "load"> | Synchronously create a Viewer that borrows an already-loaded presentation. Render with goToSlide(); destroy() leaves the presentation open. |
load(source: string | ArrayBuffer): Promise<void> | Load a Viewer-owned URL or ArrayBuffer. With progressiveLayout, resolve when the opening slide is paintable. |
goToSlide(index: number): Promise<void> | Render a specific slide (0-indexed, clamped). |
nextSlide(): Promise<void> | Advance one slide. |
prevSlide(): Promise<void> | Go back one slide. |
getScale(): number | The current zoom factor (1 = 100%). |
setScale(scale: number): Promise<void> | Set the absolute zoom factor (1 = 100%), clamped to [zoomMin, zoomMax]; re-renders at the new size and fires onScaleChange when it changes. View-only. |
fitWidth(): Promise<void> | Fit the content WIDTH to the host container and re-render (routes through setScale). Defers when nothing is loaded or the container is unlaid-out. |
fitPage(): Promise<void> | Fit the WHOLE content (width and height) inside the container so it is visible without scrolling — takes the tighter of the two fits. Defers when unloaded / unlaid-out. |
findText(query: string, opts?: { caseSensitive?: boolean }): Promise<FindMatch<PptxMatchLocation>[]> | Full-text search across the whole document; highlights every hit and returns them in document order. Each match carries matchIndex, the matched text, and its location. Case-insensitive by default. |
findNext(): Promise<FindMatch<PptxMatchLocation> | null> | Move to the next match (wrap-around), navigate to it if needed, and draw it in the active-match colour. Returns the now-active match, or null when there are none. Call findText first. |
findPrev(): Promise<FindMatch<PptxMatchLocation> | null> | Move to the previous match (wrap-around from first to last). |
clearFind(): void | Clear all highlights and reset the find state. |
get slideIndex(): number | Current slide index. |
get slideCount(): number | Total slides (0 until loaded). |
get availableSlideCount(): number | Paintable opening-slide prefix. Equals slideCount outside progressive loading. |
get layoutComplete(): boolean | True only when every slide is paintable. It remains false if background preparation fails; waitUntilLayoutComplete() reports that failure. |
waitUntilLayoutComplete(): Promise<void> | Wait until every slide is paintable; rejects if background preflight fails. |
get hiddenSlideMode(): "show" | "skip" | "dim" | The current hidden-slide mode. |
setHiddenSlideMode(mode: "show" | "skip" | "dim"): Promise<void> | Switch the hidden-slide mode at runtime and re-render. Entering skip while on a hidden slide advances to the nearest visible slide. |
get visibleSlideCount(): number | Number of non-hidden slides. During progressive loading this is provisional until layoutComplete; the absolute slideCount remains unchanged. |
getNotes(slideIndex: number): string | null | Speaker-notes text for a slide (0-based). During progressive loading the answer is authoritative only below availableSlideCount; await waitUntilLayoutComplete() before scanning the whole deck. |
get canvasElement(): HTMLCanvasElement | The underlying canvas. |
getSelectionContext(options?: PptxSelectionContextOptions): PptxSelectionContext | null | Return the current bounded, JSON-serializable text or element focus snapshot. Throws after destroy(). |
getResourceMetrics(): Promise<OoxmlResourceMetrics> | Return a fresh, content-free package-usage snapshot, including lazy archive work observed since load. Collection is always active; debug controls only console output. |
destroy(): void | Tear down the worker and release resources. |
PptxPresentation
Headless engine — parse once, render any slide into any canvas you supply (scroll views, thumbnail grids, master–detail).
await PptxPresentation.load(source, options?) Options
| Name | Type | Default | Description |
|---|---|---|---|
| Properties | |||
useGoogleFonts | boolean | false | Load metric-compatible webfonts and non-Latin script fallbacks (Noto Arabic / CJK KR·SC·TC·JP / Cyrillic / Hebrew / Thai / Devanagari) from Google Fonts so layout matches Office and non-Latin text never falls back to tofu. Off by default for privacy. |
password | string | undefined | Password for an Agile-encrypted OOXML file. Available on self-loading Viewer constructors and headless load(); borrowed fromDocument(), fromPresentation(), and fromWorkbook() factories omit load-only options because their engine is already loaded. |
wasmUrl | string | URL | bundled asset | Override the URL the parser worker fetches the WebAssembly module from. By default each format resolves the *_parser_bg.wasm asset that ships next to its bundle (relative to the module URL); set this to serve it from a CDN or a self-hosted path instead (a relative value resolves against the document URL). Pointing it at a mismatched or missing file makes load() reject when the worker instantiates it. |
maxZipEntryBytes | number | resource policy default | Deprecated compatibility alias for resourceLimits.maxArchiveEntryBytes. It is scheduled for removal in a future breaking release; new code should use resourceLimits. Existing positive values retain their per-entry meaning; zero / negative values fall back to the standard default. |
resourceLimits | OoxmlResourceLimits | 128 MiB per entry / 256 MiB distinct total / 4,096 entries | Shared DOCX/XLSX/PPTX package budgets. maxArchiveEntryBytes caps each package part; maxTotalInflatedBytes counts the largest amount read from every distinct part without charging repeat reads twice; maxArchiveEntries bounds central-directory entries before ZIP index allocation. Supply positive safe integers, or null to disable one configurable budget (internal hard ceilings remain). Violations reject with OoxmlResourceLimitError. These deterministic counters reduce OOM risk but do not measure or guarantee peak memory. Error fields → |
debug | boolean | false | Print one content-free, Ratatui-inspired resource report when the measured load or Node session finishes or fails. Browser DevTools use typography-only %c styling to keep Unicode borders and gauges aligned without changing foreground or background colours; Node and Worker consoles receive one plain argument. Use onResourceMetrics instead for production collection. |
workerTimeoutMs | number | unlimited | Opt-in worker liveness limit. Ordinary worker requests use it as their response deadline. Worker-mode progressive loads restart this silence interval whenever the worker reports progress. This allows active long-running work to continue. Silence before first paint rejects load(); silence afterward keeps layoutComplete false and rejects waitUntilLayoutComplete(), while configured completion/error callbacks receive the failure. Worker exceptions still reject immediately. Unlimited by default. |
math | MathRenderer | undefined | Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Import it from the separate @silurus/ooxml/math entry — import { math } from "@silurus/ooxml/math" — and pass it to render equations in either mode. Omit it and equations are skipped; the MathJax asset is not fetched. When passed, that standalone asset is fetched lazily the first time a document contains an equation. |
threeD | ChartThreeDRenderer | undefined | Opt-in model-space 3-D chart renderer. Import threeD from the separate @silurus/ooxml/three-d entry and inject it once. Omit it to use the canonical 2-D fallback and avoid loading or evaluating the mesh/camera implementation in main mode. The self-contained worker asset retains the worker-side implementation. It renders the view angle authored in OOXML in main and worker modes. |
regionMap | ChartRegionMapRenderer | undefined | Opt-in offline ChartEx Region Map renderer using a pinned, public-domain Natural Earth country asset. Import regionMap from @silurus/ooxml/region-map and inject it once. Unsupported cached or sub-country views fail closed. The built-in renderer works in main and worker modes. |
chartEx | ChartExRenderer | undefined | Opt-in renderer for Microsoft ChartEx (cx:*) chart families. Import chartEx from @silurus/ooxml/chart-ex and inject it once. Classic 2-D charts stay in the default format entries; ChartEx is opt-in. The built-in renderer works in main and worker modes. |
tiff | TiffRenderer | undefined | Opt-in TIFF image codec shared by DOCX, XLSX and PPTX. Import tiff from @silurus/ooxml/tiff and inject it once. The bounded codec accepts stripped TIFF 6.0 bilevel, grayscale, RGB, RGBA and process-CMYK images, plus CCITT Group 4 bilevel images. Omit it to keep the implementation out of ordinary format bundles; recognized TIFF images then use an unavailable-image placeholder while the rest of the document keeps rendering. Unsupported or malformed input makes standalone codec calls and DOCX/PPTX rendering report TiffDecodeError; XLSX rendering, including XlsxViewer, contains it at that picture and shows the placeholder. The built-in codec works in main and worker modes. |
mode | 'main' | 'worker' | 'main' | Use 'main' for the smallest worker download, the lowest single-frame overhead or custom renderer objects; parsing still runs in a Worker, while Canvas rendering runs on the main thread. Use 'worker' when document layout and paint would compete with application UI responsiveness. It requires Worker and OffscreenCanvas, downloads a larger render worker and transfers an ImageBitmap per frame. Built-in math, ChartEx, 3-D, Region Map and TIFF renderers use the same options in both modes. In worker mode, use the bitmap render methods instead of methods that accept a Canvas. |
progressiveLayout | boolean | false | Resolve load() when the opening slide is paintable and continue sequential preflight in the background. slideCount and the ScrollViewer extent are final from first paint; availableSlideCount is the paintable opening prefix. Works in main and worker modes. Progressive layout guide → |
| Event handlers | |||
onResourceMetrics | (metrics: OoxmlResourceMetrics) => void | — | Receives the content-free initial-load report used by the debug card, without enabling console output. It reports the configured public policy, timing checkpoints, format/mode, success or typed failure discriminants, source bytes, and observed archive counters when available. It does not wait for a Viewer's first paint. On success, call getResourceMetrics() on the engine or Viewer for a fresh snapshot after lazy package work. Callback exceptions never change load results. |
onLayoutProgress | (progress: Readonly<{ committedUnits: number }>) => void | — | Called as the sequential preflight commits each paintable slide. committedUnits counts slides. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onLayoutPartial | (progress: Readonly<{ availableUnits: number; totalUnits?: number; exact: boolean }>) => void | — | Called for each additional paintable prefix after load() resolves. availableUnits counts paintable slides, totalUnits is the final slide count, and exact is false until completion. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onLayoutComplete | (error?: unknown) => void | — | Called once every slide is paintable, or with the background failure. It fires only when progressiveLayout deferred work after load() resolved. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
Methods
static load(source, options?): Promise<PptxPresentation> | Parse a deck from a URL or ArrayBuffer. With progressiveLayout, resolve when the opening slide is paintable. |
get slideCount(): number | Total slides. |
get availableSlideCount(): number | Paintable opening-slide prefix; slideCount remains final throughout. |
get layoutComplete(): boolean | True only when every slide is paintable. It remains false if background preparation fails; waitUntilLayoutComplete() reports that failure. |
waitUntilLayoutComplete(): Promise<void> | Wait until every slide is paintable; rejects if background preflight fails. |
renderSlide(canvas, index, opts?: { width?, dpr?, onTextRun?, dim? }): Promise<void> | Render one slide into the given canvas at the given width. onTextRun receives each rendered segment as PptxTextRunInfo, including the source shape’s slide-local shapeId, optional frame flips, and zero-based table-cell row/column when authored, so callers can build a transparent selection overlay or stable shape mapping; dim (a DimOptions) paints a translucent wash over the finished slide (hidden-slide dimming). Equations render when a math engine was passed to load. Unavailable in mode: "worker" — use renderSlideToBitmap. |
renderSlideToBitmap(index, opts?: { width?, dpr?, dim? }): Promise<ImageBitmap> | Render one slide and return it as an ImageBitmap (both modes; in worker mode slide paint, equations, ChartEx, 3-D charts and Region Maps run off the main thread). dim paints a translucent overlay over the slide (hidden-slide dimming). The bitmap is caller-owned: pass it to transferFromImageBitmap (which consumes it) or call bitmap.close(). |
presentSlide(canvas, index, opts?: PresentSlideOptions): Promise<PresentationHandle> | Render a slide and attach canvas-native audio/video playback, returning a handle with play() / pause() / destroy(). Initial render and media acquisition failures reject this Promise. PresentSlideOptions.onError observes decode or playback failures that occur only after the handle has been returned. Works in both modes — in mode: "worker" the base slide and text-run geometry are produced off-thread and the video overlay is composited on the main thread. |
getNotes(slideIndex: number): string | null | Speaker-notes text for a slide (0-based; ECMA-376 §13.3.5). During progressive loading, null for an index at or beyond availableSlideCount means the slide is not ready, not necessarily that it has no notes. Await completion before a whole-deck scan. |
getComments(slideIndex: number): readonly Readonly<PptxComment>[] | Detached comment threads for one slide. During progressive loading, results are authoritative only below availableSlideCount; await waitUntilLayoutComplete() before scanning the whole deck. Modern comments expose slide, drawing-element, or text-range anchors; classic comments retain their authored slide point. |
isHidden(slideIndex: number): boolean | Whether a slide is authored as hidden. During progressive loading, results are authoritative only below availableSlideCount; await completion before scanning every slide. |
get slideWidth(): number | Slide width in EMU (0 until loaded). |
get slideHeight(): number | Slide height in EMU (0 until loaded). |
get mode(): "main" | "worker" | The render mode this engine was loaded with. A borrowed engine’s mode decides whether slides render via renderSlide (main) or renderSlideToBitmap (worker). |
getElementContextAt(slideIndex, point, options?): Promise<PptxElementContext | null> | Return compact context for the topmost transformed element frame at a slide-EMU point in either mode (line segments use tolerance). Includes master/layout/slide provenance, never editor tree indexes or mutable elements. |
getElementBoundsByIds(slideIndex, elementIds): Promise<readonly PptxElementBounds[]> | Resolve authored DrawingML element ids to immutable slide geometry in one lazy slide read. Use this with modern-comment drawing or text anchors; it works in main and worker modes. |
getResourceMetrics(): Promise<OoxmlResourceMetrics> | Return a fresh, content-free package-usage snapshot, including lazy archive work observed since load. Collection is always active; debug controls only console output. |
destroy(): void | Release the worker. |
PptxScrollViewer
Container-owning continuous-scroll viewer. Takes a <div> (not a canvas) and renders the whole deck as one vertically-scrolling, virtualized surface (only the visible window + overscan is mounted). Zoom is view-only.
new PptxScrollViewer(container: HTMLElement, options?: PptxScrollViewerOptions) Options
| Name | Type | Default | Description |
|---|---|---|---|
| Properties | |||
width | number | container width | Base fit width in CSS px. Default: the container width at first non-zero layout. |
gap | number | 16 | Vertical gap (px) between consecutive slides. |
paddingTop / paddingBottom | number | gap | Desk padding (px) above the first slide / below the last. Pass 0 for a flush edge. |
paddingLeft / paddingRight | number | gap | Horizontal desk gutters (px); also shrink the container-derived fit width so a slide sits inside them at 100%. Pass 0 for a flush edge. |
overscan | number | 1 | Slides kept mounted beyond the viewport on each side. |
background | string | undefined | CSS background for the scroll surface (the desk behind/between slides). Default transparent (the container shows through). |
pageShadow | string | false | '0 1px 3px rgba(0,0,0,0.2)' | CSS box-shadow painted on every slide canvas. A spread-only ring (e.g. 0 0 0 1px #c8ccd0) gives a crisp 1px border look. false disables it (flat slides). |
enableZoom | boolean | true | Enable Ctrl/⌘ + wheel (and trackpad pinch) zoom. View-only. |
zoomMin / zoomMax | number | 0.1 / 4 | Absolute zoom scale bounds (10%–400%). When width fit needs a smaller scale, that fitted scale remains reachable as the effective minimum. |
refitOnResize | boolean | true | Re-fit to the container width when it resizes. Set false to preserve an absolute scale independently of viewport width; explicit fitWidth() / fitPage() still work. |
enableTextSelection | boolean | false | Overlay a transparent, selectable text layer per slide for native copy in both render modes. |
comments | boolean | PptxCommentsOptions | false | Show read-only slide comment targets, message icons, and built-in margin cards. Pass cards: false for an application-owned list that retains Viewer-owned target highlighting, or markers: false to hide idle message icons. The options object also controls resolved-thread visibility, side, and optional connectors. Theme cards and markers with CSS custom properties or documented classes on the Viewer container. Comment UI guide → |
enableElementSelection | boolean | false | Enable read-only element selection on mounted slide canvases with a non-editable outline and element context. |
elementHitTolerance | number | 6 | Straight-line hit tolerance in CSS pixels. |
findHighlightColors | { match?: string; active?: string } | yellow / orange | CSS backgrounds for ordinary and active find matches. Values are applied verbatim; use an alpha color to keep the canvas text visible through the overlay. |
enableMediaPlayback | boolean | false | Make embedded audio/video interactive inside the real viewport plus mediaOverscan. Other mounted slides remain static and selectable without allocating media blobs or RAF loops. |
mediaOverscan | number | 1 | Slides beyond the real viewport that may keep interactive media handles. Independent from the general overscan used for mounted canvases/text overlays. |
enableHyperlinks | boolean | true | Master switch for hyperlink interactivity. Set false to disable it entirely: no hit-testing, no pointer cursor over links, no default navigation, and onHyperlinkClick is never called. Links still render exactly as authored but are inert, like plain text. |
useGoogleFonts | boolean | false | Load metric-compatible webfonts and non-Latin script fallbacks (Noto Arabic / CJK KR·SC·TC·JP / Cyrillic / Hebrew / Thai / Devanagari) from Google Fonts so layout matches Office and non-Latin text never falls back to tofu. Off by default for privacy. |
password | string | undefined | Password for an Agile-encrypted OOXML file. Available on self-loading Viewer constructors and headless load(); borrowed fromDocument(), fromPresentation(), and fromWorkbook() factories omit load-only options because their engine is already loaded. |
maxZipEntryBytes | number | resource policy default | Deprecated compatibility alias for resourceLimits.maxArchiveEntryBytes. It is scheduled for removal in a future breaking release; new code should use resourceLimits. Existing positive values retain their per-entry meaning; zero / negative values fall back to the standard default. |
resourceLimits | OoxmlResourceLimits | 128 MiB per entry / 256 MiB distinct total / 4,096 entries | Shared DOCX/XLSX/PPTX package budgets. maxArchiveEntryBytes caps each package part; maxTotalInflatedBytes counts the largest amount read from every distinct part without charging repeat reads twice; maxArchiveEntries bounds central-directory entries before ZIP index allocation. Supply positive safe integers, or null to disable one configurable budget (internal hard ceilings remain). Violations reject with OoxmlResourceLimitError. These deterministic counters reduce OOM risk but do not measure or guarantee peak memory. Error fields → |
imageResources | ImageResourceOptions | { decodedByteBudget: 128 MiB, strategy: 'adaptive', resolution: 'native-if-fit' } | Decoded-raster policy shared by DOCX, XLSX and PPTX paints. Ordinary browser rasters receive a geometry-weighted share of decodedByteBudget before source extraction, allowing each source to flow directly into decode. A source keeps native resolution when it fits its share and otherwise uses up to a 2x canvas/DPR grid when that share has headroom. If the complete set of display grids exceeds the budget, adaptive mode reduces them by one uniform quality ratio. Set resolution: 'display' to minimize retained pixels. Natural-size consumers, pixel effects that require the authored grid, and non-resizable formats retain their guarded source-specific paths. Set strategy: 'strict' to preserve requested targets and receive OoxmlDecodedImageLimitError on an aggregate crossing. The budget accepts 4 bytes through 512 MiB; encoded-source, per-axis and per-surface hard safety ceilings remain non-disableable. Safety boundaries → |
debug | boolean | false | Print one content-free, Ratatui-inspired resource report when the measured load or Node session finishes or fails. Browser DevTools use typography-only %c styling to keep Unicode borders and gauges aligned without changing foreground or background colours; Node and Worker consoles receive one plain argument. Use onResourceMetrics instead for production collection. |
math | MathRenderer | undefined | Opt-in OMML equation engine (MathJax + STIX Two Math, ~3 MB). Import it from the separate @silurus/ooxml/math entry — import { math } from "@silurus/ooxml/math" — and pass it to render equations in either mode. Omit it and equations are skipped; the MathJax asset is not fetched. When passed, that standalone asset is fetched lazily the first time a document contains an equation. |
threeD | ChartThreeDRenderer | undefined | Opt-in model-space 3-D chart renderer. Import threeD from the separate @silurus/ooxml/three-d entry and inject it once. Omit it to use the canonical 2-D fallback and avoid loading or evaluating the mesh/camera implementation in main mode. The self-contained worker asset retains the worker-side implementation. It renders the view angle authored in OOXML in main and worker modes. |
regionMap | ChartRegionMapRenderer | undefined | Opt-in offline ChartEx Region Map renderer using a pinned, public-domain Natural Earth country asset. Import regionMap from @silurus/ooxml/region-map and inject it once. Unsupported cached or sub-country views fail closed. The built-in renderer works in main and worker modes. |
chartEx | ChartExRenderer | undefined | Opt-in renderer for Microsoft ChartEx (cx:*) chart families. Import chartEx from @silurus/ooxml/chart-ex and inject it once. Classic 2-D charts stay in the default format entries; ChartEx is opt-in. The built-in renderer works in main and worker modes. |
tiff | TiffRenderer | undefined | Opt-in TIFF image codec shared by DOCX, XLSX and PPTX. Import tiff from @silurus/ooxml/tiff and inject it once. The bounded codec accepts stripped TIFF 6.0 bilevel, grayscale, RGB, RGBA and process-CMYK images, plus CCITT Group 4 bilevel images. Omit it to keep the implementation out of ordinary format bundles; recognized TIFF images then use an unavailable-image placeholder while the rest of the document keeps rendering. Unsupported or malformed input makes standalone codec calls and DOCX/PPTX rendering report TiffDecodeError; XLSX rendering, including XlsxViewer, contains it at that picture and shows the placeholder. The built-in codec works in main and worker modes. |
dpr | number | devicePixelRatio | Device pixel ratio for the backing store (crispness on HiDPI). |
mode | 'main' | 'worker' | 'main' | Use 'main' for the smallest worker download, the lowest single-frame overhead or custom renderer objects; parsing still runs in a Worker, while Canvas rendering runs on the main thread. Use 'worker' when document layout and paint would compete with application UI responsiveness. It requires Worker and OffscreenCanvas, downloads a larger render worker and transfers an ImageBitmap per frame. Built-in math, ChartEx, 3-D, Region Map and TIFF renderers use the same options in both modes. In worker mode, use the bitmap render methods instead of methods that accept a Canvas. |
progressiveLayout | boolean | false | Resolve load() when the opening slide is paintable and continue sequential preflight in the background. slideCount and the ScrollViewer extent are final from first paint; availableSlideCount is the paintable opening prefix. Works in main and worker modes. Progressive layout guide → |
| Event handlers | |||
onSelectionContextChange | (context: PptxSelectionContext | null) => void | — | Receive bounded detached text, selected-comment, or element context for external AI/MCP integrations. This callback does not enable element hit-testing. |
onContextMenu | (event: ViewerContextMenuEvent<PptxSelectionContext>) => void | — | Called synchronously for the native contextmenu event. Use originalEvent.preventDefault() before returning to replace the browser menu; getContext() starts one memoized target lookup on first call. Omit the callback to keep native browser behavior unchanged. |
onHyperlinkClick | (target: HyperlinkTarget) => void | — | Called when a hyperlink is clicked. target is { kind: 'external', url } or { kind: 'internal', ref, slideIndex? }. When supplied, the callback fully owns the click (the default external-open / internal-navigation is not run). External URLs are scheme-sanitized (http / https / mailto / tel only); internal targets resolve to a docx bookmark, pptx slide jump, or xlsx defined name / cell reference. XLSX switches sheets before scrolling the destination into view and uses the first cell of a range. |
onResourceMetrics | (metrics: OoxmlResourceMetrics) => void | — | Receives the content-free initial-load report used by the debug card, without enabling console output. It reports the configured public policy, timing checkpoints, format/mode, success or typed failure discriminants, source bytes, and observed archive counters when available. It does not wait for a Viewer's first paint. On success, call getResourceMetrics() on the engine or Viewer for a fresh snapshot after lazy package work. Callback exceptions never change load results. |
onLayoutProgress | (progress: Readonly<{ committedUnits: number }>) => void | — | Called as the sequential preflight commits each paintable slide. committedUnits counts slides. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onLayoutPartial | (progress: Readonly<{ availableUnits: number; totalUnits?: number; exact: boolean }>) => void | — | Called for each additional paintable prefix after load() resolves. availableUnits counts paintable slides, totalUnits is the final slide count, and exact is false until completion. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onLayoutComplete | (error?: unknown) => void | — | Called once every slide is paintable, or with the background failure. It fires only when progressiveLayout deferred work after load() resolved. Observer exceptions are reported once and never change the layout result. Progressive layout guide → |
onVisibleSlideChange | (topIndex: number, total: number, layoutComplete: boolean) => void | — | Fires when the top-most visible slide changes or progressive completion changes while the same slide remains visible. |
onError | (err: Error) => void | — | Receives Viewer-managed failures that have no directly awaitable result, such as virtualized rendering or embedded-media playback. load(), navigation, and other awaitable operations reject their own Promise whether or not this callback is supplied; the same failure is never delivered twice. Background failures are logged with console.error when the callback is omitted. Narrow stable cases with OoxmlError, OoxmlResourceLimitError, OoxmlDecodedImageLimitError or TiffDecodeError; other failures remain Error values and message text is not a stable discriminator. Error reference → |
Methods
static fromPresentation(container, presentation, options?): Omit<PptxScrollViewer, "load"> | Synchronously create a Scroll Viewer that borrows one loaded presentation and lays out its initial virtual window. |
load(source: string | ArrayBuffer): Promise<void> | Load a Viewer-owned deck. With progressiveLayout, render the opening paintable window while reserving the final scroll extent. |
scrollToSlide(index: number, opts?: { behavior?: "auto" | "smooth" }): void | Scroll so slide index’s top edge sits at the viewport top (index clamped). |
goToComment(slideIndex: number, commentIndex: number, opts?: { behavior?: "auto" | "smooth" }): Promise<boolean> | Reveal and highlight one entry from presentation.getComments(slideIndex). Resolves after modern element bounds or the authored slide point has been selected; returns false for an invalid locator or unresolved target. |
findText(query: string, opts?: { caseSensitive?: boolean }): Promise<FindMatch<PptxMatchLocation>[]> | Full-text search across the whole document; highlights every hit and returns them in document order. Each match carries matchIndex, the matched text, and its location. Case-insensitive by default. |
findNext(): Promise<FindMatch<PptxMatchLocation> | null> | Move to the next match (wrap-around), navigate to it if needed, and draw it in the active-match colour. Returns the now-active match, or null when there are none. Call findText first. |
findPrev(): Promise<FindMatch<PptxMatchLocation> | null> | Move to the previous match (wrap-around from first to last). |
clearFind(): void | Clear all highlights and reset the find state. |
setScale(scale: number): void | Set the absolute zoom scale at runtime (clamped to the effective zoom range, which includes a width fit below zoomMin). Flicker-free. View-only. |
relayout(): void | Force a re-fit + re-mount of the visible window. Called automatically after load / resize / zoom; use it when the container resizes in a way a ResizeObserver cannot observe (e.g. a late web-font load). Idempotent. |
get slideCount(): number | Total slides (0 until loaded). |
get availableSlideCount(): number | Paintable opening-slide prefix; the full scroll extent already uses slideCount. |
get layoutComplete(): boolean | True only when every slide is paintable. It remains false if background preparation fails; waitUntilLayoutComplete() reports that failure. |
waitUntilLayoutComplete(): Promise<void> | Wait until every slide is paintable; rejects if background preflight fails. |
get topVisibleSlide(): number | Index of the top-most visible slide. |
getSelectionContext(options?: PptxSelectionContextOptions): PptxSelectionContext | null | Return the current mounted text selection, selected comment thread, or clicked-element context. |
getResourceMetrics(): Promise<OoxmlResourceMetrics> | Return a fresh, content-free package-usage snapshot, including lazy archive work observed since load. Collection is always active; debug controls only console output. |
destroy(): void | Tear down the DOM subtree. Destroys a self-loaded engine; a borrowed one is left intact. |
Review data
Office revision records
Not available for PPTX. The library does not expose PowerPoint comparison results or cloud collaboration change indicators as revision records. Comments remain available through PptxPresentation.getComments(slideIndex) and the Viewer comment APIs.