← Overview

Comments in DOCX, XLSX, and PPTX

@silurus/ooxml reads comments already stored in Office files. Start with each Viewer's read-only UI, or use detached comment records and format-specific anchor geometry when the application needs a different layout.

Start with the built-in UI

Use the same comments option across formats. The presentation follows the document type: a page margin for DOCX, a slide margin and markers for PPTX, and a cell-anchored popup for XLSX.

DOCX

Opt in to page-side cards, range highlights, and message icons.

import { DocxScrollViewer } from '@silurus/ooxml/docx';

const viewer = new DocxScrollViewer(container, {
  comments: {
    markers: true, // Default. Set false to hide the message icons only.
  },
});

await viewer.load(source);

PPTX

Opt in to slide message icons and page-side cards.

import { PptxScrollViewer } from '@silurus/ooxml/pptx';

const viewer = new PptxScrollViewer(container, {
  comments: {
    markers: true, // Default. Set false to hide the message icons only.
  },
});

await viewer.load(source);

XLSX

Cell comments are visible by default; options can narrow visibility.

import { XlsxViewer } from '@silurus/ooxml/xlsx';

// Comments are shown by default. Pass options only to change the policy.
const viewer = new XlsxViewer(container, {
  comments: { includeResolved: false },
});

await viewer.load(source);

These snippets assume an application-owned, laid-out host element and a source URL or ArrayBuffer. Keep the Viewer for as long as the screen is mounted, then call viewer.destroy(). See the DOCX, XLSX, and PPTX live pages for complete Viewer setup.

OptionFormatsBehavior
comments: trueDOCX, PPTX, XLSXUse the built-in presentation and its format defaults. XLSX comments are already visible when the option is omitted.
comments: falseDOCX, PPTX, XLSXDo not show the built-in comment presentation.
includeResolvedDOCX, PPTX, XLSXInclude resolved or closed threads. Defaults to false for DOCX/PPTX and true for XLSX.
cardsDOCX, PPTXShow built-in margin cards. Defaults to true. Set it to false for an application-owned list while retaining Viewer-owned target highlighting.
markersDOCX, PPTXShow the built-in message icon at each comment anchor. Defaults to true. Set it to false to hide only the icons; cards and DOCX range highlights remain visible.
sideDOCX, PPTXPlace margin cards on auto, left, or right. auto follows the container direction.
connectorsDOCX, PPTXOptionally connect an anchor or marker to its card. Omit it for no lines.

Optional DOCX/PPTX connectors

Choose the route, stroke, and colors in Viewer options. Omit connectors for no line. A color may be a CSS variable such as var(--review-connector), so a theme switch can update an existing Viewer.

// Available on DocxScrollViewer and PptxScrollViewer.
const viewer = new DocxScrollViewer(container, {
  comments: {
    side: 'auto',
    connectors: {
      route: 'bezier', // or 'orthogonal'
      stroke: 'solid', // or 'dashed'
      color: '#94a3b8',
      activeColor: '#2563eb',
    },
  },
});

Style the built-in UI

Two complementary styling surfaces are available. Use either one or combine them.

CSS variables

Switch common theme tokens.

Use variables for colors, card borders, and corner radius. This convenience layer intentionally does not mirror every CSS property.

/* Switch common theme tokens with CSS variables. */
#viewer {
  --ooxml-comment-card-background: rgb(255 255 255 / 0.78);
  --ooxml-comment-card-border: 1px solid #cbd5e1;
  --ooxml-comment-card-border-left: 3px solid #2563eb;
  --ooxml-comment-card-border-right: 1px solid #cbd5e1;
  --ooxml-comment-card-radius: 8px;
  --ooxml-comment-card-active-background: #dbeafe;
  --ooxml-comment-highlight: rgba(59, 130, 246, 0.18);
  --ooxml-comment-highlight-active: rgba(37, 99, 235, 0.34);
  --ooxml-comment-marker-color: #2563eb;
}

Stable classes

Control the complete appearance.

Use classes for typography, spacing, shadows, filters, and state selectors. Cards expose data-active and data-focused. Viewer defaults use low-specificity selectors, so application CSS can override them without !important.

/* Control the complete appearance with stable classes. */
#viewer .ooxml-comment-card {
  box-shadow: 0 12px 32px rgb(15 23 42 / 0.14);
  backdrop-filter: blur(14px);
}

#viewer .ooxml-comment-card__author {
  letter-spacing: 0.01em;
}

#viewer .ooxml-comment-card[data-active="true"] {
  box-shadow: 0 0 0 2px #2563eb;
}

