pptx-svelte-viewer 0.1.0 → 0.1.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.
package/dist/index.d.ts CHANGED
@@ -32,6 +32,17 @@ export declare const defaultRadius = "0.5rem";
32
32
  */
33
33
  export declare const defaultThemeColors: ViewerThemeColors;
34
34
 
35
+ /** Options for the multi-slide PDF export (progress + cooperative cancel). */
36
+ declare interface ExportPdfOptions {
37
+ /** Capture-phase progress callback: `(currentSlide, totalSlides)`. */
38
+ onProgress?: ExportProgress;
39
+ /** Abort the export early; the loop checks this between slides. */
40
+ signal?: AbortSignal;
41
+ }
42
+
43
+ /** Per-slide progress callback: `(currentSlideIndex, totalSlides)`. */
44
+ declare type ExportProgress = (current: number, total: number) => void;
45
+
35
46
  /**
36
47
  * Explicitly-typed public export of the viewer component.
37
48
  *
@@ -41,7 +52,42 @@ export declare const defaultThemeColors: ViewerThemeColors;
41
52
  * Re-exporting through this annotated constant keeps the published `.d.ts`
42
53
  * fully typed regardless of which compiler produced it.
43
54
  */
44
- export declare const PowerPointViewer: Component<PowerPointViewerProps>;
55
+ export declare const PowerPointViewer: Component<PowerPointViewerProps, PowerPointViewerApi>;
56
+
57
+ /**
58
+ * Imperative editing API exposed on the `<PowerPointViewer>` component
59
+ * instance (via `bind:this`). Mirrors the vanilla binding's `EditorController`
60
+ * surface subset the host drives directly.
61
+ */
62
+ export declare interface PowerPointViewerApi {
63
+ /** Undo the last committed edit. */
64
+ undo(): void;
65
+ /** Redo the last undone edit. */
66
+ redo(): void;
67
+ /** Whether an undo step is available (snapshot; not reactive). */
68
+ canUndo(): boolean;
69
+ /** Whether a redo step is available (snapshot; not reactive). */
70
+ canRedo(): boolean;
71
+ /** Delete the selected element (no-op when nothing is selected). */
72
+ deleteSelected(): void;
73
+ /** The selected top-level element id, or null. */
74
+ getSelectedElementId(): string | null;
75
+ /** Serialize the edited slides to `.pptx` bytes via the core handler. */
76
+ save(): Promise<Uint8Array>;
77
+ /** Save + trigger a browser download of the `.pptx` (default name). */
78
+ downloadPptx(fileName?: string): Promise<void>;
79
+ /**
80
+ * Export a slide as a PNG download (defaults to the current slide). Renders
81
+ * the slide off-screen at scale 1 and rasterises it with `html2canvas-pro`
82
+ * (dynamically imported), so the first call pays a one-time load cost.
83
+ */
84
+ exportSlidePng(index?: number): Promise<void>;
85
+ /**
86
+ * Export every slide as a multi-page PDF download (one slide per page).
87
+ * `jspdf` is dynamically imported on first use.
88
+ */
89
+ exportPdf(options?: ExportPdfOptions): Promise<void>;
90
+ }
45
91
 
46
92
  /** Props for `<PowerPointViewer>`. */
