pptx-angular-viewer 0.1.0

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.
@@ -0,0 +1,406 @@
1
+ import * as pptx_viewer_core from 'pptx-viewer-core';
2
+ import { PptxSlide, PptxTheme, PptxSlideMaster, PptxElement } from 'pptx-viewer-core';
3
+ import * as _angular_core from '@angular/core';
4
+ import { InjectionToken, Provider } from '@angular/core';
5
+
6
+ /**
7
+ * Theme configuration types for the PowerPoint viewer.
8
+ *
9
+ * All color values accept any valid CSS color string:
10
+ * hex (`#6366f1`), rgb (`rgb(99 102 241)`), hsl (`hsl(239 84% 67%)`),
11
+ * oklch (`oklch(0.585 0.233 277)`), named colors, etc.
12
+ *
13
+ * Framework-agnostic — shared by the React, Vue, and Angular bindings.
14
+ */
15
+ /**
16
+ * Semantic color tokens for the viewer UI.
17
+ *
18
+ * These map to CSS custom properties (`--pptx-<token>`) and drive all
19
+ * UI component colors. The naming follows the shadcn/ui convention so
20
+ * that Tailwind + shadcn users get a familiar experience.
21
+ */
22
+ interface ViewerThemeColors {
23
+ /** Page / root background */
24
+ background: string;
25
+ /** Default text color */
26
+ foreground: string;
27
+ /** Card / panel surface */
28
+ card: string;
29
+ /** Text on card surfaces */
30
+ cardForeground: string;
31
+ /** Popover / dropdown surface */
32
+ popover: string;
33
+ /** Text inside popovers */
34
+ popoverForeground: string;
35
+ /** Primary action color (buttons, active indicators) */
36
+ primary: string;
37
+ /** Text on primary-colored backgrounds */
38
+ primaryForeground: string;
39
+ /** Secondary / subdued action color */
40
+ secondary: string;
41
+ /** Text on secondary backgrounds */
42
+ secondaryForeground: string;
43
+ /** Muted / disabled surface */
44
+ muted: string;
45
+ /** Text on muted surfaces (also used for secondary text) */
46
+ mutedForeground: string;
47
+ /** Accent / hover-highlight surface */
48
+ accent: string;
49
+ /** Text on accent surfaces */
50
+ accentForeground: string;
51
+ /** Destructive / danger action color */
52
+ destructive: string;
53
+ /** Text on destructive backgrounds */
54
+ destructiveForeground: string;
55
+ /** Default border color */
56
+ border: string;
57
+ /** Input field border color */
58
+ input: string;
59
+ /** Focus ring color */
60
+ ring: string;
61
+ }
62
+ /**
63
+ * Full viewer theme configuration.
64
+ *
65
+ * Every property is optional — unset values fall back to the built-in
66
+ * dark theme defaults.
67
+ */
68
+ interface ViewerTheme {
69
+ /** Semantic UI colors. Each key maps to a `--pptx-<key>` CSS custom property. */
70
+ colors?: Partial<ViewerThemeColors>;
71
+ /** Base border-radius value (e.g. `"0.5rem"`, `"8px"`). */
72
+ radius?: string;
73
+ /**
74
+ * Escape hatch: arbitrary CSS custom properties to set on the viewer
75
+ * root element. Keys should include the `--` prefix.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * { "--my-custom-shadow": "0 4px 12px rgba(0,0,0,0.5)" }
80
+ * ```
81
+ */
82
+ cssVars?: Record<string, string>;
83
+ }
84
+
85
+ /**
86
+ * Default dark-theme color values.
87
+ *
88
+ * These correspond to the built-in dark UI of the PowerPoint viewer and
89
+ * use Tailwind's gray palette as the neutral scale with indigo as the
90
+ * primary accent.
91
+ */
92
+ declare const defaultThemeColors: ViewerThemeColors;
93
+ /** Default border-radius. */
94
+ declare const defaultRadius = "0.5rem";
95
+
96
+ /**
97
+ * Convert a `ViewerTheme` into a flat `Record<string, string>` of CSS
98
+ * custom properties (including the `--` prefix) ready to be spread onto
99
+ * a `style` attribute.
100
+ *
101
+ * Only properties that differ from the built-in defaults are emitted when
102
+ * `omitDefaults` is true (the default).
103
+ */
104
+ declare function themeToCssVars(theme: ViewerTheme | undefined, omitDefaults?: boolean): Record<string, string>;
105
+ /**
106
+ * Build the complete set of CSS custom properties with all defaults.
107
+ * Useful for generating a full fallback stylesheet.
108
+ */
109
+ declare function defaultCssVars(): Record<string, string>;
110
+
111
+ /**
112
+ * Framework-agnostic public types shared by the viewer bindings.
113
+ *
114
+ * These were duplicated in the React (`types-ui.ts`) and Vue (`viewer/types.ts`)
115
+ * packages; this is the canonical copy. Each binding layers its own
116
+ * framework-specific prop/event/handle types on top of these.
117
+ */
118
+ /** Canvas dimensions in pixels. */
119
+ interface CanvasSize {
120
+ width: number;
121
+ height: number;
122
+ }
123
+ /** Collaboration role within a session. */
124
+ type CollaborationRole = 'owner' | 'collaborator' | 'viewer';
125
+ /**
126
+ * Real-time collaboration configuration.
127
+ *
128
+ * The collaboration runtime (Yjs) is not yet ported to every binding — this
129
+ * type exists so the public prop surface stays identical across React, Vue,
130
+ * and Angular.
131
+ */
132
+ interface CollaborationConfig {
133
+ /** Unique identifier for the collaboration room (alphanumeric, hyphens, underscores). */
134
+ roomId: string;
135
+ /** WebSocket server URL for the Yjs provider (e.g. "wss://collab.example.com"). */
136
+ serverUrl: string;
137
+ /** Display name for the local user. */
138
+ userName: string;
139
+ /** Avatar URL for the local user (optional). */
140
+ userAvatar?: string;
141
+ /** Hex colour for the local user's cursor/presence indicator. */
142
+ userColor?: string;
143
+ /** Optional authentication token sent with the WebSocket handshake. */
144
+ authToken?: string;
145
+ /** Role in the session — defaults to `'collaborator'`. */
146
+ role?: CollaborationRole;
147
+ }
148
+
149
+ /**
150
+ * Scalar viewer defaults shared by the UI bindings.
151
+ *
152
+ * Subset of the React package's `constants/scalar.ts` that the Vue and Angular
153
+ * viewers also need. Additional constant groups (toolbar presets, shape styles,
154
+ * transitions, etc.) remain per-binding until those features are ported.
155
+ */
156
+ /** Default slide canvas width in pixels when the file declares none. */
157
+ declare const DEFAULT_CANVAS_WIDTH = 1280;
158
+ /** Default slide canvas height in pixels when the file declares none. */
159
+ declare const DEFAULT_CANVAS_HEIGHT = 720;
160
+ /** Fallback text colour. */
161
+ declare const DEFAULT_TEXT_COLOR = "#111827";
162
+ /** Fallback shape fill colour. */
163
+ declare const DEFAULT_FILL_COLOR = "#3b82f6";
164
+ /** Fallback shape stroke colour. */
165
+ declare const DEFAULT_STROKE_COLOR = "#1f2937";
166
+
167
+ /**
168
+ * `LoadContentService` — Angular port of the React `useLoadContent` hook and
169
+ * the Vue `useLoadContent` composable.
170
+ *
171
+ * Parses `.pptx` bytes into reactive signals via the framework-agnostic
172
+ * `PptxHandler` from `pptx-viewer-core`. All heavy lifting (ZIP, XML parse,
173
+ * theme/master/layout resolution, media extraction) lives in core and the
174
+ * pure helpers live in `pptx-viewer-shared`; this service only wires the async
175
+ * load into Angular signals and manages Blob-URL / handler lifecycle.
176
+ *
177
+ * Provide it at the component level so its lifetime tracks the host viewer:
178
+ * `@Component({ providers: [LoadContentService] })`.
179
+ *
180
+ * This is the viewer-first subset; the React hook also populated ~25 extra
181
+ * pieces of presentation metadata (sections, custom shows, embedded fonts,
182
+ * digital signatures, …). Those are tracked in PORTING.md and added here as
183
+ * the corresponding features are ported.
184
+ */
185
+ declare class LoadContentService {
186
+ /** Parsed slides (with image Blob URLs patched in). */
187
+ readonly slides: _angular_core.WritableSignal<PptxSlide[]>;
188
+ /** Slide canvas size in pixels. */
189
+ readonly canvasSize: _angular_core.WritableSignal<CanvasSize>;
190
+ /** Resolved presentation theme. */
191
+ readonly theme: _angular_core.WritableSignal<PptxTheme | undefined>;
192
+ /** Slide masters (for placeholder/background resolution). */
193
+ readonly slideMasters: _angular_core.WritableSignal<PptxSlideMaster[]>;
194
+ /** Archive-path → displayable URL map for media + poster frames. */
195
+ readonly mediaDataUrls: _angular_core.WritableSignal<Map<string, string>>;
196
+ /** True while a load is in flight. */
197
+ readonly loading: _angular_core.WritableSignal<boolean>;
198
+ /** Error message from the last failed load, or null. */
199
+ readonly error: _angular_core.WritableSignal<string | null>;
200
+ /** True when the file is password-protected and could not be opened. */
201
+ readonly isEncrypted: _angular_core.WritableSignal<boolean>;
202
+ /** Number of loaded slides. */
203
+ readonly slideCount: _angular_core.Signal<number>;
204
+ private handler;
205
+ private renderToken;
206
+ private activeBlobUrls;
207
+ constructor();
208
+ /** Serialise the current presentation back to `.pptx` bytes. */
209
+ getContent(): Promise<Uint8Array>;
210
+ /** Parse the supplied `.pptx` bytes into the reactive signals. */
211
+ load(raw: Uint8Array | ArrayBuffer | null | undefined): Promise<void>;
212
+ private disposeHandler;
213
+ private revokeBlobUrls;
214
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<LoadContentService, never>;
215
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<LoadContentService>;
216
+ }
217
+
218
+ /**
219
+ * PowerPointViewerComponent — Angular port of the React `PowerPointViewer.tsx`
220
+ * and Vue `PowerPointViewer.vue`.
221
+ *
222
+ * Top-level orchestrator that loads `.pptx` bytes and renders the slides with
223
+ * navigation and zoom. This is the viewer-first milestone of the port: the
224
+ * React component additionally composes a full editor (toolbar, inspector
225
+ * panels, dialogs, presentation mode, collaboration, export). The roadmap and
226
+ * per-area status live in `packages/angular/PORTING.md`.
227
+ *
228
+ * Conventions vs. React/Vue:
229
+ * - React `forwardRef` handle / Vue `defineExpose` → public {@link getContent}
230
+ * method (reach it via a template ref or `viewChild`).
231
+ * - React callback props / Vue emits → Angular `output()` events.
232
+ * - React theme context / Vue provide-inject → `themeStyle` CSS vars applied to
233
+ * the root element (app-wide sharing via `provideViewerTheme`).
234
+ */
235
+ declare class PowerPointViewerComponent {
236
+ /** PowerPoint content as Uint8Array (or ArrayBuffer). */
237
+ readonly content: _angular_core.InputSignal<ArrayBuffer | Uint8Array<ArrayBufferLike> | null>;
238
+ /** Whether editing actions are enabled. (Editor chrome not yet ported.) */
239
+ readonly canEdit: _angular_core.InputSignal<boolean>;
240
+ /** Optional class applied to the root element. */
241
+ readonly class: _angular_core.InputSignal<string>;
242
+ /** Theme configuration for customising the viewer's appearance. */
243
+ readonly theme: _angular_core.InputSignal<ViewerTheme | undefined>;
244
+ /** Optional real-time collaboration config (accepted for API parity; not yet implemented). */
245
+ readonly collaboration: _angular_core.InputSignal<CollaborationConfig | undefined>;
246
+ /** Fired when the active slide changes. */
247
+ readonly activeSlideChange: _angular_core.OutputEmitterRef<number>;
248
+ /** Fired when the unsaved-changes flag toggles. (Editing not yet ported.) */
249
+ readonly dirtyChange: _angular_core.OutputEmitterRef<boolean>;
250
+ /** Fired when the in-memory content changes after edits. (Editing not yet ported.) */
251
+ readonly contentChange: _angular_core.OutputEmitterRef<Uint8Array<ArrayBufferLike>>;
252
+ protected readonly loader: LoadContentService;
253
+ protected readonly activeSlideIndex: _angular_core.WritableSignal<number>;
254
+ protected readonly slideCount: _angular_core.Signal<number>;
255
+ protected readonly activeSlide: _angular_core.Signal<pptx_viewer_core.PptxSlide>;
256
+ protected readonly rootStyle: _angular_core.Signal<Record<string, string>>;
257
+ protected readonly zoom: _angular_core.WritableSignal<number>;
258
+ protected readonly zoomPercent: _angular_core.Signal<number>;
259
+ constructor();
260
+ /** Serialise the current presentation to `.pptx` bytes (imperative handle). */
261
+ getContent(): Promise<Uint8Array>;
262
+ goTo(index: number): void;
263
+ goPrev(): void;
264
+ goNext(): void;
265
+ zoomIn(): void;
266
+ zoomOut(): void;
267
+ zoomReset(): void;
268
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PowerPointViewerComponent, never>;
269
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PowerPointViewerComponent, "pptx-viewer", never, { "content": { "alias": "content"; "required": false; "isSignal": true; }; "canEdit": { "alias": "canEdit"; "required": false; "isSignal": true; }; "class": { "alias": "class"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "collaboration": { "alias": "collaboration"; "required": false; "isSignal": true; }; }, { "activeSlideChange": "activeSlideChange"; "dirtyChange": "dirtyChange"; "contentChange": "contentChange"; }, never, never, true, never>;
270
+ }
271
+
272
+ /**
273
+ * Basic, framework-agnostic style computation for slide elements, returning
274
+ * `[ngStyle]`-compatible maps.
275
+ *
276
+ * This mirrors the Vue package's `element-style.ts` (and a deliberately small
277
+ * subset of the React `viewer/utils/*` style layer). It is enough to position
278
+ * and paint text boxes, basic preset shapes, and images. Advanced visuals
279
+ * (gradients, custom geometry clip-paths, shadows, 3D, image effects, text
280
+ * warp) are tracked in PORTING.md.
281
+ *
282
+ * Long term the *logic* here is a shared-extraction candidate — only the
283
+ * return type (CSS map shape) differs per framework — so a future refactor
284
+ * could hoist a neutral core into `pptx-viewer-shared`.
285
+ */
286
+ /** `[ngStyle]`-compatible style map. */
287
+ type StyleMap = Record<string, string | number>;
288
+ /**
289
+ * Absolute container style: position, size, rotation, flip, opacity, z-index.
290
+ * Mirrors the essentials of the React `getContainerStyle`.
291
+ */
292
+ declare function getContainerStyle(el: PptxElement, zIndex: number): StyleMap;
293
+ /**
294
+ * Fill / stroke / corner-radius for shape-like elements. Returns an empty
295
+ * object when the element carries no shape styling.
296
+ */
297
+ declare function getShapeFillStrokeStyle(el: PptxElement): StyleMap;
298
+ /**
299
+ * Text block style for elements that carry text. Mirrors the essentials of the
300
+ * React `getTextStyleForElement`.
301
+ */
302
+ declare function getTextBlockStyle(el: PptxElement): StyleMap;
303
+ /** Resolve a displayable image source for picture/image/media poster frames. */
304
+ declare function getImageSrc(el: PptxElement, mediaDataUrls: Map<string, string>): string | undefined;
305
+
306
+ /**
307
+ * SlideCanvasComponent — Angular port of the React `SlideCanvas.tsx` and Vue
308
+ * `SlideCanvas.vue` (viewer-first subset).
309
+ *
310
+ * Renders the active slide as a fixed-size stage scaled by `zoom`, with each
311
+ * element absolutely positioned. The React version additionally layered in
312
+ * rulers, grid, guides, marquee/selection, connector-creation, drawing, and
313
+ * collaboration overlays — all tracked in PORTING.md.
314
+ */
315
+ declare class SlideCanvasComponent {
316
+ readonly slide: _angular_core.InputSignal<PptxSlide | undefined>;
317
+ readonly canvasSize: _angular_core.InputSignal<CanvasSize>;
318
+ readonly mediaDataUrls: _angular_core.InputSignal<Map<string, string>>;
319
+ readonly zoom: _angular_core.InputSignal<number>;
320
+ readonly elements: _angular_core.Signal<pptx_viewer_core.PptxElement[]>;
321
+ readonly wrapperStyle: _angular_core.Signal<StyleMap>;
322
+ readonly stageStyle: _angular_core.Signal<StyleMap>;
323
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SlideCanvasComponent, never>;
324
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SlideCanvasComponent, "pptx-slide-canvas", never, { "slide": { "alias": "slide"; "required": false; "isSignal": true; }; "canvasSize": { "alias": "canvasSize"; "required": true; "isSignal": true; }; "mediaDataUrls": { "alias": "mediaDataUrls"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
325
+ }
326
+
327
+ interface TextRun {
328
+ text: string;
329
+ style: StyleMap;
330
+ }
331
+ /**
332
+ * ElementRendererComponent — Angular port of the React `ElementRenderer.tsx`
333
+ * and the Vue `ElementRenderer.vue`.
334
+ *
335
+ * Renders a single slide element by its `type` discriminant (viewer-first
336
+ * subset):
337
+ * - `text` / `shape` → positioned box with fill/stroke + rich text
338
+ * - `picture` / `image` → `<img>`
339
+ * - `media` → poster frame (`<img>`) — playback TODO
340
+ * - `group` → recursive children (self-referencing selector)
341
+ * - everything else → labelled placeholder (TODO, see PORTING.md)
342
+ *
343
+ * Interaction (selection, resize, inline editing), connectors, charts, tables,
344
+ * SmartArt, ink, OLE, and 3D are not yet ported.
345
+ */
346
+ declare class ElementRendererComponent {
347
+ readonly element: _angular_core.InputSignal<PptxElement>;
348
+ readonly mediaDataUrls: _angular_core.InputSignal<Map<string, string>>;
349
+ readonly zIndex: _angular_core.InputSignal<number>;
350
+ readonly containerStyle: _angular_core.Signal<StyleMap>;
351
+ readonly shapeContainerStyle: _angular_core.Signal<StyleMap>;
352
+ readonly textStyle: _angular_core.Signal<StyleMap>;
353
+ readonly imageSrc: _angular_core.Signal<string | undefined>;
354
+ readonly children: _angular_core.Signal<PptxElement[]>;
355
+ readonly isShapeLike: _angular_core.Signal<boolean>;
356
+ readonly isImageLike: _angular_core.Signal<boolean>;
357
+ readonly paragraphs: _angular_core.Signal<TextRun[][]>;
358
+ readonly hasText: _angular_core.Signal<boolean>;
359
+ readonly placeholderLabel: _angular_core.Signal<string>;
360
+ private segmentStyle;
361
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ElementRendererComponent, never>;
362
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ElementRendererComponent, "pptx-element-renderer", never, { "element": { "alias": "element"; "required": true; "isSignal": true; }; "mediaDataUrls": { "alias": "mediaDataUrls"; "required": false; "isSignal": true; }; "zIndex": { "alias": "zIndex"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
363
+ }
364
+
365
+ /**
366
+ * Theme system for the Angular PowerPoint viewer.
367
+ *
368
+ * Angular counterpart of the React `ViewerThemeProvider` / `useViewerTheme`
369
+ * context and the Vue `provide`/`inject` theme provider. The `ViewerTheme`
370
+ * type, default palette, and `themeToCssVars` helper are framework-agnostic
371
+ * and live in `pptx-viewer-shared`.
372
+ */
373
+ /** DI token carrying the active `ViewerTheme` (or `undefined`). */
374
+ declare const VIEWER_THEME: InjectionToken<ViewerTheme | undefined>;
375
+ /**
376
+ * Provide a `ViewerTheme` to a subtree.
377
+ *
378
+ * Typically you do **not** need this — passing a `theme` input to
379
+ * `<pptx-viewer>` is sufficient. Use this to share a theme across multiple
380
+ * viewers or a wider component subtree.
381
+ *
382
+ * @example
383
+ * ```ts
384
+ * bootstrapApplication(AppComponent, {
385
+ * providers: [provideViewerTheme({ colors: { primary: '#6366f1' } })],
386
+ * });
387
+ * ```
388
+ */
389
+ declare function provideViewerTheme(theme: ViewerTheme | undefined): Provider;
390
+ /**
391
+ * Build an `[ngStyle]`-compatible map of CSS custom properties for a theme.
392
+ * Returns an empty object when the theme contributes no variables.
393
+ */
394
+ declare function themeStyle(theme: ViewerTheme | undefined): Record<string, string>;
395
+
396
+ /**
397
+ * Join class values into a single space-separated string, skipping falsy
398
+ * entries. A dependency-free analogue of the React/Vue packages' `cn`
399
+ * (clsx + tailwind-merge); the Angular viewer uses plain scoped CSS rather
400
+ * than Tailwind utility classes, so de-duplication is not required.
401
+ */
402
+ type ClassValue = string | number | false | null | undefined;
403
+ declare function cn(...values: ClassValue[]): string;
404
+
405
+ export { DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_FILL_COLOR, DEFAULT_STROKE_COLOR, DEFAULT_TEXT_COLOR, ElementRendererComponent, LoadContentService, PowerPointViewerComponent, SlideCanvasComponent, VIEWER_THEME, cn, defaultCssVars, defaultRadius, defaultThemeColors, getContainerStyle, getImageSrc, getShapeFillStrokeStyle, getTextBlockStyle, provideViewerTheme, themeStyle, themeToCssVars };
406
+ export type { CanvasSize, ClassValue, CollaborationConfig, CollaborationRole, StyleMap, ViewerTheme, ViewerThemeColors };