Changing variables, a theme class, or data-theme on the Viewer container or an ancestor updates mounted cards, highlights, and markers without recreating the Viewer. Geometry-affecting changes such as font size, font family, or padding are measured again before the cards are repositioned.

By default, the Viewer assigns each author a stable accent color. Here, #viewer is an example ID on the application-owned Viewer container. The fixed blue values deliberately replace per-author accents; omit them to keep automatic author colors.

HookFormatsPurpose
.ooxml-comment-card and child classesDOCX, PPTX, XLSXComplete card typography, spacing, effects, and content styling.
data-active, data-focusedDOCX, PPTXSelected and keyboard-focused margin-card states. The XLSX popup is non-interactive.
Card CSS variablesDOCX, PPTX, XLSXCommon colors, borders, and corner radius.
Highlight and marker variablesDOCX, PPTXDOM range highlights and message icons. XLSX's cell-corner marker is Canvas-painted and is not changed by these tokens.

Default appearance

Switch between the live DOCX margin, XLSX cell popup, and PPTX slide margin. Lines are off unless requested.

The demo background is applied by the surrounding page, not by ScrollViewer.

sample-1.docx

Loading sample-1.docx…

Comments appear beside the second page.

How comments are represented

Every format exposes detached comment data. What differs is how an authored comment is anchored to visible content.

Comments and threads

Reviewer notes, replies, authors, dates, and resolved state.

Anchors

A text range in DOCX, a slide, drawing element, or text range in PPTX, and a cell reference in XLSX.

Built-in presentation

The Viewer turns those anchors into a margin, marker, highlight, or popup.

Surface geometry

Primitive APIs expose page pixels, slide EMUs, or current-sheet viewport pixels when the application owns the UI.

FormatSource recordsSurface-scoped accessCoordinates
DOCXdoc.comments, document-wideawait doc.getCommentThreads(pageIndex) returns threads rendered on that pagePage-render CSS pixels
PPTXpresentation.getComments(slideIndex)Drawing-element bounds from getElementBoundsByIds(); classic and slide anchors retain authored pointsSlide EMUs; scale them to the rendered canvas
XLSXawait workbook.getComments(sheetIndex)Each record has a cellRef; getCellViewportRect() resolves it only for the current sheetCurrent Viewer viewport CSS pixels

getSelectionContext() includes the selected comment thread in DOCX and PPTX, and comments attached to selected XLSX cells.

Built-in or custom

Use the built-in Viewer UI when its format-specific presentation is enough. DOCX and PPTX ScrollViewer, and XlsxViewer, keep comments aligned while the file scrolls or zooms.

The Viewer owns its built-in presentation. It renders the default cards or popup, markers, highlights, and their scroll and zoom behavior.

The application owns custom product behavior. Use detached comment records for application-specific lists, filtering, search, export, or virtualization. Call goToComment() to reveal and highlight the authored target; use geometry APIs only when custom UI must remain attached to authored content.

Application-owned list, Viewer-owned target

Switch between DOCX, XLSX, and PPTX. Each example keeps the list outside the document surface while goToComment() reveals and highlights the authored target.

sample-1.docx

Loading sample-1.docx…

import { DocxDocument, DocxScrollViewer } from '@silurus/ooxml/docx';

const document = await DocxDocument.load(source);
const viewer = DocxScrollViewer.fromDocument(container, document, {
  comments: { cards: false, markers: false },
});

// addRow(label, onSelect) creates an application-owned list row.
document.comments
  .filter((comment) => comment.parentId === undefined)
  .forEach((comment) => addRow(comment.text, () =>
    viewer.goToComment(comment.id, { behavior: 'smooth' })
  ));

const destroy = () => {
  viewer.destroy();
  document.destroy();
};

Custom UI with primitive APIs

Start with source records at the format's natural scope: the DOCX document, a PPTX slide, or an XLSX sheet. Add surface geometry only when custom UI must stay attached to rendered content.

// Source records for an application-owned list, search, or export.
const docxComments = docxDocument.comments;
const pptxComments = presentation.getComments(slideIndex);
const xlsxComments = await workbook.getComments(sheetIndex);

DOCX comments are stored for the document, not authored as page-owned records. getCommentThreads(pageIndex) resolves the occurrences created by layout; a range that crosses pages can therefore appear in more than one page result. PPTX text-range anchors currently resolve to their containing element bounds, and an unresolved modern element anchor is not guessed from its local offset. The rendering functions in these examples are application code.

Canvas content needs an accessible transcript or text layer. The complete example includes an accessible comment transcript; a production document viewer must also provide access to the document text itself.

API references

Look up each format's comment records, anchors, geometry, and Viewer options.