47
93
  export declare interface PowerPointViewerProps {
@@ -61,6 +107,28 @@ export declare interface PowerPointViewerProps {
61
107
  showThumbnails?: boolean;
62
108
  /** Show the navigation/zoom toolbar. Default true. */
63
109
  showToolbar?: boolean;
110
+ /**
111
+ * Show the speaker-notes panel and its toolbar toggle. Default true. The
112
+ * panel is plain-text only and reads the active slide's notes; pass
113
+ * `onnotesupdate` to make it editable (omitting it renders read-only).
114
+ */
115
+ showNotes?: boolean;
116
+ /**
117
+ * Opt in to the experimental Three.js (WebGL) SmartArt renderer for
118
+ * `smartArt` elements, in place of the default SVG renderer. Requires the
119
+ * optional `three` peer dependency; when it is unavailable, or a diagram
120
+ * has no renderable nodes, or the WebGL mount fails, the SVG renderer is
121
+ * used automatically. Default false.
122
+ */
123
+ smartArt3D?: boolean;
124
+ /**
125
+ * Enable in-place editing: click to select an element, drag to move, use the
126
+ * 8 handles to resize (Shift locks aspect) and the rotate handle to rotate,
127
+ * double-click text/shapes to edit their text, and the keyboard for
128
+ * delete/duplicate/nudge/undo/redo. Adds an Undo/Redo/Save/Download group to
129
+ * the toolbar. Default false (read-only viewer).
130
+ */
131
+ editable?: boolean;
64
132
  /** Optional class name applied to the root element. */
65
133
  class?: string;
66
134
  /** Fired after a presentation finishes loading. */
@@ -69,6 +137,20 @@ export declare interface PowerPointViewerProps {
69
137
  onerror?: (message: string) => void;
70
138
  /** Fired when the active slide changes (0-based index). */
71
139
  onslidechange?: (index: number) => void;
140
+ /**
141
+ * Fired with the committed plain-text speaker notes when the user edits
142
+ * the notes panel (on `change` / `blur`). This binding has no built-in
143
+ * slide-mutation channel, so the host is responsible for writing the text
144
+ * back onto its own copy of the slide; omit this to render the notes
145
+ * panel read-only.
146
+ */
147
+ onnotesupdate?: (notes: string) => void;
148
+ /**
149
+ * Fired after every committed editing mutation (move / resize / rotate /
150
+ * delete / duplicate / nudge / inline text / notes) when `editable`. Use it
151
+ * to track the dirty state or mirror edits into host state.
152
+ */
153
+ onchange?: () => void;
72
154
  }
73
155
 
74
156
  /**
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as r, d as a, f as e, g as i, h as o, l as m, m as t, p as l, t as n, u as h } from "./component-CacEu31z.js";
1
+ import { _ as r, d as a, f as e, g as i, h as o, l as m, m as t, p as l, t as n, u as h } from "./component-DxQFSCeR.js";
2
2
  import { r as f } from "./translator-C44zS1dl.js";
3
3
  import "./i18n.js";
4
4
  export {
@@ -0,0 +1,169 @@
1
+ import { AmbientLight as A, BufferGeometry as B, CanvasTexture as C, Color as b, DirectionalLight as L, EdgesGeometry as E, Euler as W, ExtrudeGeometry as H, Group as $, Line as D, LineBasicMaterial as R, LineSegments as Y, LinearFilter as F, Mesh as G, MeshBasicMaterial as U, MeshStandardMaterial as q, PerspectiveCamera as O, PlaneGeometry as V, RepeatWrapping as X, SRGBColorSpace as Z, Scene as j, Shape as N, Vector3 as I, WebGLRenderer as J } from "./three.module-BLwnGxzY.js";
2
+ import { OrbitControls as K } from "./OrbitControls-B2ezETBF.js";
3
+ var M = 4, P = 0.86;
4
+ function Q(o, i, e) {
5
+ const t = i.split(/\s+/u).filter(Boolean);
6
+ if (t.length === 0) return [];
7
+ const r = [];
8
+ let a = t[0];
9
+ for (let s = 1; s < t.length; s++) {
10
+ const c = `${a} ${t[s]}`;
11
+ o.measureText(c).width <= e ? a = c : (r.push(a), a = t[s]);
12
+ }
13
+ return r.push(a), r;
14
+ }
15
+ function _(o, i, e, t, r) {
16
+ if (typeof document > "u" || !o.trim() || t <= 0 || r <= 0) return null;
17
+ const a = t * P, s = r * P, c = document.createElement("canvas");
18
+ c.width = Math.max(8, Math.round(a * M)), c.height = Math.max(8, Math.round(s * M));
19
+ const n = c.getContext("2d");
20
+ if (!n) return null;
21
+ const d = "system-ui, -apple-system, Segoe UI, Roboto, sans-serif", p = c.width * 0.94;
22
+ let u = Math.max(6, e) * M, f = [];
23
+ for (let l = 0; l < 12; l++) {
24
+ n.font = `600 ${u}px ${d}`, f = Q(n, o, p);
25
+ const g = u * 1.2;
26
+ if (f.length * g <= c.height * 0.96 || u <= 6 * M) break;
27
+ u *= 0.88;
28
+ }
29
+ n.clearRect(0, 0, c.width, c.height), n.fillStyle = i, n.textAlign = "center", n.textBaseline = "middle", n.font = `600 ${u}px ${d}`;
30
+ const x = u * 1.2, m = f.length * x, y = c.height / 2 - m / 2 + x / 2;
31
+ for (let l = 0; l < f.length; l++) n.fillText(f[l], c.width / 2, y + l * x);
32
+ const h = new C(c);
33
+ return h.colorSpace = Z, h.minFilter = F, h.magFilter = F, h.flipY = !1, h.premultiplyAlpha = !1, h.wrapT = X, h.repeat.set(1, -1), h.offset.set(0, 1), h.needsUpdate = !0, {
34
+ texture: h,
35
+ worldWidth: a,
36
+ worldHeight: s
37
+ };
38
+ }
39
+ function ee(o) {
40
+ const i = new N();
41
+ o.outline.forEach((t, r) => {
42
+ r === 0 ? i.moveTo(t.x, t.y) : i.lineTo(t.x, t.y);
43
+ }), i.closePath();
44
+ const e = o.bevel > 0;
45
+ return new H(i, {
46
+ depth: o.depth,
47
+ bevelEnabled: e,
48
+ bevelThickness: o.bevel,
49
+ bevelSize: o.bevel,
50
+ bevelSegments: 2,
51
+ curveSegments: o.rounded ? 24 : 1,
52
+ steps: 1
53
+ });
54
+ }
55
+ function te(o, i, e) {
56
+ const t = ee(e), r = new q({
57
+ color: new b(e.fill),
58
+ metalness: 0.12,
59
+ roughness: 0.52,
60
+ transparent: e.opacity < 1,
61
+ opacity: e.opacity
62
+ }), a = new G(t, r);
63
+ if (a.position.set(e.position.x, e.position.y, e.position.z), a.rotation.set(e.rotation.x, e.rotation.y, e.rotation.z), o.add(a), i.push(t, r), e.strokeWidth > 0) {
64
+ const s = new E(t, 30), c = new R({ color: new b(e.stroke) }), n = new Y(s, c);
65
+ n.position.copy(a.position), n.rotation.copy(a.rotation), o.add(n), i.push(s, c);
66
+ }
67
+ return t;
68
+ }
69
+ function ne(o, i, e) {
70
+ if (!e.text) return;
71
+ const t = _(e.text, e.textColor, e.fontSize, e.halfWidth * 2, e.halfHeight * 2);
72
+ if (!t) return;
73
+ const r = new V(t.worldWidth, t.worldHeight), a = new U({
74
+ map: t.texture,
75
+ transparent: !0,
76
+ depthWrite: !1
77
+ }), s = new G(r, a), c = new W(e.rotation.x, e.rotation.y, e.rotation.z), n = new I(0, 0, e.depth + e.bevel + 0.4).applyEuler(c);
78
+ s.position.set(e.position.x + n.x, e.position.y + n.y, e.position.z + n.z), s.rotation.copy(c), o.add(s), i.push(r, a, t.texture);
79
+ }
80
+ function oe(o, i, e) {
81
+ for (const t of e.connectors) {
82
+ if (t.points.length < 2) continue;
83
+ const r = new B().setFromPoints(t.points.map((s) => new I(s.x, s.y, s.z))), a = new R({
84
+ color: new b(t.color),
85
+ transparent: !0,
86
+ opacity: 0.7
87
+ });
88
+ o.add(new D(r, a)), i.push(r, a);
89
+ }
90
+ }
91
+ function ie(o) {
92
+ const i = new $(), e = [];
93
+ for (const t of o.meshes)
94
+ te(i, e, t), ne(i, e, t);
95
+ return oe(i, e, o), {
96
+ group: i,
97
+ dispose() {
98
+ for (const t of e) t.dispose();
99
+ }
100
+ };
101
+ }
102
+ var T = 42;
103
+ function ae(o) {
104
+ let i = 1 / 0, e = 1 / 0, t = 1 / 0, r = -1 / 0, a = -1 / 0, s = -1 / 0;
105
+ const c = (n, d, p, u) => {
106
+ i = Math.min(i, n - u), e = Math.min(e, d - u), t = Math.min(t, p - u), r = Math.max(r, n + u), a = Math.max(a, d + u), s = Math.max(s, p + u);
107
+ };
108
+ for (const n of o.meshes) {
109
+ const d = Math.max(n.halfWidth, n.halfHeight) + n.depth + n.bevel;
110
+ c(n.position.x, n.position.y, n.position.z, d);
111
+ }
112
+ for (const n of o.connectors) for (const d of n.points) c(d.x, d.y, d.z, 1);
113
+ return Number.isFinite(i) ? {
114
+ cx: (i + r) / 2,
115
+ cy: (e + a) / 2,
116
+ cz: (t + s) / 2,
117
+ radius: 0.5 * Math.hypot(r - i, a - e, s - t) || 1
118
+ } : {
119
+ cx: 0,
120
+ cy: 0,
121
+ cz: 0,
122
+ radius: Math.max(o.bounds.width, o.bounds.height) / 2 || 1
123
+ };
124
+ }
125
+ function se(o, i) {
126
+ const e = T * Math.PI / 180, t = 2 * Math.atan(Math.tan(e / 2) * i);
127
+ return o / Math.sin(Math.min(e, t) / 2) * 1.1;
128
+ }
129
+ function le(o, i, e, t, r = {}) {
130
+ const a = new J({
131
+ canvas: o,
132
+ antialias: !0,
133
+ alpha: !r.background
134
+ });
135
+ a.setPixelRatio(Math.min(typeof window > "u" ? 1 : window.devicePixelRatio || 1, r.maxPixelRatio ?? 2)), a.setSize(e, t, !1);
136
+ const s = new j();
137
+ r.background && (s.background = new b(r.background));
138
+ const { cx: c, cy: n, cz: d, radius: p } = ae(i), u = e / Math.max(1, t), f = se(p, u), x = new O(T, u, 0.1, f * 8 + p * 4);
139
+ x.position.set(c + p * 0.25, n + p * 0.3, d + f), x.lookAt(c, n, d), s.add(new A(16777215, 0.62));
140
+ const m = new L(16777215, 0.95);
141
+ m.position.set(c + p, n + p * 1.4, d + f), s.add(m);
142
+ const y = new L(16777215, 0.3);
143
+ y.position.set(c - p, n - p * 0.6, d + f * 0.6), s.add(y);
144
+ const h = ie(i);
145
+ s.add(h.group);
146
+ let l = null;
147
+ const g = (w) => {
148
+ w && !l ? (l = new K(x, o), l.enablePan = !1, l.target.set(c, n, d), l.minDistance = f * 0.4, l.maxDistance = f * 3, l.update()) : !w && l && (l.dispose(), l = null), l && (l.autoRotate = !!r.autoRotate, l.autoRotateSpeed = 1.2);
149
+ };
150
+ g(!!r.interactive);
151
+ let v = 0, S = !1;
152
+ const z = () => {
153
+ S || (v = requestAnimationFrame(z), l?.update(), a.render(s, x));
154
+ };
155
+ return v = requestAnimationFrame(z), {
156
+ resize(w, k) {
157
+ x.aspect = w / Math.max(1, k), x.updateProjectionMatrix(), a.setSize(w, k, !1);
158
+ },
159
+ setInteractive(w) {
160
+ g(w);
161
+ },
162
+ dispose() {
163
+ S = !0, cancelAnimationFrame(v), l?.dispose(), h.dispose(), a.dispose();
164
+ }
165
+ };
166
+ }
167
+ export {
168
+ le as mountSmartArt3D
169
+ };