Skip to content

Repository files navigation

pptx

Composable primitives for viewing and editing PowerPoint presentations in the browser. Unstyled, accessible, and entirely yours to build on.

layout

Documentation

Visit pptx.diceui.com to view the full documentation.

Packages

Package Description
@diceui/pptx Composable primitives for viewing and editing PowerPoint presentations in the browser
@diceui/pptx-core PPTX engine for parsing, rendering, editing, and saving PowerPoint presentations in the browser

Quick start

# React
npm install @diceui/pptx

# Core only (no React dependency)
npm install @diceui/pptx-core

Viewer

import * as Presentation from "@diceui/pptx";

export function Viewer({ file }: { file: File }) {
  return (
    <Presentation.Root file={file}>
      <Presentation.ThumbnailList />
      <Presentation.Viewport>
        <Presentation.Slide />
      </Presentation.Viewport>
    </Presentation.Root>
  );
}

Viewer with editing

import * as Presentation from "@diceui/pptx";

export function Editor({ file }: { file: File }) {
  return (
    <Presentation.Root file={file} readOnly={false}>
      <Presentation.ThumbnailList />
      <Presentation.Viewport autoFit>
        <Presentation.Slide>
          <Presentation.Selection />
        </Presentation.Slide>
      </Presentation.Viewport>
    </Presentation.Root>
  );
}

Core only (no React)

import { buildPresentation, readPptx, renderSlide } from "@diceui/pptx-core";

const files = await readPptx(arrayBuffer);
const presentation = buildPresentation(files);
const slide = presentation.slides[0];
const handle = renderSlide(presentation, slide);

document.body.appendChild(handle.element);

// When done
handle.dispose();

React API

Presentation.Root

The context provider. Accepts a File, Blob, ArrayBuffer, or Uint8Array as file.

Presentation.Viewport

Scrollable canvas area. Renders the active slide scaled to fit.

Presentation.Slide

Renders the active slide. Must be inside Presentation.Viewport.

Presentation.Selection

Editing overlay. Enables drag-to-move, resize (with Shift for aspect-ratio lock), inline text editing, multi-select, marquee selection, and keyboard shortcuts. Must be placed inside Presentation.Slide (as its child) so it can overlay the slide surface.

Interaction model:

Action Description
Click text box / placeholder Select + enter text mode
Click regular shape Select
Double-click regular shape Enter text mode
Type while shape selected Enter text mode
Drag shape Move
Shift + drag shape Move along one axis, the one the drag favors
Drag border of text box Move while keeping text mode
Drag resize handle Resize, applied to every selected shape
Shift + drag corner handle Resize preserving aspect ratio
Ctrl/Cmd+A Select all
Shift/Ctrl/Cmd+click Toggle shape in selection
Drag empty canvas Marquee select
Shift + drag empty canvas Marquee select, adding to the current selection
Delete / Backspace Delete selected shape(s)
Arrow keys Nudge (1 px; Shift = 10 px)
Ctrl/Cmd+Z Undo
Ctrl/Cmd+Y / Ctrl/Cmd+Shift+Z Redo
Escape Deselect / exit text mode

Undo and redo are the exception: they are opt-in via undoRedoShortcuts. Everything else in the table is always bound.

Presentation.ThumbnailList

Scrollable list of slide thumbnails. Each ThumbnailItem is mounted immediately, while its preview is rendered lazily as it approaches the viewport and cached. Compose your own item with Presentation.ThumbnailItem, Presentation.ThumbnailItemNumber, and Presentation.ThumbnailItemPreview, or render it childless for the default.

Presentation.Error / Presentation.Loading

Slot components for custom loading and error states.

Presentation.Provider

Optional. Root creates its own store, so this is only needed when you want to own the store and drive it from outside the tree.

const store = useCreatePresentationStore();

<Presentation.Provider store={store}>
  <Presentation.Root file={file}>{/* ... */}</Presentation.Root>
</Presentation.Provider>;

Hooks

const { presentation, status } = usePresentation();
const { slide } = useSlide();
const { zoom, isAutoFit, setZoom, setAutoFit } = useZoom();
const { canUndo, canRedo, isDirty, undo, redo } = useHistory();
const store = useCreatePresentationStore();

Edit operations (core)

All mutations go through store.edit(operation) and support undo/redo via store.undo() / store.redo().

Operation Description
setTextRun Replace a single text run's content
setTextBody Replace all paragraphs and runs in a shape
setNodeTransform Move / resize a shape
setSolidFill Change a shape's fill color
deleteNode Delete a shape from a slide
moveSlide Reorder slides
duplicateSlide Duplicate a slide
deleteSlide Delete a slide
batch Group multiple operations into one undoable step

Development

pnpm install
pnpm dev          # starts apps/docs on http://localhost:3000
pnpm build        # build all packages
pnpm test         # run all tests
pnpm typecheck    # TypeScript type check
pnpm check        # lint + typecheck + format (oxlint + tsc + oxfmt)

Project structure

pptx/
├── apps/
│   ├── docs/              # Next.js docs + interactive playground
│   └── video/             # Remotion video renderer
└── packages/
    ├── core/              # @diceui/pptx-core (OOXML parse, render, edit, save)
    ├── react/             # @diceui/pptx (React primitives)
    ├── ui/                # @pptx/ui (shared shadcn/ui components)
    ├── e2e/               # @diceui/pptx-e2e (visual regression tests)
    └── config/            # Shared TypeScript / build config

OOXML support

See packages/core/OOXML-SUPPORT.md for a detailed feature matrix against ECMA-376.

Credits

  • pptx-renderer (Apache-2.0): the parser was originally derived from this work and has been substantially modified, extended, and refactored.
  • LibreOffice (MPL-2.0): the predefined table style data (packages/core/src/renderer/table-style.ts) is derived from predefined-table-styles.cxx.

The embedded font decoder (packages/core/src/fonts/mtx/) is an original implementation of the W3C MTX and EOT Member Submissions. See PROVENANCE.md.

License

Apache-2.0, except for the files noted below.

  • The predefined table style data (packages/core/src/renderer/table-style.ts) stays under MPL-2.0, as marked in its file header.
  • The fonts embedded in the sample decks under apps/video/public/ and packages/e2e/fixtures/ are licensed under OFL-1.1.

See NOTICE for the full third-party attributions.

About

Composable primitives for viewing and editing PowerPoint presentations in the browser. Unstyled, accessible, and entirely yours to build on.

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages