# PPTX Editor: full documentation This file holds the 0.x guides for the @pptx-editor.dev/* packages. Frontmatter is removed and framework tabs become labeled sections. Code samples and other MDX components are kept. The generated API reference is not included. Source of truth: https://www.pptx-editor.dev/docs/0.x API reference: https://www.pptx-editor.dev/docs/0.x/api Package index: https://www.pptx-editor.dev/llms.txt --- # Introduction Source: https://www.pptx-editor.dev/docs/0.x Embed a presentation editor in your React or Vue application. Open `.pptx` bytes, edit slides, and save the presentation in the browser. Use the packaged editor first. Compose its parts when you need custom controls or a different layout. Use the Editing API for server automation. ## Install an editor Install an adapter and the engine: #### React ```bash npm install @pptx-editor.dev/react @pptx-editor.dev/core ``` #### Vue ```bash npm install @pptx-editor.dev/vue @pptx-editor.dev/core ``` Render the editor in a container with a height: #### React ```tsx import { PptxEditor } from '@pptx-editor.dev/react'; import '@pptx-editor.dev/core/styles/editor.css'; export default function App({ bytes }: { bytes: Uint8Array }) { return (
); } ``` #### Vue ```vue ``` To open and save files, continue with the [quickstart](/docs/0.x/quickstart). ## Check packages and licenses | Package | Purpose | License | | --- | --- | --- | | [`@pptx-editor.dev/react`](https://www.npmjs.com/package/@pptx-editor.dev/react) | React adapter: `PptxEditor`, its parts, and hooks | Apache 2.0 | | [`@pptx-editor.dev/vue`](https://www.npmjs.com/package/@pptx-editor.dev/vue) | Vue 3 adapter: `PptxEditor`, its parts, and composables | Apache 2.0 | | [`@pptx-editor.dev/core`](https://www.npmjs.com/package/@pptx-editor.dev/core) | Framework-independent engine: open, cascade, layout, paint, save, and the editor facade | Apache 2.0 | | [`@pptx-editor.dev/i18n`](https://www.npmjs.com/package/@pptx-editor.dev/i18n) | Shared interface strings | Apache 2.0 | | [`@pptx-editor.dev/editor-api`](https://www.npmjs.com/package/@pptx-editor.dev/editor-api) | Presentation automation with an Office.js-shaped API | EigenPal Pro License | | [`@pptx-editor.dev/pro`](https://www.npmjs.com/package/@pptx-editor.dev/pro) | Review, real-time collaboration, and advanced drawing effects as editor modules | EigenPal Pro License | | [`@pptx-editor.dev/pptx-to-pdf`](https://www.npmjs.com/package/@pptx-editor.dev/pptx-to-pdf) | PPTX to PDF on Node.js with the editor's own layout | EigenPal Pro License | All packages release together with one version. The packages that use the EigenPal Pro License permit evaluation. Production use requires a commercial agreement; see each package's `LICENSE.md`. ## Find a task guide | Task | Guide | | --- | --- | | Check feature support and round-trip behavior | [PPTX fidelity](/docs/0.x/pptx-fidelity) | | Change controls, colors, menus, and dialogs | [Customization](/docs/0.x/customization) | | Supply your own fonts | [Fonts](/docs/0.x/customization/fonts) | | Translate the interface | [Language](/docs/0.x/customization/language) | | Set up Vite or Next.js | [Vite](/docs/0.x/frameworks/vite), [Vite with Vue](/docs/0.x/frameworks/vite-vue), [Next.js](/docs/0.x/frameworks/nextjs) | | Use the React adapter | [@pptx-editor.dev/react](/docs/0.x/react) | | Use the Vue adapter | [@pptx-editor.dev/vue](/docs/0.x/vue) | | Automate presentation edits | [Editing API](/docs/0.x/editor-api) | | Add comments or collaboration | [Pro](/docs/0.x/pro) | | Convert a presentation to PDF | [PDF export](/docs/0.x/export/pdf) | | Insert and edit tables | [Tables](/docs/0.x/guides/tables) | | Prepare the host page, and check keyboard and screen reader support | [Accessibility](/docs/0.x/accessibility) | ## Next steps - [Quickstart](/docs/0.x/quickstart): open, edit, and save a `.pptx`. - [Installation](/docs/0.x/installation): check requirements, styles, and bundler setup. --- # Accessibility Source: https://www.pptx-editor.dev/docs/0.x/accessibility The editor gives names, roles, and keyboard support to its controls. The page around the editor is yours. This page tells you what to add to the page, and what the editor provides. ## Prepare the host page The editor renders inside your page. It adds one landmark, the region "Presentation editor" around its viewport. It adds no other page-level structure. Give the page these items: - A `lang` attribute on ``. - A `` that names the page. - One `<main>` landmark that contains the editor. - A page heading (`<h1>`). The heading can be visually hidden. - A label for each control of your own, such as the file input that opens a deck. - A `title` and `allow="fullscreen"` on an `<iframe>` that holds the editor. The slide show asks for full screen (see [Installation](/docs/0.x/installation#embed-in-a-page)). Use this host page structure: ```html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Quarterly review | Deck editor

