@aixa-transformation/pptx-viewer 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +369 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +18 -0
  4. package/README.md +249 -0
  5. package/dist/GLTFLoader-CV33YWNT.js +2613 -0
  6. package/dist/GLTFLoader-FQJ2I67K.mjs +2611 -0
  7. package/dist/Model3DScene-5ODZLKJM.mjs +49 -0
  8. package/dist/Model3DScene-VLHFNN5B.js +51 -0
  9. package/dist/OrbitControls-HI6CI76Z.mjs +3 -0
  10. package/dist/OrbitControls-XGY7XEC6.js +12 -0
  11. package/dist/SmartArt3DScene-3FL5JELA.mjs +333 -0
  12. package/dist/SmartArt3DScene-7IZ3IJYV.js +335 -0
  13. package/dist/SurfaceChart3DScene-C6GQQQB7.mjs +77 -0
  14. package/dist/SurfaceChart3DScene-KHMGQAGP.js +79 -0
  15. package/dist/chunk-2TOLRBFU.js +27629 -0
  16. package/dist/chunk-2X72MOPZ.mjs +2796 -0
  17. package/dist/chunk-6DZX6EAA.mjs +33 -0
  18. package/dist/chunk-AD2CLKY6.js +92338 -0
  19. package/dist/chunk-CUUYYYC5.js +2800 -0
  20. package/dist/chunk-DAKELFNP.js +915 -0
  21. package/dist/chunk-F2HFXS2Z.mjs +19063 -0
  22. package/dist/chunk-F3LO2NKI.mjs +913 -0
  23. package/dist/chunk-HNI6JYAI.js +34591 -0
  24. package/dist/chunk-IKBO6CZC.js +2 -0
  25. package/dist/chunk-KVM4DBEU.mjs +91768 -0
  26. package/dist/chunk-MOEXMRVK.js +19220 -0
  27. package/dist/chunk-QGM4M3NI.js +37 -0
  28. package/dist/chunk-SQY54X47.js +43506 -0
  29. package/dist/chunk-T5U6P2JH.mjs +1 -0
  30. package/dist/chunk-TB5ZWNMX.mjs +34577 -0
  31. package/dist/chunk-W5V6CEFL.mjs +43064 -0
  32. package/dist/chunk-XAVVR6OX.mjs +27204 -0
  33. package/dist/chunk-Y6FQDUJU.js +1160 -0
  34. package/dist/chunk-YI3G35EC.mjs +1076 -0
  35. package/dist/dist-LQJHTLHL.mjs +2 -0
  36. package/dist/dist-NVA3FEUV.js +2275 -0
  37. package/dist/i18n.d.ts +2 -0
  38. package/dist/i18n.js +19 -0
  39. package/dist/i18n.mjs +2 -0
  40. package/dist/index.d.ts +44 -0
  41. package/dist/index.js +135 -0
  42. package/dist/index.mjs +6 -0
  43. package/dist/internals.d.ts +1 -0
  44. package/dist/internals.js +311 -0
  45. package/dist/internals.mjs +6 -0
  46. package/dist/pptx-viewer.css +2 -0
  47. package/dist/presentation.d.ts +1 -0
  48. package/dist/presentation.js +11 -0
  49. package/dist/presentation.mjs +2 -0
  50. package/dist/three.module-HOXVV2KF.mjs +2 -0
  51. package/dist/three.module-QSJWIYNI.js +1771 -0
  52. package/dist/viewer/index.d.ts +1 -0
  53. package/dist/viewer/index.js +76 -0
  54. package/dist/viewer/index.mjs +7 -0
  55. package/dist/y-webrtc-DFUKFWCA.mjs +4279 -0
  56. package/dist/y-webrtc-RRACJ6WX.js +4284 -0
  57. package/dist/y-websocket-T5R5YGVE.mjs +378 -0
  58. package/dist/y-websocket-WMSHYIGX.js +384 -0
  59. package/package.json +141 -0
