MeldUI

Document Viewer: Theming

Tailwind dark mode integration, MeldUI primitives used internally, and CSS class override points.

DocumentViewer is built entirely from MeldUI primitives, so it inherits your app’s Tailwind v4 theme automatically. No additional theme configuration is required.

Dark mode

The viewer chrome adapts to dark mode via dark: Tailwind classes on every internal element. Add class="dark" to a parent (or <html>) and the entire toolbar, panels, popovers, and overlay surfaces flip.

<template>
  <div :class="darkMode ? 'dark' : ''">
    <DocumentViewer source="/doc.pdf" wasm-url="/pdfium.wasm" />
  </div>
</template>

What’s themed vs. what isn’t

ElementThemed
Toolbar background, buttons, icons, dividers✅ via bg-background / text-foreground
Side panel chrome (header, close button, list rows)
Search popover, highlight tooltip, comment form, comment marker
Annotations panel rows + reply form
The PDF page itself❌ The page is rendered by PDFium with the document’s original page colour (typically white) — EmbedPDF does not invert page colours. For a dark-aware reader, add a wrapper with bg-muted/30 to soften the contrast with the rest of the app

MeldUI primitives in use

Every UI element inside DocumentViewer is composed from MeldUI primitives so styling overrides naturally inherit. The internals use:

PrimitiveUsed by
ButtonEvery toolbar button, search case / whole-word toggles, comment form actions, reply submit
PopoverSearch popover
DropdownMenuZoom presets, mobile overflow menu
TooltipHighlight tooltip wrapper, button hover labels
TextareaReply form (the comment-create form uses a raw <textarea>)

Override the variants via your Tailwind theme — see Theming guide (Getting Started).

CSS class override points

The viewer’s root carries class="document-viewer" and data-document-viewer. Internal parts use unprefixed semantic classes; you can target them in your global CSS without prefix gymnastics.

/* Larger toolbar buttons just for the viewer */
.document-viewer .viewer-toolbar button {
  padding: 0.5rem 0.75rem;
}

/* Custom border around the annotated PDF page */
.document-viewer .pdf-page {
  box-shadow:
    0 0 0 1px theme(colors.border),
    0 4px 12px theme(colors.shadow / 0.1);
}

/* Brand-coloured highlight tooltip */
.document-viewer .highlight-tooltip {
  --background: theme(colors.brand.50);
}

The full list of internal classes is documented in Customization → CSS class overrides.

Per-instance class prop

For one-off styling, pass class directly:

<DocumentViewer class="rounded-xl border shadow-lg" source="/doc.pdf" wasm-url="/pdfium.wasm" />

The prop merges onto the root via cn(), so Tailwind utility conflicts resolve in your favour.

Highlight palette

The 5 default highlight colours live in the exported HIGHLIGHT_COLORS constant, and the floating tooltip’s swatches always render from it:

import { HIGHLIGHT_COLORS } from '@meldui/vue'
// Yellow #FFCD45, Green #92E89E, Blue #8FCFEF, Pink #FFA0BD, Purple #C8A5DD

featureConfig.annotations.defaultTools exists on the type as the intended palette-override hook, but it is not yet applied by the viewer — the swatch palette is currently fixed to HIGHLIGHT_COLORS.

Dark-mode caveat: PDF page background

PDFium renders pages with the page’s authored background (typically white). The viewer chrome around the page goes dark, but the page itself stays white. For a fully dark-themed reader you have a few options:

  1. Filter the page — apply filter: invert(1) hue-rotate(180deg) to .pdf-page for a quick (but lossy) inversion.
  2. Reduce contrast — add bg-muted/30 dark:bg-muted/60 around the renderer to soften the white edge.
  3. Accept it — for most professional documents (contracts, reports), preserving the original page colour is the correct default.
/* Option 1: aggressive invert for dark mode */
.dark .document-viewer .pdf-page {
  filter: invert(1) hue-rotate(180deg);
}
.dark .document-viewer .pdf-page img,
.dark .document-viewer .pdf-page canvas {
  filter: invert(1) hue-rotate(180deg);
}

See also