Quarterly review

``` If your own `
` or `
` is inside the viewport, set `label={false}` on `PptxEditor.Viewport` (`:label="false"` in Vue). The viewport then adds no region, and your landmarks stay at the top level. To change the region name, give `label` a text or a translation key. The demos in `examples/` follow these rules. The [quickstart](/docs/0.x/quickstart) shows the `
` landmark and the file input label. If you build your own controls, keep them accessible. A disabled control stays focusable with `aria-disabled` and tells the user why it is off. See [Customization](/docs/0.x/customization). ## Use the keyboard The editor follows the WAI-ARIA authoring practices. Each composite part, such as the slide, the toolbar, or the slide list, is one Tab stop. The arrow keys move inside it. The chrome shows a focus ring on keyboard focus. ### On the slide The slide is one Tab stop (role `group`). When the slide has focus, these keys apply: | Key | Action | | --- | --- | | Tab, Shift+Tab | Select the next or the previous shape, in z-order. With no selection, Tab selects the backmost shape and Shift+Tab the frontmost. | | Tab on the last shape, Shift+Tab on the first | Clear the selection and move focus out of the slide. The slide never traps focus. | | Enter or F2 | Start to edit the text of the selected shape, with all of its text selected. On a group, Enter selects the shapes in the group. | | A character key | Start to edit the text of the selected shape, and type that character at the end of its text (in the editing mode only). | | Escape | Leave text editing and select the shape. Leave a group and select the group. Otherwise, clear the selection. | | Arrow keys | Nudge the selected shapes by 8 px. Ctrl/Cmd+arrow nudges by 1 px. Shift multiplies the step by 10. | | Delete, Backspace | Delete the selected shapes. | | Ctrl/Cmd+D | Duplicate the selected shapes. | | Ctrl/Cmd+A | Select all shapes, or all text when you edit text. | Inside a group, Tab and Shift+Tab cycle through the shapes of the group. While you edit text, Tab and Shift+Tab change the list level at the start of a list item or across paragraphs. Elsewhere, both keys insert a tab. Enter starts a new item at the same level, also on an empty item. Backspace at the start of a list item removes its bullet or number and keeps its level. The next Backspace joins it to the previous paragraph. Press Escape first to move with Tab again. In a table cell, Tab and Shift+Tab move to the next or the previous cell. See [Tables](/docs/0.x/guides/tables). ### While you edit text | Key | Action | | --- | --- | | Ctrl/Cmd+B, I, U | Bold, italic, underline. | | Ctrl/Cmd+L, E, R, J | Align the paragraph left, center, right, or justified. On selected shapes, align all of their text. | | Ctrl/Cmd+Shift+>, Ctrl/Cmd+Shift+< | The next larger or smaller font size. On selected shapes, all of their text. | | Ctrl/Cmd+], Ctrl/Cmd+[ | Move the paragraph one list level down or up. | | Shift+F3 | Change the case of the selection or of the word at the caret: Capitalize Each Word, UPPER CASE, lower case. | | Ctrl/Cmd+=, Ctrl/Cmd+Shift+= | Subscript, superscript. | | Ctrl/Cmd+\ | Clear the character formatting. | | Ctrl/Cmd+Shift+C, Ctrl/Cmd+Shift+V | Copy and paste the formatting. | | Alt/Ctrl+Left, Alt/Ctrl+Right | Move to the start of the previous word or of the next word. Add Shift to select. | | Alt/Ctrl+Up, Alt/Ctrl+Down | Move to the start of the paragraph, or of the next paragraph. | | Cmd+Up, Cmd+Down, Ctrl/Cmd+Home, Ctrl/Cmd+End | Move to the start or the end of the text. | | Alt/Ctrl+Backspace, Cmd+Backspace | Delete the word before the caret. | | Shift+Enter | Start a new line in the same paragraph. | In right-to-left and mixed-direction text, Left and Right move the caret one place on screen, not in reading order. Alt/Ctrl+Left and Alt/Ctrl+Right move past one word on screen. Cmd+Left and Cmd+Right move to the left or the right edge of the line. Home and End move to the start and the end of the line in reading order, wherever they show on screen. A selection holds the text between its two ends in reading order, so on a mixed-direction line it can show as several highlighted parts. The editor makes no automatic capitals, curly quotes, dashes, or spelling corrections of its own. Mobile keyboards, and systems and browsers that offer such changes, apply them. The editor replaces the text that each change targets. Undo removes the change, together with any text you type right after it. Browser spelling tools and browser extensions that write to the text input change the document in the same way as typing. Many desktop browsers offer no such changes. In those browsers, the editor adds no curly quotes or capitals while you type. AutoCorrect still makes these changes: - `(c)`, `(r)`, and `(tm)` become ©, ®, and ™. - `...` becomes …, and `1/2`, `1/4`, and `3/4` become fractions. - `1.`, `1)`, `*`, or `-` and a space at the start of a paragraph start a numbered or bulleted list. Press Backspace or Ctrl/Cmd+Z right after to keep the typed text. To turn AutoCorrect off, pass `autoCorrect: false` to `createPptxEditor`, set `autoCorrect={false}` on the React editor, or set `:auto-correct="false"` on the Vue editor. This option does not change the system replacements. In the speaker notes field, Ctrl/Cmd+B, I, and U format the text. The other keys in this table and AutoCorrect apply on the slide only. ### Toolbar, menus, and dialogs - The toolbar is one Tab stop. The Left and Right arrow keys, Home, and End move through its controls. In a right-to-left interface, Left and Right change places. - The ribbon tabs are a `tablist`. The Left and Right arrow keys, Home, and End move between tabs. - The menu bar is one Tab stop. Escape closes a menu and keeps focus on its menu bar item. - A popover, such as a color or font picker, returns focus to its trigger on Escape. - A context menu returns focus to where it was on Escape. Shift+F10 and the context menu key open it from the keyboard. - A dialog keeps Tab inside it. Escape closes it, and focus goes back to the control that opened it. ### Slide list and slide sorter The slide list in the rail is one Tab stop. The focused slide is the current slide. | Key | Action | | ------------------------------------------- | ------------------------------------- | | Up, Down (Left, Right in a horizontal rail) | Go to the previous or the next slide. | | Home, End | Go to the first or the last slide. | | Shift+arrow, Shift+Home, Shift+End | Extend the slide selection. | | Ctrl/Cmd+arrow | Move the selected slides. | | Enter, Ctrl+M | Add a slide. | | Delete, Backspace | Delete the selected slides. | | Ctrl/Cmd+D | Duplicate the selected slides. | | Shift+F10, context menu key | Open the slide menu. | In the viewing mode, the slide list keys that change the deck do nothing, and the editor tells why. With sections, the list is a tree: the arrow keys also stop on each section header. Home and End go to the first and the last row, which can be a section header. The slide sorter is one Tab stop. The arrow keys move through the grid of slides. Home and End go to the start and the end of the grid. Enter opens the focused slide. Shift+arrow, Ctrl/Cmd+arrow, Delete, Ctrl/Cmd+D, Ctrl+M, and Shift+F10 work as in the slide list. ### Slide show F5 starts the show from the first slide that is not hidden. Shift+F5 starts it from the current slide. | Key | Action | | --------------------------------------- | ------------------------------ | | Right, Down, Page Down, Space, N, Enter | Next slide | | Left, Up, Page Up, Backspace, P | Previous slide | | Home, End | First or last slide | | A number, then Enter | Go to that slide | | B or `.`, W or `,` | Show a black or a white screen | | Escape | End the show | Tab moves through the buttons of the slide show control bar. ## Hear the editor with a screen reader The editor takes its accessible names from the locale catalog, so they change with the [language](/docs/0.x/customization/language). With the English catalog, a screen reader hears these items: | Where | What the screen reader hears | | --- | --- | | Editor | A region "Presentation editor" that holds the chrome and the slide. | | Slide | The group name "Slide 3 of 12". The name changes when the slide changes. Inside it, the slide text and an image for each picture that has alt text. The image name is the alt text. A decorative picture, or a picture with no alt text, is hidden. | | Shape selection | A polite announcement with the kind and the name of the shape, for example "Shape Title 1, selected". For a picture with alt text, the alt text comes after the name: "Picture Logo, A green leaf, selected". It comes when Tab or a click selects one shape. | | Text editing | The text input "Text of the selected shape", with the description "Shows the text of the current paragraph up to the caret". Its value is that text. | | Table cell | A polite announcement, "Row 2, column 3", when the caret moves to a cell. | | Link in the text | A polite announcement, "Link: https://example.com. Press F6 for its actions." F6 moves focus to the link actions. | | Slide list | A navigation region "Slides" with a list box "Slides". With sections, the list is a tree. Items are "Slide 4", or "Slide 4 (hidden)" for a hidden slide. | | Speaker notes | A region "Speaker notes", with a multiline text box. | | Status bar | A polite announcement, "Slide 3 of 12", when the slide changes. | | Slide show | A modal dialog "Slide show" with the slide text and the picture alt text of the current slide. A polite announcement gives the position, "Slide 3 of 12", at each slide. When you type a number, a status message says "Go to slide 5". | ## Color modes and motion - **Color modes.** Set `colorMode` to `light`, `dark`, or `system`. `system` follows the operating system and updates when it changes. Only the chrome changes. The slide always shows the colors of the file. See [Appearance](/docs/0.x/customization/appearance). - **Reduced motion.** When the operating system asks for reduced motion, the editor stops the loading spinner, the tooltip animation, the press effect of buttons, the slide-in of notices, and the transition of the slide show control bar. - **Forced colors.** In a forced colors (high contrast) mode, the chrome uses the system colors. Selection, pressed and checked controls, focus rings, and disabled controls stay visible. The slide keeps the colors of the file. See [Appearance](/docs/0.x/customization/appearance). - **Slide show motion.** The slide show does not play the animations and transitions of the file. They stay in the file on save. The **Animations** tab of the side panel lists the effects of a slide as text, in play order. ## Known limits These limits apply: - **Alt text of other objects.** Only pictures give their alt text to a screen reader on the slide. Charts, groups, and shapes do not. A picture with a title but no alt text is hidden. - **Text input value.** While you edit text, the text input holds only the paragraph text up to the caret, at most about 200 characters. A screen reader does not read the text after the caret from the input. - **Slide content structure.** The slide is drawn as SVG. A screen reader gets the slide text only as flat text, in z-order. It gets no headings, lists, or reading order. It gets the shape name only when a shape is selected. When more than one shape is selected, it hears no announcement. ## Next steps - [Installation](/docs/0.x/installation): requirements, styles, and how to embed the editor. - [Customization](/docs/0.x/customization): build controls that keep labels and keyboard support. - [Language](/docs/0.x/customization/language): translate the interface and its accessible names. --- # @pptx-editor.dev/core Source: https://www.pptx-editor.dev/docs/0.x/core Core provides the PPTX engine and browser editor. React and Vue add interface components around the same editor contract. ## Install Install the package directly when your application imports its APIs: ```bash npm install @pptx-editor.dev/core ``` Keep one resolved copy of core in your application. The adapters use it as a peer dependency. ## Create an editor This browser helper mounts an editor into an existing element. It returns the instance for your controls and cleanup: ```ts import { createPptxEditor } from '@pptx-editor.dev/core/editor'; import '@pptx-editor.dev/core/styles/editor.css'; export async function mountPresentation(container: HTMLElement, bytes: Uint8Array) { const editor = createPptxEditor({ zoom: 'fit' }); container.classList.add('pptx-editor'); try { editor.attach(container); const result = await editor.load(bytes); if (!result.ok) throw new Error(result.reason); return editor; } catch (error) { editor.destroy(); throw error; } } ``` Give the container a height and available width. Call `editor.destroy()` when your application removes this editor permanently. The core editor does not add a toolbar, slide rail, or menus. Use the adapters for those components. ## Choose an import Use the editor entry point for browser integration. Other entry points expose the engine layers: | Entry point | Use | | ----------------------------------------- | ---------------------------------------------------- | | `@pptx-editor.dev/core` | Editor exports. | | `@pptx-editor.dev/core/editor` | Editor creation, commands, fonts, and image exports. | | `@pptx-editor.dev/core/contracts` | Shared editor, snapshot, and command types. | | `@pptx-editor.dev/core/store` | Package read/write and document transactions. | | `@pptx-editor.dev/core/cascade` | Slide inheritance and theme resolution. | | `@pptx-editor.dev/core/layout` | Geometry and text layout without the DOM. | | `@pptx-editor.dev/core/output` | SVG paint from layout records. | | `@pptx-editor.dev/core/automation` | Automation hosts. | | `@pptx-editor.dev/core/styles/editor.css` | Editor styles. | For server-side document editing, start with the [Editing API](/docs/0.x/editor-api). ## Read state and run commands Use `snapshot()` for state and `exec()` for edits. This helper adds a slide when the command is available: ```ts import type { Editor } from '@pptx-editor.dev/core/contracts'; export function addSlide(editor: Editor) { const command = { type: 'addSlide' } as const; const allowed = editor.can(command); if (!allowed.ok) return allowed; return editor.exec(command); } ``` Check the final result even after `can()`. Commands can be refused when their target is unavailable. For a large target, `can()` makes a shorter check. On a selection of more than 250 shapes, the commands that arrange shapes (`order`, `alignObjects`, `distributeObjects`, `flipObjects`, `duplicate`, `delete`, `group`, and `ungroup`) get a check of the editing mode only, and their argument is not checked. Other commands are checked on the first 250 shapes, and a refusal there gets the full check. A command that passes on the first 250 shapes can still be refused by `exec()`. The `duplicate` command also counts a selection of more than 20,000 XML nodes as large, and the `applyLayout` and `resetSlides` commands a named slide of more than 20,000 XML nodes. The `addSlide` and `addSection` commands always get the full check. While you type, the formatting answers of the text box hold until 300 ms after the last key. `exec()` makes the full check and returns the refusal reason. | Member | Purpose | | ------------------------------ | ------------------------------------------------------- | | `snapshot()` | Read the presentation and local view state. | | `subscribe(listener)` | Observe state changes; returns an unsubscribe function. | | `can(command)` | Check whether a command can run. | | `exec(command)` | Run a command and inspect its result. | | `load(bytes, options?)` | Open a presentation asynchronously. | | `save()` | Return PPTX bytes synchronously, or `null`. | | `attach(element)` / `detach()` | Mount or remove the surface. | | `destroy()` | Release the editor and its resources. | ## Choose an event Use `onEditorEvent(editor, name, handler)` to observe a specific change. It returns an unsubscribe function. | Event | Payload and trigger | | ----------------- | -------------------------------------------------------------------------- | | `change` | Snapshot after an edit, completed or failed load, or read-only transition. | | `selectionChange` | Snapshot after selection, current slide, or pending slide count changes. | | `rejection` | Refused edit and its snapshot. | | `openFailure` | Refused file and its snapshot. | Use `subscribe()` when you also need zoom or other view changes. Dispose every subscription when its consumer unmounts. ## See also - [Editor mount modes](/docs/0.x/core/mount-modes) - [Engine architecture](/docs/0.x/core/architecture) - [Load and save presentations](/docs/0.x/guides/loading-and-saving) --- # Engine architecture Source: https://www.pptx-editor.dev/docs/0.x/core/architecture One document store holds the presentation. The browser editor, adapters, and automation hosts apply edits through that store. ## Follow a presentation The engine reads PPTX bytes into an Open Packaging Conventions (OPC) package. It resolves slide inheritance before laying out shapes and text: ```mermaid flowchart LR Bytes[PPTX bytes] --> Store[Document store] Store --> Cascade[Slide inheritance and theme] Cascade --> Layout[Geometry and text layout] Layout --> Paint[SVG paint] Store --> Saved[Saved PPTX bytes] Commands[Editor commands] --> Store ``` Parsing, inheritance resolution, and layout do not depend on the DOM. Browser painting consumes layout records rather than calculating a separate layout. ## Choose the right layer Use editor commands for interactive features. Use the [Editing API](/docs/0.x/editor-api) for batch automation on a server or live editor. Use lower-level store APIs only when you need package-level integration. Write document changes through `PptxDocumentStore` operations. Editing the rendered DOM does not change the presentation. React and Vue read snapshots and dispatch commands. They do not keep a separate editable document model. ## Preserve document content The package model retains content that the editor does not interpret. Rendering and editing support are distinct from preservation during save. Consult [PPTX fidelity](/docs/0.x/pptx-fidelity) for feature-level evidence and rendering limits. Do not infer edit support from visible content alone. ## Use consistent fonts Text layout uses font metrics. Configure fonts before comparing browser output with PDF output. Missing or substituted fonts can change line breaks and shape text. For host font loading, see [Fonts](/docs/0.x/customization/fonts). For server output, see [PDF export](/docs/0.x/export/pdf). ## See also - [Core](/docs/0.x/core) - [Editing API](/docs/0.x/editor-api) - [PPTX fidelity](/docs/0.x/pptx-fidelity) --- # Editor mount modes Source: https://www.pptx-editor.dev/docs/0.x/core/mount-modes Create one editor per presentation session. Mount its surface with `attach(element)` and remove it with `detach()`. ## Move between containers `attach()` creates the surface in the supplied element. A second call replaces the previous surface: ```ts import type { Editor } from '@pptx-editor.dev/core/contracts'; export function moveEditor(editor: Editor, destination: HTMLElement) { editor.detach(); destination.classList.add('pptx-editor'); editor.attach(destination); editor.focus(); } ``` Detaching removes the surface. It keeps the document, selection state, and undo history in the editor instance. Use this pattern for containers in the same browser document. Do not assume that an iframe or another window has the same behavior. ## Keep the container sized Put `class="pptx-editor"` on the mount element or an ancestor to scope editor styles. Give the mount element an explicit size. For example, use this CSS with a host element whose class is `presentation-surface`: ```css .presentation-surface { width: 100%; height: 600px; min-width: 0; overflow: auto; } ``` Call `setZoom('fit')` to follow the available space. The React and Vue viewport components provide the adapter layout classes. ## Dispose thumbnail containers `renderThumbnail()` paints a slide and returns a disposer. Request deferred paint for a long slide list: ```ts import type { Editor } from '@pptx-editor.dev/core/contracts'; export function mountThumbnail(editor: Editor, slideIndex: number, container: HTMLElement) { return editor.renderThumbnail(slideIndex, container, { defer: true }); } ``` Call the returned function when you remove the thumbnail. Without `defer`, its first paint is synchronous. ## End the session Call `destroy()` when the editor is no longer needed. Dispose application subscriptions and thumbnail registrations with their owners. Adapters own their editor lifecycle. Do not destroy an adapter-owned instance from a child control. ## See also - [Core](/docs/0.x/core) - [Layout](/docs/0.x/customization/layout) - [Long decks](/docs/0.x/guides/long-decks) --- # Overview Source: https://www.pptx-editor.dev/docs/0.x/customization Customize your PPTX editor to fit your application. Each guide lists the supported options and shows React and Vue reference code. Start with props and CSS, then compose parts when you need a different layout. ## Live examples The demo app in [`examples/vite/`](https://github.com/eigenpal/pptx-editor/tree/main/examples/vite) composes these parts into a complete editor. In a checkout of the repository, run `bun install` and `bun run dev`, then open `http://localhost:5274/`. ## Design principles The PPTX editor separates presentation editing from interface controls. Every part reads the same editor state and runs the same commands as the packaged editor. Start with the smallest change that fits your application: - **Appearance:** Set `--doc-*` CSS properties on `.acme-theme .pptx-editor`, where `.acme-theme` is a wrapper around `PptxEditor.Root`. Use `className` and `data-active` or `data-disabled` to style controls. Set `colorMode` for dark controls. - **Composition:** Use `PptxEditor.Root`, `.Viewport`, `.Content`, and the panes to arrange the interface. Keep every part inside `Root`. - **Individual controls:** Use named parts such as `PptxEditor.Toolbar.Bold`. Replace an icon with `icon`, or supply your own element with `asChild`. - **Control sets:** Override a slot in place, use `hidden` to remove it, or set `preset={false}` to compose the toolbar, a menu, or a dialog yourself. - **Custom behavior:** Use `useEditorCommand(slotId)` for command state and execution. Use `useEditorState(selector)` for the state your control shows. Keep the slide selection when you build custom controls: a chrome `mousedown` calls `preventDefault()`, except on inputs, selects, and text areas. Keep labels, keyboard support, and disabled reasons accessible. A disabled control stays focusable with `aria-disabled` and tells the user why it is disabled. Hiding a control changes the interface only. The operation keeps working from menus, keyboard shortcuts, and the API. ## Customization guides Set interface colors, spacing, and dark mode. Place the toolbar, the menu bar, the slide rail, the notes, and panels. Choose controls, replace icons, and add your own buttons. Use tabs and contextual tabs, and change each tab with toolbar parts. Choose menu bar and context menu rows. Replace dialog parts, and keep draft state, validation, and focus. Load font bytes, choose font sources, and replace fonts in place. Translate the interface with a locale catalog, and translate your own controls. ## Choose the API level | Level | Use | | --- | --- | | Props and CSS tokens | Change labels, colors, and color mode. | | Named parts | Arrange controls and replace selected elements. | | Hooks and composables | Connect application controls to editor state and commands. | | Modules | Add review, collaboration, or drawing effects (glow, inner shadow, reflection, soft edge) with [`@pptx-editor.dev/pro`](https://www.npmjs.com/package/@pptx-editor.dev/pro) (EigenPal Pro License). Pass them in the `modules` prop of `PptxEditor` or its root; the editor reads it once, when it is created. See [Capability modules](/docs/0.x/react/props#capability-modules) for an example. | ## React and Vue reference Compose the same workspace in either adapter: #### React ```tsx import { PptxEditor } from '@pptx-editor.dev/react'; import '@pptx-editor.dev/core/styles/editor.css'; export function DeckEditor({ bytes }: { bytes: Uint8Array }) { return (
); } ``` #### Vue ```vue ``` The `deck-workspace` classes are your own layout CSS. [Workspace layout](/docs/0.x/customization/layout#workspace-layout) lists it. The adapters expose the same editing commands and components. Vue uses named exports such as `PptxEditorToolbar` for React's `PptxEditor.Toolbar`. ## More control See the API reports for [`@pptx-editor.dev/react`](https://github.com/eigenpal/pptx-editor/blob/main/docs/api/react/index.api.md) and [`@pptx-editor.dev/vue`](https://github.com/eigenpal/pptx-editor/blob/main/docs/api/vue/index.api.md) for every part and type. ## See also - [React composition](/docs/0.x/react/composition) - [Vue composition](/docs/0.x/vue/composition) - [Layout](/docs/0.x/customization/layout) --- # Appearance Source: https://www.pptx-editor.dev/docs/0.x/customization/appearance Put a theme class on a wrapper around `PptxEditor.Root`, and set `--doc-*` properties on `.acme-theme .pptx-editor`. Each `.pptx-editor` scope declares its own defaults, so a property set on the wrapper alone does not reach the chrome. Load your CSS after the editor stylesheet. Set `colorMode` on `PptxEditor.Root` for dark controls. Only the chrome changes: the slide keeps the colors that the file defines, in both modes. ## Apply an application color theme PPTX Editor uses the same `--doc-*` token names as DOCX Editor, so one override themes both products. Put your theme class on an element around `PptxEditor.Root`, and scope the tokens to every `.pptx-editor` inside it. Dialogs render outside `PptxEditor.Viewport` with their own `.pptx-editor` scope, so a rule on the viewport alone does not reach them. ```css .acme-theme .pptx-editor, .acme-theme .pptx-editor.dark { --doc-primary: var(--app-brand); --doc-primary-light: var(--app-brand-surface); --doc-on-primary: var(--app-on-brand); --doc-focus-ring: var(--app-focus-ring); } ``` Define light and dark application values for the mapped tokens. The shared rule keeps both editor themes connected to your application's active palette. ## Style your controls Keep CSS under your wrapper class. These tokens and selectors work in both frameworks. ```css .acme-theme .pptx-editor { --doc-font-ui: 'Inter', system-ui, sans-serif; --doc-radius-surface: 16px; --doc-radius-control: 8px; --doc-dialog-radius: 16px; --doc-dialog-padding: 24px; } .acme-theme .pptx-toolbar__button[data-active] { background: var(--doc-primary-light); } .acme-theme .pptx-toolbar__button[data-disabled] { opacity: 0.5; } ``` A part that you build yourself gets the tokens from the `.pptx-editor` scope. Inside `PptxEditor.Viewport`, the viewport gives that scope. Outside the viewport, put the classes from `useScopeClassName()` on the root element of your part. The hook returns `''` inside the viewport, and `'pptx-editor '` or `'pptx-editor dark '` outside it: ```tsx import { useScopeClassName } from '@pptx-editor.dev/react'; export function AcmePanel() { return