pptx-react-viewer 1.1.72 → 1.1.74

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project are documented here.
4
4
  This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
5
5
  by [git-cliff](https://git-cliff.org); do not edit it by hand.
6
6
 
7
+ ## [1.1.73](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-react-viewer@1.1.73) - 2026-07-03
8
+
9
+ ### Features
10
+
11
+ - Document localization and add demo language pickers (by @ChristopherVR) ([a07ad82](https://github.com/ChristopherVR/pptx-viewer/commit/a07ad8279e906590e0392d19cd1637855012a80e))
12
+
7
13
  ## [1.1.71](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-react-viewer@1.1.71) - 2026-07-02
8
14
 
9
15
  ### Features
package/README.md CHANGED
@@ -145,7 +145,7 @@ All `ViewerTheme.colors` keys are optional; override only what you need. Helpers
145
145
 
146
146
  ## Localization (i18n)
147
147
 
148
- 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). Add a new language by supplying a resource bundle under its language code.
148
+ 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). `pptx-react-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. See the [Localization guide](https://christophervr.github.io/pptx-viewer/guide/localization) for full wiring examples and how to contribute a translation upstream; the live demo's language picker is a working reference.
149
149
 
150
150
  ## How it's built
151
151
 
@@ -2,7 +2,6 @@ import { l, P, $, f, i, X, U, R, h, V } from './presentation-BRAUjTRt.js';
2
2
  import * as React from 'react';
3
3
  import React__default from 'react';
4
4
  import { ViewerTheme } from './theme/index.js';
5
- import { Doc } from 'yjs';
6
5
 
7
6
  /**
8
7
  * Core data-model types for the PowerPoint viewer/editor plugin.
@@ -177,20 +176,37 @@ interface ShapeQuickStyle {
177
176
 
178
177
  /** Collaboration role within a session. */
179
178
  type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
180
-
181
179
  /**
182
- * Collaboration types: Shared type definitions for the real-time
183
- * collaboration infrastructure (Yjs-backed CRDT sync, presence tracking,
184
- * collaborative editing).
180
+ * Collaboration transport.
185
181
  *
186
- * @module collaboration/types
182
+ * - `'websocket'` (default): y-websocket against `serverUrl`.
183
+ * - `'webrtc'`: y-webrtc peer-to-peer; needs no document server. Peers meet
184
+ * through the `signaling` servers (WebRTC signaling only, no document data)
185
+ * and same-browser tabs additionally sync via BroadcastChannel even without
186
+ * any signaling server, which makes this mode usable from static hosting.
187
+ */
188
+ type CollaborationTransport = 'websocket' | 'webrtc';
189
+ /**
190
+ * Real-time collaboration configuration.
191
+ *
192
+ * The same shape is accepted by the React, Vue, and Angular bindings.
187
193
  */
188
-
189
194
  interface CollaborationConfig {
190
195
  /** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
191
196
  roomId: string;
192
- /** WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com"). */
197
+ /**
198
+ * WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com").
199
+ * Ignored (may be empty) when `transport` is `'webrtc'`.
200
+ */
193
201
  serverUrl: string;
202
+ /** Transport to use. Defaults to `'websocket'`. */
203
+ transport?: CollaborationTransport;
204
+ /**
205
+ * WebRTC signaling server URLs (only used when `transport` is `'webrtc'`).
206
+ * Defaults to y-webrtc's built-in public signaling list. Same-browser tabs
207
+ * sync via BroadcastChannel regardless of signaling availability.
208
+ */
209
+ signaling?: string[];
194
210
  /** Display name for the local user. */
195
211
  userName: string;
196
212
  /** Avatar URL for the local user (optional). */
@@ -199,53 +215,24 @@ interface CollaborationConfig {
199
215
  userColor?: string;
200
216
  /** Optional authentication token sent with the WebSocket handshake. */
201
217
  authToken?: string;
202
- /** Role in the session: defaults to `'collaborator'`. */
203
- role?: CollaborationRole;
204
- }
205
- /** Connection lifecycle states for the Yjs WebSocket provider. */
206
- type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
207
- /**
208
- * Presence data broadcast to other participants.
209
- * Cursor position is relative to the slide canvas (0..canvasWidth, 0..canvasHeight).
210
- */
211
- interface UserPresence {
212
- /** Unique client ID (assigned by Yjs awareness). */
213
- clientId: number;
214
- /** Sanitised display name. */
215
- userName: string;
216
- /** Optional avatar URL (validated). */
217
- userAvatar?: string;
218
- /** Hex colour for the user's cursor ring. */
219
- userColor: string;
220
- /** Slide index the user is currently viewing. */
221
- activeSlideIndex: number;
222
- /** Cursor X on the canvas (clamped to slide bounds). */
223
- cursorX: number;
224
- /** Cursor Y on the canvas (clamped to slide bounds). */
225
- cursorY: number;
226
- /** ISO timestamp of last update (for stale-presence cleanup). */
227
- lastUpdated: string;
228
- /** Optional currently selected element ID. */
229
- selectedElementId?: string;
230
- /** Role in the session (owner, viewer, or collaborator). */
218
+ /** Role in the session; defaults to `'collaborator'`. */
231
219
  role?: CollaborationRole;
232
- }
233
- /** Value exposed by `CollaborationContext`. */
234
- interface CollaborationContextValue {
235
- /** Current WebSocket connection status. */
236
- status: ConnectionStatus;
237
- /** Presence data for all remote users (excludes the local user). */
238
- remoteUsers: UserPresence[];
239
- /** Broadcast the local user's presence state. */
240
- broadcastPresence: (update: Partial<Omit<UserPresence, 'clientId'>>) => void;
241
- /** Total number of connected users (including local). */
242
- connectedCount: number;
243
- /** The collaboration config that was provided. */
244
- config: CollaborationConfig;
245
- /** The Yjs document (for document sync). */
246
- doc: Doc | null;
247
- /** Manually retry the WebSocket connection after a timeout or error. */
248
- retry: () => void;
220
+ /**
221
+ * Elected-writer write-back callback (Area 3 of the C3 hardening plan).
222
+ *
223
+ * When the local user has `role: 'owner'`, the binding debounces changes and
224
+ * serializes the current Y.Doc state to a PPTX byte array, then calls this
225
+ * callback so the host can persist the snapshot. Only one writer (the owner)
226
+ * does this; other collaborators never trigger write-back, eliminating the
227
+ * last-save-wins problem.
228
+ */
229
+ onWriteBack?: (bytes: Uint8Array) => void;
230
+ /**
231
+ * Debounce delay (ms) between the last Y.Doc change and the write-back
232
+ * invocation. Defaults to 5000 ms. Set to 0 to write back on every change
233
+ * (not recommended for large documents).
234
+ */
235
+ writeBackDebounceMs?: number;
249
236
  }
250
237
 
251
238
  /**
@@ -508,4 +495,4 @@ declare function getAnimationInitialStyle(preset: f | undefined, nativeAnimation
508
495
  */
509
496
  declare const PowerPointViewer: React.ForwardRefExoticComponent<PowerPointViewerProps & React.RefAttributes<PowerPointViewerHandle>>;
510
497
 
511
- export { type AccessibilityIssue as A, type SlideSectionGroup as B, type CollaborationConfig as C, type DragState as D, type EditorHistorySnapshot as E, type FileViewerHandle as F, type SlideTransitionOption as G, type StrokeDashOption as H, type SupportedShapeType as I, type ToolbarSection as J, type MarqueeSelectionState as M, PowerPointViewer as P, type ResizeHandle as R, type ShapeAdjustmentDragState as S, type TableCellEditorState as T, type UserPresence as U, type ViewerMode as V, type PowerPointViewerHandle as a, type PowerPointViewerProps as b, type ConnectionStatus as c, type CollaborationContextValue as d, type AnimationPresetOption as e, type CanvasSize as f, getAnimationInitialStyle as g, type CollaborationRole as h, type ConnectorArrowOption as i, type ConnectorGeometryOption as j, type ConnectorGeometryType as k, type ConnectorPathGeometry as l, type DrawingTool as m, type ElementBounds as n, type ElementClipboardPayload as o, type ElementContextMenuAction as p, type ElementContextMenuState as q, type ParsedTableCell as r, type ParsedTableData as s, type PresentationAnimationRuntime as t, type ResizeState as u, type ShapeAdjustmentHandleDescriptor as v, type ShapePreset as w, type ShapeQuickStyle as x, type ShortcutReferenceItem as y, type SlideAlignment as z };
498
+ export { type AccessibilityIssue as A, type StrokeDashOption as B, type CollaborationRole as C, type DragState as D, type EditorHistorySnapshot as E, type FileViewerHandle as F, type SupportedShapeType as G, type ToolbarSection as H, type MarqueeSelectionState as M, PowerPointViewer as P, type ResizeHandle as R, type ShapeAdjustmentDragState as S, type TableCellEditorState as T, type ViewerMode as V, type PowerPointViewerHandle as a, type PowerPointViewerProps as b, type CollaborationConfig as c, type AnimationPresetOption as d, type CanvasSize as e, type ConnectorArrowOption as f, getAnimationInitialStyle as g, type ConnectorGeometryOption as h, type ConnectorGeometryType as i, type ConnectorPathGeometry as j, type DrawingTool as k, type ElementBounds as l, type ElementClipboardPayload as m, type ElementContextMenuAction as n, type ElementContextMenuState as o, type ParsedTableCell as p, type ParsedTableData as q, type PresentationAnimationRuntime as r, type ResizeState as s, type ShapeAdjustmentHandleDescriptor as t, type ShapePreset as u, type ShapeQuickStyle as v, type ShortcutReferenceItem as w, type SlideAlignment as x, type SlideSectionGroup as y, type SlideTransitionOption as z };
@@ -2,7 +2,6 @@ import { l, P, $, f, i, X, U, R, h, V } from './presentation-BRAUjTRt.js';
2
2
  import * as React from 'react';
3
3
  import React__default from 'react';
4
4
  import { ViewerTheme } from './theme/index.js';
5
- import { Doc } from 'yjs';
6
5
 
7
6
  /**
8
7
  * Core data-model types for the PowerPoint viewer/editor plugin.
@@ -177,20 +176,37 @@ interface ShapeQuickStyle {
177
176
 
178
177
  /** Collaboration role within a session. */
179
178
  type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
180
-
181
179
  /**
182
- * Collaboration types: Shared type definitions for the real-time
183
- * collaboration infrastructure (Yjs-backed CRDT sync, presence tracking,
184
- * collaborative editing).
180
+ * Collaboration transport.
185
181
  *
186
- * @module collaboration/types
182
+ * - `'websocket'` (default): y-websocket against `serverUrl`.
183
+ * - `'webrtc'`: y-webrtc peer-to-peer; needs no document server. Peers meet
184
+ * through the `signaling` servers (WebRTC signaling only, no document data)
185
+ * and same-browser tabs additionally sync via BroadcastChannel even without
186
+ * any signaling server, which makes this mode usable from static hosting.
187
+ */
188
+ type CollaborationTransport = 'websocket' | 'webrtc';
189
+ /**
190
+ * Real-time collaboration configuration.
191
+ *
192
+ * The same shape is accepted by the React, Vue, and Angular bindings.
187
193
  */
188
-
189
194
  interface CollaborationConfig {
190
195
  /** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
191
196
  roomId: string;
192
- /** WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com"). */
197
+ /**
198
+ * WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com").
199
+ * Ignored (may be empty) when `transport` is `'webrtc'`.
200
+ */
193
201
  serverUrl: string;
202
+ /** Transport to use. Defaults to `'websocket'`. */
203
+ transport?: CollaborationTransport;
204
+ /**
205
+ * WebRTC signaling server URLs (only used when `transport` is `'webrtc'`).
206
+ * Defaults to y-webrtc's built-in public signaling list. Same-browser tabs
207
+ * sync via BroadcastChannel regardless of signaling availability.
208
+ */
209
+ signaling?: string[];
194
210
  /** Display name for the local user. */
195
211
  userName: string;
196
212
  /** Avatar URL for the local user (optional). */
@@ -199,53 +215,24 @@ interface CollaborationConfig {
199
215
  userColor?: string;
200
216
  /** Optional authentication token sent with the WebSocket handshake. */
201
217
  authToken?: string;
202
- /** Role in the session: defaults to `'collaborator'`. */
203
- role?: CollaborationRole;
204
- }
205
- /** Connection lifecycle states for the Yjs WebSocket provider. */
206
- type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error';
207
- /**
208
- * Presence data broadcast to other participants.
209
- * Cursor position is relative to the slide canvas (0..canvasWidth, 0..canvasHeight).
210
- */
211
- interface UserPresence {
212
- /** Unique client ID (assigned by Yjs awareness). */
213
- clientId: number;
214
- /** Sanitised display name. */
215
- userName: string;
216
- /** Optional avatar URL (validated). */
217
- userAvatar?: string;
218
- /** Hex colour for the user's cursor ring. */
219
- userColor: string;
220
- /** Slide index the user is currently viewing. */
221
- activeSlideIndex: number;
222
- /** Cursor X on the canvas (clamped to slide bounds). */
223
- cursorX: number;
224
- /** Cursor Y on the canvas (clamped to slide bounds). */
225
- cursorY: number;
226
- /** ISO timestamp of last update (for stale-presence cleanup). */
227
- lastUpdated: string;
228
- /** Optional currently selected element ID. */
229
- selectedElementId?: string;
230
- /** Role in the session (owner, viewer, or collaborator). */
218
+ /** Role in the session; defaults to `'collaborator'`. */
231
219
  role?: CollaborationRole;
232
- }
233
- /** Value exposed by `CollaborationContext`. */
234
- interface CollaborationContextValue {
235
- /** Current WebSocket connection status. */
236
- status: ConnectionStatus;
237
- /** Presence data for all remote users (excludes the local user). */
238
- remoteUsers: UserPresence[];
239
- /** Broadcast the local user's presence state. */
240
- broadcastPresence: (update: Partial<Omit<UserPresence, 'clientId'>>) => void;
241
- /** Total number of connected users (including local). */
242
- connectedCount: number;
243
- /** The collaboration config that was provided. */
244
- config: CollaborationConfig;
245
- /** The Yjs document (for document sync). */
246
- doc: Doc | null;
247
- /** Manually retry the WebSocket connection after a timeout or error. */
248
- retry: () => void;
220
+ /**
221
+ * Elected-writer write-back callback (Area 3 of the C3 hardening plan).
222
+ *
223
+ * When the local user has `role: 'owner'`, the binding debounces changes and
224
+ * serializes the current Y.Doc state to a PPTX byte array, then calls this
225
+ * callback so the host can persist the snapshot. Only one writer (the owner)
226
+ * does this; other collaborators never trigger write-back, eliminating the
227
+ * last-save-wins problem.
228
+ */
229
+ onWriteBack?: (bytes: Uint8Array) => void;
230
+ /**
231
+ * Debounce delay (ms) between the last Y.Doc change and the write-back
232
+ * invocation. Defaults to 5000 ms. Set to 0 to write back on every change
233
+ * (not recommended for large documents).
234
+ */
235
+ writeBackDebounceMs?: number;
249
236
  }
250
237
 
251
238
  /**
@@ -508,4 +495,4 @@ declare function getAnimationInitialStyle(preset: f | undefined, nativeAnimation
508
495
  */
509
496
  declare const PowerPointViewer: React.ForwardRefExoticComponent<PowerPointViewerProps & React.RefAttributes<PowerPointViewerHandle>>;
510
497
 
511
- export { type AccessibilityIssue as A, type SlideSectionGroup as B, type CollaborationConfig as C, type DragState as D, type EditorHistorySnapshot as E, type FileViewerHandle as F, type SlideTransitionOption as G, type StrokeDashOption as H, type SupportedShapeType as I, type ToolbarSection as J, type MarqueeSelectionState as M, PowerPointViewer as P, type ResizeHandle as R, type ShapeAdjustmentDragState as S, type TableCellEditorState as T, type UserPresence as U, type ViewerMode as V, type PowerPointViewerHandle as a, type PowerPointViewerProps as b, type ConnectionStatus as c, type CollaborationContextValue as d, type AnimationPresetOption as e, type CanvasSize as f, getAnimationInitialStyle as g, type CollaborationRole as h, type ConnectorArrowOption as i, type ConnectorGeometryOption as j, type ConnectorGeometryType as k, type ConnectorPathGeometry as l, type DrawingTool as m, type ElementBounds as n, type ElementClipboardPayload as o, type ElementContextMenuAction as p, type ElementContextMenuState as q, type ParsedTableCell as r, type ParsedTableData as s, type PresentationAnimationRuntime as t, type ResizeState as u, type ShapeAdjustmentHandleDescriptor as v, type ShapePreset as w, type ShapeQuickStyle as x, type ShortcutReferenceItem as y, type SlideAlignment as z };
498
+ export { type AccessibilityIssue as A, type StrokeDashOption as B, type CollaborationRole as C, type DragState as D, type EditorHistorySnapshot as E, type FileViewerHandle as F, type SupportedShapeType as G, type ToolbarSection as H, type MarqueeSelectionState as M, PowerPointViewer as P, type ResizeHandle as R, type ShapeAdjustmentDragState as S, type TableCellEditorState as T, type ViewerMode as V, type PowerPointViewerHandle as a, type PowerPointViewerProps as b, type CollaborationConfig as c, type AnimationPresetOption as d, type CanvasSize as e, type ConnectorArrowOption as f, getAnimationInitialStyle as g, type ConnectorGeometryOption as h, type ConnectorGeometryType as i, type ConnectorPathGeometry as j, type DrawingTool as k, type ElementBounds as l, type ElementClipboardPayload as m, type ElementContextMenuAction as n, type ElementContextMenuState as o, type ParsedTableCell as p, type ParsedTableData as q, type PresentationAnimationRuntime as r, type ResizeState as s, type ShapeAdjustmentHandleDescriptor as t, type ShapePreset as u, type ShapeQuickStyle as v, type ShortcutReferenceItem as w, type SlideAlignment as x, type SlideSectionGroup as y, type SlideTransitionOption as z };
package/dist/i18n.d.mts CHANGED
@@ -1 +1 @@
1
- export { keyToLabel, translationsEn } from 'pptx-viewer-shared/i18n';
1
+ export { TranslationKey, keyToLabel, translationsEn } from 'pptx-viewer-shared/i18n';
package/dist/i18n.d.ts CHANGED
@@ -1 +1 @@
1
- export { keyToLabel, translationsEn } from 'pptx-viewer-shared/i18n';
1
+ export { TranslationKey, keyToLabel, translationsEn } from 'pptx-viewer-shared/i18n';