package/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # pptx-react-viewer
2
+
3
+ [![npm version](https://img.shields.io/npm/v/pptx-react-viewer.svg)](https://www.npmjs.com/package/pptx-react-viewer)
4
+ [![license](https://img.shields.io/npm/l/@aixa-transformation/pptx-viewer.svg)](https://github.com/Aixa-Transformation/Aixa-PptxViewer/blob/main/LICENSE)
5
+ [![types](https://img.shields.io/npm/types/pptx-react-viewer.svg)](https://www.npmjs.com/package/pptx-react-viewer)
6
+
7
+ > A drop-in **React** component that turns a `.pptx` file into a fully interactive PowerPoint: **view, edit, present, collaborate, and export**, entirely in the browser.
8
+
9
+ ![Selecting, dragging, and resizing a slide element in the React demo](https://raw.githubusercontent.com/Aixa-Transformation/Aixa-PptxViewer/main/.github/assets/packages/react-demo.gif)
10
+
11
+ Slides render with real **HTML/CSS** (not `<canvas>`), so text stays crisp at any zoom, is selectable and screen-reader accessible, and every element is directly editable. The parsing/editing engine ([`pptx-viewer-core`](https://www.npmjs.com/package/pptx-viewer-core)) is **bundled in**, so you install just one package.
12
+
13
+ <samp>**[📦 npm](https://www.npmjs.com/package/@aixa-transformation/pptx-viewer)** · **[Source](https://github.com/Aixa-Transformation/Aixa-PptxViewer)** · **[🧩 Core SDK](https://www.npmjs.com/package/pptx-viewer-core)**</samp>
14
+
15
+ ---
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install pptx-react-viewer
21
+ ```
22
+
23
+ Then add the React peer dependencies your app uses:
24
+
25
+ ```bash
26
+ npm install react react-dom framer-motion lucide-react react-icons jspdf jszip fast-xml-parser i18next react-i18next
27
+ ```
28
+
29
+ > The package is named **`pptx-react-viewer`** on npm. `pptx-viewer-core` (the engine) is **bundled in**, so you don't install it separately unless you want to call the SDK directly.
30
+ > **Optional:** `three` (3D models/charts, 3D SmartArt) and `yjs` / `y-websocket` / `y-webrtc` (real-time collaboration) are declared as `optionalDependencies`, so npm installs them automatically when possible; the features degrade gracefully if they're absent.
31
+
32
+ ## Quick start
33
+
34
+ ```tsx
35
+ import { useState } from 'react';
36
+ import { PowerPointViewer } from 'pptx-react-viewer';
37
+ // Not using Tailwind? Import the bundled stylesheet once at your app entry:
38
+ import 'pptx-react-viewer/styles';
39
+
40
+ export default function App() {
41
+ const [content, setContent] = useState<Uint8Array | null>(null);
42
+
43
+ // Load any .pptx as bytes (fetch, <input type="file">, drag-drop, …)
44
+ const onPick = (e: React.ChangeEvent<HTMLInputElement>) =>
45
+ e.target.files?.[0]?.arrayBuffer().then((buf) => setContent(new Uint8Array(buf)));
46
+
47
+ return (
48
+ <div style={{ height: '100vh' }}>
49
+ {content ? (
50
+ <PowerPointViewer content={content} canEdit />
51
+ ) : (
52
+ <input type='file' accept='.pptx' onChange={onPick} />
53
+ )}
54
+ </div>
55
+ );
56
+ }
57
+ ```
58
+
59
+ The component fills its parent, so give the parent a height. That's the whole setup: open a file and you have a working viewer/editor.
60
+
61
+ To read the edited presentation back out as bytes, pass a `ref` and call `getContent()`:
62
+
63
+ ```tsx
64
+ import { useRef } from 'react';
65
+ import { PowerPointViewer, type PowerPointViewerHandle } from 'pptx-react-viewer';
66
+
67
+ const viewerRef = useRef<PowerPointViewerHandle>(null);
68
+
69
+ // <PowerPointViewer ref={viewerRef} content={content} canEdit />
70
+ const bytes = await viewerRef.current?.getContent(); // Uint8Array of a valid .pptx
71
+ ```
72
+
73
+ ## Features
74
+
75
+ | Feature | Description |
76
+ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
77
+ | **View** | Render slides with 16 element types: shapes, text, images, tables, 23 chart types, SmartArt, connectors, media, ink, OLE, 3D models, zoom |
78
+ | **Edit** | Insert/move/resize/delete elements, edit text inline, modify styles, manage slides |
79
+ | **Present** | Fullscreen slideshow with 40+ animations, 46 transitions (including morph), speaker notes, presenter view with timer |
80
+ | **Export** | PNG/JPEG/SVG/PDF/GIF/video slide export, save-as PPTX |
81
+ | **Collaborate** | Real-time multi-user editing (powered by Yjs) with live presence, remote cursors, and user avatars |
82
+ | **Print** | Print dialog with handout layouts and notes page formatting with overflow pagination |
83
+ | **Annotate** | Pen/highlighter/laser pointer tools during presentations |
84
+ | **Find & Replace** | Cross-slide text search with regex support |
85
+ | **Accessibility** | Keyboard navigation, alt-text audit panel, screen reader support |
86
+ | **3D** | GLB/GLTF model rendering via Three.js, 3D surface charts, CSS 3D shape/text extrusion |
87
+
88
+ ---
89
+
90
+ ## API reference
91
+
92
+ ### `PowerPointViewer` props
93
+
94
+ | Prop | Type | Default | Description |
95
+ | ---------------------- | --------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- |
96
+ | `content` | `Uint8Array` | required | Raw .pptx file bytes |
97
+ | `filePath` | `string` | n/a | Optional file path (for display and autosave recovery) |
98
+ | `fileName` | `string` | n/a | Display name of the open document, shown in the title bar |
99
+ | `className` | `string` | n/a | Class applied to the root element |
100
+ | `canEdit` | `boolean` | `false` | Enable editing mode |
101
+ | `fonts` | `ViewerFontSource[]` | n/a | Licensed font sources supplied by the host application |
102
+ | `authorName` | `string` | n/a | Author name for comments/annotations and collaboration presence |
103
+ | `collaboration` | `CollaborationConfig` | n/a | Yjs real-time collaboration config (server URL, room, role) |
104
+ | `shareDefaults` | `{ roomId?, userName?, serverUrl? }` | n/a | Seed values for the Share dialog fields |
105
+ | `smartArt3D` | `boolean` | `false` | Opt-in Three.js 3D SmartArt renderer (needs the optional `three` dependency; falls back to SVG without it) |
106
+ | `onOpenFile` | `() => void` | n/a | Host override for File > Open; bypasses the built-in file picker |
107
+ | `onContentChange` | `(content: Uint8Array) => void` | n/a | Called with freshly serialised `.pptx` bytes when the content changes |
108
+ | `onDirtyChange` | `(isDirty: boolean) => void` | n/a | Called when dirty state changes |
109
+ | `onActiveSlideChange` | `(index: number) => void` | n/a | Called when the active slide changes |
110
+ | `onModeChange` | `(mode: ViewerMode) => void` | n/a | Called when the viewer mode changes |
111
+ | `onZoomChange` | `(zoom: number) => void` | n/a | Called when the zoom level changes |
112
+ | `onSelectionChange` | `(ids: string[]) => void` | n/a | Called when element selection changes |
113
+ | `onSlideCountChange` | `(count: number) => void` | n/a | Called when the total slide count changes |
114
+ | `onStartCollaboration` | `(config: CollaborationConfig) => void` | n/a | Called when the user starts a collaboration session from the Share dialog |
115
+ | `onStopCollaboration` | `() => void` | n/a | Called when the collaboration session stops |
116
+ | `theme` | `ViewerTheme` | n/a | Theme configuration for customising colours, radius, and CSS vars |
117
+ | `hiddenActions` | `ToolbarActionId[]` | n/a | Hide individual toolbar buttons and/or ribbon tabs (e.g. `['share', 'broadcast']`) instead of the whole toolbar; omitted hides nothing |
118
+ | `defaultThemeKey` | `string` | n/a | Initial File > Options > Appearance selection when no persisted preference exists |
119
+ | `availableThemes` | `ThemeCatalogEntry[]` | n/a | Theme choices offered by File > Options > Appearance (defaults to the built-in catalog) |
120
+ | `onThemeChange` | `(key: string) => void` | n/a | Host hook for the appearance picker; when set, the host owns persisting the choice |
121
+ | `defaultLocale` | `string` | n/a | Initial locale code when no persisted preference exists |
122
+ | `availableLocales` | `LocaleCatalogEntry[]` | n/a | Locale choices offered by File > Options > Language (defaults to the registered i18next locales) |
123
+ | `onLocaleChange` | `(code: string) => void` | n/a | Host hook for the language picker; when set, the host owns applying/persisting the switch |
124
+ | `accountAuth` | `AccountAuthConfig` | n/a | Optional sign-in hook point for File > Account (disabled unless `enabled: true`) |
125
+
126
+ ### `PowerPointViewerHandle` (via `ref`)
127
+
128
+ | Method | Signature | Description |
129
+ | ----------------------- | ---------------------------- | ---------------------------------------- |
130
+ | `getContent` | `() => Promise<Uint8Array>` | Serialise current state to .pptx bytes |
131
+ | `goTo` | `(index: number) => void` | Navigate to a slide by zero-based index |
132
+ | `goPrev` | `() => void` | Navigate to the previous slide |
133
+ | `goNext` | `() => void` | Navigate to the next slide |
134
+ | `undo` | `() => void` | Undo the last editing action |
135
+ | `redo` | `() => void` | Redo the last undone action |
136
+ | `canUndo` | `() => boolean` | Whether an undo action is available |
137
+ | `canRedo` | `() => boolean` | Whether a redo action is available |
138
+ | `getZoom` | `() => number` | Get the current zoom level (1 = 100%) |
139
+ | `setZoom` | `(level: number) => void` | Set the zoom level |
140
+ | `zoomIn` | `() => void` | Zoom in by one step |
141
+ | `zoomOut` | `() => void` | Zoom out by one step |
142
+ | `zoomReset` | `() => void` | Reset zoom to 100% |
143
+ | `getMode` | `() => ViewerMode` | Get the current viewer mode |
144
+ | `setMode` | `(mode: ViewerMode) => void` | Switch mode programmatically |
145
+ | `getActiveSlideIndex` | `() => number` | Get the zero-based active slide index |
146
+ | `getSlideCount` | `() => number` | Get the total number of slides |
147
+ | `isDirty` | `() => boolean` | Whether the document has unsaved changes |
148
+ | `getSelectedElementIds` | `() => string[]` | Get IDs of selected elements |
149
+ | `selectElements` | `(ids: string[]) => void` | Programmatically select elements by ID |
150
+ | `clearSelection` | `() => void` | Clear the current selection |
151
+
152
+ The handle implements the full shared `PowerPointViewerAPI`, so the following
153
+ slide/element manipulation methods are also available:
154
+ `setActiveSlideIndex(index)`, `getSlides()`, `getSlide(index)`,
155
+ `getActiveSlide()`, `addSlide(afterIndex?)`, `deleteSlides(indexes)`,
156
+ `duplicateSlides(indexes)`, `moveSlide(from, to)`, `toggleHideSlides(indexes)`,
157
+ `getElements(slideIndex?)`, `getElementById(id, slideIndex?)`,
158
+ `updateElement(id, patch)`, `deleteElements(ids)`, and
159
+ `duplicateElement(id)`.
160
+
161
+ ### `renderToCanvas`
162
+
163
+ Standalone utility for rendering a DOM element to a Canvas (with an oklch colour-space workaround):
164
+
165
+ ```typescript
166
+ import { renderToCanvas } from 'pptx-react-viewer';
167
+
168
+ const canvas = await renderToCanvas(element, options); // => HTMLCanvasElement
169
+ ```
170
+
171
+ ### Composing a custom viewer shell
172
+
173
+ `<PowerPointViewer>` bundles a full editor chrome (toolbar, canvas, side panels, dialogs, presentation mode). If you only need the toolbar and slide canvas, with your own layout around them, `Toolbar` and `SlideCanvas` are exported as standalone components, and `useViewerBuildingBlocks` wires up the same state and hooks `PowerPointViewer` uses internally, mapped into the flat props those two components expect:
174
+
175
+ ```tsx
176
+ import { Toolbar, SlideCanvas, useViewerBuildingBlocks } from 'pptx-react-viewer';
177
+
178
+ function MyCustomViewer({ content }: { content: Uint8Array }) {
179
+ // Also returned: `mode` (current ViewerMode) and `autosaveStatus`
180
+ const { toolbarProps, canvasProps, loading, error } = useViewerBuildingBlocks({
181
+ content,
182
+ canEdit: true,
183
+ });
184
+
185
+ if (loading) return <p>Loading…</p>;
186
+ if (error) return <p>Failed to load: {error}</p>;
187
+
188
+ return (
189
+ <div className='my-custom-layout'>
190
+ <Toolbar {...toolbarProps} />
191
+ <SlideCanvas {...canvasProps} />
192
+ </div>
193
+ );
194
+ }
195
+ ```
196
+
197
+ `useViewerBuildingBlocks` accepts the same `content` / `canEdit` / `filePath` / `hiddenActions` / `onDirtyChange`-style inputs as `PowerPointViewer`, plus `onOpenSettings` / `onOpenHeaderFooter` / `onOpenShareDialog` callbacks (fired by the corresponding toolbar buttons) since this composition doesn't render those dialogs itself. It's an additive alternative, not a replacement: dialogs, presentation-mode overlays, mobile chrome, resizable side panels, and real-time collaboration are all part of `PowerPointViewer` and are out of scope for these building blocks. Reach for `PowerPointViewer` when you need the full editor; reach for `useViewerBuildingBlocks` when you're assembling your own chrome around just the toolbar and canvas.
198
+
199
+ ---
200
+
201
+ ## Styling & theming
202
+
203
+ The viewer's UI references **CSS custom properties** (`--pptx-*`, the shadcn/ui token convention) for every visual token, so it works three ways:
204
+
205
+ - **Tailwind CSS v4 project**: the viewer classes resolve through your existing Tailwind tokens. No extra CSS import needed.
206
+ - **No Tailwind**: import the bundled stylesheet once at your app entry: `import 'pptx-react-viewer/styles';`
207
+ - **CSS custom properties**: define the `--pptx-*` properties yourself for full control.
208
+
209
+ Override specific values with the `theme` prop:
210
+
211
+ ```tsx
212
+ <PowerPointViewer
213
+ content={bytes}
214
+ theme={{
215
+ colors: { primary: '#6366f1', background: '#0f172a' },
216
+ radius: '0.5rem',
217
+ }}
218
+ />
219
+ ```
220
+
221
+ All `ViewerTheme.colors` keys are optional; override only what you need. Helpers `defaultThemeColors`, `defaultRadius`, `themeToCssVars`, `defaultCssVars`, `ViewerThemeProvider`, and `useViewerTheme` are exported for advanced use.
222
+
223
+ Two ready-made presets ship with the package: `vermilionLightTheme` (warm paper canvas) and `vermilionDarkTheme` (dimmed presenter room):
224
+
225
+ ```tsx
226
+ import { PowerPointViewer, vermilionLightTheme } from 'pptx-react-viewer';
227
+
228
+ <PowerPointViewer content={bytes} theme={vermilionLightTheme} />;
229
+ ```
230
+
231
+ The underlying palettes (`vermilionLightColors`, `vermilionDarkColors`) and radius (`vermilionRadius`) are exported too, so you can spread them into your own variant.
232
+
233
+ ## Localization (i18n)
234
+
235
+ UI labels go through [i18next](https://www.i18next.com/) / [react-i18next](https://react.i18next.com/) with dotted keys such as `pptx.statusBar.allSaved`. Initialise an i18next instance and wrap your app in `I18nextProvider` (the demo's `demo/i18n.ts` shows a minimal config, including a `parseMissingKeyHandler` that derives Title Case labels for any key you don't explicitly translate). `@aixa-transformation/pptx-viewer/i18n` exports `translationsEn` (the English dictionary), `keyToLabel` (the fallback), and a `TranslationKey` type you can use to type-check a new locale dictionary (`Record<TranslationKey, string>`) at compile time. Add a new language by supplying a resource bundle under its language code.
236
+
237
+ ## How it's built
238
+
239
+ You only need the `<PowerPointViewer>` component; everything else is internal. Behind it, the logic lives in many small, focused React hooks, and the components themselves just draw what those hooks produce. Slides are rendered as ordinary HTML and CSS (charts as inline SVG, tables as real `<table>` elements), which is why text stays sharp, selectable, and accessible.
240
+
241
+ A small curated set of those hooks is exported from `@aixa-transformation/pptx-viewer/viewer` with a stable API; the complete set (67+) is also importable from `@aixa-transformation/pptx-viewer/internals` for advanced integrations. The `internals` subpath is **not covered by semver**: prefer the stable root exports.
242
+
243
+ ## Limitations
244
+
245
+ CSS-based rendering trades a few visual effects for crisp text, accessibility, and DOM interactivity: `backdrop-filter` becomes semi-transparent backgrounds and path gradients approximate as elliptical radials, while `mix-blend-mode` and CSS 3D transforms render natively on screen but flatten in raster export. Text uses fonts available in the browser (embedded fonts are injected when present). Media playback depends on browser codec support. SmartArt is decomposed into editable shapes with a live reflow engine for structural edits, and charts edit via the inspector data grid rather than the chart surface. 3D models need the optional Three.js peer.
246
+
247
+ ## License
248
+
249
+ [Apache-2.0](LICENSE). Please keep the [`NOTICE`](NOTICE) file with redistributions.